vanilla-wow-addons – Rev 1

Subversion Repositories:
Rev:
--[[

Sea String (mostly Sea.string)

A Mini-Library for string functions.

Compiler:
        AnduinLothar (karlkfi@cosmosui.org)

Contributors:
        Thott (thott@thottbot.com)
        Legorol (legorol@cosmosui.org)
        Mugendai (mugekun@gmail.com)
        Iriel (iriel@vigilance-committee.org)
        

==Installation/Utilization==

Embedding:
- Drop the SeaString folder into your Interface\AddOns\YourAddon\ folder
- Add Sea and SeaString as optional dependancies
- Add the following line to the end of your TOC file, before your addon files:
SeaString\SeaString.lua

Standard:
- Drop the SeaString folder into your Interface\AddOns\ directory
- Add SeaString as a required dependancy


Change Log:
v0.2
- Changed lua file name
v0.1 (Alpha)
- SeaString Forked into Mini-Library from the main Sea. Still backwards compatible.


        $LastChangedBy: karlkfi $
        $Rev: 2577 $
        $Date: 2005-10-10 14:44:01 -0700 (Mon, 10 Oct 2005) $
]]--

local SEA_STRING_VERSION = 0.11;
local loadThisEmbeddedInstance;
SEA_STRING_DEBUG = nil;
------------------------------------------------------------------------------
--[[ Embedded Sub-Library Load Algorithm ]]--
------------------------------------------------------------------------------

if(not Sea) then
        Sea = {};
        Sea.versions = {};
        Sea.versions.SeaString = SEA_STRING_VERSION;
        loadThisEmbeddedInstance = true;
        Sea.string = {};
else
        if(not Sea.versions) then
                Sea.versions = {};
        end
        if (not Sea.versions.SeaString) or (Sea.versions.SeaString < SEA_STRING_VERSION) then
                Sea.versions.SeaString = SEA_STRING_VERSION;
                loadThisEmbeddedInstance = true;
        end
        if(not Sea.string) then
                Sea.string = {};
        end
end

if (loadThisEmbeddedInstance) then
        loadThisEmbeddedInstance = nil;


------------------------------------------------------------------------------
        --[[ Function Definitions - User Functions ]]--
------------------------------------------------------------------------------

        --
        -- byte(string)
        --
        --      Converts a character to its bytecode
        --
        -- Args:
        --      string - the string
        --
        -- Returns:
        --      (string)
        --      string - the string in byte code with format <##>
        --
        Sea.string.byte = function(c)
                return string.format("<%02X>",string.byte(c));
        end

        --
        --      byteSum (string s)
        --              returns the bytecode sum for s
        --
        -- Args:
        --      s - the string
        --
        -- Returns:
        --      (number)
        --      number - the value of the string with all of its
        --      chars summed together. 
        --              
        
        Sea.string.byteSum = function(s)
                local sum = 0;
                local len = string.len(s);
                local sbyte = string.byte;
                for i=1,len do
                        sum = sum + sbyte(s,i);
                end
                return sum;
        end
        
        --
        -- toInt (string s)
        --
        --      Converts the specified string to an int
        --
        -- Returns: 
        --      (Number int)
        --      int - the string S as a number
        --
        Sea.string.toInt = tonumber;

        -- 
        -- fromTime(Number time, Number decimalplaces)
        --
        --      Creates a readable time from a number time in WoW
        --      Decimal places gives the number of .### to display
        --
        -- Returns:
        --      (String timeString)
        --      timeString - the time
        --      
        
        Sea.string.fromTime = function (time, decimalplaces)
                if (time < 0)   then
                        time = 0;
                end
                if ( not decimalplaces ) then 
                        decimalplaces = 0;
                end
                
                local floor = math.floor;
                local mod = math.mod;
                
                local seconds = mod(time, 60);
                local minutes = mod(floor(time/60), 60);
                local hours = floor(time/(3600));
                local spfx = '';
                if (seconds < 10) then
                        spfx = '0';
                end
                
                if (hours > 0) then
                        return string.format("%d:%.2d:%s%."..decimalplaces.."f", hours, minutes, spfx, seconds);
                else
                        return string.format("%d:%s%."..decimalplaces.."f", minutes, spfx, seconds);
                end
        end
        
        --
        -- capitalizeWords(String phrase)
        --
        --      Takes a string like "hello world" and turns 
        --      it into "Hello World". 
        --
        -- Returns:
        --      (String capitalizedPhrase)
        -- 
        
        Sea.string.capitalizeWords = function ( text )
                if (not text) then
                        return text;
                end
                local capitalizedPhrase = "";
                local value, mend;
                local mstart = 1;
                local regexKey = "([^%s]+[%s]*)";
                local sfind = strfind;  -- string.find if not in WoW (n calls)
                local supper = strupper;
                local slower = strlower;
                local ssub = strsub;
                
                -- Using string.find instead of string.gfind to avoid garbage generation
                mstart, mend, value = sfind(text, regexKey, mstart);
                while (value) do
                        if( sfind(text, "^[a-zA-Z].*") ) then
                                capitalizedPhrase = capitalizedPhrase..supper(ssub(value,1,1))..slower(ssub(value,2));
                        else
                                capitalizedPhrase = capitalizedPhrase..supper(ssub(value,1,2))..slower(ssub(value,3));
                        end
                        mstart = mend + 1;
                        mstart, mend, value = sfind(text, regexKey, mstart);
                end             

                return capitalizedPhrase;
        end


        --
        -- objectToString( value, [name] )
        --
        --      Converts a value to a serialized string. 
        --      Cannot serialize functions.
        --      
        -- returns:
        --      A string which represents the object, 
        --      minus functions. 
        --      
        -- 
        Sea.string.objectToString = function( value, name ) 
                local output = "";

                if ( name == nil ) then name = ""; 
                else
                        -- Serialize the name
                        name = Sea.string.objectToString(name);
                        -- Remove the <>
                        name = string.gsub(name, "<(.*)>", "%1");
                end
                
                if (type(value) == "nil" ) then 
                        output = name.."<".."nil:nil"..">";
                elseif ( type(value) == "string" ) then
                        value = string.gsub(value, "<", "&lt;");
                        value = string.gsub(value, ">", "&gt;");
                        output = name.."<".."s:"..value..">";
                elseif ( type(value) == "number" ) then
                        output = name.."<".."n:"..value..">";
                elseif ( type(value) == "boolean" ) then
                        if ( value ) then 
                                output = name.."<".."b:".."true"..">";
                        else
                                output = name.."<".."b:".."false"..">";
                        end
                elseif ( type(value) == "function" ) then
                        output = name.."<".."func:".."*invalid*"..">";
                elseif ( type(value) == "table" ) then
                        output = name.."<".."t:";
                        for k,v in value do 
                                output = output.." "..Sea.string.objectToString(v,k);
                        end
                        output = output .. ">";
                end

                return output;
        end

        --
        -- stringToObject(string)
        --
        --      Turns a string serialized by objectToString into 
        --      and object. 
        --
        -- returns:
        --      nil or number or string or boolean or table
        --
        --
        Sea.string.stringToObject = function ( str ) 
                -- check for the format "keytype:keyvalue<valuetype:value>"
                -- take the stuff in <>
                typevalue = string.gsub(str, "%s*(%w*:?%w*)%s*(<.*>)","%2");
        
                local value = nil;
                local typeString = string.gsub(typevalue, "<%s*(%w*):(.*)>","%1");
                local valueString = string.gsub(typevalue, "<%s*(%w*):(.*)>","%2");

                
                --print("str: ", str, " typevalue: ", typevalue);
                --print("valueString: (", valueString, ") typeString: (", typeString,")");

                -- Error!
                if ( typeString == typevalue ) then 
                        Sea.io.error ( "Unparsable string passed to stringToObject: ", str );
                        return nil;
                end
        
                -- Maybe no error!
                if ( typeString == "nil" ) then 
                        value = nil;
                
                elseif ( typeString == "n" ) then 
                        value = tonumber(valueString);
        
                elseif ( typeString == "b" ) then 
                        if ( valueString == "true" ) then
                                value = true;
                        else
                                value = false;
                        end
                
                elseif ( typeString == "s" ) then 
                        value = valueString;
                        -- Parse the <> back in
                        value = string.gsub(value, "&lt;", "<");
                        value = string.gsub(value, "&gt;", ">");

                elseif ( typeString == "f" ) then
                        -- Functions are not supported, but if they were..

                        -- ...this is how it should work
                        -- value = getglobal(typeString);
                        value = Sea.io.error;
                
                elseif ( typeString == "t" ) then 
                        -- Here's the hard part
                        -- I have to extract each set of <>
                        -- which might have nested tables!
                        -- 
                        -- So I start off by tracking < until I get 0
                        --
                        value = {};

                        local left = 1;
                        local right = 1;

                        local count = 0;
                        
                        while ( valueString and valueString ~= "" ) do
                                local object = nil;
                                local key = nil;

                                -- Extract the key and convert it
                                key = string.gsub(valueString, "%s*(%w*:?.-)<.*>", "%1" );
                                key = Sea.string.stringToObject("<"..key..">");

                        
                                left = string.find(valueString, "<", 1 );
                                right = string.find(valueString, ">", 1 );

                                if ( left < right ) then 
                                        nextleft = string.find(valueString, "<", left+1 );
                                        while ( nextleft and nextleft < right ) do
                                                nextleft = string.find(valueString, "<", nextleft+1 );
                                                right = string.find(valueString, ">", right+1 );
                                        end
                                else
                                        --error ( "we all die." );
                                end

                                objectString = string.sub(valueString, left, right);
                        
                                -- Create the object
                                object = Sea.string.stringToObject(objectString);

                                -- Add it to the table
                                value[key] = object;

                                -- See if there's another entry
                                valueString = string.sub(valueString, right+1);
                        end
                end

                return value;
        end
        
        --
        -- startsWith(String text, String prefix)
        --
        --      Looks for 'prefix' at the beginning of 'text' 
        --
        -- Returns:
        --      boolean
        -- 
        
        Sea.string.startsWith = function ( text, prefix )
                if ( strfind(text, "^"..prefix, 1) ) then
                        return true;
                else
                        return false;
                end
        end
        
        --
        -- endsWith(String text, String suffix)
        --
        --      Looks for 'suffix' at the end of 'text' 
        --
        -- Returns:
        --      boolean
        -- 
        
        Sea.string.endsWith = function ( text, suffix )
                if ( strfind(text, suffix.."$") ) then
                        return true;
                else
                        return false;
                end
        end

        --
        -- colorToString(Table{r,g,b,a})
        --
        --      Converts a table to a Blizzard color code
        --
        -- Returns:
        --      string 
        --              The blizzard color code AARRGGBB
        -- 
        
        Sea.string.colorToString = function ( color )
                if ( not color ) then 
                        return "FFFFFFFF";
                end
                return string.format("%.2X%.2X%.2X%.2X",
                        (color.a or color.opacity or 1) * 255,
                        (color.r or 0) * 255, 
                        (color.g or 0) * 255, 
                        (color.b or 0) * 255
                );
        end

        -- stringToColor(String colorCode)
        --
        --      Converts a Blizzard color code to a table
        --
        -- Returns:
        --      table{r,g,b,a,opacity}
        --
        --      a & opacity are the same thing here (this could change)
        -- 
        Sea.string.stringToColor = function ( colorCode ) 
                local red, green, blue, alpha = Sea.math.rgbaFromHex( colorCode );
                return { r = red; g = green; b = blue; a = alpha; opacity = alpha };
        end

        
end