-
Notifications
You must be signed in to change notification settings - Fork 27
/
syntax.lisp
96 lines (74 loc) · 2.49 KB
/
syntax.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
(in-package #:spinneret)
(declaim (inline whitespace must-quote?
escape-string escape-attribute-value
escape-cdata escape-comment))
(deftype index () '(integer 0 #.array-total-size-limit))
(defconst no-break-space
#+lispworks #\No-break-space
#-lispworks #\No-break_space)
;; See 2.5.1.
;; http://www.w3.org/TR/html5/common-microsyntaxes.html#space-character
(declaim (inline whitespace))
(defun whitespace (char)
(declare (character char))
(case char
((#\Space #\Tab #\Newline #\Page #\Return) t)))
;; See 8.1.2.3.
;; http://www.w3.org/TR/html5/syntax.html#syntax-attribute-value
(defun must-quote? (char)
(declare (character char))
(or (whitespace char)
(case char
;; NB The HTML spec only requires escaping trailing slashes,
;; but not all parsers implement that.
((#\" #\' #\` #\= #\< #\> #\/) t))))
(defun needs-quotes? (string)
(declare (string string))
(or *always-quote*
(some #'must-quote? string)
;; See docstring for must-quote.
;; (string$= "/" string)
))
;; See 8.3.
;; http://www.w3.org/TR/html5/the-end.html#serializing-html-fragments
(defun escape-string-char (c)
(declare (character c)
(optimize (speed 3) (safety 1) (debug 0)))
(case c
(#\& "&")
(#.no-break-space " ")
(#\< "<")
(#\> ">")
(#\" """)
(#\' "'")))
(defun escape-string (string)
"Escape STRING as HTML."
(escape-with-table string #'escape-string-char))
(defun escape-to-string (object)
(if (stringp object)
(escape-string object)
(escape-string (princ-to-string object))))
(defun escape-attribute-value (string)
(escape-with-table string
(lambda (c)
(case c
(#\& "&")
(#.no-break-space " ")
(#\" """)
(#\' "'")))))
(defun escape-to-stream (string table stream)
(escape string table :stream stream))
(defun escape-with-table (string table)
(escape string table))
;; See 8.1.5
;; http://www.w3.org/TR/html5/syntax.html#cdata-sections
(defconst cdata-start "<![CDATA[")
(defconst cdata-end "]]>")
(defun escape-cdata (text)
(remove-substring text cdata-end))
;; See 8.1.6
;; http://www.w3.org/TR/html5/syntax.html#comments
(defun escape-comment (text)
(remove-substring (string-trim ">-" text) "--"))
(defun remove-substring (string substring)
(string-replace-all substring string ""))