From c308c2e60b472c6ceade2cd319e2fe32fcd1d9a7 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Mon, 8 Jun 2020 14:34:26 +0200 Subject: [PATCH] optimized wrapWords; fixes #14579 (#14606) [backport:1.2] --- lib/std/wordwrap.nim | 73 +++++++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 25 deletions(-) diff --git a/lib/std/wordwrap.nim b/lib/std/wordwrap.nim index 4b0dc4417f..bb6f2dc6fe 100644 --- a/lib/std/wordwrap.nim +++ b/lib/std/wordwrap.nim @@ -11,10 +11,10 @@ import strutils, unicode -proc olen(s: string): int = - var i = 0 +proc olen(s: string; start, lastExclusive: int): int = + var i = start result = 0 - while i < s.len: + while i < lastExclusive: inc result let L = graphemeLen(s, i) inc i, L @@ -32,31 +32,46 @@ proc wrapWords*(s: string, maxLineWidth = 80, result = newStringOfCap(s.len + s.len shr 6) var spaceLeft = maxLineWidth var lastSep = "" - for word, isSep in tokenize(s, seps): - let wlen = olen(word) + + var i = 0 + while true: + var j = i + let isSep = j < s.len and s[j] in seps + while j < s.len and (s[j] in seps) == isSep: inc(j) + if j <= i: break + #yield (substr(s, i, j-1), isSep) if isSep: - lastSep = word - spaceLeft = spaceLeft - wlen - elif wlen > spaceLeft: - if splitLongWords and wlen > maxLineWidth: - var i = 0 - while i < word.len: - if spaceLeft <= 0: - spaceLeft = maxLineWidth - result.add newLine - dec spaceLeft - let L = graphemeLen(word, i) - for j in 0 ..< L: result.add word[i+j] - inc i, L + lastSep.setLen 0 + for k in i.. spaceLeft: + if splitLongWords and wlen > maxLineWidth: + var k = 0 + while k < j - i: + if spaceLeft <= 0: + spaceLeft = maxLineWidth + result.add newLine + dec spaceLeft + let L = graphemeLen(s, k+i) + for m in 0 ..< L: result.add s[i+k+m] + inc k, L + else: + spaceLeft = maxLineWidth - wlen + result.add(newLine) + for k in i..