Starting with this version new functionality is mainly implemented in
[docutils/kirr.git] / sandbox / xml2rst / rst / xml2rst-nopy.xsl
blob5bfe7f4bf5e931077baa801a912c59dcaa2c0d04
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, 2011 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:call-template
472 name="u:blank"/>
473 </xsl:template>
475 <!-- ******************************************************************** -->
477 <!--
478 Content Model: ((author, organization?, address?, contact?)+)
479 Attributes: The authors element contains only the common attributes: ids,
480 names, dupnames, source, and classes.
482 In reStructuredText, multiple author's names are separated with semicolons
483 (";") or commas (","); semicolons take precedence. There is currently no way
484 to represent the author's organization, address, or contact in a
485 reStructuredText "Authors" field.
487 <!-- == bibliographic_element == folding_element -->
488 <xsl:template
489 match="docinfo/authors">
490 <xsl:call-template
491 name="u:outputFolding">
492 <xsl:with-param
493 name="prefix">
494 <xsl:text>:</xsl:text>
495 <xsl:value-of
496 select="name()"/>
497 <xsl:text>: </xsl:text>
498 </xsl:with-param>
499 </xsl:call-template>
500 </xsl:template>
502 <!--
503 Content Model: %text.model;
504 Attributes: All docinfo elements contains the common attributes (ids,
505 names, dupnames, source, and classes)
506 Some docinfo elements also have xml:space.
508 <xsl:template
509 match="docinfo/authors/*">
510 <xsl:apply-templates/>
511 <!-- no semicolon after final author -->
512 <xsl:if
513 test="generate-id(current()) != generate-id(../*[last()])">
514 <xsl:text>; </xsl:text>
515 </xsl:if>
516 </xsl:template>
518 <!--
519 Content Model: (field_name, field_body)
520 Attributes: The field element contains only the common attributes: ids,
521 names, dupnames, source, and classes.
523 <!-- == bibliographic_element -->
524 <xsl:template
525 match="docinfo/field">
526 <!-- contents handled by ordinary field lists -->
527 <xsl:apply-templates/>
528 <!-- Supply an EOL because following elements do not recognize this -->
529 &tEOL;
530 </xsl:template>
532 <!--
533 Content Model: %text.model;
534 Attributes: All docinfo elements contains the common attributes (ids,
535 names, dupnames, source, and classes)
536 Some docinfo elements also have xml:space.
538 <!-- == bibliographic_element == folding_element -->
539 <xsl:template
540 match="docinfo/*[name()!='authors' and name()!='field']">
541 <xsl:call-template
542 name="u:outputFolding">
543 <xsl:with-param
544 name="prefix">
545 <xsl:text>:</xsl:text>
546 <xsl:value-of
547 select="name()"/>
548 <xsl:text>: </xsl:text>
549 </xsl:with-param>
550 </xsl:call-template>
551 </xsl:template>
553 <!-- ******************************************************************** -->
555 <!--
556 Content Model: EMPTY
557 Attributes: The transition element contains only the common attributes:
558 ids, names, dupnames, source, and classes.
560 <!-- == structural_subelement -->
561 <xsl:template
562 match="transition">
563 <xsl:call-template
564 name="u:outputClass"/>
565 &tCR; <!-- req: blank line before -->
566 <xsl:text>-----</xsl:text>
567 &tEOL;
568 <!-- Add a required blank line after unless class follows immediately -->
569 <xsl:if
570 test="not(following-sibling::*[1]/@classes)">
571 &tCR;
572 </xsl:if>
573 </xsl:template>
575 <!-- ******************************************************************** -->
576 <!-- ******************************************************************** -->
578 <!--
579 IFF there is a /document/title element, it is the publication's title. All
580 other titles will appear within sections.
582 Content Model: %text.model;
583 Attributes: The title element contains the common attributes (ids, names,
584 dupnames, source, and classes), plus refid and auto.
585 refid is used as a backlink to a table of contents entry.
586 auto is used to indicate (with value "1") that the title has been
587 numbered automatically.
589 <!-- == structural_subelement -->
590 <xsl:template
591 match="//document/title">
592 <xsl:call-template
593 name="u:outputClass"/>
594 <xsl:variable
595 name="textWS">
596 <!-- Catch the title text as it is rendered so its length can be
597 determined -->
598 <xsl:apply-templates/>
599 </xsl:variable>
600 <xsl:variable
601 name="text"
602 select="normalize-space($textWS)"/>
603 <xsl:variable
604 name="length"
605 select="string-length($text)"/>
606 <xsl:call-template
607 name="u:overline">
608 <xsl:with-param
609 name="length"
610 select="$length"/>
611 <xsl:with-param
612 name="depth"
613 select="1"/>
614 </xsl:call-template>
615 <xsl:value-of
616 select="$text"/>
617 &tEOL;
618 <xsl:call-template
619 name="u:underline">
620 <xsl:with-param
621 name="length"
622 select="$length"/>
623 <xsl:with-param
624 name="depth"
625 select="1"/>
626 </xsl:call-template>
627 </xsl:template>
629 <!-- ******************************************************************** -->
631 <!--
632 Title Underlines are defined by their position within the tree.
634 Content Model: %text.model;
635 Attributes: The title element contains the common attributes (ids, names,
636 dupnames, source, and classes), plus refid and auto.
637 refid is used as a backlink to a table of contents entry.
638 auto is used to indicate (with value "1") that the title has been
639 numbered automatically.
641 <!-- == structural_subelement -->
642 <xsl:template
643 match="section/title">
644 <xsl:call-template
645 name="u:outputClass"/>
646 <xsl:variable
647 name="textWS">
648 <!-- catch the title text as it is rendered -->
649 <xsl:apply-templates/>
650 </xsl:variable>
651 <xsl:variable
652 name="text"
653 select="normalize-space($textWS)"/>
654 <xsl:variable
655 name="length"
656 select="string-length($text)"/>
657 <xsl:variable
658 name="depth"
659 select="count(ancestor::section)"/>
660 <xsl:call-template
661 name="u:overline">
662 <xsl:with-param
663 name="length"
664 select="$length"/>
665 <xsl:with-param
666 name="depth"
667 select="$depth + 2"/>
668 </xsl:call-template>
669 <xsl:value-of
670 select="$text"/>
671 &tEOL;
672 <xsl:call-template
673 name="u:underline">
674 <xsl:with-param
675 name="length"
676 select="$length"/>
677 <xsl:with-param
678 name="depth"
679 select="$depth + 2"/>
680 </xsl:call-template>
681 <!-- Add a blank line after unless structure follows immediately -->
682 <xsl:if
683 test="not(contains(concat($structural_elements, $compound_body_elements), concat('*', name(following-sibling::*[1]), '*')) or following-sibling::*[1]/@classes)">
684 &tCR;
685 </xsl:if>
686 </xsl:template>
688 <!-- ******************************************************************** -->
690 <!--
691 Content Model: %text.model;
692 Attributes: The title element contains the common attributes (ids, names,
693 dupnames, source, and classes), plus refid and auto.
694 refid is used as a backlink to a table of contents entry.
695 auto is used to indicate (with value "1") that the title has been
696 numbered automatically.
698 <!-- == structural_subelement -->
699 <xsl:template
700 match="title">
701 <xsl:call-template
702 name="u:outputClass">
703 <xsl:with-param
704 name="alreadyBlanked"
705 select="true()"/>
706 </xsl:call-template>
707 <!-- blank line provided by parent -->
708 <xsl:apply-templates/>
709 <!-- no EOL: provided by parent -->
710 </xsl:template>
712 <!-- ******************************************************************** -->
714 <!--
715 IFF there is a /document/title element, it is the publication's title. All
716 other titles will appear within sections.
718 Content Model: %text.model;
719 Attributes: The subtitle element contains only the common attributes:
720 ids, names, dupnames, source, and classes.
722 <!-- == structural_subelement -->
723 <xsl:template
724 match="//document/subtitle">
725 <xsl:call-template
726 name="u:outputClass"/>
727 <xsl:variable
728 name="textWS">
729 <!-- Catch the title text as it is rendered -->
730 <xsl:apply-templates/>
731 </xsl:variable>
732 <xsl:variable
733 name="text"
734 select="normalize-space($textWS)"/>
735 <xsl:variable
736 name="length"
737 select="string-length($text)"/>
739 <!-- always a blank line above -->
740 &tCR;
741 <xsl:call-template
742 name="u:overline">
743 <xsl:with-param
744 name="length"
745 select="$length"/>
746 <xsl:with-param
747 name="depth"
748 select="2"/>
749 </xsl:call-template>
750 <xsl:value-of
751 select="$text"/>
752 &tEOL;
753 <xsl:call-template
754 name="u:underline">
755 <xsl:with-param
756 name="length"
757 select="$length"/>
758 <xsl:with-param
759 name="depth"
760 select="2"/>
761 </xsl:call-template>
762 </xsl:template>
764 <!-- ******************************************************************** -->
766 <!--
767 Content Model: %text.model;
768 Attributes: The subtitle element contains only the common attributes: ids,
769 names, dupnames, source, and classes.
771 <!-- == structural_subelement -->
772 <xsl:template
773 match="sidebar/subtitle">
774 <xsl:call-template
775 name="u:outputClass"/>
776 <xsl:call-template
777 name="u:indent"/>
778 <xsl:apply-templates/>
779 &tEOL;
780 &tCR;
781 </xsl:template>
783 <!-- ******************************************************************** -->
784 <!-- ******************************************************************** -->
786 <!--
787 Content Model: %text.model;
788 Attributes: The comment element contains only the common attributes: ids,
789 names, dupnames, source, and classes.
791 <!-- == simple_body_element == folding_element == directive -->
792 <xsl:template
793 match="comment">
794 <xsl:call-template
795 name="u:BandI"/>
796 <xsl:call-template
797 name="u:outputFolding">
798 <xsl:with-param
799 name="prefix">
800 <xsl:text>.. </xsl:text>
801 </xsl:with-param>
802 </xsl:call-template>
803 </xsl:template>
805 <!-- ******************************************************************** -->
807 <!--
808 Content Model: %text.model;
809 Attributes: The doctest_block element contains the common attributes (ids,
810 names, dupnames, source, and classes), plus xml:space.
812 <!-- == simple_body_element -->
813 <xsl:template
814 match="doctest_block">
815 <xsl:call-template
816 name="u:outputClass"/>
817 <xsl:call-template
818 name="u:BandI"/>
819 <xsl:apply-templates/>
820 &tEOL;
821 </xsl:template>
823 <!-- ******************************************************************** -->
825 <!-- An image element can have various roles; they are all covered here -->
826 <!-- == simple_body_element == inline_element == directive -->
827 <xsl:template
828 match="image">
829 <xsl:choose>
830 <xsl:when
831 test="contains($inline_containers, concat('*', name(..), '*')) and @alt">
832 <!-- An inline image with an `@alt' - must be a substitution
833 reference -->
834 <xsl:text>|</xsl:text>
835 <!-- Original text is lost - use what we have -->
836 <xsl:value-of
837 select="@alt"/>
838 <xsl:text>|</xsl:text>
839 </xsl:when>
840 <xsl:otherwise>
841 <!-- A directive -->
842 <xsl:if
843 test="not(parent::figure)">
844 <xsl:if
845 test="not(parent::substitution_definition)">
846 <xsl:call-template
847 name="u:BandI"/>
848 <xsl:text>.. </xsl:text>
849 </xsl:if>
850 <xsl:text>image:: </xsl:text>
851 </xsl:if>
852 <xsl:value-of
853 select="@uri"/>
854 &tEOL;
855 <xsl:choose>
856 <xsl:when
857 test="parent::figure">
858 <!-- `@classes' is special because it is in the parent -->
859 <xsl:if
860 test="../@classes">
861 <xsl:call-template
862 name="u:param">
863 <xsl:with-param
864 name="name"
865 select="'figclass'"/>
866 <xsl:with-param
867 name="value"
868 select="../@classes"/>
869 <xsl:with-param
870 name="ancestors"
871 select="ancestor::*"/>
872 </xsl:call-template>
873 </xsl:if>
874 <!-- `@align' is special because it is in the parent -->
875 <xsl:if
876 test="../@align">
877 <xsl:call-template
878 name="u:param">
879 <xsl:with-param
880 name="name"
881 select="'align'"/>
882 <xsl:with-param
883 name="value"
884 select="../@align"/>
885 <xsl:with-param
886 name="ancestors"
887 select="ancestor::*"/>
888 </xsl:call-template>
889 </xsl:if>
890 <xsl:call-template
891 name="u:params">
892 <!-- `figure' would add one level of indentation -->
893 <xsl:with-param
894 name="ancestors"
895 select="ancestor::*"/>
896 </xsl:call-template>
897 </xsl:when>
898 <xsl:when
899 test="parent::substitution_definition">
900 <xsl:call-template
901 name="u:params">
902 <!-- `@alt' only for the real images -->
903 <xsl:with-param
904 name="params"
905 select="@*[name() != 'alt']"/>
906 </xsl:call-template>
907 </xsl:when>
908 <xsl:otherwise>
909 <xsl:call-template
910 name="u:params">
911 <xsl:with-param
912 name="params"
913 select="@*[name() != 'ids' and name() != 'names']"/>
914 </xsl:call-template>
915 </xsl:otherwise>
916 </xsl:choose>
917 <xsl:if
918 test="parent::reference">
919 <!-- A clickable image -->
920 <xsl:call-template
921 name="u:param">
922 <xsl:with-param
923 name="name"
924 select="'target'"/>
925 <xsl:with-param
926 name="value">
927 <xsl:choose>
928 <xsl:when
929 test="../@name">
930 <!-- An internal link -->
931 <xsl:call-template
932 name="u:inlineReference">
933 <xsl:with-param
934 name="text"
935 select="../@refid"/>
936 </xsl:call-template>
937 </xsl:when>
938 <xsl:otherwise>
939 <!-- An external link -->
940 <xsl:value-of
941 select="../@refuri"/>
942 </xsl:otherwise>
943 </xsl:choose>
944 </xsl:with-param>
945 <xsl:with-param
946 name="ancestors"
947 select="ancestor-or-self::*"/>
948 </xsl:call-template>
949 </xsl:if>
950 <!-- Always blank line after parameter block -->
951 &tCR;
952 </xsl:otherwise>
953 </xsl:choose>
954 </xsl:template>
956 <!-- ******************************************************************** -->
958 <!--
959 Content Model: (line_block | line)+
960 Attributes: The line_block element contains the common attributes (ids,
961 names, dupnames, source, and classes), plus xml:space.
963 <!-- == compound_body_element -->
964 <xsl:template
965 match="line_block">
966 <xsl:call-template
967 name="u:outputClass"/>
968 <xsl:variable
969 name="isEmbedded"
970 select="name(..) = 'line_block'"/>
971 <xsl:if
972 test="not($isEmbedded)">
973 <xsl:call-template
974 name="u:blank"/>
975 </xsl:if>
976 <xsl:apply-templates/>
977 </xsl:template>
979 <!-- ******************************************************************** -->
981 <!--
982 Content Model: %text.model;
983 Attributes: The line element contains the common attributes (ids,
984 names, dupnames, source, and classes).
986 <!-- == simple_body_subelement == folding_element -->
987 <xsl:template
988 match="line">
989 <xsl:call-template
990 name="u:outputClass"/>
991 <xsl:variable
992 name="indent">
993 <xsl:call-template
994 name="u:indent"/>
995 </xsl:variable>
996 <xsl:value-of
997 select="$indent"/>
998 <xsl:choose>
999 <xsl:when
1000 test="node()">
1001 <!-- Only for non-empty lines -->
1002 <xsl:variable
1003 name="lineBlockIndent">
1004 <!-- Very special indendation for nested `line_block's -->
1005 <xsl:for-each
1006 select="ancestor::line_block[position() > 1]">
1007 <xsl:value-of
1008 select="str:padding(4)"/>
1009 </xsl:for-each>
1010 </xsl:variable>
1011 <xsl:call-template
1012 name="u:outputFolding">
1013 <xsl:with-param
1014 name="prefix">
1015 <xsl:text>| </xsl:text>
1016 <xsl:value-of
1017 select="$lineBlockIndent"/>
1018 </xsl:with-param>
1019 <xsl:with-param
1020 name="indent"
1021 select="concat($indent, ' ', $lineBlockIndent)"/>
1022 </xsl:call-template>
1023 </xsl:when>
1024 <xsl:otherwise>
1025 <xsl:text>|</xsl:text>
1026 &tEOL;
1027 </xsl:otherwise>
1028 </xsl:choose>
1029 </xsl:template>
1031 <!-- ******************************************************************** -->
1033 <!--
1034 Content Model: %text.model;
1035 Attributes: The literal_block element contains the common attributes (ids,
1036 names, dupnames, source, and classes), plus xml:space.
1038 <!-- == simple_body_element == directive -->
1039 <xsl:template
1040 match="literal_block">
1041 <xsl:choose>
1042 <xsl:when
1043 test=".//*[contains($inline_elements, concat('*', name(), '*'))]">
1044 <!-- If it contains inline elements this is a parsed-literal -->
1045 <xsl:call-template
1046 name="u:BandI"/>
1047 <xsl:text>.. parsed-literal::</xsl:text>
1048 &tEOL;
1049 <xsl:call-template
1050 name="u:params"/>
1051 &tCR;
1052 </xsl:when>
1053 <xsl:otherwise>
1054 <xsl:call-template
1055 name="u:outputClass"/>
1056 <!-- TODO Support for the (fully) minimized style would be nice but
1057 is difficult to accomplish because there is a linefeed
1058 already when we arrive here :-( -->
1059 <xsl:call-template
1060 name="u:BandI"/>
1061 <xsl:text>::</xsl:text>
1062 &tEOL;
1063 &tCR;
1064 </xsl:otherwise>
1065 </xsl:choose>
1066 <xsl:variable
1067 name="isQuotedLiteral">
1068 <xsl:call-template
1069 name="u:isQuotedLiteral"/>
1070 </xsl:variable>
1071 <!-- Indent correctly depending on quoted literal or not -->
1072 <xsl:choose>
1073 <xsl:when
1074 test="string-length($isQuotedLiteral)">
1075 <xsl:call-template
1076 name="u:indent">
1077 <xsl:with-param
1078 name="ancestors"
1079 select="ancestor::*"/>
1080 </xsl:call-template>
1081 <xsl:apply-templates
1082 mode="quotedLiteral"/>
1083 </xsl:when>
1084 <xsl:otherwise>
1085 <xsl:call-template
1086 name="u:indent">
1087 <xsl:with-param
1088 name="ancestors"
1089 select="ancestor-or-self::*"/>
1090 </xsl:call-template>
1091 <xsl:apply-templates/>
1092 </xsl:otherwise>
1093 </xsl:choose>
1094 &tEOL;
1095 </xsl:template>
1097 <!-- Indent a text of a quoted literal containing line feeds correctly -->
1098 <xsl:template
1099 match="text()"
1100 mode="quotedLiteral">
1101 <xsl:call-template
1102 name="u:indentLF">
1103 <xsl:with-param
1104 name="indent">
1105 <xsl:call-template
1106 name="u:indent">
1107 <xsl:with-param
1108 name="ancestors"
1109 select="ancestor::*[position() > 1]"/>
1110 </xsl:call-template>
1111 </xsl:with-param>
1112 </xsl:call-template>
1113 </xsl:template>
1115 <!-- Determine whether `$text' is a quoted literal and return the quote
1116 character if so -->
1117 <xsl:template
1118 name="u:isQuotedLiteral">
1119 <xsl:param
1120 name="text"
1121 select="text()"/>
1122 <xsl:param
1123 name="quote"
1124 select="substring($text, 1, 1)"/>
1125 <xsl:if
1126 test="contains($adornment_characters, $quote) and substring($text, 1, 1) = $quote">
1127 <!-- Given quote is an adornment character and first character is this
1128 quote -->
1129 <xsl:choose>
1130 <xsl:when
1131 test="contains($text, '&#xA;')">
1132 <!-- Test the remaining lines -->
1133 <xsl:call-template
1134 name="u:isQuotedLiteral">
1135 <xsl:with-param
1136 name="text"
1137 select="substring-after($text, '&#xA;')"/>
1138 <xsl:with-param
1139 name="quote"
1140 select="$quote"/>
1141 </xsl:call-template>
1142 </xsl:when>
1143 <xsl:otherwise>
1144 <!-- No more lines to test so this is a quoted literal -->
1145 <xsl:value-of
1146 select="$quote"/>
1147 </xsl:otherwise>
1148 </xsl:choose>
1149 </xsl:if>
1150 </xsl:template>
1152 <!-- ******************************************************************** -->
1154 <!--
1155 Content Model: %text.model;
1156 Attributes: The paragraph element contains only the common attributes:
1157 ids, names, dupnames, source, and classes.
1159 <!-- == simple_body_element == folding_element -->
1160 <xsl:template
1161 match="paragraph">
1162 <xsl:variable
1163 name="previous"
1164 select="preceding-sibling::*[1]"/>
1165 <!-- Do indent except first element in some compound elements -->
1166 <xsl:variable
1167 name="needsIndent"
1168 select="($previous or not(parent::list_item or parent::field_body or contains($admonitions, concat('*', name(..), '*')))) and name($previous) != 'label'"/>
1169 <!-- Blank line in front if following a body element, except first
1170 elements in some compound elements -->
1171 <xsl:variable
1172 name="needsBlank"
1173 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')"/>
1174 <xsl:if
1175 test="$needsBlank">
1176 &tCR;
1177 </xsl:if>
1178 <xsl:if
1179 test="$needsIndent">
1180 <xsl:call-template
1181 name="u:indent"/>
1182 </xsl:if>
1183 <xsl:if
1184 test="@classes">
1185 <!-- This paragraph has a classes attribute - always needs newline and
1186 indent -->
1187 <xsl:call-template
1188 name="u:outputClass">
1189 <xsl:with-param
1190 name="alreadyBlanked"
1191 select="$needsBlank"/>
1192 <xsl:with-param
1193 name="alreadyIndented"
1194 select="$needsIndent"/>
1195 </xsl:call-template>
1196 <xsl:call-template
1197 name="u:BandI"/>
1198 </xsl:if>
1199 <xsl:call-template
1200 name="u:outputFolding"/>
1201 </xsl:template>
1203 <!-- ******************************************************************** -->
1205 <!-- == simple_body_element -->
1206 <xsl:template
1207 match="pending">
1208 <xsl:call-template
1209 name="u:notSupported"/>
1210 </xsl:template>
1212 <!-- ******************************************************************** -->
1214 <!-- == simple_body_element == inline_element == directive -->
1215 <xsl:template
1216 match="raw">
1217 <xsl:choose>
1218 <xsl:when
1219 test="contains($inline_containers, concat('*', name(..), '*'))">
1220 <!-- Used as a custom role -->
1221 <!-- TODO `role' directives must be generated for user-defined raw
1222 roles. -->
1223 <!-- The name of the custom role is not contained in the input -->
1224 <xsl:text>:RAW-ROLE:`</xsl:text>
1225 <xsl:apply-templates/>
1226 <xsl:text>`</xsl:text>
1227 </xsl:when>
1228 <xsl:otherwise>
1229 <!-- A directive -->
1230 <xsl:call-template
1231 name="u:outputClass"/>
1232 <xsl:call-template
1233 name="u:BandI"/>
1234 <xsl:text>.. raw:: </xsl:text>
1235 <xsl:value-of
1236 select="@format"/>
1237 &tEOL;
1238 <xsl:call-template
1239 name="u:params">
1240 <xsl:with-param
1241 name="params"
1242 select="@*[name() != 'format' and name() != 'classes']"/>
1243 </xsl:call-template>
1244 &tCR;
1245 <xsl:call-template
1246 name="u:indent">
1247 <xsl:with-param
1248 name="ancestors"
1249 select="ancestor-or-self::*"/>
1250 </xsl:call-template>
1251 <xsl:apply-templates/>
1252 &tEOL;
1253 </xsl:otherwise>
1254 </xsl:choose>
1255 </xsl:template>
1257 <!-- ******************************************************************** -->
1259 <!-- == simple_body_element == folding_element == directive -->
1260 <xsl:template
1261 match="rubric">
1262 <xsl:call-template
1263 name="u:BandI"/>
1264 <xsl:call-template
1265 name="u:outputFolding">
1266 <xsl:with-param
1267 name="prefix">
1268 <xsl:text>.. rubric:: </xsl:text>
1269 </xsl:with-param>
1270 </xsl:call-template>
1271 <xsl:call-template
1272 name="u:params"/>
1273 </xsl:template>
1275 <!-- ******************************************************************** -->
1277 <!-- == compound_body_element == directive -->
1278 <xsl:template
1279 match="compound">
1280 <xsl:call-template
1281 name="u:BandI"/>
1282 <xsl:text>.. compound::</xsl:text>
1283 &tEOL;
1284 <xsl:call-template
1285 name="u:params"/>
1286 <xsl:apply-templates/>
1287 </xsl:template>
1289 <!-- ******************************************************************** -->
1291 <!-- == compound_body_element == directive -->
1292 <xsl:template
1293 match="container">
1294 <xsl:call-template
1295 name="u:BandI"/>
1296 <xsl:text>.. container::</xsl:text>
1297 <xsl:if
1298 test="@classes">
1299 &tSP;
1300 <xsl:value-of
1301 select="@classes"/>
1302 </xsl:if>
1303 &tEOL;
1304 <xsl:apply-templates/>
1305 </xsl:template>
1307 <!-- ******************************************************************** -->
1309 <!-- == simple_body_element == directive -->
1310 <xsl:template
1311 match="substitution_definition">
1312 <!-- More than one child or not a directive is a replacement text -->
1313 <xsl:variable
1314 name="isReplace"
1315 select="not(* and count(node()) = 1 and contains($directives, concat('*', name(*[1]), '*')))"/>
1316 <xsl:call-template
1317 name="u:BandI"/>
1318 <xsl:variable
1319 name="prefix">
1320 <xsl:text>.. |</xsl:text>
1321 <xsl:call-template
1322 name="u:outputNames"/>
1323 <xsl:text>| </xsl:text>
1324 </xsl:variable>
1325 <xsl:choose>
1326 <xsl:when
1327 test="$isReplace">
1328 <!-- TODO Substitution references for replace can not be found because
1329 they are not marked as such; embedding them in `generated'
1330 would be nice -->
1331 <xsl:call-template
1332 name="u:outputFolding">
1333 <xsl:with-param
1334 name="prefix">
1335 <xsl:value-of
1336 select="$prefix"/>
1337 <xsl:text>replace:: </xsl:text>
1338 </xsl:with-param>
1339 </xsl:call-template>
1340 </xsl:when>
1341 <xsl:otherwise>
1342 <xsl:value-of
1343 select="$prefix"/>
1344 <xsl:apply-templates/>
1345 </xsl:otherwise>
1346 </xsl:choose>
1347 </xsl:template>
1349 <!-- ******************************************************************** -->
1351 <!--
1352 Content Model: ((%body.elements;)+, attribution?)
1353 Attributes: The block_quote element contains only the common attributes:
1354 ids, names, dupnames, source, and classes.
1356 <!-- == compound_body_element -->
1357 <xsl:template
1358 match="block_quote">
1359 <xsl:if
1360 test="@classes = 'epigraph' or @classes = 'highlights' or @classes = 'pull-quote'">
1361 <xsl:call-template
1362 name="u:BandI"/>
1363 <xsl:text>.. </xsl:text>
1364 <xsl:value-of
1365 select="@classes"/>
1366 <xsl:text>::</xsl:text>
1367 &tEOL;
1368 <xsl:call-template
1369 name="u:params"/>
1370 </xsl:if>
1371 <xsl:apply-templates/>
1372 </xsl:template>
1374 <!-- ******************************************************************** -->
1376 <!-- == simple_body_subelement == folding_element -->
1377 <xsl:template
1378 match="attribution">
1379 <xsl:call-template
1380 name="u:outputClass"/>
1381 <!-- blank line between quote and attribution -->
1382 &tCR;
1383 <xsl:call-template
1384 name="u:indent"/>
1385 <xsl:call-template
1386 name="u:outputFolding">
1387 <xsl:with-param
1388 name="prefix">
1389 <xsl:text>-- </xsl:text>
1390 </xsl:with-param>
1391 </xsl:call-template>
1392 </xsl:template>
1394 <!-- ******************************************************************** -->
1396 <!-- == compound_body_element == directive -->
1397 <xsl:template
1398 match="citation">
1399 <xsl:call-template
1400 name="u:outputClass"/>
1401 <xsl:call-template
1402 name="u:BandI"/>
1403 <xsl:text>.. [</xsl:text>
1404 <xsl:value-of
1405 select="label"/>
1406 <xsl:text>] </xsl:text>
1407 <xsl:apply-templates
1408 select="*[not(self::label)]"/>
1409 </xsl:template>
1411 <!-- == simple_body_subelement -->
1412 <xsl:template
1413 match="citation/label">
1414 <xsl:apply-templates/>
1415 </xsl:template>
1417 <!-- ******************************************************************** -->
1419 <!-- == compound_body_element == directive -->
1420 <xsl:template
1421 match="figure">
1422 <xsl:call-template
1423 name="u:BandI"/>
1424 <xsl:text>.. figure:: </xsl:text>
1425 <xsl:apply-templates/>
1426 </xsl:template>
1428 <!-- ******************************************************************** -->
1430 <!-- == simple_body_subelement == folding_element -->
1431 <xsl:template
1432 match="caption">
1433 <xsl:call-template
1434 name="u:indent"/>
1435 <xsl:call-template
1436 name="u:outputFolding"/>
1437 </xsl:template>
1439 <!-- ******************************************************************** -->
1441 <!-- == compound_body_subelement -->
1442 <xsl:template
1443 match="legend">
1444 <xsl:apply-templates/>
1445 </xsl:template>
1447 <!-- ******************************************************************** -->
1449 <!-- TODO Footnotes should continue on line of definition -->
1451 <!-- user-numbered footnotes lack @auto -->
1452 <!-- == compound_body_element == directive -->
1453 <xsl:template
1454 match="footnote[not(@auto)]">
1455 <xsl:call-template
1456 name="u:outputClass"/>
1457 <xsl:call-template
1458 name="u:BandI"/>
1459 <xsl:text>.. [</xsl:text>
1460 <xsl:apply-templates
1461 select="label"/>
1462 <xsl:text>] </xsl:text>
1463 <xsl:apply-templates
1464 select="*[not(self::label)]"/>
1465 </xsl:template>
1467 <!-- autonumbered footnotes have @auto -->
1468 <!-- if the target footnote_reference@names matches its label, it was not a
1469 numbered-name footnote -->
1470 <!-- == compound_body_element == directive -->
1471 <xsl:template
1472 match="footnote[@auto='1']">
1473 <xsl:call-template
1474 name="u:outputClass"/>
1475 <xsl:call-template
1476 name="u:BandI"/>
1477 <xsl:text>.. [#</xsl:text>
1478 <xsl:if
1479 test="@names = @ids">
1480 <xsl:call-template
1481 name="u:outputNames"/>
1482 </xsl:if>
1483 <xsl:text>] </xsl:text>
1484 <xsl:apply-templates
1485 select="*[not(self::label)]"/>
1486 </xsl:template>
1488 <!-- autosymboled footnotes have @auto -->
1489 <!-- == compound_body_element == directive -->
1490 <xsl:template
1491 match="footnote[@auto='*']">
1492 <xsl:call-template
1493 name="u:outputClass"/>
1494 <xsl:call-template
1495 name="u:BandI"/>
1496 <xsl:text>.. [*] </xsl:text>
1497 <xsl:apply-templates
1498 select="*[not(self::label)]"/>
1499 </xsl:template>
1501 <!-- == compound_body_element == directive -->
1502 <xsl:template
1503 match="footnote[starts-with(@names, 'TARGET_NOTE:\ ')]">
1504 <!-- This is not a footnote but a hint for a directive -->
1505 <xsl:if
1506 test="generate-id(//footnote[starts-with(@names, 'TARGET_NOTE:\ ')][1]) = generate-id(.)">
1507 <!-- Only for the first one -->
1508 <xsl:call-template
1509 name="u:BandI"/>
1510 <!-- TODO May have a `classes` attribute -->
1511 <xsl:text>.. target-notes::</xsl:text>
1512 &tEOL;
1513 </xsl:if>
1514 </xsl:template>
1516 <!-- == simple_body_subelement -->
1517 <xsl:template
1518 match="footnote/label">
1519 <xsl:apply-templates/>
1520 </xsl:template>
1522 <!-- ******************************************************************** -->
1524 <!--
1525 Content Model: (list_item +)
1526 Attributes: The bullet_list element contains the common attributes (ids,
1527 names, dupnames, source, and classes), plus bullet.
1528 bullet is used to record the style of bullet from the input data.
1529 In documents processed from reStructuredText, it contains one of "-",
1530 "+", or "*". It may be ignored in processing.
1532 <!-- == compound_body_element -->
1533 <xsl:template
1534 match="bullet_list">
1535 <xsl:call-template
1536 name="u:outputClass"/>
1537 <xsl:apply-templates
1538 mode="bullet_list"/>
1539 </xsl:template>
1541 <!-- ******************************************************************** -->
1543 <!--
1544 Content Model: (definition_list_item +)
1545 Attributes: The definition_list element contains only the common
1546 attributes: ids, names, dupnames, source, and classes.
1548 <!-- == compound_body_element -->
1549 <xsl:template
1550 match="definition_list">
1551 <xsl:call-template
1552 name="u:outputClass"/>
1553 <xsl:apply-templates/>
1554 </xsl:template>
1556 <!-- ******************************************************************** -->
1558 <!--
1559 Content Model: (term, classifier?, definition)
1560 Attributes: The definition_list_item element contains only the common
1561 attributes: ids, names, dupnames, source, and classes.
1563 <!-- == compound_body_subelement -->
1564 <xsl:template
1565 match="definition_list_item">
1566 <xsl:call-template
1567 name="u:outputClass"/>
1568 <xsl:call-template
1569 name="u:BandI"/>
1570 <xsl:apply-templates/>
1571 </xsl:template>
1573 <!-- ******************************************************************** -->
1575 <!--
1576 Content Model: %text.model;
1577 Attributes: The term element contains only the common attributes: ids,
1578 names, dupnames, source, and classes.
1580 <!-- == simple_body_subelement -->
1581 <xsl:template
1582 match="term">
1583 <xsl:apply-templates/>
1584 </xsl:template>
1586 <!-- ******************************************************************** -->
1588 <!--
1589 Content Model: %text.model;
1590 Attributes: The classifier element contains only the common attributes:
1591 ids, names, dupnames, source, and classes.
1593 <!-- == simple_body_subelement -->
1594 <xsl:template
1595 match="classifier">
1596 <xsl:text> : </xsl:text>
1597 <xsl:apply-templates/>
1598 </xsl:template>
1600 <!-- ******************************************************************** -->
1602 <!--
1603 Content Model: (%body.elements;)+
1604 Attributes: The definition element contains only the common attributes:
1605 ids, names, dupnames, source, and classes.
1607 <!-- == compound_body_subelement -->
1608 <xsl:template
1609 match="definition">
1610 <xsl:call-template
1611 name="u:outputClass"/>
1612 <xsl:apply-templates/>
1613 </xsl:template>
1615 <!-- ******************************************************************** -->
1617 <!--
1618 Content Model: (list_item +)
1619 Attributes: The enumerated_list element contains the common attributes
1620 (ids, names, dupnames, source, and classes), plus enumtype, prefix, suffix, and
1621 start.
1622 enumtype is used to record the intended enumeration sequence, one
1623 of "arabic" (1, 2, 3, ...), "loweralpha" (a, b, c, ..., z), "upperalpha" (A,
1624 B, C, ..., Z), "lowerroman" (i, ii, iii, iv, ..., mmmmcmxcix [4999]), or
1625 "upperroman" (I, II, III, IV, ..., MMMMCMXCIX [4999]).
1626 prefix stores the formatting characters used before the enumerator. In
1627 documents originating from reStructuredText data, it will contain either ""
1628 (empty string) or "(" (left parenthesis). It may or may not affect
1629 processing.
1630 suffix stores the formatting characters used after the enumerator. In
1631 documents originating from reStructuredText data, it will contain either "."
1632 (period) or ")" (right parenthesis). Depending on the capabilities of the
1633 output format, this attribute may or may not affect processing.
1634 start contains the ordinal value of the first item in the list, in
1635 decimal. For lists beginning at value 1 ("1", "a", "A", "i", or "I"), this
1636 attribute may be omitted.
1638 <!-- == compound_body_element -->
1639 <xsl:template
1640 match="enumerated_list">
1641 <xsl:call-template
1642 name="u:outputClass"/>
1643 <xsl:apply-templates
1644 mode="enumerated_list"/>
1645 </xsl:template>
1647 <!-- ******************************************************************** -->
1649 <!--
1650 Content Model: (field +)
1651 Attributes: The field_list element contains only the common attributes:
1652 ids, names, dupnames, source, and classes.
1654 <!-- == compound_body_element -->
1655 <xsl:template
1656 match="field_list">
1657 <xsl:call-template
1658 name="u:outputClass"/>
1659 <xsl:apply-templates/>
1660 </xsl:template>
1662 <!-- ******************************************************************** -->
1664 <!--
1665 Content Model: (field_name, field_body)
1666 Attributes: The field element contains only the common attributes: ids,
1667 names, dupnames, source, and classes.
1669 <!-- == compound_body_subelement -->
1670 <xsl:template
1671 match="field">
1672 <xsl:call-template
1673 name="u:outputClass"/>
1674 <xsl:call-template
1675 name="u:BandI"/>
1676 <xsl:apply-templates/>
1677 </xsl:template>
1679 <!-- ********************************************************************** -->
1681 <!--
1682 Content Model: %text.model;
1683 Attributes: The field_name element contains only the common attributes:
1684 ids, names, dupnames, source, and classes.
1686 <!-- == simple_body_subelement -->
1687 <xsl:template
1688 match="field_name">
1689 <xsl:text>:</xsl:text>
1690 <xsl:apply-templates/>
1691 <xsl:text>: </xsl:text>
1692 <!-- no EOL: field_body starts on same line -->
1693 </xsl:template>
1695 <!-- ******************************************************************** -->
1697 <!--
1698 Content Model: (%body.elements;)*
1699 Attributes: The field_body element contains only the common attributes:
1700 ids, names, dupnames, source, and classes.
1702 <!-- == compound_body_subelement -->
1703 <xsl:template
1704 match="field_body">
1705 <xsl:call-template
1706 name="u:outputClass"/>
1707 <xsl:apply-templates/>
1708 </xsl:template>
1710 <!-- ******************************************************************** -->
1712 <!--
1713 Content Model: (option_list_item +)
1714 Attributes: The option_list element contains only the common attributes:
1715 ids, names, dupnames, source, and classes.
1717 <!-- == compound_body_element -->
1718 <xsl:template
1719 match="option_list">
1720 <xsl:call-template
1721 name="u:outputClass"/>
1722 <xsl:call-template
1723 name="u:blank"/>
1724 <xsl:apply-templates/>
1725 </xsl:template>
1727 <!-- ******************************************************************** -->
1729 <!--
1730 Content Model: (option_group, description)
1731 Attributes: The option_list_item element contains only the common
1732 attributes: ids, names, dupnames, source, and classes.
1734 <!-- == compound_body_subelement -->
1735 <xsl:template
1736 match="option_list_item">
1737 <xsl:call-template
1738 name="u:outputClass"/>
1739 <xsl:call-template
1740 name="u:indent"/>
1741 <xsl:apply-templates/>
1742 </xsl:template>
1744 <!-- ******************************************************************** -->
1746 <!--
1747 Content Model: (option_group, description)
1748 Attributes: The option_group element contains only the common attributes:
1749 ids, names, dupnames, source, and classes.
1751 <!-- == compound_body_subelement -->
1752 <xsl:template
1753 match="option_group">
1754 <xsl:apply-templates/>
1755 &tEOL;
1756 </xsl:template>
1758 <!-- ******************************************************************** -->
1760 <!--
1761 Content Model: (option_string, option_argument *)
1762 Attributes: The option element contains only the common attributes: ids,
1763 names, dupnames, source, and classes.
1765 <!-- == compound_body_subelement -->
1766 <xsl:template
1767 match="option">
1768 <xsl:call-template
1769 name="u:outputClass"/>
1770 <xsl:apply-templates/>
1771 <xsl:if
1772 test="generate-id(current()) != generate-id(../*[last()])">
1773 <!-- No comma after final option -->
1774 <xsl:text>, </xsl:text>
1775 </xsl:if>
1776 <!-- no EOL: description on same line -->
1777 </xsl:template>
1779 <!-- ******************************************************************** -->
1781 <!--
1782 Content Model: (#PCDATA)
1783 Attributes: The option_string element contains only the common attributes:
1784 ids, names, dupnames, source, and classes.
1786 <!-- == simple_body_subelement -->
1787 <xsl:template
1788 match="option_string">
1789 <xsl:apply-templates/>
1790 </xsl:template>
1792 <!-- ******************************************************************** -->
1794 <!--
1795 Content Model: (#PCDATA)
1796 Attributes: The option_argument element contains the common attributes
1797 (ids, names, dupnames, source, and classes), plus delimiter.
1798 delimiter contains the text preceding the option_argument:
1799 either the text separating it from the option_string (typically
1800 either "=" or " ")
1801 or the text between option arguments (typically either "," or " ").
1803 <!-- == simple_body_subelement -->
1804 <xsl:template
1805 match="option_argument">
1806 <xsl:value-of
1807 select="@delimiter"/>
1808 <xsl:apply-templates/>
1809 </xsl:template>
1811 <!-- ******************************************************************** -->
1813 <!--
1814 Content Model: (%body.elements;)+
1815 Attributes: The description element contains only the common attributes:
1816 ids, names, dupnames, source, and classes.
1818 <!-- == compound_body_subelement -->
1819 <xsl:template
1820 match="description">
1821 <xsl:call-template
1822 name="u:outputClass"/>
1823 <xsl:apply-templates/>
1824 &tEOL;
1825 </xsl:template>
1827 <!-- ******************************************************************** -->
1829 <!--
1830 Content Model: (%body.elements;)+
1831 Attributes: The list_item element contains only the common attributes:
1832 ids, names, dupnames, source, and classes
1834 BULLET LIST
1835 bullet is used to record the style of bullet from the input data.
1836 In documents processed from reStructuredText, it contains one of "-",
1837 "+", or "*". It may be ignored in processing.
1839 <!-- == compound_body_subelement -->
1840 <xsl:template
1841 match="list_item"
1842 mode="bullet_list">
1843 <xsl:call-template
1844 name="u:outputClass"/>
1845 <xsl:call-template
1846 name="u:BandI"/>
1847 <xsl:value-of
1848 select="../@bullet"/>
1849 &tSP; <!-- space after bullet -->
1850 <xsl:apply-templates/>
1851 </xsl:template>
1853 <!-- ******************************************************************** -->
1855 <!--
1856 ENUMERATED LIST
1857 enumtype is used to record the intended enumeration sequence, one of
1858 "arabic" (1, 2, 3, ...), "loweralpha" (a, b, c, ..., z), "upperalpha" (A, B,
1859 C, ..., Z), "lowerroman" (i, ii, iii, iv, ..., mmmmcmxcix [4999]), or
1860 "upperroman" (I, II, III, IV, ..., MMMMCMXCIX [4999]).
1861 prefix stores the formatting characters used before the enumerator. In
1862 documents originating from reStructuredText data, it will contain either ""
1863 (empty string) or "(" (left parenthesis). It may or may not affect
1864 processing.
1865 suffix stores the formatting characters used after the enumerator. In
1866 documents originating from reStructuredText data, it will contain either "."
1867 (period) or ")" (right parenthesis). Depending on the capabilities of the
1868 output format, this attribute may or may not affect processing.
1869 start contains the ordinal value of the first item in the list, in
1870 decimal. For lists beginning at value 1 ("1", "a", "A", "i", or "I"), this
1871 attribute may be omitted.
1874 <!-- == compound_body_subelement -->
1875 <xsl:template
1876 match="list_item"
1877 mode="enumerated_list">
1878 <xsl:call-template
1879 name="u:outputClass"/>
1880 <xsl:call-template
1881 name="u:BandI"/>
1882 <xsl:call-template
1883 name="u:outputEnumerator"/>
1884 <xsl:apply-templates/>
1885 </xsl:template>
1887 <!-- Outputs a complete enumerator when called in an
1888 enumerated_list/list_item -->
1889 <xsl:template
1890 name="u:outputEnumerator">
1891 <!-- Use parent's numeration attribute -->
1892 <xsl:variable
1893 name="enumType"
1894 select="../@enumtype"/>
1895 <!-- Determine starting point -->
1896 <xsl:variable
1897 name="start">
1898 <xsl:choose>
1899 <xsl:when
1900 test="../@start">
1901 <xsl:value-of
1902 select="../@start"/>
1903 </xsl:when>
1904 <xsl:otherwise>
1905 <xsl:value-of
1906 select="1"/>
1907 </xsl:otherwise>
1908 </xsl:choose>
1909 </xsl:variable>
1910 <!-- Determine position of this item in its real context -->
1911 <xsl:variable
1912 name="position">
1913 <xsl:variable
1914 name="wanted"
1915 select="generate-id()"/>
1916 <!-- Generate the right current node list -->
1917 <xsl:for-each
1918 select="../list_item">
1919 <xsl:if
1920 test="generate-id() = $wanted">
1921 <xsl:value-of
1922 select="position()"/>
1923 </xsl:if>
1924 </xsl:for-each>
1925 </xsl:variable>
1926 <!-- Determine encoding of the number for the given numeration -->
1927 <xsl:variable
1928 name="cur">
1929 <xsl:call-template
1930 name="u:position2Enumerator">
1931 <xsl:with-param
1932 name="enumType"
1933 select="$enumType"/>
1934 <xsl:with-param
1935 name="position"
1936 select="$position"/>
1937 <xsl:with-param
1938 name="start"
1939 select="$start"/>
1940 </xsl:call-template>
1941 </xsl:variable>
1942 <!-- Determine encoding of the maximum number -->
1943 <xsl:variable
1944 name="max">
1945 <xsl:call-template
1946 name="u:position2Enumerator">
1947 <xsl:with-param
1948 name="enumType"
1949 select="$enumType"/>
1950 <xsl:with-param
1951 name="position"
1952 select="count(../list_item)"/>
1953 <xsl:with-param
1954 name="start"
1955 select="$start"/>
1956 </xsl:call-template>
1957 </xsl:variable>
1958 <!-- Output complete enumerator -->
1959 <xsl:value-of
1960 select="../@prefix"/>
1961 <xsl:value-of
1962 select="$cur"/>
1963 <xsl:value-of
1964 select="../@suffix"/>
1965 <!-- Output at least one trailing space -->
1966 &tSP;
1967 <!-- Output more whitespace to align with the maximum enumerator -->
1968 <xsl:if
1969 test="$enumType != 'lowerroman' and $enumType != 'upperroman'">
1970 <!-- Assumes that the maximum number has maximum string length -->
1971 <xsl:value-of
1972 select="str:padding(string-length($max) - string-length($cur))"/>
1973 </xsl:if>
1974 </xsl:template>
1976 <!-- Determine the right ordinal enumerator based on the parameters -->
1977 <xsl:template
1978 name="u:position2Enumerator">
1979 <xsl:param
1980 name="enumType"/>
1981 <xsl:param
1982 name="start"/>
1983 <xsl:param
1984 name="position"/>
1985 <!-- Determine logical number -->
1986 <xsl:variable
1987 name="ordinal"
1988 select="$start - 1 + $position"/>
1989 <xsl:choose>
1990 <xsl:when
1991 test="$enumType = 'arabic'">
1992 <xsl:value-of
1993 select="$ordinal"/>
1994 </xsl:when>
1995 <xsl:when
1996 test="$enumType = 'loweralpha'">
1997 <xsl:value-of
1998 select="substring('abcdefghijklmnopqrstzuvwxyz', $ordinal, 1)"/>
1999 </xsl:when>
2000 <xsl:when
2001 test="$enumType = 'upperalpha'">
2002 <xsl:value-of
2003 select="substring('ABCDEFGHIJKLMNOPQRSTZUVWXYZ', $ordinal, 1)"/>
2004 </xsl:when>
2005 <!-- TODO Support for counting roman numbers -->
2006 <xsl:when
2007 test="$enumType = 'lowerroman'">
2008 <xsl:text>i</xsl:text>
2009 </xsl:when>
2010 <xsl:when
2011 test="$enumType = 'upperroman'">
2012 <xsl:text>I</xsl:text>
2013 </xsl:when>
2014 </xsl:choose>
2015 </xsl:template>
2017 <!-- ******************************************************************** -->
2018 <!-- ******************************************************************** -->
2020 <!--
2021 Content Model: (title?, tgroup+)
2022 Attributes: The table element contains the common attributes and:
2023 frame, colsep, rowsep, pgwide
2025 <!-- == compound_body_element -->
2026 <xsl:template
2027 match="table">
2028 <xsl:call-template
2029 name="u:outputClass"/>
2030 <xsl:call-template
2031 name="u:blank"/>
2032 <xsl:apply-templates
2033 select="tgroup"/>
2034 <xsl:if
2035 test="title">
2036 <!-- TODO A table title must be rendered by using the `.. table::'
2037 directive -->
2038 <xsl:call-template
2039 name="u:BandI"/>
2040 <xsl:apply-templates
2041 select="title"/>
2042 &tEOL;
2043 </xsl:if>
2044 </xsl:template>
2046 <!-- ******************************************************************** -->
2048 <!--
2049 Content Model: (colspec*, thead?, tbody)
2050 Attributes: The tgroup element contains the common attributes and:
2051 cols, colsep, rowsep, align
2053 <!-- == compound_body_subelement -->
2054 <xsl:template
2055 match="tgroup">
2056 <xsl:apply-templates/>
2057 </xsl:template>
2059 <!-- ******************************************************************** -->
2061 <!--
2062 Content Model: EMPTY
2063 Attributes: The colspec element contains the common attributes and:
2064 colnum, colname, colwidth, colsep, rowsep, align, char, charoff
2066 The colwidth attribute gives the width of the respective column in characters
2067 including padding whitespace but no separator markup.
2069 <!-- == simple_body_subelement -->
2070 <!-- @colwidth needed by children but element has no own output -->
2071 <xsl:template
2072 match="colspec"/>
2074 <!-- ******************************************************************** -->
2076 <!--
2077 Content Model: (row+)
2078 Attributes: The thead element contains the common attributes and:
2079 valign
2081 <!-- == compound_body_subelement -->
2082 <xsl:template
2083 match="thead">
2084 <xsl:apply-templates/>
2085 </xsl:template>
2087 <!--
2088 Content Model: (row+)
2089 Attributes: The tbody element contains the common attributes and:
2090 valign
2092 <!-- == compound_body_subelement -->
2093 <xsl:template
2094 match="tbody">
2095 <xsl:apply-templates/>
2096 </xsl:template>
2098 <!-- ******************************************************************** -->
2100 <!--
2101 Content Model: (entry+)
2102 Attributes: The row element contains the common attributes and:
2103 rowsep, valign
2105 <!-- == compound_body_subelement -->
2106 <xsl:template
2107 match="row">
2108 <!-- Separator line above unless first row of a tbody with no previous
2109 thead (in this case the separator line is output already as the
2110 closing separator line of thead) -->
2111 <xsl:if
2112 test="position() > 1 or parent::thead or parent::tbody and not(../../thead)">
2113 <xsl:call-template
2114 name="u:rowSeparatorLine"/>
2115 </xsl:if>
2116 <!-- Determine heights in physical lines of all entries -->
2117 <xsl:variable
2118 name="heights">
2119 <xsl:for-each
2120 select="entry">
2121 <xsl:variable
2122 name="text">
2123 <!-- Catch the text of all entries -->
2124 <xsl:apply-templates/>
2125 </xsl:variable>
2126 <!-- Compute height of this entry; leading and trailing EOL must be
2127 subtracted -->
2128 <xsl:value-of
2129 select="string-length($text) - string-length(translate($text, '&#xA;', '')) - 1"/>
2130 &tSP; <!-- A space as a list separator -->
2131 </xsl:for-each>
2132 </xsl:variable>
2133 <!-- Determine maximum height so every entry must be this high -->
2134 <xsl:variable
2135 name="maxHeight"
2136 select="math:max(str:tokenize(normalize-space($heights)))"/>
2137 <!-- Output all the physical lines of this row -->
2138 <xsl:call-template
2139 name="u:rowLines">
2140 <xsl:with-param
2141 name="currentLine"
2142 select="1"/>
2143 <xsl:with-param
2144 name="maxLine"
2145 select="$maxHeight"/>
2146 </xsl:call-template>
2147 <!-- Output final separator line if this is the last row -->
2148 <xsl:if
2149 test="position() = last()">
2150 <xsl:call-template
2151 name="u:rowSeparatorLine">
2152 <xsl:with-param
2153 name="char">
2154 <!-- Determine correct character for the separator line -->
2155 <xsl:choose>
2156 <xsl:when
2157 test="parent::thead">
2158 <xsl:value-of
2159 select="'='"/>
2160 </xsl:when>
2161 <xsl:otherwise>
2162 <xsl:value-of
2163 select="'-'"/>
2164 </xsl:otherwise>
2165 </xsl:choose>
2166 </xsl:with-param>
2167 </xsl:call-template>
2168 </xsl:if>
2169 </xsl:template>
2171 <!-- Output physical line $currentLine of a row and continue until
2172 line $maxLine is output -->
2173 <xsl:template
2174 name="u:rowLines">
2175 <xsl:param
2176 name="currentLine"/>
2177 <xsl:param
2178 name="maxLine"/>
2179 <xsl:if
2180 test="$currentLine &lt;= $maxLine">
2181 <!-- If there are still physical lines to output do it -->
2182 <xsl:call-template
2183 name="u:indent"/>
2184 <!-- Leading bar -->
2185 <xsl:text>|</xsl:text>
2186 <xsl:apply-templates>
2187 <xsl:with-param
2188 name="currentLine"
2189 select="$currentLine"/>
2190 </xsl:apply-templates>
2191 <!-- End of this physical line -->
2192 &tEOL;
2193 <!-- Continue with the next physical line -->
2194 <xsl:call-template
2195 name="u:rowLines">
2196 <xsl:with-param
2197 name="currentLine"
2198 select="$currentLine + 1"/>
2199 <xsl:with-param
2200 name="maxLine"
2201 select="$maxLine"/>
2202 </xsl:call-template>
2203 </xsl:if>
2204 </xsl:template>
2206 <!-- Output a separator line with all the right characters -->
2207 <xsl:template
2208 name="u:rowSeparatorLine">
2209 <xsl:param
2210 name="char"
2211 select="'-'"/>
2212 <xsl:call-template
2213 name="u:indent"/>
2214 <xsl:text>+</xsl:text>
2215 <xsl:for-each
2216 select="../../colspec">
2217 <xsl:value-of
2218 select="str:padding(@colwidth, $char)"/>
2219 <xsl:text>+</xsl:text>
2220 </xsl:for-each>
2221 &tEOL;
2222 </xsl:template>
2224 <!-- ******************************************************************** -->
2226 <!--
2227 Content Model: (%body.elements;)*
2228 Attributes: The entry element contains the common attributes and:
2229 colname, namest, morerows, colsep, rowsep, align, char, charoff, valign and
2230 morecols
2232 <!-- == compound_body_subelement -->
2233 <xsl:template
2234 match="entry">
2235 <!-- TODO `classes` attribute needs support -->
2236 <!-- This is called in two ways; if $currentLine = 0 all physical lines
2237 of this entry must be output; if $currentLine > 0 the physical line
2238 with exactly this number shall be output -->
2239 <xsl:param
2240 name="currentLine"
2241 select="0"/>
2242 <xsl:variable
2243 name="column"
2244 select="position() + sum(preceding-sibling::entry/@morecols)"/>
2245 <!-- Determine width in characters needed for this entry -->
2246 <xsl:variable
2247 name="width">
2248 <xsl:call-template
2249 name="u:computeEntryWidth">
2250 <xsl:with-param
2251 name="colspecs"
2252 select="../../../colspec"/>
2253 <xsl:with-param
2254 name="column"
2255 select="$column"/>
2256 <xsl:with-param
2257 name="span"
2258 select="@morecols"/>
2259 </xsl:call-template>
2260 </xsl:variable>
2261 <!-- Output the entry completely or a certain physical line -->
2262 <xsl:call-template
2263 name="u:outputEntry">
2264 <xsl:with-param
2265 name="string">
2266 <!-- Capture physical lines of the entry in a variable -->
2267 <xsl:apply-templates/>
2268 </xsl:with-param>
2269 <xsl:with-param
2270 name="width"
2271 select="$width"/>
2272 <xsl:with-param
2273 name="expectedIndent">
2274 <!-- Capture indent for the entry generated by the normal template
2275 rules to remove it later -->
2276 <xsl:call-template
2277 name="u:indent"/>
2278 </xsl:with-param>
2279 <xsl:with-param
2280 name="outputLine"
2281 select="$currentLine"/>
2282 </xsl:call-template>
2283 <!-- Final bar after the entry -->
2284 <xsl:text>|</xsl:text>
2285 </xsl:template>
2287 <!-- Compute width of the entry -->
2288 <xsl:template
2289 name="u:computeEntryWidth">
2290 <!-- The colspec elements of all columns -->
2291 <xsl:param
2292 name="colspecs"/>
2293 <!-- Column of this entry -->
2294 <xsl:param
2295 name="column"/>
2296 <!-- Number of columns this entry spans -->
2297 <xsl:param
2298 name="span"
2299 select="0"/>
2300 <xsl:param
2301 name="sum"
2302 select="0"/>
2303 <xsl:choose>
2304 <xsl:when
2305 test="$span">
2306 <!-- If entry spans multiple columns compute their width -->
2307 <xsl:call-template
2308 name="u:computeEntryWidth">
2309 <xsl:with-param
2310 name="colspecs"
2311 select="$colspecs"/>
2312 <xsl:with-param
2313 name="column"
2314 select="$column + 1"/>
2315 <xsl:with-param
2316 name="span"
2317 select="$span - 1"/>
2318 <!-- Add the separator character and the following column width -->
2319 <xsl:with-param
2320 name="sum"
2321 select="$sum + 1 + $colspecs[$column]/@colwidth"/>
2322 </xsl:call-template>
2323 </xsl:when>
2324 <xsl:otherwise>
2325 <!-- Does not span more columns so return sum and width of this
2326 column -->
2327 <xsl:value-of
2328 select="$sum + $colspecs[$column]/@colwidth"/>
2329 </xsl:otherwise>
2330 </xsl:choose>
2331 </xsl:template>
2333 <!-- Outputs one or all lines of a table entry as a string trimmed left and
2334 padded -->
2335 <xsl:template
2336 name="u:outputEntry">
2337 <!-- Width of the entry; there is no provision for actual physical lines
2338 longer than this width -->
2339 <xsl:param
2340 name="width"/>
2341 <!-- The string containing the remaining physical lines; may be an empty
2342 string -->
2343 <xsl:param
2344 name="string"
2345 select="''"/>
2346 <!-- The indendation which is expected to be prefixed before every
2347 physical line -->
2348 <xsl:param
2349 name="expectedIndent"
2350 select="''"/>
2351 <!-- Is this the first call to this template -->
2352 <xsl:param
2353 name="isFirst"
2354 select="true()"/>
2355 <!-- Number of physical line to output or 0 to output all lines -->
2356 <xsl:param
2357 name="outputLine"
2358 select="0"/>
2359 <!-- Output is wanted if all or the first physical line are to be
2360 output -->
2361 <xsl:variable
2362 name="doOutput"
2363 select="$outputLine = 0 or $outputLine = 1"/>
2364 <xsl:variable
2365 name="stringLFHalfTrimmed">
2366 <xsl:choose>
2367 <xsl:when
2368 test="$isFirst and substring($string, 1, 1) = '&#x0A;'">
2369 <!-- Remove leading linefeed if this is the first time -->
2370 <xsl:value-of
2371 select="substring($string, 2)"/>
2372 </xsl:when>
2373 <xsl:otherwise>
2374 <xsl:value-of
2375 select="$string"/>
2376 </xsl:otherwise>
2377 </xsl:choose>
2378 </xsl:variable>
2379 <xsl:variable
2380 name="stringLFTrimmed">
2381 <xsl:choose>
2382 <xsl:when
2383 test="$isFirst and substring($stringLFHalfTrimmed, string-length($stringLFHalfTrimmed), 1) = '&#x0A;'">
2384 <!-- Remove trailing linefeed if this is the first time -->
2385 <xsl:value-of
2386 select="substring($stringLFHalfTrimmed, 1, string-length($stringLFHalfTrimmed) - 1)"/>
2387 </xsl:when>
2388 <xsl:otherwise>
2389 <xsl:value-of
2390 select="$stringLFHalfTrimmed"/>
2391 </xsl:otherwise>
2392 </xsl:choose>
2393 </xsl:variable>
2394 <!-- Determine remaining lines after the first one -->
2395 <xsl:variable
2396 name="remainingLines">
2397 <xsl:if
2398 test="contains($stringLFTrimmed, '&#x0A;')">
2399 <xsl:value-of
2400 select="substring-after($stringLFTrimmed, '&#x0A;')"/>
2401 </xsl:if>
2402 </xsl:variable>
2403 <xsl:if
2404 test="$doOutput">
2405 <!-- If this physical line must be output determine the first physical
2406 line -->
2407 <xsl:variable
2408 name="firstLine">
2409 <xsl:choose>
2410 <xsl:when
2411 test="string-length($remainingLines)">
2412 <xsl:value-of
2413 select="substring-before($stringLFTrimmed, '&#x0A;')"/>
2414 </xsl:when>
2415 <xsl:otherwise>
2416 <xsl:value-of
2417 select="$stringLFTrimmed"/>
2418 </xsl:otherwise>
2419 </xsl:choose>
2420 </xsl:variable>
2421 <!-- Remove the leading indentation from the physical line which is
2422 brought there by the normal templates -->
2423 <xsl:variable
2424 name="trimmed">
2425 <xsl:if
2426 test="string-length($firstLine)">
2427 <!-- Trim only non-empty lines -->
2428 <xsl:value-of
2429 select="substring-after($firstLine, $expectedIndent)"/>
2430 </xsl:if>
2431 </xsl:variable>
2432 <!-- Pad the line with a leading and a trailing space -->
2433 <xsl:variable
2434 name="padded"
2435 select="concat(' ', $trimmed, ' ')"/>
2436 <!-- Output the padded value -->
2437 <xsl:value-of
2438 select="$padded"/>
2439 <!-- Fill up the width of the entry with spaces -->
2440 <xsl:if
2441 test="$width - string-length($padded) &lt; 0">
2442 <xsl:message>
2443 <xsl:text>WARNING: Table column too narrow (minimum: </xsl:text>
2444 <xsl:value-of
2445 select="string-length($padded)"/>
2446 <xsl:text>)</xsl:text>
2447 &tEOL;
2448 </xsl:message>
2449 </xsl:if>
2450 <xsl:value-of
2451 select="str:padding($width - string-length($padded))"/>
2452 </xsl:if>
2453 <xsl:if
2454 test="$outputLine > 1 or $outputLine = 0 and string-length($remainingLines)">
2455 <!-- If a following physical line must be output or if all physical
2456 lines shall be output and there are remaining physical lines -->
2457 <xsl:if
2458 test="$outputLine = 0">
2459 <!-- Output linefeed only if we output all the lines -->
2460 &tEOL;
2461 </xsl:if>
2462 <!-- Output the remaining lines -->
2463 <xsl:call-template
2464 name="u:outputEntry">
2465 <xsl:with-param
2466 name="width"
2467 select="$width"/>
2468 <xsl:with-param
2469 name="string"
2470 select="$remainingLines"/>
2471 <xsl:with-param
2472 name="expectedIndent"
2473 select="$expectedIndent"/>
2474 <xsl:with-param
2475 name="isFirst"
2476 select="false()"/>
2477 <xsl:with-param
2478 name="outputLine">
2479 <xsl:choose>
2480 <xsl:when
2481 test="$outputLine = 0">
2482 <xsl:value-of
2483 select="0"/>
2484 </xsl:when>
2485 <xsl:otherwise>
2486 <xsl:value-of
2487 select="$outputLine - 1"/>
2488 </xsl:otherwise>
2489 </xsl:choose>
2490 </xsl:with-param>
2491 </xsl:call-template>
2492 </xsl:if>
2493 </xsl:template>
2495 <!-- ******************************************************************** -->
2496 <!-- ******************************************************************** -->
2498 <!-- == inline_element -->
2499 <xsl:template
2500 match="citation_reference">
2501 <xsl:call-template
2502 name="u:bkslshEscPre"/>
2503 <xsl:text>[</xsl:text>
2504 <xsl:apply-templates/>
2505 <xsl:text>]_</xsl:text>
2506 <xsl:call-template
2507 name="u:bkslshEscSuf"/>
2508 </xsl:template>
2510 <!-- ******************************************************************** -->
2512 <!-- == inline_element -->
2513 <xsl:template
2514 match="emphasis">
2515 <xsl:call-template
2516 name="u:bkslshEscPre"/>
2517 <xsl:text>*</xsl:text>
2518 <xsl:apply-templates/>
2519 <xsl:text>*</xsl:text>
2520 <xsl:call-template
2521 name="u:bkslshEscSuf"/>
2522 </xsl:template>
2524 <!-- ******************************************************************** -->
2526 <!-- user-numbered footnotes lack @auto -->
2527 <!-- == inline_element -->
2528 <xsl:template
2529 match="footnote_reference[not(@auto)]">
2530 <xsl:call-template
2531 name="u:bkslshEscPre"/>
2532 <xsl:text>[</xsl:text>
2533 <xsl:value-of
2534 select="text()"/>
2535 <xsl:text>]_</xsl:text>
2536 <xsl:call-template
2537 name="u:bkslshEscSuf"/>
2538 <!-- child paragraph provides blank line -->
2539 </xsl:template>
2541 <!-- automatically numbered footnotes have @auto -->
2542 <!-- if @names is different from label content, it is a named footnote -->
2543 <!-- == inline_element -->
2544 <xsl:template
2545 match="footnote_reference[@auto='1']">
2546 <xsl:variable
2547 name="ref"
2548 select="@refid"/>
2549 <xsl:if
2550 test="not(starts-with(//footnote[@ids=$ref]/@names, 'TARGET_NOTE:\ '))">
2551 <!-- Not a generated footnote reference for a `.. target-notes::';
2552 such footnote reference and the preceding space should be
2553 embedded in `generated'! -->
2554 <xsl:call-template
2555 name="u:bkslshEscPre"/>
2556 <xsl:text>[#</xsl:text>
2557 <xsl:if
2558 test="//footnote[@ids=$ref]/@names != //footnote[@ids=$ref]/label">
2559 <xsl:call-template
2560 name="u:outputNames">
2561 <xsl:with-param
2562 name="names"
2563 select="//footnote[@ids=$ref]/@names"/>
2564 </xsl:call-template>
2565 </xsl:if>
2566 <xsl:text>]_</xsl:text>
2567 <xsl:call-template
2568 name="u:bkslshEscSuf"/>
2569 </xsl:if>
2570 </xsl:template>
2572 <!-- automatically symboled footnotes have @auto=* -->
2573 <!-- == inline_element -->
2574 <xsl:template
2575 match="footnote_reference[@auto='*']">
2576 <xsl:call-template
2577 name="u:bkslshEscPre"/>
2578 <xsl:text>[*]_</xsl:text>
2579 <xsl:call-template
2580 name="u:bkslshEscSuf"/>
2581 </xsl:template>
2583 <!-- ******************************************************************** -->
2585 <!--
2586 Content Model: %text.model;
2588 <!-- == inline_element -->
2589 <xsl:template
2590 match="literal">
2591 <xsl:call-template
2592 name="u:bkslshEscPre"/>
2593 <xsl:text>``</xsl:text>
2594 <xsl:apply-templates/>
2595 <xsl:text>``</xsl:text>
2596 <xsl:call-template
2597 name="u:bkslshEscSuf"/>
2598 </xsl:template>
2600 <!-- ******************************************************************** -->
2602 <!-- Attribute combinations found in `standard' text and other examples:
2603 @refuri = standalone hyperlink
2604 @ids @refid = TOC, probably all in <generated>
2605 @name @refuri with matching <target> in document = named external hyperlink _
2606 @name @refuri immediately followed by matching <target> = named embedded URI _
2607 @name @refuri with no matching <target> in document = anonymous embedded URI __
2608 @anonymous @name @refuri with no matching <target> in document = anonymous explicit URI __
2609 @name @refid = internal cross-reference _
2610 @anonymous @name @refid = anonymous implicit internal reference __
2611 @name @refid image = clickable image to internal reference _
2612 @refuri image = clickable image to standalone hyperlink
2614 A target matches if target/@names contains the lower cased, whitespace
2615 quoted reference/@name
2618 <!-- Standalone hyperlink -->
2619 <!-- == inline_element -->
2620 <xsl:template
2621 match="reference[not(@name or @anonymous)]">
2622 <xsl:call-template
2623 name="u:bkslshEscPre"/>
2624 <xsl:choose>
2625 <xsl:when
2626 test="starts-with(., 'PEP ')">
2627 <xsl:text>:PEP:`</xsl:text>
2628 <xsl:value-of
2629 select="substring-after(., 'PEP ')"/>
2630 <xsl:text>`</xsl:text>
2631 </xsl:when>
2632 <xsl:when
2633 test="starts-with(., 'RFC ')">
2634 <xsl:text>:RFC:`</xsl:text>
2635 <xsl:value-of
2636 select="substring-after(., 'RFC ')"/>
2637 <xsl:text>`</xsl:text>
2638 </xsl:when>
2639 <xsl:otherwise>
2640 <xsl:apply-templates/>
2641 </xsl:otherwise>
2642 </xsl:choose>
2643 <xsl:call-template
2644 name="u:bkslshEscSuf"/>
2645 </xsl:template>
2647 <!-- External references -->
2648 <!-- == inline_element -->
2649 <xsl:template
2650 match="reference[@name and @refuri]">
2651 <!-- Determine normalized name by downcasing it -->
2652 <xsl:variable
2653 name="normalized"
2654 select="translate(normalize-space(@name), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"/>
2655 <xsl:variable
2656 name="quoted"
2657 select="str:replace($normalized, ' ', '\ ')"/>
2658 <xsl:variable
2659 name="matching"
2660 select="//target[contains(@names, $quoted)]"/>
2661 <xsl:call-template
2662 name="u:inlineReference">
2663 <xsl:with-param
2664 name="anonymous"
2665 select="not($matching) or @anonymous"/>
2666 <xsl:with-param
2667 name="embedded"
2668 select="not(@anonymous) and (not($matching) or generate-id(following-sibling::node()[1]) = generate-id($matching))"/>
2669 </xsl:call-template>
2670 </xsl:template>
2672 <!-- Internal references -->
2673 <!-- == inline_element -->
2674 <xsl:template
2675 match="reference[@name and @refid]">
2676 <xsl:call-template
2677 name="u:inlineReference">
2678 <xsl:with-param
2679 name="anonymous"
2680 select="@anonymous"/>
2681 </xsl:call-template>
2682 </xsl:template>
2684 <!-- Image references -->
2685 <!-- == inline_element -->
2686 <xsl:template
2687 match="reference[image]">
2688 <!-- All done by the `image' tag -->
2689 <xsl:apply-templates/>
2690 </xsl:template>
2692 <!-- ******************************************************************** -->
2694 <!--
2695 Content Model: %text.model;
2697 <!-- == inline_element -->
2698 <xsl:template
2699 match="strong">
2700 <xsl:call-template
2701 name="u:bkslshEscPre"/>
2702 <xsl:text>**</xsl:text>
2703 <xsl:apply-templates/>
2704 <xsl:text>**</xsl:text>
2705 <xsl:call-template
2706 name="u:bkslshEscSuf"/>
2707 </xsl:template>
2709 <!-- ******************************************************************** -->
2711 <!-- == inline_element -->
2712 <xsl:template
2713 match="subscript">
2714 <xsl:call-template
2715 name="u:bkslshEscPre"/>
2716 <xsl:text>:sub:`</xsl:text>
2717 <xsl:apply-templates/>
2718 <xsl:text>`</xsl:text>
2719 <xsl:call-template
2720 name="u:bkslshEscSuf"/>
2721 </xsl:template>
2723 <!-- ******************************************************************** -->
2725 <!-- == inline_element -->
2726 <xsl:template
2727 match="superscript">
2728 <xsl:call-template
2729 name="u:bkslshEscPre"/>
2730 <xsl:text>:sup:`</xsl:text>
2731 <xsl:apply-templates/>
2732 <xsl:text>`</xsl:text>
2733 <xsl:call-template
2734 name="u:bkslshEscSuf"/>
2735 </xsl:template>
2737 <!-- ******************************************************************** -->
2739 <!-- The target element has various roles depending on context; they are
2740 all handled here -->
2741 <!-- == simple_body_element == inline_element == directive -->
2742 <xsl:template
2743 match="target">
2744 <xsl:choose>
2745 <xsl:when
2746 test="name(preceding-sibling::*[1]) = 'reference'">
2747 <!-- An embedded inline target - handled by the reference itself -->
2748 </xsl:when>
2749 <xsl:when
2750 test="contains($inline_containers, concat('*', name(..), '*'))">
2751 <!-- An inline target of some sort -->
2752 <xsl:call-template
2753 name="u:inlineReference">
2754 <xsl:with-param
2755 name="isTarget"
2756 select="true()"/>
2757 </xsl:call-template>
2758 </xsl:when>
2759 <xsl:when
2760 test="@anonymous">
2761 <!-- An anonymous target directive -->
2762 <xsl:call-template
2763 name="u:outputClass"/>
2764 <xsl:call-template
2765 name="u:BandI"/>
2766 <xsl:text>__ </xsl:text>
2767 <xsl:choose>
2768 <xsl:when
2769 test="@refid">
2770 <xsl:call-template
2771 name="u:outputNamesRefid"/>
2772 <xsl:text>_</xsl:text>
2773 </xsl:when>
2774 <xsl:when
2775 test="@refuri">
2776 <xsl:value-of
2777 select="@refuri"/>
2778 </xsl:when>
2779 </xsl:choose>
2780 &tEOL;
2781 </xsl:when>
2782 <xsl:when
2783 test="@names | @refid">
2784 <!-- A target directive -->
2785 <xsl:call-template
2786 name="u:outputClass"/>
2787 <xsl:call-template
2788 name="u:BandI"/>
2789 <xsl:text>.. _</xsl:text>
2790 <xsl:choose>
2791 <xsl:when
2792 test="@refid">
2793 <xsl:call-template
2794 name="u:outputNamesRefid"/>
2795 </xsl:when>
2796 <xsl:otherwise>
2797 <xsl:variable
2798 name="quoteNeeded"
2799 select="contains(@names, ':')"/>
2800 <xsl:if
2801 test="$quoteNeeded">
2802 <xsl:text>`</xsl:text>
2803 </xsl:if>
2804 <xsl:call-template
2805 name="u:outputNames"/>
2806 <xsl:if
2807 test="$quoteNeeded">
2808 <xsl:text>`</xsl:text>
2809 </xsl:if>
2810 </xsl:otherwise>
2811 </xsl:choose>
2812 <xsl:text>:</xsl:text>
2813 <xsl:if
2814 test="@refuri">
2815 <xsl:text> </xsl:text>
2816 <xsl:value-of
2817 select="@refuri"/>
2818 </xsl:if>
2819 &tEOL;
2820 </xsl:when>
2821 <xsl:otherwise>
2822 <!-- Should not happen -->
2823 <xsl:call-template
2824 name="u:notSupported"/>
2825 </xsl:otherwise>
2826 </xsl:choose>
2827 </xsl:template>
2829 <!-- ******************************************************************** -->
2831 <!--
2832 Content Model: %text.model;
2834 <!-- == inline_element -->
2835 <xsl:template
2836 match="title_reference">
2837 <xsl:call-template
2838 name="u:bkslshEscPre"/>
2839 <xsl:text>`</xsl:text>
2840 <xsl:apply-templates/>
2841 <xsl:text>`</xsl:text>
2842 <xsl:call-template
2843 name="u:bkslshEscSuf"/>
2844 </xsl:template>
2846 <!-- ******************************************************************** -->
2848 <!--
2849 Content Model: %text.model;
2851 <!-- == inline_element -->
2852 <xsl:template
2853 match="inline">
2854 <!-- TODO `role' directives must be generated for plain and derived
2855 user-defined roles. -->
2856 <xsl:call-template
2857 name="u:bkslshEscPre"/>
2858 <xsl:text>:</xsl:text>
2859 <xsl:value-of
2860 select="@classes"/>
2861 <xsl:text>:`</xsl:text>
2862 <xsl:apply-templates/>
2863 <xsl:text>`</xsl:text>
2864 <xsl:call-template
2865 name="u:bkslshEscSuf"/>
2866 </xsl:template>
2868 <!-- ******************************************************************** -->
2870 <!-- TODO `meta` directive must be implemented. -->
2872 <!-- ******************************************************************** -->
2874 <!--
2875 Docutils wraps generated elements around text that is inserted (generated) by
2876 Docutils; i.e., text that was not in the document, like section numbers
2877 inserted by the "sectnum" directive.
2879 <!-- == inline_element -->
2880 <xsl:template
2881 match="generated"/>
2883 <!-- == inline_element -->
2884 <xsl:template
2885 match="problematic">
2886 <!-- Simply output the contained text because this is probably the
2887 original text-->
2888 <xsl:value-of
2889 select="text()"/>
2890 </xsl:template>
2892 <!-- == compound_body_element -->
2893 <xsl:template
2894 match="system_message"/>
2896 <!-- ******************************************************************** -->
2897 <!-- ******************************************************************** -->
2899 <!--
2900 When a block of text contains linefeeds, it was indented relative to a marker
2901 on the first line
2903 <xsl:template
2904 match="text()">
2905 <xsl:call-template
2906 name="u:indentLF"/>
2907 </xsl:template>
2909 <!-- ******************************************************************** -->
2910 <!-- ******************************************************************** -->
2912 <!-- Add a blank line if necessary and indent -->
2913 <xsl:template
2914 name="u:BandI">
2915 <xsl:call-template
2916 name="u:blank"/>
2917 <xsl:call-template
2918 name="u:indent"/>
2919 </xsl:template>
2921 <!-- ******************************************************************** -->
2923 <!-- Add a blank line in certain contexts -->
2924 <xsl:template
2925 name="u:blank">
2926 <xsl:apply-templates
2927 mode="blankSkipInline"
2928 select="preceding::*[1]"/>
2929 </xsl:template>
2931 <!-- Find the preceding element we are really interested in and act
2932 according to this element -->
2933 <xsl:template
2934 mode="blankSkipInline"
2935 match="*">
2936 <xsl:choose>
2937 <!-- Skip all inline elements and body subelements and check their
2938 parents -->
2939 <xsl:when
2940 test="contains(concat($inline_elements, $simple_body_subelements, $compound_body_subelements), concat('*', name(.), '*'))">
2941 <xsl:apply-templates
2942 mode="blankSkipInline"
2943 select=".."/>
2944 </xsl:when>
2945 <xsl:otherwise>
2946 <!-- Reached the type of element we decide on -->
2947 <xsl:if
2948 test="contains($blank_after, concat('*', name(.), '*'))">
2949 &tCR;
2950 </xsl:if>
2951 </xsl:otherwise>
2952 </xsl:choose>
2953 </xsl:template>
2955 <!-- ******************************************************************** -->
2957 <!--
2958 Indent a block if it's a child of...
2960 <data:lookup>
2961 <node
2962 name="address"
2963 indent="10"/>
2964 <node
2965 name="author"
2966 indent="9"/>
2967 <node
2968 name="authors"
2969 indent="10"/>
2970 <node
2971 name="contact"
2972 indent="10"/>
2973 <node
2974 name="copyright"
2975 indent="12"/>
2976 <node
2977 name="date"
2978 indent="7"/>
2979 <node
2980 name="organization"
2981 indent="15"/>
2982 <node
2983 name="revision"
2984 indent="11"/>
2985 <node
2986 name="status"
2987 indent="9"/>
2988 <node
2989 name="version"
2990 indent="10"/>
2991 <!-- This is only for `bullet_list/list_item';
2992 `enumerated_list/list_item' is handled special -->
2993 <node
2994 name="list_item"
2995 indent="2"/>
2996 <node
2997 name="definition_list_item"
2998 indent="4"/>
2999 <node
3000 name="field_body"
3001 indent="4"/>
3002 <node
3003 name="option_list_item"
3004 indent="4"/>
3005 <!-- This is also the indentation if block_quote comes as one of the
3006 special directives -->
3007 <node
3008 name="block_quote"
3009 indent="4"/>
3010 <node
3011 name="literal_block"
3012 indent="4"/>
3013 <node
3014 name="attribution"
3015 indent="3"/>
3016 <node
3017 name="line"
3018 indent="2"/>
3019 </data:lookup>
3021 <!-- Do indent according to ancestor -->
3022 <xsl:template
3023 name="u:indent">
3024 <!-- In some cases the ancestors to indent for need to be determined
3025 by the calling template -->
3026 <xsl:param
3027 name="ancestors"
3028 select="ancestor::*"/>
3029 <xsl:for-each
3030 select="$ancestors">
3031 <xsl:variable
3032 name="this"
3033 select="name()"/>
3034 <xsl:choose>
3035 <xsl:when
3036 test="contains($directives, concat('*', $this, '*'))">
3037 <!-- TODO Indentation of lines after some directives must be
3038 indented to align with the directive instead of a
3039 fixed indentation; however, this is rather complicated
3040 since identation for parameters should be fixed -->
3041 <xsl:value-of
3042 select="str:padding(3)"/>
3043 </xsl:when>
3044 <xsl:when
3045 test="$this = 'list_item' and parent::enumerated_list">
3046 <!-- Enumerated list items base their indentation on the
3047 numeration -->
3048 <xsl:variable
3049 name="enumerator">
3050 <xsl:call-template
3051 name="u:outputEnumerator"/>
3052 </xsl:variable>
3053 <xsl:value-of
3054 select="str:padding(string-length($enumerator))"/>
3055 </xsl:when>
3056 <xsl:otherwise>
3057 <xsl:value-of
3058 select="str:padding(document('')//data:lookup/node[@name=$this]/@indent)"/>
3059 </xsl:otherwise>
3060 </xsl:choose>
3061 </xsl:for-each>
3062 </xsl:template>
3064 <!-- ******************************************************************** -->
3066 <!-- Indent a text containing line feeds correctly -->
3067 <xsl:template
3068 name="u:indentLF">
3069 <xsl:param
3070 name="string"
3071 select="."/>
3072 <!-- A fixed indentation may be given by caller -->
3073 <xsl:param
3074 name="indent">
3075 <!-- If not given compute it -->
3076 <xsl:call-template
3077 name="u:indent"/>
3078 </xsl:param>
3079 <xsl:choose>
3080 <xsl:when
3081 test="contains($string,'&#x0A;')">
3082 <!-- Output first physical line -->
3083 <xsl:value-of
3084 select="substring-before($string, '&#x0A;')"/>
3085 &tEOL;
3086 <!-- Indent before the next line -->
3087 <xsl:value-of
3088 select="$indent"/>
3089 <!-- Output remaining physical lines -->
3090 <xsl:call-template
3091 name="u:indentLF">
3092 <xsl:with-param
3093 name="string"
3094 select="substring-after($string, '&#x0A;')"/>
3095 <xsl:with-param
3096 name="indent"
3097 select="$indent"/>
3098 </xsl:call-template>
3099 </xsl:when>
3100 <!-- String does not contain newline, so just output it -->
3101 <xsl:otherwise>
3102 <xsl:value-of
3103 select="$string"/>
3104 </xsl:otherwise>
3105 </xsl:choose>
3106 </xsl:template>
3108 <!-- ******************************************************************** -->
3110 <!-- Do output for those elements which do fold their inline content -->
3111 <xsl:template
3112 name="u:outputFolding">
3113 <!-- The prefix text to be output before the body -->
3114 <xsl:param
3115 name="prefix"
3116 select="''"/>
3117 <!-- The indentation for this body -->
3118 <xsl:param
3119 name="indent">
3120 <xsl:call-template
3121 name="u:indent">
3122 <xsl:with-param
3123 name="ancestors"
3124 select="ancestor-or-self::*"/>
3125 </xsl:call-template>
3126 </xsl:param>
3127 <xsl:variable
3128 name="string">
3129 <!-- TODO Whitespace count of inline literals must be preserved -->
3130 <xsl:apply-templates/>
3131 </xsl:variable>
3132 <!-- Always output prefix with all trailing and leading spaces -->
3133 <xsl:value-of
3134 select="$prefix"/>
3135 <xsl:choose>
3136 <xsl:when
3137 test="$fold &gt; 0">
3138 <xsl:variable
3139 name="normalized"
3140 select="normalize-space($string)"/>
3141 <xsl:choose>
3142 <xsl:when
3143 test="$string = ''">
3144 <!-- Empty strings need no output -->
3145 </xsl:when>
3146 <xsl:when
3147 test="$normalized = ''">
3148 <!-- Only white-space in string; output a single space here -->
3149 &tSP;
3150 </xsl:when>
3151 <xsl:otherwise>
3152 <!-- Output leading white-space here -->
3153 <xsl:if
3154 test="normalize-space(substring($string, 1, 1)) = ''">
3155 &tSP;
3156 </xsl:if>
3157 <xsl:call-template
3158 name="u:indentFold">
3159 <xsl:with-param
3160 name="string"
3161 select="$normalized"/>
3162 <xsl:with-param
3163 name="indent"
3164 select="$indent"/>
3165 <xsl:with-param
3166 name="cursorColumn"
3167 select="string-length($indent) + string-length($prefix)"/>
3168 </xsl:call-template>
3169 <!-- Output trailing white-space here -->
3170 <xsl:if
3171 test="normalize-space(substring($string, string-length($string), 1)) = ''">
3172 &tSP;
3173 </xsl:if>
3174 </xsl:otherwise>
3175 </xsl:choose>
3176 </xsl:when>
3177 <xsl:otherwise>
3178 <xsl:value-of
3179 select="$string"/>
3180 </xsl:otherwise>
3181 </xsl:choose>
3182 &tEOL;
3183 </xsl:template>
3185 <!-- ******************************************************************** -->
3187 <!-- Indent a string with folding -->
3188 <xsl:template
3189 name="u:indentFold">
3190 <!-- Normalized string to output -->
3191 <xsl:param
3192 name="string"/>
3193 <!-- Indentation to use for a new line -->
3194 <xsl:param
3195 name="indent"/>
3196 <!-- Current output column -->
3197 <!-- TODO This is not a correct assumption for field definitions where
3198 the field name effectively determines the column of the first
3199 line -->
3200 <xsl:param
3201 name="cursorColumn"
3202 select="string-length($indent)"/>
3203 <!-- Do we start on a new (indented) line? -->
3204 <xsl:param
3205 name="isNewLine"
3206 select="true()"/>
3207 <xsl:variable
3208 name="firstWord">
3209 <xsl:choose>
3210 <!-- TODO Quoted spaces must not end a word -->
3211 <xsl:when
3212 test="contains($string, ' ')">
3213 <xsl:value-of
3214 select="substring-before($string, ' ')"/>
3215 </xsl:when>
3216 <xsl:otherwise>
3217 <xsl:value-of
3218 select="$string"/>
3219 </xsl:otherwise>
3220 </xsl:choose>
3221 </xsl:variable>
3222 <xsl:variable
3223 name="rest"
3224 select="substring-after($string, ' ')"/>
3225 <xsl:choose>
3226 <xsl:when
3227 test="$string = ''"/>
3228 <xsl:when
3229 test="$isNewLine">
3230 <!-- Output at least first word -->
3231 <xsl:value-of
3232 select="$firstWord"/>
3233 <xsl:call-template
3234 name="u:indentFold">
3235 <xsl:with-param
3236 name="string"
3237 select="$rest"/>
3238 <xsl:with-param
3239 name="indent"
3240 select="$indent"/>
3241 <xsl:with-param
3242 name="cursorColumn"
3243 select="$cursorColumn + string-length($firstWord)"/>
3244 <xsl:with-param
3245 name="isNewLine"
3246 select="false()"/>
3247 </xsl:call-template>
3248 </xsl:when>
3249 <xsl:when
3250 test="$cursorColumn + 1 + string-length($firstWord) &gt; $fold">
3251 <!-- Line would get too long; start new line, indent and continue -->
3252 &tEOL;
3253 <xsl:value-of
3254 select="$indent"/>
3255 <xsl:call-template
3256 name="u:indentFold">
3257 <xsl:with-param
3258 name="string"
3259 select="$string"/>
3260 <xsl:with-param
3261 name="indent"
3262 select="$indent"/>
3263 <xsl:with-param
3264 name="cursorColumn"
3265 select="string-length($indent)"/>
3266 <xsl:with-param
3267 name="isNewLine"
3268 select="true()"/>
3269 </xsl:call-template>
3270 </xsl:when>
3271 <xsl:otherwise>
3272 <!-- In a line and first word fits; separate and add word -->
3273 &tSP;
3274 <xsl:value-of
3275 select="$firstWord"/>
3276 <xsl:call-template
3277 name="u:indentFold">
3278 <xsl:with-param
3279 name="string"
3280 select="$rest"/>
3281 <xsl:with-param
3282 name="indent"
3283 select="$indent"/>
3284 <xsl:with-param
3285 name="cursorColumn"
3286 select="$cursorColumn + 1 + string-length($firstWord)"/>
3287 <xsl:with-param
3288 name="isNewLine"
3289 select="false()"/>
3290 </xsl:call-template>
3291 </xsl:otherwise>
3292 </xsl:choose>
3293 </xsl:template>
3295 <!-- ******************************************************************** -->
3297 <!-- Output attributes of the current element as a field list -->
3298 <xsl:template
3299 name="u:params">
3300 <xsl:param
3301 name="params"
3302 select="@*"/>
3303 <!-- Ancestors are needed for determining indentation; caller may give
3304 them -->
3305 <xsl:param
3306 name="ancestors"
3307 select="ancestor-or-self::*"/>
3308 <xsl:for-each
3309 select="$params">
3310 <!-- Skip URIs based on parent -->
3311 <xsl:if
3312 test="name() != 'uri' and name() != 'xml:space'">
3313 <xsl:call-template
3314 name="u:param">
3315 <xsl:with-param
3316 name="ancestors"
3317 select="$ancestors"/>
3318 </xsl:call-template>
3319 </xsl:if>
3320 </xsl:for-each>
3321 </xsl:template>
3323 <!-- Output one attribute of the current element as a field list -->
3324 <xsl:template
3325 name="u:param">
3326 <xsl:param
3327 name="name"
3328 select="name()"/>
3329 <xsl:param
3330 name="value"
3331 select="."/>
3332 <!-- Ancestors are needed for determining indentation; caller may give
3333 them -->
3334 <xsl:param
3335 name="ancestors"
3336 select="ancestor::*"/>
3337 <xsl:call-template
3338 name="u:indent">
3339 <xsl:with-param
3340 name="ancestors"
3341 select="$ancestors"/>
3342 </xsl:call-template>
3343 <xsl:text>:</xsl:text>
3344 <xsl:choose>
3345 <xsl:when
3346 test="$name = 'classes'">
3347 <xsl:text>class</xsl:text>
3348 </xsl:when>
3349 <xsl:otherwise>
3350 <xsl:value-of
3351 select="$name"/>
3352 </xsl:otherwise>
3353 </xsl:choose>
3354 <xsl:text>:</xsl:text>
3355 <xsl:if
3356 test="$value">
3357 <xsl:text> </xsl:text>
3358 <xsl:value-of
3359 select="$value"/>
3360 </xsl:if>
3361 &tEOL;
3362 </xsl:template>
3364 <!-- ******************************************************************** -->
3366 <!-- Output `\' or `\ ' before some inline element if necessary -->
3367 <xsl:template
3368 name="u:bkslshEscPre">
3369 <!-- Get the sibling node directly before the current element -->
3370 <xsl:variable
3371 name="before"
3372 select="preceding-sibling::node()[1]"/>
3373 <xsl:choose>
3374 <!-- No sibling before this node -->
3375 <xsl:when
3376 test="not($before)"/>
3377 <!-- Element directly before this - must be another inline element -->
3378 <xsl:when
3379 test="name($before)">
3380 <!-- So separate it by a quoted space -->
3381 <xsl:text>\ </xsl:text>
3382 </xsl:when>
3383 <!-- Node directly before this is text - check it -->
3384 <xsl:when
3385 test="not(contains(concat($apos, ' &#xA;&#x9;&#xD;&quot;([{&lt;-/:'), substring($before, string-length($before), 1)))">
3386 <!-- Does not end in one of the allowed characters so separate it -->
3387 <xsl:text>\ </xsl:text>
3388 </xsl:when>
3389 </xsl:choose>
3390 </xsl:template>
3392 <!-- Output `\' after some inline element if necessary -->
3393 <xsl:template
3394 name="u:bkslshEscSuf">
3395 <!-- Get the sibling node directly after the current element -->
3396 <xsl:variable
3397 name="after"
3398 select="following-sibling::node()[1]"/>
3399 <xsl:choose>
3400 <!-- No sibling after this node -->
3401 <xsl:when
3402 test="not($after)"/>
3403 <!-- Element directly after this - must be another inline element
3404 handling itself -->
3405 <xsl:when
3406 test="name($after)"/>
3407 <!-- Node directly after this is text - check it -->
3408 <xsl:when
3409 test="not(contains(concat($apos, ' &#xA;&#x9;&#xD;&quot;)]}&gt;-/:.,;!?\'), substring($after, 1, 1)))">
3410 <!-- Does not start with one of the allowed characters so separate
3411 it -->
3412 <xsl:text>\</xsl:text>
3413 </xsl:when>
3414 </xsl:choose>
3415 </xsl:template>
3417 <!-- ******************************************************************** -->
3419 <xsl:template
3420 name="u:notSupported">
3421 <xsl:call-template
3422 name="u:BandI"/>
3423 <xsl:text>######## NOT SUPPORTED: `</xsl:text>
3424 <xsl:value-of
3425 select="name(.)"/>
3426 <xsl:text>' ########</xsl:text>
3427 &tEOL;
3428 </xsl:template>
3430 <!-- ******************************************************************** -->
3432 <xsl:template
3433 name="u:overline">
3434 <!-- Length of the rendered(!) text -->
3435 <xsl:param
3436 name="length"/>
3437 <!-- Depth 1 and 2 are document title and subtitle while depths
3438 greater than 2 are normal section titles -->
3439 <xsl:param
3440 name="depth"/>
3441 <!-- Test whether a overline is wanted at all -->
3442 <xsl:if
3443 test="substring($adornment, 2 * ($depth - 1) + 1, 1) = 'o'">
3444 <xsl:value-of
3445 select="str:padding($length, substring($adornment, 2 * ($depth - 1) + 2, 1))"/>
3446 &tEOL;
3447 </xsl:if>
3448 </xsl:template>
3450 <xsl:template
3451 name="u:underline">
3452 <!-- Length of the rendered(!) text -->
3453 <xsl:param
3454 name="length"/>
3455 <!-- Depth 1 and 2 are document title and subtitle while depths
3456 greater than 2 are normal section titles -->
3457 <xsl:param
3458 name="depth"/>
3459 <xsl:value-of
3460 select="str:padding($length, substring($adornment, 2 * ($depth - 1) + 2, 1))"/>
3461 &tEOL;
3462 </xsl:template>
3464 <!-- ******************************************************************** -->
3466 <!-- Output a non-standalone reference or target -->
3467 <xsl:template
3468 name="u:inlineReference">
3469 <xsl:param
3470 name="anonymous"
3471 select="false()"/>
3472 <xsl:param
3473 name="embedded"
3474 select="false()"/>
3475 <!-- Is this a target instead of a reference? -->
3476 <xsl:param
3477 name="isTarget"
3478 select="false()"/>
3479 <xsl:param
3480 name="text"
3481 select="node()"/>
3482 <xsl:call-template
3483 name="u:bkslshEscPre"/>
3484 <!-- Delimiter only if link contains other than alphanumerics -->
3485 <xsl:variable
3486 name="delimiter">
3487 <xsl:if
3488 test="* or translate($text, '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', '') or $embedded">
3489 <xsl:text>`</xsl:text>
3490 </xsl:if>
3491 </xsl:variable>
3492 <xsl:if
3493 test="$isTarget">
3494 <xsl:text>_</xsl:text>
3495 </xsl:if>
3496 <xsl:value-of
3497 select="$delimiter"/>
3498 <xsl:apply-templates
3499 select="$text"/>
3500 <xsl:if
3501 test="$embedded">
3502 <xsl:text> &lt;</xsl:text>
3503 <xsl:value-of
3504 select="@refuri"/>
3505 <xsl:text>&gt;</xsl:text>
3506 </xsl:if>
3507 <xsl:value-of
3508 select="$delimiter"/>
3509 <xsl:if
3510 test="not($isTarget)">
3511 <xsl:text>_</xsl:text>
3512 <xsl:if
3513 test="$anonymous">
3514 <xsl:text>_</xsl:text>
3515 </xsl:if>
3516 </xsl:if>
3517 <xsl:call-template
3518 name="u:bkslshEscSuf"/>
3519 </xsl:template>
3521 <!-- ******************************************************************** -->
3523 <!-- Output a class directive for the directly following element. -->
3524 <!-- TODO A class directive can also be used as a container putting the
3525 respective attribute to its content; however, this is not
3526 reflected in XML - you'd need to check a sequence of elements
3527 whether they all have the same attribute; furthermore class
3528 settings for block quotes needs to be treated special -->
3529 <xsl:template
3530 name="u:outputClass">
3531 <!-- Blank line already output? -->
3532 <xsl:param
3533 name="alreadyBlanked"
3534 select="false()"/>
3535 <!-- Indentation already output? -->
3536 <xsl:param
3537 name="alreadyIndented"
3538 select="false()"/>
3539 <!-- Add a blank line after class directive? -->
3540 <xsl:param
3541 name="blankAfter"
3542 select="false()"/>
3543 <xsl:if
3544 test="@classes">
3545 <xsl:if
3546 test="not($alreadyBlanked)">
3547 <xsl:call-template
3548 name="u:blank"/>
3549 </xsl:if>
3550 <xsl:if
3551 test="not($alreadyIndented)">
3552 <xsl:call-template
3553 name="u:indent"/>
3554 </xsl:if>
3555 <xsl:text>.. class:: </xsl:text>
3556 <xsl:value-of
3557 select="@classes"/>
3558 &tEOL;
3559 <xsl:if
3560 test="$blankAfter">
3561 &tCR;
3562 </xsl:if>
3563 </xsl:if>
3564 </xsl:template>
3566 <!-- ******************************************************************** -->
3568 <!-- Output a names attribute at index considering quoted spaces. -->
3569 <xsl:template
3570 name="u:outputNames">
3571 <!-- Blank line already output? -->
3572 <xsl:param
3573 name="names"
3574 select="@names"/>
3575 <xsl:param
3576 name="index"
3577 select="0"/>
3578 <xsl:value-of
3579 select="str:replace(str:tokenize(normalize-space(str:replace($names, '\ ', '|')))[position() = $index + 1], '|', ' ')"/>
3580 </xsl:template>
3582 <!-- ******************************************************************** -->
3584 <!-- Output a names attribute for a refid. -->
3585 <xsl:template
3586 name="u:outputNamesRefid">
3587 <xsl:param
3588 name="refid"
3589 select="@refid"/>
3590 <!-- Determine the elements which is referred -->
3591 <xsl:variable
3592 name="refElem"
3593 select="//*[@ids and math:max(dyn:map(str:tokenize(normalize-space(@ids)), 'number($refid = .)')) > 0]"/>
3594 <xsl:call-template
3595 name="u:outputNames">
3596 <xsl:with-param
3597 name="names"
3598 select="$refElem/@names"/>
3599 <xsl:with-param
3600 name="index"
3601 select="math:max(dyn:map(str:tokenize(normalize-space($refElem/@ids)), 'number($refid = .) * position() - 1'))"/>
3602 </xsl:call-template>
3603 </xsl:template>
3605 <!-- ******************************************************************** -->
3606 <!-- ******************************************************************** -->
3608 <!-- Report unknown tags -->
3609 <xsl:template
3610 match="*">
3611 <xsl:message>
3612 <xsl:text>`</xsl:text>
3613 <xsl:value-of
3614 select="name(.)"/>
3615 <xsl:text>' encountered</xsl:text>
3616 <xsl:if
3617 test="parent::*">
3618 <xsl:text> in `</xsl:text>
3619 <xsl:value-of
3620 select="name(parent::*)"/>
3621 <xsl:text>'</xsl:text>
3622 </xsl:if>
3623 <xsl:text>, but no template matches.</xsl:text>
3624 </xsl:message>
3625 </xsl:template>
3627 </xsl:stylesheet>
3629 <!-- ********************************************************************** -->
3630 <!-- ********************************************************************** -->
3631 <!-- ********************************************************************** -->
3632 <!-- POD manual page
3634 =head1 NAME
3636 xml2rst-nopy.xsl - An XSLT script to convert Docutils XML to reStructuredText
3638 =head1 SYNOPSIS
3640 xsltproc docutils.xml xml2rst-nopy.xsl
3642 =head1 NOTE
3644 Today B<xml2rst-nopy.xsl> is not the recommended way to use
3645 B<xml2rst>. The preferred way is to install B<lxml> and use
3646 B<xml2rst.py> instead.
3648 =head1 DESCRIPTION
3650 B<xml2rst-nopy.xsl> is an XSLT script to convert Docutils XML to
3651 reStructuredText. You can use your favorite XSLT processor supporting
3652 EXSLT (e.g. xsltproc from the Gnome project) to generate
3653 reStructuredText from the Docutils intermediate XML representation.
3654 Its main use is to generate reStructuredText from some other format
3655 where a converter to Docutils XML already exists.
3657 =head2 Options
3659 The following options are supported. They are XSLT parameters for the
3660 whole script and must be given to the XSLT processor by the respective
3661 option (xsltproc: B<- -param> or B<- -stringparam>).
3663 =over 4
3665 =item adornment
3667 Configures title markup to use so different styles can be requested
3668 easily.
3670 The value of the parameter must be a string made up of a sequence of
3671 character pairs. The first character of a pair is C<o> (overline) or
3672 C<u> (underline) and the second character is the character to use for
3673 the markup.
3675 The first and the second character pair is used for document title and
3676 subtitle, the following pairs are used for section titles where the
3677 third pair is used for the top level section title.
3679 Defaults to C<o=o-u=u-u~u:u.u`>.
3681 =item fold
3683 Configures whether long text lines in paragraphs should be folded and
3684 to which length. This option is for input not coming from reST which
3685 may have no internal line feeds in plain text strings.
3687 If folding is enabled text strings not in a line feed preserving
3688 context are first white-space normalized and then broken according to
3689 the folding rules. Folding rules put out the first word and continue
3690 to do so with the following words unless the next word would cross
3691 the folding boundary. Words are delimited by white-space.
3693 Defaults to C<0>, i.e. no folding.
3695 =back
3697 =head2 Unsupported features
3699 It is generally not possible to create an exact reproduction of an
3700 original reStructuredText source from an intermediate XML file. The
3701 reason is that Docutils transports pretty much but not all information
3702 of the original source into the XML. Also the sequence is changed
3703 sometimes.
3705 However, the coverage of Docutils features of B<xml2rst-nopy.xsl> is
3706 pretty good. A few minor features are not supported:
3708 =over 4
3710 =item * Fully minimized style for literal blocks
3712 =item * Substitution references for C<replace::> substitutions
3714 =item * Counting roman numbers in enumerated lists
3716 =item * Special table types like C<list-table::> and C<csv-table::>
3718 =item * Custom role definitions
3720 =back
3722 =head1 INSTALLATION
3724 Installation is not necessary. Just use the file as downloaded with
3725 your favorite XSLT processor supporting EXSLT. For instance you can
3726 use B<xsltproc> from the Gnome project.
3728 =head1 AUTHOR
3730 Stefan Merten <smerten@oekonux.de> based on works by David Priest.
3732 =head1 LICENSE
3734 This program is licensed under the terms of the GPL. See
3736 http://www.gnu.org/licenses/gpl.txt
3738 =head1 AVAILABILTY
3742 http://www.merten-home.de/FreeSoftware/xml2rst/
3744 =cut