Mercurial > geeqie
comparison doc/wiki2docbook/html2db/html2db.xsl @ 1773:2ae81598b254
scripts for converting wiki documentation to docbook
author | nadvornik |
---|---|
date | Sun, 22 Nov 2009 09:12:22 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1772:9f3b7a089caf | 1773:2ae81598b254 |
---|---|
1 <?xml version="1.0" encoding="utf-8"?> | |
2 <!-- Copyright 2004 by Laszlo Systems, Inc. | |
3 Released under the Artistic License. | |
4 Written by Oliver Steele. | |
5 Version 1.0.1 | |
6 http://osteele.com/sources/xslt/htm2db/ | |
7 --> | |
8 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" | |
9 xmlns:exslt="http://exslt.org/common" | |
10 xmlns:java="http://xml.apache.org/xalan/java" | |
11 xmlns:math="http://exslt.org/math" | |
12 xmlns:db="urn:docbook" | |
13 xmlns:h="http://www.w3.org/1999/xhtml" | |
14 exclude-result-prefixes="exslt java math db h" | |
15 version="1.0"> | |
16 | |
17 <!-- Prefixed to every id generated from <a name=> and <a href="#"> --> | |
18 <xsl:param name="anchor-id-prefix" select="''"/> | |
19 | |
20 <!-- Default document root; can be overridden by <?html2db class=> --> | |
21 <xsl:param name="document-root" select="'article'"/> | |
22 | |
23 <xsl:include href="html2db-utils.xsl"/> | |
24 | |
25 <!-- | |
26 Default templates | |
27 --> | |
28 | |
29 <!-- pass docbook elements through unchanged; just strip the prefix | |
30 --> | |
31 <xsl:template match="db:*"> | |
32 <xsl:element name="{local-name()}"> | |
33 <xsl:for-each select="@*"> | |
34 <xsl:attribute name="{name()}"> | |
35 <xsl:value-of select="."/> | |
36 </xsl:attribute> | |
37 </xsl:for-each> | |
38 <xsl:apply-templates/> | |
39 </xsl:element> | |
40 </xsl:template> | |
41 | |
42 <xsl:template match="@id"> | |
43 <xsl:copy/> | |
44 </xsl:template> | |
45 | |
46 <!-- copy processing instructions, too --> | |
47 <xsl:template match="processing-instruction()"> | |
48 <xsl:copy/> | |
49 </xsl:template> | |
50 | |
51 <!-- except for html2db instructions --> | |
52 <xsl:template match="processing-instruction('html2db')"/> | |
53 | |
54 <!-- Warn about any html elements that don't match a more | |
55 specific template. Copy them too, since it's often | |
56 easier to find them in the output. --> | |
57 <xsl:template match="h:*"> | |
58 <xsl:message terminate="no"> | |
59 Unknown element <xsl:value-of select="name()"/> | |
60 </xsl:message> | |
61 <xsl:copy> | |
62 <xsl:apply-templates/> | |
63 </xsl:copy> | |
64 </xsl:template> | |
65 | |
66 <!-- | |
67 Root element and body | |
68 --> | |
69 | |
70 <!-- ignore everything except the body --> | |
71 <xsl:template match="/"> | |
72 <xsl:apply-templates select="//h:body"/> | |
73 </xsl:template> | |
74 | |
75 <xsl:template match="h:body"> | |
76 <xsl:variable name="class-pi" | |
77 select="processing-instruction('html2db')[starts-with(string(), 'class="')][1]"/> | |
78 <xsl:variable name="class"> | |
79 <xsl:choose> | |
80 <xsl:when test="count($class-pi)!=0"> | |
81 <xsl:value-of select="substring-before(substring-after(string($class-pi[0]), 'class="'), '"')"/> | |
82 </xsl:when> | |
83 <xsl:otherwise> | |
84 <xsl:value-of select="$document-root"/> | |
85 </xsl:otherwise> | |
86 </xsl:choose> | |
87 </xsl:variable> | |
88 | |
89 <!-- Warn if there are any text nodes outside a para, etc. See | |
90 the note at the naked text template for why this is a | |
91 warning. --> | |
92 <xsl:if test="text()[normalize-space() != '']"> | |
93 <xsl:message terminate="no"> | |
94 Text must be inside a <p> tag. | |
95 </xsl:message> | |
96 </xsl:if> | |
97 | |
98 <xsl:element name="{$class}"> | |
99 <xsl:apply-templates select="@id"/> | |
100 <xsl:call-template name="section-content"> | |
101 <xsl:with-param name="level" select="1"/> | |
102 <xsl:with-param name="nodes" select="//h:body/node()|//h:body/text()"/> | |
103 </xsl:call-template> | |
104 </xsl:element> | |
105 </xsl:template> | |
106 | |
107 <!-- | |
108 Section and section title processing | |
109 --> | |
110 | |
111 <!-- | |
112 Nest elements that *follow* an h1, h2, etc. into <section> elements | |
113 such that the <h1> content is the section's <title>. | |
114 --> | |
115 <xsl:template name="section-content"> | |
116 <xsl:param name="level"/> | |
117 <xsl:param name="nodes"/> | |
118 <xsl:param name="h1" select="concat('h', $level)"/> | |
119 <xsl:param name="h2" select="concat('h', $level+1)"/> | |
120 <xsl:param name="h2-position" select="count(exslt:node-set($nodes)[1]/following-sibling::*[local-name()=$h2])"/> | |
121 | |
122 <!-- copy up to first h2 --> | |
123 <xsl:apply-templates select="exslt:node-set($nodes)[ | |
124 count(following-sibling::*[local-name()=$h2])=$h2-position | |
125 ]"/> | |
126 | |
127 <!-- if section is empty, add an empty para so it will validate --> | |
128 <xsl:if test="not(exslt:node-set($nodes)/h:para[ | |
129 count(following-sibling::*[local-name()=$h2])=$h2-position | |
130 ])"> | |
131 <para/> | |
132 </xsl:if> | |
133 | |
134 <!-- subsections --> | |
135 <xsl:for-each select="exslt:node-set($nodes)[local-name()=$h2]"> | |
136 <section> | |
137 <xsl:variable name="mynodes" select="exslt:node-set($nodes)[ | |
138 count(following-sibling::*[local-name()=$h2])= | |
139 count(current()/following-sibling::*[local-name()=$h2])]"/> | |
140 <xsl:for-each select="exslt:node-set($mynodes)[local-name()=$h2]"> | |
141 <xsl:choose> | |
142 <xsl:when test="@id"> | |
143 <xsl:apply-templates select="@id"/> | |
144 </xsl:when> | |
145 <xsl:when test="h:a/@name"> | |
146 <xsl:attribute name="id"> | |
147 <xsl:value-of select="concat($anchor-id-prefix, h:a/@name)"/> | |
148 </xsl:attribute> | |
149 </xsl:when> | |
150 </xsl:choose> | |
151 </xsl:for-each> | |
152 <xsl:call-template name="section-content"> | |
153 <xsl:with-param name="level" select="$level+1"/> | |
154 <xsl:with-param name="nodes" select="exslt:node-set($nodes)[ | |
155 count(following-sibling::*[local-name()=$h2])= | |
156 count(current()/following-sibling::*[local-name()=$h2])]"/> | |
157 </xsl:call-template> | |
158 </section> | |
159 </xsl:for-each> | |
160 </xsl:template> | |
161 | |
162 <!-- | |
163 Remove anchors from hn titles. section-content attaches these as ids | |
164 to the section (after mutilating them as described in the docs). | |
165 --> | |
166 <xsl:template match="h:h1|h:h2|h:h3|h:h4|h:h5|h:h6"> | |
167 <title> | |
168 <xsl:apply-templates mode="skip-anchors" select="node()"/> | |
169 </title> | |
170 </xsl:template> | |
171 | |
172 <xsl:template mode="skip-anchors" match="h:a[@name]"> | |
173 <xsl:apply-templates/> | |
174 </xsl:template> | |
175 | |
176 <xsl:template mode="skip-anchors" match="node()"> | |
177 <xsl:apply-templates select="."/> | |
178 </xsl:template> | |
179 | |
180 <!-- | |
181 Inline elements | |
182 --> | |
183 <xsl:template match="h:b|h:i|h:em|h:strong"> | |
184 <emphasis role="{local-name()}"> | |
185 <xsl:apply-templates/> | |
186 </emphasis> | |
187 </xsl:template> | |
188 | |
189 <xsl:template match="h:dfn"> | |
190 <indexterm significance="preferred"> | |
191 <primary><xsl:apply-templates/></primary> | |
192 </indexterm> | |
193 <glossterm><xsl:apply-templates/></glossterm> | |
194 </xsl:template> | |
195 | |
196 <xsl:template match="h:var"> | |
197 <replaceable><xsl:apply-templates/></replaceable> | |
198 </xsl:template> | |
199 | |
200 <!-- | |
201 Inline elements in code | |
202 --> | |
203 <xsl:template match="h:code/h:i|h:tt/h:i|h:pre/h:i"> | |
204 <replaceable> | |
205 <xsl:apply-templates/> | |
206 </replaceable> | |
207 </xsl:template> | |
208 | |
209 <xsl:template match="h:code|h:tt"> | |
210 <literal> | |
211 <xsl:if test="@class"> | |
212 <xsl:attribute name="role"><xsl:value-of select="@class"/></xsl:attribute> | |
213 </xsl:if> | |
214 <xsl:apply-templates/> | |
215 </literal> | |
216 </xsl:template> | |
217 | |
218 <!-- For now, everything that doesn't have a specific match in inline | |
219 processing mode is matched against the default processing mode. --> | |
220 <xsl:template mode="inline" match="*"> | |
221 <xsl:apply-templates select="."/> | |
222 </xsl:template> | |
223 | |
224 <!-- | |
225 Block elements | |
226 --> | |
227 <xsl:template match="h:p"> | |
228 <para> | |
229 <xsl:apply-templates select="@id"/> | |
230 <xsl:apply-templates mode="inline"/> | |
231 </para> | |
232 </xsl:template> | |
233 | |
234 <!-- Wrap naked text nodes in a <para> so that they'll process more | |
235 correctly. The h:body also warns about these, because even | |
236 this preprocessing step isn't guaranteed to fix them. This is | |
237 because "Some <i>italic</i> text" will be preprocessed into | |
238 "<para>Some </para> <emphasis>italic</emphasis><para> | |
239 text</para>" instead of "<para>Some <emphasis>italic</emphasis> | |
240 text</para>". Getting this right would require more work than | |
241 just maintaining the source documents. --> | |
242 <xsl:template match="h:body/text()[normalize-space()!= '']"> | |
243 <!-- add an invalid tag to make it easy to find this in | |
244 the generated file --> | |
245 <naked-text> | |
246 <para> | |
247 <xsl:apply-templates/> | |
248 </para> | |
249 </naked-text> | |
250 </xsl:template> | |
251 | |
252 <xsl:template match="h:body/h:code|h:pre"> | |
253 <programlisting> | |
254 <xsl:apply-templates/> | |
255 </programlisting> | |
256 </xsl:template> | |
257 | |
258 <xsl:template match="h:blockquote"> | |
259 <blockquote> | |
260 <xsl:apply-templates mode="item" select="."/> | |
261 </blockquote> | |
262 </xsl:template> | |
263 | |
264 <!-- | |
265 Images | |
266 --> | |
267 <xsl:template name="imageobject"> | |
268 <imageobject> | |
269 <imagedata fileref="{@src}"> | |
270 <xsl:apply-templates select="@width|@height"/> | |
271 </imagedata> | |
272 </imageobject> | |
273 </xsl:template> | |
274 | |
275 <xsl:template match="h:img/@width"> | |
276 <xsl:copy/> | |
277 </xsl:template> | |
278 | |
279 <xsl:template match="h:img"> | |
280 <xsl:param name="informal"> | |
281 <xsl:if test="not(@title) and not(db:title)">informal</xsl:if> | |
282 </xsl:param> | |
283 <xsl:element name="{$informal}figure"> | |
284 <xsl:apply-templates select="@id"/> | |
285 <xsl:choose> | |
286 <xsl:when test="@title"> | |
287 <title><xsl:value-of select="@title"/></title> | |
288 </xsl:when> | |
289 <xsl:otherwise> | |
290 <xsl:apply-templates select="db:title"/> | |
291 </xsl:otherwise> | |
292 </xsl:choose> | |
293 <mediaobject> | |
294 <xsl:call-template name="imageobject"/> | |
295 <xsl:if test="@alt and normalize-space(@alt)!=''"> | |
296 <caption> | |
297 <para> | |
298 <xsl:value-of select="@alt"/> | |
299 </para> | |
300 </caption> | |
301 </xsl:if> | |
302 </mediaobject> | |
303 </xsl:element> | |
304 </xsl:template> | |
305 | |
306 <xsl:template mode="inline" match="h:img"> | |
307 <inlinemediaobject> | |
308 <xsl:apply-templates select="@id"/> | |
309 <xsl:call-template name="imageobject"/> | |
310 </inlinemediaobject> | |
311 </xsl:template> | |
312 | |
313 <!-- | |
314 links | |
315 --> | |
316 | |
317 <!-- anchors --> | |
318 <xsl:template match="h:a[@name]"> | |
319 <anchor id="{$anchor-id-prefix}{@name}"/> | |
320 <xsl:apply-templates/> | |
321 </xsl:template> | |
322 | |
323 <!-- internal link --> | |
324 <xsl:template match="h:a[starts-with(@href, '#')]"> | |
325 <link linkend="{$anchor-id-prefix}{substring-after(@href, '#')}"> | |
326 <xsl:apply-templates select="@*"/> | |
327 <xsl:apply-templates/> | |
328 </link> | |
329 </xsl:template> | |
330 | |
331 <!-- external link --> | |
332 <xsl:template match="h:a"> | |
333 <ulink url="{@href}"> | |
334 <xsl:apply-templates select="@*"/> | |
335 <xsl:apply-templates/> | |
336 </ulink> | |
337 </xsl:template> | |
338 | |
339 <!-- email --> | |
340 <xsl:template match="h:a[starts-with(@href, 'mailto:')]"> | |
341 <email> | |
342 <xsl:apply-templates select="@*"/> | |
343 <xsl:value-of select="substring-after(@href, 'mailto:')"/> | |
344 </email> | |
345 </xsl:template> | |
346 | |
347 <!-- link attributes --> | |
348 | |
349 <xsl:template match="h:a/@*"/> | |
350 | |
351 <xsl:template match="h:a/@id"> | |
352 <xsl:apply-templates select="@id"/> | |
353 </xsl:template> | |
354 | |
355 <xsl:template match="h:a/@target|h:a/@link"> | |
356 <xsl:processing-instruction name="db2html"> | |
357 <xsl:text>attribute name="</xsl:text> | |
358 <xsl:value-of select="name()"/> | |
359 <xsl:text>" value=</xsl:text> | |
360 <xsl:call-template name="quote"/> | |
361 </xsl:processing-instruction> | |
362 </xsl:template> | |
363 | |
364 <!-- | |
365 lists | |
366 --> | |
367 | |
368 <xsl:template match="h:dl"> | |
369 <variablelist> | |
370 <xsl:apply-templates select="db:*"/> | |
371 <xsl:apply-templates select="h:dt"/> | |
372 </variablelist> | |
373 </xsl:template> | |
374 | |
375 <xsl:template match="h:dt"> | |
376 <xsl:variable name="item-number" select="count(preceding-sibling::h:dt)+1"/> | |
377 <varlistentry> | |
378 <term> | |
379 <xsl:apply-templates/> | |
380 </term> | |
381 <listitem> | |
382 <!-- Select the dd that follows this dt without an intervening dd --> | |
383 <xsl:apply-templates mode="item" | |
384 select="following-sibling::h:dd[ | |
385 count(preceding-sibling::h:dt)=$item-number | |
386 ]"/> | |
387 <!-- If there is no such dd, then insert an empty para --> | |
388 <xsl:if test="count(following-sibling::h:dd[ | |
389 count(preceding-sibling::h:dt)=$item-number | |
390 ])=0"> | |
391 <para/> | |
392 </xsl:if> | |
393 </listitem> | |
394 </varlistentry> | |
395 </xsl:template> | |
396 | |
397 <xsl:template mode="item" match="*[count(h:p) = 0]"> | |
398 <para> | |
399 <xsl:apply-templates/> | |
400 </para> | |
401 </xsl:template> | |
402 | |
403 <xsl:template mode="nonblank-nodes" match="node()"> | |
404 <xsl:element name="{local-name()}"/> | |
405 </xsl:template> | |
406 | |
407 <xsl:template mode="nonblank-nodes" match="text()[normalize-space()='']"/> | |
408 | |
409 <xsl:template mode="nonblank-nodes" match="text()"> | |
410 <text/> | |
411 </xsl:template> | |
412 | |
413 <xsl:template mode="item" match="*"> | |
414 <!-- Test whether the first non-blank node is not a p --> | |
415 <xsl:param name="nonblank-nodes"> | |
416 <xsl:apply-templates mode="nonblank-nodes"/> | |
417 </xsl:param> | |
418 | |
419 <xsl:param name="tested" select=" | |
420 count(exslt:node-set($nonblank-nodes)/*) != 0 and | |
421 local-name(exslt:node-set($nonblank-nodes)/*[1]) != 'p'"/> | |
422 | |
423 <xsl:param name="n1" select="count(*[1]/following::h:p)"/> | |
424 <xsl:param name="n2" select="count(text()[1]/following::h:p)"/> | |
425 | |
426 <xsl:param name="n"> | |
427 <xsl:if test="$tested"> | |
428 <xsl:value-of select="java:java.lang.Math.max($n1, $n2)"/> | |
429 </xsl:if> | |
430 </xsl:param> | |
431 | |
432 <xsl:if test="false()"> | |
433 <nodeset tested="{$tested}" count="{count(exslt:node-set($nonblank-nodes)/*)}"> | |
434 <xsl:for-each select="exslt:node-set($nonblank-nodes)/*"> | |
435 <element name="{local-name()}"/> | |
436 </xsl:for-each> | |
437 </nodeset> | |
438 </xsl:if> | |
439 | |
440 <!-- Wrap everything before the first p into a para --> | |
441 <xsl:if test="$tested"> | |
442 <para> | |
443 <xsl:apply-templates select=" | |
444 node()[count(following::h:p)=$n] | | |
445 text()[count(following::h:p)=$n]"/> | |
446 </para> | |
447 </xsl:if> | |
448 <xsl:apply-templates select=" | |
449 node()[count(following::h:p)!=$n] | | |
450 text()[count(following::h:p)!=$n]"/> | |
451 </xsl:template> | |
452 | |
453 <xsl:template match="h:ol"> | |
454 <orderedlist spacing="compact"> | |
455 <xsl:for-each select="h:li"> | |
456 <listitem> | |
457 <xsl:apply-templates mode="item" select="."/> | |
458 </listitem> | |
459 </xsl:for-each> | |
460 </orderedlist> | |
461 </xsl:template> | |
462 | |
463 <xsl:template match="h:ul"> | |
464 <itemizedlist spacing="compact"> | |
465 <xsl:for-each select="h:li"> | |
466 <listitem> | |
467 <xsl:apply-templates mode="item" select="."/> | |
468 </listitem> | |
469 </xsl:for-each> | |
470 </itemizedlist> | |
471 </xsl:template> | |
472 | |
473 <xsl:template match="h:ul[processing-instruction('html2db')]"> | |
474 <simplelist> | |
475 <xsl:for-each select="h:li"> | |
476 <member type="vert"> | |
477 <xsl:apply-templates mode="item" select="."/> | |
478 </member> | |
479 </xsl:for-each> | |
480 </simplelist> | |
481 </xsl:template> | |
482 | |
483 <!-- | |
484 ignored markup | |
485 --> | |
486 <xsl:template match="h:br"> | |
487 <xsl:processing-instruction name="db2html"> | |
488 <xsl:text>element="</xsl:text> | |
489 <xsl:value-of select="local-name()"/> | |
490 <xsl:text>"</xsl:text> | |
491 </xsl:processing-instruction> | |
492 </xsl:template> | |
493 | |
494 <xsl:template match="h:span|h:div"> | |
495 <xsl:apply-templates select="*|node()|text()"/> | |
496 </xsl:template> | |
497 | |
498 <!-- | |
499 Utility functions and templates for tables | |
500 --> | |
501 <xsl:template mode="count-columns" match="h:tr"> | |
502 <n> | |
503 <xsl:value-of select="count(h:td)"/> | |
504 </n> | |
505 </xsl:template> | |
506 | |
507 <!-- tables --> | |
508 <xsl:template match="h:table"> | |
509 <xsl:param name="informal"> | |
510 <xsl:if test="not(@summary)">informal</xsl:if> | |
511 </xsl:param> | |
512 <xsl:param name="colcounts"> | |
513 <xsl:apply-templates mode="count-columns" select=".//h:tr"/> | |
514 </xsl:param> | |
515 <xsl:param name="cols" select="math:max(exslt:node-set($colcounts)/n)"/> | |
516 <xsl:param name="sorted"> | |
517 <xsl:for-each select="exslt:node-set($colcounts)/n"> | |
518 <xsl:sort order="descending" data-type="number"/> | |
519 <n><xsl:value-of select="."/></n> | |
520 </xsl:for-each> | |
521 </xsl:param> | |
522 <xsl:element name="{$informal}table"> | |
523 <xsl:apply-templates select="@id"/> | |
524 <xsl:if test="processing-instruction('html2db')[starts-with(., 'rowsep')]"> | |
525 <xsl:attribute name="rowsep">1</xsl:attribute> | |
526 </xsl:if> | |
527 <xsl:apply-templates select="processing-instruction()"/> | |
528 <xsl:if test="@summary"> | |
529 <title><xsl:value-of select="@summary"/></title> | |
530 </xsl:if> | |
531 <tgroup cols="{$cols}"> | |
532 <xsl:if test=".//h:tr/h:th"> | |
533 <thead> | |
534 <xsl:for-each select=".//h:tr[count(h:th)!=0]"> | |
535 <row> | |
536 <xsl:apply-templates select="@id"/> | |
537 <xsl:for-each select="h:td|h:th"> | |
538 <entry> | |
539 <xsl:apply-templates select="@id"/> | |
540 <xsl:apply-templates/> | |
541 </entry> | |
542 </xsl:for-each> | |
543 </row> | |
544 <xsl:text> </xsl:text> <!-- cr --> | |
545 </xsl:for-each> | |
546 </thead> | |
547 </xsl:if> | |
548 <tbody> | |
549 <xsl:for-each select=".//h:tr[count(h:th)=0]"> | |
550 <row> | |
551 <xsl:apply-templates select="@id"/> | |
552 <xsl:for-each select="h:td|h:th"> | |
553 <entry> | |
554 <xsl:apply-templates select="@id"/> | |
555 <xsl:apply-templates/> | |
556 </entry> | |
557 </xsl:for-each> | |
558 </row> | |
559 <xsl:text> </xsl:text> <!-- cr --> | |
560 </xsl:for-each> | |
561 </tbody> | |
562 </tgroup> | |
563 </xsl:element> | |
564 </xsl:template> | |
565 </xsl:stylesheet> |