package textedit func replaceEdit(match, replacement []rune) func(rune, []rune) ([]rune, []rune) { return func(r rune, state []rune) ([]rune, []rune) { state = append(state, r) if len(state) > len(match) { return state, nil } if r != match[len(state)-1] { return state, nil } if len(state) == len(match) { return replacement, nil } return nil, state } } func replaceRelease(state []rune) []rune { return state } func replaceOne(match, replacement string) Editor { return Func( replaceEdit([]rune(match), []rune(replacement)), replaceRelease, ) } func replace(a ...string) Editor { if len(a)%2 != 0 { a = append(a, "") } var e []Editor for i := 0; i < len(a); i += 2 { e = append( e, replaceOne(a[i], a[i+1]), ) } return sequence(e...) } func escape(esc rune, chars ...rune) Editor { r := []string{string(esc), string([]rune{esc, esc})} for _, c := range chars { r = append(r, string(c), string([]rune{esc, c})) } return replace(r...) }