esc.go (1367B)
1 package blackfriday 2 3 import ( 4 "html" 5 "io" 6 ) 7 8 var htmlEscaper = [256][]byte{ 9 '&': []byte("&"), 10 '<': []byte("<"), 11 '>': []byte(">"), 12 '"': []byte("""), 13 } 14 15 func escapeHTML(w io.Writer, s []byte) { 16 escapeEntities(w, s, false) 17 } 18 19 func escapeAllHTML(w io.Writer, s []byte) { 20 escapeEntities(w, s, true) 21 } 22 23 func escapeEntities(w io.Writer, s []byte, escapeValidEntities bool) { 24 var start, end int 25 for end < len(s) { 26 escSeq := htmlEscaper[s[end]] 27 if escSeq != nil { 28 isEntity, entityEnd := nodeIsEntity(s, end) 29 if isEntity && !escapeValidEntities { 30 w.Write(s[start : entityEnd+1]) 31 start = entityEnd + 1 32 } else { 33 w.Write(s[start:end]) 34 w.Write(escSeq) 35 start = end + 1 36 } 37 } 38 end++ 39 } 40 if start < len(s) && end <= len(s) { 41 w.Write(s[start:end]) 42 } 43 } 44 45 func nodeIsEntity(s []byte, end int) (isEntity bool, endEntityPos int) { 46 isEntity = false 47 endEntityPos = end + 1 48 49 if s[end] == '&' { 50 for endEntityPos < len(s) { 51 if s[endEntityPos] == ';' { 52 if entities[string(s[end:endEntityPos+1])] { 53 isEntity = true 54 break 55 } 56 } 57 if !isalnum(s[endEntityPos]) && s[endEntityPos] != '&' && s[endEntityPos] != '#' { 58 break 59 } 60 endEntityPos++ 61 } 62 } 63 64 return isEntity, endEntityPos 65 } 66 67 func escLink(w io.Writer, text []byte) { 68 unesc := html.UnescapeString(string(text)) 69 escapeHTML(w, []byte(unesc)) 70 }