83 lines
1.5 KiB
Go
83 lines
1.5 KiB
Go
package textfmt
|
|
|
|
import (
|
|
"fmt"
|
|
"unicode"
|
|
)
|
|
|
|
type indent struct {
|
|
out writer
|
|
firstIndent, indent int
|
|
firstWidth, width int
|
|
currentLineLength int
|
|
currentWord []rune
|
|
multiline bool
|
|
}
|
|
|
|
func (i *indent) write(a ...any) {
|
|
for _, ai := range a {
|
|
s := fmt.Sprint(ai)
|
|
r := []rune(s)
|
|
for _, ri := range r {
|
|
width := i.width
|
|
if !i.multiline {
|
|
width = i.firstWidth
|
|
}
|
|
|
|
indent := i.indent
|
|
if !i.multiline {
|
|
indent = i.firstIndent
|
|
}
|
|
|
|
if !unicode.IsSpace(ri) || ri == '\u00a0' {
|
|
i.currentWord = append(i.currentWord, ri)
|
|
continue
|
|
}
|
|
|
|
nonWrapNewline := width == 0 && ri == '\n'
|
|
if len(i.currentWord) == 0 && !nonWrapNewline {
|
|
continue
|
|
}
|
|
|
|
nextLineLength := i.currentLineLength + len(i.currentWord) + 1
|
|
if i.currentLineLength > 0 && width > 0 && nextLineLength > width {
|
|
i.out.write("\n")
|
|
i.currentLineLength = 0
|
|
i.multiline = true
|
|
}
|
|
|
|
if i.currentLineLength > 0 && len(i.currentWord) > 0 {
|
|
i.out.write(" ")
|
|
i.currentLineLength++
|
|
}
|
|
|
|
if i.currentLineLength == 0 && len(i.currentWord) > 0 {
|
|
i.out.write(timesn(" ", indent))
|
|
i.currentLineLength += indent
|
|
}
|
|
|
|
if len(i.currentWord) > 0 {
|
|
i.out.write(string(i.currentWord))
|
|
i.currentLineLength += len(i.currentWord)
|
|
i.currentWord = nil
|
|
}
|
|
|
|
if nonWrapNewline {
|
|
i.out.write("\n")
|
|
i.currentLineLength = 0
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (i *indent) flush() {
|
|
i.out.flush()
|
|
}
|
|
|
|
func (i *indent) error() error {
|
|
return i.out.error()
|
|
}
|
|
|
|
func (e *indent) setErr(err error) {
|
|
}
|