swwmgz_m/zscript/utility/swwm_utility_string.zsc

161 lines
4.5 KiB
Text

// string-related functions
extend Class SWWMUtility
{
// bit ugly, but it works
static void ThousandsStr( String &s, int col = Font.CR_UNDEFINED, String colstr = "" )
{
if ( (col < Font.CR_UNDEFINED) || (col >= Font.NUM_TEXT_COLORS) )
ThrowAbortException("col parameter out of range, use colstr for non-standard font colors.");
String nstr = s;
s.Truncate(0);
int len = nstr.CodePointCount();
int t = len;
if ( nstr.Left(1) == "-" ) t++;
for ( int i=0, pos=0; i<len; i++ )
{
int ch;
[ch, pos] = nstr.GetNextCodePoint(pos);
s.AppendCharacter(ch);
t = (t-1)%3;
if ( (pos < len) && !t )
{
if ( colstr != "" ) s.AppendFormat("\c[%s],\c-",colstr);
else if ( col != Font.CR_UNDEFINED ) s.AppendFormat("\c%c,\c-",0x61+col);
else s.AppendCharacter(0x2C);
}
}
}
static String ThousandsNum( int n, int col = Font.CR_UNDEFINED, String colstr = "", int digits = 0 )
{
String nstr;
if ( digits > 0 ) nstr = String.Format("%0*d",digits,n);
else nstr = String.Format("%d",n);
ThousandsStr(nstr,col,colstr);
return nstr;
}
static void StripColor( String &str )
{
int len = str.CodePointCount();
for ( int i=0, pos=0; i<len; i++ )
{
int remlen = 0;
int cplen = 0;
int ch, nxt;
[ch, nxt] = str.GetNextCodePoint(pos);
if ( ch != 0x1C )
{
pos = nxt;
continue;
}
remlen++;
cplen++;
[ch, nxt] = str.GetNextCodePoint(pos+remlen);
if ( ch == 0x5B )
{
int ch2;
do
{
[ch2, nxt] = str.GetNextCodePoint(pos+remlen);
remlen += nxt-(pos+remlen);
cplen++;
}
while ( ch2 != 0x5D );
}
remlen++;
str.Remove(pos,remlen);
len -= cplen;
i--;
}
}
static String SuperscriptNum( int val )
{
// unicode is fun
static const int digs[] = {0x2070,0x00B9,0x00B2,0x00B3,0x2074,0x2075,0x2076,0x2077,0x2078,0x2079};
String str = String.Format("%d",val);
int len = str.CodePointCount();
String newstr = "";
for ( int i=0, pos=0; i<len; i++ )
{
int ch;
[ch, pos] = str.GetNextCodePoint(pos);
if ( (ch >= 0x0030) || (ch <= 0x0039) ) newstr.AppendCharacter(digs[ch-0x0030]);
else if ( ch == 0x002D ) newstr.AppendCharacter(0x207A); // minus
// everything else gets ignored
}
return newstr;
}
static void ObscureText( String &str, int seed, bool alnum = false, bool minihud = false )
{
int len = str.CodePointCount();
String newstr = "";
for ( int i=0, pos=0; i<len; i++ )
{
seed = ((seed<<1)*35447+(seed/87));
int ch;
[ch, pos] = str.GetNextCodePoint(pos);
if ( (ch == 0x20) || (ch == 0x09) || (ch == 0x0A) )
newstr.AppendCharacter(ch);
else if ( alnum )
{
// only uppercase letters and numbers
int sd = abs(seed%36);
if ( sd >= 10 ) sd += 7;
newstr.AppendCharacter(sd+48);
}
else if ( minihud )
{
// exclude forward/backward slashes as they're wider
int sd = abs(seed%93);
if ( sd >= 15 ) sd++;
if ( sd >= 60 ) sd++;
newstr.AppendCharacter(sd+32);
}
else newstr.AppendCharacter((abs(seed)%95)+32);
}
str = newstr;
}
static void BeautifyClassName( String &str )
{
String workstr = str;
str.Truncate(0);
workstr.Replace("_"," ");
int len = workstr.CodePointCount();
for ( int i=0, pos=0; i<len; i++ )
{
int cp1;
[cp1, pos] = workstr.GetNextCodePoint(pos);
str.AppendCharacter(cp1);
if ( cp1 == 0x20 ) continue; // already spaced
if ( i < len-1 )
{
let [cp2, pos2] = workstr.GetNextCodePoint(pos);
if ( cp2 == 0x20 ) continue; // already spaced
// this looks awkward, but I have to also account for non-letter characters
// uppercase after lowercase
if ( (String.CharUpper(cp1) != cp1) && (String.CharLower(cp2) != cp2) )
str.AppendCharacter(0x20);
// uppercase after non-letter
else if ( (String.CharUpper(cp1) == cp1) && (String.CharLower(cp1) == cp1) && (String.CharLower(cp2) != cp2) )
str.AppendCharacter(0x20);
// lowercase after non-letter
if ( (String.CharUpper(cp1) == cp1) && (String.CharLower(cp1) == cp1) && (String.CharUpper(cp2) != cp2) )
str.AppendCharacter(0x20);
// non-letter after lowercase
else if ( (String.CharUpper(cp1) != cp1) && (String.CharLower(cp2) == cp2) && (String.CharUpper(cp2) == cp2) )
str.AppendCharacter(0x20);
if ( i < len-2 )
{
let [cp3, pos3] = workstr.GetNextCodePoint(pos2);
if ( cp3 == 0x20 ) continue; // already spaced
// uppercase before uppercase before lowercase
if ( (String.CharLower(cp1) != cp1) && (String.CharLower(cp2) != cp2) && (String.CharUpper(cp3) != cp3) )
str.AppendCharacter(0x20);
}
}
}
}
}