blob: ed498e6532959e50b9945ead10071ddc19b27547 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
use strings;
export fn runewidth(r: rune) uint = {
let ru = r: u32;
// emoticons: https://en.wikipedia.org/wiki/Emoticons_(Unicode_block)
if (ru >= '\U0001F600' && ru <= '\U0001F64F') {
return 2;
};
// hiragana: https://en.wikipedia.org/wiki/Hiragana_%28Unicode_block%29
if (ru >= '\U00003040' && ru <= '\U0000309F') {
return 2;
};
// katakana: https://en.wikipedia.org/wiki/Katakana_(Unicode_block)
if (ru >= '\U000030A0' && ru <= '\U000030FF') {
return 2;
};
// CJK: https://en.wikipedia.org/wiki/CJK_Unified_Ideographs_(Unicode_block)
if (ru >= '\U00004E00' && ru <= '\U00009FFF') {
return 2;
};
return 1;
};
export fn strwidth(s: str) uint = {
const runes = strings::torunes(s);
defer free(runes);
let sum = 0u;
for (let r .. runes) {
sum += runewidth(r);
};
return sum;
};
export fn subwidth(s: str, end: (size | strings::end)) str = {
const runes = strings::torunes(s);
defer free(runes);
let sum = 0u;
for (let i = 0z; i < len(runes); i += 1) {
const r = runes[i];
sum += runewidth(r);
if (sum > end: uint) {
return strings::sub(s, 0, i - 1);
};
};
return s;
};
|