I6 Template Layer

Inform 7 6M62ContentsIntroductionFunction IndexRules Index

Char.i6t

Char contents

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.

15[ CharIsOfCase c case 16    i tab min max len par; 17    if (c<'A') rfalse; 18    if (case == 0) { 19        if ((c >= 'a') && (c <= 'z')) rtrue; 20        tab = CharCasingChart0; 21    } else { 22        if ((c >= 'A') && (c <= 'Z')) rtrue; 23        tab = CharCasingChart1; 24    } 25    if (c<128) rfalse; 26    while (tab-->i) { 27        min = tab-->i; i++; 28        len = tab-->i; i++; 29        i++; 30        par = 0; 31        if (len<0) { par = 1; len = -len; } 32        if (c < min) rfalse; 33        if (c < min+len) { 34            if (par) { if ((c-min) % 2 == 0) rtrue; } 35            else { rtrue; } 36        } 37    } 38    rfalse; 39];

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.

46[ CharToCase c case 47    i tab min max len par del f; 48    if (c<'A') return c; 49    if (case == 1) { 50        if ((c >= 'a') && (c <= 'z')) return c-32; 51        tab = CharCasingChart0; 52    } else { 53        if ((c >= 'A') && (c <= 'Z')) return c+32; 54        tab = CharCasingChart1; 55    } 56    if (c<128) return c; 57    while (tab-->i) { 58        min = tab-->i; i++; 59        len = tab-->i; i++; 60        del = tab-->i; i++; 61        par = 0; 62        if (len<0) { par = 1; len = -len; } 63        if (c < min) return c; 64        if (c < min+len) { 65            f = false; 66            if (par) { if ((c-min) % 2 == 0) f = true; } 67            else { f = true; } 68            if (f) { 69                if (del == UNIC_NCT) return c; 70                return c+del; 71            } 72        } 73    } 74    return c; 75];

Reversing Case.

It's convenient to provide this relatively fast routine to reverse the case of a letter since this is an operation used frequently in regular expression matching (see RegExp.i6t).

83#IFDEF TARGET_ZCODE; 84[ TEXT_TY_RevCase ch; 85    if (ch<'A') return ch; 86    if ((ch >= 'a') && (ch <= 'z')) return ch-'a'+'A'; 87    if ((ch >= 'A') && (ch <= 'Z')) return ch-'A'+'a'; 88    if (ch<128) return ch; 89    if ((ch >= 155) && (ch <= 157)) return ch+3; ! a, o, u umlaut in ZSCII 90    if ((ch >= 158) && (ch <= 160)) return ch-3; ! A, O, U umlaut 91    if ((ch >= 164) && (ch <= 165)) return ch+3; ! e, i umlaut 92    if ((ch >= 167) && (ch <= 168)) return ch-3; ! E, I umlaut 93    if ((ch >= 169) && (ch <= 174)) return ch+6; ! a, e, i, o, u, y acute 94    if ((ch >= 175) && (ch <= 180)) return ch-6; ! A, E, I, O, U, Y acute 95    if ((ch >= 181) && (ch <= 185)) return ch+5; ! a, e, i, o, u grave 96    if ((ch >= 186) && (ch <= 190)) return ch-5; ! A, E, I, O, U grave 97    if ((ch >= 191) && (ch <= 195)) return ch+5; ! a, e, i, o, u circumflex 98    if ((ch >= 196) && (ch <= 200)) return ch-5; ! A, E, I, O, U circumflex 99    if (ch == 201) return 202; ! a circle 100    if (ch == 202) return 201; ! A circle 101    if (ch == 203) return 204; ! o slash 102    if (ch == 204) return 203; ! O slash 103    if ((ch >= 205) && (ch <= 207)) return ch+3; ! a, n, o tilde 104    if ((ch >= 208) && (ch <= 210)) return ch-3; ! A, N, O tilde 105    if (ch == 211) return 212; ! ae ligature 106    if (ch == 212) return 211; ! AE ligature 107    if (ch == 213) return 214; ! c cedilla 108    if (ch == 214) return 213; ! C cedilla 109    if (ch == 215 or 216) return ch+2; ! thorn, eth 110    if (ch == 217 or 218) return ch-2; ! Thorn, Eth 111    if (ch == 220) return 221; ! oe ligature 112    if (ch == 221) return 220; ! OE ligature 113    return ch; 114]; 115#IFNOT; 116[ TEXT_TY_RevCase ch; 117    if (ch<'A') return ch; 118    if ((ch >= 'a') && (ch <= 'z')) return ch-'a'+'A'; 119    if ((ch >= 'A') && (ch <= 'Z')) return ch-'A'+'a'; 120    if (ch<128) return ch; 121    if (CharIsOfCase(ch, 0)) return CharToCase(ch, 1); 122    if (CharIsOfCase(ch, 1)) return CharToCase(ch, 0); 123    return ch; 124]; 125#ENDIF;

Testing.

Not actually used: simply for testing the tables.

131[ CharTestCases case i j; 132    for (i=32: i<$E0; i++) { 133        if ((i>=127) && (i<155)) continue; 134        print i, " - ", (char) i, " -"; 135        if (CharIsOfCase(i, 0)) print " lower"; 136        if (CharIsOfCase(i, 1)) print " upper"; 137        j = CharToCase(i, 0); if (j ~= i) print " tolower: ", (char) j; 138        j = CharToCase(i, 1); if (j ~= i) print " toupper: ", (char) j; 139        print "^"; 140    } 141];