1 <page title="Closure HTML Examples">
3 Simple examples using Closure HTML.
8 <div style="float: left">
9 <section>Parsing a string</section>
12 <fun>make-lhtml-builder</fun>
13 <fun>serialize-lhtml</fun>
14 <fun>make-string-sink</fun>
17 <p>Parse into LHTML:</p>
18 <example>(chtml:parse "<p>nada</p>" (chtml:make-lhtml-builder))</example>
19 <result>(:HTML NIL (:HEAD NIL) (:BODY NIL (:P NIL "nada")))</result>
21 <p>Serialize LHTML back into a string:</p>
22 <example>(chtml:serialize-lhtml * (chtml:make-string-sink))</example>
23 <result>"<HTML><HEAD></HEAD><BODY><P>nada</P></BODY></HTML>"</result>
25 <section>Parsing a file</section>
29 <fun>make-lhtml-builder</fun>
33 Note that the filename must be passed as a pathname (written
34 using <tt>#p</tt>), not just a
35 string, because a string would be interpreted as a literal HTML
36 document as in the first example above.
38 <example>(chtml:parse #p"example.html" (chtml:make-lhtml-builder))</example>
39 <result>(:HTML NIL (:HEAD NIL) (:BODY NIL (:P NIL "nada")))</result>
41 <section>Cleaning up broken HTML</section>
44 <fun>make-string-sink</fun>
48 Many HTML syntax errors are corrected by Closure HTML
49 automatically. In this example, we parse from a string and
50 serialize it back immediately.
52 <example>(defun clean-html (string)
53 (chtml:parse string (chtml:make-string-sink)))</example>
54 <result>CLEAN-HTML</result>
56 Note the differences between input and output in the following document:
59 <li><title> is moved into <head>.</li>
60 <li>The <tt>bogus</tt> attribute is removed.</li>
61 <li><br is corrected to <br> and </oops> to </p>.</li>
63 <example>(clean-html "<title>cleanup example</title>
66 </oops>")</example>
67 <result>"<HTML><HEAD><TITLE>cleanup example</TITLE></HEAD><BODY><P>
68 <BR></P></BODY></HTML>"</result>
70 <section>Translating an HTML file to XHTML</section>
73 <a href="http://common-lisp.net/project/cxml/sax.html#serialization">
74 cxml:make-octet-stream-sink
79 In this example, we parse an HTML file and serialize it into XHTML.
83 uses <a href="http://common-lisp.net/project/cxml">Closure XML</a>.
85 <example>(defun html2xhtml (file &key (if-exists :error))
86 (with-open-file (out (make-pathname :type "xml" :defaults file)
87 :element-type '(unsigned-byte 8)
90 (chtml:parse (pathname file)
91 (cxml:make-octet-stream-sink out))))</example>
92 <result>HTML2XHTML</result>
94 <example>(html2xhtml "/home/david/test.html" :if-exists :supersede)</example>
96 The following input file and its XHTML version illustrate some of
97 the differences between the two syntaxes.
101 <pre style="border: solid 1px #9c0000;
103 width: 60%;"><p>foo</p>
108 <option selected>123
114 <pre style="border: solid 1px #9c0000;
116 width: 60%;"><?xml version="1.0" encoding="UTF-8"?>
117 <html xmlns="http://www.w3.org/1999/xhtml"><head/><body><p>foo</p>
121 <select><option selected="selected">123
122 </option><option>456
123 </option></select>
124 </body></html></pre>
127 <section>Translating an XHTML file to HTML</section>
129 <a href="http://common-lisp.net/project/cxml/sax.html">
132 <fun>make-octet-stream-sink</fun>
136 This is a continuation of the opposite example above. In that
137 example, we converted an HTML file to HTML. Going back to HTML is
140 <example>(defun xhtml2html (file &key (if-exists :error))
141 (with-open-file (out (make-pathname :type "html" :defaults file)
142 :element-type '(unsigned-byte 8)
145 (cxml:parse (pathname file)
146 (chtml:make-octet-stream-sink out))))</example>
147 <result>XHTML2HTML</result>
148 Running this function on the example above results in a clean-up
149 version of the original document:
152 <pre style="border: solid 1px #9c0000;
154 width: 60%;"><html><head></head><body><p>foo</p>
158 <select><option selected>123
159 </option><option>456
160 </option></select>
161 </body></html></pre>
164 <section>Fetching and parsing Google search results</section>
167 <a href="http://weitz.de/drakma/#http-request">
170 <a href="http://www.lichteblau.com/cxml-stp/doc/pages/cxml-stp__fun__make-builder.html">
171 cxml-stp:make-builder
173 <a href="http://www.lichteblau.com/cxml-stp/doc/pages/cxml-stp__macro__do-recursively.html">
174 cxml-stp:do-recursively
176 <a href="http://www.lichteblau.com/cxml-stp/doc/pages/cxml-stp__class__element.html">
179 <a href="http://www.lichteblau.com/cxml-stp/doc/pages/cxml-stp__fun__local-name.html">
182 <a href="http://www.lichteblau.com/cxml-stp/doc/pages/cxml-stp__fun__attribute-value.html">
183 cxml-stp:attribute-value
188 In this example, we perform a google search and print the first ten
189 results by looking for all links of the form <a class="l">.
193 uses <a href="http://weitz.de/drakma">Drakma</a> to perform the HTTP
195 alternative <a href="http://www.lichteblau.com/cxml-stp/">cxml-stp</a>.
197 <example>(defun show-google-hits (term)
198 (let* ((query (list (cons "q" term)))
199 (str (drakma:http-request "http://www.google.com/search"
201 (document (chtml:parse str (cxml-stp:make-builder))))
202 (stp:do-recursively (a document)
203 (when (and (typep a 'stp:element)
204 (equal (stp:local-name a) "a")
205 (equal (stp:attribute-value a "class") "l"))
206 (format t "~A:~% ~A~%~%"
208 (stp:attribute-value a "href"))))))</example>
209 <result>SHOW-GOOGLE-HITS</result>
210 Searching for "lisp" we get these results:
211 <example>(show-google-hits "lisp")</example>
212 <result>Lisp (programming language) - Wikipedia, the free encyclopedia:
213 http://en.wikipedia.org/wiki/Lisp_programming_language
215 Lisp - Wikipedia, the free encyclopedia:
216 http://en.wikipedia.org/wiki/Lisp
218 Association of Lisp Users:
221 An Introduction and Tutorial for Common Lisp:
222 http://www.apl.jhu.edu/~hall/lisp.html
225 http://www.paulgraham.com/lisp.html
228 http://www.paulgraham.com/rootsoflisp.html
231 http://planet.lisp.org/
233 Practical Common Lisp:
234 http://www.gigamonkeys.com/book/
236 CLISP - an ANSI Common Lisp Implementation:
237 http://clisp.cons.org/
240 http://www.cs.cmu.edu/Groups/AI/html/faqs/lang/lisp/top.html</result>
243 <section>Serializing using WITH-HTML-OUTPUT</section>
245 <macro>with-html-output</macro>
246 <macro>with-element</macro>