diff options
author | Arne Döring <arne.doering@gmx.net> | 2018-11-04 20:52:20 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-11-08 20:52:22 +0100 |
commit | 795d7e3217bafee94af9c69374428b63d586eb2d (patch) | |
tree | 2db17ef617afa65adf61db45e9fc69f606c1d0b0 /lib/std | |
parent | 6a57ec6d2ea85ebc279eaf0bea4efd81da8b6a06 (diff) | |
download | Nim-795d7e3217bafee94af9c69374428b63d586eb2d.tar.gz |
WIP
Diffstat (limited to 'lib/std')
-rw-r--r-- | lib/std/wordwrap.nim | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/lib/std/wordwrap.nim b/lib/std/wordwrap.nim new file mode 100644 index 000000000..ce5598de8 --- /dev/null +++ b/lib/std/wordwrap.nim @@ -0,0 +1,124 @@ +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 = + + var currentWordLength: int = 0 + var currentWord: string = newStringOfCap(32) + var currentLineLength: int = 0 + var currentWordLineEndMark: int = -1 + var currentWordLengthAtLineEnd: int = -1 + + 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 + + if currentLineLength > 0: + result.add ' ' + currentLineLength += 1 + + result.add currentWord + currentLineLength += currentWordLength + + currentWord.setlen 0 + currentWordLength = 0 + + currentWordLineEndMark = -1 + + for rune in s.runes: + if rune.isWhiteSpace: + handleWhitespace() + else: + 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) + + +import strutils + +echo strutils.wordWrap(tmp, splitLongWords=true) +echo strutils.wordWrap(tmp, splitLongWords=false) + + # 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) |