var replacementTable … // unescapeEntity reads an entity like "<" from b[src:] and writes the // corresponding "<" to b[dst:], returning the incremented dst and src cursors. // Precondition: b[src] == '&' && dst <= src. // attribute should be true if parsing an attribute value. func unescapeEntity(b []byte, dst, src int, attribute bool) (dst1, src1 int) { … } // unescape unescapes b's entities in-place, so that "a<b" becomes "a<b". // attribute should be true if parsing an attribute value. func unescape(b []byte, attribute bool) []byte { … } // lower lower-cases the A-Z bytes in b in-place, so that "aBc" becomes "abc". func lower(b []byte) []byte { … } // escapeComment is like func escape but escapes its input bytes less often. // Per https://github.com/golang/go/issues/58246 some HTML comments are (1) // meaningful and (2) contain angle brackets that we'd like to avoid escaping // unless we have to. // // "We have to" includes the '&' byte, since that introduces other escapes. // // It also includes those bytes (not including EOF) that would otherwise end // the comment. Per the summary table at the bottom of comment_test.go, this is // the '>' byte that, per above, we'd like to avoid escaping unless we have to. // // Studying the summary table (and T actions in its '>' column) closely, we // only need to escape in states 43, 44, 49, 51 and 52. State 43 is at the // start of the comment data. State 52 is after a '!'. The other three states // are after a '-'. // // Our algorithm is thus to escape every '&' and to escape '>' if and only if: // - The '>' is after a '!' or '-' (in the unescaped data) or // - The '>' is at the start of the comment data (after the opening "<!--"). func escapeComment(w writer, s string) error { … } // escapeCommentString is to EscapeString as escapeComment is to escape. func escapeCommentString(s string) string { … } const escapedChars … func escape(w writer, s string) error { … } // EscapeString escapes special characters like "<" to become "<". It // escapes only five such characters: <, >, &, ' and ". // UnescapeString(EscapeString(s)) == s always holds, but the converse isn't // always true. func EscapeString(s string) string { … } // UnescapeString unescapes entities like "<" to become "<". It unescapes a // larger range of entities than EscapeString escapes. For example, "á" // unescapes to "á", as does "á" and "&xE1;". // UnescapeString(EscapeString(s)) == s always holds, but the converse isn't // always true. func UnescapeString(s string) string { … }