77 lines
1.3 KiB
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("<")
|
|
case '>':
|
|
rr = []rune(">")
|
|
case '&':
|
|
rr = []rune("&")
|
|
case unicodeNBSP:
|
|
rr = []rune(" ")
|
|
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(
|
|
"&", "&",
|
|
"\"", """,
|
|
),
|
|
)
|
|
|
|
w.Write([]byte(value))
|
|
w.Flush()
|
|
return b.String()
|
|
}
|