1 <page title="Closure HTML Examples">
3 Simple examples using Closure HTML.
8 <div style="width: 60%">
9 <b>Note on non-Unicode Lisps:</b> The examples on this page were
10 written for Lisps with Unicode support. When using Closure HTML on
11 Lisps without Unicode characters, some changes need to be made. For
12 example, <tt>make-string-sink</tt> is not available without Unicode
13 support, but <tt>make-string-sink/utf8</tt> can be substituted in
17 <div style="float: left">
18 <section>Parsing a string</section>
21 <fun>make-lhtml-builder</fun>
22 <fun>serialize-lhtml</fun>
23 <fun>make-string-sink</fun>
26 <p>Parse into LHTML:</p>
27 <example>(chtml:parse "<p>nada</p>" (chtml:make-lhtml-builder))</example>
28 <result>(:HTML NIL (:HEAD NIL) (:BODY NIL (:P NIL "nada")))</result>
30 <p>Serialize LHTML back into a string:</p>
31 <example>(chtml:serialize-lhtml * (chtml:make-string-sink))</example>
32 <result>"<HTML><HEAD></HEAD><BODY><P>nada</P></BODY></HTML>"</result>
34 <section>Parsing a file</section>
38 <fun>make-lhtml-builder</fun>
42 Note that the filename must be passed as a pathname (written
43 using <tt>#p</tt>), not just a
44 string, because a string would be interpreted as a literal HTML
45 document as in the first example above.
47 <example>(chtml:parse #p"example.html" (chtml:make-lhtml-builder))</example>
48 <result>(:HTML NIL (:HEAD NIL) (:BODY NIL (:P NIL "nada")))</result>
50 <section>Cleaning up broken HTML</section>
53 <fun>make-string-sink</fun>
57 Many HTML syntax errors are corrected by Closure HTML
58 automatically. In this example, we parse from a string and
59 serialize it back immediately.
61 <example>(defun clean-html (string)
62 (chtml:parse string (chtml:make-string-sink)))</example>
63 <result>CLEAN-HTML</result>
65 Note the differences between input and output in the following document:
68 <li><title> is moved into <head>.</li>
69 <li>The <tt>bogus</tt> attribute is removed.</li>
70 <li><br is corrected to <br> and </oops> to </p>.</li>
72 <example>(clean-html "<title>cleanup example</title>
75 </oops>")</example>
76 <result>"<HTML><HEAD><TITLE>cleanup example</TITLE></HEAD><BODY><P>
77 <BR></P></BODY></HTML>"</result>
79 <section>Translating an HTML file to XHTML</section>
82 <a href="http://common-lisp.net/project/cxml/sax.html#serialization">
83 cxml:make-octet-stream-sink
88 In this example, we parse an HTML file and serialize it into XHTML.
92 uses <a href="http://common-lisp.net/project/cxml">Closure XML</a>.
94 <example>(defun html2xhtml (file &key (if-exists :error))
95 (with-open-file (out (make-pathname :type "xml" :defaults file)
96 :element-type '(unsigned-byte 8)
99 (chtml:parse (pathname file)
100 (cxml:make-octet-stream-sink out))))</example>
101 <result>HTML2XHTML</result>
103 <example>(html2xhtml "/home/david/test.html" :if-exists :supersede)</example>
105 The following input file and its XHTML version illustrate some of
106 the differences between the two syntaxes.
110 <pre style="border: solid 1px #9c0000;
112 width: 60%;"><p>foo</p>
117 <option selected>123
123 <pre style="border: solid 1px #9c0000;
125 width: 60%;"><?xml version="1.0" encoding="UTF-8"?>
126 <html xmlns="http://www.w3.org/1999/xhtml"><head/><body><p>foo</p>
130 <select><option selected="selected">123
131 </option><option>456
132 </option></select>
133 </body></html></pre>
136 <section>Translating an XHTML file to HTML</section>
138 <a href="http://common-lisp.net/project/cxml/sax.html">
141 <fun>make-octet-stream-sink</fun>
145 This is a continuation of the opposite example above. In that
146 example, we converted an HTML file to HTML. Going back to HTML is
149 <example>(defun xhtml2html (file &key (if-exists :error))
150 (with-open-file (out (make-pathname :type "html" :defaults file)
151 :element-type '(unsigned-byte 8)
154 (cxml:parse (pathname file)
155 (chtml:make-octet-stream-sink out))))</example>
156 <result>XHTML2HTML</result>
157 Running this function on the example above results in a clean-up
158 version of the original document:
161 <pre style="border: solid 1px #9c0000;
163 width: 60%;"><html><head></head><body><p>foo</p>
167 <select><option selected>123
168 </option><option>456
169 </option></select>
170 </body></html></pre>
173 <section>Fetching and parsing Google search results</section>
176 <a href="http://weitz.de/drakma/#http-request">
179 <a href="http://www.lichteblau.com/cxml-stp/doc/pages/cxml-stp__fun__make-builder.html">
180 cxml-stp:make-builder
182 <a href="http://www.lichteblau.com/cxml-stp/doc/pages/cxml-stp__macro__do-recursively.html">
183 cxml-stp:do-recursively
185 <a href="http://www.lichteblau.com/cxml-stp/doc/pages/cxml-stp__class__element.html">
188 <a href="http://www.lichteblau.com/cxml-stp/doc/pages/cxml-stp__fun__local-name.html">
191 <a href="http://www.lichteblau.com/cxml-stp/doc/pages/cxml-stp__fun__attribute-value.html">
192 cxml-stp:attribute-value
197 In this example, we perform a google search and print the first ten
198 results by looking for all links of the form <a class="l">.
202 uses <a href="http://weitz.de/drakma">Drakma</a> to perform the HTTP
204 alternative <a href="http://www.lichteblau.com/cxml-stp/">cxml-stp</a>.
206 <example>(defun show-google-hits (term)
207 (let* ((query (list (cons "q" term)))
208 (str (drakma:http-request "http://www.google.com/search"
210 (document (chtml:parse str (cxml-stp:make-builder))))
211 (stp:do-recursively (a document)
212 (when (and (typep a 'stp:element)
213 (equal (stp:local-name a) "a")
214 (equal (stp:attribute-value a "class") "l"))
215 (format t "~A:~% ~A~%~%"
217 (stp:attribute-value a "href"))))))</example>
218 <result>SHOW-GOOGLE-HITS</result>
219 Searching for "lisp" we get these results:
220 <example>(show-google-hits "lisp")</example>
221 <result>Lisp (programming language) - Wikipedia, the free encyclopedia:
222 http://en.wikipedia.org/wiki/Lisp_programming_language
224 Lisp - Wikipedia, the free encyclopedia:
225 http://en.wikipedia.org/wiki/Lisp
227 Association of Lisp Users:
230 An Introduction and Tutorial for Common Lisp:
231 http://www.apl.jhu.edu/~hall/lisp.html
234 http://www.paulgraham.com/lisp.html
237 http://www.paulgraham.com/rootsoflisp.html
240 http://planet.lisp.org/
242 Practical Common Lisp:
243 http://www.gigamonkeys.com/book/
245 CLISP - an ANSI Common Lisp Implementation:
246 http://clisp.cons.org/
249 http://www.cs.cmu.edu/Groups/AI/html/faqs/lang/lisp/top.html</result>
252 <section>Serializing using WITH-HTML-OUTPUT</section>
254 <macro>with-html-output</macro>
255 <macro>with-element</macro>