Cecho String Length

Post Reply
User avatar
tsuujin
Posts: 695
Joined: Fri Feb 26, 2010 12:59 am
Location: California
Contact:

Cecho String Length

Post by tsuujin »

So I sat down recently to write a couple of screen printing functions for my combat system and included a method to print a bar-style message to the screen with the text centered in the middle, ie:

-----------------------------[ This is a test ]-----------------------------

I wanted to be able to easily colorize it, so I made the string input to the function use cecho as the printing method, and came across an interesting problem: all the tags count towards the string length, but are not printed to the screen. This means that the total length of the bar was wrong on everything that included color tags.

I'm sure someone else will come across this problem, so here's the solution:
Code: [show] | [select all] lua
local txtOnly = s:gsub("\<.+\>","")
local sLen = txtOnly:len()
All this does is give you a string containing only the actual text from the line by replacing anything in brackets with nothing. A simpler example, if you just want the length, is:
Code: [show] | [select all] lua
local sLen = s:gsub("\<.+\>",""):len()

User avatar
Vadi
Posts: 5042
Joined: Sat Mar 14, 2009 3:13 pm

Re: Cecho String Length

Post by Vadi »

Oh, that is nice, thanks. Been need something like that to help with alignment as well.

Iocun
Posts: 174
Joined: Wed Dec 02, 2009 1:45 am

Re: Cecho String Length

Post by Iocun »

There's still the problem with using string.format() (with fixed-size string blocks etc.) alongside cecho(). I have some solutions for this, but nothing elegant yet.

User avatar
tsuujin
Posts: 695
Joined: Fri Feb 26, 2010 12:59 am
Location: California
Contact:

Re: Cecho String Length

Post by tsuujin »

Iocun wrote:There's still the problem with using string.format() (with fixed-size string blocks etc.) alongside cecho(). I have some solutions for this, but nothing elegant yet.
What problems? I do this heavily for all of my outputs and haven't seen anything.

Iocun
Posts: 174
Joined: Wed Dec 02, 2009 1:45 am

Re: Cecho String Length

Post by Iocun »

Well, if you do it like this, it will work perfectly fine:

cecho(string.format("%s%-10s %s\n", "<red>","Foo", "Bar"))
cecho(string.format("%s%-10s %s\n", "<yellow>","Foo", "Bar"))

Those lines are properly displayed in two columns right below each other. And usually that's what I use as well, so there's no problem.

But for some cases, I need to use something like:

cecho(string.format("%-10s %s\n", "<red>Foo", "Bar"))
cecho(string.format("%-10s %s\n", "<yellow>Foo", "Bar"))

And in this case, the formatting is messed up as the 10 characters from %-10s are calculated -with- the color tag, but then the space of the color tag is retroactively removed again, so I get something like:
Code: [show] | [select all] lua
Foo    Bar
Foo Bar
But it isn't really a huge deal as there are several alternatives to this approach.

User avatar
tsuujin
Posts: 695
Joined: Fri Feb 26, 2010 12:59 am
Location: California
Contact:

Re: Cecho String Length

Post by tsuujin »

Ah, i see what you mean. It's just a difference in coding styles. I do something like:
Code: [show] | [select all] lua
string.format("<%s>%-10s","red","Test")

Nemutaur
Posts: 22
Joined: Mon Mar 19, 2012 10:58 pm

Re: Cecho String Length

Post by Nemutaur »

Hi there,

i've been trying to get this to work for a concatenated string. I think i better just start from the top. I'm trying to align people eating a certain herb or applying a salve to the right. But i want the persons color to be either Yellow or Red depending if they are my primary target or not, the action like eating/ate to be colored white and the herb or salve to be colored forest_green.

I thought i could just do something like this:
Code: [show] | [select all] lua
tempString = "<red>" .. matches[2] .. " " .. "<white" .. matches[3] .. " " .. "<forest_green>" .. matches[4]
trueLength = tempString.:gsub("\<.+\>",""):len()
The problem is that will only return the length of the last part of the string, so matches[4] in this case. Does anyone know how i could bypass this, or how to concatenate a string so that this won't happen? I really want to get this color coding and align right to work with different colors for people, actions and whatnot.

Thanks,
Nemu

Iocun
Posts: 174
Joined: Wed Dec 02, 2009 1:45 am

Re: Cecho String Length

Post by Iocun »

You have two other errors here, too: First, "<white>", not "<white". Second, tempString:gsub not tempString.:gsub

The actual problem you're referring to though is that the Lua pattern "\<.+\>" is greedy, meaning it will try to match as much as possible. It will thus start a match from the first < to the last >, encompassing anything from <red> to <forest_green> and deleting that, leaving you only with matches[4].

By the way, it is also not needed to escape the < and > in the pattern, so no need to use \< and \>.

There are two easy ways to change the gsub pattern to fix this:

1: tempString:gsub("<[%a_]+>","")
2: tempString:gsub("<.->","")

The first will only match a single word (plus underscores) within the angular brackets, so it won't encompass the whole series of color tags like the original pattern. The second is very similar to the original pattern, except that the - instead of the + makes it non-greedy, which, again, makes it only match a -single- color tag. Both those methods should give you the desired result.

Nemutaur
Posts: 22
Joined: Mon Mar 19, 2012 10:58 pm

Re: Cecho String Length

Post by Nemutaur »

Thanks a lot Iocun. I'm using the first method to check for length now and it works perfectly. Now i should be able to get the modified align right to work properly.

Post Reply