vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 --[[
2  
3 Sea String (mostly Sea.string)
4  
5 A Mini-Library for string functions.
6  
7 Compiler:
8 AnduinLothar (karlkfi@cosmosui.org)
9  
10 Contributors:
11 Thott (thott@thottbot.com)
12 Legorol (legorol@cosmosui.org)
13 Mugendai (mugekun@gmail.com)
14 Iriel (iriel@vigilance-committee.org)
15  
16  
17 ==Installation/Utilization==
18  
19 Embedding:
20 - Drop the SeaString folder into your Interface\AddOns\YourAddon\ folder
21 - Add Sea and SeaString as optional dependancies
22 - Add the following line to the end of your TOC file, before your addon files:
23 SeaString\SeaString.lua
24  
25 Standard:
26 - Drop the SeaString folder into your Interface\AddOns\ directory
27 - Add SeaString as a required dependancy
28  
29  
30 Change Log:
31 v0.2
32 - Changed lua file name
33 v0.1 (Alpha)
34 - SeaString Forked into Mini-Library from the main Sea. Still backwards compatible.
35  
36  
37 $LastChangedBy: karlkfi $
38 $Rev: 2577 $
39 $Date: 2005-10-10 14:44:01 -0700 (Mon, 10 Oct 2005) $
40 ]]--
41  
42 local SEA_STRING_VERSION = 0.11;
43 local loadThisEmbeddedInstance;
44 SEA_STRING_DEBUG = nil;
45 ------------------------------------------------------------------------------
46 --[[ Embedded Sub-Library Load Algorithm ]]--
47 ------------------------------------------------------------------------------
48  
49 if(not Sea) then
50 Sea = {};
51 Sea.versions = {};
52 Sea.versions.SeaString = SEA_STRING_VERSION;
53 loadThisEmbeddedInstance = true;
54 Sea.string = {};
55 else
56 if(not Sea.versions) then
57 Sea.versions = {};
58 end
59 if (not Sea.versions.SeaString) or (Sea.versions.SeaString < SEA_STRING_VERSION) then
60 Sea.versions.SeaString = SEA_STRING_VERSION;
61 loadThisEmbeddedInstance = true;
62 end
63 if(not Sea.string) then
64 Sea.string = {};
65 end
66 end
67  
68 if (loadThisEmbeddedInstance) then
69 loadThisEmbeddedInstance = nil;
70  
71  
72 ------------------------------------------------------------------------------
73 --[[ Function Definitions - User Functions ]]--
74 ------------------------------------------------------------------------------
75  
76 --
77 -- byte(string)
78 --
79 -- Converts a character to its bytecode
80 --
81 -- Args:
82 -- string - the string
83 --
84 -- Returns:
85 -- (string)
86 -- string - the string in byte code with format <##>
87 --
88 Sea.string.byte = function(c)
89 return string.format("<%02X>",string.byte(c));
90 end
91  
92 --
93 -- byteSum (string s)
94 -- returns the bytecode sum for s
95 --
96 -- Args:
97 -- s - the string
98 --
99 -- Returns:
100 -- (number)
101 -- number - the value of the string with all of its
102 -- chars summed together.
103 --
104  
105 Sea.string.byteSum = function(s)
106 local sum = 0;
107 local len = string.len(s);
108 local sbyte = string.byte;
109 for i=1,len do
110 sum = sum + sbyte(s,i);
111 end
112 return sum;
113 end
114  
115 --
116 -- toInt (string s)
117 --
118 -- Converts the specified string to an int
119 --
120 -- Returns:
121 -- (Number int)
122 -- int - the string S as a number
123 --
124 Sea.string.toInt = tonumber;
125  
126 --
127 -- fromTime(Number time, Number decimalplaces)
128 --
129 -- Creates a readable time from a number time in WoW
130 -- Decimal places gives the number of .### to display
131 --
132 -- Returns:
133 -- (String timeString)
134 -- timeString - the time
135 --
136  
137 Sea.string.fromTime = function (time, decimalplaces)
138 if (time < 0) then
139 time = 0;
140 end
141 if ( not decimalplaces ) then
142 decimalplaces = 0;
143 end
144  
145 local floor = math.floor;
146 local mod = math.mod;
147  
148 local seconds = mod(time, 60);
149 local minutes = mod(floor(time/60), 60);
150 local hours = floor(time/(3600));
151 local spfx = '';
152 if (seconds < 10) then
153 spfx = '0';
154 end
155  
156 if (hours > 0) then
157 return string.format("%d:%.2d:%s%."..decimalplaces.."f", hours, minutes, spfx, seconds);
158 else
159 return string.format("%d:%s%."..decimalplaces.."f", minutes, spfx, seconds);
160 end
161 end
162  
163 --
164 -- capitalizeWords(String phrase)
165 --
166 -- Takes a string like "hello world" and turns
167 -- it into "Hello World".
168 --
169 -- Returns:
170 -- (String capitalizedPhrase)
171 --
172  
173 Sea.string.capitalizeWords = function ( text )
174 if (not text) then
175 return text;
176 end
177 local capitalizedPhrase = "";
178 local value, mend;
179 local mstart = 1;
180 local regexKey = "([^%s]+[%s]*)";
181 local sfind = strfind; -- string.find if not in WoW (n calls)
182 local supper = strupper;
183 local slower = strlower;
184 local ssub = strsub;
185  
186 -- Using string.find instead of string.gfind to avoid garbage generation
187 mstart, mend, value = sfind(text, regexKey, mstart);
188 while (value) do
189 if( sfind(text, "^[a-zA-Z].*") ) then
190 capitalizedPhrase = capitalizedPhrase..supper(ssub(value,1,1))..slower(ssub(value,2));
191 else
192 capitalizedPhrase = capitalizedPhrase..supper(ssub(value,1,2))..slower(ssub(value,3));
193 end
194 mstart = mend + 1;
195 mstart, mend, value = sfind(text, regexKey, mstart);
196 end
197  
198 return capitalizedPhrase;
199 end
200  
201  
202 --
203 -- objectToString( value, [name] )
204 --
205 -- Converts a value to a serialized string.
206 -- Cannot serialize functions.
207 --
208 -- returns:
209 -- A string which represents the object,
210 -- minus functions.
211 --
212 --
213 Sea.string.objectToString = function( value, name )
214 local output = "";
215  
216 if ( name == nil ) then name = "";
217 else
218 -- Serialize the name
219 name = Sea.string.objectToString(name);
220 -- Remove the <>
221 name = string.gsub(name, "<(.*)>", "%1");
222 end
223  
224 if (type(value) == "nil" ) then
225 output = name.."<".."nil:nil"..">";
226 elseif ( type(value) == "string" ) then
227 value = string.gsub(value, "<", "&lt;");
228 value = string.gsub(value, ">", "&gt;");
229 output = name.."<".."s:"..value..">";
230 elseif ( type(value) == "number" ) then
231 output = name.."<".."n:"..value..">";
232 elseif ( type(value) == "boolean" ) then
233 if ( value ) then
234 output = name.."<".."b:".."true"..">";
235 else
236 output = name.."<".."b:".."false"..">";
237 end
238 elseif ( type(value) == "function" ) then
239 output = name.."<".."func:".."*invalid*"..">";
240 elseif ( type(value) == "table" ) then
241 output = name.."<".."t:";
242 for k,v in value do
243 output = output.." "..Sea.string.objectToString(v,k);
244 end
245 output = output .. ">";
246 end
247  
248 return output;
249 end
250  
251 --
252 -- stringToObject(string)
253 --
254 -- Turns a string serialized by objectToString into
255 -- and object.
256 --
257 -- returns:
258 -- nil or number or string or boolean or table
259 --
260 --
261 Sea.string.stringToObject = function ( str )
262 -- check for the format "keytype:keyvalue<valuetype:value>"
263 -- take the stuff in <>
264 typevalue = string.gsub(str, "%s*(%w*:?%w*)%s*(<.*>)","%2");
265  
266 local value = nil;
267 local typeString = string.gsub(typevalue, "<%s*(%w*):(.*)>","%1");
268 local valueString = string.gsub(typevalue, "<%s*(%w*):(.*)>","%2");
269  
270  
271 --print("str: ", str, " typevalue: ", typevalue);
272 --print("valueString: (", valueString, ") typeString: (", typeString,")");
273  
274 -- Error!
275 if ( typeString == typevalue ) then
276 Sea.io.error ( "Unparsable string passed to stringToObject: ", str );
277 return nil;
278 end
279  
280 -- Maybe no error!
281 if ( typeString == "nil" ) then
282 value = nil;
283  
284 elseif ( typeString == "n" ) then
285 value = tonumber(valueString);
286  
287 elseif ( typeString == "b" ) then
288 if ( valueString == "true" ) then
289 value = true;
290 else
291 value = false;
292 end
293  
294 elseif ( typeString == "s" ) then
295 value = valueString;
296 -- Parse the <> back in
297 value = string.gsub(value, "&lt;", "<");
298 value = string.gsub(value, "&gt;", ">");
299  
300 elseif ( typeString == "f" ) then
301 -- Functions are not supported, but if they were..
302  
303 -- ...this is how it should work
304 -- value = getglobal(typeString);
305 value = Sea.io.error;
306  
307 elseif ( typeString == "t" ) then
308 -- Here's the hard part
309 -- I have to extract each set of <>
310 -- which might have nested tables!
311 --
312 -- So I start off by tracking < until I get 0
313 --
314 value = {};
315  
316 local left = 1;
317 local right = 1;
318  
319 local count = 0;
320  
321 while ( valueString and valueString ~= "" ) do
322 local object = nil;
323 local key = nil;
324  
325 -- Extract the key and convert it
326 key = string.gsub(valueString, "%s*(%w*:?.-)<.*>", "%1" );
327 key = Sea.string.stringToObject("<"..key..">");
328  
329  
330 left = string.find(valueString, "<", 1 );
331 right = string.find(valueString, ">", 1 );
332  
333 if ( left < right ) then
334 nextleft = string.find(valueString, "<", left+1 );
335 while ( nextleft and nextleft < right ) do
336 nextleft = string.find(valueString, "<", nextleft+1 );
337 right = string.find(valueString, ">", right+1 );
338 end
339 else
340 --error ( "we all die." );
341 end
342  
343 objectString = string.sub(valueString, left, right);
344  
345 -- Create the object
346 object = Sea.string.stringToObject(objectString);
347  
348 -- Add it to the table
349 value[key] = object;
350  
351 -- See if there's another entry
352 valueString = string.sub(valueString, right+1);
353 end
354 end
355  
356 return value;
357 end
358  
359 --
360 -- startsWith(String text, String prefix)
361 --
362 -- Looks for 'prefix' at the beginning of 'text'
363 --
364 -- Returns:
365 -- boolean
366 --
367  
368 Sea.string.startsWith = function ( text, prefix )
369 if ( strfind(text, "^"..prefix, 1) ) then
370 return true;
371 else
372 return false;
373 end
374 end
375  
376 --
377 -- endsWith(String text, String suffix)
378 --
379 -- Looks for 'suffix' at the end of 'text'
380 --
381 -- Returns:
382 -- boolean
383 --
384  
385 Sea.string.endsWith = function ( text, suffix )
386 if ( strfind(text, suffix.."$") ) then
387 return true;
388 else
389 return false;
390 end
391 end
392  
393 --
394 -- colorToString(Table{r,g,b,a})
395 --
396 -- Converts a table to a Blizzard color code
397 --
398 -- Returns:
399 -- string
400 -- The blizzard color code AARRGGBB
401 --
402  
403 Sea.string.colorToString = function ( color )
404 if ( not color ) then
405 return "FFFFFFFF";
406 end
407 return string.format("%.2X%.2X%.2X%.2X",
408 (color.a or color.opacity or 1) * 255,
409 (color.r or 0) * 255,
410 (color.g or 0) * 255,
411 (color.b or 0) * 255
412 );
413 end
414  
415 -- stringToColor(String colorCode)
416 --
417 -- Converts a Blizzard color code to a table
418 --
419 -- Returns:
420 -- table{r,g,b,a,opacity}
421 --
422 -- a & opacity are the same thing here (this could change)
423 --
424 Sea.string.stringToColor = function ( colorCode )
425 local red, green, blue, alpha = Sea.math.rgbaFromHex( colorCode );
426 return { r = red; g = green; b = blue; a = alpha; opacity = alpha };
427 end
428  
429  
430 end
431