From 864bb7c2c05ddb21a58d37df4010da0c486db686 Mon Sep 17 00:00:00 2001 From: asdf Date: Tue, 10 Sep 2019 21:06:14 +1000 Subject: [PATCH 1/5] added unit test --- cui/cui_test.go | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/cui/cui_test.go b/cui/cui_test.go index 1a286d3..26bf26e 100644 --- a/cui/cui_test.go +++ b/cui/cui_test.go @@ -38,6 +38,35 @@ func Test_wrapLines_space_preservation(t *testing.T) { } } +func Test_wrapLines_incorrect_wrapping_endash(t *testing.T) { + tables := []struct { + testinput []string + expectedoutput []string + linelength int + }{ + { + //a specific test from cat's phlog that was wrapping and I'm not sure why + //TODO this test passes but in reality it does not + []string{ + " Suldusk – Really cool dark folk/black metal sort of deal. The lead singer", + "is a tiny fairy of a person and she's very charming. It's the bass players", + }, + []string{ + " Suldusk – Really cool dark folk/black metal sort of deal. The lead singer", + "is a tiny fairy of a person and she's very charming. It's the bass players", + }, + 80, + }, + } + + for _, table := range tables { + output := wrapLines(table.testinput, table.linelength) + + if !reflect.DeepEqual(output, table.expectedoutput) { + t.Errorf("Expected %v, got %v", table.expectedoutput, output) + } + } +} func Benchmark_wrapLines(b *testing.B) { teststring := []string{ "0123456789", From 98cfd120ca974caf30bb6598373ded884e56b084 Mon Sep 17 00:00:00 2001 From: asdf Date: Tue, 10 Sep 2019 21:10:52 +1000 Subject: [PATCH 2/5] corrected test description --- cui/cui_test.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cui/cui_test.go b/cui/cui_test.go index 26bf26e..374be25 100644 --- a/cui/cui_test.go +++ b/cui/cui_test.go @@ -45,8 +45,10 @@ func Test_wrapLines_incorrect_wrapping_endash(t *testing.T) { linelength int }{ { - //a specific test from cat's phlog that was wrapping and I'm not sure why - //TODO this test passes but in reality it does not + + // a specific test from cat's phlog (gopher://baud.baby:70/0/phlog/fs20190818.txt) + // I think the – character U+2013 : EN DASH characteris causing wrapping incorrectly + // but the test passes and i'm not sure why []string{ " Suldusk – Really cool dark folk/black metal sort of deal. The lead singer", "is a tiny fairy of a person and she's very charming. It's the bass players", From 38c9721817ee942c2768409276cc7008e41387cc Mon Sep 17 00:00:00 2001 From: asdf Date: Wed, 11 Sep 2019 15:36:56 +1000 Subject: [PATCH 3/5] this is a test only for wraplines rune tests --- cui/cui.go | 67 +++++++++++++++++++++++++++++++++++++++++++++++-- cui/cui_test.go | 24 ++++++++++++++++++ 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/cui/cui.go b/cui/cui.go index 67d8b3a..f3950a1 100644 --- a/cui/cui.go +++ b/cui/cui.go @@ -7,6 +7,7 @@ import ( "os" "os/exec" "strings" + "unicode/utf8" ) var shapes = map[string]string{ @@ -88,14 +89,14 @@ func Clear(dir string) { func wrapLines(s []string, consolewidth int) []string { out := []string{} for _, ln := range s { - if len(ln) <= consolewidth { + if len([]rune(ln)) <= consolewidth { out = append(out, ln) } else { words := strings.SplitAfter(ln, " ") var subout bytes.Buffer for i, wd := range words { sublen := subout.Len() - wdlen := len(wd) + wdlen := len([]rune(wd)) if sublen+wdlen <= consolewidth { subout.WriteString(wd) if i == len(words)-1 { @@ -171,3 +172,65 @@ func HandleAlternateScreen(opt string) { // to run _ = cmd.Run() } + +func wrapLines2(s []string, consolewidth int) []string { + out := []string{} + for _, ln := range s { + if utf8.RuneCountInString(ln) <= consolewidth { + out = append(out, ln) + } else { + words := strings.SplitAfter(ln, " ") + var subout bytes.Buffer + for i, wd := range words { + sublen := subout.Len() + wdlen := utf8.RuneCountInString(wd) + if sublen+wdlen <= consolewidth { + subout.WriteString(wd) + if i == len(words)-1 { + out = append(out, subout.String()) + } + } else { + out = append(out, subout.String()) + subout.Reset() + subout.WriteString(wd) + if i == len(words)-1 { + out = append(out, subout.String()) + subout.Reset() + } + } + } + } + } + return out +} + +func wrapLines3(s []string, consolewidth int) []string { + out := []string{} + for _, ln := range s { + if len(ln) <= consolewidth { + out = append(out, ln) + } else { + words := strings.SplitAfter(ln, " ") + var subout bytes.Buffer + for i, wd := range words { + sublen := subout.Len() + wdlen := len(wd) + if sublen+wdlen <= consolewidth { + subout.WriteString(wd) + if i == len(words)-1 { + out = append(out, subout.String()) + } + } else { + out = append(out, subout.String()) + subout.Reset() + subout.WriteString(wd) + if i == len(words)-1 { + out = append(out, subout.String()) + subout.Reset() + } + } + } + } + } + return out +} diff --git a/cui/cui_test.go b/cui/cui_test.go index 374be25..f7897ae 100644 --- a/cui/cui_test.go +++ b/cui/cui_test.go @@ -81,3 +81,27 @@ func Benchmark_wrapLines(b *testing.B) { wrapLines(teststring, 20) } } +func Benchmark_wrapLines2(b *testing.B) { + teststring := []string{ + "0123456789", + "a really long line that will prolly be wrapped", + "a l i n e w i t h a l o t o f w o r d s", + "onehugelongwordaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + } + b.ResetTimer() + for n := 0; n < b.N; n++ { + wrapLines2(teststring, 20) + } +} +func Benchmark_wrapLines3(b *testing.B) { + teststring := []string{ + "0123456789", + "a really long line that will prolly be wrapped", + "a l i n e w i t h a l o t o f w o r d s", + "onehugelongwordaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + } + b.ResetTimer() + for n := 0; n < b.N; n++ { + wrapLines3(teststring, 20) + } +} From 45596d4e8d0a980cd6225cd74eff3226abc90402 Mon Sep 17 00:00:00 2001 From: asdf Date: Thu, 12 Sep 2019 12:49:51 +1000 Subject: [PATCH 4/5] Using slice of runes for calculating lengths --- cui/cui.go | 75 ++++++------------------------------------------- cui/cui_test.go | 25 +---------------- 2 files changed, 9 insertions(+), 91 deletions(-) diff --git a/cui/cui.go b/cui/cui.go index f3950a1..c5a8fea 100644 --- a/cui/cui.go +++ b/cui/cui.go @@ -7,7 +7,6 @@ import ( "os" "os/exec" "strings" - "unicode/utf8" ) var shapes = map[string]string{ @@ -82,10 +81,14 @@ func Clear(dir string) { } -// takes the document content (as a slice) and modifies any lines that are longer -// than the specified console width, splitting them over two lines. returns the -// amended document content as a slice. -// word wrapping uses a "greedy" algorithm +// Takes the document content (as a slice of strings) and wraps any lines that +// are longer than the specified console width. returns the amended document +// content as a slice of strings. +// Word wrapping uses a "greedy" algorithm, where long lines are split in to +// words, and then rebuilt word by word to fill the available space. any +// leftover words overflow to the next line. +// To offer some support for unicode, some lengths are calculated using a slice +// of runes in the following way: len([]rune(string)) func wrapLines(s []string, consolewidth int) []string { out := []string{} for _, ln := range s { @@ -172,65 +175,3 @@ func HandleAlternateScreen(opt string) { // to run _ = cmd.Run() } - -func wrapLines2(s []string, consolewidth int) []string { - out := []string{} - for _, ln := range s { - if utf8.RuneCountInString(ln) <= consolewidth { - out = append(out, ln) - } else { - words := strings.SplitAfter(ln, " ") - var subout bytes.Buffer - for i, wd := range words { - sublen := subout.Len() - wdlen := utf8.RuneCountInString(wd) - if sublen+wdlen <= consolewidth { - subout.WriteString(wd) - if i == len(words)-1 { - out = append(out, subout.String()) - } - } else { - out = append(out, subout.String()) - subout.Reset() - subout.WriteString(wd) - if i == len(words)-1 { - out = append(out, subout.String()) - subout.Reset() - } - } - } - } - } - return out -} - -func wrapLines3(s []string, consolewidth int) []string { - out := []string{} - for _, ln := range s { - if len(ln) <= consolewidth { - out = append(out, ln) - } else { - words := strings.SplitAfter(ln, " ") - var subout bytes.Buffer - for i, wd := range words { - sublen := subout.Len() - wdlen := len(wd) - if sublen+wdlen <= consolewidth { - subout.WriteString(wd) - if i == len(words)-1 { - out = append(out, subout.String()) - } - } else { - out = append(out, subout.String()) - subout.Reset() - subout.WriteString(wd) - if i == len(words)-1 { - out = append(out, subout.String()) - subout.Reset() - } - } - } - } - } - return out -} diff --git a/cui/cui_test.go b/cui/cui_test.go index f7897ae..1ee3d3b 100644 --- a/cui/cui_test.go +++ b/cui/cui_test.go @@ -69,6 +69,7 @@ func Test_wrapLines_incorrect_wrapping_endash(t *testing.T) { } } } + func Benchmark_wrapLines(b *testing.B) { teststring := []string{ "0123456789", @@ -81,27 +82,3 @@ func Benchmark_wrapLines(b *testing.B) { wrapLines(teststring, 20) } } -func Benchmark_wrapLines2(b *testing.B) { - teststring := []string{ - "0123456789", - "a really long line that will prolly be wrapped", - "a l i n e w i t h a l o t o f w o r d s", - "onehugelongwordaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - } - b.ResetTimer() - for n := 0; n < b.N; n++ { - wrapLines2(teststring, 20) - } -} -func Benchmark_wrapLines3(b *testing.B) { - teststring := []string{ - "0123456789", - "a really long line that will prolly be wrapped", - "a l i n e w i t h a l o t o f w o r d s", - "onehugelongwordaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - } - b.ResetTimer() - for n := 0; n < b.N; n++ { - wrapLines3(teststring, 20) - } -} From a5c14b9b7c0c6e864efd2d103d96221c815889cf Mon Sep 17 00:00:00 2001 From: asdf Date: Sun, 15 Sep 2019 08:42:58 +1000 Subject: [PATCH 5/5] Finalising change --- cui/cui_test.go | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/cui/cui_test.go b/cui/cui_test.go index 1ee3d3b..1a286d3 100644 --- a/cui/cui_test.go +++ b/cui/cui_test.go @@ -38,38 +38,6 @@ func Test_wrapLines_space_preservation(t *testing.T) { } } -func Test_wrapLines_incorrect_wrapping_endash(t *testing.T) { - tables := []struct { - testinput []string - expectedoutput []string - linelength int - }{ - { - - // a specific test from cat's phlog (gopher://baud.baby:70/0/phlog/fs20190818.txt) - // I think the – character U+2013 : EN DASH characteris causing wrapping incorrectly - // but the test passes and i'm not sure why - []string{ - " Suldusk – Really cool dark folk/black metal sort of deal. The lead singer", - "is a tiny fairy of a person and she's very charming. It's the bass players", - }, - []string{ - " Suldusk – Really cool dark folk/black metal sort of deal. The lead singer", - "is a tiny fairy of a person and she's very charming. It's the bass players", - }, - 80, - }, - } - - for _, table := range tables { - output := wrapLines(table.testinput, table.linelength) - - if !reflect.DeepEqual(output, table.expectedoutput) { - t.Errorf("Expected %v, got %v", table.expectedoutput, output) - } - } -} - func Benchmark_wrapLines(b *testing.B) { teststring := []string{ "0123456789",