To decide whether letters are upper or lower case, and convert between the two.
§1. Char Is Of Case. The following decides whether a character c belongs to case case, where 0 means lower case and 1 means upper. c is interpreted according to the character casing chart in "UnicodeData.i6t", which means, it will be ZSCII for the Z-machine and Unicode for Glulx.
[ CharIsOfCase c case i tab min max len par; if (c<'A') rfalse; if (case == 0) { if ((c >= 'a') && (c <= 'z')) rtrue; tab = CharCasingChart0; } else { if ((c >= 'A') && (c <= 'Z')) rtrue; tab = CharCasingChart1; } if (c<128) rfalse; while (tab-->i) { min = tab-->i; i++; len = tab-->i; i++; i++; par = 0; if (len<0) { par = 1; len = -len; } if (c < min) rfalse; if (c < min+len) { if (par) { if ((c-min) % 2 == 0) rtrue; } else { rtrue; } } } rfalse; ];
§2. Char To Case. And the following converts character c to the desired case, or returns it unchanged if it is not a letter with variant casings.
[ CharToCase c case i tab min max len par del f; if (c<'A') return c; if (case == 1) { if ((c >= 'a') && (c <= 'z')) return c-32; tab = CharCasingChart0; } else { if ((c >= 'A') && (c <= 'Z')) return c+32; tab = CharCasingChart1; } if (c<128) return c; while (tab-->i) { min = tab-->i; i++; len = tab-->i; i++; del = tab-->i; i++; par = 0; if (len<0) { par = 1; len = -len; } if (c < min) return c; if (c < min+len) { f = false; if (par) { if ((c-min) % 2 == 0) f = true; } else { f = true; } if (f) { if (del == UNIC_NCT) return c; return c+del; } } } return c; ];
§3. DigitToValue. This takes a ZSCII or Unicode character code and returns its value as a digit, or returns \(-1\) if it isn't a digit.
[ DigitToValue c base n; if (base == 0) { n = c-'0'; if ((n<0) || (n>9)) return -1; return n; } if ((c >= '0') && (c <= '9')) n = c - '0'; else if ((c >= 'a') && (c <= 'z')) n = c - 'a' + 10; else if ((c >= 'A') && (c <= 'Z')) n = c - 'A' + 10; else return -1; if (n < base) return n; return -1; ];
§4. Testing. Not actually used: simply for testing the tables.
[ CharTestCases case i j; for (i=32: i<$E0: i++) { if ((i>=127) && (i<155)) continue; print i, " - ", (char) i, " -"; if (CharIsOfCase(i, 0)) print " lower"; if (CharIsOfCase(i, 1)) print " upper"; j = CharToCase(i, 0); if (j ~= i) print " tolower: ", (char) j; j = CharToCase(i, 1); if (j ~= i) print " toupper: ", (char) j; print "^"; } ];
[ UNICODE_CHARACTER_TY_Say c; print "unicode U+"; PrintInBase(c, 16, 4); ];