1
0
textfmt/escape.go
2025-10-31 20:24:37 +01:00

73 lines
1.2 KiB
Go

package textfmt
import "fmt"
type escapeRange struct {
from, to rune
replacement string
}
type escape[S any] struct {
out writer
state S
escape map[rune]string
escapeRanges []escapeRange
conditionalEscape map[rune]func(S, rune) (string, bool)
updateState func(S, rune) S
}
func (e *escape[S]) inEscapeRange(r rune) (string, bool) {
for _, rng := range e.escapeRanges {
if r >= rng.from && r <= rng.to {
return rng.replacement, true
}
}
return "", false
}
func (e *escape[S]) write(a ...any) {
for _, ai := range a {
s := fmt.Sprint(ai)
r := []rune(s)
for _, ri := range r {
var (
output string
found bool
)
output, found = e.escape[ri]
if !found {
output, found = e.inEscapeRange(ri)
}
if !found {
conditional := e.conditionalEscape[ri]
if conditional != nil {
output, found = conditional(e.state, ri)
}
}
if !found {
output = string(ri)
}
e.out.write(output)
if e.updateState != nil {
e.state = e.updateState(e.state, ri)
}
}
}
}
func (e *escape[S]) flush() {
e.out.flush()
}
func (e *escape[S]) error() error {
return e.out.error()
}
func (e *escape[S]) setErr(err error) {
}