wordwrap stuff
This commit is contained in:
parent
795d7e3217
commit
1d7c36bd8c
1 changed files with 22 additions and 85 deletions
|
|
@ -1,18 +1,5 @@
|
||||||
import unicode
|
import unicode
|
||||||
|
|
||||||
proc addSubstrExcl(self: var string, str: string; a,b: int) =
|
|
||||||
## equivalent to ``self.add str.substr(a,b-1)``. Exclusive upper bound.
|
|
||||||
if a > b:
|
|
||||||
echo a, " ", b
|
|
||||||
assert a <= b
|
|
||||||
|
|
||||||
if a < b:
|
|
||||||
let idx = self.len
|
|
||||||
self.setLen idx + b - a
|
|
||||||
copyMem(self[idx].addr, str[a].unsafeAddr, b - a)
|
|
||||||
|
|
||||||
let tmp ="Наши исследования позволяют сделать вывод о том, что субъект выбирает uiaetudtiraeüöätpghiacodöeronfdquiahgoüöädoiaqofhgiaeotrnuiaßqzfgiaoeurnudtitraenuitenruitarenitarenuitarentduiranetduiranetdruianetrnuiaertnuiatdenruiatdrne институциональный психоз. Важность этой функции подчеркивается тем фактом, что объект вызывает эгоцентризм. Самоактуализация аннигилирует генезис. Анима аннигилирует возрастной код. Закон просветляет аутотренинг. Наши исследования позволяют сделать вывод о том, что воспитание заметно осознаёт инсайт."
|
|
||||||
|
|
||||||
proc wordWrap*(s: string, maxLineWidth = 80,
|
proc wordWrap*(s: string, maxLineWidth = 80,
|
||||||
splitLongWords = true,
|
splitLongWords = true,
|
||||||
newLine = "\n"): string =
|
newLine = "\n"): string =
|
||||||
|
|
@ -20,30 +7,15 @@ proc wordWrap*(s: string, maxLineWidth = 80,
|
||||||
var currentWordLength: int = 0
|
var currentWordLength: int = 0
|
||||||
var currentWord: string = newStringOfCap(32)
|
var currentWord: string = newStringOfCap(32)
|
||||||
var currentLineLength: int = 0
|
var currentLineLength: int = 0
|
||||||
var currentWordLineEndMark: int = -1
|
|
||||||
var currentWordLengthAtLineEnd: int = -1
|
var currentWordLengthAtLineEnd: int = -1
|
||||||
|
var longWordMode = false
|
||||||
|
|
||||||
template handleWhitespace(): untyped =
|
template handleWhitespace(): untyped =
|
||||||
if currentWord.len > 0:
|
if currentWord.len > 0:
|
||||||
|
|
||||||
if currentLineLength + 1 + currentWordLength > maxLineWidth:
|
if currentLineLength + 1 + currentWordLength > maxLineWidth:
|
||||||
var splitWord = splitLongWords
|
result.add newLine
|
||||||
if splitLongWords:
|
currentLineLength = 0
|
||||||
# arbitrary minimum length of words to split
|
|
||||||
splitWord = currentWordLength > maxLineWidth div 2
|
|
||||||
if currentWordLengthAtLineEnd <= 3:
|
|
||||||
# does the current word fit in the next line?
|
|
||||||
if currentWordLength <= maxLineWidth:
|
|
||||||
splitWord = false
|
|
||||||
|
|
||||||
if splitWord:
|
|
||||||
result.addSubstrExcl(currentWord, 0, currentWordLineEndMark)
|
|
||||||
result.add newLine
|
|
||||||
result.addSubstrExcl(currentWord, currentWordLineEndMark, currentWord.len)
|
|
||||||
currentLineLength = currentWordLength - currentWordLengthAtLineEnd
|
|
||||||
else:
|
|
||||||
result.add newLine
|
|
||||||
currentLineLength = 0
|
|
||||||
|
|
||||||
if currentLineLength > 0:
|
if currentLineLength > 0:
|
||||||
result.add ' '
|
result.add ' '
|
||||||
|
|
@ -55,70 +27,35 @@ proc wordWrap*(s: string, maxLineWidth = 80,
|
||||||
currentWord.setlen 0
|
currentWord.setlen 0
|
||||||
currentWordLength = 0
|
currentWordLength = 0
|
||||||
|
|
||||||
currentWordLineEndMark = -1
|
|
||||||
|
|
||||||
for rune in s.runes:
|
for rune in s.runes:
|
||||||
if rune.isWhiteSpace:
|
if rune.isWhiteSpace:
|
||||||
handleWhitespace()
|
handleWhitespace()
|
||||||
else:
|
else:
|
||||||
|
if splitLongWords and currentWordLength >= maxLineWidth:
|
||||||
|
handleWhitespace()
|
||||||
|
|
||||||
currentWord.add rune
|
currentWord.add rune
|
||||||
inc currentWordLength
|
inc currentWordLength
|
||||||
|
|
||||||
if splitLongWords:
|
|
||||||
# the word reached the end of the current line
|
|
||||||
if currentLineLength + 1 + currentWordLength == maxLineWidth:
|
|
||||||
assert(currentWordLineEndMark == -1)
|
|
||||||
currentWordLineEndMark = currentWord.len
|
|
||||||
currentWordLengthAtLineEnd = currentWordLength
|
|
||||||
|
|
||||||
# the word reached the end of the next line
|
|
||||||
if currentWordLength - currentWordLengthAtLineEnd == maxLineWidth:
|
|
||||||
# superlong word, stop being smart.
|
|
||||||
result.addSubstrExcl(currentWord, 0, currentWordLineEndMark)
|
|
||||||
result.add newLine
|
|
||||||
|
|
||||||
currentWord.
|
|
||||||
currentWordLineEndMark()
|
|
||||||
currentWordLength = currentWordLength - currentWordLengthAtLineEnd
|
|
||||||
|
|
||||||
handleWhitespace()
|
|
||||||
currentWordLineEndMark = maxLineWidth
|
|
||||||
|
|
||||||
handleWhitespace()
|
handleWhitespace()
|
||||||
|
|
||||||
echo wordWrap(tmp)
|
|
||||||
|
when isMainModule:
|
||||||
|
import strutils
|
||||||
|
|
||||||
|
|
||||||
import strutils
|
proc checkLineLength(arg: string): void =
|
||||||
|
for line in splitlines(arg):
|
||||||
|
var numRunes = 0
|
||||||
|
for rune in runes(line):
|
||||||
|
numRunes += 1
|
||||||
|
|
||||||
echo strutils.wordWrap(tmp, splitLongWords=true)
|
assert numRunes <= 80
|
||||||
echo strutils.wordWrap(tmp, splitLongWords=false)
|
|
||||||
|
|
||||||
# result = newStringOfCap(s.len + s.len shr 6)
|
let longlongword = "abc uitdaeröägfßhydüäpydqfü,träpydqgpmüdträpydföägpydörztdüöäfguiaeowäzjdtrüöäp psnrtuiydrözenrüöäpyfdqazpesnrtulocjtüöäzydgyqgfqfgprtnwjlcydkqgfüöezmäzydydqüüöäpdtrnvwfhgckdumböäpydfgtdgfhtdrntdrntydfogiayqfguiatrnydrntüöärtniaoeydfgaoeiqfglwcßqfgxvlcwgtfhiaoenrsüöäapmböäptdrniaoydfglckqfhouenrtsüöäptrniaoeyqfgulocfqclgwxßqflgcwßqfxglcwrniatrnmüböäpmöäbpümöäbpüöämpbaoestnriaesnrtdiaesrtdniaesdrtnaetdriaoenvlcyfglwckßqfgvwkßqgfvlwkßqfgvlwckßqvlwkgfUIαοιαοιαχολωχσωχνωκψρχκψρτιεαοσηζϵηζιοεννκεωνιαλωσωκνκψρκγτφγτχκγτεκργτιχνκιωχσιλωσλωχξλξλξωχωχξχλωωχαοεοιαεοαεοιαεοαεοιαοεσναοεκνρκψγκψφϵιηαααοε"
|
||||||
# var spaceLeft = maxLineWidth
|
|
||||||
# var lastSep = ""
|
checkLineLength(longlongword.wordWrap)
|
||||||
# for word, isSep in tokenize(s, seps):
|
|
||||||
# if isSep:
|
let tmp ="Наши исследования позволяют сделать вывод о том, что субъект выбирает xxxuiaetudtiraeüöätpghiacodöeronfdquiahgoüöädoiaqofhgiaeotrnuiaßqzfgiaoeurnudtitraenuitenruitarenitarenuitarentduiranetduiranetdruianetrnuiaertnuiatdenruiatdrne институциональный психоз. Важность этой функции подчеркивается тем фактом, что объект вызывает эгоцентризм. Самоактуализация аннигилирует генезис. Анима аннигилирует возрастной код. Закон просветляет аутотренинг. Наши исследования позволяют сделать вывод о том, что воспитание заметно осознаёт инсайт."
|
||||||
# lastSep = word
|
|
||||||
# spaceLeft = spaceLeft - len(word)
|
checkLineLength(tmp.wordWrap)
|
||||||
# continue
|
|
||||||
# if len(word) > spaceLeft:
|
|
||||||
# if splitLongWords and len(word) > maxLineWidth:
|
|
||||||
# result.add(substr(word, 0, spaceLeft-1))
|
|
||||||
# var w = spaceLeft
|
|
||||||
# var wordLeft = len(word) - spaceLeft
|
|
||||||
# while wordLeft > 0:
|
|
||||||
# result.add(newLine)
|
|
||||||
# var L = min(maxLineWidth, wordLeft)
|
|
||||||
# spaceLeft = maxLineWidth - L
|
|
||||||
# result.add(substr(word, w, w+L-1))
|
|
||||||
# inc(w, L)
|
|
||||||
# dec(wordLeft, L)
|
|
||||||
# else:
|
|
||||||
# spaceLeft = maxLineWidth - len(word)
|
|
||||||
# result.add(newLine)
|
|
||||||
# result.add(word)
|
|
||||||
# else:
|
|
||||||
# spaceLeft = spaceLeft - len(word)
|
|
||||||
# result.add(lastSep & word)
|
|
||||||
# lastSep.setLen(0)
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue