From dac13e1669071cea781226dffa0fd48c2710b015 Mon Sep 17 00:00:00 2001 From: "R. Aidan Campbell" Date: Sun, 6 Feb 2022 22:09:06 -0700 Subject: [PATCH] soft wrap between words --- page.go | 22 ++++++++++++++++++---- page_test.go | 17 +++++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/page.go b/page.go index 99ebdce..d45184a 100644 --- a/page.go +++ b/page.go @@ -3,8 +3,8 @@ package main import ( "fmt" "strings" - "tildegit.org/sloum/bombadillo/tdiv" + "unicode" ) //------------------------------------------------\\ @@ -86,7 +86,10 @@ func (p *Page) WrapContent(width, maxWidth int, color bool) { } else if strings.HasSuffix(p.Location.Mime, "gemini") { //gemini document spacer = " " } - for _, ch := range []rune(p.RawContent) { + + runeArr := []rune(p.RawContent) + for i := 0; i < len(runeArr); i++ { + ch := runeArr[i] if escape { if color { esc.WriteRune(ch) @@ -112,7 +115,7 @@ func (p *Page) WrapContent(width, maxWidth int, color bool) { counter = 0 } } else if ch == '\r' || ch == '\v' || ch == '\b' || ch == '\f' || ch == '\a' { - // Get rid of control characters we dont want + // Get rid of control characters we don't want continue } else if ch == 27 { if p.Location.Scheme == "local" { @@ -128,7 +131,18 @@ func (p *Page) WrapContent(width, maxWidth int, color bool) { } continue } else { - if counter <= width { + // peek forward to see if we can render the word without going over + j := i + for ; j < len(runeArr) && !unicode.IsSpace(runeArr[j]); j++ { + if counter+(j-i) > width+1 { + break + } + } + + // if we can render the rest of the word, write the next letter. else, skip to the next line. + // TODO(raidancampbell): optimize this to write out the whole word, this will involve referencing the + // above special cases + if counter+(j-i) <= width+1 && !(j == i && counter == width+1) { content.WriteRune(ch) counter++ } else { diff --git a/page_test.go b/page_test.go index 33de341..1b6866d 100644 --- a/page_test.go +++ b/page_test.go @@ -47,6 +47,23 @@ func Test_WrapContent_Wrapped_Line_Length(t *testing.T) { false, }, }, + { + "multiple words should wrap at the right point", + "01 345 789 123456789 123456789 123456789 123456789\n", + []string{ + "01 345 789", + " 123456789", + " 123456789", + " 123456789", + " 123456789", + "", + }, + args{ + 10, + 10, + false, + }, + }, { "Long line wrapped to 10 columns", "0123456789 123456789 123456789 123456789 123456789\n",