diff options
author | bptato <nincsnevem662@gmail.com> | 2021-08-05 17:05:20 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2021-08-05 17:05:20 +0200 |
commit | 69a0f081e6eefdd6a52b0da6586100349b1a6ea8 (patch) | |
tree | 23a61bc20918809fb99927071feca01a55e37c92 /src/utils/twtstr.nim | |
parent | caad7b577162a73524277a943050493c489bfb59 (diff) | |
download | chawan-69a0f081e6eefdd6a52b0da6586100349b1a6ea8.tar.gz |
more stuff
Diffstat (limited to 'src/utils/twtstr.nim')
-rw-r--r-- | src/utils/twtstr.nim | 105 |
1 files changed, 101 insertions, 4 deletions
diff --git a/src/utils/twtstr.nim b/src/utils/twtstr.nim index d5de3eef..29a38c59 100644 --- a/src/utils/twtstr.nim +++ b/src/utils/twtstr.nim @@ -1,6 +1,10 @@ import terminal import strutils import unicode +import tables +import json +import sugar +import sequtils func ansiStyle*(str: string, style: Style): seq[string] = result &= ansiStyleCode(style) @@ -321,12 +325,12 @@ func makewidthtable(): array[0..0x10FFFF, byte] = else: result[ucs] = 1 -when defined(small): - # compute lookup table on startup - let width_table = makewidthtable() -else: +when defined(full): # store lookup table in executable const width_table = makewidthtable() +else: + # compute lookup table on startup + let width_table = makewidthtable() {.push boundChecks:off.} func width*(r: Rune): int = @@ -453,3 +457,96 @@ func mk_wcswidth_cjk(s: string): int = for r in s.runes: result += mk_wcwidth_cjk(r) return result + +const CanHaveDakuten = "かきくけこさしすせそたちつてとはひふへほカキクケコサシスセソタチツテトハヒフヘホ".toRunes() + +const CanHaveHandakuten = "はひふへほハヒフヘホ".toRunes() + +const HasDakuten = "がぎぐげござじずぜぞだぢづでどばびぶべぼガギグゲゴザジゼゾダヂヅデドバビブベボ".toRunes() + +const HasHanDakuten = "ぱぴぷぺぽパピプペポ".toRunes() + +#in unicode, char + 1 is dakuten and char + 2 handakuten +#゙゚ + +const Dakuten = "゙".toRunes()[0] +const HanDakuten = "゚".toRunes()[0] + +func dakuten*(r: Rune): Rune = + if r in CanHaveDakuten: + return cast[Rune](cast[int](r) + 1) + return r + +func handakuten*(r: Rune): Rune = + if r in CanHaveHandakuten: + return cast[Rune](cast[int](r) + 2) + +func nodakuten*(r: Rune): Rune = + return cast[Rune](cast[int](r) - 1) + +func nohandakuten*(r: Rune): Rune = + return cast[Rune](cast[int](r) - 2) + +# Halfwidth to fullwidth & vice versa +const widthconv = staticRead"../../res/widthconv.json" +proc genHalfWidthTable(): Table[Rune, Rune] = + let widthconvjson = parseJson(widthconv) + for k, v in widthconvjson: + if v.kind == JString: + result[v.getStr().toRunes()[0]] = k.toRunes()[0] + else: + for s in v: + result[s.getStr().toRunes()[0]] = k.toRunes()[0] + +proc genFullWidthTable(): Table[Rune, Rune] = + let widthconvjson = parseJson(widthconv) + for k, v in widthconvjson: + if v.kind == JString: + result[k.toRunes()[0]] = v.getStr().toRunes()[0] + else: + result[k.toRunes()[0]] = v[0].getStr().toRunes()[0] + +const halfwidthtable = genHalfWidthTable() +const fullwidthtable = genFullWidthTable() + +func halfwidth*(r: Rune): Rune = + return halfwidthtable.getOrDefault(r, r) + +func halfwidth*(s: seq[Rune]): seq[Rune] = + for r in s: + #TODO implement a setting to enable this, I personally dislike it + #if r in HasDakuten: + # result.add(halfwidth(r.nodakuten())) + # result.add(Dakuten) + #elif r in HasHanDakuten: + # result.add(halfwidth(r.nohandakuten())) + # result.add(HanDakuten) + #else: + result.add(halfwidth(r)) + +func halfwidth*(s: string): string = + return $halfwidth(s.toRunes()) + +func fullwidth*(r: Rune): Rune = + return fullwidthtable.getOrDefault(r, r) + +proc fullwidth*(s: seq[Rune]): seq[Rune] = + for r in s: + if r == Rune(0xFF9E): #dakuten + if result.len > 0: + result[^1] = result[^1].dakuten() + else: + result.add(r) + elif r == Rune(0xFF9F): #handakuten + if result.len > 0: + result[^1] = result[^1].handakuten() + else: + result.add(r) + else: + result.add(fullwidth(r)) + +proc fullwidth*(s: string): string = + return $fullwidth(s.toRunes()) + +echo (halfwidth("とうギょう")) +echo "東京" |