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)) { var f []func() error ww := out for i := len(w) - 1; i >= 0; i-- { var fi func() error ww, fi = w[i](ww) f = append(f, 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 } } }