WoWInterface

WoWInterface (http://www.wowinterface.com/forums/index.php)
-   AddOn Help/Support (http://www.wowinterface.com/forums/forumdisplay.php?f=3)
-   -   Lua code help (stuf text) (http://www.wowinterface.com/forums/showthread.php?t=46497)

Rusken 05-21-13 10:29 AM

Lua code help (stuf text)
 
Evening, i got this custom lua code from a fella over at mmo a couple of months back and what it does is that it shortens name like "Raider's Training Dummy" in to "R.T.Dummy".
What i need help with is to change the code so it still does what it does but i want it to look like this ->

"R.T.Dummy | 100", 100 being perchp and i want it to be colored by "hpthreshold", the name and the "|" should be white.

So, is this possible and is there any kind soul here with the knowledge on how to do this that could give me a hand?:)
Thanks in advance.

SDPhantom 05-21-13 04:01 PM

It would be easier if you posted a copy of the working code as-is. Be sure to encase it in [code] tags.

ravagernl 05-22-13 06:32 AM

Quote:

Originally Posted by SDPhantom (Post 278378)
It would be easier if you posted a copy of the working code as-is. Be sure to encase it in [code] tags.

I'm thinking it's something like
Code:

function(unit)
        local name = UnitName(unit) or unit
        name = name:gsub('(%S+) ',function(t) return t:sub(1,1)..'.' end)
        return name
end


Rusken 05-22-13 10:26 AM

Oh snap, forgot to do that, its the one ravagernl posted.

Code:

function(unit)
        local name = UnitName(unit) or unit
        name = name:gsub('(%S+) ',function(t) return t:sub(1,1)..'.' end)
        return name
end


SDPhantom 05-22-13 12:44 PM

This has an improvement over the unit's name conversion as it doesn't allocate a dynamic function to handle the string.gsub() call and it's kept on C side. The way I have the coloring work is it starts as green at 100%, moves to yellow at 50% and red at 0%. The way text colors work is they use UI escape sequences. The one for colors is in the format |cAARRGGBB in which AA, RR, GG, and BB represent hex values for Alpha, Red, Green, and Blue respectively. Although it should be customary to use |r as an end tag for colored text, it's not necessary if you're immediately changing to another color for following text. The purpose of |r is to reset the color of following text to what is set by the object that is given the string to display. The use of || is to print a literal pipe character "|" as this is used for the UI escape sequences.
Code:

function(unit)
        local short=(UnitName(unit) or unit):gsub("(%S)%S*%s+","%1%.");
        local pcnt=math.min(1,UnitHealth(unit)/UnitHealthMax(unit));-- If max is zero (it happens) assume 100%
        local r,g=math.max(0,2-pcnt*2)*255,math.min(1,pcnt*2)*255;

        return ("|cffffffff%s || |cff%02x%02x00%.0f|r"):format(short,r,g,pcnt*100));
end


This is to get dynamic text colors to work in a string-only standpoint, but it'll be much better to leave the static colors in the string and control the dynamic color from a FontString object. The following code makes use of this.
Code:

function(obj,unit)
        local short=(UnitName(unit) or unit):gsub("(%S)%S*%s+","%1%.");
        local pcnt=math.min(1,UnitHealth(unit)/UnitHealthMax(unit));-- If max is zero (it happens) assume 100%
        obj:SetTextColor(math.max(0,2-pcnt*2),math.min(1,pcnt*2),0);
        obj:SetFormattedText("|cffffffff%s |||r %.0f",short,pcnt*100));
end


UI Escapes (WoWPedia)

Rusken 05-23-13 05:52 PM

Quote:

Originally Posted by SDPhantom (Post 278449)
This has an improvement over the unit's name conversion as it doesn't allocate a dynamic function to handle the string.gsub() call and it's kept on C side. The way I have the coloring work is it starts as green at 100%, moves to yellow at 50% and red at 0%. The way text colors work is they use UI escape sequences. The one for colors is in the format |cAARRGGBB in which AA, RR, GG, and BB represent hex values for Alpha, Red, Green, and Blue respectively. Although it should be customary to use |r as an end tag for colored text, it's not necessary if you're immediately changing to another color for following text. The purpose of |r is to reset the color of following text to what is set by the object that is given the string to display. The use of || is to print a literal pipe character "|" as this is used for the UI escape sequences.
Code:

function(unit)
        local short=(UnitName(unit) or unit):gsub("(%S)%S*%s+","%1%.");
        local pcnt=math.min(1,UnitHealth(unit)/UnitHealthMax(unit));-- If max is zero (it happens) assume 100%
        local r,g=math.max(0,2-pcnt*2)*255,math.min(1,pcnt*2)*255;

        return ("|cffffffff%s || |cff%02x%02x00%.0f|r"):format(short,r,g,pcnt*100));
end


This is to get dynamic text colors to work in a string-only standpoint, but it'll be much better to leave the static colors in the string and control the dynamic color from a FontString object. The following code makes use of this.
Code:

function(obj,unit)
        local short=(UnitName(unit) or unit):gsub("(%S)%S*%s+","%1%.");
        local pcnt=math.min(1,UnitHealth(unit)/UnitHealthMax(unit));-- If max is zero (it happens) assume 100%
        obj:SetTextColor(math.max(0,2-pcnt*2),math.min(1,pcnt*2),0);
        obj:SetFormattedText("|cffffffff%s |||r %.0f",short,pcnt*100));
end


UI Escapes (WoWPedia)

Thanks but none of them seem to work when i paste them in to "use custom lua" in stuf, is it something i need to add to the actual .lua?
As you might have noticed, my lua skills are worse then worse:(

Rainrider 05-24-13 10:07 PM

I have a very similar issue I posted about here and Phanx pointed me to this thread as it closely relates to my problem.

What SDPhantom suggested (unit:gsub("(%S)%S*%s+","%1%.")) is what I looked for, but I need to make this work with languages other than english. The string I test with is "Echo of a Pandaren Monk" and the single 'a' appears to be the problem if I use the following:

Code:

unit:gsub("(.[\128-\191]*)%S+%s", "%1. ")
.
I get "E. o. a . Monk" instead of "E. o. a P. Monk".

I also don't understand what exactly is .[\128-\191]* supposed to mean but it makes it work for non-english characters (haven't tested chinese and korean though, but I do not look for such functionality).

Sorry for writing in between.

ravagernl 05-25-13 02:04 AM

Quote:

Originally Posted by Rainrider (Post 278626)
I also don't understand what exactly is .[\128-\191]* supposed to mean but it makes it work for non-english characters (haven't tested chinese and korean though, but I do not look for such functionality).

Sorry for writing in between.

I think range 128 - 191 match the diacritic characters used to compose a unicode character (first 128 are basically ascii characters).

EDIT: Found this on http://lua-users.org/wiki/LuaUnicode:
Quote:

Happily UTF-8 is designed so that it is relatively easy to count the number of unicode symbols in a string: simply count the number of octets that are in the ranges 0x00 to 0x7f (inclusive) or 0xC2 to 0xF4 (inclusive). (In decimal, 0-127 and 194-244.) These are the codes which can start a UTF-8 character code. Octets 0xC0, 0xC1 and 0xF5 to 0xFF (192, 193 and 245-255) cannot appear in a conforming UTF-8 sequence; octets in the range 0x80 to 0xBF (128-191) can only appear in the second and subsequent octets of a multi-octet encoding. Remember that you cannot use \0 in a Lua pattern.

Rainrider 05-25-13 07:41 PM

1 Attachment(s)
Oh, I actually read your quoted link before and now it makes sense. Thank you.

I also found the solution to the other issue: just use '%S' instead of '.':
Code:

string.gsub("Echo of a Pandaren Monk", "(%S[\128-191]*)%S+%s", "%1. ")
Is there any way to make this work for the Russian client too?

Edit: It actually works for Russian with the exception that it also matches the single 'a'. This is a cool page to look up uft8 characters as you can read the corresponding lua excape sequence from it. So for cyrillic 'a' it would be \208\176. I still don't get why this is a match, as I require one or more non-space characters after what's in my capture.

Phanx 05-27-13 12:36 AM

You're getting that ? character because you're actually breaking the Russian character \208\176 (а) in half, keeping only \208 which is not a valid Unicode character by itself. The string functions in WoW are not Unicode aware; they only look at bytes. If you want to support languages with multi-byte characters, you can either use the UTF8 library which provides UTF8-aware versions of some string functions, or you can split it up, count bytes, etc. yourself.

Either way it's going to take more than a simple gsub. You'd probably want to just split it up into "Russian clients use this code path" and "everyone else use this code path" since Korean and Chinese (the other WoW locales with multi-byte characters) generally don't use spaces between words, and cannot be meaningfully abbreviated anyway.

Code:

local old, new = "Echo of a Pandaren Monk"
if GetLocale() == "ruRU" then
    -- complicated version
    new = ""
    for word in string.gmatch(old, "(%S+)%s") do
        new = new .. string.utf8sub(word, 1, 1), " " -- uses UTF8 lib function
    end
    new = new .. strmatch(old, "%S+$")
else
    -- simple version
    new = gsub(old, "(%S[\128-191]*)%S+%s", "%1. ")
end
-- do something with new here


Rainrider 05-27-13 01:25 PM

I just still wonder why it is a match. The representation of the 'a ' as lua escape sequence is \208\176\32. One can verify that by:
lua Code:
  1. local str = "Ецхо оф а Пандарен Монк"
  2.  
  3. for i=1, #str do
  4.    print(i, str:byte(i))
  5. end

In my match pattern I demand a non-space character, followed by zero or more characters from the range between \128 and \191, followed by one or more non-space characters, followed by a space character. \32 is a space character, but there is nothing else between \176 and \32, so the match should actually fail. As it appears, it matches the \208 in my capture, the \176 as the non-space char and the \32 as the space char. So why does it skip the \176 in the capture, when '*' means zero or more and the longest possible match of that?

Appart from that, I don't believe single characters would occur in unit names in the russian locale. The translation for 'a' is 'один'/'одна'/'одно' (they decline those depending on gender). Is there a way to verify that on wowhead?

Phanx 05-27-13 02:32 PM

Code:

string.gsub("Echo of a Pandaren Monk", "(%S[\128-191]*)%S+%s", "%1. ")
That pattern doesn't require one or more non-whitespace characters. It requires one or more non-whitespace bytes (eg. \32 is flagged as "whitespace"). In the case of multi-byte characters, the extra bytes per character are matched. In the case of \208\176, neither \208 nor \176 by themselves are "whitespace" so string.gsub sees them as separate non-whitespace entities, since it is not Unicode-aware.

As for your other question, "Echo of a Pandaren Monk" [url="http://ru.wowhead.com/npc=58669"]in Russian[/b] is "Эхо пандарена-монаха". The preposition "of" is generally not used directly in Russian (the declension of the relevant noun changes instead) and articles like "a" and "the" are generally omitted. There are one-character words in Russian that are used often -- в, с, к, у are several that spring to mind -- but I don't know if any of them appear in NPC names.

Edit: A quick scan of Wowhead in Russian finds at least one NPC name with a single-character word -- Эрунак Говорящий с Камнем. There are likely more, but I quit looking after spotting the first one on page 2. :p

Rainrider 05-27-13 04:40 PM

Wow, I've learnt russian for 7 years, but haven't spoken it for the last 15 years now. And you beat me to it, your explanations are perfectly right. Shame on me :)

You are also right about character vs word, I worded it incorrectly, but I think my previous post still holds true.

Code:

(%S[\128-191]*)%S+%s
The part of my transliterated name for the pandaren monk (just the 'a' and the whitespace after it:
Code:

\208\176\32
There isn't a match for the red part, is it? I'm sorry, I still don't understand why it matches the way it does. Thank you very much for trying to explain it to me that persistently.


All times are GMT -6. The time now is 07:37 AM.

vBulletin © 2014, Jelsoft Enterprises Ltd
©2012 ZAM Network LLC