parent
e3f80e434a
commit
c308c2e60b
1 changed files with 48 additions and 25 deletions
|
|
@ -11,10 +11,10 @@
|
||||||
|
|
||||||
import strutils, unicode
|
import strutils, unicode
|
||||||
|
|
||||||
proc olen(s: string): int =
|
proc olen(s: string; start, lastExclusive: int): int =
|
||||||
var i = 0
|
var i = start
|
||||||
result = 0
|
result = 0
|
||||||
while i < s.len:
|
while i < lastExclusive:
|
||||||
inc result
|
inc result
|
||||||
let L = graphemeLen(s, i)
|
let L = graphemeLen(s, i)
|
||||||
inc i, L
|
inc i, L
|
||||||
|
|
@ -32,31 +32,46 @@ proc wrapWords*(s: string, maxLineWidth = 80,
|
||||||
result = newStringOfCap(s.len + s.len shr 6)
|
result = newStringOfCap(s.len + s.len shr 6)
|
||||||
var spaceLeft = maxLineWidth
|
var spaceLeft = maxLineWidth
|
||||||
var lastSep = ""
|
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:
|
if isSep:
|
||||||
lastSep = word
|
lastSep.setLen 0
|
||||||
spaceLeft = spaceLeft - wlen
|
for k in i..<j:
|
||||||
elif wlen > spaceLeft:
|
if s[k] notin {'\L', '\C'}: lastSep.add s[k]
|
||||||
if splitLongWords and wlen > maxLineWidth:
|
if lastSep.len == 0:
|
||||||
var i = 0
|
lastSep.add ' '
|
||||||
while i < word.len:
|
dec spaceLeft
|
||||||
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
|
|
||||||
else:
|
else:
|
||||||
spaceLeft = maxLineWidth - wlen
|
spaceLeft = spaceLeft - olen(lastSep, 0, lastSep.len)
|
||||||
result.add(newLine)
|
|
||||||
result.add(word)
|
|
||||||
else:
|
else:
|
||||||
spaceLeft = spaceLeft - wlen
|
let wlen = olen(s, i, j)
|
||||||
result.add(lastSep)
|
if wlen > spaceLeft:
|
||||||
result.add(word)
|
if splitLongWords and wlen > maxLineWidth:
|
||||||
lastSep.setLen(0)
|
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..<j: result.add(s[k])
|
||||||
|
else:
|
||||||
|
spaceLeft = spaceLeft - wlen
|
||||||
|
result.add(lastSep)
|
||||||
|
for k in i..<j: result.add(s[k])
|
||||||
|
#lastSep.setLen(0)
|
||||||
|
i = j
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
|
|
||||||
|
|
@ -93,3 +108,11 @@ tnaetdriaoenvlcyfglwckßqfgvwkßqgfvlwkßqfgvlwckßqvlwkgfUIαοιαοιαχολ
|
||||||
ξχλωωχαοεοιαεοαεοιαεοαεοιαοεσναοεκνρκψγκψφϵιηαααοε"""
|
ξχλωωχαοεοιαεοαεοιαεοαεοιαοεσναοεκνρκψγκψφϵιηαααοε"""
|
||||||
doAssert wrapWords(longlongword) == longlongwordRes
|
doAssert wrapWords(longlongword) == longlongwordRes
|
||||||
|
|
||||||
|
# bug #14579
|
||||||
|
const input60 = """
|
||||||
|
This is a long string. It is manually wrapped to 60
|
||||||
|
characters. I would not expect it to be changed by
|
||||||
|
wordwrap if wordwrap is set to wrap at 80 characters"""
|
||||||
|
const input60Res = """This is a long string. It is manually wrapped to 60 characters. I would not
|
||||||
|
expect it to be changed by wordwrap if wordwrap is set to wrap at 80 characters"""
|
||||||
|
doAssert wrapWords(input60) == input60Res
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue