Merge branch 'line_wrapping_alignment' of asdf/bombadillo into master
This keeps proper spaces, including multiple spaces in a row, when wrapping text. This is a big improvement. TODO in a future PR: - Wrap long lines with no spaces properly - Handle multispace characters (unicode) properly - Handle tabs - Handle extra indent of wrapped link lines on gophermaps
This commit is contained in:
commit
2641b03295
16
cui/cui.go
16
cui/cui.go
|
@ -81,20 +81,22 @@ func Clear(dir string) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func wrapLines(s []string, length int) []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
|
||||||
|
func wrapLines(s []string, consolewidth int) []string {
|
||||||
out := []string{}
|
out := []string{}
|
||||||
for _, ln := range s {
|
for _, ln := range s {
|
||||||
if len(ln) <= length {
|
if len(ln) <= consolewidth {
|
||||||
out = append(out, ln)
|
out = append(out, ln)
|
||||||
} else {
|
} else {
|
||||||
words := strings.Split(ln, " ")
|
words := strings.SplitAfter(ln, " ")
|
||||||
var subout bytes.Buffer
|
var subout bytes.Buffer
|
||||||
for i, wd := range words {
|
for i, wd := range words {
|
||||||
sublen := subout.Len()
|
sublen := subout.Len()
|
||||||
if sublen+len(wd)+1 <= length {
|
wdlen := len(wd)
|
||||||
if sublen > 0 {
|
if sublen+wdlen <= consolewidth {
|
||||||
subout.WriteString(" ")
|
|
||||||
}
|
|
||||||
subout.WriteString(wd)
|
subout.WriteString(wd)
|
||||||
if i == len(words)-1 {
|
if i == len(words)-1 {
|
||||||
out = append(out, subout.String())
|
out = append(out, subout.String())
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
package cui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// tests related to issue 31
|
||||||
|
func Test_wrapLines_space_preservation(t *testing.T) {
|
||||||
|
tables := []struct {
|
||||||
|
testinput []string
|
||||||
|
expectedoutput []string
|
||||||
|
linelength int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
//normal sentence - 20 characters - should not wrap
|
||||||
|
[]string{"it is her fav thingy"},
|
||||||
|
[]string{"it is her fav thingy"},
|
||||||
|
20,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
//normal sentence - more than 20 characters - should wrap with a space at the end of the first line
|
||||||
|
[]string{"it is her favourite thing in the world"},
|
||||||
|
[]string{
|
||||||
|
"it is her favourite ",
|
||||||
|
"thing in the world",
|
||||||
|
},
|
||||||
|
20,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
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",
|
||||||
|
"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++ {
|
||||||
|
wrapLines(teststring, 20)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue