Basically, iterate through the string one character at a time. Add each character to the current line, and in a second variable, add the width of the character. If the character is an opening tag, start a second loop that keeps adding the characters to the string, but does not add the width, until the closing tag is found.
Sadly I cannot just work with 2 variables as you suggest because I won't want only the width of the text-until-now but more precisely the width of each and every line. I also have to parse the line to find spaces and/or special characters like ( or - to allow breaking the line.
I'd have a couple ds_lists, one holding each string separated whenever a tag is encountered, one for colors per string, and another for anything else you may have. If no tag, set the first color to default and copy the string to the strings list until you encounter a tag.
and
Then use a parse script/string_split script to extract what you need. You can hold data within a script or the create event with an array. To go to next line use"#".
I already have a ds_list of all the tags and all the text, separated. I have no issue with that. My issue is how to remove the tags from the text, do the wrapping, and then add those tags back at the correct location.
If removing/adding them is not a viable solution, how can I effectively ignore them during the wrapping of the text. That my big issue right now.
------
Ok I think I didn't explain my problem properly, let me reformulate:
I have a string with tags, that you all understood very well.
This said string uses a monospace font, so I don't care about string_width, I'm using string_length only.
My code does 2 things:
1. It wraps the text in a ds_list
2. For each lines, it pads the end with spaces and adds '|' to the start and the end.
My goal is to create a script that creates a box using some special characters. My script works fine as long as I have no tags, but the goal is to modify it in order to support tags. The wrapping must occure like if the tags don't exists, but once the wrapping is done, the tags must be re-inserted at the correct location. This is the part that I'm having issues with.
I'm able to get a ds_list that looks like this:
Code:
DS_LIST [
Array [ 0, 1, "Hello " ],
Array [ 1, 7, "c", "yellow" ],
Array [ 0, 16, "friend" ],
Array [ 1, 23, "c", "default" ],
Array [ 0, 34, "! How are you?" ]
]
Where the first number is 0=text and 1=tag, the second is the index in the string where this 'part' belongs, and finally the rest in data related to either text or tag.
That's not a problem. Now my issue is how to wrap the text like if the tags don't exists, but keep the tags in the wrapped text at the end.
Right now, my script includes the tag text in the wrapping algorithm, which obviously breaks it.
I calculate the wrapping before I do the rendering logic, which means I can't get rid of the tags before I do the wrapping logic.
I end up with 'tokens' which tell my renderer how to render them:
Code:
// A token
Array [ 'Hello', 16, 8, c_black, f_mono ]
// [ Text, x, y, color, font ]
Here is an illustration of what I'm trying to achieve:
Code:
// this bit of text
Hello [c:yellow]friend[c:default]! How are you?
// Should wrap as follow (note the box of character around it!)
+----------------+
| Hello friend! |
| How are you ? |
+----------------+
// Now because of the tags, the length gets
// completely wrong, and I get this
+----------------+
| Hello |
| friend! |
| How are you ? |
+----------------+
// Because there is no tags around the last bit it wraps well.
So I'm supposed to end up with this (note the trailing spaces, they are important to add the closing wall of the box):
Code:
DS_LIST [
"Hello [c:yellow]friend[c:default]! ",
"How are you ? "
]
In this specific case, the tags are all on the first line, but obviously they can be sparse anywhere.
I hope this clears up what my issue is.
1. I cannot remove those tags before I apply the wrapping logic
2. The tags should not count as a character for the wrapping, that's what I'm trying to do
3. Once the wrapping is completed, the tags should be at the correct position in each lines.
Thanks for anyone taking the time to answer. I'll probably end up doing something more complicated as in 'not a single script' instead, which lots of data structures.
I wanted to avoid that route using a 'quick but effective script' but I'm starting to think there is no such thing as that for this specific issue.
-------
EDIT: An external source pointed out that I should focus more on how I treat indexes rather than trying to think about removing/adding text. Said source mentionned that, for example, if I try to get character at position 9 (which is inside a tag) I should instead 'convert' this index to the new index 19, since "[c:yellow]" has a length of 10.
But that means that I have to change how I call string_char_at(), amd string_copy() since I now have to convert all of those value... constantly.