Update to version V0.5.0.
[docutils/kirr.git] / sandbox / xml2rst / xml2rst.xsl
blobc27a4200f56aea5a3461747850dc267004637ead
1 <?xml version="1.0" encoding="utf-8"?>
2 <!DOCTYPE xsl:stylesheet [
3 <!ENTITY CR "&#x0A;">
4 <!-- "xml:space='preserve'" is needed for use with libxslt -->
5 <!-- "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'" is needed for
6 use with xsltproc -->
7 <!-- Used to create a blank line -->
8 <!ENTITY tCR "<xsl:text xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xml:space='preserve'>&CR;</xsl:text>">
9 <!-- Used when the line before must be ended -->
10 <!ENTITY tEOL "<xsl:text xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xml:space='preserve'>&CR;</xsl:text>">
11 <!ENTITY tSP "<xsl:text xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xml:space='preserve'> </xsl:text>">
14 <!--
15 Copyright (C) 2005, 2006 Stefan Merten, David Priest
16 Copyright (C) 2009, 2010 Stefan Merten
18 xml2rst.xsl is free software; you can redistribute it and/or modify
19 it under the terms of the GNU General Public License as published
20 by the Free Software Foundation; either version 2 of the License,
21 or (at your option) any later version.
23 This program is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 General Public License for more details.
28 You should have received a copy of the GNU General Public License
29 along with this program; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
31 02111-1307, USA.
32 -->
34 <!-- ********************************************************************** -->
35 <!-- ********************************************************************** -->
37 <!-- These elements in the DTD need support:
39 - ``colspec`` has attribute "stub %yesorno; #IMPLIED"
41 - ``document`` has attribute "title CDATA #IMPLIED"
43 Probably rendered by the `.. title::` directive
45 -->
47 <!--
48 Set namespace extensions. These are used as [shortname]:[tag] throughout the
49 XSL-FO files.
50 xsl: eXtensible Stylesheet Language
51 u: user extensions (indicates utility 'call-template' routines defined in
52 these XSL files)
53 data: Data elements used by the stylesheet
54 -->
55 <xsl:stylesheet
56 version="1.0"
57 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
58 xmlns:u="u"
59 xmlns:data="a"
60 exclude-result-prefixes="data"
61 xmlns:str="http://exslt.org/strings"
62 xmlns:dyn="http://exslt.org/dynamic"
63 xmlns:math="http://exslt.org/math"
64 extension-element-prefixes="str dyn math">
66 <!-- xmlns:regexp="http://exslt.org/regular-expressions" not supported :-( -->
68 <xsl:output
69 method="text"
70 omit-xml-declaration="yes"
71 indent="no"/>
73 <!-- ******************************************************************** -->
74 <!-- ******************************************************************** -->
76 <!-- Parameter to configure title markup; see manual page for description -->
77 <xsl:param
78 name="adornment"
79 select="'o=o-u=u-u~u`u,u.'"/>
81 <!-- Parameter for folding long lines; see manual page for description -->
82 <xsl:param
83 name="fold"
84 select="0"/>
86 <!-- ******************************************************************** -->
87 <!-- ******************************************************************** -->
89 <xsl:variable
90 name="apos"
91 select='"&apos;"'/>
93 <xsl:variable
94 name="structural_elements"
95 select="'*document*section*topic*sidebar*'"/>
97 <xsl:variable
98 name="structural_subelements"
99 select="'*title*subtitle*docinfo*decoration*transition*'"/>
101 <xsl:variable
102 name="bibliographic_elements"
103 select="'*address*author*authors*contact*copyright*date*field*organization*revision*status*version*'"/>
105 <xsl:variable
106 name="decorative_elements"
107 select="'*footer*header*'"/>
109 <xsl:variable
110 name="simple_body_elements_no_substitution"
111 select="'*comment*doctest_block*image*literal_block*paragraph*pending*raw*rubric*target*'"/>
113 <xsl:variable
114 name="folding_elements"
115 select="concat('*comment*paragraph*rubric*attribution*caption*line*', substring-after($bibliographic_elements, '*'))"/>
117 <xsl:variable
118 name="simple_body_elements"
119 select="concat($simple_body_elements_no_substitution, 'substitution_definition*')"/>
121 <xsl:variable
122 name="compound_body_elements"
123 select="'*admonition*attention*block_quote*bullet_list*caution*citation*compound*danger*definition_list*enumerated_list*error*field_list*figure*footnote*hint*important*line_block*note*option_list*system_message*table*tip*warning*container*'"/>
125 <xsl:variable
126 name="body_elements"
127 select="concat($simple_body_elements, substring-after($compound_body_elements, '*'))"/>
129 <xsl:variable
130 name="admonitions"
131 select="'*admonition*attention*caution*danger*error*hint*important*note*tip*warning*'"/>
133 <xsl:variable
134 name="simple_body_subelements"
135 select="'*attribution*caption*classifier*colspec*field_name*label*line*option_argument*option_string*term*'"/>
137 <xsl:variable
138 name="compound_body_subelements"
139 select="'*definition*definition_list_item*description*entry*field*field_body*legend*list_item*option*option_group*option_list_item*row*tbody*tgroup*thead*'"/>
141 <xsl:variable
142 name="inline_elements"
143 select="'*abbreviation*acronym*citation_reference*emphasis*footnote_reference*generated*image*inline*literal*problematic*reference*strong*subscript*substitution_reference*superscript*target*title_reference*raw*'"/>
145 <xsl:variable
146 name="inline_containers"
147 select="concat($simple_body_elements_no_substitution, substring-after($inline_elements, '*'))"/>
149 <xsl:variable
150 name="directives"
151 select="'*admonition*attention*caution*comment*danger*error*footnote*hint*important*note*tip*warning*image*figure*topic*sidebar*rubric*meta*raw*citation*compound*substitution_definition*container*'"/>
153 <xsl:variable
154 name="titled_elements"
155 select="'*sidebar*topic*admonition*'"/>
157 <xsl:variable
158 name="blank_after"
159 select="concat($structural_elements, substring-after($structural_subelements, '*'), substring-after($body_elements, '*'))"/>
161 <xsl:variable
162 name="adornment_characters"
163 select="concat($apos, '!&quot;#$%&amp;()*+,-./:;&lt;=&gt;?@[\]^_`{|}~')"/>
165 <!-- ******************************************************************** -->
166 <!-- ******************************************************************** -->
168 <!--
169 Content Model: ((title, subtitle?)?, docinfo?, decoration?,
170 %structure.model;)
172 Attributes: The document element contains only the common attributes: ids,
173 names, dupnames, source, and classes.
175 Depending on the source of the data and the stage of processing, the
176 "document" may not initially contain a "title". A document title is not
177 directly representable in reStructuredText. Instead, a lone top-level section
178 may have its title promoted to become the document title, and similarly for a
179 lone second-level (sub)section's title to become the document subtitle. The
180 "docinfo" may be transformed from an initial field_list, and "decoration" is
181 usually constructed programmatically.
183 <!-- == structural_element -->
184 <xsl:template
185 match="document">
186 <xsl:if
187 test="//generated[@classes = 'sectnum']">
188 <xsl:text>.. section-numbering::</xsl:text>
189 &tEOL;
190 &tCR;
191 </xsl:if>
192 <xsl:call-template
193 name="u:outputClass">
194 <xsl:with-param
195 name="blankAfter"
196 select="true()"/>
197 </xsl:call-template>
198 <xsl:apply-templates/>
199 </xsl:template>
201 <!-- ******************************************************************** -->
203 <!--
204 Content Model: (title, %structure.model;)
205 Attributes: The section element contains only the common attributes: ids,
206 names, dupnames, source, and classes.
208 <!-- == structural_element -->
209 <xsl:template
210 match="section">
211 <xsl:call-template
212 name="u:outputClass"/>
213 <xsl:call-template
214 name="u:blank"/>
215 <xsl:apply-templates/>
216 </xsl:template>
218 <!-- == structural_element -->
219 <xsl:template
220 match="section[@classes = 'system-messages']"/>
221 <!-- Ignore system messages completely -->
222 <!-- This should be really in `generated' -->
224 <!-- ******************************************************************** -->
226 <!--
227 Content Model: (title, subtitle?, (%body.elements;)+)
228 Attributes: The sidebar element contains only the common attributes: ids,
229 names, dupnames, source, and classes.
231 <!-- == structural_element == directive -->
232 <xsl:template
233 match="sidebar">
234 <xsl:call-template
235 name="u:BandI"/>
236 <xsl:text>.. sidebar:: </xsl:text>
237 <xsl:value-of
238 select="title"/>
239 &tEOL;
240 <xsl:if
241 test="subtitle">
242 <xsl:call-template
243 name="u:param">
244 <xsl:with-param
245 name="name"
246 select="'subtitle'"/>
247 <xsl:with-param
248 name="value"
249 select="subtitle"/>
250 <xsl:with-param
251 name="ancestors"
252 select="ancestor-or-self::*"/>
253 </xsl:call-template>
254 </xsl:if>
255 <xsl:call-template
256 name="u:params"/>
257 <!-- Always blank line after parameter block -->
258 &tCR;
259 <xsl:apply-templates
260 select="*[not(self::title) and not(self::subtitle)]"/>
261 </xsl:template>
263 <!-- ******************************************************************** -->
265 <!--
266 Content Model: (title?, (%body.elements;)+)
267 Attributes: The topic element contains only the common attributes: ids,
268 names, dupnames, source, and classes.
270 <!-- == structural_element == directive -->
271 <xsl:template
272 match="topic">
273 <xsl:call-template
274 name="u:BandI"/>
275 <xsl:text>.. topic:: </xsl:text>
276 <xsl:value-of
277 select="title"/>
278 &tEOL;
279 <xsl:call-template
280 name="u:params"/>
281 <xsl:apply-templates
282 select="*[not(self::title)]"/>
283 </xsl:template>
285 <!-- == structural_element == directive -->
286 <xsl:template
287 match="topic[starts-with(@classes, 'contents')]">
288 <xsl:call-template
289 name="u:BandI"/>
290 <xsl:text>.. contents:: </xsl:text>
291 <xsl:apply-templates
292 select="title"/>
293 &tEOL;
294 <xsl:call-template
295 name="u:params">
296 <xsl:with-param
297 name="params"
298 select="@*[name() != 'ids' and name() != 'names' and name() != 'classes']"/>
299 </xsl:call-template>
300 <xsl:variable
301 name="isLocal"
302 select="substring-before(@classes, ' local')"/>
303 <xsl:variable
304 name="realClassesLocal"
305 select="normalize-space(substring-after(@classes, 'contents'))"/>
306 <xsl:variable
307 name="realClassesNode">
308 <xsl:choose>
309 <xsl:when
310 test="$isLocal">
311 <xsl:value-of
312 select="normalize-space(substring-before($realClassesLocal, 'local'))"/>
313 </xsl:when>
314 <xsl:otherwise>
315 <xsl:value-of
316 select="$realClassesLocal"/>
317 </xsl:otherwise>
318 </xsl:choose>
319 </xsl:variable>
320 <xsl:variable
321 name="realClasses"
322 select="string($realClassesNode)"/>
323 <xsl:if
324 test="$isLocal">
325 <xsl:call-template
326 name="u:param">
327 <xsl:with-param
328 name="name"
329 select="'local'"/>
330 <xsl:with-param
331 name="value"
332 select="''"/>
333 <xsl:with-param
334 name="ancestors"
335 select="ancestor-or-self::*"/>
336 </xsl:call-template>
337 </xsl:if>
338 <xsl:if
339 test="$realClasses">
340 <xsl:call-template
341 name="u:param">
342 <xsl:with-param
343 name="name"
344 select="'class'"/>
345 <xsl:with-param
346 name="value"
347 select="$realClasses"/>
348 <xsl:with-param
349 name="ancestors"
350 select="ancestor-or-self::*"/>
351 </xsl:call-template>
352 </xsl:if>
353 <!-- Autogenerated content is discarded -->
354 &tCR;
355 </xsl:template>
357 <!-- == structural_element == directive -->
358 <xsl:template
359 match="topic[@classes='dedication' or @classes='abstract']">
360 <xsl:call-template
361 name="u:BandI"/>
362 <xsl:text>:</xsl:text>
363 <xsl:apply-templates
364 select="title"/>
365 <xsl:text>: </xsl:text>
366 &tEOL;
367 <xsl:apply-templates
368 select="*[not(self::title)]"/>
369 </xsl:template>
371 <!-- ******************************************************************** -->
373 <!--
374 Content Model: (title, (%body.elements;)+)
375 Attributes: The admonition element contains only the common attributes:
376 ids, names, dupnames, source, and classes.
378 <!-- == compound_body_element == directive -->
379 <xsl:template
380 match="admonition">
381 <xsl:call-template
382 name="u:BandI"/>
383 <xsl:text>.. admonition:: </xsl:text>
384 <xsl:apply-templates
385 select="title"/>
386 &tEOL;
387 <xsl:call-template
388 name="u:params">
389 <xsl:with-param
390 name="params"
391 select="@*[name() != 'classes' or not(starts-with(., 'admonition-'))]"/>
392 </xsl:call-template>
393 <xsl:call-template
394 name="u:indent"/>
395 <xsl:apply-templates
396 select="*[not(self::title)]"/>
397 </xsl:template>
399 <!-- ******************************************************************** -->
401 <!--
402 Content Model: (%body.elements;)+
403 Attributes: The note element contains only the common attributes: ids,
404 names, dupnames, source, and classes.
406 <!-- == compound_body_element == directive -->
407 <xsl:template
408 match="attention | caution | danger | error | hint | important | note | tip | warning">
409 <xsl:call-template
410 name="u:outputClass"/>
411 <xsl:call-template
412 name="u:BandI"/>
413 <xsl:text>.. </xsl:text>
414 <xsl:value-of
415 select="name()"/>
416 <xsl:text>:: </xsl:text>
417 <xsl:call-template
418 name="u:params">
419 <xsl:with-param
420 name="params"
421 select="@*[name() != 'classes']"/>
422 </xsl:call-template>
423 <xsl:apply-templates/>
424 </xsl:template>
426 <!-- ******************************************************************** -->
428 <!--
429 Content Model: (header?, footer?)
430 Attributes: The decoration element contains only the common attributes:
431 ids, names, dupnames, source, and classes.
433 Although the content model doesn't specifically require contents, no empty
434 decoration elements are ever created.
436 <!-- == structural_subelement -->
437 <xsl:template
438 match="//document/decoration">
439 <xsl:apply-templates/>
440 </xsl:template>
442 <!-- TODO To be rendered as `.. header::` directive -->
443 <!-- == decorative_element -->
444 <xsl:template
445 match="//document/decoration/header">
446 <xsl:apply-templates/>
447 </xsl:template>
449 <!-- TODO To be rendered as `.. footer::` directive -->
450 <!-- == decorative_element -->
451 <xsl:template
452 match="//document/decoration/footer">
453 <xsl:apply-templates/>
454 </xsl:template>
456 <!-- ******************************************************************** -->
458 <!--
459 Content Model: (%bibliographic.elements;)+
460 Attributes: The docinfo element contains only the common attributes: ids,
461 names, dupnames, source, and classes.
463 <!-- == structural_subelement -->
464 <xsl:template
465 match="docinfo">
466 <xsl:call-template
467 name="u:outputClass"/>
468 <xsl:call-template
469 name="u:blank"/>
470 <xsl:apply-templates/>
471 </xsl:template>
473 <!-- ******************************************************************** -->
475 <!--
476 Content Model: ((author, organization?, address?, contact?)+)
477 Attributes: The authors element contains only the common attributes: ids,
478 names, dupnames, source, and classes.
480 In reStructuredText, multiple author's names are separated with semicolons
481 (";") or commas (","); semicolons take precedence. There is currently no way
482 to represent the author's organization, address, or contact in a
483 reStructuredText "Authors" field.
485 <!-- == bibliographic_element == folding_element -->
486 <xsl:template
487 match="docinfo/authors">
488 <xsl:call-template
489 name="u:outputFolding">
490 <xsl:with-param
491 name="prefix">
492 <xsl:text>:</xsl:text>
493 <xsl:value-of
494 select="name()"/>
495 <xsl:text>: </xsl:text>
496 </xsl:with-param>
497 </xsl:call-template>
498 </xsl:template>
500 <!--
501 Content Model: %text.model;
502 Attributes: All docinfo elements contains the common attributes (ids,
503 names, dupnames, source, and classes)
504 Some docinfo elements also have xml:space.
506 <xsl:template
507 match="docinfo/authors/*">
508 <xsl:apply-templates/>
509 <!-- no semicolon after final author -->
510 <xsl:if
511 test="generate-id(current()) != generate-id(../*[last()])">
512 <xsl:text>; </xsl:text>
513 </xsl:if>
514 </xsl:template>
516 <!--
517 Content Model: (field_name, field_body)
518 Attributes: The field element contains only the common attributes: ids,
519 names, dupnames, source, and classes.
521 <!-- == bibliographic_element -->
522 <xsl:template
523 match="docinfo/field">
524 <!-- contents handled by ordinary field lists -->
525 <xsl:apply-templates/>
526 <!-- Supply an EOL because following elements do not recognize this -->
527 &tEOL;
528 </xsl:template>
530 <!--
531 Content Model: %text.model;
532 Attributes: All docinfo elements contains the common attributes (ids,
533 names, dupnames, source, and classes)
534 Some docinfo elements also have xml:space.
536 <!-- == bibliographic_element == folding_element -->
537 <xsl:template
538 match="docinfo/*[name()!='authors' and name()!='field']">
539 <xsl:call-template
540 name="u:outputFolding">
541 <xsl:with-param
542 name="prefix">
543 <xsl:text>:</xsl:text>
544 <xsl:value-of
545 select="name()"/>
546 <xsl:text>: </xsl:text>
547 </xsl:with-param>
548 </xsl:call-template>
549 </xsl:template>
551 <!-- ******************************************************************** -->
553 <!--
554 Content Model: EMPTY
555 Attributes: The transition element contains only the common attributes:
556 ids, names, dupnames, source, and classes.
558 <!-- == structural_subelement -->
559 <xsl:template
560 match="transition">
561 <xsl:call-template
562 name="u:outputClass"/>
563 &tCR; <!-- req: blank line before -->
564 <xsl:text>-----</xsl:text>
565 &tEOL;
566 <!-- Add a required blank line after unless class follows immediately -->
567 <xsl:if
568 test="not(following-sibling::*[1]/@classes)">
569 &tCR;
570 </xsl:if>
571 </xsl:template>
573 <!-- ******************************************************************** -->
574 <!-- ******************************************************************** -->
576 <!--
577 IFF there is a /document/title element, it is the publication's title. All
578 other titles will appear within sections.
580 Content Model: %text.model;
581 Attributes: The title element contains the common attributes (ids, names,
582 dupnames, source, and classes), plus refid and auto.
583 refid is used as a backlink to a table of contents entry.
584 auto is used to indicate (with value "1") that the title has been
585 numbered automatically.
587 <!-- == structural_subelement -->
588 <xsl:template
589 match="//document/title">
590 <xsl:call-template
591 name="u:outputClass"/>
592 <xsl:variable
593 name="textWS">
594 <!-- Catch the title text as it is rendered so its length can be
595 determined -->
596 <xsl:apply-templates/>
597 </xsl:variable>
598 <xsl:variable
599 name="text"
600 select="normalize-space($textWS)"/>
601 <xsl:variable
602 name="length"
603 select="string-length($text)"/>
604 <xsl:call-template
605 name="u:overline">
606 <xsl:with-param
607 name="length"
608 select="$length"/>
609 <xsl:with-param
610 name="depth"
611 select="1"/>
612 </xsl:call-template>
613 <xsl:value-of
614 select="$text"/>
615 &tEOL;
616 <xsl:call-template
617 name="u:underline">
618 <xsl:with-param
619 name="length"
620 select="$length"/>
621 <xsl:with-param
622 name="depth"
623 select="1"/>
624 </xsl:call-template>
625 </xsl:template>
627 <!-- ******************************************************************** -->
629 <!--
630 Title Underlines are defined by their position within the tree.
632 Content Model: %text.model;
633 Attributes: The title element contains the common attributes (ids, names,
634 dupnames, source, and classes), plus refid and auto.
635 refid is used as a backlink to a table of contents entry.
636 auto is used to indicate (with value "1") that the title has been
637 numbered automatically.
639 <!-- == structural_subelement -->
640 <xsl:template
641 match="section/title">
642 <xsl:call-template
643 name="u:outputClass"/>
644 <xsl:variable
645 name="textWS">
646 <!-- catch the title text as it is rendered -->
647 <xsl:apply-templates/>
648 </xsl:variable>
649 <xsl:variable
650 name="text"
651 select="normalize-space($textWS)"/>
652 <xsl:variable
653 name="length"
654 select="string-length($text)"/>
655 <xsl:variable
656 name="depth"
657 select="count(ancestor::section)"/>
658 <xsl:call-template
659 name="u:overline">
660 <xsl:with-param
661 name="length"
662 select="$length"/>
663 <xsl:with-param
664 name="depth"
665 select="$depth + 2"/>
666 </xsl:call-template>
667 <xsl:value-of
668 select="$text"/>
669 &tEOL;
670 <xsl:call-template
671 name="u:underline">
672 <xsl:with-param
673 name="length"
674 select="$length"/>
675 <xsl:with-param
676 name="depth"
677 select="$depth + 2"/>
678 </xsl:call-template>
679 <!-- Add a blank line after unless structure follows immediately -->
680 <xsl:if
681 test="not(contains(concat($structural_elements, $compound_body_elements), concat('*', name(following-sibling::*[1]), '*')) or following-sibling::*[1]/@classes)">
682 &tCR;
683 </xsl:if>
684 </xsl:template>
686 <!-- ******************************************************************** -->
688 <!--
689 Content Model: %text.model;
690 Attributes: The title element contains the common attributes (ids, names,
691 dupnames, source, and classes), plus refid and auto.
692 refid is used as a backlink to a table of contents entry.
693 auto is used to indicate (with value "1") that the title has been
694 numbered automatically.
696 <!-- == structural_subelement -->
697 <xsl:template
698 match="title">
699 <xsl:call-template
700 name="u:outputClass">
701 <xsl:with-param
702 name="alreadyBlanked"
703 select="true()"/>
704 </xsl:call-template>
705 <!-- blank line provided by parent -->
706 <xsl:apply-templates/>
707 <!-- no EOL: provided by parent -->
708 </xsl:template>
710 <!-- ******************************************************************** -->
712 <!--
713 IFF there is a /document/title element, it is the publication's title. All
714 other titles will appear within sections.
716 Content Model: %text.model;
717 Attributes: The subtitle element contains only the common attributes:
718 ids, names, dupnames, source, and classes.
720 <!-- == structural_subelement -->
721 <xsl:template
722 match="//document/subtitle">
723 <xsl:call-template
724 name="u:outputClass"/>
725 <xsl:variable
726 name="textWS">
727 <!-- Catch the title text as it is rendered -->
728 <xsl:apply-templates/>
729 </xsl:variable>
730 <xsl:variable
731 name="text"
732 select="normalize-space($textWS)"/>
733 <xsl:variable
734 name="length"
735 select="string-length($text)"/>
737 <!-- always a blank line above -->
738 &tCR;
739 <xsl:call-template
740 name="u:overline">
741 <xsl:with-param
742 name="length"
743 select="$length"/>
744 <xsl:with-param
745 name="depth"
746 select="2"/>
747 </xsl:call-template>
748 <xsl:value-of
749 select="$text"/>
750 &tEOL;
751 <xsl:call-template
752 name="u:underline">
753 <xsl:with-param
754 name="length"
755 select="$length"/>
756 <xsl:with-param
757 name="depth"
758 select="2"/>
759 </xsl:call-template>
760 </xsl:template>
762 <!-- ******************************************************************** -->
764 <!--
765 Content Model: %text.model;
766 Attributes: The subtitle element contains only the common attributes: ids,
767 names, dupnames, source, and classes.
769 <!-- == structural_subelement -->
770 <xsl:template
771 match="sidebar/subtitle">
772 <xsl:call-template
773 name="u:outputClass"/>
774 <xsl:call-template
775 name="u:indent"/>
776 <xsl:apply-templates/>
777 &tEOL;
778 &tCR;
779 </xsl:template>
781 <!-- ******************************************************************** -->
782 <!-- ******************************************************************** -->
784 <!--
785 Content Model: %text.model;
786 Attributes: The comment element contains only the common attributes: ids,
787 names, dupnames, source, and classes.
789 <!-- == simple_body_element == folding_element == directive -->
790 <xsl:template
791 match="comment">
792 <xsl:call-template
793 name="u:BandI"/>
794 <xsl:call-template
795 name="u:outputFolding">
796 <xsl:with-param
797 name="prefix">
798 <xsl:text>.. </xsl:text>
799 </xsl:with-param>
800 </xsl:call-template>
801 </xsl:template>
803 <!-- ******************************************************************** -->
805 <!--
806 Content Model: %text.model;
807 Attributes: The doctest_block element contains the common attributes (ids,
808 names, dupnames, source, and classes), plus xml:space.
810 <!-- == simple_body_element -->
811 <xsl:template
812 match="doctest_block">
813 <xsl:call-template
814 name="u:outputClass"/>
815 <xsl:call-template
816 name="u:BandI"/>
817 <xsl:apply-templates/>
818 &tEOL;
819 </xsl:template>
821 <!-- ******************************************************************** -->
823 <!-- An image element can have various roles; they are all covered here -->
824 <!-- == simple_body_element == inline_element == directive -->
825 <xsl:template
826 match="image">
827 <xsl:choose>
828 <xsl:when
829 test="contains($inline_containers, concat('*', name(..), '*')) and @alt">
830 <!-- An inline image with an `@alt' - must be a substitution
831 reference -->
832 <xsl:text>|</xsl:text>
833 <!-- Original text is lost - use what we have -->
834 <xsl:value-of
835 select="@alt"/>
836 <xsl:text>|</xsl:text>
837 </xsl:when>
838 <xsl:otherwise>
839 <!-- A directive -->
840 <xsl:if
841 test="not(parent::figure)">
842 <xsl:if
843 test="not(parent::substitution_definition)">
844 <xsl:call-template
845 name="u:BandI"/>
846 <xsl:text>.. </xsl:text>
847 </xsl:if>
848 <xsl:text>image:: </xsl:text>
849 </xsl:if>
850 <xsl:value-of
851 select="@uri"/>
852 &tEOL;
853 <xsl:choose>
854 <xsl:when
855 test="parent::figure">
856 <!-- `@classes' is special because it is in the parent -->
857 <xsl:if
858 test="../@classes">
859 <xsl:call-template
860 name="u:param">
861 <xsl:with-param
862 name="name"
863 select="'figclass'"/>
864 <xsl:with-param
865 name="value"
866 select="../@classes"/>
867 <xsl:with-param
868 name="ancestors"
869 select="ancestor::*"/>
870 </xsl:call-template>
871 </xsl:if>
872 <!-- `@align' is special because it is in the parent -->
873 <xsl:if
874 test="../@align">
875 <xsl:call-template
876 name="u:param">
877 <xsl:with-param
878 name="name"
879 select="'align'"/>
880 <xsl:with-param
881 name="value"
882 select="../@align"/>
883 <xsl:with-param
884 name="ancestors"
885 select="ancestor::*"/>
886 </xsl:call-template>
887 </xsl:if>
888 <xsl:call-template
889 name="u:params">
890 <!-- `figure' would add one level of indentation -->
891 <xsl:with-param
892 name="ancestors"
893 select="ancestor::*"/>
894 </xsl:call-template>
895 </xsl:when>
896 <xsl:when
897 test="parent::substitution_definition">
898 <xsl:call-template
899 name="u:params">
900 <!-- `@alt' only for the real images -->
901 <xsl:with-param
902 name="params"
903 select="@*[name() != 'alt']"/>
904 </xsl:call-template>
905 </xsl:when>
906 <xsl:otherwise>
907 <xsl:call-template
908 name="u:params">
909 <xsl:with-param
910 name="params"
911 select="@*[name() != 'ids' and name() != 'names']"/>
912 </xsl:call-template>
913 </xsl:otherwise>
914 </xsl:choose>
915 <xsl:if
916 test="parent::reference">
917 <!-- A clickable image -->
918 <xsl:call-template
919 name="u:param">
920 <xsl:with-param
921 name="name"
922 select="'target'"/>
923 <xsl:with-param
924 name="value">
925 <xsl:choose>
926 <xsl:when
927 test="../@name">
928 <!-- An internal link -->
929 <xsl:call-template
930 name="u:inlineReference">
931 <xsl:with-param
932 name="text"
933 select="../@refid"/>
934 </xsl:call-template>
935 </xsl:when>
936 <xsl:otherwise>
937 <!-- An external link -->
938 <xsl:value-of
939 select="../@refuri"/>
940 </xsl:otherwise>
941 </xsl:choose>
942 </xsl:with-param>
943 <xsl:with-param
944 name="ancestors"
945 select="ancestor-or-self::*"/>
946 </xsl:call-template>
947 </xsl:if>
948 <!-- Always blank line after parameter block -->
949 &tCR;
950 </xsl:otherwise>
951 </xsl:choose>
952 </xsl:template>
954 <!-- ******************************************************************** -->
956 <!--
957 Content Model: (line_block | line)+
958 Attributes: The line_block element contains the common attributes (ids,
959 names, dupnames, source, and classes), plus xml:space.
961 <!-- == compound_body_element -->
962 <xsl:template
963 match="line_block">
964 <xsl:call-template
965 name="u:outputClass"/>
966 <xsl:variable
967 name="isEmbedded"
968 select="name(..) = 'line_block'"/>
969 <xsl:if
970 test="not($isEmbedded)">
971 <xsl:call-template
972 name="u:blank"/>
973 </xsl:if>
974 <xsl:apply-templates/>
975 </xsl:template>
977 <!-- ******************************************************************** -->
979 <!--
980 Content Model: %text.model;
981 Attributes: The line element contains the common attributes (ids,
982 names, dupnames, source, and classes).
984 <!-- == simple_body_subelement == folding_element -->
985 <xsl:template
986 match="line">
987 <xsl:call-template
988 name="u:outputClass"/>
989 <xsl:variable
990 name="indent">
991 <xsl:call-template
992 name="u:indent"/>
993 </xsl:variable>
994 <xsl:value-of
995 select="$indent"/>
996 <xsl:choose>
997 <xsl:when
998 test="node()">
999 <!-- Only for non-empty lines -->
1000 <xsl:variable
1001 name="lineBlockIndent">
1002 <!-- Very special indendation for nested `line_block's -->
1003 <xsl:for-each
1004 select="ancestor::line_block[position() > 1]">
1005 <xsl:value-of
1006 select="str:padding(4)"/>
1007 </xsl:for-each>
1008 </xsl:variable>
1009 <xsl:call-template
1010 name="u:outputFolding">
1011 <xsl:with-param
1012 name="prefix">
1013 <xsl:text>| </xsl:text>
1014 <xsl:value-of
1015 select="$lineBlockIndent"/>
1016 </xsl:with-param>
1017 <xsl:with-param
1018 name="indent"
1019 select="concat($indent, ' ', $lineBlockIndent)"/>
1020 </xsl:call-template>
1021 </xsl:when>
1022 <xsl:otherwise>
1023 <xsl:text>|</xsl:text>
1024 &tEOL;
1025 </xsl:otherwise>
1026 </xsl:choose>
1027 </xsl:template>
1029 <!-- ******************************************************************** -->
1031 <!--
1032 Content Model: %text.model;
1033 Attributes: The literal_block element contains the common attributes (ids,
1034 names, dupnames, source, and classes), plus xml:space.
1036 <!-- == simple_body_element == directive -->
1037 <xsl:template
1038 match="literal_block">
1039 <xsl:choose>
1040 <xsl:when
1041 test=".//*[contains($inline_elements, concat('*', name(), '*'))]">
1042 <!-- If it contains inline elements this is a parsed-literal -->
1043 <xsl:call-template
1044 name="u:BandI"/>
1045 <xsl:text>.. parsed-literal::</xsl:text>
1046 &tEOL;
1047 <xsl:call-template
1048 name="u:params"/>
1049 &tCR;
1050 </xsl:when>
1051 <xsl:otherwise>
1052 <xsl:call-template
1053 name="u:outputClass"/>
1054 <!-- TODO Support for the (fully) minimized style would be nice but
1055 is difficult to accomplish because there is a linefeed
1056 already when we arrive here :-( -->
1057 <xsl:call-template
1058 name="u:BandI"/>
1059 <xsl:text>::</xsl:text>
1060 &tEOL;
1061 &tCR;
1062 </xsl:otherwise>
1063 </xsl:choose>
1064 <xsl:variable
1065 name="isQuotedLiteral">
1066 <xsl:call-template
1067 name="u:isQuotedLiteral"/>
1068 </xsl:variable>
1069 <!-- Indent correctly depending on quoted literal or not -->
1070 <xsl:choose>
1071 <xsl:when
1072 test="string-length($isQuotedLiteral)">
1073 <xsl:call-template
1074 name="u:indent">
1075 <xsl:with-param
1076 name="ancestors"
1077 select="ancestor::*"/>
1078 </xsl:call-template>
1079 <xsl:apply-templates
1080 mode="quotedLiteral"/>
1081 </xsl:when>
1082 <xsl:otherwise>
1083 <xsl:call-template
1084 name="u:indent">
1085 <xsl:with-param
1086 name="ancestors"
1087 select="ancestor-or-self::*"/>
1088 </xsl:call-template>
1089 <xsl:apply-templates/>
1090 </xsl:otherwise>
1091 </xsl:choose>
1092 &tEOL;
1093 </xsl:template>
1095 <!-- Indent a text of a quoted literal containing line feeds correctly -->
1096 <xsl:template
1097 match="text()"
1098 mode="quotedLiteral">
1099 <xsl:call-template
1100 name="u:indentLF">
1101 <xsl:with-param
1102 name="indent">
1103 <xsl:call-template
1104 name="u:indent">
1105 <xsl:with-param
1106 name="ancestors"
1107 select="ancestor::*[position() > 1]"/>
1108 </xsl:call-template>
1109 </xsl:with-param>
1110 </xsl:call-template>
1111 </xsl:template>
1113 <!-- Determine whether `$text' is a quoted literal and return the quote
1114 character if so -->
1115 <xsl:template
1116 name="u:isQuotedLiteral">
1117 <xsl:param
1118 name="text"
1119 select="text()"/>
1120 <xsl:param
1121 name="quote"
1122 select="substring($text, 1, 1)"/>
1123 <xsl:if
1124 test="contains($adornment_characters, $quote) and substring($text, 1, 1) = $quote">
1125 <!-- Given quote is an adornment character and first character is this
1126 quote -->
1127 <xsl:choose>
1128 <xsl:when
1129 test="contains($text, '&#xA;')">
1130 <!-- Test the remaining lines -->
1131 <xsl:call-template
1132 name="u:isQuotedLiteral">
1133 <xsl:with-param
1134 name="text"
1135 select="substring-after($text, '&#xA;')"/>
1136 <xsl:with-param
1137 name="quote"
1138 select="$quote"/>
1139 </xsl:call-template>
1140 </xsl:when>
1141 <xsl:otherwise>
1142 <!-- No more lines to test so this is a quoted literal -->
1143 <xsl:value-of
1144 select="$quote"/>
1145 </xsl:otherwise>
1146 </xsl:choose>
1147 </xsl:if>
1148 </xsl:template>
1150 <!-- ******************************************************************** -->
1152 <!--
1153 Content Model: %text.model;
1154 Attributes: The paragraph element contains only the common attributes:
1155 ids, names, dupnames, source, and classes.
1157 <!-- == simple_body_element == folding_element -->
1158 <xsl:template
1159 match="paragraph">
1160 <xsl:variable
1161 name="previous"
1162 select="preceding-sibling::*[1]"/>
1163 <!-- Do indent except first element in some compound elements -->
1164 <xsl:variable
1165 name="needsIndent"
1166 select="($previous or not(parent::list_item or parent::field_body or contains($admonitions, concat('*', name(..), '*')))) and name($previous) != 'label'"/>
1167 <!-- Blank line in front if following a body element, except first
1168 elements in some compound elements -->
1169 <xsl:variable
1170 name="needsBlank"
1171 select="($previous or not(parent::list_item or ../parent::option_list_item or parent::field_body or parent::document or contains($admonitions, concat('*', name(..), '*')))) and (not($previous) or contains($body_elements, concat('*', name($previous), '*')) or name($previous) = 'title' and contains($titled_elements, concat('*', name(..), '*')) or name($previous) = 'docinfo')"/>
1172 <xsl:if
1173 test="$needsBlank">
1174 &tCR;
1175 </xsl:if>
1176 <xsl:if
1177 test="$needsIndent">
1178 <xsl:call-template
1179 name="u:indent"/>
1180 </xsl:if>
1181 <xsl:if
1182 test="@classes">
1183 <!-- This paragraph has a classes attribute - always needs newline and
1184 indent -->
1185 <xsl:call-template
1186 name="u:outputClass">
1187 <xsl:with-param
1188 name="alreadyBlanked"
1189 select="$needsBlank"/>
1190 <xsl:with-param
1191 name="alreadyIndented"
1192 select="$needsIndent"/>
1193 </xsl:call-template>
1194 <xsl:call-template
1195 name="u:BandI"/>
1196 </xsl:if>
1197 <xsl:call-template
1198 name="u:outputFolding"/>
1199 </xsl:template>
1201 <!-- ******************************************************************** -->
1203 <!-- == simple_body_element -->
1204 <xsl:template
1205 match="pending">
1206 <xsl:call-template
1207 name="u:notSupported"/>
1208 </xsl:template>
1210 <!-- ******************************************************************** -->
1212 <!-- == simple_body_element == inline_element == directive -->
1213 <xsl:template
1214 match="raw">
1215 <xsl:choose>
1216 <xsl:when
1217 test="contains($inline_containers, concat('*', name(..), '*'))">
1218 <!-- Used as a custom role -->
1219 <!-- TODO `role' directives must be generated for user-defined raw
1220 roles. -->
1221 <!-- The name of the custom role is not contained in the input -->
1222 <xsl:text>:RAW-ROLE:`</xsl:text>
1223 <xsl:apply-templates/>
1224 <xsl:text>`</xsl:text>
1225 </xsl:when>
1226 <xsl:otherwise>
1227 <!-- A directive -->
1228 <xsl:call-template
1229 name="u:outputClass"/>
1230 <xsl:call-template
1231 name="u:BandI"/>
1232 <xsl:text>.. raw:: </xsl:text>
1233 <xsl:value-of
1234 select="@format"/>
1235 &tEOL;
1236 <xsl:call-template
1237 name="u:params">
1238 <xsl:with-param
1239 name="params"
1240 select="@*[name() != 'format' and name() != 'classes']"/>
1241 </xsl:call-template>
1242 &tCR;
1243 <xsl:call-template
1244 name="u:indent">
1245 <xsl:with-param
1246 name="ancestors"
1247 select="ancestor-or-self::*"/>
1248 </xsl:call-template>
1249 <xsl:apply-templates/>
1250 &tEOL;
1251 </xsl:otherwise>
1252 </xsl:choose>
1253 </xsl:template>
1255 <!-- ******************************************************************** -->
1257 <!-- == simple_body_element == folding_element == directive -->
1258 <xsl:template
1259 match="rubric">
1260 <xsl:call-template
1261 name="u:BandI"/>
1262 <xsl:call-template
1263 name="u:outputFolding">
1264 <xsl:with-param
1265 name="prefix">
1266 <xsl:text>.. rubric:: </xsl:text>
1267 </xsl:with-param>
1268 </xsl:call-template>
1269 <xsl:call-template
1270 name="u:params"/>
1271 </xsl:template>
1273 <!-- ******************************************************************** -->
1275 <!-- == compound_body_element == directive -->
1276 <xsl:template
1277 match="compound">
1278 <xsl:call-template
1279 name="u:BandI"/>
1280 <xsl:text>.. compound::</xsl:text>
1281 &tEOL;
1282 <xsl:call-template
1283 name="u:params"/>
1284 <xsl:apply-templates/>
1285 </xsl:template>
1287 <!-- ******************************************************************** -->
1289 <!-- == compound_body_element == directive -->
1290 <xsl:template
1291 match="container">
1292 <xsl:call-template
1293 name="u:BandI"/>
1294 <xsl:text>.. container::</xsl:text>
1295 <xsl:if
1296 test="@classes">
1297 &tSP;
1298 <xsl:value-of
1299 select="@classes"/>
1300 </xsl:if>
1301 &tEOL;
1302 <xsl:apply-templates/>
1303 </xsl:template>
1305 <!-- ******************************************************************** -->
1307 <!-- == simple_body_element == directive -->
1308 <xsl:template
1309 match="substitution_definition">
1310 <!-- More than one child or not a directive is a replacement text -->
1311 <xsl:variable
1312 name="isReplace"
1313 select="not(* and count(node()) = 1 and contains($directives, concat('*', name(*[1]), '*')))"/>
1314 <xsl:call-template
1315 name="u:BandI"/>
1316 <xsl:variable
1317 name="prefix">
1318 <xsl:text>.. |</xsl:text>
1319 <xsl:call-template
1320 name="u:outputNames"/>
1321 <xsl:text>| </xsl:text>
1322 </xsl:variable>
1323 <xsl:choose>
1324 <xsl:when
1325 test="$isReplace">
1326 <!-- TODO Substitution references for replace can not be found because
1327 they are not marked as such; embedding them in `generated'
1328 would be nice -->
1329 <xsl:call-template
1330 name="u:outputFolding">
1331 <xsl:with-param
1332 name="prefix">
1333 <xsl:value-of
1334 select="$prefix"/>
1335 <xsl:text>replace:: </xsl:text>
1336 </xsl:with-param>
1337 </xsl:call-template>
1338 </xsl:when>
1339 <xsl:otherwise>
1340 <xsl:value-of
1341 select="$prefix"/>
1342 <xsl:apply-templates/>
1343 </xsl:otherwise>
1344 </xsl:choose>
1345 </xsl:template>
1347 <!-- ******************************************************************** -->
1349 <!--
1350 Content Model: ((%body.elements;)+, attribution?)
1351 Attributes: The block_quote element contains only the common attributes:
1352 ids, names, dupnames, source, and classes.
1354 <!-- == compound_body_element -->
1355 <xsl:template
1356 match="block_quote">
1357 <xsl:if
1358 test="@classes = 'epigraph' or @classes = 'highlights' or @classes = 'pull-quote'">
1359 <xsl:call-template
1360 name="u:BandI"/>
1361 <xsl:text>.. </xsl:text>
1362 <xsl:value-of
1363 select="@classes"/>
1364 <xsl:text>::</xsl:text>
1365 &tEOL;
1366 <xsl:call-template
1367 name="u:params"/>
1368 </xsl:if>
1369 <xsl:apply-templates/>
1370 </xsl:template>
1372 <!-- ******************************************************************** -->
1374 <!-- == simple_body_subelement == folding_element -->
1375 <xsl:template
1376 match="attribution">
1377 <xsl:call-template
1378 name="u:outputClass"/>
1379 <!-- blank line between quote and attribution -->
1380 &tCR;
1381 <xsl:call-template
1382 name="u:indent"/>
1383 <xsl:call-template
1384 name="u:outputFolding">
1385 <xsl:with-param
1386 name="prefix">
1387 <xsl:text>-- </xsl:text>
1388 </xsl:with-param>
1389 </xsl:call-template>
1390 </xsl:template>
1392 <!-- ******************************************************************** -->
1394 <!-- == compound_body_element == directive -->
1395 <xsl:template
1396 match="citation">
1397 <xsl:call-template
1398 name="u:outputClass"/>
1399 <xsl:call-template
1400 name="u:BandI"/>
1401 <xsl:text>.. [</xsl:text>
1402 <xsl:value-of
1403 select="label"/>
1404 <xsl:text>] </xsl:text>
1405 <xsl:apply-templates
1406 select="*[not(self::label)]"/>
1407 </xsl:template>
1409 <!-- == simple_body_subelement -->
1410 <xsl:template
1411 match="citation/label">
1412 <xsl:apply-templates/>
1413 </xsl:template>
1415 <!-- ******************************************************************** -->
1417 <!-- == compound_body_element == directive -->
1418 <xsl:template
1419 match="figure">
1420 <xsl:call-template
1421 name="u:BandI"/>
1422 <xsl:text>.. figure:: </xsl:text>
1423 <xsl:apply-templates/>
1424 </xsl:template>
1426 <!-- ******************************************************************** -->
1428 <!-- == simple_body_subelement == folding_element -->
1429 <xsl:template
1430 match="caption">
1431 <xsl:call-template
1432 name="u:indent"/>
1433 <xsl:call-template
1434 name="u:outputFolding"/>
1435 </xsl:template>
1437 <!-- ******************************************************************** -->
1439 <!-- == compound_body_subelement -->
1440 <xsl:template
1441 match="legend">
1442 <xsl:apply-templates/>
1443 </xsl:template>
1445 <!-- ******************************************************************** -->
1447 <!-- TODO Footnotes should continue on line of definition -->
1449 <!-- user-numbered footnotes lack @auto -->
1450 <!-- == compound_body_element == directive -->
1451 <xsl:template
1452 match="footnote[not(@auto)]">
1453 <xsl:call-template
1454 name="u:outputClass"/>
1455 <xsl:call-template
1456 name="u:BandI"/>
1457 <xsl:text>.. [</xsl:text>
1458 <xsl:apply-templates
1459 select="label"/>
1460 <xsl:text>] </xsl:text>
1461 <xsl:apply-templates
1462 select="*[not(self::label)]"/>
1463 </xsl:template>
1465 <!-- autonumbered footnotes have @auto -->
1466 <!-- if the target footnote_reference@names matches its label, it was not a
1467 numbered-name footnote -->
1468 <!-- == compound_body_element == directive -->
1469 <xsl:template
1470 match="footnote[@auto='1']">
1471 <xsl:call-template
1472 name="u:outputClass"/>
1473 <xsl:call-template
1474 name="u:BandI"/>
1475 <xsl:text>.. [#</xsl:text>
1476 <xsl:if
1477 test="@names = @ids">
1478 <xsl:call-template
1479 name="u:outputNames"/>
1480 </xsl:if>
1481 <xsl:text>] </xsl:text>
1482 <xsl:apply-templates
1483 select="*[not(self::label)]"/>
1484 </xsl:template>
1486 <!-- autosymboled footnotes have @auto -->
1487 <!-- == compound_body_element == directive -->
1488 <xsl:template
1489 match="footnote[@auto='*']">
1490 <xsl:call-template
1491 name="u:outputClass"/>
1492 <xsl:call-template
1493 name="u:BandI"/>
1494 <xsl:text>.. [*] </xsl:text>
1495 <xsl:apply-templates
1496 select="*[not(self::label)]"/>
1497 </xsl:template>
1499 <!-- == compound_body_element == directive -->
1500 <xsl:template
1501 match="footnote[starts-with(@names, 'TARGET_NOTE:\ ')]">
1502 <!-- This is not a footnote but a hint for a directive -->
1503 <xsl:if
1504 test="generate-id(//footnote[starts-with(@names, 'TARGET_NOTE:\ ')][1]) = generate-id(.)">
1505 <!-- Only for the first one -->
1506 <xsl:call-template
1507 name="u:BandI"/>
1508 <!-- TODO May have a `classes` attribute -->
1509 <xsl:text>.. target-notes::</xsl:text>
1510 &tEOL;
1511 </xsl:if>
1512 </xsl:template>
1514 <!-- == simple_body_subelement -->
1515 <xsl:template
1516 match="footnote/label">
1517 <xsl:apply-templates/>
1518 </xsl:template>
1520 <!-- ******************************************************************** -->
1522 <!--
1523 Content Model: (list_item +)
1524 Attributes: The bullet_list element contains the common attributes (ids,
1525 names, dupnames, source, and classes), plus bullet.
1526 bullet is used to record the style of bullet from the input data.
1527 In documents processed from reStructuredText, it contains one of "-",
1528 "+", or "*". It may be ignored in processing.
1530 <!-- == compound_body_element -->
1531 <xsl:template
1532 match="bullet_list">
1533 <xsl:call-template
1534 name="u:outputClass"/>
1535 <xsl:apply-templates
1536 mode="bullet_list"/>
1537 </xsl:template>
1539 <!-- ******************************************************************** -->
1541 <!--
1542 Content Model: (definition_list_item +)
1543 Attributes: The definition_list element contains only the common
1544 attributes: ids, names, dupnames, source, and classes.
1546 <!-- == compound_body_element -->
1547 <xsl:template
1548 match="definition_list">
1549 <xsl:call-template
1550 name="u:outputClass"/>
1551 <xsl:apply-templates/>
1552 </xsl:template>
1554 <!-- ******************************************************************** -->
1556 <!--
1557 Content Model: (term, classifier?, definition)
1558 Attributes: The definition_list_item element contains only the common
1559 attributes: ids, names, dupnames, source, and classes.
1561 <!-- == compound_body_subelement -->
1562 <xsl:template
1563 match="definition_list_item">
1564 <xsl:call-template
1565 name="u:outputClass"/>
1566 <xsl:call-template
1567 name="u:BandI"/>
1568 <xsl:apply-templates/>
1569 </xsl:template>
1571 <!-- ******************************************************************** -->
1573 <!--
1574 Content Model: %text.model;
1575 Attributes: The term element contains only the common attributes: ids,
1576 names, dupnames, source, and classes.
1578 <!-- == simple_body_subelement -->
1579 <xsl:template
1580 match="term">
1581 <xsl:apply-templates/>
1582 </xsl:template>
1584 <!-- ******************************************************************** -->
1586 <!--
1587 Content Model: %text.model;
1588 Attributes: The classifier element contains only the common attributes:
1589 ids, names, dupnames, source, and classes.
1591 <!-- == simple_body_subelement -->
1592 <xsl:template
1593 match="classifier">
1594 <xsl:text> : </xsl:text>
1595 <xsl:apply-templates/>
1596 </xsl:template>
1598 <!-- ******************************************************************** -->
1600 <!--
1601 Content Model: (%body.elements;)+
1602 Attributes: The definition element contains only the common attributes:
1603 ids, names, dupnames, source, and classes.
1605 <!-- == compound_body_subelement -->
1606 <xsl:template
1607 match="definition">
1608 <xsl:call-template
1609 name="u:outputClass"/>
1610 <xsl:apply-templates/>
1611 </xsl:template>
1613 <!-- ******************************************************************** -->
1615 <!--
1616 Content Model: (list_item +)
1617 Attributes: The enumerated_list element contains the common attributes
1618 (ids, names, dupnames, source, and classes), plus enumtype, prefix, suffix, and
1619 start.
1620 enumtype is used to record the intended enumeration sequence, one
1621 of "arabic" (1, 2, 3, ...), "loweralpha" (a, b, c, ..., z), "upperalpha" (A,
1622 B, C, ..., Z), "lowerroman" (i, ii, iii, iv, ..., mmmmcmxcix [4999]), or
1623 "upperroman" (I, II, III, IV, ..., MMMMCMXCIX [4999]).
1624 prefix stores the formatting characters used before the enumerator. In
1625 documents originating from reStructuredText data, it will contain either ""
1626 (empty string) or "(" (left parenthesis). It may or may not affect
1627 processing.
1628 suffix stores the formatting characters used after the enumerator. In
1629 documents originating from reStructuredText data, it will contain either "."
1630 (period) or ")" (right parenthesis). Depending on the capabilities of the
1631 output format, this attribute may or may not affect processing.
1632 start contains the ordinal value of the first item in the list, in
1633 decimal. For lists beginning at value 1 ("1", "a", "A", "i", or "I"), this
1634 attribute may be omitted.
1636 <!-- == compound_body_element -->
1637 <xsl:template
1638 match="enumerated_list">
1639 <xsl:call-template
1640 name="u:outputClass"/>
1641 <xsl:apply-templates
1642 mode="enumerated_list"/>
1643 </xsl:template>
1645 <!-- ******************************************************************** -->
1647 <!--
1648 Content Model: (field +)
1649 Attributes: The field_list element contains only the common attributes:
1650 ids, names, dupnames, source, and classes.
1652 <!-- == compound_body_element -->
1653 <xsl:template
1654 match="field_list">
1655 <xsl:call-template
1656 name="u:outputClass"/>
1657 <xsl:apply-templates/>
1658 </xsl:template>
1660 <!-- ******************************************************************** -->
1662 <!--
1663 Content Model: (field_name, field_body)
1664 Attributes: The field element contains only the common attributes: ids,
1665 names, dupnames, source, and classes.
1667 <!-- == compound_body_subelement -->
1668 <xsl:template
1669 match="field">
1670 <xsl:call-template
1671 name="u:outputClass"/>
1672 <xsl:call-template
1673 name="u:BandI"/>
1674 <xsl:apply-templates/>
1675 </xsl:template>
1677 <!-- ********************************************************************** -->
1679 <!--
1680 Content Model: %text.model;
1681 Attributes: The field_name element contains only the common attributes:
1682 ids, names, dupnames, source, and classes.
1684 <!-- == simple_body_subelement -->
1685 <xsl:template
1686 match="field_name">
1687 <xsl:text>:</xsl:text>
1688 <xsl:apply-templates/>
1689 <xsl:text>: </xsl:text>
1690 <!-- no EOL: field_body starts on same line -->
1691 </xsl:template>
1693 <!-- ******************************************************************** -->
1695 <!--
1696 Content Model: (%body.elements;)*
1697 Attributes: The field_body element contains only the common attributes:
1698 ids, names, dupnames, source, and classes.
1700 <!-- == compound_body_subelement -->
1701 <xsl:template
1702 match="field_body">
1703 <xsl:call-template
1704 name="u:outputClass"/>
1705 <xsl:apply-templates/>
1706 </xsl:template>
1708 <!-- ******************************************************************** -->
1710 <!--
1711 Content Model: (option_list_item +)
1712 Attributes: The option_list element contains only the common attributes:
1713 ids, names, dupnames, source, and classes.
1715 <!-- == compound_body_element -->
1716 <xsl:template
1717 match="option_list">
1718 <xsl:call-template
1719 name="u:outputClass"/>
1720 <xsl:call-template
1721 name="u:blank"/>
1722 <xsl:apply-templates/>
1723 </xsl:template>
1725 <!-- ******************************************************************** -->
1727 <!--
1728 Content Model: (option_group, description)
1729 Attributes: The option_list_item element contains only the common
1730 attributes: ids, names, dupnames, source, and classes.
1732 <!-- == compound_body_subelement -->
1733 <xsl:template
1734 match="option_list_item">
1735 <xsl:call-template
1736 name="u:outputClass"/>
1737 <xsl:call-template
1738 name="u:indent"/>
1739 <xsl:apply-templates/>
1740 </xsl:template>
1742 <!-- ******************************************************************** -->
1744 <!--
1745 Content Model: (option_group, description)
1746 Attributes: The option_group element contains only the common attributes:
1747 ids, names, dupnames, source, and classes.
1749 <!-- == compound_body_subelement -->
1750 <xsl:template
1751 match="option_group">
1752 <xsl:apply-templates/>
1753 &tEOL;
1754 </xsl:template>
1756 <!-- ******************************************************************** -->
1758 <!--
1759 Content Model: (option_string, option_argument *)
1760 Attributes: The option element contains only the common attributes: ids,
1761 names, dupnames, source, and classes.
1763 <!-- == compound_body_subelement -->
1764 <xsl:template
1765 match="option">
1766 <xsl:call-template
1767 name="u:outputClass"/>
1768 <xsl:apply-templates/>
1769 <xsl:if
1770 test="generate-id(current()) != generate-id(../*[last()])">
1771 <!-- No comma after final option -->
1772 <xsl:text>, </xsl:text>
1773 </xsl:if>
1774 <!-- no EOL: description on same line -->
1775 </xsl:template>
1777 <!-- ******************************************************************** -->
1779 <!--
1780 Content Model: (#PCDATA)
1781 Attributes: The option_string element contains only the common attributes:
1782 ids, names, dupnames, source, and classes.
1784 <!-- == simple_body_subelement -->
1785 <xsl:template
1786 match="option_string">
1787 <xsl:apply-templates/>
1788 </xsl:template>
1790 <!-- ******************************************************************** -->
1792 <!--
1793 Content Model: (#PCDATA)
1794 Attributes: The option_argument element contains the common attributes
1795 (ids, names, dupnames, source, and classes), plus delimiter.
1796 delimiter contains the text preceding the option_argument:
1797 either the text separating it from the option_string (typically
1798 either "=" or " ")
1799 or the text between option arguments (typically either "," or " ").
1801 <!-- == simple_body_subelement -->
1802 <xsl:template
1803 match="option_argument">
1804 <xsl:value-of
1805 select="@delimiter"/>
1806 <xsl:apply-templates/>
1807 </xsl:template>
1809 <!-- ******************************************************************** -->
1811 <!--
1812 Content Model: (%body.elements;)+
1813 Attributes: The description element contains only the common attributes:
1814 ids, names, dupnames, source, and classes.
1816 <!-- == compound_body_subelement -->
1817 <xsl:template
1818 match="description">
1819 <xsl:call-template
1820 name="u:outputClass"/>
1821 <xsl:apply-templates/>
1822 &tEOL;
1823 </xsl:template>
1825 <!-- ******************************************************************** -->
1827 <!--
1828 Content Model: (%body.elements;)+
1829 Attributes: The list_item element contains only the common attributes:
1830 ids, names, dupnames, source, and classes
1832 BULLET LIST
1833 bullet is used to record the style of bullet from the input data.
1834 In documents processed from reStructuredText, it contains one of "-",
1835 "+", or "*". It may be ignored in processing.
1837 <!-- == compound_body_subelement -->
1838 <xsl:template
1839 match="list_item"
1840 mode="bullet_list">
1841 <xsl:call-template
1842 name="u:outputClass"/>
1843 <xsl:call-template
1844 name="u:BandI"/>
1845 <xsl:value-of
1846 select="../@bullet"/>
1847 &tSP; <!-- space after bullet -->
1848 <xsl:apply-templates/>
1849 </xsl:template>
1851 <!-- ******************************************************************** -->
1853 <!--
1854 ENUMERATED LIST
1855 enumtype is used to record the intended enumeration sequence, one of
1856 "arabic" (1, 2, 3, ...), "loweralpha" (a, b, c, ..., z), "upperalpha" (A, B,
1857 C, ..., Z), "lowerroman" (i, ii, iii, iv, ..., mmmmcmxcix [4999]), or
1858 "upperroman" (I, II, III, IV, ..., MMMMCMXCIX [4999]).
1859 prefix stores the formatting characters used before the enumerator. In
1860 documents originating from reStructuredText data, it will contain either ""
1861 (empty string) or "(" (left parenthesis). It may or may not affect
1862 processing.
1863 suffix stores the formatting characters used after the enumerator. In
1864 documents originating from reStructuredText data, it will contain either "."
1865 (period) or ")" (right parenthesis). Depending on the capabilities of the
1866 output format, this attribute may or may not affect processing.
1867 start contains the ordinal value of the first item in the list, in
1868 decimal. For lists beginning at value 1 ("1", "a", "A", "i", or "I"), this
1869 attribute may be omitted.
1872 <!-- == compound_body_subelement -->
1873 <xsl:template
1874 match="list_item"
1875 mode="enumerated_list">
1876 <xsl:call-template
1877 name="u:outputClass"/>
1878 <xsl:call-template
1879 name="u:BandI"/>
1880 <xsl:call-template
1881 name="u:outputEnumerator"/>
1882 <xsl:apply-templates/>
1883 </xsl:template>
1885 <!-- Outputs a complete enumerator when called in an
1886 enumerated_list/list_item -->
1887 <xsl:template
1888 name="u:outputEnumerator">
1889 <!-- Use parent's numeration attribute -->
1890 <xsl:variable
1891 name="enumType"
1892 select="../@enumtype"/>
1893 <!-- Determine starting point -->
1894 <xsl:variable
1895 name="start">
1896 <xsl:choose>
1897 <xsl:when
1898 test="../@start">
1899 <xsl:value-of
1900 select="../@start"/>
1901 </xsl:when>
1902 <xsl:otherwise>
1903 <xsl:value-of
1904 select="1"/>
1905 </xsl:otherwise>
1906 </xsl:choose>
1907 </xsl:variable>
1908 <!-- Determine position of this item in its real context -->
1909 <xsl:variable
1910 name="position">
1911 <xsl:variable
1912 name="wanted"
1913 select="generate-id()"/>
1914 <!-- Generate the right current node list -->
1915 <xsl:for-each
1916 select="../list_item">
1917 <xsl:if
1918 test="generate-id() = $wanted">
1919 <xsl:value-of
1920 select="position()"/>
1921 </xsl:if>
1922 </xsl:for-each>
1923 </xsl:variable>
1924 <!-- Determine encoding of the number for the given numeration -->
1925 <xsl:variable
1926 name="cur">
1927 <xsl:call-template
1928 name="u:position2Enumerator">
1929 <xsl:with-param
1930 name="enumType"
1931 select="$enumType"/>
1932 <xsl:with-param
1933 name="position"
1934 select="$position"/>
1935 <xsl:with-param
1936 name="start"
1937 select="$start"/>
1938 </xsl:call-template>
1939 </xsl:variable>
1940 <!-- Determine encoding of the maximum number -->
1941 <xsl:variable
1942 name="max">
1943 <xsl:call-template
1944 name="u:position2Enumerator">
1945 <xsl:with-param
1946 name="enumType"
1947 select="$enumType"/>
1948 <xsl:with-param
1949 name="position"
1950 select="count(../list_item)"/>
1951 <xsl:with-param
1952 name="start"
1953 select="$start"/>
1954 </xsl:call-template>
1955 </xsl:variable>
1956 <!-- Output complete enumerator -->
1957 <xsl:value-of
1958 select="../@prefix"/>
1959 <xsl:value-of
1960 select="$cur"/>
1961 <xsl:value-of
1962 select="../@suffix"/>
1963 <!-- Output at least one trailing space -->
1964 &tSP;
1965 <!-- Output more whitespace to align with the maximum enumerator -->
1966 <xsl:if
1967 test="$enumType != 'lowerroman' and $enumType != 'upperroman'">
1968 <!-- Assumes that the maximum number has maximum string length -->
1969 <xsl:value-of
1970 select="str:padding(string-length($max) - string-length($cur))"/>
1971 </xsl:if>
1972 </xsl:template>
1974 <!-- Determine the right ordinal enumerator based on the parameters -->
1975 <xsl:template
1976 name="u:position2Enumerator">
1977 <xsl:param
1978 name="enumType"/>
1979 <xsl:param
1980 name="start"/>
1981 <xsl:param
1982 name="position"/>
1983 <!-- Determine logical number -->
1984 <xsl:variable
1985 name="ordinal"
1986 select="$start - 1 + $position"/>
1987 <xsl:choose>
1988 <xsl:when
1989 test="$enumType = 'arabic'">
1990 <xsl:value-of
1991 select="$ordinal"/>
1992 </xsl:when>
1993 <xsl:when
1994 test="$enumType = 'loweralpha'">
1995 <xsl:value-of
1996 select="substring('abcdefghijklmnopqrstzuvwxyz', $ordinal, 1)"/>
1997 </xsl:when>
1998 <xsl:when
1999 test="$enumType = 'upperalpha'">
2000 <xsl:value-of
2001 select="substring('ABCDEFGHIJKLMNOPQRSTZUVWXYZ', $ordinal, 1)"/>
2002 </xsl:when>
2003 <!-- TODO Support for counting roman numbers -->
2004 <xsl:when
2005 test="$enumType = 'lowerroman'">
2006 <xsl:text>i</xsl:text>
2007 </xsl:when>
2008 <xsl:when
2009 test="$enumType = 'upperroman'">
2010 <xsl:text>I</xsl:text>
2011 </xsl:when>
2012 </xsl:choose>
2013 </xsl:template>
2015 <!-- ******************************************************************** -->
2016 <!-- ******************************************************************** -->
2018 <!--
2019 Content Model: (title?, tgroup+)
2020 Attributes: The table element contains the common attributes and:
2021 frame, colsep, rowsep, pgwide
2023 <!-- == compound_body_element -->
2024 <xsl:template
2025 match="table">
2026 <xsl:call-template
2027 name="u:outputClass"/>
2028 <xsl:call-template
2029 name="u:blank"/>
2030 <xsl:apply-templates
2031 select="tgroup"/>
2032 <xsl:if
2033 test="title">
2034 <!-- TODO A table title must be rendered by using the `.. table::'
2035 directive -->
2036 <xsl:call-template
2037 name="u:BandI"/>
2038 <xsl:apply-templates
2039 select="title"/>
2040 &tEOL;
2041 </xsl:if>
2042 </xsl:template>
2044 <!-- ******************************************************************** -->
2046 <!--
2047 Content Model: (colspec*, thead?, tbody)
2048 Attributes: The tgroup element contains the common attributes and:
2049 cols, colsep, rowsep, align
2051 <!-- == compound_body_subelement -->
2052 <xsl:template
2053 match="tgroup">
2054 <xsl:apply-templates/>
2055 </xsl:template>
2057 <!-- ******************************************************************** -->
2059 <!--
2060 Content Model: EMPTY
2061 Attributes: The colspec element contains the common attributes and:
2062 colnum, colname, colwidth, colsep, rowsep, align, char, charoff
2064 The colwidth attribute gives the width of the respective column in characters
2065 including padding whitespace but no separator markup.
2067 <!-- == simple_body_subelement -->
2068 <!-- @colwidth needed by children but element has no own output -->
2069 <xsl:template
2070 match="colspec"/>
2072 <!-- ******************************************************************** -->
2074 <!--
2075 Content Model: (row+)
2076 Attributes: The thead element contains the common attributes and:
2077 valign
2079 <!-- == compound_body_subelement -->
2080 <xsl:template
2081 match="thead">
2082 <xsl:apply-templates/>
2083 </xsl:template>
2085 <!--
2086 Content Model: (row+)
2087 Attributes: The tbody element contains the common attributes and:
2088 valign
2090 <!-- == compound_body_subelement -->
2091 <xsl:template
2092 match="tbody">
2093 <xsl:apply-templates/>
2094 </xsl:template>
2096 <!-- ******************************************************************** -->
2098 <!--
2099 Content Model: (entry+)
2100 Attributes: The row element contains the common attributes and:
2101 rowsep, valign
2103 <!-- == compound_body_subelement -->
2104 <xsl:template
2105 match="row">
2106 <!-- Separator line above unless first row of a tbody with no previous
2107 thead (in this case the separator line is output already as the
2108 closing separator line of thead) -->
2109 <xsl:if
2110 test="position() > 1 or parent::thead or parent::tbody and not(../../thead)">
2111 <xsl:call-template
2112 name="u:rowSeparatorLine"/>
2113 </xsl:if>
2114 <!-- Determine heights in physical lines of all entries -->
2115 <xsl:variable
2116 name="heights">
2117 <xsl:for-each
2118 select="entry">
2119 <xsl:variable
2120 name="text">
2121 <!-- Catch the text of all entries -->
2122 <xsl:apply-templates/>
2123 </xsl:variable>
2124 <!-- Compute height of this entry; leading and trailing EOL must be
2125 subtracted -->
2126 <xsl:value-of
2127 select="string-length($text) - string-length(translate($text, '&#xA;', '')) - 1"/>
2128 &tSP; <!-- A space as a list separator -->
2129 </xsl:for-each>
2130 </xsl:variable>
2131 <!-- Determine maximum height so every entry must be this high -->
2132 <xsl:variable
2133 name="maxHeight"
2134 select="math:max(str:tokenize(normalize-space($heights)))"/>
2135 <!-- Output all the physical lines of this row -->
2136 <xsl:call-template
2137 name="u:rowLines">
2138 <xsl:with-param
2139 name="currentLine"
2140 select="1"/>
2141 <xsl:with-param
2142 name="maxLine"
2143 select="$maxHeight"/>
2144 </xsl:call-template>
2145 <!-- Output final separator line if this is the last row -->
2146 <xsl:if
2147 test="position() = last()">
2148 <xsl:call-template
2149 name="u:rowSeparatorLine">
2150 <xsl:with-param
2151 name="char">
2152 <!-- Determine correct character for the separator line -->
2153 <xsl:choose>
2154 <xsl:when
2155 test="parent::thead">
2156 <xsl:value-of
2157 select="'='"/>
2158 </xsl:when>
2159 <xsl:otherwise>
2160 <xsl:value-of
2161 select="'-'"/>
2162 </xsl:otherwise>
2163 </xsl:choose>
2164 </xsl:with-param>
2165 </xsl:call-template>
2166 </xsl:if>
2167 </xsl:template>
2169 <!-- Output physical line $currentLine of a row and continue until
2170 line $maxLine is output -->
2171 <xsl:template
2172 name="u:rowLines">
2173 <xsl:param
2174 name="currentLine"/>
2175 <xsl:param
2176 name="maxLine"/>
2177 <xsl:if
2178 test="$currentLine &lt;= $maxLine">
2179 <!-- If there are still physical lines to output do it -->
2180 <xsl:call-template
2181 name="u:indent"/>
2182 <!-- Leading bar -->
2183 <xsl:text>|</xsl:text>
2184 <xsl:apply-templates>
2185 <xsl:with-param
2186 name="currentLine"
2187 select="$currentLine"/>
2188 </xsl:apply-templates>
2189 <!-- End of this physical line -->
2190 &tEOL;
2191 <!-- Continue with the next physical line -->
2192 <xsl:call-template
2193 name="u:rowLines">
2194 <xsl:with-param
2195 name="currentLine"
2196 select="$currentLine + 1"/>
2197 <xsl:with-param
2198 name="maxLine"
2199 select="$maxLine"/>
2200 </xsl:call-template>
2201 </xsl:if>
2202 </xsl:template>
2204 <!-- Output a separator line with all the right characters -->
2205 <xsl:template
2206 name="u:rowSeparatorLine">
2207 <xsl:param
2208 name="char"
2209 select="'-'"/>
2210 <xsl:call-template
2211 name="u:indent"/>
2212 <xsl:text>+</xsl:text>
2213 <xsl:for-each
2214 select="../../colspec">
2215 <xsl:value-of
2216 select="str:padding(@colwidth, $char)"/>
2217 <xsl:text>+</xsl:text>
2218 </xsl:for-each>
2219 &tEOL;
2220 </xsl:template>
2222 <!-- ******************************************************************** -->
2224 <!--
2225 Content Model: (%body.elements;)*
2226 Attributes: The entry element contains the common attributes and:
2227 colname, namest, morerows, colsep, rowsep, align, char, charoff, valign and
2228 morecols
2230 <!-- == compound_body_subelement -->
2231 <xsl:template
2232 match="entry">
2233 <!-- TODO `classes` attribute needs support -->
2234 <!-- This is called in two ways; if $currentLine = 0 all physical lines
2235 of this entry must be output; if $currentLine > 0 the physical line
2236 with exactly this number shall be output -->
2237 <xsl:param
2238 name="currentLine"
2239 select="0"/>
2240 <xsl:variable
2241 name="column"
2242 select="position() + sum(preceding-sibling::entry/@morecols)"/>
2243 <!-- Determine width in characters needed for this entry -->
2244 <xsl:variable
2245 name="width">
2246 <xsl:call-template
2247 name="u:computeEntryWidth">
2248 <xsl:with-param
2249 name="colspecs"
2250 select="../../../colspec"/>
2251 <xsl:with-param
2252 name="column"
2253 select="$column"/>
2254 <xsl:with-param
2255 name="span"
2256 select="@morecols"/>
2257 </xsl:call-template>
2258 </xsl:variable>
2259 <!-- Output the entry completely or a certain physical line -->
2260 <xsl:call-template
2261 name="u:outputEntry">
2262 <xsl:with-param
2263 name="string">
2264 <!-- Capture physical lines of the entry in a variable -->
2265 <xsl:apply-templates/>
2266 </xsl:with-param>
2267 <xsl:with-param
2268 name="width"
2269 select="$width"/>
2270 <xsl:with-param
2271 name="expectedIndent">
2272 <!-- Capture indent for the entry generated by the normal template
2273 rules to remove it later -->
2274 <xsl:call-template
2275 name="u:indent"/>
2276 </xsl:with-param>
2277 <xsl:with-param
2278 name="outputLine"
2279 select="$currentLine"/>
2280 </xsl:call-template>
2281 <!-- Final bar after the entry -->
2282 <xsl:text>|</xsl:text>
2283 </xsl:template>
2285 <!-- Compute width of the entry -->
2286 <xsl:template
2287 name="u:computeEntryWidth">
2288 <!-- The colspec elements of all columns -->
2289 <xsl:param
2290 name="colspecs"/>
2291 <!-- Column of this entry -->
2292 <xsl:param
2293 name="column"/>
2294 <!-- Number of columns this entry spans -->
2295 <xsl:param
2296 name="span"
2297 select="0"/>
2298 <xsl:param
2299 name="sum"
2300 select="0"/>
2301 <xsl:choose>
2302 <xsl:when
2303 test="$span">
2304 <!-- If entry spans multiple columns compute their width -->
2305 <xsl:call-template
2306 name="u:computeEntryWidth">
2307 <xsl:with-param
2308 name="colspecs"
2309 select="$colspecs"/>
2310 <xsl:with-param
2311 name="column"
2312 select="$column + 1"/>
2313 <xsl:with-param
2314 name="span"
2315 select="$span - 1"/>
2316 <!-- Add the separator character and the following column width -->
2317 <xsl:with-param
2318 name="sum"
2319 select="$sum + 1 + $colspecs[$column]/@colwidth"/>
2320 </xsl:call-template>
2321 </xsl:when>
2322 <xsl:otherwise>
2323 <!-- Does not span more columns so return sum and width of this
2324 column -->
2325 <xsl:value-of
2326 select="$sum + $colspecs[$column]/@colwidth"/>
2327 </xsl:otherwise>
2328 </xsl:choose>
2329 </xsl:template>
2331 <!-- Outputs one or all lines of a table entry as a string trimmed left and
2332 padded -->
2333 <xsl:template
2334 name="u:outputEntry">
2335 <!-- Width of the entry; there is no provision for actual physical lines
2336 longer than this width -->
2337 <xsl:param
2338 name="width"/>
2339 <!-- The string containing the remaining physical lines; may be an empty
2340 string -->
2341 <xsl:param
2342 name="string"
2343 select="''"/>
2344 <!-- The indendation which is expected to be prefixed before every
2345 physical line -->
2346 <xsl:param
2347 name="expectedIndent"
2348 select="''"/>
2349 <!-- Is this the first call to this template -->
2350 <xsl:param
2351 name="isFirst"
2352 select="true()"/>
2353 <!-- Number of physical line to output or 0 to output all lines -->
2354 <xsl:param
2355 name="outputLine"
2356 select="0"/>
2357 <!-- Output is wanted if all or the first physical line are to be
2358 output -->
2359 <xsl:variable
2360 name="doOutput"
2361 select="$outputLine = 0 or $outputLine = 1"/>
2362 <xsl:variable
2363 name="stringLFHalfTrimmed">
2364 <xsl:choose>
2365 <xsl:when
2366 test="$isFirst and substring($string, 1, 1) = '&#x0A;'">
2367 <!-- Remove leading linefeed if this is the first time -->
2368 <xsl:value-of
2369 select="substring($string, 2)"/>
2370 </xsl:when>
2371 <xsl:otherwise>
2372 <xsl:value-of
2373 select="$string"/>
2374 </xsl:otherwise>
2375 </xsl:choose>
2376 </xsl:variable>
2377 <xsl:variable
2378 name="stringLFTrimmed">
2379 <xsl:choose>
2380 <xsl:when
2381 test="$isFirst and substring($stringLFHalfTrimmed, string-length($stringLFHalfTrimmed), 1) = '&#x0A;'">
2382 <!-- Remove trailing linefeed if this is the first time -->
2383 <xsl:value-of
2384 select="substring($stringLFHalfTrimmed, 1, string-length($stringLFHalfTrimmed) - 1)"/>
2385 </xsl:when>
2386 <xsl:otherwise>
2387 <xsl:value-of
2388 select="$stringLFHalfTrimmed"/>
2389 </xsl:otherwise>
2390 </xsl:choose>
2391 </xsl:variable>
2392 <!-- Determine remaining lines after the first one -->
2393 <xsl:variable
2394 name="remainingLines">
2395 <xsl:if
2396 test="contains($stringLFTrimmed, '&#x0A;')">
2397 <xsl:value-of
2398 select="substring-after($stringLFTrimmed, '&#x0A;')"/>
2399 </xsl:if>
2400 </xsl:variable>
2401 <xsl:if
2402 test="$doOutput">
2403 <!-- If this physical line must be output determine the first physical
2404 line -->
2405 <xsl:variable
2406 name="firstLine">
2407 <xsl:choose>
2408 <xsl:when
2409 test="string-length($remainingLines)">
2410 <xsl:value-of
2411 select="substring-before($stringLFTrimmed, '&#x0A;')"/>
2412 </xsl:when>
2413 <xsl:otherwise>
2414 <xsl:value-of
2415 select="$stringLFTrimmed"/>
2416 </xsl:otherwise>
2417 </xsl:choose>
2418 </xsl:variable>
2419 <!-- Remove the leading indentation from the physical line which is
2420 brought there by the normal templates -->
2421 <xsl:variable
2422 name="trimmed">
2423 <xsl:if
2424 test="string-length($firstLine)">
2425 <!-- Trim only non-empty lines -->
2426 <xsl:value-of
2427 select="substring-after($firstLine, $expectedIndent)"/>
2428 </xsl:if>
2429 </xsl:variable>
2430 <!-- Pad the line with a leading and a trailing space -->
2431 <xsl:variable
2432 name="padded"
2433 select="concat(' ', $trimmed, ' ')"/>
2434 <!-- Output the padded value -->
2435 <xsl:value-of
2436 select="$padded"/>
2437 <!-- Fill up the width of the entry with spaces -->
2438 <xsl:if
2439 test="$width - string-length($padded) &lt; 0">
2440 <xsl:message>
2441 <xsl:text>WARNING: Table column too narrow (minimum: </xsl:text>
2442 <xsl:value-of
2443 select="string-length($padded)"/>
2444 <xsl:text>)</xsl:text>
2445 &tEOL;
2446 </xsl:message>
2447 </xsl:if>
2448 <xsl:value-of
2449 select="str:padding($width - string-length($padded))"/>
2450 </xsl:if>
2451 <xsl:if
2452 test="$outputLine > 1 or $outputLine = 0 and string-length($remainingLines)">
2453 <!-- If a following physical line must be output or if all physical
2454 lines shall be output and there are remaining physical lines -->
2455 <xsl:if
2456 test="$outputLine = 0">
2457 <!-- Output linefeed only if we output all the lines -->
2458 &tEOL;
2459 </xsl:if>
2460 <!-- Output the remaining lines -->
2461 <xsl:call-template
2462 name="u:outputEntry">
2463 <xsl:with-param
2464 name="width"
2465 select="$width"/>
2466 <xsl:with-param
2467 name="string"
2468 select="$remainingLines"/>
2469 <xsl:with-param
2470 name="expectedIndent"
2471 select="$expectedIndent"/>
2472 <xsl:with-param
2473 name="isFirst"
2474 select="false()"/>
2475 <xsl:with-param
2476 name="outputLine">
2477 <xsl:choose>
2478 <xsl:when
2479 test="$outputLine = 0">
2480 <xsl:value-of
2481 select="0"/>
2482 </xsl:when>
2483 <xsl:otherwise>
2484 <xsl:value-of
2485 select="$outputLine - 1"/>
2486 </xsl:otherwise>
2487 </xsl:choose>
2488 </xsl:with-param>
2489 </xsl:call-template>
2490 </xsl:if>
2491 </xsl:template>
2493 <!-- ******************************************************************** -->
2494 <!-- ******************************************************************** -->
2496 <!-- == inline_element -->
2497 <xsl:template
2498 match="citation_reference">
2499 <xsl:call-template
2500 name="u:bkslshEscPre"/>
2501 <xsl:text>[</xsl:text>
2502 <xsl:apply-templates/>
2503 <xsl:text>]_</xsl:text>
2504 <xsl:call-template
2505 name="u:bkslshEscSuf"/>
2506 </xsl:template>
2508 <!-- ******************************************************************** -->
2510 <!-- == inline_element -->
2511 <xsl:template
2512 match="emphasis">
2513 <xsl:call-template
2514 name="u:bkslshEscPre"/>
2515 <xsl:text>*</xsl:text>
2516 <xsl:apply-templates/>
2517 <xsl:text>*</xsl:text>
2518 <xsl:call-template
2519 name="u:bkslshEscSuf"/>
2520 </xsl:template>
2522 <!-- ******************************************************************** -->
2524 <!-- user-numbered footnotes lack @auto -->
2525 <!-- == inline_element -->
2526 <xsl:template
2527 match="footnote_reference[not(@auto)]">
2528 <xsl:call-template
2529 name="u:bkslshEscPre"/>
2530 <xsl:text>[</xsl:text>
2531 <xsl:value-of
2532 select="text()"/>
2533 <xsl:text>]_</xsl:text>
2534 <xsl:call-template
2535 name="u:bkslshEscSuf"/>
2536 <!-- child paragraph provides blank line -->
2537 </xsl:template>
2539 <!-- automatically numbered footnotes have @auto -->
2540 <!-- if @names is different from label content, it is a named footnote -->
2541 <!-- == inline_element -->
2542 <xsl:template
2543 match="footnote_reference[@auto='1']">
2544 <xsl:variable
2545 name="ref"
2546 select="@refid"/>
2547 <xsl:if
2548 test="not(starts-with(//footnote[@ids=$ref]/@names, 'TARGET_NOTE:\ '))">
2549 <!-- Not a generated footnote reference for a `.. target-notes::';
2550 such footnote reference and the preceding space should be
2551 embedded in `generated'! -->
2552 <xsl:call-template
2553 name="u:bkslshEscPre"/>
2554 <xsl:text>[#</xsl:text>
2555 <xsl:if
2556 test="//footnote[@ids=$ref]/@names != //footnote[@ids=$ref]/label">
2557 <xsl:call-template
2558 name="u:outputNames">
2559 <xsl:with-param
2560 name="names"
2561 select="//footnote[@ids=$ref]/@names"/>
2562 </xsl:call-template>
2563 </xsl:if>
2564 <xsl:text>]_</xsl:text>
2565 <xsl:call-template
2566 name="u:bkslshEscSuf"/>
2567 </xsl:if>
2568 </xsl:template>
2570 <!-- automatically symboled footnotes have @auto=* -->
2571 <!-- == inline_element -->
2572 <xsl:template
2573 match="footnote_reference[@auto='*']">
2574 <xsl:call-template
2575 name="u:bkslshEscPre"/>
2576 <xsl:text>[*]_</xsl:text>
2577 <xsl:call-template
2578 name="u:bkslshEscSuf"/>
2579 </xsl:template>
2581 <!-- ******************************************************************** -->
2583 <!--
2584 Content Model: %text.model;
2586 <!-- == inline_element -->
2587 <xsl:template
2588 match="literal">
2589 <xsl:call-template
2590 name="u:bkslshEscPre"/>
2591 <xsl:text>``</xsl:text>
2592 <xsl:apply-templates/>
2593 <xsl:text>``</xsl:text>
2594 <xsl:call-template
2595 name="u:bkslshEscSuf"/>
2596 </xsl:template>
2598 <!-- ******************************************************************** -->
2600 <!-- Attribute combinations found in `standard' text and other examples:
2601 @refuri = standalone hyperlink
2602 @ids @refid = TOC, probably all in <generated>
2603 @name @refuri with matching <target> in document = named external hyperlink _
2604 @name @refuri immediately followed by matching <target> = named embedded URI _
2605 @name @refuri with no matching <target> in document = anonymous embedded URI __
2606 @anonymous @name @refuri with no matching <target> in document = anonymous explicit URI __
2607 @name @refid = internal cross-reference _
2608 @anonymous @name @refid = anonymous implicit internal reference __
2609 @name @refid image = clickable image to internal reference _
2610 @refuri image = clickable image to standalone hyperlink
2612 A target matches if target/@names contains the lower cased, whitespace
2613 quoted reference/@name
2616 <!-- Standalone hyperlink -->
2617 <!-- == inline_element -->
2618 <xsl:template
2619 match="reference[not(@name or @anonymous)]">
2620 <xsl:call-template
2621 name="u:bkslshEscPre"/>
2622 <xsl:choose>
2623 <xsl:when
2624 test="starts-with(., 'PEP ')">
2625 <xsl:text>:PEP:`</xsl:text>
2626 <xsl:value-of
2627 select="substring-after(., 'PEP ')"/>
2628 <xsl:text>`</xsl:text>
2629 </xsl:when>
2630 <xsl:when
2631 test="starts-with(., 'RFC ')">
2632 <xsl:text>:RFC:`</xsl:text>
2633 <xsl:value-of
2634 select="substring-after(., 'RFC ')"/>
2635 <xsl:text>`</xsl:text>
2636 </xsl:when>
2637 <xsl:otherwise>
2638 <xsl:apply-templates/>
2639 </xsl:otherwise>
2640 </xsl:choose>
2641 <xsl:call-template
2642 name="u:bkslshEscSuf"/>
2643 </xsl:template>
2645 <!-- External references -->
2646 <!-- == inline_element -->
2647 <xsl:template
2648 match="reference[@name and @refuri]">
2649 <!-- Determine normalized name by downcasing it -->
2650 <xsl:variable
2651 name="normalized"
2652 select="translate(normalize-space(@name), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"/>
2653 <xsl:variable
2654 name="quoted"
2655 select="str:replace($normalized, ' ', '\ ')"/>
2656 <xsl:variable
2657 name="matching"
2658 select="//target[contains(@names, $quoted)]"/>
2659 <xsl:call-template
2660 name="u:inlineReference">
2661 <xsl:with-param
2662 name="anonymous"
2663 select="not($matching) or @anonymous"/>
2664 <xsl:with-param
2665 name="embedded"
2666 select="not(@anonymous) and (not($matching) or generate-id(following-sibling::node()[1]) = generate-id($matching))"/>
2667 </xsl:call-template>
2668 </xsl:template>
2670 <!-- Internal references -->
2671 <!-- == inline_element -->
2672 <xsl:template
2673 match="reference[@name and @refid]">
2674 <xsl:call-template
2675 name="u:inlineReference">
2676 <xsl:with-param
2677 name="anonymous"
2678 select="@anonymous"/>
2679 </xsl:call-template>
2680 </xsl:template>
2682 <!-- Image references -->
2683 <!-- == inline_element -->
2684 <xsl:template
2685 match="reference[image]">
2686 <!-- All done by the `image' tag -->
2687 <xsl:apply-templates/>
2688 </xsl:template>
2690 <!-- ******************************************************************** -->
2692 <!--
2693 Content Model: %text.model;
2695 <!-- == inline_element -->
2696 <xsl:template
2697 match="strong">
2698 <xsl:call-template
2699 name="u:bkslshEscPre"/>
2700 <xsl:text>**</xsl:text>
2701 <xsl:apply-templates/>
2702 <xsl:text>**</xsl:text>
2703 <xsl:call-template
2704 name="u:bkslshEscSuf"/>
2705 </xsl:template>
2707 <!-- ******************************************************************** -->
2709 <!-- == inline_element -->
2710 <xsl:template
2711 match="subscript">
2712 <xsl:call-template
2713 name="u:bkslshEscPre"/>
2714 <xsl:text>:sub:`</xsl:text>
2715 <xsl:apply-templates/>
2716 <xsl:text>`</xsl:text>
2717 <xsl:call-template
2718 name="u:bkslshEscSuf"/>
2719 </xsl:template>
2721 <!-- ******************************************************************** -->
2723 <!-- == inline_element -->
2724 <xsl:template
2725 match="superscript">
2726 <xsl:call-template
2727 name="u:bkslshEscPre"/>
2728 <xsl:text>:sup:`</xsl:text>
2729 <xsl:apply-templates/>
2730 <xsl:text>`</xsl:text>
2731 <xsl:call-template
2732 name="u:bkslshEscSuf"/>
2733 </xsl:template>
2735 <!-- ******************************************************************** -->
2737 <!-- The target element has various roles depending on context; they are
2738 all handled here -->
2739 <!-- == simple_body_element == inline_element == directive -->
2740 <xsl:template
2741 match="target">
2742 <xsl:choose>
2743 <xsl:when
2744 test="name(preceding-sibling::*[1]) = 'reference'">
2745 <!-- An embedded inline target - handled by the reference itself -->
2746 </xsl:when>
2747 <xsl:when
2748 test="contains($inline_containers, concat('*', name(..), '*'))">
2749 <!-- An inline target of some sort -->
2750 <xsl:call-template
2751 name="u:inlineReference">
2752 <xsl:with-param
2753 name="isTarget"
2754 select="true()"/>
2755 </xsl:call-template>
2756 </xsl:when>
2757 <xsl:when
2758 test="@anonymous">
2759 <!-- An anonymous target directive -->
2760 <xsl:call-template
2761 name="u:outputClass"/>
2762 <xsl:call-template
2763 name="u:BandI"/>
2764 <xsl:text>__ </xsl:text>
2765 <xsl:choose>
2766 <xsl:when
2767 test="@refid">
2768 <xsl:call-template
2769 name="u:outputNamesRefid"/>
2770 <xsl:text>_</xsl:text>
2771 </xsl:when>
2772 <xsl:when
2773 test="@refuri">
2774 <xsl:value-of
2775 select="@refuri"/>
2776 </xsl:when>
2777 </xsl:choose>
2778 &tEOL;
2779 </xsl:when>
2780 <xsl:when
2781 test="@names | @refid">
2782 <!-- A target directive -->
2783 <xsl:call-template
2784 name="u:outputClass"/>
2785 <xsl:call-template
2786 name="u:BandI"/>
2787 <xsl:text>.. _</xsl:text>
2788 <xsl:choose>
2789 <xsl:when
2790 test="@refid">
2791 <xsl:call-template
2792 name="u:outputNamesRefid"/>
2793 </xsl:when>
2794 <xsl:otherwise>
2795 <xsl:call-template
2796 name="u:outputNames"/>
2797 </xsl:otherwise>
2798 </xsl:choose>
2799 <xsl:text>:</xsl:text>
2800 <xsl:if
2801 test="@refuri">
2802 <xsl:text> </xsl:text>
2803 <xsl:value-of
2804 select="@refuri"/>
2805 </xsl:if>
2806 &tEOL;
2807 </xsl:when>
2808 <xsl:otherwise>
2809 <!-- Should not happen -->
2810 <xsl:call-template
2811 name="u:notSupported"/>
2812 </xsl:otherwise>
2813 </xsl:choose>
2814 </xsl:template>
2816 <!-- ******************************************************************** -->
2818 <!--
2819 Content Model: %text.model;
2821 <!-- == inline_element -->
2822 <xsl:template
2823 match="title_reference">
2824 <xsl:call-template
2825 name="u:bkslshEscPre"/>
2826 <xsl:text>`</xsl:text>
2827 <xsl:apply-templates/>
2828 <xsl:text>`</xsl:text>
2829 <xsl:call-template
2830 name="u:bkslshEscSuf"/>
2831 </xsl:template>
2833 <!-- ******************************************************************** -->
2835 <!--
2836 Content Model: %text.model;
2838 <!-- == inline_element -->
2839 <xsl:template
2840 match="inline">
2841 <!-- TODO `role' directives must be generated for plain and derived
2842 user-defined roles. -->
2843 <xsl:call-template
2844 name="u:bkslshEscPre"/>
2845 <xsl:text>:</xsl:text>
2846 <xsl:value-of
2847 select="@classes"/>
2848 <xsl:text>:`</xsl:text>
2849 <xsl:apply-templates/>
2850 <xsl:text>`</xsl:text>
2851 <xsl:call-template
2852 name="u:bkslshEscSuf"/>
2853 </xsl:template>
2855 <!-- ******************************************************************** -->
2857 <!-- TODO `meta` directive must be implemented. -->
2859 <!-- ******************************************************************** -->
2861 <!--
2862 Docutils wraps generated elements around text that is inserted (generated) by
2863 Docutils; i.e., text that was not in the document, like section numbers
2864 inserted by the "sectnum" directive.
2866 <!-- == inline_element -->
2867 <xsl:template
2868 match="generated"/>
2870 <!-- == inline_element -->
2871 <xsl:template
2872 match="problematic">
2873 <!-- Simply output the contained text because this is probably the
2874 original text-->
2875 <xsl:value-of
2876 select="text()"/>
2877 </xsl:template>
2879 <!-- == compound_body_element -->
2880 <xsl:template
2881 match="system_message"/>
2883 <!-- ******************************************************************** -->
2884 <!-- ******************************************************************** -->
2886 <!--
2887 When a block of text contains linefeeds, it was indented relative to a marker
2888 on the first line
2890 <xsl:template
2891 match="text()">
2892 <xsl:call-template
2893 name="u:indentLF"/>
2894 </xsl:template>
2896 <!-- ******************************************************************** -->
2897 <!-- ******************************************************************** -->
2899 <!-- Add a blank line if necessary and indent -->
2900 <xsl:template
2901 name="u:BandI">
2902 <xsl:call-template
2903 name="u:blank"/>
2904 <xsl:call-template
2905 name="u:indent"/>
2906 </xsl:template>
2908 <!-- ******************************************************************** -->
2910 <!-- Add a blank line in certain contexts -->
2911 <xsl:template
2912 name="u:blank">
2913 <xsl:apply-templates
2914 mode="blankSkipInline"
2915 select="preceding::*[1]"/>
2916 </xsl:template>
2918 <!-- Find the preceding element we are really interested in and act
2919 according to this element -->
2920 <xsl:template
2921 mode="blankSkipInline"
2922 match="*">
2923 <xsl:choose>
2924 <!-- Skip all inline elements and body subelements and check their
2925 parents -->
2926 <xsl:when
2927 test="contains(concat($inline_elements, $simple_body_subelements, $compound_body_subelements), concat('*', name(.), '*'))">
2928 <xsl:apply-templates
2929 mode="blankSkipInline"
2930 select=".."/>
2931 </xsl:when>
2932 <xsl:otherwise>
2933 <!-- Reached the type of element we decide on -->
2934 <xsl:if
2935 test="contains($blank_after, concat('*', name(.), '*'))">
2936 &tCR;
2937 </xsl:if>
2938 </xsl:otherwise>
2939 </xsl:choose>
2940 </xsl:template>
2942 <!-- ******************************************************************** -->
2944 <!--
2945 Indent a block if it's a child of...
2947 <data:lookup>
2948 <node
2949 name="address"
2950 indent="10"/>
2951 <node
2952 name="author"
2953 indent="9"/>
2954 <node
2955 name="authors"
2956 indent="10"/>
2957 <node
2958 name="contact"
2959 indent="10"/>
2960 <node
2961 name="copyright"
2962 indent="12"/>
2963 <node
2964 name="date"
2965 indent="7"/>
2966 <node
2967 name="organization"
2968 indent="15"/>
2969 <node
2970 name="revision"
2971 indent="11"/>
2972 <node
2973 name="status"
2974 indent="9"/>
2975 <node
2976 name="version"
2977 indent="10"/>
2978 <!-- This is only for `bullet_list/list_item';
2979 `enumerated_list/list_item' is handled special -->
2980 <node
2981 name="list_item"
2982 indent="2"/>
2983 <node
2984 name="definition_list_item"
2985 indent="4"/>
2986 <node
2987 name="field_body"
2988 indent="4"/>
2989 <node
2990 name="option_list_item"
2991 indent="4"/>
2992 <!-- This is also the indentation if block_quote comes as one of the
2993 special directives -->
2994 <node
2995 name="block_quote"
2996 indent="4"/>
2997 <node
2998 name="literal_block"
2999 indent="4"/>
3000 <node
3001 name="attribution"
3002 indent="3"/>
3003 <node
3004 name="line"
3005 indent="2"/>
3006 </data:lookup>
3008 <!-- Do indent according to ancestor -->
3009 <xsl:template
3010 name="u:indent">
3011 <!-- In some cases the ancestors to indent for need to be determined
3012 by the calling template -->
3013 <xsl:param
3014 name="ancestors"
3015 select="ancestor::*"/>
3016 <xsl:for-each
3017 select="$ancestors">
3018 <xsl:variable
3019 name="this"
3020 select="name()"/>
3021 <xsl:choose>
3022 <xsl:when
3023 test="contains($directives, concat('*', $this, '*'))">
3024 <!-- TODO Indentation of lines after some directives must be
3025 indented to align with the directive instead of a
3026 fixed indentation; however, this is rather complicated
3027 since identation for parameters should be fixed -->
3028 <xsl:value-of
3029 select="str:padding(3)"/>
3030 </xsl:when>
3031 <xsl:when
3032 test="$this = 'list_item' and parent::enumerated_list">
3033 <!-- Enumerated list items base their indentation on the
3034 numeration -->
3035 <xsl:variable
3036 name="enumerator">
3037 <xsl:call-template
3038 name="u:outputEnumerator"/>
3039 </xsl:variable>
3040 <xsl:value-of
3041 select="str:padding(string-length($enumerator))"/>
3042 </xsl:when>
3043 <xsl:otherwise>
3044 <xsl:value-of
3045 select="str:padding(document('')//data:lookup/node[@name=$this]/@indent)"/>
3046 </xsl:otherwise>
3047 </xsl:choose>
3048 </xsl:for-each>
3049 </xsl:template>
3051 <!-- ******************************************************************** -->
3053 <!-- Indent a text containing line feeds correctly -->
3054 <xsl:template
3055 name="u:indentLF">
3056 <xsl:param
3057 name="string"
3058 select="."/>
3059 <!-- A fixed indentation may be given by caller -->
3060 <xsl:param
3061 name="indent">
3062 <!-- If not given compute it -->
3063 <xsl:call-template
3064 name="u:indent"/>
3065 </xsl:param>
3066 <xsl:choose>
3067 <xsl:when
3068 test="contains($string,'&#x0A;')">
3069 <!-- Output first physical line -->
3070 <xsl:value-of
3071 select="substring-before($string, '&#x0A;')"/>
3072 &tEOL;
3073 <!-- Indent before the next line -->
3074 <xsl:value-of
3075 select="$indent"/>
3076 <!-- Output remaining physical lines -->
3077 <xsl:call-template
3078 name="u:indentLF">
3079 <xsl:with-param
3080 name="string"
3081 select="substring-after($string, '&#x0A;')"/>
3082 <xsl:with-param
3083 name="indent"
3084 select="$indent"/>
3085 </xsl:call-template>
3086 </xsl:when>
3087 <!-- String does not contain newline, so just output it -->
3088 <xsl:otherwise>
3089 <xsl:value-of
3090 select="$string"/>
3091 </xsl:otherwise>
3092 </xsl:choose>
3093 </xsl:template>
3095 <!-- ******************************************************************** -->
3097 <!-- Do output for those elements which do fold their inline content -->
3098 <xsl:template
3099 name="u:outputFolding">
3100 <!-- The prefix text to be output before the body -->
3101 <xsl:param
3102 name="prefix"
3103 select="''"/>
3104 <!-- The indentation for this body -->
3105 <xsl:param
3106 name="indent">
3107 <xsl:call-template
3108 name="u:indent">
3109 <xsl:with-param
3110 name="ancestors"
3111 select="ancestor-or-self::*"/>
3112 </xsl:call-template>
3113 </xsl:param>
3114 <xsl:variable
3115 name="string">
3116 <!-- TODO Whitespace count of inline literals must be preserved -->
3117 <xsl:apply-templates/>
3118 </xsl:variable>
3119 <!-- Always output prefix with all trailing and leading spaces -->
3120 <xsl:value-of
3121 select="$prefix"/>
3122 <xsl:choose>
3123 <xsl:when
3124 test="$fold &gt; 0">
3125 <xsl:variable
3126 name="normalized"
3127 select="normalize-space($string)"/>
3128 <xsl:choose>
3129 <xsl:when
3130 test="$string = ''">
3131 <!-- Empty strings need no output -->
3132 </xsl:when>
3133 <xsl:when
3134 test="$normalized = ''">
3135 <!-- Only white-space in string; output a single space here -->
3136 &tSP;
3137 </xsl:when>
3138 <xsl:otherwise>
3139 <!-- Output leading white-space here -->
3140 <xsl:if
3141 test="normalize-space(substring($string, 1, 1)) = ''">
3142 &tSP;
3143 </xsl:if>
3144 <xsl:call-template
3145 name="u:indentFold">
3146 <xsl:with-param
3147 name="string"
3148 select="$normalized"/>
3149 <xsl:with-param
3150 name="indent"
3151 select="$indent"/>
3152 <xsl:with-param
3153 name="cursorColumn"
3154 select="string-length($indent) + string-length($prefix)"/>
3155 </xsl:call-template>
3156 <!-- Output trailing white-space here -->
3157 <xsl:if
3158 test="normalize-space(substring($string, string-length($string), 1)) = ''">
3159 &tSP;
3160 </xsl:if>
3161 </xsl:otherwise>
3162 </xsl:choose>
3163 </xsl:when>
3164 <xsl:otherwise>
3165 <xsl:value-of
3166 select="$string"/>
3167 </xsl:otherwise>
3168 </xsl:choose>
3169 &tEOL;
3170 </xsl:template>
3172 <!-- ******************************************************************** -->
3174 <!-- Indent a string with folding -->
3175 <xsl:template
3176 name="u:indentFold">
3177 <!-- Normalized string to output -->
3178 <xsl:param
3179 name="string"/>
3180 <!-- Indentation to use for a new line -->
3181 <xsl:param
3182 name="indent"/>
3183 <!-- Current output column -->
3184 <!-- TODO This is not a correct assumption for field definitions where
3185 the field name effectively determines the column of the first
3186 line -->
3187 <xsl:param
3188 name="cursorColumn"
3189 select="string-length($indent)"/>
3190 <!-- Do we start on a new (indented) line? -->
3191 <xsl:param
3192 name="isNewLine"
3193 select="true()"/>
3194 <xsl:variable
3195 name="firstWord">
3196 <xsl:choose>
3197 <!-- TODO Quoted spaces must not end a word -->
3198 <xsl:when
3199 test="contains($string, ' ')">
3200 <xsl:value-of
3201 select="substring-before($string, ' ')"/>
3202 </xsl:when>
3203 <xsl:otherwise>
3204 <xsl:value-of
3205 select="$string"/>
3206 </xsl:otherwise>
3207 </xsl:choose>
3208 </xsl:variable>
3209 <xsl:variable
3210 name="rest"
3211 select="substring-after($string, ' ')"/>
3212 <xsl:choose>
3213 <xsl:when
3214 test="$string = ''"/>
3215 <xsl:when
3216 test="$isNewLine">
3217 <!-- Output at least first word -->
3218 <xsl:value-of
3219 select="$firstWord"/>
3220 <xsl:call-template
3221 name="u:indentFold">
3222 <xsl:with-param
3223 name="string"
3224 select="$rest"/>
3225 <xsl:with-param
3226 name="indent"
3227 select="$indent"/>
3228 <xsl:with-param
3229 name="cursorColumn"
3230 select="$cursorColumn + string-length($firstWord)"/>
3231 <xsl:with-param
3232 name="isNewLine"
3233 select="false()"/>
3234 </xsl:call-template>
3235 </xsl:when>
3236 <xsl:when
3237 test="$cursorColumn + 1 + string-length($firstWord) &gt; $fold">
3238 <!-- Line would get too long; start new line, indent and continue -->
3239 &tEOL;
3240 <xsl:value-of
3241 select="$indent"/>
3242 <xsl:call-template
3243 name="u:indentFold">
3244 <xsl:with-param
3245 name="string"
3246 select="$string"/>
3247 <xsl:with-param
3248 name="indent"
3249 select="$indent"/>
3250 <xsl:with-param
3251 name="cursorColumn"
3252 select="string-length($indent)"/>
3253 <xsl:with-param
3254 name="isNewLine"
3255 select="true()"/>
3256 </xsl:call-template>
3257 </xsl:when>
3258 <xsl:otherwise>
3259 <!-- In a line and first word fits; separate and add word -->
3260 &tSP;
3261 <xsl:value-of
3262 select="$firstWord"/>
3263 <xsl:call-template
3264 name="u:indentFold">
3265 <xsl:with-param
3266 name="string"
3267 select="$rest"/>
3268 <xsl:with-param
3269 name="indent"
3270 select="$indent"/>
3271 <xsl:with-param
3272 name="cursorColumn"
3273 select="$cursorColumn + 1 + string-length($firstWord)"/>
3274 <xsl:with-param
3275 name="isNewLine"
3276 select="false()"/>
3277 </xsl:call-template>
3278 </xsl:otherwise>
3279 </xsl:choose>
3280 </xsl:template>
3282 <!-- ******************************************************************** -->
3284 <!-- Output attributes of the current element as a field list -->
3285 <xsl:template
3286 name="u:params">
3287 <xsl:param
3288 name="params"
3289 select="@*"/>
3290 <!-- Ancestors are needed for determining indentation; caller may give
3291 them -->
3292 <xsl:param
3293 name="ancestors"
3294 select="ancestor-or-self::*"/>
3295 <xsl:for-each
3296 select="$params">
3297 <!-- Skip URIs based on parent -->
3298 <xsl:if
3299 test="name() != 'uri' and name() != 'xml:space'">
3300 <xsl:call-template
3301 name="u:param">
3302 <xsl:with-param
3303 name="ancestors"
3304 select="$ancestors"/>
3305 </xsl:call-template>
3306 </xsl:if>
3307 </xsl:for-each>
3308 </xsl:template>
3310 <!-- Output one attribute of the current element as a field list -->
3311 <xsl:template
3312 name="u:param">
3313 <xsl:param
3314 name="name"
3315 select="name()"/>
3316 <xsl:param
3317 name="value"
3318 select="."/>
3319 <!-- Ancestors are needed for determining indentation; caller may give
3320 them -->
3321 <xsl:param
3322 name="ancestors"
3323 select="ancestor::*"/>
3324 <xsl:call-template
3325 name="u:indent">
3326 <xsl:with-param
3327 name="ancestors"
3328 select="$ancestors"/>
3329 </xsl:call-template>
3330 <xsl:text>:</xsl:text>
3331 <xsl:choose>
3332 <xsl:when
3333 test="$name = 'classes'">
3334 <xsl:text>class</xsl:text>
3335 </xsl:when>
3336 <xsl:otherwise>
3337 <xsl:value-of
3338 select="$name"/>
3339 </xsl:otherwise>
3340 </xsl:choose>
3341 <xsl:text>:</xsl:text>
3342 <xsl:if
3343 test="$value">
3344 <xsl:text> </xsl:text>
3345 <xsl:value-of
3346 select="$value"/>
3347 </xsl:if>
3348 &tEOL;
3349 </xsl:template>
3351 <!-- ******************************************************************** -->
3353 <!-- Output `\' or `\ ' before some inline element if necessary -->
3354 <xsl:template
3355 name="u:bkslshEscPre">
3356 <!-- Get the sibling node directly before the current element -->
3357 <xsl:variable
3358 name="before"
3359 select="preceding-sibling::node()[1]"/>
3360 <xsl:choose>
3361 <!-- No sibling before this node -->
3362 <xsl:when
3363 test="not($before)"/>
3364 <!-- Element directly before this - must be another inline element -->
3365 <xsl:when
3366 test="name($before)">
3367 <!-- So separate it by a quoted space -->
3368 <xsl:text>\ </xsl:text>
3369 </xsl:when>
3370 <!-- Node directly before this is text - check it -->
3371 <xsl:when
3372 test="not(contains(concat($apos, ' &#xA;&#x9;&#xD;&quot;([{&lt;-/:'), substring($before, string-length($before), 1)))">
3373 <!-- Does not end in one of the allowed characters so separate it -->
3374 <xsl:text>\ </xsl:text>
3375 </xsl:when>
3376 </xsl:choose>
3377 </xsl:template>
3379 <!-- Output `\' after some inline element if necessary -->
3380 <xsl:template
3381 name="u:bkslshEscSuf">
3382 <!-- Get the sibling node directly after the current element -->
3383 <xsl:variable
3384 name="after"
3385 select="following-sibling::node()[1]"/>
3386 <xsl:choose>
3387 <!-- No sibling after this node -->
3388 <xsl:when
3389 test="not($after)"/>
3390 <!-- Element directly after this - must be another inline element
3391 handling itself -->
3392 <xsl:when
3393 test="name($after)"/>
3394 <!-- Node directly after this is text - check it -->
3395 <xsl:when
3396 test="not(contains(concat($apos, ' &#xA;&#x9;&#xD;&quot;)]}&gt;-/:.,;!?\'), substring($after, 1, 1)))">
3397 <!-- Does not start with one of the allowed characters so separate
3398 it -->
3399 <xsl:text>\</xsl:text>
3400 </xsl:when>
3401 </xsl:choose>
3402 </xsl:template>
3404 <!-- ******************************************************************** -->
3406 <xsl:template
3407 name="u:notSupported">
3408 <xsl:call-template
3409 name="u:BandI"/>
3410 <xsl:text>######## NOT SUPPORTED: `</xsl:text>
3411 <xsl:value-of
3412 select="name(.)"/>
3413 <xsl:text>' ########</xsl:text>
3414 &tEOL;
3415 </xsl:template>
3417 <!-- ******************************************************************** -->
3419 <xsl:template
3420 name="u:overline">
3421 <!-- Length of the rendered(!) text -->
3422 <xsl:param
3423 name="length"/>
3424 <!-- Depth 1 and 2 are document title and subtitle while depths
3425 greater than 2 are normal section titles -->
3426 <xsl:param
3427 name="depth"/>
3428 <!-- Test whether a overline is wanted at all -->
3429 <xsl:if
3430 test="substring($adornment, 2 * ($depth - 1) + 1, 1) = 'o'">
3431 <xsl:value-of
3432 select="str:padding($length, substring($adornment, 2 * ($depth - 1) + 2, 1))"/>
3433 &tEOL;
3434 </xsl:if>
3435 </xsl:template>
3437 <xsl:template
3438 name="u:underline">
3439 <!-- Length of the rendered(!) text -->
3440 <xsl:param
3441 name="length"/>
3442 <!-- Depth 1 and 2 are document title and subtitle while depths
3443 greater than 2 are normal section titles -->
3444 <xsl:param
3445 name="depth"/>
3446 <xsl:value-of
3447 select="str:padding($length, substring($adornment, 2 * ($depth - 1) + 2, 1))"/>
3448 &tEOL;
3449 </xsl:template>
3451 <!-- ******************************************************************** -->
3453 <!-- Output a non-standalone reference or target -->
3454 <xsl:template
3455 name="u:inlineReference">
3456 <xsl:param
3457 name="anonymous"
3458 select="false()"/>
3459 <xsl:param
3460 name="embedded"
3461 select="false()"/>
3462 <!-- Is this a target instead of a reference? -->
3463 <xsl:param
3464 name="isTarget"
3465 select="false()"/>
3466 <xsl:param
3467 name="text"
3468 select="node()"/>
3469 <xsl:call-template
3470 name="u:bkslshEscPre"/>
3471 <!-- Delimiter only if link contains other than alphanumerics -->
3472 <xsl:variable
3473 name="delimiter">
3474 <xsl:if
3475 test="* or translate($text, '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', '') or $embedded">
3476 <xsl:text>`</xsl:text>
3477 </xsl:if>
3478 </xsl:variable>
3479 <xsl:if
3480 test="$isTarget">
3481 <xsl:text>_</xsl:text>
3482 </xsl:if>
3483 <xsl:value-of
3484 select="$delimiter"/>
3485 <xsl:apply-templates
3486 select="$text"/>
3487 <xsl:if
3488 test="$embedded">
3489 <xsl:text> &lt;</xsl:text>
3490 <xsl:value-of
3491 select="@refuri"/>
3492 <xsl:text>&gt;</xsl:text>
3493 </xsl:if>
3494 <xsl:value-of
3495 select="$delimiter"/>
3496 <xsl:if
3497 test="not($isTarget)">
3498 <xsl:text>_</xsl:text>
3499 <xsl:if
3500 test="$anonymous">
3501 <xsl:text>_</xsl:text>
3502 </xsl:if>
3503 </xsl:if>
3504 <xsl:call-template
3505 name="u:bkslshEscSuf"/>
3506 </xsl:template>
3508 <!-- ******************************************************************** -->
3510 <!-- Output a class directive for the directly following element. -->
3511 <!-- TODO A class directive can also be used as a container putting the
3512 respective attribute to its content; however, this is not
3513 reflected in XML - you'd need to check a sequence of elements
3514 whether they all have the same attribute; furthermore class
3515 settings for block quotes needs to be treated special -->
3516 <xsl:template
3517 name="u:outputClass">
3518 <!-- Blank line already output? -->
3519 <xsl:param
3520 name="alreadyBlanked"
3521 select="false()"/>
3522 <!-- Indentation already output? -->
3523 <xsl:param
3524 name="alreadyIndented"
3525 select="false()"/>
3526 <!-- Add a blank line after class directive? -->
3527 <xsl:param
3528 name="blankAfter"
3529 select="false()"/>
3530 <xsl:if
3531 test="@classes">
3532 <xsl:if
3533 test="not($alreadyBlanked)">
3534 <xsl:call-template
3535 name="u:blank"/>
3536 </xsl:if>
3537 <xsl:if
3538 test="not($alreadyIndented)">
3539 <xsl:call-template
3540 name="u:indent"/>
3541 </xsl:if>
3542 <xsl:text>.. class:: </xsl:text>
3543 <xsl:value-of
3544 select="@classes"/>
3545 &tEOL;
3546 <xsl:if
3547 test="$blankAfter">
3548 &tCR;
3549 </xsl:if>
3550 </xsl:if>
3551 </xsl:template>
3553 <!-- ******************************************************************** -->
3555 <!-- Output a names attribute at index considering quoted spaces. -->
3556 <xsl:template
3557 name="u:outputNames">
3558 <!-- Blank line already output? -->
3559 <xsl:param
3560 name="names"
3561 select="@names"/>
3562 <xsl:param
3563 name="index"
3564 select="0"/>
3565 <xsl:value-of
3566 select="str:replace(str:tokenize(normalize-space(str:replace($names, '\ ', '|')))[position() = $index + 1], '|', ' ')"/>
3567 </xsl:template>
3569 <!-- ******************************************************************** -->
3571 <!-- Output a names attribute for a refid. -->
3572 <xsl:template
3573 name="u:outputNamesRefid">
3574 <xsl:param
3575 name="refid"
3576 select="@refid"/>
3577 <!-- Determine the elements which is referred -->
3578 <xsl:variable
3579 name="refElem"
3580 select="//*[@ids and math:max(dyn:map(str:tokenize(normalize-space(@ids)), 'number($refid = .)')) > 0]"/>
3581 <xsl:call-template
3582 name="u:outputNames">
3583 <xsl:with-param
3584 name="names"
3585 select="$refElem/@names"/>
3586 <xsl:with-param
3587 name="index"
3588 select="math:max(dyn:map(str:tokenize(normalize-space($refElem/@ids)), 'number($refid = .) * position() - 1'))"/>
3589 </xsl:call-template>
3590 </xsl:template>
3592 <!-- ******************************************************************** -->
3593 <!-- ******************************************************************** -->
3595 <!-- Report unknown tags -->
3596 <xsl:template
3597 match="*">
3598 <xsl:message>
3599 <xsl:text>`</xsl:text>
3600 <xsl:value-of
3601 select="name(.)"/>
3602 <xsl:text>' encountered</xsl:text>
3603 <xsl:if
3604 test="parent::*">
3605 <xsl:text> in `</xsl:text>
3606 <xsl:value-of
3607 select="name(parent::*)"/>
3608 <xsl:text>'</xsl:text>
3609 </xsl:if>
3610 <xsl:text>, but no template matches.</xsl:text>
3611 </xsl:message>
3612 </xsl:template>
3614 </xsl:stylesheet>
3616 <!-- ********************************************************************** -->
3617 <!-- ********************************************************************** -->
3618 <!-- ********************************************************************** -->
3619 <!-- POD manual page
3621 =head1 NAME
3623 xml2rst.xsl - An XSLT script to convert Docutils XML to reStructuredText
3625 =head1 SYNOPSIS
3627 xsltproc docutils.xml xml2rst.xsl
3629 =head1 DESCRIPTION
3631 B<xml2rst.xsl> is an XSLT script to convert Docutils XML to
3632 reStructuredText. You can use your favorite XSLT processor supporting
3633 EXSLT (e.g. xsltproc from the Gnome project) to generate
3634 reStructuredText from the Docutils intermediate XML representation.
3635 Its main use is to generate reStructuredText from some other format
3636 where a converter to Docutils XML already exists.
3638 =head2 Options
3640 The following options are supported. They are XSLT parameters for the
3641 whole script and must be given to the XSLT processor by the respective
3642 option (xsltproc: B<--param> or B<--stringparam>).
3644 =over 4
3646 =item adornment
3648 Configures title markup to use so different styles can be requested
3649 easily.
3651 The value of the parameter must be a string made up of a sequence of
3652 character pairs. The first character of a pair is C<o> (overline) or
3653 C<u> (underline) and the second character is the character to use for
3654 the markup.
3656 The first and the second character pair is used for document title and
3657 subtitle, the following pairs are used for section titles where the
3658 third pair is used for the top level section title.
3660 Defaults to C<o=o-u=u-u~u:u.u`>.
3662 =item fold
3664 Configures whether long text lines in paragraphs should be folded and
3665 to which length. This option is for input not coming from reST which
3666 may have no internal line feeds in plain text strings.
3668 If folding is enabled text strings not in a line feed preserving
3669 context are first white-space normalized and then broken according to
3670 the folding rules. Folding rules put out the first word and continue
3671 to do so with the following words unless the next word would cross
3672 the folding boundary. Words are delimited by white-space.
3674 Defaults to C<0>, i.e. no folding.
3676 =back
3678 =head2 Unsupported features
3680 It is generally not possible to create an exact reproduction of an
3681 original reStructuredText source from an intermediate XML file. The
3682 reason is that Docutils transports pretty much but not all information
3683 of the original source into the XML. Also the sequence is changed
3684 sometimes.
3686 However, the coverage of Docutils features of B<xml2rst.xsl> is pretty
3687 good. A few minor features are not supported:
3689 =over 4
3691 =item * Fully minimized style for literal blocks
3693 =item * Substitution references for C<replace::> substitutions
3695 =item * Counting roman numbers in enumerated lists
3697 =item * Special table types like C<list-table::> and C<csv-table::>
3699 =item * Custom role definitions
3701 =back
3703 =head1 INSTALLATION
3705 Installation is not necessary. Just use the file as downloaded with
3706 your favorite XSLT processor supporting EXSLT. For instance you can
3707 use B<xsltproc> from the Gnome project.
3709 =head1 AUTHOR
3711 Stefan Merten <smerten@oekonux.de> based on works by David Priest.
3713 =head1 LICENSE
3715 This program is licensed under the terms of the GPL. See
3717 http://www.gnu.org/licenses/gpl.txt
3719 =head1 AVAILABILTY
3723 http://www.merten-home.de/FreeSoftware/xml2rst/
3725 =cut