From bc8373bd43bd4e5dd4f62f6ede73d34867960dff Mon Sep 17 00:00:00 2001 From: Evert Provoost Date: Wed, 30 Jun 2021 12:52:46 +0200 Subject: [PATCH] ... but not always the best --- pkg/linewrap/linewrap.go | 50 ++++++++++++++++++++++++++++++++-------- pkg/linewrap/util.go | 34 +++++++++++++++------------ 2 files changed, 60 insertions(+), 24 deletions(-) diff --git a/pkg/linewrap/linewrap.go b/pkg/linewrap/linewrap.go index a273d7a..cfaa09b 100644 --- a/pkg/linewrap/linewrap.go +++ b/pkg/linewrap/linewrap.go @@ -36,15 +36,42 @@ func WrapLineOnce(line ast.Line, lineLength int) (ast.Line, ast.Line) { // Is potential breakpoint? precC := lineText[bidx-1] thisC := lineText[bidx] - if (unicode.IsSpace(thisC) && thisC != '\u00A0') || // U+00A0 is NBSP - (unicode.IsLetter(precC) && !unicode.IsLetter(thisC) && !unicode.IsPunct(thisC)) || - (!unicode.IsLetter(precC) && unicode.IsLetter(thisC)) { + if (unicode.In(precC, unicode.Pd) && !unicode.In(thisC, unicode.Pd)) || + (unicode.IsSpace(thisC) && thisC != '\u00A0') { // U+00A0 is NBSP break } } - // No break found, TODO: at least try something? + // No break found, try a less ideal point if bidx == 0 { + bidx = lineLength + for ; bidx > 0; bidx-- { + // Is second rate breakpoint? + precC := lineText[bidx-1] + thisC := lineText[bidx] + if (unicode.IsLetter(precC) && !unicode.IsLetter(thisC)) || + (!unicode.IsLetter(precC) && unicode.IsLetter(thisC)) { + break + } + } + } + + // Still no break found, try an even less ideal point + if bidx == 0 { + bidx = lineLength + 1 + for ; bidx > 0 && bidx < len(lineText); bidx++ { + // Is third rate breakpoint? + precC := lineText[bidx-1] + thisC := lineText[bidx] + if (unicode.IsLetter(precC) && !unicode.IsLetter(thisC)) || + (!unicode.IsLetter(precC) && unicode.IsLetter(thisC)) { + break + } + } + } + + // Still no found: give up. + if bidx >= len(lineText) { return line, ast.Line{} } @@ -55,25 +82,30 @@ func WrapLineOnce(line ast.Line, lineLength int) (ast.Line, ast.Line) { for currentCell := 0; currentCell < len(line); currentCell++ { cell := line[currentCell] + cellContent := []rune(cell.Content) // If breakpoint in this cell: break cell - if headLength+cell.Lenght() > bidx { + if headLength+len(cellContent) > bidx { cidx := bidx - headLength fh := cell sh := cell - fh.Content = removeSpaceAfter(string(cell.Content[:cidx])) - sh.Content = removeSpaceBefore(string(cell.Content[cidx:])) + fh.Content = string(removeSpaceAfter(cellContent[:cidx])) + sh.Content = string(removeSpaceBefore(cellContent[cidx:])) head = append(head, fh) - tail = append(ast.Line{sh}, line[currentCell+1:]...) + if len(sh.Content) == 0 { + tail = line[currentCell+1:] + } else { + tail = append(ast.Line{sh}, line[currentCell+1:]...) + } break } head = append(head, cell) - headLength += cell.Lenght() + headLength += len(cellContent) } return head, tail diff --git a/pkg/linewrap/util.go b/pkg/linewrap/util.go index bfe6225..c2566c1 100644 --- a/pkg/linewrap/util.go +++ b/pkg/linewrap/util.go @@ -4,25 +4,31 @@ import ( "unicode" ) -func removeSpaceBefore(s string) string { +func removeSpaceBefore(s []rune) []rune { // Can't remove from something empty... - if s == "" { - return "" + if len(s) == 0 { + return []rune{} } i := 0 - for currentlyspace := true; i < len(s) && currentlyspace; i++ { - currentlyspace = unicode.IsSpace(rune(s[i])) + currentlyspace := true + for ; i < len(s) && currentlyspace; i++ { + currentlyspace = unicode.IsSpace(s[i]) } - // Now i is the point where the first nonspace is, thus + // It's all spaces + if currentlyspace { + return []rune{} + } + + // Now i is the point after where the first nonspace is, thus return s[i-1:] } -func removeSpaceAfter(s string) string { +func removeSpaceAfter(s []rune) []rune { // Can't remove from something empty... - if s == "" { - return "" + if len(s) == 0 { + return s } s = reverse(s) @@ -31,12 +37,10 @@ func removeSpaceAfter(s string) string { return s } -func reverse(s string) string { - c := []rune(s) - - for i, j := 0, len(c)-1; i < len(c)/2; i, j = i+1, j-1 { - c[i], c[j] = c[j], c[i] +func reverse(s []rune) []rune { + for i, j := 0, len(s)-1; i < len(s)/2; i, j = i+1, j-1 { + s[i], s[j] = s[j], s[i] } - return string(c) + return s }