1
0
textfmt/write.go

91 lines
2.0 KiB
Go

package textfmt
import (
"bytes"
"code.squareroundforest.org/arpio/textedit"
"fmt"
"io"
)
type wrapper func(io.Writer) (io.Writer, func() error)
type errorWriter struct {
out io.Writer
err error
}
func (w *errorWriter) Write(p []byte) (int, error) {
if w.err != nil {
return 0, w.err
}
var n int
n, w.err = w.out.Write(p)
return n, w.err
}
func writeWith(out io.Writer, w ...wrapper) (io.Writer, func() (io.Writer, error)) {
f := make([]func() error, len(w))
ww := out
for i := len(w) - 1; i >= 0; i-- {
var fi func() error
ww, fi = w[i](ww)
f[i] = fi
}
return ww, func() (io.Writer, error) {
for _, fi := range f {
if err := fi(); err != nil {
return out, err
}
}
return out, nil
}
}
func errorHandler(out io.Writer) (io.Writer, func() error) {
ew := errorWriter{out: out}
return &ew, func() error { return ew.err }
}
func editor(e textedit.Editor) wrapper {
return func(out io.Writer) (io.Writer, func() error) {
ew := textedit.New(out, e)
return ew, func() error { return ew.Flush() }
}
}
func editString(s string, e ...wrapper) string {
var b bytes.Buffer
w, finish := writeWith(&b, e...)
w.Write([]byte(s))
finish()
return b.String()
}
func ttyNBSP() wrapper { return editor(textedit.Replace("\u00a0", " ")) }
func roffNBSP() wrapper { return editor(textedit.Replace("\u00a0", "\\~")) }
func mdNBSP() wrapper { return editor(textedit.Replace("\u00a0", " ")) }
func singleLine() wrapper { return editor(textedit.SingleLine()) }
func indent(first, rest int) wrapper {
return editor(textedit.Indent(timesn(" ", first), timesn(" ", rest)))
}
func wrap(firstWidth, restWidth int) wrapper {
return editor(textedit.Wrap(firstWidth, restWidth))
}
func wrapIndent(first, rest, firstWidth, restWidth int) wrapper {
return editor(textedit.WrapIndent(timesn(" ", first), timesn(" ", rest), firstWidth, restWidth))
}
func write(out io.Writer, a ...any) {
for _, ai := range a {
if _, err := out.Write([]byte(fmt.Sprint(ai))); err != nil {
return
}
}
}