wordwrap stuff

This commit is contained in:
Arne Döring
2018-11-06 08:39:07 +01:00
committed by Andreas Rumpf
parent 795d7e3217
commit 1d7c36bd8c

View File

@@ -1,18 +1,5 @@
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,
splitLongWords = true,
newLine = "\n"): string =
@@ -20,30 +7,15 @@ proc wordWrap*(s: string, maxLineWidth = 80,
var currentWordLength: int = 0
var currentWord: string = newStringOfCap(32)
var currentLineLength: int = 0
var currentWordLineEndMark: int = -1
var currentWordLengthAtLineEnd: int = -1
var longWordMode = false
template handleWhitespace(): untyped =
if currentWord.len > 0:
if currentLineLength + 1 + currentWordLength > maxLineWidth:
var splitWord = splitLongWords
if splitLongWords:
# 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
result.add newLine
currentLineLength = 0
if currentLineLength > 0:
result.add ' '
@@ -55,70 +27,35 @@ proc wordWrap*(s: string, maxLineWidth = 80,
currentWord.setlen 0
currentWordLength = 0
currentWordLineEndMark = -1
for rune in s.runes:
if rune.isWhiteSpace:
handleWhitespace()
else:
if splitLongWords and currentWordLength >= maxLineWidth:
handleWhitespace()
currentWord.add rune
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()
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)
echo strutils.wordWrap(tmp, splitLongWords=false)
assert numRunes <= 80
# result = newStringOfCap(s.len + s.len shr 6)
# var spaceLeft = maxLineWidth
# var lastSep = ""
# for word, isSep in tokenize(s, seps):
# if isSep:
# lastSep = word
# spaceLeft = spaceLeft - len(word)
# 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)
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αοιαοιαχολωχσωχνωκψρχκψρτιεαοσηζϵηζιοεννκεωνιαλωσωκνκψρκγτφγτχκγτεκργτιχνκιωχσιλωσλωχξλξλξωχωχξχλωωχαοεοιαεοαεοιαεοαεοιαοεσναοεκνρκψγκψφϵιηαααοε"
checkLineLength(longlongword.wordWrap)
let tmp ="Наши исследования позволяют сделать вывод о том, что субъект выбирает xxxuiaetudtiraeüöätpghiacodöeronfdquiahgoüöädoiaqofhgiaeotrnuiaßqzfgiaoeurnudtitraenuitenruitarenitarenuitarentduiranetduiranetdruianetrnuiaertnuiatdenruiatdrne институциональный психоз. Важность этой функции подчеркивается тем фактом, что объект вызывает эгоцентризм. Самоактуализация аннигилирует генезис. Анима аннигилирует возрастной код. Закон просветляет аутотренинг. Наши исследования позволяют сделать вывод о том, что воспитание заметно осознаёт инсайт."
checkLineLength(tmp.wordWrap)