fix changing case for Unicode characters which change size (#11271)
Some Unicode characters don't have the same byte length in their upper- and lower-case variants.
This commit is contained in:
parent
468599c654
commit
a63c2a25d0
1 changed files with 16 additions and 9 deletions
|
|
@ -656,13 +656,12 @@ template convertRune(s, runeProc) =
|
||||||
result = newString(len(s))
|
result = newString(len(s))
|
||||||
var
|
var
|
||||||
i = 0
|
i = 0
|
||||||
lastIndex = 0
|
resultIndex = 0
|
||||||
rune: Rune
|
rune: Rune
|
||||||
while i < len(s):
|
while i < len(s):
|
||||||
lastIndex = i
|
|
||||||
fastRuneAt(s, i, rune, doInc=true)
|
fastRuneAt(s, i, rune, doInc=true)
|
||||||
rune = runeProc(rune)
|
rune = runeProc(rune)
|
||||||
rune.fastToUTF8Copy(result, lastIndex)
|
fastToUTF8Copy(rune, result, resultIndex, doInc=true)
|
||||||
|
|
||||||
proc toUpper*(s: string): string {.noSideEffect, procvar,
|
proc toUpper*(s: string): string {.noSideEffect, procvar,
|
||||||
rtl, extern: "nuc$1Str".} =
|
rtl, extern: "nuc$1Str".} =
|
||||||
|
|
@ -689,17 +688,16 @@ proc swapCase*(s: string): string {.noSideEffect, procvar,
|
||||||
|
|
||||||
var
|
var
|
||||||
i = 0
|
i = 0
|
||||||
lastIndex = 0
|
resultIndex = 0
|
||||||
rune: Rune
|
rune: Rune
|
||||||
result = newString(len(s))
|
result = newString(len(s))
|
||||||
while i < len(s):
|
while i < len(s):
|
||||||
lastIndex = i
|
|
||||||
fastRuneAt(s, i, rune)
|
fastRuneAt(s, i, rune)
|
||||||
if rune.isUpper():
|
if rune.isUpper():
|
||||||
rune = rune.toLower()
|
rune = rune.toLower()
|
||||||
elif rune.isLower():
|
elif rune.isLower():
|
||||||
rune = rune.toUpper()
|
rune = rune.toUpper()
|
||||||
rune.fastToUTF8Copy(result, lastIndex)
|
fastToUTF8Copy(rune, result, resultIndex, doInc=true)
|
||||||
|
|
||||||
proc capitalize*(s: string): string {.noSideEffect, procvar,
|
proc capitalize*(s: string): string {.noSideEffect, procvar,
|
||||||
rtl, extern: "nuc$1".} =
|
rtl, extern: "nuc$1".} =
|
||||||
|
|
@ -779,20 +777,19 @@ proc title*(s: string): string {.noSideEffect, procvar,
|
||||||
|
|
||||||
var
|
var
|
||||||
i = 0
|
i = 0
|
||||||
lastIndex = 0
|
resultIndex = 0
|
||||||
rune: Rune
|
rune: Rune
|
||||||
result = newString(len(s))
|
result = newString(len(s))
|
||||||
var firstRune = true
|
var firstRune = true
|
||||||
|
|
||||||
while i < len(s):
|
while i < len(s):
|
||||||
lastIndex = i
|
|
||||||
fastRuneAt(s, i, rune)
|
fastRuneAt(s, i, rune)
|
||||||
if not rune.isWhiteSpace() and firstRune:
|
if not rune.isWhiteSpace() and firstRune:
|
||||||
rune = rune.toUpper()
|
rune = rune.toUpper()
|
||||||
firstRune = false
|
firstRune = false
|
||||||
elif rune.isWhiteSpace():
|
elif rune.isWhiteSpace():
|
||||||
firstRune = true
|
firstRune = true
|
||||||
rune.fastToUTF8Copy(result, lastIndex)
|
fastToUTF8Copy(rune, result, resultIndex, doInc=true)
|
||||||
|
|
||||||
|
|
||||||
iterator runes*(s: string): Rune =
|
iterator runes*(s: string): Rune =
|
||||||
|
|
@ -1468,3 +1465,13 @@ when isMainModule:
|
||||||
doAssert alignLeft("1232", 6) == "1232 "
|
doAssert alignLeft("1232", 6) == "1232 "
|
||||||
doAssert alignLeft("1232", 6, '#'.Rune) == "1232##"
|
doAssert alignLeft("1232", 6, '#'.Rune) == "1232##"
|
||||||
doAssert alignLeft("1232", 6, "×".asRune) == "1232××"
|
doAssert alignLeft("1232", 6, "×".asRune) == "1232××"
|
||||||
|
|
||||||
|
block differentSizes:
|
||||||
|
# upper and lower variants have different number of bytes
|
||||||
|
doAssert toLower("AẞC") == "aßc"
|
||||||
|
doAssert toLower("ȺẞCD") == "ⱥßcd"
|
||||||
|
doAssert toUpper("ⱥbc") == "ȺBC"
|
||||||
|
doAssert toUpper("rsⱦuv") == "RSȾUV"
|
||||||
|
doAssert swapCase("ⱥbCd") == "ȺBcD"
|
||||||
|
doAssert swapCase("XyꟆaB") == "xYᶎAb"
|
||||||
|
doAssert swapCase("aᵹcᲈd") == "AꝽCꙊD"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue