1
0
html/escape.go

77 lines
1.3 KiB
Go

package html
import (
"bytes"
"code.squareroundforest.org/arpio/textedit"
"io"
)
const unicodeNBSP = 0xa0
func escapeEdit(nonbreakSpaces bool) func(rune, []rune) ([]rune, []rune) {
return func(r rune, state []rune) ([]rune, []rune) {
var rr []rune
switch r {
case ' ':
if !nonbreakSpaces {
return []rune{r}, nil
}
if len(state) == 0 {
return nil, []rune{' '}
}
return []rune(" "), []rune(" ")
case '<':
rr = []rune("&lt;")
case '>':
rr = []rune("&gt;")
case '&':
rr = []rune("&amp;")
case unicodeNBSP:
rr = []rune("&nbsp;")
default:
rr = []rune{r}
}
return append(state, rr...), nil
}
}
func escapeReleaseState(state []rune) []rune {
return state
}
func newEscapeWriter(out io.Writer, nonbreakSpaces bool) *textedit.Writer {
return textedit.New(
out,
textedit.Func(
escapeEdit(nonbreakSpaces),
escapeReleaseState,
),
)
}
func escape(s string, nonbreakSpaces bool) string {
var b bytes.Buffer
w := newEscapeWriter(&b, nonbreakSpaces)
w.Write([]byte(s))
w.Flush()
return b.String()
}
func escapeAttribute(value string) string {
var b bytes.Buffer
w := textedit.New(
&b,
textedit.Replace(
"&", "&amp;",
"\"", "&quot;",
),
)
w.Write([]byte(value))
w.Flush()
return b.String()
}