XSLT Explorer: docbook.xsl

48 imports, 653 templates, 203 functions, 88 variables, 142 params, 4 FIXME: comments

List of Imports
List of Templates
tp:link
tp:xref
t:biblioentry
tp:out-of-line-xlink
tp:simple-xlink
t:xlink
tp:orderedlist-properties
t:person-name
t:person-name-family-given
t:person-name-first-last
t:person-name-last-first
t:person-name-list
tp:toc
t:chunk-cleanup
t:chunk-output
t:docbook
t:postprocess
t:preprocess
t:process
t:table-footnotes
t:imagemap
tp:process-object
tp:viewport
tp:docbook
tp:filter-callouts
tp:verbatim
tp:verbatim-array
tp:verbatim-lines
tp:verbatim-plain
tp:verbatim-raw
t:generate-index
t:index-zone-reference
tp:cals-colspec
tp:cell
tp:group-or-arg
t:bottom-nav
t:chunk-footnotes
t:top-nav
t:inline
List of Functions
fp:syntax-highlight()
fp:syntax-highlight()
f:syntax-highlight()
f:syntax-highlight()
f:syntax-highlight()
fp:construct-templates()
fp:pick-template()
f:template()
fp:patch-toc-href()
f:gentext()
f:gentext()
f:language()
fp:existing-localization()
fp:gentext()
fp:load-locales()
fp:localization()
fp:localization()
fp:check-profile()
fp:dynamic-include()
fp:dynamic-profile-tokens()
fp:profile-suppress()
fp:profile-tokens()
fp:document-title-properties()
fp:title-properties()
f:attributes()
f:attributes()
f:check-gentext()
f:date-format()
f:generate-id()
f:gentext-letters()
f:gentext-letters-for-language()
f:href()
f:id()
f:intra-number-separator()
f:is-true()
f:l10n-language()
f:label-separator()
f:number-separator()
f:orderedlist-item-number()
f:orderedlist-item-numeration()
f:orderedlist-startingnumber()
f:pi()
f:pi()
f:pi-attributes()
f:post-label-punctuation()
f:post-label-punctuation()
fp:label-format()
fp:lookup-string()
fp:parse-key-value-pairs()
fp:parse-key-value-pairs()
fp:pi-attributes()
fp:pi-from-list()
fp:pi-pi-attributes()
fp:properties()
fp:replace-element()
fp:replace-element()
fp:separator()
f:refsection()
f:section()
f:section-depth()
f:spaces()
f:step-number()
f:step-numeration()
f:target()
f:tokenize-on-char()
fp:find-xlink-nodes()
fp:pmuj()
fp:pmuj-enabled()
fp:xlink-sources()
fp:xlink-targets()
fp:xlink-xmlns-scheme()
fp:xlink-xpath-scheme()
f:xlink-style()
f:xpointer-idref()
fp:estimated-term-length()
fp:select-vert-members()
fp:collapse-years()
fp:collapse-years()
f:generate-id()
f:id()
f:absolute-length()
f:empty-length()
f:equal-lengths()
f:is-empty-length()
f:length-string()
f:length-units()
f:make-length()
f:make-length()
f:make-length()
f:parse-length()
f:relative-length()
fp:footnote-mark()
fp:footnote-number()
f:css-length()
f:css-property()
f:object-align()
f:object-contentheight()
f:object-contentwidth()
f:object-height()
f:object-properties()
f:object-scale()
f:object-scalefit()
f:object-valign()
f:object-width()
f:resolve-object-uri()
f:select-mediaobject()
f:select-mediaobject-data()
f:select-mediaobject-data()
f:highlight-verbatim()
fp:array-append()
fp:array-pad()
fp:balance-line()
fp:balance-markup()
fp:balance-markup()
fp:contains()
fp:following()
fp:inject()
fp:inject-array()
fp:inject-into-chars()
fp:inject-into-line()
fp:injection-array()
fp:line-to-chars()
fp:make-lines()
fp:make-lines()
fp:open()
fp:trim-trailing-blank-lines()
fp:unflatten()
fp:unflatten()
fp:unflatten-line()
fp:unflatten-line()
fp:up-to()
fp:validate-injection-array()
fp:verbatim-properties()
f:verbatim-highlight()
f:verbatim-numbered()
f:verbatim-style()
f:verbatim-trim-trailing()
fp:crossref-properties()
fp:document-crossref-properties()
fp:group-index()
fp:group-label()
fp:nearest-section()
fp:nearest-section-id()
fp:primary()
fp:scope()
fp:secondary()
fp:tertiary()
f:cals-colsep()
f:cals-rowsep()
fp:align-char-pad()
fcals:align()
fcals:align-colspec()
fcals:align-spanspec()
fcals:cell()
fcals:cell-decoration()
fcals:cell-overhang()
fcals:char()
fcals:char-colspec()
fcals:char-spanspec()
fcals:colsep()
fcals:colsep-colspec()
fcals:colsep-spanspec()
fcals:colspan()
fcals:colspec()
fcals:colspec-column-number()
fcals:colspec-for-column()
fcals:column-number()
fcals:decrement-overhang()
fcals:empty-cell-colsep()
fcals:empty-cell-rowsep()
fcals:next-empty-cell()
fcals:overhang()
fcals:overhang-into-row()
fcals:rowsep()
fcals:rowsep-colspec()
fcals:rowsep-spanspec()
fcals:rowspan()
fcals:spanspec()
fcals:table-columns()
fcals:tgroup()
fcals:valign()
fcals:zeros()
fp:colspec-for-colnum()
fp:only-initial-pis()
f:chunk()
f:chunk-filename()
fp:chunk-exclude()
fp:chunk-include()
fp:chunk-navigation()
fp:matches-expr()
fp:root-base-uri()
fp:trim-common-parts()
fp:trim-common-prefix()
f:chunk-title()
fp:chunk-output-filename()
fp:footnote-mark()
fp:footnote-number()
fp:navigable()
fp:relative-link()
fp:relative-uri()
fp:root-base-uri()
fp:trim-common-parts()
fp:trim-common-prefix()

docbook.xsl

2 imports

main.xsl

45 imports

param.xsl

1 variable, 139 params (2 used only in one other module)

Instructions
Param $debug as xs:string [static]
Param $xspec as xs:string
Param $verbatim-plain-style as xs:string
Param $verbatim-trim-trailing-blank-lines
Param $verbatim-callouts as xs:string
Param $callout-default-column
Param $default-length-magnitude
Param $table-accessibility as xs:string*
Param $mediaobject-accessibility as xs:string*
Param $align-char-default as xs:string
Param $mediaobject-exclude-extensions
Param $mediaobject-input-base-uri as xs:string
Param $mediaobject-output-base-uri as xs:string
Param $default-personal-name-style
Param $productionset-lhs-rhs-separator
Param $funcsynopsis-default-style
Param $funcsynopsis-table-threshold
Param $classsynopsis-indent
Param $copyright-collapse-years
Param $division-numbers-inherit as xs:string
Param $component-numbers-inherit as xs:string
Param $section-numbers as xs:string
Param $section-numbers-inherit
Param $number-single-appendix
Param $generate-toc as xs:string
Param $generate-nested-toc as xs:string
Param $vp:section-toc-depth as xs:integer
Param $revhistory-style
Param $segmentedlist-style
Param $lists-of-figures as xs:string
Param $lists-of-tables as xs:string
Param $lists-of-examples as xs:string
Param $lists-of-equations as xs:string
Param $lists-of-procedures as xs:string
Param $variablelist-termlength-threshold
Param $procedure-step-numeration
Param $refentry-generate-name
Param $refentry-generate-title
Param $index-show-entries
Param $glossary-sort-entries
Param $default-float-style
Param $sidebar-as-aside
Param $verbatim-syntax-highlight-css
Param $persistent-toc-css
Param $oxy-markup-css
Param $annotations-js
Param $persistent-toc-js
Param $mathml-js
Param $control-js as xs:string
Param $chunk-nav as xs:string
Param $chunk-nav-js as xs:string
Param $chunk-include as xs:string*
Param $chunk-exclude as xs:string*
Param $annotation-collection as xs:string
Param $glossary-collection as xs:string
Param $bibliography-collection as xs:string
Param $docbook-transclusion
Param $transclusion-prefix-separator
Param $local-conventions as xs:string?
Param $relax-ng-grammar as xs:string?
Param $allow-eval as xs:string
Param $dynamic-profiles as xs:string
Param $default-theme as xs:string
Param $generate-html-page as xs:string
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:db="http://docbook.org/ns/docbook"
                xmlns:ext="http://docbook.org/extensions/xslt"
                xmlns:f="http://docbook.org/ns/docbook/functions"
                xmlns:m="http://docbook.org/ns/docbook/modes"
                xmlns:v="http://docbook.org/ns/docbook/variables"
                xmlns:vp="http://docbook.org/ns/docbook/variables/private"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns="http://www.w3.org/1999/xhtml"
                default-mode="m:docbook"
                exclude-result-prefixes="db ext f m v vp xs"
                version="3.0">

<!-- Note: Some of these parameters are initialized using content
     instead of a select attribute in order to make the reference page
     in the Guide work better. -->

<!-- Many of these parameters are shadowed by variables (see
     variable.xsl) for use in the stylesheets. Often, they're defined
     as strings here and as more useful data types in the variables. -->

<!-- 'pipeline', 'objects', 'templates', 'template-matches', 'tables',
     'callouts', 'verbatim', 'render-verbatim', 'profile', 'properties',
     'xlink' 'chunks', 'chunk-cleanup', 'intra-chunk-refs', 'intra-chunk-links',
     'structure', 'mediaobject-uris', 'cals-align-char', 'image-properties',
     'db4to5' 'profile-suppress', 'dynamic-profile', 'dynamic-profile-suppress' -->
<xsl:param name="debug" static="yes" as="xs:string"
           select="''"/>

<!-- This parameter is only true when the stylesheets are being run by XSpec -->
<xsl:param name="xspec" as="xs:string" select="'false'"/>

<xsl:param name="gentext-language" select="()"/>

<xsl:param name="verbatim-line-style"
           select="'programlisting programlistingco
                    screen screenco synopsis'"/>

<xsl:param name="verbatim-plain-style" as="xs:string"
           select="'address literallayout funcsynopsisinfo classsynopsisinfo'"/>

<xsl:param name="verbatim-space" select="' '"/>

<xsl:param name="verbatim-trim-trailing-blank-lines" select="'true'"/>
<xsl:param name="verbatim-style-default" select="'lines'"/>

<!-- the parameter is a list of names so it's easier to specify
     from the command line or through a parameter API. -->
<xsl:param name="verbatim-numbered-elements"
           select="'programlisting programlistingco'"/>

<xsl:param name="verbatim-number-minlines" select="'5'"/>

<xsl:param name="verbatim-number-every-nth" select="5"/>

<xsl:param name="verbatim-number-first-line" select="'true'"/>

<!-- 'linecolumn', 'lines', 'lineranges-first', 'lineranges-all' -->
<xsl:param name="verbatim-callouts" as="xs:string"
           select="'linecolumn lines lineranges-first'"/>

<xsl:param name="verbatim-syntax-highlighter" as="xs:string" select="'pygments'"/>
<xsl:param name="verbatim-syntax-highlight-languages"
           select="'python perl html xml xslt xquery javascript json'"/>

<xsl:param name="callout-default-column" select="60"/>

<xsl:param name="pixels-per-inch" select="96.0"/>
<xsl:param name="nominal-page-width" select="'6in'"/>
<xsl:param name="default-length-magnitude" select="25.0"/>
<xsl:param name="default-length-unit" select="'%'"/>

<xsl:param name="table-accessibility" as="xs:string*"
           select="('summary', 'details')"/>
<xsl:param name="mediaobject-accessibility" as="xs:string*"
           select="('summary', 'details')"/>

<xsl:param name="align-char-default" as="xs:string" select="'.'"/>
<xsl:param name="align-char-width" select="2"/>
<xsl:param name="align-char-pad" select="'&#x2002;'"/> <!-- en space -->

<xsl:param name="mediaobject-exclude-extensions"
           select="('.eps', '.ps', '.pdf')"/>

<xsl:param name="mediaobject-input-base-uri" as="xs:string">
  <xsl:sequence use-when="function-available('ext:cwd')"
                select="resolve-uri(ext:cwd(), static-base-uri())"/>
  <xsl:sequence use-when="not(function-available('ext:cwd'))"
                select="''"/>
</xsl:param>

<xsl:param name="mediaobject-output-base-uri" as="xs:string"
           select="''"/>

<xsl:param name="image-ignore-scaling" as="xs:boolean" select="false()"/>
<xsl:param name="image-property-warning" select="true()"/>
<xsl:param name="image-nominal-width" select="$nominal-page-width"/>
<xsl:param name="image-nominal-height" select="'4in'"/>

<xsl:param name="default-personal-name-style" select="'first-last'"/>
<xsl:param name="othername-in-middle" select="'true'"/>

<xsl:param name="productionset-lhs-rhs-separator" select="':='"/>

<xsl:param name="date-date-format"
           select="'[D01] [MNn,*-3] [Y0001]'"/>
<xsl:param name="date-dateTime-format"
           select="'[H01]:[m01] [D01] [MNn,*-3] [Y0001]'"/>

<xsl:param name="qandaset-default-toc" select="'true'"/>
<xsl:param name="qandadiv-default-toc" select="$qandaset-default-toc"/>
<xsl:param name="qandaset-default-label" select="'number'"/>

<xsl:param name="funcsynopsis-default-style" select="'kr'"/>
<xsl:param name="funcsynopsis-table-threshold" select="40"/>
<xsl:param name="funcsynopsis-trailing-punctuation" select="';'"/>

<xsl:param name="classsynopsis-indent" select="'  '"/>

<xsl:param name="copyright-collapse-years" select="true()"/>
<xsl:param name="copyright-year-separator" select="', '"/>
<xsl:param name="copyright-year-range-separator" select="'–'"/>

<xsl:param name="division-numbers-inherit" as="xs:string" select="'false'"/>
<xsl:param name="component-numbers-inherit" as="xs:string" select="'false'"/>
<xsl:param name="section-numbers" as="xs:string" select="'1'"/>
<xsl:param name="section-numbers-inherit" select="'true'"/>

<xsl:param name="number-single-appendix" select="'true'"/>

<xsl:param name="generate-toc" as="xs:string">
  (empty(parent::*) and self::db:article)
  or self::db:set or self::db:book
  or self::db:part or self::db:reference
</xsl:param>

<xsl:param name="generate-nested-toc" as="xs:string">
  not(f:section(.))
  or (f:section(.) and f:section-depth(.) le $vp:section-toc-depth)
</xsl:param>

<xsl:param name="section-toc-depth" select="'unbounded'"/>
<xsl:param name="vp:section-toc-depth" as="xs:integer">
  <xsl:choose>
    <xsl:when test="$section-toc-depth instance of xs:integer">
      <xsl:sequence select="max((0, $section-toc-depth))"/>
    </xsl:when>
    <xsl:when test="$section-toc-depth castable as xs:integer">
      <xsl:sequence select="max((0, xs:integer($section-toc-depth)))"/>
    </xsl:when>
    <xsl:when test="string($section-toc-depth) = 'unbounded'">
      <xsl:sequence select="-1"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:sequence select="0"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:param>

<xsl:param name="annotation-style" select="'javascript'"/>
<xsl:param name="annotation-mark"><sup>⌖</sup></xsl:param>

<xsl:param name="xlink-style" select="'document'"/>
<xsl:param name="xlink-style-default" select="'inline'"/>
<xsl:param name="xlink-icon-open" select="()"/>
<xsl:param name="xlink-icon-closed" select="()"/>

<!-- 'list' or 'table' -->
<xsl:param name="revhistory-style" select="'table'"/>

<xsl:param name="segmentedlist-style" select="'table'"/>

<xsl:param name="formal-object-title-placement"
           select="'after formalgroup:before'"/>

<xsl:param name="lists-of-figures" as="xs:string" select="'true'"/>
<xsl:param name="lists-of-tables" as="xs:string" select="'true'"/>
<xsl:param name="lists-of-examples" as="xs:string" select="'true'"/>
<xsl:param name="lists-of-equations" as="xs:string" select="'false'"/>
<xsl:param name="lists-of-procedures" as="xs:string" select="'false'"/>

<xsl:param name="variablelist-termlength-threshold" select="20"/>
<xsl:param name="procedure-step-numeration" select="'1aiAI'"/>
<xsl:param name="orderedlist-item-numeration" select="'1aiAI'"/>

<xsl:param name="refentry-generate-name" select="true()"/>
<xsl:param name="refentry-generate-title" select="true()"/>
<xsl:param name="annotate-toc" select="'true'"/>

<xsl:param name="callout-unicode-start" select="9311"/>

<xsl:param name="index-show-entries" select="()"/> <!-- '🔖' -->
<xsl:param name="generate-index" select="'true'"/>
<xsl:param name="index-on-role" select="'true'"/>
<xsl:param name="index-on-type" select="'true'"/>

<xsl:param name="glossary-sort-entries" select="true()"/>

<xsl:param name="sort-collation"
           select="'http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive'"/>

<xsl:param name="default-float-style" select="'left'"/>

<xsl:param name="show-remarks" select="'false'"/>
<xsl:param name="sidebar-as-aside" select="false()"/>

<xsl:param name="resource-base-uri" select="'./'"/>

<xsl:param name="css-links" select="'css/docbook.css css/docbook-screen.css'"/>
<xsl:param name="verbatim-syntax-highlight-css" select="'css/pygments.css'"/>
<xsl:param name="persistent-toc-css"
           select="'css/docbook-toc.css'"/>
<xsl:param name="oxy-markup-css"
           select="'css/oxy-markup.css'"/>
<xsl:param name="oxy-markup" select="'false'"/>

<xsl:param name="annotations-js" select="'js/annotations.js'"/>
<xsl:param name="xlink-js" select="'js/xlink.js'"/>
<xsl:param name="persistent-toc-js" select="'js/persistent-toc.js'"/>
<xsl:param name="mathml-js"
           select="'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=MML_CHTML'"/>

<xsl:param name="control-js" as="xs:string" select="'js/controls.js'"/>
<xsl:param name="theme-picker" as="xs:string" select="'false'"/>

<xsl:param name="chunk" as="xs:string?" select="()"/>
<xsl:param name="chunk-nav" as="xs:string" select="'true'"/>
<xsl:param name="chunk-nav-js" as="xs:string" select="'js/chunk-nav.js'"/>

<xsl:variable name="v:chunk" as="xs:boolean"
              select="not(normalize-space($chunk) = '')"/>

<xsl:param name="chunk-output-base-uri" as="xs:string">
  <xsl:choose>
    <xsl:when test="not($v:chunk)">
      <!-- it doesn't actually matter -->
      <xsl:sequence select="''"/>
    </xsl:when>
    <xsl:when use-when="function-available('ext:cwd')"
              test="true()">
      <xsl:message select="'Default output base uri:',
                           resolve-uri(ext:cwd(), static-base-uri())"/>
      <xsl:sequence select="resolve-uri(ext:cwd(), static-base-uri())"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:message terminate="yes"
                   select="'You must specify the $chunk-output-base-uri'"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:param>

<xsl:param name="chunk-section-depth" select="1"/>

<!-- N.B. this can lead to confusing numeration if you have
     footnoterefs that cross chunk boundaries! -->
<xsl:param name="chunk-renumber-footnotes" select="'true'"/>

<xsl:param name="chunk-include" as="xs:string*"
           select="('parent::db:set',
                    'parent::db:book',
                    'parent::db:part',
                    'parent::db:reference',
                    'self::db:refentry',
                    'self::db:section',
                    'self::db:sect1')"/>

<xsl:param name="chunk-exclude" as="xs:string*"
           select="('self::db:partintro',
                    'self::*[ancestor::db:partintro]',
                    'self::db:annotation',
                    'self::db:section[not(preceding-sibling::db:section)]',
                    'self::db:sect1[not(preceding-sibling::db:sect1)]',
                    'self::db:toc')"/>

<xsl:param name="html-extension" select="'.html'"/>

<!--
<xsl:param name="footnote-numeration" select="('*', '**', '†','‡', '§', '1')"/>
-->
<xsl:param name="footnote-numeration" select="('1')"/>
<xsl:param name="table-footnote-numeration" select="('a')"/>

<xsl:param name="persistent-toc" select="'false'"/>

<xsl:param name="profile-separator" select="';'"/>
<xsl:param name="profile-lang" select="''"/>
<xsl:param name="profile-revisionflag" select="''"/>
<xsl:param name="profile-role" select="''"/>
<xsl:param name="profile-arch" select="''"/>
<xsl:param name="profile-audience" select="''"/>
<xsl:param name="profile-condition" select="''"/>
<xsl:param name="profile-conformance" select="''"/>
<xsl:param name="profile-os" select="''"/>
<xsl:param name="profile-outputformat" select="''"/>
<xsl:param name="profile-revision" select="''"/>
<xsl:param name="profile-security" select="''"/>
<xsl:param name="profile-userlevel" select="''"/>
<xsl:param name="profile-vendor" select="''"/>
<xsl:param name="profile-wordsize" select="''"/>

<xsl:param name="annotation-collection" as="xs:string" select="''"/>
<xsl:param name="glossary-collection" as="xs:string" select="''"/>
<xsl:param name="bibliography-collection" as="xs:string" select="''"/>
<xsl:param name="olink-databases" as="xs:string" select="''"/>

<xsl:param name="docbook-transclusion" select="'false'"/>
<xsl:param name="transclusion-prefix-separator" select="'---'"/>

<xsl:param name="local-conventions" as="xs:string?" select="()"/>
<xsl:param name="relax-ng-grammar" as="xs:string?" select="()"/>

<xsl:param name="allow-eval" as="xs:string" select="'false'"/>
<xsl:param name="dynamic-profiles" as="xs:string" select="'false'"/>
<xsl:param name="dynamic-profile-error" select="'ignore'"/>

<xsl:param name="experimental-pmuj" select="'false'"/>

<xsl:param name="default-theme" as="xs:string" select="''"/>

<xsl:param name="generate-html-page" as="xs:string" select="'true'"/>

</xsl:stylesheet>

parameter-maps.xsl

2 variables (1 unused, 1 used only in one other module)

Instructions
Variable $vp:static-parameters as map(xs:QName, item()*)
Uses: $debug
Unused
Variable $vp:dynamic-parameters as map(xs:QName, item()*)
Uses: $vp:section-toc-depth, $align-char-default, $align-char-pad, $align-char-width, $allow-eval, $annotate-toc, $annotation-collection, $annotation-mark, $annotation-style, $annotations-js, $bibliography-collection, $callout-default-column, $callout-unicode-start, $chunk, $chunk-exclude, $chunk-include, $chunk-nav, $chunk-nav-js, $chunk-output-base-uri, $chunk-renumber-footnotes, $chunk-section-depth, $classsynopsis-indent, $component-numbers-inherit, $control-js, $copyright-collapse-years, $copyright-year-range-separator, $copyright-year-separator, $css-links, $date-date-format, $date-dateTime-format, $default-float-style, $default-length-magnitude, $default-length-unit, $default-personal-name-style, $default-theme, $division-numbers-inherit, $docbook-transclusion, $dynamic-profile-error, $dynamic-profiles, $experimental-pmuj, $footnote-numeration, $formal-object-title-placement, $funcsynopsis-default-style, $funcsynopsis-table-threshold, $funcsynopsis-trailing-punctuation, $generate-html-page, $generate-index, $generate-nested-toc, $generate-toc, $gentext-language, $glossary-collection, $glossary-sort-entries, $html-extension, $image-ignore-scaling, $image-nominal-height, $image-nominal-width, $image-property-warning, $index-on-role, $index-on-type, $index-show-entries, $lists-of-equations, $lists-of-examples, $lists-of-figures, $lists-of-procedures, $lists-of-tables, $local-conventions, $mathml-js, $mediaobject-accessibility, $mediaobject-exclude-extensions, $mediaobject-input-base-uri, $mediaobject-output-base-uri, $nominal-page-width, $number-single-appendix, $olink-databases, $orderedlist-item-numeration, $othername-in-middle, $oxy-markup, $oxy-markup-css, $persistent-toc, $persistent-toc-css, $persistent-toc-js, $pixels-per-inch, $procedure-step-numeration, $productionset-lhs-rhs-separator, $profile-arch, $profile-audience, $profile-condition, $profile-conformance, $profile-lang, $profile-os, $profile-outputformat, $profile-revision, $profile-revisionflag, $profile-role, $profile-security, $profile-separator, $profile-userlevel, $profile-vendor, $profile-wordsize, $qandadiv-default-toc, $qandaset-default-label, $qandaset-default-toc, $refentry-generate-name, $refentry-generate-title, $relax-ng-grammar, $resource-base-uri, $revhistory-style, $section-numbers, $section-numbers-inherit, $section-toc-depth, $segmentedlist-style, $show-remarks, $sidebar-as-aside, $sort-collation, $table-accessibility, $table-footnote-numeration, $theme-picker, $transclusion-prefix-separator, $variablelist-termlength-threshold, $verbatim-callouts, $verbatim-line-style, $verbatim-number-every-nth, $verbatim-number-first-line, $verbatim-number-minlines, $verbatim-numbered-elements, $verbatim-plain-style, $verbatim-space, $verbatim-style-default, $verbatim-syntax-highlight-css, $verbatim-syntax-highlight-languages, $verbatim-syntax-highlighter, $verbatim-trim-trailing-blank-lines, $xlink-icon-closed, $xlink-icon-open, $xlink-js, $xlink-style, $xlink-style-default, $xspec
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:vp="http://docbook.org/ns/docbook/variables/private"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="3.0">
   <xsl:variable name="vp:static-parameters" as="map(xs:QName, item()*)">
      <xsl:map>
         <xsl:map-entry key="xs:QName('debug')" select="$debug"/>
      </xsl:map>
   </xsl:variable>
   <xsl:variable name="vp:dynamic-parameters" as="map(xs:QName, item()*)">
      <xsl:map>
         <xsl:map-entry key="xs:QName('xspec')" select="$xspec"/>
         <xsl:map-entry key="xs:QName('gentext-language')" select="$gentext-language"/>
         <xsl:map-entry key="xs:QName('verbatim-line-style')" select="$verbatim-line-style"/>
         <xsl:map-entry key="xs:QName('verbatim-plain-style')" select="$verbatim-plain-style"/>
         <xsl:map-entry key="xs:QName('verbatim-space')" select="$verbatim-space"/>
         <xsl:map-entry key="xs:QName('verbatim-trim-trailing-blank-lines')"
                        select="$verbatim-trim-trailing-blank-lines"/>
         <xsl:map-entry key="xs:QName('verbatim-style-default')"
                        select="$verbatim-style-default"/>
         <xsl:map-entry key="xs:QName('verbatim-numbered-elements')"
                        select="$verbatim-numbered-elements"/>
         <xsl:map-entry key="xs:QName('verbatim-number-minlines')"
                        select="$verbatim-number-minlines"/>
         <xsl:map-entry key="xs:QName('verbatim-number-every-nth')"
                        select="$verbatim-number-every-nth"/>
         <xsl:map-entry key="xs:QName('verbatim-number-first-line')"
                        select="$verbatim-number-first-line"/>
         <xsl:map-entry key="xs:QName('verbatim-callouts')" select="$verbatim-callouts"/>
         <xsl:map-entry key="xs:QName('verbatim-syntax-highlighter')"
                        select="$verbatim-syntax-highlighter"/>
         <xsl:map-entry key="xs:QName('verbatim-syntax-highlight-languages')"
                        select="$verbatim-syntax-highlight-languages"/>
         <xsl:map-entry key="xs:QName('callout-default-column')"
                        select="$callout-default-column"/>
         <xsl:map-entry key="xs:QName('pixels-per-inch')" select="$pixels-per-inch"/>
         <xsl:map-entry key="xs:QName('nominal-page-width')" select="$nominal-page-width"/>
         <xsl:map-entry key="xs:QName('default-length-magnitude')"
                        select="$default-length-magnitude"/>
         <xsl:map-entry key="xs:QName('default-length-unit')" select="$default-length-unit"/>
         <xsl:map-entry key="xs:QName('table-accessibility')" select="$table-accessibility"/>
         <xsl:map-entry key="xs:QName('mediaobject-accessibility')"
                        select="$mediaobject-accessibility"/>
         <xsl:map-entry key="xs:QName('align-char-default')" select="$align-char-default"/>
         <xsl:map-entry key="xs:QName('align-char-width')" select="$align-char-width"/>
         <xsl:map-entry key="xs:QName('align-char-pad')" select="$align-char-pad"/>
         <xsl:map-entry key="xs:QName('mediaobject-exclude-extensions')"
                        select="$mediaobject-exclude-extensions"/>
         <xsl:map-entry key="xs:QName('mediaobject-input-base-uri')"
                        select="$mediaobject-input-base-uri"/>
         <xsl:map-entry key="xs:QName('mediaobject-output-base-uri')"
                        select="$mediaobject-output-base-uri"/>
         <xsl:map-entry key="xs:QName('image-ignore-scaling')" select="$image-ignore-scaling"/>
         <xsl:map-entry key="xs:QName('image-property-warning')"
                        select="$image-property-warning"/>
         <xsl:map-entry key="xs:QName('image-nominal-width')" select="$image-nominal-width"/>
         <xsl:map-entry key="xs:QName('image-nominal-height')" select="$image-nominal-height"/>
         <xsl:map-entry key="xs:QName('default-personal-name-style')"
                        select="$default-personal-name-style"/>
         <xsl:map-entry key="xs:QName('othername-in-middle')" select="$othername-in-middle"/>
         <xsl:map-entry key="xs:QName('productionset-lhs-rhs-separator')"
                        select="$productionset-lhs-rhs-separator"/>
         <xsl:map-entry key="xs:QName('date-date-format')" select="$date-date-format"/>
         <xsl:map-entry key="xs:QName('date-dateTime-format')" select="$date-dateTime-format"/>
         <xsl:map-entry key="xs:QName('qandaset-default-toc')" select="$qandaset-default-toc"/>
         <xsl:map-entry key="xs:QName('qandadiv-default-toc')" select="$qandadiv-default-toc"/>
         <xsl:map-entry key="xs:QName('qandaset-default-label')"
                        select="$qandaset-default-label"/>
         <xsl:map-entry key="xs:QName('funcsynopsis-default-style')"
                        select="$funcsynopsis-default-style"/>
         <xsl:map-entry key="xs:QName('funcsynopsis-table-threshold')"
                        select="$funcsynopsis-table-threshold"/>
         <xsl:map-entry key="xs:QName('funcsynopsis-trailing-punctuation')"
                        select="$funcsynopsis-trailing-punctuation"/>
         <xsl:map-entry key="xs:QName('classsynopsis-indent')" select="$classsynopsis-indent"/>
         <xsl:map-entry key="xs:QName('copyright-collapse-years')"
                        select="$copyright-collapse-years"/>
         <xsl:map-entry key="xs:QName('copyright-year-separator')"
                        select="$copyright-year-separator"/>
         <xsl:map-entry key="xs:QName('copyright-year-range-separator')"
                        select="$copyright-year-range-separator"/>
         <xsl:map-entry key="xs:QName('division-numbers-inherit')"
                        select="$division-numbers-inherit"/>
         <xsl:map-entry key="xs:QName('component-numbers-inherit')"
                        select="$component-numbers-inherit"/>
         <xsl:map-entry key="xs:QName('section-numbers')" select="$section-numbers"/>
         <xsl:map-entry key="xs:QName('section-numbers-inherit')"
                        select="$section-numbers-inherit"/>
         <xsl:map-entry key="xs:QName('number-single-appendix')"
                        select="$number-single-appendix"/>
         <xsl:map-entry key="xs:QName('generate-toc')" select="$generate-toc"/>
         <xsl:map-entry key="xs:QName('generate-nested-toc')" select="$generate-nested-toc"/>
         <xsl:map-entry key="xs:QName('section-toc-depth')" select="$section-toc-depth"/>
         <xsl:map-entry key="xs:QName('vp:section-toc-depth')" select="$vp:section-toc-depth"/>
         <xsl:map-entry key="xs:QName('annotation-style')" select="$annotation-style"/>
         <xsl:map-entry key="xs:QName('annotation-mark')" select="$annotation-mark"/>
         <xsl:map-entry key="xs:QName('xlink-style')" select="$xlink-style"/>
         <xsl:map-entry key="xs:QName('xlink-style-default')" select="$xlink-style-default"/>
         <xsl:map-entry key="xs:QName('xlink-icon-open')" select="$xlink-icon-open"/>
         <xsl:map-entry key="xs:QName('xlink-icon-closed')" select="$xlink-icon-closed"/>
         <xsl:map-entry key="xs:QName('revhistory-style')" select="$revhistory-style"/>
         <xsl:map-entry key="xs:QName('segmentedlist-style')" select="$segmentedlist-style"/>
         <xsl:map-entry key="xs:QName('formal-object-title-placement')"
                        select="$formal-object-title-placement"/>
         <xsl:map-entry key="xs:QName('lists-of-figures')" select="$lists-of-figures"/>
         <xsl:map-entry key="xs:QName('lists-of-tables')" select="$lists-of-tables"/>
         <xsl:map-entry key="xs:QName('lists-of-examples')" select="$lists-of-examples"/>
         <xsl:map-entry key="xs:QName('lists-of-equations')" select="$lists-of-equations"/>
         <xsl:map-entry key="xs:QName('lists-of-procedures')" select="$lists-of-procedures"/>
         <xsl:map-entry key="xs:QName('variablelist-termlength-threshold')"
                        select="$variablelist-termlength-threshold"/>
         <xsl:map-entry key="xs:QName('procedure-step-numeration')"
                        select="$procedure-step-numeration"/>
         <xsl:map-entry key="xs:QName('orderedlist-item-numeration')"
                        select="$orderedlist-item-numeration"/>
         <xsl:map-entry key="xs:QName('refentry-generate-name')"
                        select="$refentry-generate-name"/>
         <xsl:map-entry key="xs:QName('refentry-generate-title')"
                        select="$refentry-generate-title"/>
         <xsl:map-entry key="xs:QName('annotate-toc')" select="$annotate-toc"/>
         <xsl:map-entry key="xs:QName('callout-unicode-start')" select="$callout-unicode-start"/>
         <xsl:map-entry key="xs:QName('index-show-entries')" select="$index-show-entries"/>
         <xsl:map-entry key="xs:QName('generate-index')" select="$generate-index"/>
         <xsl:map-entry key="xs:QName('index-on-role')" select="$index-on-role"/>
         <xsl:map-entry key="xs:QName('index-on-type')" select="$index-on-type"/>
         <xsl:map-entry key="xs:QName('glossary-sort-entries')" select="$glossary-sort-entries"/>
         <xsl:map-entry key="xs:QName('sort-collation')" select="$sort-collation"/>
         <xsl:map-entry key="xs:QName('default-float-style')" select="$default-float-style"/>
         <xsl:map-entry key="xs:QName('show-remarks')" select="$show-remarks"/>
         <xsl:map-entry key="xs:QName('sidebar-as-aside')" select="$sidebar-as-aside"/>
         <xsl:map-entry key="xs:QName('resource-base-uri')" select="$resource-base-uri"/>
         <xsl:map-entry key="xs:QName('css-links')" select="$css-links"/>
         <xsl:map-entry key="xs:QName('verbatim-syntax-highlight-css')"
                        select="$verbatim-syntax-highlight-css"/>
         <xsl:map-entry key="xs:QName('persistent-toc-css')" select="$persistent-toc-css"/>
         <xsl:map-entry key="xs:QName('oxy-markup-css')" select="$oxy-markup-css"/>
         <xsl:map-entry key="xs:QName('oxy-markup')" select="$oxy-markup"/>
         <xsl:map-entry key="xs:QName('annotations-js')" select="$annotations-js"/>
         <xsl:map-entry key="xs:QName('xlink-js')" select="$xlink-js"/>
         <xsl:map-entry key="xs:QName('persistent-toc-js')" select="$persistent-toc-js"/>
         <xsl:map-entry key="xs:QName('mathml-js')" select="$mathml-js"/>
         <xsl:map-entry key="xs:QName('control-js')" select="$control-js"/>
         <xsl:map-entry key="xs:QName('theme-picker')" select="$theme-picker"/>
         <xsl:map-entry key="xs:QName('chunk')" select="$chunk"/>
         <xsl:map-entry key="xs:QName('chunk-nav')" select="$chunk-nav"/>
         <xsl:map-entry key="xs:QName('chunk-nav-js')" select="$chunk-nav-js"/>
         <xsl:map-entry key="xs:QName('chunk-output-base-uri')" select="$chunk-output-base-uri"/>
         <xsl:map-entry key="xs:QName('chunk-section-depth')" select="$chunk-section-depth"/>
         <xsl:map-entry key="xs:QName('chunk-renumber-footnotes')"
                        select="$chunk-renumber-footnotes"/>
         <xsl:map-entry key="xs:QName('chunk-include')" select="$chunk-include"/>
         <xsl:map-entry key="xs:QName('chunk-exclude')" select="$chunk-exclude"/>
         <xsl:map-entry key="xs:QName('html-extension')" select="$html-extension"/>
         <xsl:map-entry key="xs:QName('footnote-numeration')" select="$footnote-numeration"/>
         <xsl:map-entry key="xs:QName('table-footnote-numeration')"
                        select="$table-footnote-numeration"/>
         <xsl:map-entry key="xs:QName('persistent-toc')" select="$persistent-toc"/>
         <xsl:map-entry key="xs:QName('profile-separator')" select="$profile-separator"/>
         <xsl:map-entry key="xs:QName('profile-lang')" select="$profile-lang"/>
         <xsl:map-entry key="xs:QName('profile-revisionflag')" select="$profile-revisionflag"/>
         <xsl:map-entry key="xs:QName('profile-role')" select="$profile-role"/>
         <xsl:map-entry key="xs:QName('profile-arch')" select="$profile-arch"/>
         <xsl:map-entry key="xs:QName('profile-audience')" select="$profile-audience"/>
         <xsl:map-entry key="xs:QName('profile-condition')" select="$profile-condition"/>
         <xsl:map-entry key="xs:QName('profile-conformance')" select="$profile-conformance"/>
         <xsl:map-entry key="xs:QName('profile-os')" select="$profile-os"/>
         <xsl:map-entry key="xs:QName('profile-outputformat')" select="$profile-outputformat"/>
         <xsl:map-entry key="xs:QName('profile-revision')" select="$profile-revision"/>
         <xsl:map-entry key="xs:QName('profile-security')" select="$profile-security"/>
         <xsl:map-entry key="xs:QName('profile-userlevel')" select="$profile-userlevel"/>
         <xsl:map-entry key="xs:QName('profile-vendor')" select="$profile-vendor"/>
         <xsl:map-entry key="xs:QName('profile-wordsize')" select="$profile-wordsize"/>
         <xsl:map-entry key="xs:QName('annotation-collection')" select="$annotation-collection"/>
         <xsl:map-entry key="xs:QName('glossary-collection')" select="$glossary-collection"/>
         <xsl:map-entry key="xs:QName('bibliography-collection')"
                        select="$bibliography-collection"/>
         <xsl:map-entry key="xs:QName('olink-databases')" select="$olink-databases"/>
         <xsl:map-entry key="xs:QName('docbook-transclusion')" select="$docbook-transclusion"/>
         <xsl:map-entry key="xs:QName('transclusion-prefix-separator')"
                        select="$transclusion-prefix-separator"/>
         <xsl:map-entry key="xs:QName('local-conventions')" select="$local-conventions"/>
         <xsl:map-entry key="xs:QName('relax-ng-grammar')" select="$relax-ng-grammar"/>
         <xsl:map-entry key="xs:QName('allow-eval')" select="$allow-eval"/>
         <xsl:map-entry key="xs:QName('dynamic-profiles')" select="$dynamic-profiles"/>
         <xsl:map-entry key="xs:QName('dynamic-profile-error')" select="$dynamic-profile-error"/>
         <xsl:map-entry key="xs:QName('experimental-pmuj')" select="$experimental-pmuj"/>
         <xsl:map-entry key="xs:QName('default-theme')" select="$default-theme"/>
         <xsl:map-entry key="xs:QName('generate-html-page')" select="$generate-html-page"/>
      </xsl:map>
   </xsl:variable>
</xsl:stylesheet>

VERSION.xsl

2 variables (1 used only in one other module)

Instructions
Variable $v:VERSION
Variable $v:VERSION-ID
Used by: template
Used in: modules/head.xsl
Source code
1
2
3
4
5
6
7
<xsl:stylesheet xmlns:v="http://docbook.org/ns/docbook/variables"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="3.0">
   <xsl:variable name="v:VERSION" select="'1.3.1-SNAPSHOT'"/>
   <xsl:variable name="v:VERSION-ID" select="'5c89ae5'"/>
</xsl:stylesheet>

variable.xsl

43 variables (40 used only in one other module)

Instructions
Variable $v:verbatim-line-style
Variable $v:verbatim-plain-style as xs:string*
Variable $v:verbatim-space as node()
Variable $v:verbatim-numbered-elements as xs:string*
Variable $v:verbatim-number-minlines
Variable $v:verbatim-number-every-nth
Variable $v:verbatim-number-first-line
Variable $v:verbatim-callouts as xs:string*
Variable $v:verbatim-syntax-highlight-languages
Variable $v:verbatim-syntax-highlight-options
Variable $v:verbatim-syntax-highlight-pygments-options
Variable $v:mediaobject-input-base-uri as xs:string?
Variable $v:mediaobject-output-base-uri as xs:string?
Variable $v:personal-name-styles
Used by: template
Used in: modules/info.xsl
Variable $v:formal-object-title-placement as map(xs:string,xs:string)
Variable $v:arg-choice-opt-open-str
Variable $v:arg-choice-opt-close-str
Variable $v:arg-choice-req-open-str
Variable $v:arg-choice-req-close-str
Variable $v:arg-choice-plain-open-str
Variable $v:arg-choice-plain-close-str
Variable $v:arg-choice-def-open-str
Variable $v:arg-choice-def-close-str
Variable $v:arg-rep-repeat-str
Variable $v:arg-rep-norepeat-str
Variable $v:arg-rep-def-str
Variable $v:arg-or-sep
Used by: template
Variable $v:chunk-renumber-footnotes as xs:boolean
Variable $v:chunk-filter-namespaces as namespace-node()*
Variable $v:admonition-icons
Used by: template
Variable $v:annotation-close as element()
Used by: template
Used in: main.xsl
Variable $v:nominal-page-width
Variable $v:image-nominal-width
Variable $v:image-nominal-height
Variable $v:toc-open as element()
Variable $v:toc-close as element()
Variable $v:theme-list as element()*
Variable $vp:js-controls as element()*
Used by: template
Used in: main.xsl
Variable $v:highlight-js-head-elements as element()*
Used by: template
Used in: modules/head.xsl
Variable $v:prism-js-head-elements as element()*
Used by: template
Used in: modules/head.xsl
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:db="http://docbook.org/ns/docbook"
                xmlns:ext="http://docbook.org/extensions/xslt"
                xmlns:f="http://docbook.org/ns/docbook/functions"
                xmlns:fp="http://docbook.org/ns/docbook/functions/private"
                xmlns:h="http://www.w3.org/1999/xhtml"
                xmlns:m="http://docbook.org/ns/docbook/modes"
                xmlns:v="http://docbook.org/ns/docbook/variables"
                xmlns:vp="http://docbook.org/ns/docbook/variables/private"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns="http://www.w3.org/1999/xhtml"
                default-mode="m:docbook"
                exclude-result-prefixes="db ext f fp h m v vp xs"
                version="3.0">

<!-- Note: These are variables used by the stylesheet. Many are
     initialized by parsing parameters defined in param.xsl. They're
     in a separate stylesheet to make the pipelines cleaner. -->

<!-- Some them are initialized using content instead of a select
     attribute in order to make the reference page in the Guide work
     better. -->

<xsl:variable name="v:debug" static="yes" as="xs:string*"
              select="tokenize($debug, '[,\s]+') ! normalize-space(.)"/>

<xsl:variable name="v:verbatim-line-style"
              select="tokenize($verbatim-line-style, '\s+')"/>

<xsl:variable name="v:verbatim-plain-style" as="xs:string*"
              select="tokenize($verbatim-plain-style, '\s+')"/>

<xsl:variable name="v:verbatim-space" as="node()">
  <xsl:value-of select="substring($verbatim-space || ' ', 1, 1)"/>
</xsl:variable>

<xsl:variable name="v:verbatim-numbered-elements" as="xs:string*"
              select="tokenize($verbatim-numbered-elements, '\s+')"/>

<xsl:variable name="v:verbatim-number-minlines"
              select="xs:integer($verbatim-number-minlines)"/>

<xsl:variable name="v:verbatim-number-every-nth"
              select="xs:integer($verbatim-number-every-nth)"/>

<xsl:variable name="v:verbatim-number-first-line"
              select="f:is-true($verbatim-number-first-line)"/>

<xsl:variable name="v:verbatim-callouts" as="xs:string*"
              select="tokenize($verbatim-callouts, '\s+')"/>

<xsl:variable name="v:verbatim-syntax-highlight-languages"
              select="tokenize($verbatim-syntax-highlight-languages, '\s+')"/>
<xsl:variable name="v:verbatim-syntax-highlight-options"
           select="map { }"/>
<xsl:variable name="v:verbatim-syntax-highlight-pygments-options"
           select="map { }"/>

<xsl:variable name="v:mediaobject-input-base-uri" as="xs:string?">
  <xsl:message use-when="'mediaobject-uris' = $v:debug"
               select="'Mediaobject input base URI:',
                       if ($mediaobject-input-base-uri = '')
                       then ()
                       else resolve-uri($mediaobject-input-base-uri, static-base-uri())"/>
  <xsl:sequence select="if ($mediaobject-input-base-uri = '')
                        then ()
                        else resolve-uri($mediaobject-input-base-uri, static-base-uri())"/>
</xsl:variable>

<xsl:variable name="v:mediaobject-output-base-uri" as="xs:string?">
  <xsl:message use-when="'mediaobject-uris' = $v:debug"
               select="'Mediaobject output base URI:',
                       if ($mediaobject-output-base-uri = '')
                       then ()
                       else if (ends-with($mediaobject-output-base-uri, '/'))
                            then $mediaobject-output-base-uri
                            else $mediaobject-output-base-uri || '/'"/>
  <xsl:sequence select="if ($mediaobject-output-base-uri = '')
                        then ()
                        else if (ends-with($mediaobject-output-base-uri, '/'))
                             then $mediaobject-output-base-uri
                             else $mediaobject-output-base-uri || '/'"/>
</xsl:variable>

<xsl:variable name="v:personal-name-styles"
              select="('first-last', 'last-first', 'FAMILY-given')"/>

<xsl:variable name="v:formal-object-title-placement" as="map(xs:string,xs:string)"
              select="fp:parse-key-value-pairs(
                        tokenize($formal-object-title-placement, '\s+'))"/>

<xsl:variable name="v:arg-choice-opt-open-str"><span class="cmdpunct">[</span></xsl:variable>
<xsl:variable name="v:arg-choice-opt-close-str"><span class="cmdpunct">]</span></xsl:variable>
<xsl:variable name="v:arg-choice-req-open-str"><span class="cmdpunct">{</span></xsl:variable>
<xsl:variable name="v:arg-choice-req-close-str"><span class="cmdpunct">}</span></xsl:variable>
<xsl:variable name="v:arg-choice-plain-open-str"><xsl:text></xsl:text></xsl:variable>
<xsl:variable name="v:arg-choice-plain-close-str"><xsl:text></xsl:text></xsl:variable>
<xsl:variable name="v:arg-choice-def-open-str"><span class="cmdpunct">[</span></xsl:variable>
<xsl:variable name="v:arg-choice-def-close-str"><span class="cmdpunct">]</span></xsl:variable>
<xsl:variable name="v:arg-rep-repeat-str"><span class="cmdpunct">…</span></xsl:variable>
<xsl:variable name="v:arg-rep-norepeat-str"><xsl:text></xsl:text></xsl:variable>
<xsl:variable name="v:arg-rep-def-str"><xsl:text></xsl:text></xsl:variable>
<xsl:variable name="v:arg-or-sep"><span class="cmdpunct"> | </span></xsl:variable>

<xsl:variable name="v:css-links"
              select="tokenize($css-links, '\s+') ! normalize-space(.)"/>

<xsl:variable name="v:chunk-renumber-footnotes" as="xs:boolean"
              select="f:is-true($chunk-renumber-footnotes)"/>

<xsl:variable name="v:chunk-filter-namespaces" as="namespace-node()*">
  <xsl:namespace name="db" select="'http://docbook.org/ns/docbook'"/>
</xsl:variable>

<xsl:variable name="v:admonition-icons">
  <db:tip>☞&#xFE0E;</db:tip>
  <db:note>🛈&#xFE0E;</db:note>
  <db:important>☝&#xFE0E;</db:important>
  <db:caution>⚠&#xFE0E;</db:caution>
  <db:warning>⯃&#xFE0E;</db:warning>
  <db:danger>⚡&#xFE0E;</db:danger>
</xsl:variable>

<xsl:variable name="v:annotation-close" as="element()">
  <span>╳</span>
</xsl:variable>

<xsl:variable name="v:nominal-page-width"
              select="f:parse-length($nominal-page-width)"/>
<xsl:variable name="v:image-nominal-width"
              select="f:parse-length($image-nominal-width)"/>
<xsl:variable name="v:image-nominal-height"
              select="f:parse-length($image-nominal-height)"/>

<xsl:variable name="v:toc-open" as="element()">
  <span>[toc]</span>
</xsl:variable>

<xsl:variable name="v:toc-close" as="element()">
  <span>╳</span>
</xsl:variable>

<xsl:variable name="v:olink-databases" as="element(h:targetdb)*">
  <xsl:if test="normalize-space($olink-databases) != ''">
    <xsl:for-each select="tokenize($olink-databases, ',\s*') ! normalize-space(.)">
      <xsl:variable name="db" select="."/>
      <xsl:try>
        <xsl:variable name="olinkdb" select="doc($db)/h:targetdb"/>
        <xsl:if test="empty($olinkdb)">
          <xsl:message select="'No targets in olinkdb:', $db"/>
        </xsl:if>
        <xsl:sequence select="$olinkdb"/>
        <xsl:catch>
          <xsl:message select="'Failed to load olinkdb:', $db"/>
        </xsl:catch>
      </xsl:try>
    </xsl:for-each>
  </xsl:if>
</xsl:variable>

<xsl:variable name="v:theme-list" as="element()*">
  <theme name="Materials dark" id="materials-dark" dark="true"/>
  <theme name="Materials light" id="materials-light" dark="false"/>
</xsl:variable>

<xsl:variable name="vp:js-controls" as="element()*">
  <xsl:variable name="chars"
                select="('a','b','c','d','e','f','_','_','_','1','2','3','4','5','6')"/>
  <xsl:variable name="random"
                select="string-join(random-number-generator()?permute($chars), '')"/>
  <span class="controls-open">☰</span>
  <div class="js-controls-wrapper">
    <xsl:if test="$v:theme-list[@dark='true']">
      <xsl:attribute name="db-dark-theme"
                     select="($v:theme-list[@dark='true'])[1]/@id"/>
    </xsl:if>
    <div class="js-controls-body">
      <div class="js-controls-header">
        <div class="js-controls-close">╳</div>
        <div class="js-controls-title">
          <xsl:text>Settings</xsl:text>
        </div>
      </div>
      <div class="js-controls-content">
        <fieldset db-random="{$random}" class="js-controls-toggles">
          <legend>Select options:</legend>
          <input id="db-js-annotations_{$random}" type="checkbox" value="js" />
          <label for="db-js-annotations_{$random}">JavaScript annotations</label><br/>
          <input id="db-js-xlinks_{$random}" type="checkbox" value="js" />
          <label for="db-js-xlinks_{$random}">JavaScript extended links</label><br/>
        </fieldset>
        <div id="db-js-controls-reload_{$random}" class="js-controls-reload"></div>
        <fieldset>
          <legend>Choose a theme:</legend>
          <input id="db-default-theme_{$random}" type="radio" name="db-theme" value="default" />
          <label for="db-default-theme_{$random}">Default</label><br/>
          <xsl:for-each select="$v:theme-list">
            <input id="db-theme-{@id}-{$random}"
                   type="radio" name="db-theme" value="{@id}" />
            <label for="db-theme-{@id}-{$random}">
              <xsl:sequence select="@name/string()"/>
            </label>
            <br/>
          </xsl:for-each>
        </fieldset>
      </div>
      <div class="js-controls-buttons">
        <button id="js-controls-cancel">✗</button>
        <xsl:text> </xsl:text>
        <button id="js-controls-ok">✓</button>
      </div>
    </div>
  </div>
</xsl:variable>

<xsl:variable name="v:highlight-js-head-elements" as="element()*">
  <link rel="stylesheet"
        href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.2/styles/default.min.css" />
  <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.2/highlight.min.js"></script>
  <script>hljs.initHighlightingOnLoad();</script>
</xsl:variable>

<xsl:variable name="v:prism-js-head-elements" as="element()*">
  <link rel="stylesheet" href="css/prism.css"/>
  <script src="js/prism.js"></script>
</xsl:variable>

</xsl:stylesheet>

space.xsl

Instructions
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:db="http://docbook.org/ns/docbook"
                xmlns:m="http://docbook.org/ns/docbook/modes"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns="http://www.w3.org/1999/xhtml"
                default-mode="m:docbook"
                exclude-result-prefixes="db m xs"
                version="3.0">

<xsl:preserve-space elements="*"/>

<xsl:strip-space elements="
db:abstract
db:affiliation
db:anchor
db:answer
db:appendix
db:area
db:areaset
db:areaspec
db:artheader
db:article
db:audiodata
db:audioobject
db:author
db:authorblurb
db:authorgroup
db:beginpage
db:bibliodiv
db:biblioentry
db:bibliography
db:biblioset
db:blockquote
db:book
db:bookbiblio
db:bookinfo
db:callout
db:calloutlist
db:caption
db:caution
db:chapter
db:citerefentry
db:classsynopsis
db:cmdsynopsis
db:co
db:colgroup
db:collab
db:colophon
db:colspec
db:confgroup
db:constructorsynopsis
db:copyright
db:danger
db:dedication
db:destructorsynopsis
db:docinfo
db:editor
db:entrytbl
db:epigraph
db:equation
db:example
db:fieldsynopsis
db:figure
db:footnote
db:formalpara
db:funcprototype
db:funcsynopsis
db:glossary
db:glossdef
db:glossdiv
db:glossentry
db:glosslist
db:graphicco
db:group
db:highlights
db:imagedata
db:imageobject
db:imageobjectco
db:important
db:index
db:indexdiv
db:indexentry
db:indexterm
db:info
db:informalequation
db:informalexample
db:informalfigure
db:informaltable
db:inlineequation
db:inlinemediaobject
db:itemizedlist
db:itermset
db:keycombo
db:keywordset
db:legalnotice
db:listitem
db:lot
db:mediaobject
db:mediaobjectco
db:menuchoice
db:methodparam
db:methodsynopsis
db:msg
db:msgentry
db:msgexplan
db:msginfo
db:msgmain
db:msgrel
db:msgset
db:msgsub
db:msgtext
db:note
db:objectinfo
db:ooclass
db:ooexception
db:oointerface
db:orderedlist
db:othercredit
db:part
db:partintro
db:preface
db:printhistory
db:procedure
db:productionset
db:programlistingco
db:publisher
db:qandadiv
db:qandaentry
db:qandaset
db:question
db:refentry
db:reference
db:refmeta
db:refnamediv
db:refsect1
db:refsect1info
db:refsect2
db:refsect2info
db:refsect3
db:refsect3info
db:refsynopsisdiv
db:refsynopsisdivinfo
db:revhistory
db:revision
db:row
db:sbr
db:screenco
db:screenshot
db:sect1
db:sect1info
db:sect2
db:sect2info
db:sect3
db:sect3info
db:sect4
db:sect4info
db:sect5
db:sect5info
db:section
db:sectioninfo
db:seglistitem
db:segmentedlist
db:seriesinfo
db:set
db:setindex
db:setinfo
db:shortcut
db:sidebar
db:simplelist
db:simplemsgentry
db:simplesect
db:spanspec
db:step
db:subject
db:subjectset
db:subjectset
db:substeps
db:synopfragment
db:table
db:tr
db:tbody
db:textobject
db:tfoot
db:tgroup
db:thead
db:tip
db:toc
db:tocchap
db:toclevel1
db:toclevel2
db:toclevel3
db:toclevel4
db:toclevel5
db:tocpart
db:varargs
db:variablelist
db:varlistentry
db:videodata
db:videoobject
db:void
db:warning

db:dialogue
db:poetry
db:linegroup
db:speaker
db:person
"/>

</xsl:stylesheet>

unhandled.xsl

2 templates

Instructions
Template match ≅ *
Mode: m:docbook
Matches: *
Template match ≅ h:*
Mode: m:docbook
Matches: h:*
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:f="http://docbook.org/ns/docbook/functions"
                xmlns:m="http://docbook.org/ns/docbook/modes"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns="http://www.w3.org/1999/xhtml"
                default-mode="m:docbook"
                exclude-result-prefixes="f m xs"
                version="3.0">

<xsl:template match="*">
  <xsl:message
      select="'No template for ' || node-name(.) || ': ' || f:generate-id(.)"/>
  <xsl:variable name="inline-style"
                select="'font: monospace;
                         color: yellow;
                         background-color: red;
                         font-weight: bold;'"/>
  <xsl:variable name="block-style"
                select="'font: monospace;
                         color: yellow;
                         width: 100%;
                         background-color: red;
                         font-weight: bold;'"/>

  <xsl:variable name="inline"
                select="normalize-space(string-join(text(),'')) != ''"/>

  <xsl:element namespace="http://www.w3.org/1999/xhtml"
               name="{if ($inline) then 'span' else 'div'}">

    <xsl:element namespace="http://www.w3.org/1999/xhtml"
                 name="{if ($inline) then 'span' else 'div'}">
      <xsl:attribute name="style"
                     select="if ($inline) then $inline-style else $block-style"/>
      <xsl:text>&lt;</xsl:text>
      <xsl:value-of select="node-name(.)"/>
      <xsl:text>&gt;</xsl:text>
    </xsl:element>

    <xsl:apply-templates/>

    <xsl:element namespace="http://www.w3.org/1999/xhtml"
                 name="{if ($inline) then 'span' else 'div'}">
      <xsl:attribute name="style"
                     select="if ($inline) then $inline-style else $block-style"/>
      <xsl:text>&lt;/</xsl:text>
      <xsl:value-of select="node-name(.)"/>
      <xsl:text>&gt;</xsl:text>
    </xsl:element>
  </xsl:element>

  <!--
    <xsl:message>
      <xsl:text>Unhandled element: </xsl:text>
      <xsl:value-of select="node-name(.)"/>
    </xsl:message>
  -->
</xsl:template>

<xsl:template xmlns:h="http://www.w3.org/1999/xhtml"
              match="h:*">
  <xsl:element name="{local-name(.)}" namespace="http://www.w3.org/1999/xhtml">
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates select="node()"/>
  </xsl:element>
</xsl:template>

</xsl:stylesheet>

errors.xsl

12 variables (12 used only in one other module)

Instructions
Variable $dbe:INVALID-CALS
Variable $dbe:INVALID-AREAREFS
Used by: template
Used in: modules/lists.xsl
Variable $dbe:INVALID-PRODUCTIONRECAP
Used by: template
Variable $dbe:INVALID-CONSTRAINT
Used by: template
Variable $dbe:INVALID-TEMPLATE
Used by: template
Variable $dbe:INTERNAL-RENUMBER-ERROR
Variable $dbe:INTERNAL-HIGHLIGHT-ERROR
Variable $dbe:INVALID-NAME-STYLE
Used by: t:person-name
Used in: modules/info.xsl
Variable $dbe:DYNAMIC-PROFILE-SYNTAX-ERROR
Variable $dbe:DYNAMIC-PROFILE-EVAL-ERROR
Variable $dbe:INVALID-DYNAMIC-PROFILE-ERROR
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:db="http://docbook.org/ns/docbook"
                xmlns:dbe="http://docbook.org/ns/docbook/errors"
                xmlns:f="http://docbook.org/ns/docbook/functions"
                xmlns:m="http://docbook.org/ns/docbook/modes"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns="http://www.w3.org/1999/xhtml"
                default-mode="m:docbook"
                exclude-result-prefixes="db dbe f m xs"
                version="3.0">

<xsl:variable name="dbe:INVALID-INJECT" select="xs:QName('dbe:INVALID-INJECT')"/>
<xsl:variable name="dbe:INVALID-CALS" select="xs:QName('dbe:INVALID-CALS')"/>
<xsl:variable name="dbe:INVALID-AREAREFS" select="xs:QName('dbe:INVALID-AREAREFS')"/>
<xsl:variable name="dbe:INVALID-PRODUCTIONRECAP"
              select="xs:QName('dbe:INVALID-PRODUCTIONRECAP')"/>
<xsl:variable name="dbe:INVALID-CONSTRAINT"
              select="xs:QName('dbe:INVALID-CONSTRAINT')"/>
<xsl:variable name="dbe:INVALID-TEMPLATE"
              select="xs:QName('dbe:INVALID-TEMPLATE')"/>
<xsl:variable name="dbe:INTERNAL-RENUMBER-ERROR"
              select="xs:QName('dbe:INTERNAL-RENUMBER-ERROR')"/>
<xsl:variable name="dbe:INTERNAL-HIGHLIGHT-ERROR"
              select="xs:QName('dbe:INTERNAL-HIGHLIGHT-ERROR')"/>
<xsl:variable name="dbe:INVALID-NAME-STYLE"
              select="xs:QName('dbe:INVALID-NAME-STYLE')"/>
<xsl:variable name="dbe:DYNAMIC-PROFILE-SYNTAX-ERROR"
              select="xs:QName('dbe:DYNAMIC-PROFILE-SYNTAX-ERROR')"/>
<xsl:variable name="dbe:DYNAMIC-PROFILE-EVAL-ERROR"
              select="xs:QName('dbe:DYNAMIC-PROFILE-EVAL-ERROR')"/>
<xsl:variable name="dbe:INVALID-DYNAMIC-PROFILE-ERROR"
              select="xs:QName('dbe:INVALID-DYNAMIC-PROFILE-ERROR')"/>

</xsl:stylesheet>

head.xsl

11 templates

Instructions
Template match ≅ * as element(h:head)
Template match ≅ db:keywordset
Mode: m:html-head
Matches: db:keywordset
Template match ≅ db:subjectset
Mode: m:html-head
Matches: db:subjectset
Template match ≅ h:*
Mode: m:html-head
Matches: h:*
Template match ≅ attribute()|comment()|processi…
Mode: m:html-head
Matches: attribute(), comment(), processing-instruction(), text()
Template match ≅ *
Mode: mp:html-head
Matches: *
Template match ≅ *
Mode: m:html-head-script
Matches: *
Template match ≅ *
Mode: m:html-head-links
Matches: *
Template match ≅ *
Mode: m:html-head-last
Matches: *
Template match ≅ *
Mode: m:html-body-script
Matches: *
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:db="http://docbook.org/ns/docbook"
                xmlns:f="http://docbook.org/ns/docbook/functions"
                xmlns:h="http://www.w3.org/1999/xhtml"
                xmlns:m="http://docbook.org/ns/docbook/modes"
                xmlns:mp="http://docbook.org/ns/docbook/modes/private"
                xmlns:t="http://docbook.org/ns/docbook/templates"
                xmlns:tp="http://docbook.org/ns/docbook/templates/private"
                xmlns:v="http://docbook.org/ns/docbook/variables"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns="http://www.w3.org/1999/xhtml"
                default-mode="m:docbook"
                exclude-result-prefixes="db f h m mp t tp v xs"
                version="3.0">

<xsl:template match="*" mode="m:html-head" as="element(h:head)">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>
      <xsl:variable name="title">
        <xsl:apply-templates select="/*" mode="m:headline-title"/>
      </xsl:variable>
      <xsl:value-of select="$title"/>
    </title>

    <xsl:apply-templates select="db:keywordset|db:subjectset"
                         mode="m:html-head"/>

    <xsl:apply-templates select="." mode="mp:html-head"/>

    <xsl:for-each select="$v:css-links">
      <link rel="stylesheet" href="{$resource-base-uri}{.}"/>
    </xsl:for-each>

    <xsl:if test="exists($oxy-markup-css)
                  and //processing-instruction()[starts-with(name(), 'oxy_')]">
      <link rel="stylesheet" href="{$resource-base-uri}{$oxy-markup-css}"/>
    </xsl:if>

    <xsl:if test="exists($v:verbatim-syntax-highlight-languages)
                  and normalize-space($verbatim-syntax-highlight-css) != ''">
      <link rel="stylesheet" href="{$resource-base-uri}{$verbatim-syntax-highlight-css}"/>
    </xsl:if>

    <xsl:apply-templates select="." mode="mp:html-head-script"/>
    <xsl:apply-templates select="." mode="m:html-head-script"/>
    <xsl:apply-templates select="." mode="m:html-head-links"/>
    <xsl:apply-templates select="h:*" mode="m:html-head"/>
    <xsl:apply-templates select="." mode="m:html-head-last"/>
  </head>
</xsl:template>

<xsl:template match="db:keywordset" mode="m:html-head">
  <xsl:variable name="keywords" as="xs:string*">
    <xsl:for-each select="db:keyword">
      <xsl:sort select="normalize-space(.)"/>
      <xsl:sequence select="normalize-space(.)"/>
    </xsl:for-each>
  </xsl:variable>

  <meta name="keywords" content="{string-join($keywords,',')}"/>
</xsl:template>

<xsl:template match="db:subjectset" mode="m:html-head">
  <xsl:variable name="keywords" as="xs:string*">
    <xsl:for-each select="db:subject/db:subjectterm">
      <xsl:sort select="normalize-space(.)"/>
      <xsl:sequence select="normalize-space(.)"/>
    </xsl:for-each>
  </xsl:variable>

  <meta name="keywords" content="{string-join($keywords,',')}"/>
</xsl:template>

<xsl:template match="h:*" mode="m:html-head">
  <xsl:element name="{local-name(.)}" namespace="http://www.w3.org/1999/xhtml">
    <xsl:apply-templates select="@*,node()" mode="m:html-head"/>
  </xsl:element>
</xsl:template>

<xsl:template match="attribute()|text()|comment()|processing-instruction()"
              mode="m:html-head">
  <xsl:copy/>
</xsl:template>

<!-- ============================================================ -->

<xsl:template match="*" mode="mp:html-head">
  <xsl:variable name="Z" select="xs:dayTimeDuration('PT0H')"/>

 <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
 <link rel="schema.dc" href="http://purl.org/dc/elements/1.1/"/>
 <meta name="dc.modified"
       content="{format-dateTime(adjust-dateTime-to-timezone(current-dateTime(), $Z),
                                 '[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01]Z')}"/>
 <xsl:choose>
   <xsl:when test="empty(/*/db:info/db:pubdate)"/>
   <xsl:when test="/*/db:info/db:pubdate/string() castable as xs:dateTime">
     <xsl:variable name="date" select="xs:dateTime(/*/db:info/db:pubdate/string())"/>
     <meta name="dc.created"
           content="{format-dateTime(adjust-dateTime-to-timezone($date, $Z),
                                     '[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01]Z')}"/>
   </xsl:when>
   <xsl:when test="/*/db:info/db:pubdate/string() castable as xs:date">
     <xsl:variable name="date" select="xs:date(/*/db:info/db:pubdate/string())"/>
     <meta name="dc.created"
           content="{format-date($date, '[Y0001]-[M01]-[D01]')}"/>
   </xsl:when>
   <xsl:otherwise>
     <meta name="dc.created" content="{string(/*/db:info/db:pubdate)}"/>
   </xsl:otherwise>
 </xsl:choose>
 <meta name="generator"
       content="{'DocBook xslTNG version ' || $v:VERSION
                 || ' / ' || $v:VERSION-ID
                 || ' / ' || system-property('xsl:product-name')
                 || ' ' || system-property('xsl:product-version')}"/>
</xsl:template>

<xsl:template match="*" mode="mp:html-head-script">
  <xsl:if test="f:is-true($persistent-toc)">
    <link rel="stylesheet"
          href="{$resource-base-uri}{$persistent-toc-css}"/>
  </xsl:if>
  <xsl:choose>
    <xsl:when test="$verbatim-syntax-highlighter = ('', 'none')"/>
    <xsl:when test="$verbatim-syntax-highlighter = 'pygments'"/>
    <xsl:when test="$verbatim-syntax-highlighter = 'highlight.js'">
      <xsl:sequence select="$v:highlight-js-head-elements"/>
    </xsl:when>
    <xsl:when test="$verbatim-syntax-highlighter = ('prism', 'prism.js')">
      <xsl:sequence select="$v:prism-js-head-elements"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:message select="'Unrecognized syntax highlighter:', $verbatim-syntax-highlighter"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="*" mode="m:html-head-script">
</xsl:template>

<xsl:template match="*" mode="m:html-head-links">
</xsl:template>

<xsl:template match="*" mode="m:html-head-last">
</xsl:template>

<xsl:template match="*" mode="m:html-body-script">
  <xsl:param name="rootbaseuri" as="xs:anyURI" required="yes"/>
  <xsl:param name="chunkbaseuri" as="xs:anyURI" required="yes"/>
</xsl:template>

</xsl:stylesheet>

titles.xsl

28 templates, 2 functions, 2 variables

Instructions
Variable $v:user-title-properties as element()*
Template match ≅ *
Mode: m:headline
Matches: *
Template match ≅ *
Mode: m:headline-prefix
Matches: *
Template match ≅ *
Mode: m:headline-label
Matches: *
Template match ≅ db:equation|db:example|db:figu…
Mode: m:headline-label
Priority: 20
Matches: db:equation, db:example, db:figure, db:formalgroup, db:procedure, db:table
Template match ≅ db:formalgroup
Mode: m:headline-label
Priority: 10
Matches: db:formalgroup
Template match ≅ db:equation|db:example|db:figu…
Mode: m:headline-label
Priority: 10
Matches: db:equation, db:example, db:figure, db:procedure, db:table
Template match ≅ db:qandaentry
Mode: m:headline-label
Matches: db:qandaentry
Template match ≅ db:question
Mode: m:headline-label
Matches: db:question
Template match ≅ db:answer
Mode: m:headline-label
Matches: db:answer
Template match ≅ *
Mode: m:headline-label-separator
Matches: *
Template match ≅ *
Mode: m:headline-number
Matches: *
Template match ≅ db:section
Mode: m:headline-number
Matches: db:section
Template match ≅ db:appendix
Mode: m:headline-number
Matches: db:appendix
Template match ≅ db:step
Mode: m:headline-number
Matches: db:step
Template match ≅ db:listitem
Mode: m:headline-number
Matches: db:listitem
Template match ≅ *
Mode: m:headline-number-separator
Matches: *
Template match ≅ *
Mode: m:headline-title
Matches: *
Template match ≅ db:refentry
Mode: m:headline-title
Matches: db:refentry
Template match ≅ db:refmeta
Mode: m:headline-title
Matches: db:refmeta
Template match ≅ db:refnamediv
Mode: m:headline-title
Matches: db:refnamediv
Template match ≅ db:refname
Mode: m:headline-title
Matches: db:refname
Template match ≅ db:question
Mode: m:headline-title
Matches: db:question
Template match ≅ *
Mode: m:headline-suffix
Matches: *
Function fp:document-title-properties($node as element()) as element()*
Function fp:title-properties($node as element()) as map(*)
Template match ≅ db:title|db:titleabbrev
Mode: m:title
Matches: db:title, db:titleabbrev
Template match ≅ h:db-annotation|h:db-footnote
Mode: mp:strip-links
Matches: h:db-annotation, h:db-footnote
Template match ≅ h:a
Mode: mp:strip-links
Matches: h:a
Template match ≅ element()
Mode: mp:strip-links
Matches: element()
Template match ≅ attribute()|comment()|processi…
Mode: mp:strip-links
Matches: attribute(), comment(), processing-instruction(), text()
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:db="http://docbook.org/ns/docbook"
                xmlns:dbe="http://docbook.org/ns/docbook/errors"
                xmlns:f="http://docbook.org/ns/docbook/functions"
                xmlns:fp="http://docbook.org/ns/docbook/functions/private"
                xmlns:l="http://docbook.org/ns/docbook/l10n"
                xmlns:m="http://docbook.org/ns/docbook/modes"
                xmlns:map="http://www.w3.org/2005/xpath-functions/map"
                xmlns:mp="http://docbook.org/ns/docbook/modes/private"
                xmlns:t="http://docbook.org/ns/docbook/templates"
                xmlns:v="http://docbook.org/ns/docbook/variables"
                xmlns:vp="http://docbook.org/ns/docbook/variables/private"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns="http://www.w3.org/1999/xhtml"
                default-mode="m:docbook"
                exclude-result-prefixes="db dbe f fp l m map mp t v vp xs"
                version="3.0">
<!--
    prefix, label, separator, title, suffix : context (title, lot)

                  Section 3.4 The Title
                ^    ^   ^^^ ^    ^     ^
                |    |   ||| |    |     +- the suffix
                |    |   ||| |    +- the title
                |    |   ||| +- the number separator
                |    |   ||+- the intra-number separator
                |    |   |+- the number (3.4)
                |    |   +- the label separator
                |    +- the label
                +- the prefix
-->

<!-- label defaults to false;
     number defaults to false;
     inherit is ignored if number is false -->

<xsl:variable name="v:user-title-properties" as="element()*"/>

<xsl:variable name="v:title-properties" as="element()+"
              xmlns:db="http://docbook.org/ns/docbook">
  <xsl:sequence select="$v:user-title-properties"/>

  <title xpath="self::db:section[ancestor::db:preface]"
         label="false"/>

  <title xpath="self::db:section[parent::db:section]"
         number-format="{$section-numbers}"
         inherit="{$section-numbers-inherit}"/>

  <title xpath="self::db:section"
         number-format="{$section-numbers}"
         inherit="{$component-numbers-inherit}"/>

  <title xpath="self::db:sect1"
         number-format="{$section-numbers}"
         inherit="{$component-numbers-inherit}"/>

  <title xpath="self::db:sect2|self::db:sect3|self::db:sect4|self::db:sect5"
         number-format="{$section-numbers}"
         inherit="{$section-numbers-inherit}"/>

  <title xpath="self::db:refsection|self::db:refsect1|self::db:refsect2|self::db:refsect3"/>

  <title xpath="self::db:article"/>

  <title xpath="self::db:preface"/>

  <title xpath="self::db:chapter"
         number-format="1"
         label="true"
         inherit="{$division-numbers-inherit}"/>

  <title xpath="self::db:appendix"
         number-format="A"
         label="true"
         inherit="{$division-numbers-inherit}"/>

  <title xpath="self::db:part"
         label="true"
         number="true"
         number-format="I"/>

  <title xpath="self::db:reference"
         number-format="I"/>

  <title xpath="self::db:figure|self::db:table|self::db:equation|self::db:example"
         label="true"
         number-format="1"
         inherit="true"/>

  <title xpath="self::db:formalgroup"
         label="true"
         number-format="1"
         inherit="true"/>

  <title xpath="self::db:step|self::db:listitem[parent::db:orderedlist]"
         label="false"
         number="false"
         inherit="true"/>

  <title xpath="self::db:glosssee|self::db:glossseealso"
         label="true"/>

  <title xpath="self::db:see|self::db:seealso"
         label="true"/>

  <title xpath="self::db:question|self::db:answer"
         label="true"
         title="true"/>

  <title xpath="self::*"/>
</xsl:variable>

<!-- ============================================================ -->

<xsl:template match="*" mode="m:headline">
  <xsl:param name="purpose" as="xs:string" required="yes"/>

  <xsl:variable name="properties" select="fp:title-properties(.)"/>

  <!--
  <xsl:message select="path(.), ':'"/>
  <xsl:for-each select="map:keys($properties)">
    <xsl:message select="'  prop:', ., '=', map:get($properties, .)"/>
  </xsl:for-each>
  -->

  <xsl:variable name="title" as="node()*">
    <xsl:apply-templates select="." mode="m:headline-title">
      <xsl:with-param name="purpose" select="$purpose"/>
    </xsl:apply-templates>
  </xsl:variable>

  <xsl:variable name="number" as="node()*">
    <xsl:if test="$properties?number">
      <xsl:choose>
        <xsl:when test="@label">
          <xsl:value-of select="@label/string()"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:apply-templates select="." mode="m:headline-number">
            <xsl:with-param name="purpose" select="$purpose"/>
          </xsl:apply-templates>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:if>
  </xsl:variable>

  <xsl:variable name="label" as="item()*">
    <xsl:if test="($properties?label and $purpose ne 'lot')
                  or ($properties?label-toc and $purpose eq 'lot')">
      <xsl:apply-templates select="." mode="m:headline-label">
        <xsl:with-param name="purpose" select="$purpose"/>
        <xsl:with-param name="number" select="$number"/>
        <xsl:with-param name="title" select="$title"/>
      </xsl:apply-templates>
    </xsl:if>
  </xsl:variable>

  <xsl:apply-templates select="." mode="m:headline-prefix">
    <xsl:with-param name="purpose" select="$purpose"/>
    <xsl:with-param name="label" select="$label"/>
    <xsl:with-param name="number" select="$number"/>
    <xsl:with-param name="title" select="$title"/>
  </xsl:apply-templates>

  <xsl:if test="not(empty($label))">
    <span class="label">
      <xsl:sequence select="$label"/>
      <xsl:variable name="sep" as="node()*">
        <xsl:apply-templates select="." mode="m:headline-label-separator">
          <xsl:with-param name="purpose" select="$purpose"/>
          <xsl:with-param name="label" select="$label"/>
          <xsl:with-param name="number" select="$number"/>
          <xsl:with-param name="title" select="$title"/>
        </xsl:apply-templates>
      </xsl:variable>
      <xsl:if test="not(empty($sep))">
        <span class="sep">
          <xsl:sequence select="$sep"/>
        </span>
      </xsl:if>
    </span>
  </xsl:if>

  <xsl:if test="not(empty($number))">
    <span class="number">
      <xsl:sequence select="$number"/>
      <xsl:apply-templates select="." mode="m:headline-number-separator">
        <xsl:with-param name="purpose" select="$purpose"/>
        <xsl:with-param name="number" select="$number"/>
        <xsl:with-param name="title" select="$title"/>
      </xsl:apply-templates>
    </span>
  </xsl:if>

  <xsl:sequence select="$title"/>

  <xsl:apply-templates select="." mode="m:headline-suffix">
    <xsl:with-param name="purpose" select="$purpose"/>
    <xsl:with-param name="title" select="$title"/>
  </xsl:apply-templates>
</xsl:template>

<!-- ============================================================ -->

<xsl:template match="*" mode="m:headline-prefix">
  <xsl:param name="purpose" as="xs:string" required="yes"/>
  <xsl:param name="label" as="item()*" required="yes"/>
  <xsl:param name="number" as="item()*" required="yes"/>
  <xsl:param name="title" as="node()*" required="yes"/>
  <xsl:sequence select="()"/>
</xsl:template>

<!-- ============================================================ -->

<xsl:template match="*" mode="m:headline-label">
  <xsl:param name="purpose" as="xs:string" select="'title'"/>
  <xsl:param name="number" as="node()*" required="yes"/>
  <xsl:param name="title" as="node()*" required="yes"/>
  <xsl:sequence select="f:gentext(., 'label')"/>
</xsl:template>

<xsl:template match="db:formalgroup
                     |db:figure|db:example|db:table
                     |db:equation|db:procedure"
              priority="20"
              mode="m:headline-label">
  <xsl:param name="purpose" as="xs:string" select="'title'"/>
  <xsl:param name="number" as="node()*" required="yes"/>
  <xsl:param name="title" as="node()*" required="yes"/>
  <xsl:choose>
    <xsl:when test="$purpose = 'lot'">
      <xsl:sequence select="()"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:next-match>
        <xsl:with-param name="purpose" select="$purpose"/>
        <xsl:with-param name="number" select="$number"/>
        <xsl:with-param name="title" select="$title"/>
      </xsl:next-match>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="db:formalgroup" priority="10"
              mode="m:headline-label">
  <xsl:param name="purpose" as="xs:string" select="'title'"/>
  <xsl:param name="number" as="node()*" required="yes"/>
  <xsl:param name="title" as="node()*" required="yes"/>

  <xsl:variable name="ctx"
                select="(db:figure|db:table
                         |db:example|db:equation)[1]"/>

  <xsl:sequence select="f:gentext(., 'label', local-name($ctx))"/>
</xsl:template>

<xsl:template match="db:figure|db:example|db:table|db:equation|db:procedure"
              priority="10"
              mode="m:headline-label">
  <xsl:param name="purpose" as="xs:string" select="'title'"/>
  <xsl:param name="number" as="node()*" required="yes"/>
  <xsl:param name="title" as="node()*" required="yes"/>

  <xsl:choose>
    <xsl:when test="empty(parent::db:formalgroup)">
      <xsl:next-match>
        <xsl:with-param name="purpose" select="$purpose"/>
        <xsl:with-param name="number" select="$number"/>
        <xsl:with-param name="title" select="$title"/>
      </xsl:next-match>
    </xsl:when>
    <xsl:otherwise>
      <xsl:sequence select="f:gentext(., 'label',
                                      'sub' || local-name(.))"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="db:qandaentry" mode="m:headline-label">
  <xsl:param name="purpose" as="xs:string" select="'title'"/>
  <xsl:param name="number" as="node()*"/>
  <xsl:param name="title" as="node()*"/>
  <xsl:apply-templates select="db:question" mode="m:headline-label"/>
</xsl:template>

<xsl:template match="db:question" mode="m:headline-label">
  <xsl:param name="purpose" as="xs:string" select="'title'"/>
  <xsl:param name="number" as="node()*"/>
  <xsl:param name="title" as="node()*"/>

  <xsl:variable name="label"
                select="ancestor::db:qandaset[@defaultlabel][1]/@defaultlabel/string()"/>
  <xsl:variable name="label"
                select="if ($label)
                        then $label
                        else $qandaset-default-label"/>

  <xsl:choose>
    <xsl:when test="db:label">
      <xsl:apply-templates select="db:label"/>
    </xsl:when>
    <xsl:when test="$label = 'none'"/>
    <xsl:when test="$label = 'number'">
      <xsl:number from="db:qandaset" level="multiple" select=".."
                  count="db:qandaentry|db:qandadiv"/>
      <xsl:sequence select="f:post-label-punctuation(.)"/>
    </xsl:when>
    <xsl:when test="$label = 'qanda'">
      <xsl:text>Q:</xsl:text>
    </xsl:when>
    <xsl:otherwise>
      <xsl:message
          select="'Unexpected qandaset label: ' || $label || ', using qanda'"/>
      <xsl:text>Q:</xsl:text>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="db:answer" mode="m:headline-label">
  <xsl:param name="purpose" as="xs:string" select="'title'"/>
  <xsl:param name="number" as="node()*"/>
  <xsl:param name="title" as="node()*"/>

  <xsl:variable name="label"
                select="ancestor::db:qandaset[@defaultlabel][1]/@defaultlabel/string()"/>
  <xsl:variable name="label"
                select="if ($label)
                        then $label
                        else $qandaset-default-label"/>

  <xsl:choose>
    <xsl:when test="db:label">
      <xsl:apply-templates select="db:label"/>
    </xsl:when>
    <xsl:when test="$label = 'none' or $label='number'"/>
    <xsl:when test="$label = 'qanda'">
      <xsl:text>A:</xsl:text>
    </xsl:when>
    <xsl:otherwise>
      <xsl:message
          select="'Unexpected qandaset label: ' || $label || ', using qanda'"/>
      <xsl:text>A:</xsl:text>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<!-- ============================================================ -->

<xsl:template match="*" mode="m:headline-label-separator">
  <xsl:param name="purpose" as="xs:string" required="yes"/>
  <xsl:param name="label" as="item()*" required="yes"/>
  <xsl:param name="number" as="item()*" required="yes"/>
  <xsl:param name="title" as="node()*" required="yes"/>
  <xsl:sequence select="f:label-separator(.)"/>
</xsl:template>

<!-- ============================================================ -->

<xsl:template match="*" mode="m:headline-number">
  <xsl:param name="purpose" as="xs:string" required="yes"/>

  <xsl:variable name="properties" select="fp:title-properties(.)"/>

  <xsl:if test="exists(parent::*) and $properties?inherit">
    <xsl:variable name="pnum" as="node()*">
      <xsl:apply-templates select=".." mode="m:headline-number">
        <xsl:with-param name="purpose" select="$purpose"/>
      </xsl:apply-templates>
    </xsl:variable>
    <xsl:if test="exists($pnum)">
      <xsl:sequence select="$pnum"/>
      <span class="sep">
        <xsl:sequence select="f:intra-number-separator(.)"/>
      </span>
    </xsl:if>
  </xsl:if>

  <xsl:variable name="number"
                select="count(preceding-sibling::*
                              [node-name(.)=node-name(current())]) + 1"/>

  <xsl:number value="$number" format="{$properties?number-format}"/>
</xsl:template>

<xsl:template match="db:section" mode="m:headline-number">
  <xsl:param name="purpose" as="xs:string" required="yes"/>

  <xsl:variable name="properties" select="fp:title-properties(.)"/>

  <xsl:if test="exists(parent::*) and $properties?inherit">
    <xsl:variable name="pnum" as="node()*">
      <xsl:apply-templates select=".." mode="m:headline-number">
        <xsl:with-param name="purpose" select="$purpose"/>
      </xsl:apply-templates>
    </xsl:variable>
    <xsl:if test="exists($pnum)">
      <xsl:sequence select="$pnum"/>
      <span class="sep">
        <xsl:sequence select="f:intra-number-separator(.)"/>
      </span>
    </xsl:if>
  </xsl:if>

  <xsl:variable name="number"
                select="count(preceding-sibling::db:section) + 1"/>

  <xsl:number value="$number" format="{$properties?number-format}"/>
</xsl:template>

<!-- if there's a single appendix, don't number it -->
<xsl:template match="db:appendix" mode="m:headline-number">
  <xsl:param name="purpose" as="xs:string" required="yes"/>

  <xsl:variable name="properties" select="fp:title-properties(.)"/>

  <xsl:choose>
    <xsl:when test="not(f:is-true($number-single-appendix))
                    and not($properties?label)
                    and empty(preceding-sibling::db:appendix)
                    and empty(following-sibling::db:appendix)">
      <xsl:sequence select="()"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:next-match>
        <xsl:with-param name="purpose" select="$purpose"/>
      </xsl:next-match>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="db:step" mode="m:headline-number">
  <xsl:param name="purpose" as="xs:string" required="yes"/>

  <xsl:variable name="properties" select="fp:title-properties(.)"/>

  <xsl:if test="exists(ancestor::db:step) and $properties?inherit">
    <xsl:variable name="pnum" as="node()*">
      <xsl:apply-templates select="ancestor::db:step[1]"
                           mode="m:headline-number">
        <xsl:with-param name="purpose" select="$purpose"/>
      </xsl:apply-templates>
    </xsl:variable>
    <xsl:if test="exists($pnum)">
      <xsl:sequence select="$pnum"/>
      <span class="sep">
        <xsl:sequence select="f:intra-number-separator(.)"/>
      </span>
    </xsl:if>
  </xsl:if>

  <xsl:variable name="number"
                select="count(preceding-sibling::db:step) + 1"/>

  <xsl:number value="$number" format="{f:step-numeration(.)}"/>
</xsl:template>

<xsl:template match="db:listitem[parent::db:orderedlist]" mode="m:headline-number">
  <xsl:param name="purpose" as="xs:string" required="yes"/>

  <xsl:variable name="properties" select="fp:title-properties(.)"/>

  <xsl:if test="exists(ancestor::db:listitem[parent::db:orderedlist])
                and $properties?inherit">
    <xsl:variable name="pnum" as="node()*">
      <xsl:apply-templates
          select="ancestor::db:listitem[parent::db:orderedlist][1]"
          mode="m:headline-number">
        <xsl:with-param name="purpose" select="$purpose"/>
      </xsl:apply-templates>
    </xsl:variable>
    <xsl:if test="exists($pnum)">
      <xsl:sequence select="$pnum"/>
      <span class="sep">
        <xsl:sequence select="f:intra-number-separator(.)"/>
      </span>
    </xsl:if>
  </xsl:if>

  <xsl:variable name="number"
                select="count(preceding-sibling::db:listitem) + 1"/>

  <xsl:number value="$number" format="{f:orderedlist-item-numeration(.)}"/>
</xsl:template>

<!-- ============================================================ -->

<xsl:template match="*" mode="m:headline-number-separator">
  <xsl:param name="purpose" as="xs:string" required="yes"/>
  <xsl:param name="number" as="node()*" required="yes"/>
  <xsl:param name="title" as="node()*" required="yes"/>
  <xsl:choose>
    <xsl:when test="self::db:set|self::db:book|self::db:part
                    |self::db:reference|self::db:chapter|self::db:appendix">
      <span class="sep">. </span>
    </xsl:when>
    <xsl:otherwise>
      <span class="sep"> </span>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<!-- ============================================================ -->

<xsl:template match="*" mode="m:headline-title">
  <xsl:param name="purpose" as="xs:string" select="'title'"/>

  <xsl:choose>
    <xsl:when test="$purpose = 'title' or not(db:info/db:titleabbrev)">
      <xsl:apply-templates select="db:info/db:title" mode="m:title">
        <xsl:with-param name="purpose" select="$purpose"/>
      </xsl:apply-templates>
    </xsl:when>
    <xsl:otherwise>
      <xsl:apply-templates select="db:info/db:titleabbrev" mode="m:title">
        <xsl:with-param name="purpose" select="$purpose"/>
      </xsl:apply-templates>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="db:refentry" mode="m:headline-title">
  <xsl:param name="purpose" as="xs:string" select="'title'"/>
  <xsl:choose>
    <xsl:when test="db:refmeta">
      <xsl:apply-templates select="db:refmeta" mode="m:headline-title">
        <xsl:with-param name="purpose" select="$purpose"/>
      </xsl:apply-templates>
    </xsl:when>
    <xsl:otherwise>
      <xsl:apply-templates select="db:refnamediv/db:refname[1]" mode="m:headline-title">
        <xsl:with-param name="purpose" select="$purpose"/>
      </xsl:apply-templates>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="db:refmeta" mode="m:headline-title">
  <xsl:param name="purpose" as="xs:string" select="'title'"/>
  <xsl:apply-templates select="db:refentrytitle/node()"/>
  <xsl:apply-templates select="db:manvolnum"/>
</xsl:template>

<xsl:template match="db:refnamediv" mode="m:headline-title">
  <xsl:param name="purpose" as="xs:string" select="'title'"/>
  <xsl:apply-templates select="db:refname[1]" mode="m:headline-title"/>
</xsl:template>

<xsl:template match="db:refname" mode="m:headline-title">
  <xsl:param name="purpose" as="xs:string" select="'title'"/>
  <xsl:apply-templates mode="m:title"/>
</xsl:template>

<xsl:template match="db:question" mode="m:headline-title">
  <xsl:param name="purpose" as="xs:string" select="'title'"/>
  <xsl:apply-templates select="*[1]" mode="m:title"/>
</xsl:template>

<!-- ============================================================ -->

<xsl:template match="*" mode="m:headline-suffix">
  <xsl:param name="purpose" as="xs:string" required="yes"/>
  <xsl:param name="title" as="node()*" required="yes"/>

  <xsl:sequence select="()"/>
</xsl:template>

<!-- ============================================================ -->

<xsl:function name="fp:document-title-properties" as="element()*" cache="yes">
  <xsl:param name="node" as="element()"/>
  <xsl:sequence select="root($node)/*/db:info/v:title"/>
</xsl:function>

<xsl:function name="fp:title-properties" as="map(*)" cache="yes">
  <xsl:param name="node" as="element()"/>

  <!-- You might think it would be convenient to accumulate the properties,
       but that requires making every property explicit on every element
       in order to prevent broader matches from overriding narrower ones.
       So there wouldn't be any point. -->

  <xsl:variable name="prop" as="element()?">
    <xsl:iterate select="(fp:document-title-properties($node), $v:title-properties)">
      <xsl:variable name="test" as="element()*">
        <xsl:evaluate context-item="$node" xpath="@xpath"/>
      </xsl:variable>

      <xsl:choose>
        <xsl:when test="$test">
          <xsl:sequence select="."/>
          <xsl:break/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:next-iteration/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:iterate>
  </xsl:variable>

  <xsl:variable name="number" as="xs:boolean"
                select="exists($prop/@number-format)
                        and (not(exists($prop/@number)) or f:is-true($prop/@number))"/>

  <xsl:variable name="format" as="xs:string?"
                select="if ($number)
                        then ($prop/@number-format, '1')[1]
                        else ()"/>

  <xsl:variable name="label-toc" as="xs:boolean"
                select="if ($prop/@label-toc)
                        then f:is-true($prop/@label-toc)
                        else f:is-true($prop/@label)"/>

  <xsl:message use-when="false()"
               select="node-name($node), ' ', f:is-true($prop/@label), ' ', $number"/>
  <xsl:message use-when="false()"
               select="$prop"/>

  <xsl:sequence select="map {
    'label':         f:is-true($prop/@label),
    'label-toc':     $label-toc,
    'number':        $number,
    'number-format': $prop/@number-format/string(),
    'inherit':       f:is-true($prop/@inherit)
    }"/>
</xsl:function>

<!-- ============================================================ -->

<xsl:template match="db:title|db:titleabbrev" mode="m:title">
  <xsl:param name="purpose" as="xs:string" required="yes"/>

  <xsl:choose>
    <xsl:when test="$purpose = 'title'">
      <xsl:apply-templates/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:variable name="title" as="item()*">
        <xsl:apply-templates/>
      </xsl:variable>
      <xsl:apply-templates select="$title" mode="mp:strip-links"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<!-- ============================================================ -->

<xsl:template xmlns:h="http://www.w3.org/1999/xhtml"
              match="h:db-footnote|h:db-annotation" mode="mp:strip-links"/>

<xsl:template xmlns:h="http://www.w3.org/1999/xhtml"
              match="h:a" mode="mp:strip-links">
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="element()" mode="mp:strip-links">
  <xsl:copy>
    <xsl:apply-templates select="@*,node()" mode="mp:strip-links"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="attribute()|text()|comment()|processing-instruction()"
              mode="mp:strip-links">
  <xsl:copy/>
</xsl:template>

</xsl:stylesheet>

units.xsl

11 functions (2 unused, 5 used only in one other module), 4 variables (1 unused)

Instructions
Variable $v:unit-scale as map(*)
Variable $vp:length-regex
Variable $vp:percent-regex
Unused
Variable $vp:relative-regex
Function f:length-units($length as xs:string?) as xs:string?
Unused
Function f:absolute-length($length as map(*)) as xs:double
Function f:relative-length($length as map(*)) as xs:double
Function f:is-empty-length($length as map(*)?) as xs:boolean
Function f:equal-lengths($a as map(*)?, $b as map(*)?) as xs:boolean
Function f:make-length#1($relative as xs:double) as map(*)
Unused
Function f:make-length#2($magnitude as xs:double, $unit as xs:string) as map(*)
Function f:make-length#3($relative as xs:double, $magnitude as xs:double, $unit as xs:string) as map(*)
Function f:length-string($length as map(*)?) as xs:string?
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:db="http://docbook.org/ns/docbook"
                xmlns:f="http://docbook.org/ns/docbook/functions"
                xmlns:v="http://docbook.org/ns/docbook/variables"
                xmlns:vp="http://docbook.org/ns/docbook/variables/private"
                xmlns:m="http://docbook.org/ns/docbook/modes"
                xmlns:map="http://www.w3.org/2005/xpath-functions/map"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns="http://www.w3.org/1999/xhtml"
                default-mode="m:docbook"
                exclude-result-prefixes="db f m map v vp xs"
                version="3.0">

<xsl:variable name="v:unit-scale" as="map(*)">
  <xsl:map>
    <xsl:map-entry key="'px'" select="1.0"/>
    <xsl:map-entry key="'in'" select="$pixels-per-inch"/>
    <xsl:map-entry key="'m'" select="$pixels-per-inch div 2.54 * 100.0"/>
    <xsl:map-entry key="'cm'" select="$pixels-per-inch div 2.54"/>
    <xsl:map-entry key="'mm'" select="$pixels-per-inch div 25.4"/>
    <xsl:map-entry key="'pt'" select="$pixels-per-inch div 72.0"/>
    <xsl:map-entry key="'pc'" select="$pixels-per-inch div 6.0"/>
    <xsl:map-entry key="'em'" select="$pixels-per-inch div 6.0"/>
    <xsl:map-entry key="'barleycorn'" select="$pixels-per-inch div 3.0"/>
  </xsl:map>
</xsl:variable>

<xsl:variable name="vp:length-regex" select="'^(\d+(\.\d+)?)\s*(\S+)?$'"/>
<xsl:variable name="vp:percent-regex" select="'^(\d+(\.\d+)?)\s*%$'"/>
<xsl:variable name="vp:relative-regex" select="'^(\d+(\.\d+)?)\s*\*(\s*\+\s*(.*))?$'"/>

<xsl:function name="f:parse-length" as="map(*)">
  <xsl:param name="length" as="xs:string"/>

  <!--
  <xsl:variable name="x" select="'3*+0.25pt'"/>
  <xsl:message select="'matches: ' || $x, matches($x, $vp:relative-regex)"/>
  <xsl:message select="'matches: ', $vp:relative-regex"/>
  <xsl:message select="'matches: ' || $x,
                       matches($x, '^(\d+(\.\d+)?)\s*\*\s*(\+\s*(.*)$)')"/>
  -->

  <xsl:variable name="length" select="normalize-space($length)"/>

  <xsl:variable name="parsed"
                select="if (matches($length, $vp:relative-regex))
                        then map { 'relative':
                                    xs:decimal(replace($length, $vp:relative-regex, '$1'))
                                 }
                        else map { 'relative': 0.0 }"/>

  <xsl:variable name="length"
                select="if (matches($length, $vp:relative-regex))
                        then replace($length, $vp:relative-regex, '$4')
                        else $length"/>

  <xsl:choose>
    <xsl:when test="$parsed?relative and $length = ''">
      <xsl:sequence select="map:put($parsed, 'magnitude', 0)
                            => map:put('unit', 'px')"/>
    </xsl:when>
    <xsl:when test="matches($length, $vp:length-regex)">
      <xsl:variable name="mag"
                    select="xs:double(replace($length, $vp:length-regex, '$1'))"/>
      <xsl:variable name="unit"
                    select="replace($length, $vp:length-regex, '$3')"/>
      <xsl:variable name="unit"
                    select="if ($unit = '')
                            then 'px'
                            else $unit"/>

      <xsl:choose>
        <xsl:when test="map:contains($v:unit-scale, $unit) or $unit = '%'">
          <xsl:sequence select="map:put($parsed, 'magnitude', $mag)
                                => map:put('unit', $unit)"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:message expand-text="yes"
                       >Unrecognized unit {$unit}, using default length</xsl:message>
          <xsl:sequence select="map:put($parsed, 'magnitude', $default-length-magnitude)
                                => map:put('unit', $default-length-unit)"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:when>
    <xsl:otherwise>
      <xsl:message expand-text="yes"
                   >Unparsable length {$length}, using default length</xsl:message>
      <xsl:sequence select="map:put($parsed, 'magnitude', $default-length-magnitude)
                            => map:put('unit', $default-length-unit)"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

<xsl:function name="f:length-units" as="xs:string?">
  <xsl:param name="length" as="xs:string?"/>
  <xsl:sequence select="if (exists($length))
                        then f:parse-length($length)?unit
                        else ()"/>
</xsl:function>

<xsl:function name="f:absolute-length" as="xs:double">
  <xsl:param name="length" as="map(*)"/>
  <xsl:choose>
    <xsl:when test="exists($length?magnitude) and exists($length?unit)
                    and map:contains($v:unit-scale, $length?unit)">
      <xsl:sequence select="round($length?magnitude * map:get($v:unit-scale, $length?unit))"/>
    </xsl:when>
    <xsl:otherwise>
      <!-- this should never happen, but ... -->
      <xsl:message>
        <xsl:text>Invalid length (</xsl:text>
        <xsl:value-of select="concat($length?magnitude, $length?unit)"/>
        <xsl:text>), returning 0 for absolute-length</xsl:text>
      </xsl:message>
      <xsl:sequence select="0"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

<xsl:function name="f:relative-length" as="xs:double">
  <xsl:param name="length" as="map(*)"/>
  <xsl:sequence select="if ($length?relative)
                        then $length?relative
                        else 0.0"/>
</xsl:function>

<xsl:function name="f:empty-length" as="map(*)">
  <xsl:sequence select="map { }"/>
</xsl:function>

<xsl:function name="f:is-empty-length" as="xs:boolean">
  <xsl:param name="length" as="map(*)?"/>
  <xsl:sequence select="empty($length)
                        or (not($length?relative) and not($length?magnitude))"/>
</xsl:function>

<xsl:function name="f:equal-lengths" as="xs:boolean">
  <xsl:param name="a" as="map(*)?"/>
  <xsl:param name="b" as="map(*)?"/>
  <xsl:choose>
    <xsl:when test="f:is-empty-length($a) and f:is-empty-length($b)">
      <xsl:sequence select="true()"/>
    </xsl:when>
    <xsl:when test="f:is-empty-length($a) and not(f:is-empty-length($b))
                    or f:is-empty-length($b) and not(f:is-empty-length($a))">
      <xsl:sequence select="false()"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:sequence select="$a?relative eq $b?relative
                            and $a?magnitude eq $b?magnitude
                            and $a?unit eq $b?unit"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

<xsl:function name="f:make-length" as="map(*)">
  <xsl:param name="relative" as="xs:double"/>
  <xsl:sequence select="map {
    'relative': $relative
    }"/>
</xsl:function>

<xsl:function name="f:make-length" as="map(*)">
  <xsl:param name="magnitude" as="xs:double"/>
  <xsl:param name="unit" as="xs:string"/>
  <xsl:sequence select="f:make-length(0.0, $magnitude, $unit)"/>
</xsl:function>

<xsl:function name="f:make-length" as="map(*)">
  <xsl:param name="relative" as="xs:double"/>
  <xsl:param name="magnitude" as="xs:double"/>
  <xsl:param name="unit" as="xs:string"/>
  <xsl:sequence select="map {
    'relative': 0.0,
    'magnitude': $magnitude,
    'unit': $unit
    }"/>
</xsl:function>

<xsl:function name="f:length-string" as="xs:string?">
  <xsl:param name="length" as="map(*)?"/>
  <xsl:if test="exists($length)">
    <xsl:variable name="rel"
                  select="if ($length?relative and $length?relative != 0.0)
                          then concat($length?relative, '*')
                          else ''"/>
    <xsl:sequence select="$rel || $length?magnitude || $length?unit"/>
  </xsl:if>
</xsl:function>

</xsl:stylesheet>

shared.xsl

2 functions (2 unused), 1 variable (1 unused), 2 params

Instructions
Param $generated-id-root
Variable $vp:gidmap
Unused
Function f:generate-id#1($node as element()) as xs:string
Function f:id#1($node as element()) as xs:string
Unused
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:db="http://docbook.org/ns/docbook"
                xmlns:f="http://docbook.org/ns/docbook/functions"
                xmlns:m="http://docbook.org/ns/docbook/modes"
                xmlns:map="http://www.w3.org/2005/xpath-functions/map"
                xmlns:vp="http://docbook.org/ns/docbook/variables/private"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns="http://www.w3.org/1999/xhtml"
                default-mode="m:docbook"
                exclude-result-prefixes="db f m map vp xs"
                version="3.0">

<xsl:param name="generated-id-root" select="'R'"/>
<!-- Historically, this was ".", but if you do that, you can't find
     elements by ID using JavaScript querySelector because "." is
     a separator in CSS. -->
<xsl:param name="generated-id-sep" select="'_'"/>

<xsl:variable name="vp:gidmap" select="map {
  'acknowledgements': 'ack',
  'appendix': 'ap',
  'book': 'bo',
  'chapter': 'ch',
  'colophon': 'co',
  'dedication': 'ded',
  'equation': 'eq',
  'example': 'ex',
  'figure': 'fig',
  'part': 'part',
  'preface': 'p',
  'procedure': 'proc',
  'refentry': 're',
  'reference': 'ref',
  'refsect1': 'rs1',
  'refsect2': 'rs2',
  'refsect3': 'rs3',
  'sect1': 's1_',
  'sect2': 's2_',
  'sect3': 's3_',
  'sect4': 's4_',
  'sect5': 's5_',
  'section': 's',
  'table': 'tab',
  'glossary': 'g',
  'glossdiv': 'gd',
  'glossentry': 'ge',
  'glossterm': 'gt',
  'bibliography': 'bi',
  'bibliodiv': 'bd'
  }"/>

<xsl:function name="f:generate-id" as="xs:string" cache="yes">
  <xsl:param name="node" as="element()"/>
  <xsl:choose>
    <xsl:when test="$node/@xml:id">
      <xsl:sequence select="string($node/@xml:id)"/>
    </xsl:when>
    <xsl:when test="empty($node/parent::*)">
      <xsl:sequence select="$generated-id-root"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:variable name="aid" select="f:generate-id($node/parent::*)"/>
      <xsl:variable name="type" select="(map:get($vp:gidmap, local-name($node)),
                                         local-name($node))[1]"/>
      <xsl:variable name="prec"
                    select="$node/preceding-sibling::*[node-name(.)=node-name($node)]"/>
      <xsl:sequence
          select="$aid || $generated-id-sep || $type || string(count($prec)+1)"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

<xsl:function name="f:id" as="xs:string" cache="yes">
  <xsl:param name="node" as="element()"/>
  <xsl:sequence select="if ($node/@xml:id)
                        then $node/@xml:id
                        else f:generate-id($node)"/>
</xsl:function>

</xsl:stylesheet>

gentext.xsl

8 functions, 2 variables, 1 param

Instructions
Variable $v:locales as xs:string+ [static]
Variable $vp:l10n as map(*)
Function fp:load-locales() as map(*)+
Function fp:localization#1($lang as xs:string) as element(l:l10n)?
Function fp:localization#2($lang as xs:string, $warn as xs:boolean) as element(l:l10n)?
Function fp:existing-localization($lang as xs:string) as element(l:l10n)
Function f:gentext#2($node as element(), $context as xs:string) as item()*
Function fp:gentext($node as element(), $context as xs:string, $key as xs:string, $report-errors as xs:boolean) as item()*
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:db="http://docbook.org/ns/docbook"
                xmlns:f="http://docbook.org/ns/docbook/functions"
                xmlns:fp="http://docbook.org/ns/docbook/functions/private"
                xmlns:l="http://docbook.org/ns/docbook/l10n"
                xmlns:m="http://docbook.org/ns/docbook/modes"
                xmlns:map="http://www.w3.org/2005/xpath-functions/map"
                xmlns:n="http://docbook.org/ns/docbook/l10n/number"
                xmlns:t="http://docbook.org/ns/docbook/l10n/title"
                xmlns:v="http://docbook.org/ns/docbook/variables"
                xmlns:vp="http://docbook.org/ns/docbook/variables/private"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns="http://www.w3.org/1999/xhtml"
                default-mode="m:docbook"
                exclude-result-prefixes="db f fp l m map n t v vp xs"
                version="3.0">

<xsl:param name="default-language" select="'en'"/>

<xsl:key name="l:string" match="l:string" use="@key"/>
<xsl:key name="l:style" match="l:style" use="@key"/>
<xsl:key name="l:gentext" match="l:gentext" use="@name"/>
<xsl:key name="l:tokens" match="l:tokens" use="../@name || '/' || @key"/>

<xsl:variable name="v:locales" as="xs:string+" static="yes"
              select="('en', 'fr', 'cs')"/>

<xsl:variable name="vp:l10n" as="map(*)"
              select="map:merge(fp:load-locales())"/>

<xsl:function name="fp:load-locales" as="map(*)+">
  <xsl:for-each select="$v:locales">
    <xsl:variable name="locale" select="."/>
    <xsl:variable name="doc" select="doc('../locale/' || $locale || '.xml')"/>
    <xsl:sequence select="map:entry($doc/l:l10n/@language, $doc)"/>
  </xsl:for-each>
</xsl:function>

<xsl:function name="f:language" as="xs:string" cache="yes">
  <xsl:param name="node" as="node()"/>

  <xsl:variable name="nearest-lang"
                select="$node/ancestor-or-self::*[@xml:lang][1]"/>

  <xsl:choose>
    <xsl:when test="$nearest-lang">
      <xsl:sequence select="$nearest-lang/@xml:lang/string()"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:sequence select="$default-language"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

<xsl:function name="fp:localization" as="element(l:l10n)?">
  <xsl:param name="lang" as="xs:string"/>
  <xsl:sequence select="fp:localization($lang, true())"/>
</xsl:function>

<xsl:function name="fp:localization" as="element(l:l10n)?">
  <xsl:param name="lang" as="xs:string"/>
  <xsl:param name="warn" as="xs:boolean"/>

  <xsl:variable name="l10n" select="map:get($vp:l10n, $lang)/l:l10n"/>

  <xsl:if test="$warn and empty($l10n)">
    <xsl:message expand-text="yes">No localization data for {$lang}</xsl:message>
  </xsl:if>

  <xsl:sequence select="$l10n"/>
</xsl:function>

<xsl:function name="fp:existing-localization" as="element(l:l10n)">
  <xsl:param name="lang" as="xs:string"/>

  <xsl:variable name="l10n" select="fp:localization($lang)"/>
  <xsl:variable name="l10n"
                select="if (empty($l10n) and $default-language ne $lang)
                        then fp:localization($default-language)
                        else $l10n"/>
  <xsl:sequence select="if (empty($l10n))
                        then fp:localization('en')
                        else $l10n"/>
</xsl:function>

<xsl:function name="f:gentext" as="item()*">
  <xsl:param name="node" as="element()"/>
  <xsl:param name="context" as="xs:string"/>
  <xsl:sequence select="fp:gentext($node, $context, local-name($node), true())"/>
</xsl:function>

<xsl:function name="f:gentext" as="item()*">
  <xsl:param name="node" as="element()"/>
  <xsl:param name="context" as="xs:string"/>
  <xsl:param name="key" as="xs:string"/>
  <xsl:sequence select="fp:gentext($node, $context, $key, true())"/>
</xsl:function>

<xsl:function name="fp:gentext" as="item()*">
  <xsl:param name="node" as="element()"/>
  <xsl:param name="context" as="xs:string"/>
  <xsl:param name="key" as="xs:string"/>
  <xsl:param name="report-errors" as="xs:boolean"/>

  <xsl:variable name="l10n"
                select="fp:existing-localization(f:language($node))"/>

  <xsl:variable name="tokens"
                select="key('l:tokens', $context || '/' || $key, root($l10n))"/>

  <xsl:if test="$report-errors and count($tokens) gt 1">
    <xsl:message
        select="'Multiple tokens match '
                || $context || '/' || $key
                || ' for ' || f:language($node)"/>
  </xsl:if>

  <xsl:choose>
    <xsl:when test="empty($tokens) and not($report-errors)">
      <xsl:sequence select="()"/>
    </xsl:when>
    <xsl:when test="empty($tokens)">
      <xsl:if test="$report-errors">
      <xsl:message select="'No tokens match '
                           || $context || '/' || $key
                           || ' for ' || f:language($node)
                           || ' using MISSING'"/>
      </xsl:if>
      <xsl:sequence select="'MISSING'"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:sequence select="$tokens[1]/node()"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

</xsl:stylesheet>

functions.xsl

41 functions (6 unused, 2 shadow, 9 used only in one other module), 3 variables (1 shadow)

Instructions
Variable $fp:class
Function f:attributes#2($node as element(), $attributes as attribute()*) as attribute()*
Function f:attributes#4($node as element(), $attributes as attribute()*, $extra-classes as xs:string*, $exclude-classes as xs:string*) as attribute()*
Function f:orderedlist-startingnumber($list as element(db:orderedlist)) as xs:integer
Function f:l10n-language($target as element()) as xs:string
Function f:check-gentext($node as element(), $context as xs:string, $key as xs:string) as item()*
Function f:gentext-letters($node as element()) as element(l:letters)
Unused
Function f:gentext-letters-for-language($lang as xs:string) as element(l:letters)
Function fp:properties($context as element(), $properties as array(map(*))) as map(*)
Function f:date-format($context as element()) as xs:string
Function f:post-label-punctuation#1($node as element()) as xs:string?
Used by: template
Used in: modules/titles.xsl
Function f:post-label-punctuation#2($node as element(), $context as xs:string?) as xs:string?
Function fp:replace-element#3($lines as array(*), $elemno as xs:integer, $new-elem as item()*) as array(*)
Used by: fp:inject()
Function fp:replace-element#5($array as array(*), $elemno as xs:integer, $count as xs:integer, $new-elem as item()*, $newarray as array(*)) as array(*)
Function f:target($id as xs:string, $context as node()) as element()*
Variable $vp:gidmap
Function fp:pi-from-list($pis as processing-instruction()*, $property as xs:string, $default as xs:string*) as xs:string*
Function fp:pi-attributes($pis as processing-instruction()*, $pimap as map(*)) as map(*)?
Variable $vp:pi-match
Function fp:pi-pi-attributes($pimap as map(*), $text as xs:string) as map(*)
Function f:spaces($length as item()*) as xs:string?
Function fp:lookup-string($context as element(), $lookup as element(), $table-name as xs:string) as node()*
Unused
Function f:label-separator($node as element()) as node()*
Function f:number-separator($node as element()) as node()*
Unused
Function f:intra-number-separator($node as element()) as node()*
Function fp:label-format($node as element()) as node()*
Unused
Function fp:parse-key-value-pairs#1($strings as xs:string*) as map(xs:string,xs:string)
Function fp:parse-key-value-pairs#2($strings as xs:string*, $map as map(xs:string,xs:string)) as map(xs:string,xs:string)
Function f:refsection($node as element()) as xs:boolean
Function f:section($node as element()) as xs:boolean
Unused
Function f:section-depth($node as element()?) as xs:integer
Function f:step-number($node as element(db:step)) as xs:integer+
Function f:step-numeration($node as element(db:step)) as xs:string
Function f:orderedlist-item-number($node as element(db:listitem)) as xs:integer+
Function f:orderedlist-item-numeration($node as element(db:listitem)) as xs:string
Function f:tokenize-on-char($string as xs:string, $char as xs:string) as xs:string*
Used by: template
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:array="http://www.w3.org/2005/xpath-functions/array"
                xmlns:db="http://docbook.org/ns/docbook"
                xmlns:f="http://docbook.org/ns/docbook/functions"
                xmlns:fp="http://docbook.org/ns/docbook/functions/private"
                xmlns:l="http://docbook.org/ns/docbook/l10n"
                xmlns:m="http://docbook.org/ns/docbook/modes"
                xmlns:map="http://www.w3.org/2005/xpath-functions/map"
                xmlns:mp="http://docbook.org/ns/docbook/modes/private"
                xmlns:v="http://docbook.org/ns/docbook/variables"
                xmlns:vp="http://docbook.org/ns/docbook/variables/private"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns="http://www.w3.org/1999/xhtml"
                default-mode="m:docbook"
                exclude-result-prefixes="array db f fp l m map mp v vp xs"
                version="3.0">

<xsl:variable name="fp:class" select="QName('', 'class')"/>

<xsl:function name="f:attributes" as="attribute()*">
  <xsl:param name="node" as="element()"/>
  <xsl:param name="attributes" as="attribute()*"/>
  <xsl:sequence select="f:attributes($node, $attributes, local-name($node), ())"/>
</xsl:function>

<xsl:function name="f:attributes" as="attribute()*">
  <xsl:param name="node" as="element()"/>
  <xsl:param name="attributes" as="attribute()*"/>
  <xsl:param name="extra-classes" as="xs:string*"/>
  <xsl:param name="exclude-classes" as="xs:string*"/>

  <!--
  <xsl:message>
    <xsl:text>f:attributes(</xsl:text>
    <xsl:value-of select="node-name($node)"/>
    <xsl:text>,</xsl:text>
    <xsl:sequence select="$attributes"/>
    <xsl:text>,</xsl:text>
    <xsl:sequence select="$extra-classes"/>
    <xsl:text>,</xsl:text>
    <xsl:sequence select="$exclude-classes"/>
    <xsl:text>)</xsl:text>
  </xsl:message>
  -->

  <!-- combine duplicates -->
  <xsl:variable name="names"
                select="distinct-values($attributes/node-name())"/>
  <xsl:for-each select="$names">
    <xsl:variable name="name" select="."/>
    <xsl:variable name="values" as="xs:string*"
                  select="$attributes[node-name()=$name]/string()"/>
    <xsl:if test="exists($values)">
      <xsl:attribute name="{$name}"
                     select="string-join($values, ' ')"/>
    </xsl:if>
  </xsl:for-each>

  <!-- if there isn't a class attribute, manufacture one -->
  <xsl:if test="not($fp:class = $attributes/node-name())">
    <xsl:variable name="roles"
                  select="(tokenize(normalize-space(string-join($extra-classes, ' '))),
                           tokenize(normalize-space($node/@role)),
                           if ($node/@revisionflag)
                           then 'rev'||$node/@revisionflag
                           else ())"/>
    <xsl:variable name="exclude" 
                  select="tokenize(normalize-space(string-join($exclude-classes, ' ')))"/>
    <!-- sort them and make them unique -->
    <xsl:variable name="classes" as="xs:string*">
      <xsl:for-each select="distinct-values($roles)">
        <xsl:sort select="."/>
        <xsl:if test="not(. = $exclude)">
          <xsl:sequence select="."/>
        </xsl:if>
      </xsl:for-each>
    </xsl:variable>

    <xsl:if test="exists($classes)">
      <xsl:attribute name="class" select="string-join($classes, ' ')"/>
    </xsl:if>
  </xsl:if>
</xsl:function>

<xsl:function name="f:is-true" as="xs:boolean">
  <xsl:param name="value"/>

  <xsl:choose>
    <xsl:when test="empty($value)">
      <xsl:value-of select="false()"/>
    </xsl:when>
    <xsl:when test="$value castable as xs:boolean">
      <xsl:value-of select="xs:boolean($value)"/>
    </xsl:when>
    <xsl:when test="$value castable as xs:integer">
      <xsl:value-of select="xs:integer($value) != 0"/>
    </xsl:when>
    <xsl:when test="string($value) = ('true', 'yes')">
      <xsl:value-of select="true()"/>
    </xsl:when>
    <xsl:when test="string($value) = ('false', 'no')">
      <xsl:value-of select="false()"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:message expand-text="yes"
                   >Warning: interpreting ‘{$value}’ as true.</xsl:message>
      <xsl:value-of select="true()"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

<xsl:function name="f:orderedlist-startingnumber" as="xs:integer">
  <xsl:param name="list" as="element(db:orderedlist)"/>

  <xsl:choose>
    <xsl:when test="not($list/@continuation = 'continues')">
      <xsl:sequence select="1"/>
    </xsl:when>
    <xsl:when test="empty($list/preceding::db:orderedlist)">
      <xsl:message>
        <xsl:text>Warning: orderedlist continuation=continues, </xsl:text>
        <xsl:text>but no preceding list</xsl:text>
      </xsl:message>
      <xsl:sequence select="1"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:variable name="plist" select="$list/preceding::db:orderedlist[1]"/>
      <xsl:sequence select="f:orderedlist-startingnumber($plist)
                            + count($plist/db:listitem)"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

<xsl:function name="f:l10n-language" as="xs:string">
  <xsl:param name="target" as="element()"/>

  <xsl:variable name="mc-language" as="xs:string"
                select="($gentext-language,
                        $target/ancestor-or-self::*[@xml:lang][1]/@xml:lang,
                        $default-language)[1]"/>

  <xsl:variable name="language" select="translate($mc-language,
                                        'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
                                        'abcdefghijklmnopqrstuvwxyz')"/>

  <xsl:variable name="adjusted-language"
                select="if (contains($language, '-'))
                        then substring-before($language, '-')
                             || '_' || substring-after($language, '-')
                        else $language"/>

  <xsl:choose>
    <xsl:when test="fp:localization($adjusted-language, false())">
      <xsl:sequence select="$adjusted-language"/>
    </xsl:when>
    <!-- try just the lang code without country -->
    <xsl:when test="fp:localization(substring-before($adjusted-language,'_'), false())">
      <xsl:sequence select="substring-before($adjusted-language,'_')"/>
    </xsl:when>
    <!-- or use the default -->
    <xsl:otherwise>
      <xsl:message>
        <xsl:text>No localization exists for "</xsl:text>
        <xsl:sequence select="$adjusted-language"/>
        <xsl:text>" or "</xsl:text>
        <xsl:sequence select="substring-before($adjusted-language,'_')"/>
        <xsl:text>". Using default "</xsl:text>
        <xsl:sequence select="$default-language"/>
        <xsl:text>".</xsl:text>
      </xsl:message>
      <xsl:sequence select="$default-language"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

<xsl:function name="f:check-gentext" as="item()*">
  <xsl:param name="node" as="element()"/>
  <xsl:param name="context" as="xs:string"/>
  <xsl:param name="key" as="xs:string"/>
  <xsl:sequence select="fp:gentext($node, $context, $key, false())"/>
</xsl:function>

<xsl:function name="f:gentext-letters" as="element(l:letters)">
  <xsl:param name="node" as="element()"/>
  <xsl:sequence select="f:gentext-letters-for-language(f:language($node))"/>
</xsl:function>

<xsl:function name="f:gentext-letters-for-language" as="element(l:letters)">
  <xsl:param name="lang" as="xs:string"/>

  <xsl:variable name="l10n"
                select="fp:existing-localization($lang)"/>

  <xsl:variable name="letters"
                select="$l10n/l:letters"/>

  <xsl:if test="empty($letters)">
    <xsl:message select="'No letters for', $lang"/>
  </xsl:if>

  <xsl:variable name="letters"
                select="if (empty($letters))
                        then f:gentext-letters-for-language('en')
                        else $letters"/>

  <xsl:if test="count($letters) gt 1">
    <xsl:message
        select="'Multiple letters for localization:', $lang"/>
  </xsl:if>

  <xsl:sequence select="$letters[1]"/>
</xsl:function>

<xsl:function name="fp:properties" as="map(*)">
  <xsl:param name="context" as="element()"/>
  <xsl:param name="properties" as="array(map(*))"/>

  <xsl:variable name="props" as="map(*)*">
    <xsl:for-each select="1 to array:size($properties)">
      <xsl:variable name="map" select="array:get($properties, .)"/>
      <xsl:variable name="nodes" as="node()*">
        <xsl:evaluate context-item="$context" xpath="$map?xpath"/>
      </xsl:variable>
      <xsl:if test="exists($nodes)">
        <xsl:sequence select="$map"/>
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>

  <xsl:choose>
    <xsl:when test="empty($props)">
      <xsl:message use-when="'properties' = $v:debug"
          select="'No properties for ' || local-name($context)"/>
      <xsl:sequence select="map { }"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:sequence select="$props[1]"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

<xsl:function name="f:date-format" as="xs:string">
  <xsl:param name="context" as="element()"/>

  <xsl:variable name="format"
                select="f:pi($context, 'date-format')"/>

  <xsl:choose>
    <xsl:when test="$context/*">
      <xsl:sequence select="'apply-templates'"/>
    </xsl:when>
    <xsl:when test="string($context) castable as xs:dateTime">
      <xsl:choose>
        <xsl:when test="$format">
          <xsl:sequence select="$format"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:sequence select="$date-dateTime-format"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:when>
    <xsl:when test="string($context) castable as xs:date">
      <xsl:choose>
        <xsl:when test="$format">
          <xsl:sequence select="$format"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:sequence select="$date-date-format"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:when>
    <xsl:otherwise>
      <xsl:sequence select="'apply-templates'"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

<!-- ============================================================ -->

<xsl:function name="f:post-label-punctuation" as="xs:string?">
  <xsl:param name="node" as="element()"/>
  <xsl:sequence select="f:post-label-punctuation($node, ())"/>
</xsl:function>

<xsl:function name="f:post-label-punctuation" as="xs:string?">
  <xsl:param name="node" as="element()"/>
  <xsl:param name="context" as="xs:string?"/>
  <xsl:sequence select="if ($context = 'xref')
                        then ()
                        else '.'"/>
</xsl:function>

<!-- ============================================================ -->

<xsl:function name="fp:replace-element" as="array(*)">
  <xsl:param name="lines" as="array(*)"/>
  <xsl:param name="elemno" as="xs:integer"/>
  <xsl:param name="new-elem" as="item()*"/>
  <xsl:sequence
      select="fp:replace-element($lines, $elemno, 1, $new-elem, [])"/>
</xsl:function>

<xsl:function name="fp:replace-element" as="array(*)">
  <!-- See https://saxonica.plan.io/issues/4500 -->
  <!-- reimplement this with array:join when that but is fixed -->
  <xsl:param name="array" as="array(*)"/>
  <xsl:param name="elemno" as="xs:integer"/>
  <xsl:param name="count" as="xs:integer"/>
  <xsl:param name="new-elem" as="item()*"/>
  <xsl:param name="newarray" as="array(*)"/>

  <xsl:choose>
    <xsl:when test="$count gt array:size($array)">
      <xsl:sequence select="$newarray"/>
    </xsl:when>
    <xsl:when test="$count = $elemno">
      <xsl:sequence
          select="fp:replace-element($array, $elemno, $count+1, $new-elem,
                                     array:append($newarray, $new-elem))"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:sequence
          select="fp:replace-element($array, $elemno, $count+1, $new-elem,
                                     array:append($newarray, $array($count)))"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

<xsl:function name="f:target" as="element()*" cache="yes">
  <xsl:param name="id" as="xs:string"/>
  <xsl:param name="context" as="node()"/>
  <xsl:sequence select="key('id', $id, root($context))"/>
</xsl:function>

<xsl:function name="f:href" as="xs:string" cache="yes">
  <xsl:param name="context" as="node()"/>
  <xsl:param name="node" as="element()"/>
  <xsl:sequence select="'#' || f:generate-id($node)"/>
</xsl:function>

<xsl:variable name="vp:gidmap" select="map {
  'acknowledgements': 'ack',
  'appendix': 'ap',
  'book': 'bo',
  'chapter': 'ch',
  'colophon': 'co',
  'dedication': 'ded',
  'equation': 'eq',
  'example': 'ex',
  'figure': 'fig',
  'part': 'part',
  'preface': 'p',
  'procedure': 'proc',
  'refentry': 're',
  'reference': 'ref',
  'refsect1': 'rs1',
  'refsect2': 'rs2',
  'refsect3': 'rs3',
  'sect1': 's1_',
  'sect2': 's2_',
  'sect3': 's3_',
  'sect4': 's4_',
  'sect5': 's5_',
  'section': 's',
  'table': 'tab',
  'glossary': 'g',
  'glossdiv': 'gd',
  'glossentry': 'ge',
  'glossterm': 'gt',
  'bibliography': 'bi',
  'bibliodiv': 'bd'
  }"/>

<xsl:function name="f:generate-id" as="xs:string" cache="yes">
  <xsl:param name="node" as="element()"/>
  <xsl:choose>
    <xsl:when test="$node/@xml:id">
      <xsl:sequence select="string($node/@xml:id)"/>
    </xsl:when>
    <xsl:when test="empty($node/parent::*)">
      <xsl:sequence select="$generated-id-root"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:variable name="aid" select="f:generate-id($node/parent::*)"/>
      <xsl:variable name="type" select="(map:get($vp:gidmap, local-name($node)),
                                         local-name($node))[1]"/>
      <xsl:variable name="prec"
                    select="$node/preceding-sibling::*[node-name(.)=node-name($node)]"/>
      <xsl:sequence
          select="$aid || $generated-id-sep || $type || string(count($prec)+1)"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

<xsl:function name="f:id" as="xs:string" cache="yes">
  <xsl:param name="node" as="element()"/>
  <xsl:sequence select="if ($node/@xml:id)
                        then $node/@xml:id
                        else f:generate-id($node)"/>
</xsl:function>

<xsl:function name="f:pi" as="xs:string?">
  <xsl:param name="context" as="node()?"/>
  <xsl:param name="property" as="xs:string"/>
  <xsl:sequence select="f:pi($context, $property, ())"/>
</xsl:function>

<xsl:function name="f:pi" as="xs:string*">
  <xsl:param name="context" as="node()?"/>
  <xsl:param name="property" as="xs:string"/>
  <xsl:param name="default" as="xs:string*"/>

  <xsl:choose>
    <xsl:when test="empty($context)">
      <xsl:sequence select="$default"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:sequence select="fp:pi-from-list(($context/processing-instruction('db'),
                                             root($context)/processing-instruction('db')),
                                            $property, $default)"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

<xsl:function name="fp:pi-from-list" as="xs:string*">
  <xsl:param name="pis" as="processing-instruction()*"/>
  <xsl:param name="property" as="xs:string"/>
  <xsl:param name="default" as="xs:string*"/>

  <xsl:variable name="value"
                select="f:pi-attributes($pis)/@*[local-name(.) = $property]/string()"/>

  <xsl:sequence select="if (empty($value))
                        then $default
                        else $value"/>
</xsl:function>

<xsl:function name="f:pi-attributes" as="element()?">
  <xsl:param name="pis" as="processing-instruction()*"/>

  <xsl:variable name="attributes"
                select="fp:pi-attributes($pis, map { })"/>

  <xsl:element name="pis" namespace="">
    <xsl:for-each select="map:keys($attributes)">
      <xsl:attribute name="{.}" select="map:get($attributes, .)"/>
    </xsl:for-each>
  </xsl:element>
</xsl:function>

<xsl:function name="fp:pi-attributes" as="map(*)?">
  <xsl:param name="pis" as="processing-instruction()*"/>
  <xsl:param name="pimap" as="map(*)"/>

  <xsl:choose>
    <xsl:when test="empty($pis)">
      <xsl:sequence select="$pimap"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:variable name="map" select="fp:pi-pi-attributes($pimap,
                                          normalize-space($pis[1]))"/>
      <xsl:sequence select="fp:pi-attributes(subsequence($pis, 2), $map)"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

<xsl:variable name="vp:pi-match"
              select="'^.*?(\c+)=[''&quot;](.*?)[''&quot;](.*)$'"/>
<xsl:function name="fp:pi-pi-attributes" as="map(*)">
  <xsl:param name="pimap" as="map(*)"/>
  <xsl:param name="text" as="xs:string"/>

  <xsl:choose>
    <xsl:when test="matches($text, $vp:pi-match)">
      <xsl:variable name="aname" select="replace($text, $vp:pi-match, '$1')"/>
      <xsl:variable name="avalue" select="replace($text, $vp:pi-match, '$2')"/>
      <xsl:variable name="rest" select="replace($text, $vp:pi-match, '$3')"/>
      <xsl:sequence select="fp:pi-pi-attributes(map:put($pimap, $aname, $avalue),
                                                $rest)"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:sequence select="$pimap"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

<xsl:function name="f:spaces" as="xs:string?">
  <xsl:param name="length" as="item()*"/>

  <xsl:choose>
    <xsl:when test="empty($length)"/>
    <xsl:when test="count($length) gt 1">
      <xsl:sequence
          select="f:spaces(string-join($length ! string(.), ''))"/>
    </xsl:when>
    <xsl:when test="$length castable as xs:integer">
      <xsl:variable name="length" select="xs:integer($length)"/>
      <xsl:choose>
        <xsl:when test="$length lt 0"/>
        <xsl:when test="$length lt 10">
          <xsl:sequence select="substring('          ', 1, $length)"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:sequence select="'          ' || f:spaces($length - 10)"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:when>
    <xsl:otherwise>
      <xsl:sequence select="f:spaces(string-length(string($length)))"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

<!-- ============================================================ -->

<xsl:function name="fp:lookup-string" as="node()*">
  <xsl:param name="context" as="element()"/>
  <xsl:param name="lookup" as="element()"/>
  <xsl:param name="table-name" as="xs:string"/>

  <xsl:variable name="value"
                select="$lookup/*[node-name(.)=node-name($context)]"/>

  <xsl:if test="count($value) gt 1">
    <xsl:message expand-text="yes"
                 >Duplicate {$table-name} for {node-name($context)}</xsl:message>
  </xsl:if>

  <xsl:sequence select="if (empty($value))
                        then $lookup/db:_default/node()
                        else $value[1]/node()"/>
</xsl:function>

<xsl:function name="fp:separator" as="node()*">
  <xsl:param name="node" as="element()"/>
  <xsl:param name="context" as="xs:string"/>
  <xsl:choose>
    <xsl:when test="f:check-gentext($node, $context, local-name($node))">
      <xsl:sequence
          select="f:gentext($node, $context, local-name($node))"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:sequence
          select="f:gentext($node, $context, '_default')"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

<xsl:function name="f:label-separator" as="node()*">
  <xsl:param name="node" as="element()"/>
  <xsl:sequence select="fp:separator($node, 'label-separator')"/>
</xsl:function>

<xsl:function name="f:number-separator" as="node()*">
  <xsl:param name="node" as="element()"/>
  <xsl:sequence select="fp:separator($node, 'number-separator')"/>
</xsl:function>

<xsl:function name="f:intra-number-separator" as="node()*">
  <xsl:param name="node" as="element()"/>
  <xsl:sequence select="fp:separator($node, 'intra-number-separator')"/>
</xsl:function>

<xsl:function name="fp:label-format" as="node()*">
  <xsl:param name="node" as="element()"/>
  <xsl:sequence select="fp:separator($node, 'label-format')"/>
</xsl:function>

<xsl:function name="fp:parse-key-value-pairs" as="map(xs:string,xs:string)">
  <xsl:param name="strings" as="xs:string*"/>
  <xsl:sequence select="fp:parse-key-value-pairs($strings, map { })"/>
</xsl:function>

<xsl:function name="fp:parse-key-value-pairs" as="map(xs:string,xs:string)">
  <xsl:param name="strings" as="xs:string*"/>
  <xsl:param name="map" as="map(xs:string,xs:string)"/>

  <xsl:variable name="car" select="$strings[1]"/>
  <xsl:variable name="cdr" select="subsequence($strings, 2)"/>

  <xsl:variable name="key" select="if (contains($car, ':'))
                                   then substring-before($car, ':')
                                   else '_default'"/>
  <xsl:variable name="value" select="if (contains($car, ':'))
                                     then substring-after($car, ':')
                                     else $car"/>

  <xsl:choose>
    <xsl:when test="empty($car)">
      <xsl:sequence select="$map"/>
    </xsl:when>
    <xsl:when test="map:contains($map, $key)">
      <xsl:message select="'Warning: ignoring duplicate key:', $key"/>
      <xsl:sequence select="fp:parse-key-value-pairs($cdr, $map)"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:sequence select="fp:parse-key-value-pairs($cdr,
                               map:put($map, $key, $value))"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

<xsl:function name="f:refsection" as="xs:boolean">
  <xsl:param name="node" as="element()"/>
  <xsl:sequence select="$node/self::db:refsection
                        or $node/self::db:refsect1
                        or $node/self::db:refsect2
                        or $node/self::db:refsect3"/>
</xsl:function> 

<xsl:function name="f:section" as="xs:boolean" visibility="public">
  <xsl:param name="node" as="element()"/>
  <xsl:sequence select="$node/self::db:section
                        or $node/self::db:sect1
                        or $node/self::db:sect2
                        or $node/self::db:sect3
                        or $node/self::db:sect4
                        or $node/self::db:sect5
                        or f:refsection($node)"/>
</xsl:function>

<xsl:function name="f:section-depth" as="xs:integer" visibility="public">
  <xsl:param name="node" as="element()?"/>
  <xsl:choose>
    <xsl:when test="empty($node)">
      <xsl:value-of select="0"/>
    </xsl:when>
    <xsl:when test="$node/self::db:section">
      <xsl:value-of select="count($node/ancestor::db:section) + 1"/>
    </xsl:when>
    <xsl:when test="$node/self::db:sect1 or $node/self::db:sect2
                    or $node/self::db:sect3 or $node/self::db:sect4
                    or $node/self::db:sect5">
      <xsl:value-of select="xs:integer(substring(local-name($node), 5))"/>
    </xsl:when>
    <xsl:when test="$node/self::db:refsection">
      <xsl:value-of select="count($node/ancestor::db:refsection)+1"/>
    </xsl:when>
    <xsl:when test="$node/self::db:refsect1 or $node/self::db:refsect2
                    or $node/self::db:refsect3">
      <xsl:value-of select="xs:integer(substring(local-name($node), 8))"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:sequence select="f:section-depth($node/parent::*)"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

<xsl:function name="f:step-number" as="xs:integer+">
  <xsl:param name="node" as="element(db:step)"/>
  <xsl:iterate select="reverse($node/ancestor-or-self::*)">
    <xsl:param name="number" select="()"/>
    <xsl:choose>
      <xsl:when test="self::db:procedure">
        <xsl:sequence select="$number"/>
        <xsl:break/>
      </xsl:when>
      <xsl:when test="self::db:step">
        <xsl:next-iteration>
          <xsl:with-param name="number"
                          select="(count(preceding-sibling::db:step)+1, $number)"/>
        </xsl:next-iteration>
      </xsl:when>
      <xsl:otherwise>
        <xsl:next-iteration>
          <xsl:with-param name="number" select="$number"/>
        </xsl:next-iteration>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:iterate>
</xsl:function>

<xsl:function name="f:step-numeration" as="xs:string">
  <xsl:param name="node" as="element(db:step)"/>
  <xsl:variable name="depth"
                select="count(f:step-number($node))"/>
  <xsl:variable name="depth"
                select="$depth
                        mod string-length($procedure-step-numeration)"/>
  <xsl:variable name="depth"
                select="if ($depth eq 0)
                        then string-length($procedure-step-numeration)
                        else $depth"/>
  <xsl:sequence select="substring($procedure-step-numeration, $depth, 1)"/>
</xsl:function>

<xsl:function name="f:orderedlist-item-number" as="xs:integer+">
  <xsl:param name="node" as="element(db:listitem)"/>
  <xsl:iterate select="reverse($node/ancestor-or-self::*)">
    <xsl:param name="number" select="()"/>
    <xsl:on-completion select="$number"/>
    <xsl:choose>
      <xsl:when test="self::db:listitem[parent::db:orderedlist]">
        <xsl:next-iteration>
          <xsl:with-param name="number"
                          select="(count(preceding-sibling::db:listitem)
                                   + f:orderedlist-startingnumber(parent::db:orderedlist),
                                   $number)"/>
        </xsl:next-iteration>
      </xsl:when>
      <xsl:otherwise>
        <xsl:next-iteration>
          <xsl:with-param name="number" select="$number"/>
        </xsl:next-iteration>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:iterate>
</xsl:function>

<xsl:function name="f:orderedlist-item-numeration" as="xs:string">
  <xsl:param name="node" as="element(db:listitem)"/>
  <xsl:variable name="depth"
                select="count(f:orderedlist-item-number($node))"/>
  <xsl:variable name="depth"
                select="$depth
                        mod string-length($orderedlist-item-numeration)"/>
  <xsl:variable name="depth"
                select="if ($depth eq 0)
                        then string-length($orderedlist-item-numeration)
                        else $depth"/>
  <xsl:sequence select="substring($orderedlist-item-numeration, $depth, 1)"/>
</xsl:function>

<xsl:function name="f:tokenize-on-char" as="xs:string*">
  <xsl:param name="string" as="xs:string"/>
  <xsl:param name="char" as="xs:string"/>

  <xsl:variable name="ch" select="substring($char||' ', 1, 1)"/>

  <xsl:variable name="tchar"
                select="if ($ch = ('.', '?', '*', '{', '}', '\', '\[', '\]'))
                        then '\' || $ch
                        else $ch"/>

  <xsl:sequence select="tokenize($string, $tchar)"/>
</xsl:function>

</xsl:stylesheet>

toc.xsl

30 templates, 1 FIXME: comment

Instructions
Template match ≅ *
Mode: m:toc
Matches: *
Template match ≅ *
Template match ≅ db:book|db:part|db:reference|d…
Mode: m:toc
Matches: db:book, db:part, db:reference, db:set
Template match ≅ db:acknowledgements|db:bibliod…
Mode: m:toc
Matches: db:acknowledgements, db:bibliodiv, db:colophon, db:dedication, db:glossdiv, db:indexdiv, db:partintro
Template match ≅ db:equation|db:example|db:figu…
Mode: m:toc
Matches: db:equation, db:example, db:figure, db:formalgroup, db:procedure, db:table
Template match ≅ db:article
Mode: m:toc
Matches: db:article
Template match ≅ db:topic
Mode: m:toc
Matches: db:topic
Template match ≅ db:appendix|db:chapter|db:pref…
Mode: m:toc
Matches: db:appendix, db:chapter, db:preface
Template match ≅ db:bibliography|db:glossary|db…
Mode: m:toc
Matches: db:bibliography, db:glossary, db:index
Template match ≅ db:refentry
Mode: m:toc
Matches: db:refentry
Template match ≅ db:refsect1|db:refsect2|db:ref…
Mode: m:toc
Matches: db:refsect1, db:refsect2, db:refsect3, db:refsection
Template match ≅ db:sect1|db:sect2|db:sect3|db:…
Mode: m:toc
Matches: db:sect1, db:sect2, db:sect3, db:sect4, db:sect5, db:section
Template match ≅ db:refsect1|db:refsect2|db:ref…
Mode: m:toc
Matches: db:refsect1, db:refsect2, db:refsect3, db:refsection
Template match ≅ *
Mode: m:list-of-figures
Matches: *
Template match ≅ db:book|db:set
Mode: m:list-of-figures
Matches: db:book, db:set
Template match ≅ *
Mode: m:list-of-tables
Matches: *
Template match ≅ db:book|db:set
Mode: m:list-of-tables
Matches: db:book, db:set
Template match ≅ *
Mode: m:list-of-examples
Matches: *
Template match ≅ db:book|db:set
Mode: m:list-of-examples
Matches: db:book, db:set
Template match ≅ *
Mode: m:list-of-equations
Matches: *
Template match ≅ db:book|db:set
Mode: m:list-of-equations
Matches: db:book, db:set
Template match ≅ *
Mode: m:list-of-procedures
Matches: *
Template match ≅ db:book|db:set
Mode: m:list-of-procedures
Matches: db:book, db:set
Template tp:toc match ≅
Used by: template
Mode: m:docbook
Template match ≅ db:refentry
Mode: m:toc-entry
Priority: 100
Matches: db:refentry
Template match ≅ *
Calls: f:id()
Mode: m:toc-entry
Matches: *
Template match ≅ *
Mode: m:toc-entry
Priority: 10
Matches: *
Template match ≅ db:bibliodiv|db:colophon|db:gl…
Mode: m:toc-entry
Matches: db:bibliodiv, db:colophon, db:glossdiv, db:indexdiv
Template match ≅ db:toc|db:tocdiv
Mode: m:docbook
Matches: db:toc, db:tocdiv
Template match ≅ db:tocentry
Mode: m:docbook
Matches: db:tocentry
FIXME: comments
Comment
FIXME: what's the right way to go about this?
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:db="http://docbook.org/ns/docbook"
                xmlns:f="http://docbook.org/ns/docbook/functions"
                xmlns:m="http://docbook.org/ns/docbook/modes"
                xmlns:mp="http://docbook.org/ns/docbook/modes/private"
                xmlns:t="http://docbook.org/ns/docbook/templates"
                xmlns:tp="http://docbook.org/ns/docbook/templates/private"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns:h="http://www.w3.org/1999/xhtml"
                xmlns="http://www.w3.org/1999/xhtml"
                default-mode="m:docbook"
                exclude-result-prefixes="db f h m mp t tp xs"
                version="3.0">

<xsl:template match="*" mode="m:toc">
  <xsl:message select="'Unexpected in m:toc:', node-name(.)"/>
</xsl:template>

<xsl:template match="*" mode="mp:toc">
  <xsl:param name="nested" as="xs:boolean" required="yes"/>
  <xsl:param name="entries" as="element()*" required="yes"/>

  <!-- FIXME: what's the right way to go about this? -->
  <xsl:variable name="nscontext" as="element()">
    <xsl:element name="nscontext">
      <xsl:namespace name="f" select="'http://docbook.org/ns/docbook/functions'"/>
      <xsl:namespace name="v" select="'http://docbook.org/ns/docbook/variables'"/>
      <xsl:namespace name="vp" select="'http://docbook.org/ns/docbook/variables/private'"/>
      <xsl:namespace name="f" select="'http://docbook.org/ns/docbook/functions'"/>
      <xsl:namespace name="db" select="'http://docbook.org/ns/docbook'"/>
    </xsl:element>
  </xsl:variable>

  <xsl:variable name="toc" as="item()">
    <xsl:choose xmlns:vp="http://docbook.org/ns/docbook/variables/private">
      <xsl:when test="$nested">
        <xsl:evaluate context-item="." xpath="$generate-nested-toc"
                      namespace-context="$nscontext">
          <xsl:with-param name="vp:section-toc-depth"
                          select="$vp:section-toc-depth"/>
        </xsl:evaluate>
      </xsl:when>
      <xsl:otherwise>
        <xsl:evaluate context-item="." xpath="$generate-toc"
                      namespace-context="$nscontext">
          <xsl:with-param name="vp:section-toc-depth"
                          select="$vp:section-toc-depth"/>
        </xsl:evaluate>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:if test="$toc and exists($entries)
                and f:is-true(f:pi(db:info, 'toc', 'true'))">
    <xsl:call-template name="tp:toc">
      <xsl:with-param name="entries" select="$entries"/>
      <xsl:with-param name="nested" select="$nested"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>

<xsl:template match="db:set|db:book|db:part|db:reference" mode="m:toc">
  <xsl:param name="nested" select="false()"/>
  <xsl:apply-templates select="." mode="mp:toc">
    <xsl:with-param name="nested" select="$nested"/>
    <xsl:with-param name="entries"
                    select="db:book|db:preface|db:chapter|db:appendix|db:article
                            |db:topic|db:part|db:reference|db:refentry|db:dedication
                            |db:bibliography|db:index|db:glossary
                            |db:acknowledgements|db:colophon"/>
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="db:partintro|db:acknowledgements
                     |db:bibliodiv|db:glossdiv|db:indexdiv
                     |db:dedication|db:colophon"
              mode="m:toc">
  <xsl:param name="nested" select="false()"/>
  <!-- these don't get a ToC -->
</xsl:template>

<xsl:template match="db:formalgroup
                     |db:figure|db:table|db:example|db:equation|db:procedure"
              mode="m:toc">
  <!-- these don't nest -->
</xsl:template>

<xsl:template match="db:article" mode="m:toc">
  <xsl:param name="nested" select="false()"/>
  <xsl:apply-templates select="." mode="mp:toc">
    <xsl:with-param name="nested" select="$nested"/>
    <xsl:with-param name="entries"
                    select="db:section|db:sect1|db:appendix
                            |db:refentry"/>
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="db:topic" mode="m:toc">
  <xsl:param name="nested" select="false()"/>
  <xsl:apply-templates select="." mode="mp:toc">
    <xsl:with-param name="nested" select="$nested"/>
    <xsl:with-param name="entries"
                    select="db:bibliography|db:glossary|db:index
                            |db:section|db:sect1|db:simplesect
                            |db:refentry"/>
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="db:preface|db:chapter|db:appendix"
              mode="m:toc">
  <xsl:param name="nested" select="false()"/>
  <xsl:apply-templates select="." mode="mp:toc">
    <xsl:with-param name="nested" select="$nested"/>
    <xsl:with-param name="entries"
                    select="db:section|db:sect1|db:article
                            |db:topic|db:appendix"/>
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="db:bibliography|db:glossary|db:index"
              mode="m:toc">
  <xsl:param name="nested" select="false()"/>
  <xsl:apply-templates select="." mode="mp:toc">
    <xsl:with-param name="nested" select="$nested"/>
    <xsl:with-param name="entries"
                    select="db:bibliodiv|db:glossdiv|db:indexdiv"/>
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="db:refentry" mode="m:toc">
  <xsl:param name="nested" select="false()"/>
  <xsl:apply-templates select="." mode="mp:toc">
    <xsl:with-param name="nested" select="$nested"/>
    <xsl:with-param name="entries" select="db:refsection|db:refsect1"/>
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="db:refsection|db:refsect1|db:refsect2|db:refsect3"
              mode="m:toc">
  <xsl:param name="nested" select="false()"/>
  <xsl:apply-templates select="." mode="mp:toc">
    <xsl:with-param name="nested" select="$nested"/>
    <xsl:with-param name="entries"
                    select="db:refsection|db:refsect1|db:refsect2|db:refsect3"/>
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="db:section|db:sect1|db:sect2|db:sect3
                     |db:sect4|db:sect5"
              mode="m:toc">
  <xsl:param name="nested" select="false()"/>
  <xsl:apply-templates select="." mode="mp:toc">
    <xsl:with-param name="nested" select="$nested"/>
    <xsl:with-param name="entries"
                select="db:section|db:sect1
                        |db:sect2|db:sect3|db:sect4|db:sect5"/>
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="db:refsection|db:refsect1|db:refsect2|db:refsect3"
              mode="m:toc">
  <xsl:param name="nested" select="false()"/>
  <!-- these don't get a ToC -->
</xsl:template>

<!-- ============================================================ -->

<xsl:template match="*" mode="m:list-of-figures"/>
<xsl:template match="db:set|db:book" mode="m:list-of-figures">
  <xsl:if test="f:is-true($lists-of-figures)">
    <xsl:variable name="entries" as="element(h:li)*">
      <xsl:apply-templates select=".//db:figure[not(ancestor::db:formalgroup)]
                                   |.//db:formalgroup[db:figure]"
                           mode="m:toc-entry"/>
    </xsl:variable>
    <xsl:if test="$entries">
      <div class="list-of-figures lot">
        <div class="title">
          <xsl:sequence select="f:gentext(., 'title', 'listoffigures')"/>
        </div>
        <ul class="toc">
          <xsl:sequence select="$entries"/>
        </ul>
      </div>
    </xsl:if>
  </xsl:if>
</xsl:template>

<xsl:template match="*" mode="m:list-of-tables"/>
<xsl:template match="db:set|db:book" mode="m:list-of-tables">
  <xsl:if test="f:is-true($lists-of-tables)">
    <xsl:variable name="entries" as="element(h:li)*">
      <xsl:apply-templates select=".//db:table[not(ancestor::db:formalgroup)]
                                   |.//db:formalgroup[db:table]" mode="m:toc-entry"/>
    </xsl:variable>
    <xsl:if test="$entries">
      <div class="list-of-tables lot">
        <div class="title">
          <xsl:sequence select="f:gentext(., 'title', 'listoftables')"/>
        </div>
        <ul class="toc">
          <xsl:sequence select="$entries"/>
        </ul>
      </div>
    </xsl:if>
  </xsl:if>
</xsl:template>

<xsl:template match="*" mode="m:list-of-examples"/>
<xsl:template match="db:set|db:book" mode="m:list-of-examples">
  <xsl:if test="f:is-true($lists-of-examples)">
    <xsl:variable name="entries" as="element(h:li)*">
      <xsl:apply-templates select=".//db:example[not(ancestor::db:formalgroup)]
                                   |.//db:formalgroup[db:example]" mode="m:toc-entry"/>
    </xsl:variable>
    <xsl:if test="$entries">
      <div class="list-of-examples lot">
        <div class="title">
          <xsl:sequence select="f:gentext(., 'title', 'listofexamples')"/>
        </div>
        <ul class="toc">
          <xsl:sequence select="$entries"/>
        </ul>
      </div>
    </xsl:if>
  </xsl:if>
</xsl:template>

<xsl:template match="*" mode="m:list-of-equations"/>
<xsl:template match="db:set|db:book" mode="m:list-of-equations">
  <xsl:if test="f:is-true($lists-of-equations)">
    <xsl:variable name="entries" as="element(h:li)*">
      <xsl:apply-templates select=".//db:equation[not(ancestor::db:formalgroup)]
                                   |.//db:formalgroup[db:figure]" mode="m:toc-entry"/>
    </xsl:variable>
    <xsl:if test="$entries">
      <div class="list-of-equations lot">
        <div class="title">
          <xsl:sequence select="f:gentext(., 'title', 'listofequations')"/>
        </div>
        <ul class="toc">
          <xsl:sequence select="$entries"/>
        </ul>
      </div>
    </xsl:if>
  </xsl:if>
</xsl:template>

<xsl:template match="*" mode="m:list-of-procedures"/>
<xsl:template match="db:set|db:book" mode="m:list-of-procedures">
  <xsl:if test="f:is-true($lists-of-procedures)">
    <xsl:variable name="entries" as="element(h:li)*">
      <xsl:apply-templates select=".//db:procedure" mode="m:toc-entry"/>
    </xsl:variable>
    <xsl:if test="$entries">
      <div class="list-of-procedures lot">
        <div class="title">
          <xsl:sequence select="f:gentext(., 'title', 'listofprocedures')"/>
        </div>
        <ul class="toc">
          <xsl:sequence select="$entries"/>
        </ul>
      </div>
    </xsl:if>
  </xsl:if>
</xsl:template>

<xsl:template name="tp:toc">
  <xsl:param name="entries" as="element()+" required="yes"/>
  <xsl:param name="nested" as="xs:boolean" required="yes"/>
  <xsl:choose>
    <xsl:when test="$nested">
      <xsl:variable name="entries" as="element(h:li)*">
        <xsl:apply-templates select="$entries" mode="m:toc-entry"/>
      </xsl:variable>
      <xsl:if test="$entries">
        <ul class="toc">
          <xsl:sequence select="$entries"/>
        </ul>
      </xsl:if>
    </xsl:when>
    <xsl:otherwise>
      <xsl:variable name="entries" as="element(h:li)*">
        <xsl:apply-templates select="$entries" mode="m:toc-entry"/>
      </xsl:variable>
      <xsl:variable name="l-o-f" as="element(h:div)?">
        <xsl:apply-templates select="." mode="m:list-of-figures"/>
      </xsl:variable>
      <xsl:variable name="l-o-t" as="element(h:div)?">
        <xsl:apply-templates select="." mode="m:list-of-tables"/>
      </xsl:variable>
      <xsl:variable name="l-o-ex" as="element(h:div)?">
        <xsl:apply-templates select="." mode="m:list-of-examples"/>
      </xsl:variable>
      <xsl:variable name="l-o-eq" as="element(h:div)?">
        <xsl:apply-templates select="." mode="m:list-of-equations"/>
      </xsl:variable>
      <xsl:variable name="l-o-p" as="element(h:div)?">
        <xsl:apply-templates select="." mode="m:list-of-procedures"/>
      </xsl:variable>
      <xsl:if test="$entries or $l-o-f or $l-o-t
                    or $l-o-ex or $l-o-eq or $l-o-p">
        <div class="list-of-titles">
          <xsl:if test="$entries">
            <div class="lot toc">
              <div class="title">
                <xsl:sequence select="f:gentext(., 'title', 'tableofcontents')"/>
              </div>
              <ul class="toc">
                <xsl:sequence select="$entries"/>
              </ul>
            </div>
          </xsl:if>
          <xsl:sequence select="$l-o-f"/>
          <xsl:sequence select="$l-o-t"/>
          <xsl:sequence select="$l-o-ex"/>
          <xsl:sequence select="$l-o-eq"/>
          <xsl:sequence select="$l-o-p"/>
        </div>
      </xsl:if>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="db:refentry" mode="m:toc-entry" priority="100">
  <xsl:variable name="refmeta" select=".//db:refmeta"/>
  <xsl:variable name="refentrytitle" select="$refmeta//db:refentrytitle"/>
  <xsl:variable name="refnamediv" select=".//db:refnamediv"/>
  <xsl:variable name="refname" select="$refnamediv//db:refname"/>

  <xsl:variable name="title">
    <xsl:choose>
      <xsl:when test="$refentrytitle">
        <xsl:apply-templates select="$refentrytitle[1]">
          <xsl:with-param name="purpose" select="'lot'"/>
        </xsl:apply-templates>
      </xsl:when>
      <xsl:when test="$refnamediv/db:refdescriptor">
        <xsl:apply-templates select="($refnamediv/db:refdescriptor)[1]">
          <xsl:with-param name="purpose" select="'lot'"/>
        </xsl:apply-templates>
      </xsl:when>
      <xsl:when test="$refname">
        <xsl:apply-templates select="$refname[1]">
          <xsl:with-param name="purpose" select="'lot'"/>
        </xsl:apply-templates>
      </xsl:when>
      <xsl:otherwise></xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <li>
    <span class='refentrytitle'>
      <a href="#{f:id(.)}">
        <xsl:sequence select="$title"/>
      </a>
    </span>
    <xsl:if test="f:is-true($annotate-toc)">
      <xsl:apply-templates select="(db:refnamediv/db:refpurpose)[1]">
        <xsl:with-param name="purpose" select="'lot'"/>
      </xsl:apply-templates>
    </xsl:if>
  </li>
</xsl:template>

<xsl:template match="*" mode="m:toc-entry">
  <li>
    <a href="#{f:id(.)}">
      <xsl:apply-templates select="." mode="m:headline">
        <xsl:with-param name="purpose" select="'lot'"/>
      </xsl:apply-templates>
    </a>
    <xsl:apply-templates select="." mode="m:toc">
      <xsl:with-param name="nested" select="true()"/>
    </xsl:apply-templates>
  </li>
</xsl:template>

<xsl:template match="*[not(db:info/db:title)]" mode="m:toc-entry"
              priority="10">
  <!-- things without titles don't appear in the, uh, lists of titles -->
  <!-- preface, dedication, acknowledgements, colophon, equation,
       and procedure spring to mind... -->
</xsl:template>

<xsl:template match="db:colophon|db:bibliodiv|db:glossdiv|db:indexdiv"
              mode="m:toc-entry">
  <!-- by default, these don't appear in the ToC -->
</xsl:template>

<!-- ============================================================ -->

<xsl:template match="db:toc|db:tocdiv">
  <div>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates select="." mode="m:generate-titlepage"/>
    <xsl:choose>
      <xsl:when test="db:tocentry">
        <ul>
          <xsl:apply-templates select="db:tocentry"/>
        </ul>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates/>
      </xsl:otherwise>
    </xsl:choose>
  </div>
</xsl:template>

<xsl:template match="db:tocentry">
  <ul>
    <xsl:apply-templates/>
  </ul>
</xsl:template>

</xsl:stylesheet>

divisions.xsl

1 template

Instructions
Template match ≅ db:book|db:part|db:partintro|d…
Mode: m:docbook
Matches: db:book, db:part, db:partintro, db:reference, db:set
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:db="http://docbook.org/ns/docbook"
                xmlns:f="http://docbook.org/ns/docbook/functions"
                xmlns:m="http://docbook.org/ns/docbook/modes"
                xmlns:t="http://docbook.org/ns/docbook/templates"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns="http://www.w3.org/1999/xhtml"
                default-mode="m:docbook"
                exclude-result-prefixes="db f m t xs"
                version="3.0">

<xsl:template match="db:set|db:book|db:part|db:reference|db:partintro">
  <article>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates select="." mode="m:generate-titlepage"/>
    <xsl:apply-templates select="." mode="m:toc"/>
    <xsl:apply-templates/>
  </article>
</xsl:template>

</xsl:stylesheet>

components.xsl

2 templates

Instructions
Template match ≅ db:appendix|db:article|db:chap…
Mode: m:docbook
Matches: db:appendix, db:article, db:chapter, db:preface, db:topic
Template match ≅ db:acknowledgements|db:colopho…
Mode: m:docbook
Matches: db:acknowledgements, db:colophon, db:dedication
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:db="http://docbook.org/ns/docbook"
                xmlns:f="http://docbook.org/ns/docbook/functions"
                xmlns:m="http://docbook.org/ns/docbook/modes"
                xmlns:t="http://docbook.org/ns/docbook/templates"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns="http://www.w3.org/1999/xhtml"
                default-mode="m:docbook"
                exclude-result-prefixes="db f m t xs"
                version="3.0">

<xsl:template match="db:preface|db:chapter|db:appendix|db:article
                     |db:topic">
  <xsl:variable name="gi" select="if (parent::*)
                                  then 'div'
                                  else 'article'"/>
  <xsl:element name="{$gi}" namespace="http://www.w3.org/1999/xhtml">
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates select="." mode="m:generate-titlepage"/>
    <xsl:apply-templates select="." mode="m:toc"/>
    <xsl:apply-templates/>
  </xsl:element>
</xsl:template>

<xsl:template match="db:acknowledgements|db:dedication|db:colophon">
  <div>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates select="." mode="m:generate-titlepage"/>
    <xsl:apply-templates/>
  </div>
</xsl:template>

</xsl:stylesheet>

refentry.xsl

11 templates

Instructions
Template match ≅ db:refentry
Mode: m:docbook
Matches: db:refentry
Template match ≅ db:refnamediv
Mode: m:docbook
Matches: db:refnamediv
Template match ≅ db:refnamediv
Mode: m:docbook
Matches: db:refnamediv
Template match ≅ db:refclass|db:refmeta
Mode: m:docbook
Matches: db:refclass, db:refmeta
Template match ≅ db:refdescriptor
Mode: m:docbook
Matches: db:refdescriptor
Template match ≅ db:manvolnum
Mode: m:docbook
Matches: db:manvolnum
Template match ≅ db:refentrytitle
Mode: m:docbook
Matches: db:refentrytitle
Template match ≅ db:refname
Mode: m:docbook
Matches: db:refname
Template match ≅ db:refpurpose
Mode: m:docbook
Matches: db:refpurpose
Template match ≅ db:refsynopsisdiv
Mode: m:docbook
Matches: db:refsynopsisdiv
Template match ≅ db:refsect1|db:refsect2|db:ref…
Mode: m:docbook
Matches: db:refsect1, db:refsect2, db:refsect3, db:refsection
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:db="http://docbook.org/ns/docbook"
                xmlns:f="http://docbook.org/ns/docbook/functions"
                xmlns:fp="http://docbook.org/ns/docbook/functions/private"
                xmlns:m="http://docbook.org/ns/docbook/modes"
                xmlns:t="http://docbook.org/ns/docbook/templates"
                xmlns:vp="http://docbook.org/ns/docbook/variables/private"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns="http://www.w3.org/1999/xhtml"
                default-mode="m:docbook"
                exclude-result-prefixes="db f fp m t vp xs"
                version="3.0">

<xsl:template match="db:refentry">
  <xsl:variable name="gi" select="if (parent::*)
                                  then 'div'
                                  else 'article'"/>
  <xsl:element name="{$gi}" namespace="http://www.w3.org/1999/xhtml">
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates select="." mode="m:generate-titlepage"/>
    <xsl:apply-templates select="." mode="m:toc"/>
    <xsl:apply-templates/>
  </xsl:element>
</xsl:template>

<xsl:template match="db:refnamediv[preceding-sibling::db:refnamediv]"/>
<xsl:template match="db:refnamediv[not(preceding-sibling::db:refnamediv)]">
  <div>
    <xsl:apply-templates select="." mode="m:attributes"/>

    <xsl:choose>
      <xsl:when test="$refentry-generate-name">
        <h2>
          <xsl:sequence
              select="f:gentext(., 'label', 'refname')"/>
        </h2>
      </xsl:when>

      <xsl:when test="$refentry-generate-title">
        <h2>
          <xsl:choose>
            <xsl:when test="../db:refmeta/db:refentrytitle">
              <xsl:apply-templates select="../db:refmeta/db:refentrytitle"/>
            </xsl:when>
            <xsl:when test="db:refdescriptor">
              <xsl:apply-templates select="db:refdescriptor"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:apply-templates select="db:refname[1]"/>
            </xsl:otherwise>
          </xsl:choose>
        </h2>
      </xsl:when>
    </xsl:choose>
    <p>
      <xsl:choose>
        <xsl:when test="db:refdescriptor">
          <xsl:apply-templates select="db:refdescriptor"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:apply-templates select="db:refname"/>
        </xsl:otherwise>
      </xsl:choose>
      <xsl:apply-templates select="* except (db:refdescriptor|db:refname)"/>
    </p>
    <xsl:for-each select="following-sibling::db:refnamediv">
      <p>
        <xsl:choose>
          <xsl:when test="db:refdescriptor">
            <xsl:apply-templates select="db:refdescriptor"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:apply-templates select="db:refname"/>
          </xsl:otherwise>
        </xsl:choose>
        <xsl:apply-templates select="* except (db:refdescriptor|db:refname)"/>
      </p>
    </xsl:for-each>
  </div>
</xsl:template>

<xsl:template match="db:refmeta|db:refclass"/>

<xsl:template match="db:refdescriptor">
  <xsl:param name="purpose" select="''"/>
  <span>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates/>
  </span>
</xsl:template>

<xsl:template match="db:manvolnum">
  <span class="manvolnum">
    <span class="sep">(</span>
    <xsl:apply-templates/>
    <span class="sep">)</span>
  </span>
</xsl:template>

<xsl:template match="db:refentrytitle">
  <xsl:param name="purpose" select="''"/>
  <span>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates/>
  </span>
</xsl:template>

<xsl:template match="db:refname">
  <xsl:param name="purpose" select="''"/>
  <span>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates/>
  </span>
  <xsl:if test="not($purpose = 'lot') and following-sibling::db:refname">
    <span class="refname-sep">
      <xsl:sequence
          select="f:gentext(., 'separator', 'refname-sep')"/>
    </span>
  </xsl:if>
</xsl:template>

<xsl:template match="db:refpurpose">
  <xsl:param name="purpose" select="''"/>
  <span>
    <xsl:choose>
      <xsl:when test="$purpose = 'lot'">
        <xsl:attribute name="class" select="local-name(.)"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates select="." mode="m:attributes"/>
      </xsl:otherwise>
    </xsl:choose>
    <span class="refpurpose-sep">
      <xsl:sequence
          select="f:gentext(., 'separator', 'refpurpose-sep')"/>
    </span>
    <span class="refpurpose-text">
      <xsl:apply-templates/>
    </span>
    <xsl:if test="not($purpose = 'lot')
                  and not(matches(normalize-space(.), '\p{P}$'))">
      <span class="refpurpose-punc">
        <xsl:text>.</xsl:text>
      </span>
    </xsl:if>
  </span>
</xsl:template>

<xsl:template match="db:refsynopsisdiv">
  <div>
    <xsl:apply-templates select="." mode="m:attributes"/>

    <h2>
      <xsl:choose>
        <xsl:when test="db:info/db:title">
          <xsl:apply-templates select="db:info/db:title"
                               mode="m:titlepage-mode"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:text>Synopsis</xsl:text>
        </xsl:otherwise>
      </xsl:choose>
    </h2>
    <xsl:apply-templates/>
  </div>
</xsl:template>

<xsl:template match="db:refsection|db:refsect1|db:refsect2|db:refsect3">
  <div>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates select="." mode="m:generate-titlepage"/>
    <xsl:apply-templates/>
  </div>
</xsl:template>

</xsl:stylesheet>

bibliography.xsl

23 templates

Instructions
Template match ≅ db:bibliodiv|db:bibliography|d…
Mode: m:docbook
Matches: db:bibliodiv, db:bibliography, db:bibliolist
Template match ≅ db:biblioentry
Mode: m:docbook
Matches: db:biblioentry
Template match ≅ db:bibliomixed
Mode: m:docbook
Matches: db:bibliomixed
Template match ≅ db:bibliomset
Mode: m:bibliomixed
Matches: db:bibliomset
Template match ≅ db:abbrev
Mode: m:bibliomixed
Matches: db:abbrev
Template match ≅ db:title
Mode: m:bibliomixed
Matches: db:title
Template match ≅ db:address|db:publisher
Mode: m:bibliomixed
Matches: db:address, db:publisher
Template match ≅ *
Mode: m:bibliomixed
Matches: *
Template match ≅ text()
Mode: m:bibliomixed
Matches: text()
Template match ≅ db:releaseinfo
Mode: m:bibliomixed
Matches: db:releaseinfo
Template match ≅ db:biblioset
Mode: m:biblioentry
Matches: db:biblioset
Template match ≅ db:title
Mode: m:biblioentry
Matches: db:title
Template match ≅ db:subtitle
Calls: t:inline
Mode: m:biblioentry
Matches: db:subtitle
Template match ≅ db:address|db:publisher
Mode: m:biblioentry
Matches: db:address, db:publisher
Template match ≅ db:collab|db:othercredit
Mode: m:biblioentry
Matches: db:collab, db:othercredit
Template match ≅ db:confgroup
Mode: m:biblioentry
Matches: db:confgroup
Template match ≅ db:confdates|db:confnum|db:con…
Mode: m:biblioentry
Matches: db:confdates, db:confnum, db:confsponsor, db:conftitle
Template match ≅ db:contractnum|db:contractspon…
Mode: m:biblioentry
Matches: db:contractnum, db:contractsponsor, db:edition, db:volumenum
Template match ≅ db:releaseinfo
Mode: m:biblioentry
Matches: db:releaseinfo
Template match ≅ *
Mode: m:biblioentry
Matches: *
Template match ≅ text()
Mode: m:biblioentry
Matches: text()
Template match ≅ db:authorgroup
Mode: m:docbook
Matches: db:authorgroup
Template match ≅ db:biblioid|db:bibliomisc|db:b…
Calls: t:inline
Mode: m:docbook
Matches: db:biblioid, db:bibliomisc, db:bibliosource, db:orgdiv, db:orgname, db:subtitle
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:db="http://docbook.org/ns/docbook"
                xmlns:f="http://docbook.org/ns/docbook/functions"
                xmlns:fp="http://docbook.org/ns/docbook/functions/private"
                xmlns:m="http://docbook.org/ns/docbook/modes"
                xmlns:t="http://docbook.org/ns/docbook/templates"
                xmlns:vp="http://docbook.org/ns/docbook/variables/private"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns="http://www.w3.org/1999/xhtml"
                default-mode="m:docbook"
                exclude-result-prefixes="db f fp m t vp xs"
                version="3.0">

<xsl:template match="db:bibliography|db:bibliodiv|db:bibliolist">
  <xsl:variable name="gi" select="if (parent::*)
                                  then 'div'
                                  else 'article'"/>
  <xsl:element name="{$gi}" namespace="http://www.w3.org/1999/xhtml">
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates select="." mode="m:generate-titlepage"/>
    <xsl:apply-templates/>
  </xsl:element>
</xsl:template>

<xsl:template match="db:biblioentry">
  <p>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:call-template name="t:biblioentry"/>
  </p>
</xsl:template>

<xsl:template match="db:bibliomixed">
  <p>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:choose>
      <xsl:when test="@xml:id and not(child::*[1]/self::db:abbrev)">
        <xsl:sequence select="'[' || @xml:id || '] '"/>
        <xsl:apply-templates mode="m:bibliomixed"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates mode="m:bibliomixed"/>
      </xsl:otherwise>
    </xsl:choose>
  </p>
</xsl:template>

<!-- ============================================================ -->

<xsl:template match="db:bibliomset" mode="m:bibliomixed">
  <span>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates mode="m:bibliomixed"/>
  </span>
</xsl:template>

<xsl:template match="db:abbrev" mode="m:bibliomixed">
  <xsl:choose>
    <xsl:when test="empty(preceding-sibling::*)
                    and (normalize-space(preceding-sibling::text()) = '')">
      <!-- this is the citation -->
      <xsl:text>[</xsl:text>
      <span>
        <xsl:apply-templates select="." mode="m:attributes"/>
        <xsl:apply-templates mode="m:bibliomixed"/>
      </span>
      <xsl:text>] </xsl:text>
    </xsl:when>
    <xsl:otherwise>
      <span>
        <xsl:apply-templates select="." mode="m:attributes"/>
        <xsl:apply-templates mode="m:bibliomixed"/>
      </span>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="db:title" mode="m:bibliomixed">
  <xsl:choose>
    <xsl:when test="parent::db:bibliomset[@relation='article']">
      <q>
        <xsl:apply-templates select="." mode="m:attributes"/>
        <xsl:apply-templates/>
      </q>
    </xsl:when>
    <xsl:otherwise>
      <cite>
        <xsl:apply-templates select="." mode="m:attributes"/>
        <xsl:apply-templates/>
      </cite>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="db:address|db:publisher" mode="m:bibliomixed">
  <span>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates mode="m:bibliomixed"/>
  </span>
</xsl:template>

<xsl:template match="*" mode="m:bibliomixed">
  <xsl:apply-templates select="."/>
</xsl:template>

<xsl:template match="text()" mode="m:bibliomixed">
  <xsl:choose>
    <xsl:when test="parent::db:address">
      <!-- explicitly xsl:value-of because we need a text node -->
      <xsl:value-of select="replace(string(.), '&#10;', ' / ')"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:copy/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="db:releaseinfo" mode="m:bibliomixed">
  <span>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates mode="m:biblioentry"/>
  </span>
</xsl:template>

<!-- ============================================================ -->

<xsl:template match="db:biblioset" mode="m:biblioentry">
  <span>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates/>
  </span>
</xsl:template>

<xsl:template match="db:title" mode="m:biblioentry">
  <xsl:choose>
    <xsl:when test="parent::db:biblioset[@relation='article']">
      <q>
        <xsl:apply-templates select="." mode="m:attributes"/>
        <xsl:apply-templates/>
      </q>
    </xsl:when>
    <xsl:otherwise>
      <cite>
        <xsl:apply-templates select="." mode="m:attributes"/>
        <xsl:apply-templates/>
      </cite>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="db:subtitle" mode="m:biblioentry">
  <xsl:call-template name="t:inline"/>
</xsl:template>

<xsl:template match="db:address|db:publisher" mode="m:biblioentry">
  <span>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates mode="m:biblioentry"/>
  </span>
</xsl:template>

<xsl:template match="db:collab|db:othercredit" mode="m:biblioentry">
  <span>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates select="db:personname|db:orgname"
                         mode="m:biblioentry"/>
  </span>
</xsl:template>

<xsl:template match="db:confgroup" mode="m:biblioentry">
  <span>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates mode="m:biblioentry"/>
  </span>
</xsl:template>

<xsl:template match="db:confdates|db:conftitle|db:confsponsor|db:confnum"
              mode="m:biblioentry">
  <span>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates mode="m:biblioentry"/>
  </span>
  <xsl:text>. </xsl:text>
</xsl:template>

<xsl:template match="db:contractnum|db:contractsponsor
                     |db:edition|db:volumenum" mode="m:biblioentry">
  <span>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates mode="m:biblioentry"/>
  </span>
</xsl:template>

<xsl:template match="db:releaseinfo" mode="m:biblioentry">
  <span>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates mode="m:biblioentry"/>
  </span>
</xsl:template>

<xsl:template match="*" mode="m:biblioentry">
  <xsl:apply-templates select="."/>
</xsl:template>

<xsl:template match="text()" mode="m:biblioentry">
  <xsl:choose>
    <xsl:when test="parent::db:address">
      <!-- explicitly xsl:value-of because we need a text node -->
      <xsl:value-of select="replace(string(.), '&#10;', ' / ')"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:copy/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<!-- ============================================================ -->

<xsl:template match="db:authorgroup[not(parent::db:info)]">
  <span>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:call-template name="t:person-name-list"/>
  </span>
</xsl:template>

<xsl:template match="db:biblioid|db:orgname|db:orgdiv|db:bibliosource
                     |db:bibliomisc|db:subtitle">
  <xsl:call-template name="t:inline"/>
</xsl:template>

<!-- ============================================================ -->

</xsl:stylesheet>

glossary.xsl

10 templates

Instructions
Template match ≅ db:glossary|db:glossdiv|db:glo…
Mode: m:docbook
Matches: db:glossary, db:glossdiv, db:glosslist
Template match ≅ db:glossentry
Mode: m:docbook
Matches: db:glossentry
Template match ≅ db:glossterm
Calls: t:inline
Mode: m:docbook
Matches: db:glossterm
Template match ≅ db:glossentry/db:glossterm
Mode: m:docbook
Matches: db:glossentry/db:glossterm
Template match ≅ db:glossentry/db:acronym
Mode: m:docbook
Matches: db:glossentry/db:acronym
Template match ≅ db:glossentry/db:abbrev
Mode: m:docbook
Matches: db:glossentry/db:abbrev
Template match ≅ db:glosssee
Calls: f:href()
Mode: m:docbook
Matches: db:glosssee
Template match ≅ db:glossentry/db:glossdef
Mode: m:docbook
Matches: db:glossentry/db:glossdef
Template match ≅ db:glossseealso
Mode: m:docbook
Matches: db:glossseealso
Template match ≅ db:glossseealso
Calls: f:href()
Mode: m:docbook
Matches: db:glossseealso
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:db="http://docbook.org/ns/docbook"
                xmlns:f="http://docbook.org/ns/docbook/functions"
                xmlns:fp="http://docbook.org/ns/docbook/functions/private"
                xmlns:m="http://docbook.org/ns/docbook/modes"
                xmlns:t="http://docbook.org/ns/docbook/templates"
                xmlns:vp="http://docbook.org/ns/docbook/variables/private"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns="http://www.w3.org/1999/xhtml"
                default-mode="m:docbook"
                exclude-result-prefixes="db f fp m t vp xs"
                version="3.0">

<xsl:key name="glossterm" match="db:glossentry"
         use="(db:glossterm/@baseform, db:glossterm/normalize-space(.))[1]"/>

<xsl:template match="db:glossary|db:glossdiv|db:glosslist">
  <xsl:variable name="gi" select="if (parent::*)
                                  then 'div'
                                  else 'article'"/>
  <xsl:element name="{$gi}" namespace="http://www.w3.org/1999/xhtml">
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates select="." mode="m:generate-titlepage"/>
    <xsl:apply-templates select="* except (db:glossentry|db:bibliography)"/>
    <dl class="{local-name(.)}">
      <xsl:choose>
        <xsl:when test="$glossary-sort-entries">
          <xsl:apply-templates select="db:glossentry">
            <xsl:sort select="(@sortas, normalize-space(db:glossterm[1]))"
                      collation="{$sort-collation}"/>
          </xsl:apply-templates>
        </xsl:when>
        <xsl:otherwise>
          <xsl:apply-templates select="db:glossentry"/>
        </xsl:otherwise>
      </xsl:choose>
    </dl>
    <xsl:apply-templates select="db:bibliography"/>
  </xsl:element>
</xsl:template>

<xsl:template match="db:glossentry">
  <dt>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates select="db:glossterm|db:indexterm"/>
  </dt>
  <xsl:apply-templates select="db:glosssee|db:glossdef"/>
</xsl:template>

<xsl:template match="db:glossterm">
  <xsl:call-template name="t:inline"/>
</xsl:template>

<xsl:template match="db:glossentry/db:glossterm">
  <span>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates/>
  </span>
  <xsl:if test="following-sibling::db:glossterm">
    <xsl:sequence select="f:gentext(., 'separator', 'glossterm-sep')"/>
  </xsl:if>
</xsl:template>

<xsl:template match="db:glossentry/db:acronym">
  <span>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates/>
  </span>
  <xsl:if test="following-sibling::db:acronym
                |following-sibling::db:abbrev">
    <xsl:sequence select="f:gentext(., 'separator', 'glossterm-sep')"/>
  </xsl:if>
</xsl:template>

<xsl:template match="db:glossentry/db:abbrev">
  <span>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates/>
  </span>
  <xsl:if test="following-sibling::db:acronym
                |following-sibling::db:abbrev">
    <xsl:sequence select="f:gentext(., 'separator', 'glossterm-sep')"/>
  </xsl:if>
</xsl:template>

<xsl:template match="db:glosssee">
  <xsl:variable name="target"
                select="(key('id', @otherterm),
                         key('glossterm', normalize-space(.)))[1]"/>

  <dd>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <p>
      <xsl:apply-templates select="." mode="m:crossref-prefix">
        <xsl:with-param name="label" select="''"/>
        <xsl:with-param name="number" select="''"/>
        <xsl:with-param name="title" select="string(.)"/>
      </xsl:apply-templates>
      <xsl:choose>
        <xsl:when test="$target">
          <a href="{f:href(., $target)}">
            <xsl:apply-templates/>
          </a>
        </xsl:when>
        <xsl:when test="@otherterm and not($target)">
          <xsl:message>
            <xsl:text>Warning: </xsl:text>
            <xsl:text>glosssee @otherterm reference not found: </xsl:text>
            <xsl:value-of select="@otherterm"/>
          </xsl:message>
          <xsl:apply-templates/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:apply-templates/>
        </xsl:otherwise>
      </xsl:choose>
      <xsl:text>.</xsl:text>
    </p>
  </dd>
</xsl:template>

<xsl:template match="db:glossentry/db:glossdef">
  <dd>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates select="*[not(self::db:glossseealso)]"/>
  </dd>
  <xsl:apply-templates select="db:glossseealso"/>
</xsl:template>

<xsl:template match="db:glossseealso[preceding-sibling::db:glossseealso]"/>
<xsl:template match="db:glossseealso">
  <dd>
    <p>
      <xsl:apply-templates select="." mode="m:crossref-prefix">
        <xsl:with-param name="label" select="''"/>
        <xsl:with-param name="number" select="''"/>
        <xsl:with-param name="title" select="string(.)"/>
      </xsl:apply-templates>
      <xsl:for-each select="(., following-sibling::db:glossseealso)">
        <xsl:variable name="target"
                      select="if (key('id', @otherterm))
                              then key('id', @otherterm)[1]
                              else key('glossterm', string(.))"/>
        <xsl:choose>
          <xsl:when test="$target">
            <a href="{f:href(/,$target)}">
              <xsl:apply-templates select="$target" mode="m:crossref"/>
            </a>
          </xsl:when>
          <xsl:when test="@otherterm and not($target)">
            <xsl:message>
              <xsl:text>Warning: </xsl:text>
              <xsl:text>glossseealso @otherterm reference not found: </xsl:text>
              <xsl:value-of select="@otherterm"/>
            </xsl:message>
            <xsl:apply-templates/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:apply-templates/>
          </xsl:otherwise>
        </xsl:choose>

        <xsl:choose>
          <xsl:when test="position() = last()">
            <xsl:text>.</xsl:text>
          </xsl:when>
          <xsl:otherwise>
            <xsl:text>, </xsl:text>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:for-each>
    </p>
  </dd>
</xsl:template>

<!-- ============================================================ -->

</xsl:stylesheet>

index.xsl

18 templates, 8 functions (1 unused)

Instructions
Template match ≅ db:indexterm
Mode: m:docbook
Matches: db:indexterm
Template match ≅ db:primary|db:secondary|db:see…
Mode: m:docbook
Matches: db:primary, db:secondary, db:see, db:seealso, db:tertiary
Template match ≅ db:index|db:indexdiv|db:setind…
Mode: m:docbook
Matches: db:index, db:indexdiv, db:setindex
Function fp:primary($indexterm as element(db:indexterm)) as xs:string
Function fp:secondary($indexterm as element(db:indexterm)) as xs:string
Function fp:tertiary($indexterm as element(db:indexterm)) as xs:string
Function fp:scope($node as element(), $scope as element(), $role as xs:string?, $type as xs:string?) as xs:boolean
Function fp:nearest-section($node as element()) as element()
Function fp:nearest-section-id($indexterm as element(db:indexterm)) as xs:string
Unused
Function fp:group-index($term as xs:string, $lang as xs:string)
Function fp:group-label($index as xs:integer, $lang as xs:string)
Used by: template
Template t:generate-index match ≅
Template match ≅ db:indexterm
Mode: m:index-div
Matches: db:indexterm
Template match ≅ db:indexterm
Mode: m:index-primary
Matches: db:indexterm
Template match ≅ db:indexterm
Mode: m:index-secondary
Matches: db:indexterm
Template match ≅ db:indexterm
Mode: m:index-tertiary
Matches: db:indexterm
Template match ≅ db:indexterm
Mode: mp:reference
Matches: db:indexterm
Template t:index-zone-reference match ≅
Mode: m:docbook
Template match ≅ db:indexterm
Mode: m:index-see
Matches: db:indexterm
Template match ≅ db:indexterm
Mode: m:index-seealso
Matches: db:indexterm
Template match ≅ db:indexentry
Mode: m:docbook
Matches: db:indexentry
Template match ≅ db:primaryie
Mode: m:docbook
Matches: db:primaryie
Template match ≅ db:secondaryie
Mode: m:docbook
Matches: db:secondaryie
Template match ≅ db:tertiaryie
Mode: m:docbook
Matches: db:tertiaryie
Template match ≅ db:seeie
Mode: m:docbook
Matches: db:seeie
Template match ≅ db:seealsoie
Mode: m:docbook
Matches: db:seealsoie
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:db="http://docbook.org/ns/docbook"
                xmlns:f="http://docbook.org/ns/docbook/functions"
                xmlns:fp="http://docbook.org/ns/docbook/functions/private"
                xmlns:l="http://docbook.org/ns/docbook/l10n"
                xmlns:m="http://docbook.org/ns/docbook/modes"
                xmlns:mp="http://docbook.org/ns/docbook/modes/private"
                xmlns:t="http://docbook.org/ns/docbook/templates"
                xmlns:vp="http://docbook.org/ns/docbook/variables/private"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns="http://www.w3.org/1999/xhtml"
                default-mode="m:docbook"
                exclude-result-prefixes="db f fp l m mp t vp xs"
                version="3.0">

<xsl:template match="db:indexterm">
  <span class="indexterm" id="{f:generate-id(.)}">
    <xsl:if test="not(empty($index-show-entries))">
      <xsl:attribute name="title" select="string-join(.//*, ', ')"/>
      <xsl:sequence select="$index-show-entries"/>
    </xsl:if>
  </span>
</xsl:template>

<xsl:template match="db:primary|db:secondary|db:tertiary|db:see|db:seealso"/>

<xsl:template match="db:setindex|db:index|db:indexdiv">
  <xsl:variable name="gi" select="if (parent::*)
                                  then 'div'
                                  else 'article'"/>
  <xsl:element name="{$gi}" namespace="http://www.w3.org/1999/xhtml">
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates select="." mode="m:generate-titlepage"/>
    <xsl:apply-templates
        select="node() except (db:indexdiv|db:indexentry|db:segmentedlist)"/>

    <xsl:variable name="autoindex"
                  select="f:pi(., 'autoindex', $generate-index)"/>
    <xsl:if test="f:is-true($autoindex)">
      <div class="index-list">
        <xsl:choose>
          <xsl:when test="not(db:indexdiv|db:indexentry|db:segmentedlist)
                          and f:is-true(f:pi(., 'autoindex', 'true'))
                          and f:is-true($generate-index)">
            <xsl:call-template name="t:generate-index">
              <xsl:with-param name="scope" select="parent::*"/>
            </xsl:call-template>
          </xsl:when>
          <xsl:otherwise>
            <xsl:apply-templates select="db:indexdiv|db:indexentry|db:segmentedlist"/>
          </xsl:otherwise>
        </xsl:choose>
      </div>
    </xsl:if>
  </xsl:element>
</xsl:template>

<!-- ============================================================ -->

<xsl:key name="primary"
         match="db:indexterm"
         use="normalize-space(concat(db:primary/@sortas, db:primary[not(@sortas)]))"/>

<xsl:key name="endofrange"
         match="db:indexterm[@class='endofrange']"
         use="@startref"/>

<!-- ============================================================ -->

<xsl:function name="fp:primary" as="xs:string">
  <xsl:param name="indexterm" as="element(db:indexterm)"/>
  <xsl:sequence
      select="normalize-space(concat($indexterm/db:primary/@sortas,
                                     $indexterm/db:primary[not(@sortas)]))"/>
</xsl:function>

<xsl:function name="fp:secondary" as="xs:string">
  <xsl:param name="indexterm" as="element(db:indexterm)"/>
  <xsl:sequence
      select="normalize-space(concat($indexterm/db:secondary/@sortas,
                                     $indexterm/db:secondary[not(@sortas)]))"/>
</xsl:function>

<xsl:function name="fp:tertiary" as="xs:string">
  <xsl:param name="indexterm" as="element(db:indexterm)"/>
  <xsl:sequence
      select="normalize-space(concat($indexterm/db:tertiary/@sortas,
                                     $indexterm/db:tertiary[not(@sortas)]))"/>
</xsl:function>

<xsl:function name="fp:scope" as="xs:boolean">
  <xsl:param name="node" as="element()"/>
  <xsl:param name="scope" as="element()"/>
  <xsl:param name="role" as="xs:string?"/>
  <xsl:param name="type" as="xs:string?"/>
  <xsl:sequence
      select="count($node/ancestor::node()|$scope) = count($node/ancestor::node())
                and ($role = $node/@role or $type = $node/@type or
                (string-length($role) = 0 and string-length($type) = 0))"/>
</xsl:function>

<xsl:function name="fp:nearest-section" as="element()">
  <xsl:param name="node" as="element()"/>
  <xsl:sequence select="($node/ancestor-or-self::db:set
                         |$node/ancestor-or-self::db:book
                         |$node/ancestor-or-self::db:part
                         |$node/ancestor-or-self::db:reference
                         |$node/ancestor-or-self::db:partintro
                         |$node/ancestor-or-self::db:chapter
                         |$node/ancestor-or-self::db:appendix
                         |$node/ancestor-or-self::db:preface
                         |$node/ancestor-or-self::db:article
                         |$node/ancestor-or-self::db:section
                         |$node/ancestor-or-self::db:sect1
                         |$node/ancestor-or-self::db:sect2
                         |$node/ancestor-or-self::db:sect3
                         |$node/ancestor-or-self::db:sect4
                         |$node/ancestor-or-self::db:sect5
                         |$node/ancestor-or-self::db:refentry
                         |$node/ancestor-or-self::db:refsect1
                         |$node/ancestor-or-self::db:refsect2
                         |$node/ancestor-or-self::db:refsect3
                         |$node/ancestor-or-self::db:simplesect
                         |$node/ancestor-or-self::db:bibliography
                         |$node/ancestor-or-self::db:glossary
                         |$node/ancestor-or-self::db:index)[last()]"/>
</xsl:function>

<xsl:function name="fp:nearest-section-id" as="xs:string">
  <xsl:param name="indexterm" as="element(db:indexterm)"/>
  <xsl:sequence select="f:generate-id(fp:nearest-section($indexterm))"/>
</xsl:function>

<xsl:function name="fp:group-index">
  <xsl:param name="term" as="xs:string"/>
  <xsl:param name="lang" as="xs:string"/>

  <xsl:variable name="letters"
                select="f:gentext-letters-for-language($lang)"/>

  <xsl:variable name="long-letter-index"
                select="$letters/l:l[. = substring($term,1,2)]/@i"/>

  <xsl:variable name="short-letter-index"
                select="$letters/l:l[. = substring($term,1,1)]/@i"/>

  <xsl:sequence select="($long-letter-index, $short-letter-index, 0)[1]"/>
</xsl:function>

<xsl:function name="fp:group-label">
  <xsl:param name="index" as="xs:integer"/>
  <xsl:param name="lang" as="xs:string"/>

  <xsl:variable name="letters"
                select="f:gentext-letters-for-language($lang)"/>

  <xsl:value-of select="$letters/l:l[@i=$index][1]"/>
</xsl:function>

<!-- ============================================================ -->

<xsl:template name="t:generate-index">
  <xsl:param name="scope" select="(ancestor::db:book|/)[last()]"/>

  <xsl:variable name="role"
                select="if (f:is-true($index-on-role))
                        then @role
                        else ()"/>

  <xsl:variable name="type"
                select="if (f:is-true($index-on-type))
                        then @type
                        else ()"/>

  <xsl:variable name="lang" select="f:l10n-language($scope)"/>

  <div class="generated-index">
    <xsl:for-each-group select="//db:indexterm[fp:scope(., $scope, $role, $type)]
                                   [not(@class = 'endofrange')]"
                        group-by="fp:group-index(fp:primary(.), $lang)">
      <xsl:sort select="fp:group-index(fp:primary(.), $lang)" data-type="number"/>
      <xsl:apply-templates select="." mode="m:index-div">
        <xsl:with-param name="scope" select="$scope"/>
        <xsl:with-param name="role" select="$role"/>
        <xsl:with-param name="type" select="$type"/>
        <xsl:with-param name="lang" select="$lang"/>
        <xsl:with-param name="nodes" select="current-group()"/>
        <xsl:with-param name="group-index" select="current-grouping-key()"/>
      </xsl:apply-templates>
    </xsl:for-each-group>
  </div>
</xsl:template>

<xsl:template match="db:indexterm" mode="m:index-div">
  <xsl:param name="scope" select="."/>
  <xsl:param name="role" select="''"/>
  <xsl:param name="type" select="''"/>
  <xsl:param name="lang" select="'en'"/>
  <xsl:param name="nodes" as="element()*"/>
  <xsl:param name="group-index"/>

  <xsl:if test="$nodes">
    <div class="generated-indexdiv">
      <header>
        <h3>
          <xsl:value-of select="fp:group-label($group-index, $lang)"/>
        </h3>
      </header>
      <ul>
        <xsl:for-each-group select="$nodes" group-by="fp:primary(.)">
          <xsl:sort select="fp:primary(.)" lang="{$lang}"/>
          <xsl:apply-templates select="current-group()[1]" mode="m:index-primary">
            <xsl:with-param name="scope" select="$scope"/>
            <xsl:with-param name="role" select="$role"/>
            <xsl:with-param name="type" select="$type"/>
            <xsl:with-param name="lang" select="$lang"/>
          </xsl:apply-templates>
        </xsl:for-each-group>
      </ul>
    </div>
  </xsl:if>
</xsl:template>

<xsl:template match="db:indexterm" mode="m:index-primary">
  <xsl:param name="scope" select="."/>
  <xsl:param name="role" select="''"/>
  <xsl:param name="type" select="''"/>
  <xsl:param name="lang" select="'en'"/>

  <xsl:variable name="key" select="fp:primary(.)"/>
  <xsl:variable name="refs"
                select="key('primary', $key)[fp:scope(., $scope, $role, $type)]"/>
  <li>
    <xsl:value-of select="db:primary"/>
    <xsl:for-each-group select="$refs[not(db:secondary) and not(db:see)]"
                        group-by="concat(fp:primary(.), ' ', fp:nearest-section-id(.))">
      <xsl:apply-templates select="." mode="mp:reference">
        <xsl:with-param name="scope" select="$scope"/>
        <xsl:with-param name="role" select="$role"/>
        <xsl:with-param name="type" select="$type"/>
      </xsl:apply-templates>
    </xsl:for-each-group>

    <xsl:if test="$refs[not(db:secondary)]/*[self::db:see]">
      <xsl:for-each-group select="$refs[db:see]"
                          group-by="concat(fp:primary(.), ' ', ' ', ' ', db:see)">
        <xsl:apply-templates select="." mode="m:index-see">
          <xsl:with-param name="scope" select="$scope"/>
          <xsl:with-param name="role" select="$role"/>
          <xsl:with-param name="type" select="$type"/>
          <xsl:with-param name="lang" select="$lang"/>
          <xsl:sort select="upper-case(db:see)" lang="{$lang}"/>
        </xsl:apply-templates>
      </xsl:for-each-group>
    </xsl:if>
    <xsl:if test="$refs/db:secondary or $refs[not(db:secondary)]/*[self::db:seealso]">
      <ul>
        <xsl:if test="count(db:seealso) &gt; 1">
          <xsl:message>Multiple see also's not supported: only using first</xsl:message>
        </xsl:if>

        <xsl:for-each-group select="$refs[db:seealso]"
                            group-by="concat(fp:primary(.), ' ', ' ', ' ', db:seealso[1])">
          <xsl:apply-templates select="." mode="m:index-seealso">
            <xsl:with-param name="scope" select="$scope"/>
            <xsl:with-param name="role" select="$role"/>
            <xsl:with-param name="type" select="$type"/>
            <xsl:with-param name="lang" select="$lang"/>
            <xsl:sort select="upper-case(db:seealso[1])" lang="{$lang}"/>
          </xsl:apply-templates>
        </xsl:for-each-group>
        <xsl:for-each-group select="$refs[db:secondary]"
                            group-by="concat(fp:primary(.), ' ', fp:secondary(.))">
          <xsl:apply-templates select="." mode="m:index-secondary">
            <xsl:with-param name="scope" select="$scope"/>
            <xsl:with-param name="role" select="$role"/>
            <xsl:with-param name="type" select="$type"/>
            <xsl:with-param name="lang" select="$lang"/>
            <xsl:with-param name="refs" select="current-group()"/>
            <xsl:sort select="upper-case(fp:secondary(.))" lang="{$lang}"/>
          </xsl:apply-templates>
        </xsl:for-each-group>
      </ul>
    </xsl:if>
  </li>
</xsl:template>

<xsl:template match="db:indexterm" mode="m:index-secondary">
  <xsl:param name="scope" select="."/>
  <xsl:param name="role" select="''"/>
  <xsl:param name="type" select="''"/>
  <xsl:param name="refs" as="element()*"/>
  <xsl:param name="lang" select="'en'"/>

  <xsl:variable name="key" select="concat(fp:primary(.), ' ', fp:secondary(.))"/>
  <li>
    <xsl:value-of select="db:secondary"/>
    <xsl:for-each-group select="$refs[not(db:tertiary) and not(db:see)]"
                        group-by="concat($key, ' ', fp:nearest-section-id(.))">
      <xsl:apply-templates select="." mode="mp:reference">
        <xsl:with-param name="scope" select="$scope"/>
        <xsl:with-param name="role" select="$role"/>
        <xsl:with-param name="type" select="$type"/>
        <xsl:with-param name="lang" select="$lang"/>
      </xsl:apply-templates>
    </xsl:for-each-group>

    <xsl:if test="$refs[not(db:tertiary)]/*[self::db:see]">
      <xsl:for-each-group select="$refs[db:see]"
                          group-by="concat(fp:primary(.), ' ', fp:secondary(.), ' ', ' ', db:see)">
        <xsl:apply-templates select="." mode="m:index-see">
          <xsl:with-param name="scope" select="$scope"/>
          <xsl:with-param name="role" select="$role"/>
          <xsl:with-param name="type" select="$type"/>
          <xsl:with-param name="lang" select="$lang"/>
          <xsl:sort select="upper-case(db:see)" lang="{$lang}"/>
        </xsl:apply-templates>
      </xsl:for-each-group>
    </xsl:if>
    <xsl:if test="$refs/db:tertiary or $refs[not(db:tertiary)]/*[self::db:seealso]">
      <ul>
        <xsl:if test="count(db:seealso) &gt; 1">
          <xsl:message>Multiple see also's not supported: only using first</xsl:message>
        </xsl:if>

        <xsl:for-each-group select="$refs[db:seealso]"
                            group-by="concat(fp:primary(.), ' ', fp:secondary(.), ' ', ' ', db:seealso[1])">
          <xsl:apply-templates select="." mode="m:index-seealso">
            <xsl:with-param name="scope" select="$scope"/>
            <xsl:with-param name="role" select="$role"/>
            <xsl:with-param name="type" select="$type"/>
            <xsl:with-param name="lang" select="$lang"/>
            <xsl:sort select="upper-case(db:seealso[1])" lang="{$lang}"/>
          </xsl:apply-templates>
        </xsl:for-each-group>

        <xsl:for-each-group select="$refs[db:tertiary]"
                            group-by="concat($key, ' ', fp:tertiary(.))">
          <xsl:apply-templates select="." mode="m:index-tertiary">
            <xsl:with-param name="scope" select="$scope"/>
            <xsl:with-param name="role" select="$role"/>
            <xsl:with-param name="type" select="$type"/>
            <xsl:with-param name="lang" select="$lang"/>
            <xsl:with-param name="refs" select="current-group()"/>
            <xsl:sort select="upper-case(fp:tertiary(.))" lang="{$lang}"/>
          </xsl:apply-templates>
        </xsl:for-each-group>
      </ul>
    </xsl:if>
  </li>
</xsl:template>

<xsl:template match="db:indexterm" mode="m:index-tertiary">
  <xsl:param name="scope" select="."/>
  <xsl:param name="role" select="''"/>
  <xsl:param name="type" select="''"/>
  <xsl:param name="lang" select="'en'"/>
  <xsl:param name="refs" as="element()*"/>

  <xsl:variable name="key" select="concat(fp:primary(.), ' ', fp:secondary(.), ' ', fp:tertiary(.))"/>
  <li>
    <xsl:value-of select="db:tertiary"/>
    <xsl:for-each-group select="$refs[not(db:see)]"
                        group-by="concat($key, ' ', fp:nearest-section-id(.))">
      <xsl:apply-templates select="." mode="mp:reference">
        <xsl:with-param name="scope" select="$scope"/>
        <xsl:with-param name="role" select="$role"/>
        <xsl:with-param name="type" select="$type"/>
        <xsl:with-param name="lang" select="$lang"/>
      </xsl:apply-templates>
    </xsl:for-each-group>

    <xsl:if test="$refs/db:see">
      <xsl:for-each-group select="$refs[db:see]"
                          group-by="concat(fp:primary(.), ' ', fp:secondary(.), ' ', fp:tertiary(.), ' ', db:see)">
        <xsl:apply-templates select="." mode="m:index-see">
          <xsl:with-param name="scope" select="$scope"/>
          <xsl:with-param name="role" select="$role"/>
          <xsl:with-param name="type" select="$type"/>
          <xsl:with-param name="lang" select="$lang"/>
          <xsl:sort select="upper-case(db:see)" lang="{$lang}"/>
        </xsl:apply-templates>
      </xsl:for-each-group>
    </xsl:if>
    <xsl:if test="$refs/db:seealso">
      <ul>
        <xsl:if test="count(db:seealso) &gt; 1">
          <xsl:message>Multiple see also's not supported: only using first</xsl:message>
        </xsl:if>

        <xsl:for-each-group select="$refs[db:seealso]"
                            group-by="concat(fp:primary(.), ' ', fp:secondary(.), ' ', fp:tertiary(.), ' ', db:seealso[1])">
          <xsl:apply-templates select="." mode="m:index-seealso">
            <xsl:with-param name="scope" select="$scope"/>
            <xsl:with-param name="role" select="$role"/>
            <xsl:with-param name="type" select="$type"/>
            <xsl:with-param name="lang" select="$lang"/>
            <xsl:sort select="upper-case(db:seealso[1])" lang="{$lang}"/>
          </xsl:apply-templates>
        </xsl:for-each-group>
      </ul>
    </xsl:if>
  </li>
</xsl:template>

<xsl:template match="db:indexterm" mode="mp:reference">
  <xsl:param name="scope" select="."/>
  <xsl:param name="role" select="''"/>
  <xsl:param name="type" select="''"/>
  <xsl:param name="lang" select="'en'"/>
  <xsl:param name="separator" select="', '"/>

  <xsl:value-of select="$separator"/>
  <xsl:choose>
    <xsl:when test="@zone">
      <xsl:call-template name="t:index-zone-reference">
        <xsl:with-param name="zones" select="tokenize(@zone, '\s+')"/>
        <xsl:with-param name="scope" select="$scope"/>
        <xsl:with-param name="role" select="$role"/>
        <xsl:with-param name="type" select="$type"/>
        <xsl:with-param name="lang" select="$lang"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:variable name="tobject"
                    select="ancestor::*[db:title or db:info/db:title][1]"/>
      <a class="indexref" href="{f:href(/,.)}">
        <xsl:attribute name="title">
          <xsl:apply-templates select="$tobject" mode="m:headline">
            <xsl:with-param name="purpose" select="'index-tooltip'"/>
          </xsl:apply-templates>
        </xsl:attribute>
        <xsl:value-of select="position()"/>
      </a>

      <xsl:if test="key('endofrange', @xml:id)[fp:scope(., $scope, $role, $type)]">
        <xsl:apply-templates select="key('endofrange', @xml:id)[fp:scope(., $scope, $role, $type)][last()]"
                             mode="mp:reference">
          <xsl:with-param name="scope" select="$scope"/>
          <xsl:with-param name="role" select="$role"/>
          <xsl:with-param name="type" select="$type"/>
          <xsl:with-param name="lang" select="$lang"/>
          <xsl:with-param name="separator" select="'-'"/>
        </xsl:apply-templates>
      </xsl:if>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template name="t:index-zone-reference">
  <xsl:param name="scope" select="."/>
  <xsl:param name="role" select="''"/>
  <xsl:param name="type" select="''"/>
  <xsl:param name="lang" select="'en'"/>
  <xsl:param name="zones" as="xs:string*"/>

  <xsl:choose>
    <xsl:when test="empty($zones)"/>
    <xsl:otherwise>
      <xsl:variable name="zone" select="$zones[1]"/>
      <xsl:variable name="target" select="key('id', $zone)
                                             [fp:scope(., $scope, $role, $type)]"/>
      <xsl:choose>
        <xsl:when test="$target">
          <a class="indexref" href="{f:href(/,$target[1])}">
            <xsl:apply-templates select="$target[1]" mode="m:headline">
              <xsl:with-param name="purpose" select="'index'"/>
            </xsl:apply-templates>
          </a>
        </xsl:when>
        <xsl:otherwise>
          <xsl:message select="'Warning: missing zone:', $zone"/>
        </xsl:otherwise>
      </xsl:choose>
      <xsl:if test="count($zones) gt 1">
        <xsl:text>, </xsl:text>
        <xsl:call-template name="t:index-zone-reference">
          <xsl:with-param name="zones" select="substring-after($zones, ' ')"/>
          <xsl:with-param name="scope" select="$scope"/>
          <xsl:with-param name="role" select="$role"/>
          <xsl:with-param name="type" select="$type"/>
          <xsl:with-param name="lang" select="$lang"/>
        </xsl:call-template>
      </xsl:if>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="db:indexterm" mode="m:index-see">
  <xsl:param name="scope" select="."/>
  <xsl:param name="role" select="''"/>
  <xsl:param name="type" select="''"/>
  <xsl:param name="lang" select="'en'"/>

  <span class="sep"> (</span>
   <xsl:apply-templates select="db:see" mode="m:crossref"/>
  <span class="sep">)</span>
</xsl:template>

<xsl:template match="db:indexterm" mode="m:index-seealso">
  <xsl:param name="scope" select="."/>
  <xsl:param name="role" select="''"/>
  <xsl:param name="type" select="''"/>
  <xsl:param name="lang" select="'en'"/>

  <xsl:for-each select="db:seealso">
    <xsl:sort select="upper-case(.)" lang="{$lang}"/>
    <li>
      <span class="sep">(</span>
      <xsl:apply-templates select="." mode="m:crossref"/>
      <span class="sep">)</span>
    </li>
  </xsl:for-each>
</xsl:template>

<!-- ============================================================ -->

<xsl:template match="db:indexentry">
  <xsl:apply-templates select="db:primaryie"/>
</xsl:template>

<xsl:template match="db:primaryie">
  <li>
    <xsl:apply-templates/>
    <xsl:choose>
      <xsl:when test="following-sibling::db:secondaryie">
        <ul>
          <xsl:apply-templates select="following-sibling::db:secondaryie"/>
        </ul>
      </xsl:when>
      <xsl:when test="following-sibling::db:seeie
                      |following-sibling::db:seealsoie">
        <ul>
          <xsl:apply-templates select="following-sibling::db:seeie
                                       |following-sibling::db:seealsoie"/>
        </ul>
      </xsl:when>
    </xsl:choose>
  </li>
</xsl:template>

<xsl:template match="db:secondaryie">
  <li>
    <xsl:apply-templates/>
    <xsl:choose>
      <xsl:when test="following-sibling::db:tertiaryie">
        <ul>
          <xsl:apply-templates select="following-sibling::db:tertiaryie"/>
        </ul>
      </xsl:when>
      <xsl:when test="following-sibling::db:seeie
                      |following-sibling::db:seealsoie">
        <ul>
          <xsl:apply-templates select="following-sibling::db:seeie
                                       |following-sibling::db:seealsoie"/>
        </ul>
      </xsl:when>
    </xsl:choose>
  </li>
</xsl:template>

<xsl:template match="db:tertiaryie">
  <li>
    <xsl:apply-templates/>
    <xsl:if test="following-sibling::db:seeie
                  |following-sibling::db:seealsoie">
      <ul>
        <xsl:apply-templates select="following-sibling::db:seeie
                                     |following-sibling::db:seealsoie"/>
      </ul>
    </xsl:if>
  </li>
</xsl:template>

<xsl:template match="db:seeie">
  <li>
    <xsl:sequence select="f:gentext(., 'label', 'see')"/>
    <xsl:text> </xsl:text>
    <xsl:apply-templates/>
  </li>
</xsl:template>

<xsl:template match="db:seealsoie">
  <li>
    <xsl:sequence select="f:gentext(., 'label', 'seealso')"/>
    <xsl:text> </xsl:text>
    <xsl:apply-templates/>
  </li>
</xsl:template>

</xsl:stylesheet>

sections.xsl

2 templates, 1 variable

Instructions
Template match ≅ db:sect1|db:sect2|db:sect3|db:…
Mode: m:docbook
Matches: db:sect1, db:sect2, db:sect3, db:sect4, db:sect5, db:section, db:simplesect
Variable $v:bridgehead-map as map(*)
Template match ≅ db:bridgehead
Mode: m:docbook
Matches: db:bridgehead
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:db="http://docbook.org/ns/docbook"
                xmlns:f="http://docbook.org/ns/docbook/functions"
                xmlns:m="http://docbook.org/ns/docbook/modes"
                xmlns:map="http://www.w3.org/2005/xpath-functions/map"
                xmlns:t="http://docbook.org/ns/docbook/templates"
                xmlns:v="http://docbook.org/ns/docbook/variables"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns="http://www.w3.org/1999/xhtml"
                default-mode="m:docbook"
                exclude-result-prefixes="db f m map t v xs"
                version="3.0">

<xsl:template match="db:sect1|db:sect2|db:sect3|db:sect4|db:sect5
                     |db:section|db:simplesect">
  <section>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates select="." mode="m:generate-titlepage"/>
    <xsl:apply-templates/>
  </section>
</xsl:template>

<xsl:variable name="v:bridgehead-map" as="map(*)">
  <xsl:map>
    <xsl:map-entry key="'sect1'" select="'h2'"/>
    <xsl:map-entry key="'sect2'" select="'h3'"/>
    <xsl:map-entry key="'sect3'" select="'h4'"/>
    <xsl:map-entry key="'sect4'" select="'h5'"/>
    <xsl:map-entry key="'sect5'" select="'h5'"/>
    <xsl:map-entry key="'sect6'" select="'h5'"/>
    <xsl:map-entry key="'block'" select="'div'"/>
  </xsl:map>
</xsl:variable>

<xsl:template match="db:bridgehead">
  <xsl:variable name="renderas" as="xs:string">
    <xsl:choose>
      <xsl:when test="@renderas">
        <xsl:sequence select="@renderas/string()"/>
      </xsl:when>
      <xsl:when test="parent::db:section">
        <xsl:sequence select="'sect' || (count(ancestor::db:section)+1)"/>
      </xsl:when>
      <xsl:when test="parent::db:refsection">
        <xsl:sequence select="'sect' || (count(ancestor::db:refsection)+1)"/>
      </xsl:when>
      <xsl:when test="parent::db:sect5">
        <xsl:sequence select="'sect5'"/>
      </xsl:when>
      <xsl:when test="parent::db:sect1|parent::db:sect2|parent::db:sect3|parent::db:sect4">
        <xsl:sequence select="'sect' ||
                               (xs:integer(substring(local-name(parent::*), 5, 1)) + 1)"/>
      </xsl:when>
      <xsl:when test="parent::db:refsect1|parent::db:refsect2|parent::db:refsect3">
        <xsl:sequence select="'sect' ||
                               (xs:integer(substring(local-name(parent::*), 8, 1)) + 1)"/>
      </xsl:when>
      <xsl:when test="parent::db:article|parent::db:chapter|parent::db:appendix
                      |parent::db:preface|parent::db:partintro
                      |parent::db:part|parent::db:reference">
        <xsl:sequence select="'sect1'"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:sequence select="'block'"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:choose>
    <xsl:when test="empty(map:get($v:bridgehead-map, $renderas))">
      <xsl:message select="'Unknown bridgehead renderas:', $renderas"/>
      <div>
        <xsl:apply-templates select="." mode="m:attributes">
          <xsl:with-param name="extra-classes" select="('title')"/>
        </xsl:apply-templates>
        <xsl:apply-templates/>
      </div>
    </xsl:when>
    <xsl:when test="map:get($v:bridgehead-map, $renderas) = 'div'">
      <div>
        <xsl:apply-templates select="." mode="m:attributes">
          <xsl:with-param name="extra-classes" select="('title')"/>
        </xsl:apply-templates>
        <xsl:apply-templates/>
      </div>
    </xsl:when>
    <xsl:otherwise>
      <xsl:element name="{map:get($v:bridgehead-map, $renderas)}"
                   namespace="http://www.w3.org/1999/xhtml">
        <xsl:apply-templates select="." mode="m:attributes"/>
        <xsl:apply-templates/>
      </xsl:element>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

</xsl:stylesheet>

templates.xsl

15 templates (1 used only in one other module), 3 functions, 3 variables

Instructions
Variable $v:templates as document-node()
Variable $vp:templates as document-node()
Function fp:construct-templates($templates as element()*, $list as element()*)
Template match ≅ element()
Mode: mp:expand-template
Matches: element()
Template match ≅ tmp:insert
Mode: mp:expand-template
Matches: tmp:insert
Template match ≅ attribute()|comment()|processi…
Mode: mp:expand-template
Matches: attribute(), comment(), processing-instruction(), text()
Function f:template($context as element(), $default as element()) as element()
Function fp:pick-template($context as element(), $templates as element()+) as element()
Variable $v:titlepage-default as element()
Template match ≅ *
Mode: m:generate-titlepage
Matches: *
Template match ≅ tmp:apply-templates
Mode: mp:construct-titlepage
Matches: tmp:apply-templates
Template match ≅ tmp:content
Mode: mp:construct-titlepage
Matches: tmp:content
Template match ≅ element()
Mode: mp:construct-titlepage
Matches: element()
Template match ≅ text()
Mode: mp:construct-titlepage
Matches: text()
Template match ≅ attribute()|comment()|processi…
Mode: mp:construct-titlepage
Matches: attribute(), comment(), processing-instruction()
Template t:biblioentry match ≅
Used by: template
Mode: m:docbook
Template match ≅ tmp:apply-templates
Mode: mp:construct-biblioentry
Matches: tmp:apply-templates
Template match ≅ tmp:content
Mode: mp:construct-biblioentry
Matches: tmp:content
Template match ≅ element()
Mode: mp:construct-biblioentry
Matches: element()
Template match ≅ text()
Mode: mp:construct-biblioentry
Matches: text()
Template match ≅ attribute()|comment()|processi…
Mode: mp:construct-biblioentry
Matches: attribute(), comment(), processing-instruction()
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:db="http://docbook.org/ns/docbook"
                xmlns:dbe="http://docbook.org/ns/docbook/errors"
                xmlns:f="http://docbook.org/ns/docbook/functions"
                xmlns:fp="http://docbook.org/ns/docbook/functions/private"
                xmlns:h="http://www.w3.org/1999/xhtml"
                xmlns:m="http://docbook.org/ns/docbook/modes"
                xmlns:mp="http://docbook.org/ns/docbook/modes/private"
                xmlns:t="http://docbook.org/ns/docbook/templates"
                xmlns:tmp="http://docbook.org/ns/docbook/templates"
                xmlns:v="http://docbook.org/ns/docbook/variables"
                xmlns:vp="http://docbook.org/ns/docbook/variables/private"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns="http://www.w3.org/1999/xhtml"
                default-mode="m:docbook"
                exclude-result-prefixes="db dbe f fp h m mp t tmp v vp xs"
                version="3.0">

<!-- It's a real shame that you can't have mode variables ... -->

<xsl:strip-space elements="tmp:*"/>

<!-- The default value is an empty document, it's for customizations to override -->
<xsl:variable name="v:templates" as="document-node()">
  <xsl:document/>
</xsl:variable>

<xsl:variable name="vp:templates" as="document-node()">
  <!-- Yes, this is basically fold-left done the hard way,
       but it avoids an EE feature in Saxon 9. -->
  <xsl:document>
    <xsl:sequence
        select="fp:construct-templates(($v:templates/*, doc('templates.xml')/*/*),
                                        ())"/>
  </xsl:document>
</xsl:variable>

<xsl:function name="fp:construct-templates">
  <xsl:param name="templates" as="element()*"/>
  <xsl:param name="list" as="element()*"/>

  <xsl:variable name="car" select="subsequence($templates, 1, 1)"/>
  <xsl:variable name="cdr" select="subsequence($templates, 2)"/>

  <xsl:choose>
    <xsl:when test="empty($templates)">
      <xsl:sequence select="$list"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:variable name="template" as="element()">
        <xsl:apply-templates select="$car" mode="mp:expand-template">
          <xsl:with-param name="list" select="$list"/>
        </xsl:apply-templates>
      </xsl:variable>
      <xsl:sequence select="fp:construct-templates($cdr, ($list, $template))"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

<xsl:template match="element()" mode="mp:expand-template">
  <xsl:param name="list" as="element()*" required="yes"/>
  <xsl:copy>
    <xsl:apply-templates select="@*, node()"
                         mode="mp:expand-template">
      <xsl:with-param name="list" select="$list"/>
    </xsl:apply-templates>
  </xsl:copy>
</xsl:template>

<xsl:template match="tmp:insert" mode="mp:expand-template">
  <xsl:param name="list" as="element()*" required="yes"/>

  <xsl:variable name="name"
                select="QName('http://docbook.org/ns/docbook/templates', @ref)"/>
  <xsl:variable name="template"
                select="($list[node-name(.)=$name])[1]"/>

  <xsl:sequence select="if (empty($template))
                        then error($dbe:INVALID-TEMPLATE,
                                   'No such template: ' || @ref)
                        else $template/*"/>
</xsl:template>

<xsl:template match="attribute()|text()|comment()|processing-instruction()"
              mode="mp:expand-template">
  <xsl:copy/>
</xsl:template>

<!-- ============================================================ -->

<xsl:function name="f:template" as="element()">
  <xsl:param name="context" as="element()"/>
  <xsl:param name="default" as="element()"/>

  <xsl:variable name="xpath" select="'/db:' || local-name($context)"/>
  <xsl:variable name="template" as="element()*">
    <xsl:evaluate context-item="$vp:templates" xpath="$xpath"/>
  </xsl:variable>

  <xsl:variable name="template" as="element()*">
    <xsl:sequence select="if (empty($template))
                          then $default
                          else $template"/>
  </xsl:variable>

  <xsl:sequence select="if (count($template) gt 1)
                        then fp:pick-template($context, $template)
                        else $template"/>
</xsl:function>

<xsl:function name="fp:pick-template" as="element()">
  <xsl:param name="context" as="element()"/>
  <xsl:param name="templates" as="element()+"/>

  <xsl:if test="not($templates[1]/@context) and (count($templates) gt 1)"
          use-when="'templates' = $v:debug">
    <xsl:message select="'A template without context should be last.'"/>
  </xsl:if>

  <xsl:choose>
    <xsl:when test="count($templates) eq 1 or not($templates[1]/@context)">
      <xsl:sequence select="$templates[1]"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:variable name="items" as="item()*">
        <xsl:evaluate context-item="$context"
                      xpath="$templates[1]/@context"/>
      </xsl:variable>

      <xsl:choose>
        <xsl:when test="count($items) = 1 and $items instance of xs:boolean">
          <xsl:sequence
              select="if ($items)
                      then $templates[1]
                      else fp:pick-template($context, subsequence($templates, 2))"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:sequence select="if (empty($items))
                                then fp:pick-template($context, subsequence($templates, 2))
                                else $templates[1]"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

<!-- ============================================================ -->

<xsl:variable name="v:titlepage-default" as="element()">
  <tmp:titlepage-default>
    <header>
      <tmp:apply-templates select="db:title">
        <div class="title"><tmp:content/></div>
      </tmp:apply-templates>
    </header>
  </tmp:titlepage-default>
</xsl:variable>

<xsl:template match="*" mode="m:generate-titlepage">
  <xsl:if test="fp:pmuj-enabled(/)">
    <xsl:sequence select="@xml:id ! fp:pmuj(./parent::*, ./string())"/>
  </xsl:if>

  <xsl:variable name="template"
                select="if (db:info/tmp:titlepage-template)
                        then db:info/tmp:titlepage-template
                        else f:template(., $v:titlepage-default)"/>

  <xsl:if test="empty(db:info)" use-when="'templates' = $v:debug">
    <xsl:message terminate="yes" select="'No db:info in', local-name(.)"/>
  </xsl:if>

  <xsl:variable name="empty-info" as="element(db:info)">
    <info xmlns="http://docbook.org/ns/docbook"/>
  </xsl:variable>

  <xsl:variable name="info"
                select="if (empty(db:info)) then $empty-info else db:info"/>

  <xsl:variable name="titlepage" as="node()*">
    <xsl:apply-templates select="$template/node()" mode="mp:construct-titlepage">
      <xsl:with-param name="info" select="$info"/>
      <xsl:with-param name="context" select="$info"/>
      <xsl:with-param name="template" select="$template/*"/>
      <xsl:with-param name="content" select="()"/>
    </xsl:apply-templates>
  </xsl:variable>

  <xsl:sequence select="if (count($titlepage) = 1
                            and $titlepage/self::*
                            and empty($titlepage/node())
                            and empty($titlepage/@*))
                        then ()
                        else $titlepage"/>
</xsl:template>

<xsl:template match="tmp:apply-templates" mode="mp:construct-titlepage">
  <xsl:param name="info" required="yes"/>
  <xsl:param name="context" required="yes"/>
  <xsl:param name="template" required="yes"/>
  <xsl:param name="content" required="yes"/>

  <xsl:variable name="content" select="node()"/>

  <xsl:variable use-when="'templates' = $v:debug"
                name="select" select="@select/string()"/>

  <xsl:variable name="elements" as="element()*">
    <xsl:evaluate xpath="@select" context-item="$context"/>
  </xsl:variable>

  <xsl:for-each select="$elements">
    <xsl:message use-when="'templates-matches' = $v:debug"
                 select="'Template:', $select, 'matched', node-name(.)"/>

    <xsl:choose>
      <xsl:when test="empty($content)">
        <xsl:apply-templates select="." mode="m:titlepage"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates select="$content" mode="mp:construct-titlepage">
          <xsl:with-param name="info" select="$info"/>
          <xsl:with-param name="context" select="."/>
          <xsl:with-param name="template" select="$template"/>
          <xsl:with-param name="content" select="."/>
        </xsl:apply-templates>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:for-each>
</xsl:template>

<xsl:template match="tmp:content" mode="mp:construct-titlepage">
  <xsl:param name="info" required="yes"/>
  <xsl:param name="context" required="yes"/>
  <xsl:param name="template" required="yes"/>
  <xsl:param name="content" required="yes"/>

  <xsl:apply-templates select="$content" mode="m:titlepage"/>
</xsl:template>

<xsl:template match="element()" mode="mp:construct-titlepage">
  <xsl:param name="info" required="yes"/>
  <xsl:param name="context" required="yes"/>
  <xsl:param name="template" required="yes"/>
  <xsl:param name="content" required="yes"/>

  <!-- For some reason, exclude-result-prefixes isn't
       excluding them, so just don't copy them. -->
  <xsl:element name="{node-name(.)}" namespace="http://www.w3.org/1999/xhtml">
    <xsl:apply-templates select="@*,node()"
                         mode="mp:construct-titlepage">
      <xsl:with-param name="info" select="$info"/>
      <xsl:with-param name="context" select="$context"/>
      <xsl:with-param name="template" select="$template"/>
      <xsl:with-param name="content" select="$content"/>
    </xsl:apply-templates>
  </xsl:element>
</xsl:template>

<xsl:template match="text()" mode="mp:construct-titlepage">
  <!-- whitespace in templates is ignored -->
  <xsl:param name="info" required="yes"/>
  <xsl:param name="context" required="yes"/>
  <xsl:param name="template" required="yes"/>
  <xsl:param name="content" required="yes"/>
  <xsl:if test="normalize-space(.) != ''">
    <xsl:copy/>
  </xsl:if>
</xsl:template>

<xsl:template match="attribute()|comment()|processing-instruction()"
              mode="mp:construct-titlepage">
  <xsl:param name="info" required="yes"/>
  <xsl:param name="context" required="yes"/>
  <xsl:param name="template" required="yes"/>
  <xsl:param name="content" required="yes"/>
  <xsl:copy/>
</xsl:template>

<!-- ============================================================ -->

<xsl:template name="t:biblioentry">
  <!-- For many elements, there's a default template if the user fails
       to provide one. There's so much variation in biblioentry, it's
       not even worth trying. -->
  <xsl:variable name="biblioentry-default" as="element()">
    <tmp:biblioentry-default>
      <div>ERROR: No template for biblioentry</div>
    </tmp:biblioentry-default>
  </xsl:variable>
  <xsl:variable name="template" select="f:template(., $biblioentry-default)"/>
  <xsl:variable name="entry" as="node()*">
    <xsl:apply-templates select="$template/node()" mode="mp:construct-biblioentry">
      <xsl:with-param name="info" select="."/>
      <xsl:with-param name="context" select="."/>
      <xsl:with-param name="template" select="$template/*"/>
      <xsl:with-param name="content" select="()"/>
    </xsl:apply-templates>
  </xsl:variable>

  <xsl:sequence select="if (count($entry) = 1
                            and $entry/self::*
                            and empty($entry/node())
                            and empty($entry/@*))
                        then ()
                        else $entry"/>
</xsl:template>

<xsl:template match="tmp:apply-templates" mode="mp:construct-biblioentry">
  <xsl:param name="info" required="yes"/>
  <xsl:param name="context" required="yes"/>
  <xsl:param name="template" required="yes"/>
  <xsl:param name="content" required="yes"/>

  <xsl:variable name="content" select="node()"/>

  <xsl:variable use-when="'templates' = $v:debug"
                name="select" select="@select/string()"/>

  <xsl:variable name="elements" as="element()*">
    <xsl:evaluate xpath="@select" context-item="$context"/>
  </xsl:variable>

  <xsl:for-each select="$elements">
    <xsl:message use-when="'templates-matches' = $v:debug"
                 select="'Template:', $select, 'matched', node-name(.)"/>

    <xsl:choose>
      <xsl:when test="empty($content)">
        <xsl:apply-templates select="." mode="m:biblioentry"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates select="$content" mode="mp:construct-biblioentry">
          <xsl:with-param name="info" select="$info"/>
          <xsl:with-param name="context" select="."/>
          <xsl:with-param name="template" select="$template"/>
          <xsl:with-param name="content" select="."/>
        </xsl:apply-templates>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:for-each>
</xsl:template>

<xsl:template match="tmp:content" mode="mp:construct-biblioentry">
  <xsl:param name="info" required="yes"/>
  <xsl:param name="context" required="yes"/>
  <xsl:param name="template" required="yes"/>
  <xsl:param name="content" required="yes"/>

  <xsl:apply-templates select="$content" mode="m:biblioentry"/>
</xsl:template>

<xsl:template match="element()" mode="mp:construct-biblioentry">
  <xsl:param name="info" required="yes"/>
  <xsl:param name="context" required="yes"/>
  <xsl:param name="template" required="yes"/>
  <xsl:param name="content" required="yes"/>

  <!-- For some reason, exclude-result-prefixes isn't
       excluding them, so just don't copy them. -->
  <xsl:element name="{node-name(.)}" namespace="http://www.w3.org/1999/xhtml">
    <xsl:apply-templates select="@*,node()"
                         mode="mp:construct-biblioentry">
      <xsl:with-param name="info" select="$info"/>
      <xsl:with-param name="context" select="$context"/>
      <xsl:with-param name="template" select="$template"/>
      <xsl:with-param name="content" select="$content"/>
    </xsl:apply-templates>
  </xsl:element>
</xsl:template>

<xsl:template match="text()" mode="mp:construct-biblioentry">
  <!-- whitespace in templates is ignored -->
  <xsl:param name="info" required="yes"/>
  <xsl:param name="context" required="yes"/>
  <xsl:param name="template" required="yes"/>
  <xsl:param name="content" required="yes"/>
  <xsl:if test="normalize-space(.) != ''">
    <xsl:copy/>
  </xsl:if>
</xsl:template>

<xsl:template match="attribute()|comment()|processing-instruction()"
              mode="mp:construct-biblioentry">
  <xsl:param name="info" required="yes"/>
  <xsl:param name="context" required="yes"/>
  <xsl:param name="template" required="yes"/>
  <xsl:param name="content" required="yes"/>
  <xsl:copy/>
</xsl:template>


</xsl:stylesheet>

titlepage.xsl

9 templates

Instructions
Template match ≅ db:title
Mode: m:titlepage
Matches: db:title
Template match ≅ db:formalpara/db:info/db:title
Mode: m:titlepage
Priority: 10
Matches: db:formalpara/db:info/db:title
Template match ≅ db:subtitle
Mode: m:titlepage
Matches: db:subtitle
Template match ≅ db:abstract|db:authorgroup|db:…
Mode: m:titlepage
Matches: db:abstract, db:authorgroup, db:copyright, db:legalnotice, db:pubdate, db:revhistory
Template match ≅ db:releaseinfo
Mode: m:titlepage
Matches: db:releaseinfo
Template match ≅ db:author
Mode: m:titlepage
Matches: db:author
Template match ≅ db:editor
Mode: m:titlepage
Matches: db:editor
Template match ≅ db:jobtitle|db:orgdiv|db:orgna…
Mode: m:titlepage
Matches: db:jobtitle, db:orgdiv, db:orgname
Template match ≅ *
Mode: m:titlepage
Matches: *
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:db="http://docbook.org/ns/docbook"
                xmlns:f="http://docbook.org/ns/docbook/functions"
                xmlns:fp="http://docbook.org/ns/docbook/functions/private"
                xmlns:m="http://docbook.org/ns/docbook/modes"
                xmlns:t="http://docbook.org/ns/docbook/l10n/title"
                xmlns:vp="http://docbook.org/ns/docbook/variables/private"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns="http://www.w3.org/1999/xhtml"
                default-mode="m:docbook"
                exclude-result-prefixes="db f fp m t vp xs"
                version="3.0">

<xsl:template match="db:title" mode="m:titlepage">
  <xsl:apply-templates select="../.." mode="m:headline">
    <xsl:with-param name="purpose" select="'title'"/>
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="db:formalpara/db:info/db:title" mode="m:titlepage" priority="10">
  <span>
    <xsl:choose>
      <xsl:when test="matches(normalize-space(string(.)), '^.*\p{P}$')">
        <xsl:attribute name="class" select="'title titlepunct'"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:attribute name="class" select="'title'"/>
      </xsl:otherwise>
    </xsl:choose>
    <xsl:apply-templates mode="m:titlepage"/>
  </span>
</xsl:template>

<xsl:template match="db:subtitle" mode="m:titlepage">
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="db:copyright|db:abstract|db:legalnotice
                     |db:authorgroup|db:revhistory
                     |db:pubdate"
              mode="m:titlepage">
  <xsl:apply-templates select="."/>
</xsl:template>

<xsl:template match="db:releaseinfo" mode="m:titlepage">
  <span>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates/>
  </span>
</xsl:template>

<xsl:template match="db:author" mode="m:titlepage">
  <xsl:apply-templates select="db:personname|db:orgname"/>
</xsl:template>

<xsl:template match="db:editor" mode="m:titlepage">
  <span class="editedby">
    <xsl:sequence select="f:gentext(., 'label', 'edited-by')"/>
    <xsl:sequence select="f:label-separator(.)"/>
  </span>
  <xsl:apply-templates select="db:personname|db:orgname"/>
</xsl:template>

<xsl:template match="db:jobtitle|db:orgname|db:orgdiv" mode="m:titlepage">
  <xsl:apply-templates select="."/>
</xsl:template>

<xsl:template match="*" mode="m:titlepage">
  <xsl:message select="'No titlepage template for: ' || node-name(.)"/>
  <xsl:apply-templates select="node()"/>
</xsl:template>

</xsl:stylesheet>

info.xsl

20 templates, 2 functions

Instructions
Template match ≅ db:info
Mode: m:docbook
Matches: db:info
Template match ≅ db:copyright
Mode: m:docbook
Matches: db:copyright
Template match ≅ db:year
Mode: m:copyright-years
Matches: db:year
Function fp:collapse-years#1($years as element(db:year)*)
Function fp:collapse-years#4($years as element(db:year)*, $first as xs:boolean, $prevyear as element(db:year)?, $constructed as item()*)
Template match ≅ db:holder|db:year
Mode: m:docbook
Matches: db:holder, db:year
Template match ≅ db:abstract|db:authorgroup|db:…
Mode: m:docbook
Matches: db:abstract, db:authorgroup, db:legalnotice
Template match ≅ db:firstname|db:givenname|db:h…
Mode: m:docbook
Matches: db:firstname, db:givenname, db:honorific, db:lineage, db:othername, db:surname
Template match ≅ db:personname
Template t:person-name match ≅
Template t:person-name-family-given match ≅
Used by: t:person-name
Mode: m:docbook
Template match ≅ /
Mode: m:to-uppercase
Matches: /
Template match ≅ *
Mode: m:to-uppercase
Matches: *
Template match ≅ comment()|processing-instructi…
Mode: m:to-uppercase
Matches: comment(), processing-instruction()
Template match ≅ text()
Mode: m:to-uppercase
Matches: text()
Template t:person-name-last-first match ≅
Used by: t:person-name
Mode: m:docbook
Template t:person-name-first-last match ≅
Used by: t:person-name
Mode: m:docbook
Template match ≅ db:city|db:country|db:email|db…
Calls: t:inline
Mode: m:docbook
Matches: db:city, db:country, db:email, db:fax, db:otheraddr, db:phone, db:pob, db:postcode, db:state, db:street
Template t:person-name-list match ≅
Template match ≅ db:artpagenums|db:authorinitia…
Calls: t:inline
Mode: m:docbook
Matches: db:artpagenums, db:authorinitials, db:contractnum, db:contractsponsor, db:edition, db:issuenum, db:pagenums, db:publishername, db:seriesvolnums, db:volumenum
Template match ≅ db:pubdate
Calls: f:pi()
Calls: t:inline
Mode: m:docbook
Matches: db:pubdate
Template match ≅ db:info/db:pubdate
Calls: f:pi()
Calls: t:inline
Mode: m:docbook
Matches: db:info/db:pubdate
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:db="http://docbook.org/ns/docbook"
                xmlns:dbe="http://docbook.org/ns/docbook/errors"
                xmlns:f="http://docbook.org/ns/docbook/functions"
                xmlns:fp="http://docbook.org/ns/docbook/functions/private"
                xmlns:m="http://docbook.org/ns/docbook/modes"
                xmlns:t="http://docbook.org/ns/docbook/templates"
                xmlns:v="http://docbook.org/ns/docbook/variables"
                xmlns:vp="http://docbook.org/ns/docbook/variables/private"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns="http://www.w3.org/1999/xhtml"
                default-mode="m:docbook"
                exclude-result-prefixes="db dbe f fp m t v vp xs"
                version="3.0">

<xsl:template match="db:info">
  <xsl:apply-templates select="db:indexterm"/>
</xsl:template>

<xsl:template match="db:copyright">
  <xsl:variable name="gi" select="if (parent::db:info)
                                  then 'div'
                                  else 'span'"/>
  <xsl:element name="{$gi}" namespace="http://www.w3.org/1999/xhtml">
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:text>Copyright © </xsl:text>
    <xsl:apply-templates select="db:year[1]" mode="m:copyright-years"/>
    <xsl:text> </xsl:text>
    <xsl:apply-templates select="db:holder"/>
  </xsl:element>
</xsl:template>

<xsl:template match="db:year" mode="m:copyright-years">
  <xsl:param name="prevyear" select="()"/>
  <xsl:param name="range" select="()"/>

  <xsl:choose>
    <xsl:when test="not($copyright-collapse-years)">
      <span>
        <xsl:apply-templates select="." mode="m:attributes"/>
        <xsl:apply-templates/>
      </span>
      <xsl:if test="following-sibling::db:year">
        <xsl:text>, </xsl:text>
        <xsl:apply-templates select="(following-sibling::db:year)[1]"/>
      </xsl:if>
    </xsl:when>
    <xsl:otherwise>
      <xsl:sequence select="fp:collapse-years((., following-sibling::db:year))"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:function name="fp:collapse-years">
  <xsl:param name="years" as="element(db:year)*"/>

  <span class="copyright-years">
    <xsl:choose>
      <xsl:when test="count($years) = 1">
        <xsl:apply-templates select="$years"/>
      </xsl:when>
      <xsl:when test="count($years) = 2">
        <xsl:choose>
          <xsl:when test="$years[1] castable as xs:integer
                          and $years[2] castable as xs:integer
                          and xs:integer($years[2]) = xs:integer($years[1]) + 1">
            <xsl:apply-templates select="$years[1]"/>
            <xsl:sequence select="$copyright-year-range-separator"/>
            <xsl:apply-templates select="$years[2]"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:apply-templates select="$years[1]"/>
            <xsl:sequence select="$copyright-year-separator"/>
            <xsl:apply-templates select="$years[2]"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:when>
      <xsl:otherwise>
        <xsl:sequence select="fp:collapse-years($years, true(), (), ())"/>
      </xsl:otherwise>
    </xsl:choose>
  </span>
</xsl:function>

<xsl:function name="fp:collapse-years">
  <xsl:param name="years" as="element(db:year)*"/>
  <xsl:param name="first" as="xs:boolean"/>
  <xsl:param name="prevyear" as="element(db:year)?"/>
  <xsl:param name="constructed" as="item()*"/>

  <!--
  <xsl:message select="'[', $prevyear/string(), ']:', $years ! string(.)"/>
  <xsl:message select="'X:', $first, $constructed"/>
  -->

  <xsl:choose>
    <xsl:when test="empty($prevyear)">
      <xsl:sequence
          select="fp:collapse-years(subsequence($years, 2), $first, $years[1], ())"/>
    </xsl:when>
    <xsl:when test="empty($years)">
      <xsl:choose>
        <xsl:when test="empty($constructed)">
          <xsl:if test="not($first)">
            <xsl:sequence select="$copyright-year-separator"/>
          </xsl:if>
          <xsl:apply-templates select="$prevyear"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:if test="not($first)">
            <xsl:sequence select="$copyright-year-separator"/>
          </xsl:if>
          <xsl:sequence select="$constructed"/>
          <xsl:sequence select="$copyright-year-range-separator"/>
          <xsl:apply-templates select="$prevyear"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:when>
    <xsl:when test="$prevyear castable as xs:integer
                    and $years[1] castable as xs:integer
                    and xs:integer($years[1]) = xs:integer($prevyear) + 1">
      <xsl:choose>
        <xsl:when test="empty($constructed)">
          <xsl:variable name="firstitem" as="item()*">
            <xsl:apply-templates select="$prevyear"/>
          </xsl:variable>
          <xsl:sequence
              select="fp:collapse-years(subsequence($years, 2),
                         $first, $years[1], $firstitem)"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:sequence
              select="fp:collapse-years(subsequence($years, 2),
                         $first, $years[1], $constructed)"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:when>
    <xsl:otherwise>
      <xsl:choose>
        <xsl:when test="empty($constructed)">
          <xsl:if test="not($first)">
            <xsl:sequence select="$copyright-year-separator"/>
          </xsl:if>
          <xsl:apply-templates select="$prevyear"/>
          <xsl:sequence
              select="fp:collapse-years(subsequence($years, 2), false(), $years[1], ())"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:if test="not($first)">
            <xsl:sequence select="$copyright-year-separator"/>
          </xsl:if>
          <xsl:sequence select="$constructed"/>
          <xsl:sequence select="$copyright-year-range-separator"/>
          <xsl:apply-templates select="$prevyear"/>
          <xsl:sequence
              select="fp:collapse-years(subsequence($years, 2), false(), $years[1], ())"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

<xsl:template match="db:holder|db:year">
  <span>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates/>
  </span>
</xsl:template>

<xsl:template match="db:abstract|db:legalnotice
                     |db:authorgroup[parent::db:info]">
  <div>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates/>
  </div>
</xsl:template>

<xsl:template match="db:honorific|db:firstname|db:othername
                     |db:surname|db:givenname|db:lineage">
  <span>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates/>
  </span>
</xsl:template>

<xsl:template match="db:personname">
  <xsl:variable name="node" select="."/>

  <xsl:variable name="style" as="xs:string?">
    <xsl:for-each select="$v:personal-name-styles">
      <xsl:if test="contains-token($node/@role, .)">
        <xsl:sequence select="."/>
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>

  <xsl:variable name="style" as="xs:string?">
    <xsl:choose>
      <xsl:when test="empty($style)
                      and (parent::db:author
                           or parent::db:editor
                           or parent::db:othercredit)
                      and parent::*/@role">
        <xsl:for-each select="$v:personal-name-styles">
          <xsl:if test="contains-token($node/parent::*/@role, .)">
            <xsl:sequence select="."/>
          </xsl:if>
        </xsl:for-each>
      </xsl:when>
      <xsl:otherwise>
        <xsl:sequence select="$style"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="style" as="xs:string?"
                select="if (empty($style))
                        then if (f:check-gentext(., 'style', 'personname'))
                             then  f:gentext(., 'style', 'personname')
                             else  $default-personal-name-style
                        else $style"/>

  <span>
    <xsl:apply-templates select="." mode="m:attributes">
      <xsl:with-param name="style" select="$style"/>
    </xsl:apply-templates>
    <xsl:call-template name="t:person-name">
      <xsl:with-param name="style" select="$style"/>
    </xsl:call-template>
  </span>
</xsl:template>

<xsl:template name="t:person-name">
  <xsl:param name="style" as="xs:string" required="yes"/>

  <xsl:variable name="node" select="."/>

  <xsl:choose>
    <xsl:when test="not(*)">
      <xsl:value-of select="normalize-space(.)"/>
    </xsl:when>
    <xsl:when test="$style = 'FAMILY-given'">
      <xsl:call-template name="t:person-name-family-given"/>
    </xsl:when>
    <xsl:when test="$style = 'last-first'">
      <xsl:call-template name="t:person-name-last-first"/>
    </xsl:when>
    <xsl:when test="$style = 'first-last'">
      <xsl:call-template name="t:person-name-first-last"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:sequence select="error($dbe:INVALID-NAME-STYLE,
        'Invalid name style: ' || $style)"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<!-- ============================================================ -->

<xsl:template name="t:person-name-family-given">
  <!-- The family-given style applies a convention for identifying given -->
  <!-- and family names in locales where it may be ambiguous -->
  <xsl:variable name="surname">
    <xsl:apply-templates select="db:surname[1]"/>
  </xsl:variable>

  <xsl:apply-templates select="$surname/node()" mode="m:to-uppercase"/>

  <xsl:if test="db:surname and (db:firstname or db:givenname)">
    <xsl:text> </xsl:text>
  </xsl:if>

  <xsl:apply-templates select="(db:firstname|db:givenname)[1]"/>

  <xsl:text> [FAMILY Given]</xsl:text>
</xsl:template>

<!-- ============================================================ -->

<xsl:template match="/" mode="m:to-uppercase">
  <xsl:apply-templates mode="m:to-uppercase"/>
</xsl:template>

<xsl:template match="*" mode="m:to-uppercase">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates mode="m:to-uppercase"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="processing-instruction()|comment()" mode="m:to-uppercase">
  <xsl:copy/>
</xsl:template>

<xsl:template match="text()" mode="m:to-uppercase">
  <xsl:value-of select="upper-case(.)"/>
</xsl:template>

<!-- ============================================================ -->

<xsl:template name="t:person-name-last-first">
  <xsl:apply-templates select="db:surname[1]"/>

  <xsl:if test="db:surname and (db:firstname or db:givenname)">
    <xsl:text>, </xsl:text>
  </xsl:if>

  <xsl:apply-templates select="(db:firstname|db:givenname)[1]"/>
</xsl:template>

<!-- ============================================================ -->

<xsl:template name="t:person-name-first-last">
  <xsl:if test="db:honorific">
    <xsl:apply-templates select="db:honorific[1]"/>
  </xsl:if>

  <xsl:if test="db:firstname or db:givenname">
    <xsl:if test="db:honorific">
      <xsl:text> </xsl:text>
    </xsl:if>
    <xsl:apply-templates select="(db:firstname|db:givenname)[1]"/>
  </xsl:if>

  <xsl:if test="db:othername and f:is-true($othername-in-middle)">
    <xsl:if test="db:honorific or db:firstname or db:givenname">
      <xsl:text> </xsl:text>
    </xsl:if>
    <xsl:apply-templates select="db:othername[1]"/>
  </xsl:if>

  <xsl:if test="db:surname">
    <xsl:if test="db:honorific or db:firstname or db:givenname
                  or (db:othername and f:is-true($othername-in-middle))">
      <xsl:text> </xsl:text>
    </xsl:if>
    <xsl:apply-templates select="db:surname[1]"/>
  </xsl:if>

  <xsl:if test="db:lineage">
    <xsl:text>, </xsl:text>
    <xsl:apply-templates select="db:lineage[1]"/>
  </xsl:if>
</xsl:template>

<xsl:template match="db:city|db:country|db:email|db:fax|db:phone
                     |db:pob|db:postcode|db:state|db:street|db:otheraddr">
  <xsl:call-template name="t:inline"/>
</xsl:template>

<!-- ============================================================ -->

<xsl:template name="t:person-name-list">
  <!-- Return a formatted string representation of the contents of
       the current element. The current element must contain one or
       more AUTHORs, CORPAUTHORs, OTHERCREDITs, and/or EDITORs.

       John Doe
     or
       John Doe and Jane Doe
     or
       John Doe, Jane Doe, and A. Nonymous
  -->
  <xsl:param name="person.list"
             select="db:author|db:corpauthor|db:othercredit|db:editor"/>
  <xsl:param name="person.count" select="count($person.list)"/>
  <xsl:param name="count" select="1"/>

  <xsl:choose>
    <xsl:when test="$count &gt; $person.count"></xsl:when>
    <xsl:otherwise>
      <xsl:apply-templates select="$person.list[position()=$count]"/>

      <xsl:choose>
        <xsl:when test="$person.count = 2 and $count = 1">
          <xsl:sequence select="f:gentext(., 'separator', 'author-sep2')"/>
        </xsl:when>
        <xsl:when test="$person.count &gt; 2 and $count+1 = $person.count">
          <xsl:sequence select="f:gentext(., 'separator', 'author-seplast')"/>
        </xsl:when>
        <xsl:when test="$count &lt; $person.count">
          <xsl:sequence select="f:gentext(., 'separator', 'author-sep')"/>
        </xsl:when>
      </xsl:choose>

      <xsl:call-template name="t:person-name-list">
        <xsl:with-param name="person.list" select="$person.list"/>
        <xsl:with-param name="person.count" select="$person.count"/>
        <xsl:with-param name="count" select="$count+1"/>
      </xsl:call-template>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<!-- ============================================================ -->

<xsl:template match="db:publishername
                     |db:seriesvolnums|db:volumenum|db:issuenum
                     |db:artpagenums|db:authorinitials|db:edition|db:pagenums
                     |db:contractnum|db:contractsponsor">
  <xsl:call-template name="t:inline"/>
</xsl:template>

<xsl:template match="db:pubdate">
  <xsl:variable name="format" select="f:pi(., 'format')"/>

  <xsl:call-template name="t:inline">
    <xsl:with-param name="namemap" select="'time'"/>
    <xsl:with-param name="content">
      <xsl:apply-templates/>
    </xsl:with-param>
    <xsl:with-param name="extra-attributes" as="attribute()*">
      <xsl:choose>
        <xsl:when test="*"/>
        <xsl:when test="string(.) castable as xs:dateTime">
          <xsl:attribute name="datetime" select="."/>
        </xsl:when>
        <xsl:when test="string(.) castable as xs:date">
          <xsl:attribute name="datetime" select="."/>
        </xsl:when>
        <xsl:when test="string(.) castable as xs:integer">
          <xsl:attribute name="datetime" select="."/>
        </xsl:when>
        <xsl:otherwise/>
      </xsl:choose>
    </xsl:with-param>
  </xsl:call-template>
</xsl:template>

<xsl:template match="db:info/db:pubdate">
  <xsl:variable name="format" select="f:pi(., 'format')"/>

  <xsl:call-template name="t:inline">
    <xsl:with-param name="namemap" select="'time'"/>
    <xsl:with-param name="content">
      <xsl:choose>
        <xsl:when test="*">
          <xsl:apply-templates/>
        </xsl:when>
        <xsl:when test="string(.) castable as xs:dateTime">
          <xsl:variable name="date" select="xs:dateTime(string(.))"/>
          <xsl:choose>
            <xsl:when test="$format">
              <xsl:sequence select="format-dateTime($date, $format)"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:sequence select="format-dateTime($date, $date-dateTime-format)"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:when>
        <xsl:when test="string(.) castable as xs:date">
          <xsl:variable name="date" select="xs:date(string(.))"/>
          <xsl:choose>
            <xsl:when test="$format">
              <xsl:sequence select="format-date($date, $format)"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:sequence select="format-date($date, $date-date-format)"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:when>
        <xsl:otherwise>
          <xsl:apply-templates/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:with-param>
    <xsl:with-param name="extra-attributes" as="attribute()*">
      <xsl:choose>
        <xsl:when test="*"/>
        <xsl:when test="string(.) castable as xs:dateTime">
          <xsl:attribute name="datetime" select="."/>
        </xsl:when>
        <xsl:when test="string(.) castable as xs:date">
          <xsl:attribute name="datetime" select="."/>
        </xsl:when>
        <xsl:when test="string(.) castable as xs:integer">
          <xsl:attribute name="datetime" select="."/>
        </xsl:when>
        <xsl:otherwise/>
      </xsl:choose>
    </xsl:with-param>
  </xsl:call-template>
</xsl:template>
</xsl:stylesheet>

lists.xsl

29 templates, 2 functions, 1 variable (1 unused)

Instructions
Template match ≅ db:itemizedlist
Mode: m:docbook
Matches: db:itemizedlist
Template match ≅ db:orderedlist
Mode: m:docbook
Matches: db:orderedlist
Template tp:orderedlist-properties match ≅
Template match ≅ db:listitem
Mode: m:docbook
Matches: db:listitem
Template match ≅ db:simplelist
Mode: m:docbook
Matches: db:simplelist
Template match ≅ db:simplelist
Mode: m:docbook
Matches: db:simplelist
Function fp:select-vert-members($member as element(db:member)?, $rows as xs:integer) as element(db:member)*
Template match ≅ db:member
Mode: m:docbook
Matches: db:member
Template match ≅ db:variablelist
Mode: m:docbook
Matches: db:variablelist
Variable $vp:term
Unused
Template match ≅ db:varlistentry
Mode: m:docbook
Matches: db:varlistentry
Template match ≅ db:term
Mode: m:docbook
Matches: db:term
Function fp:estimated-term-length($entry as element(db:varlistentry))
Used by: template
Template match ≅ db:segmentedlist
Calls: f:pi()
Mode: m:docbook
Matches: db:segmentedlist
Template match ≅ db:segtitle
Mode: m:docbook
Matches: db:segtitle
Template match ≅ db:segtitle
Mode: m:segtitle-in-seg
Matches: db:segtitle
Template match ≅ db:seglistitem
Mode: m:docbook
Matches: db:seglistitem
Template match ≅ db:seg
Mode: m:docbook
Matches: db:seg
Template match ≅ db:segmentedlist
Calls: f:pi()
Mode: m:seglist-table
Matches: db:segmentedlist
Template match ≅ db:segtitle
Mode: m:seglist-table
Matches: db:segtitle
Template match ≅ db:seglistitem
Mode: m:seglist-table
Matches: db:seglistitem
Template match ≅ db:seg
Mode: m:seglist-table
Matches: db:seg
Template match ≅ db:calloutlist
Mode: m:docbook
Matches: db:calloutlist
Template match ≅ db:callout
Mode: m:docbook
Matches: db:callout
Template match ≅ *
Mode: m:callout-link
Matches: *
Template match ≅ db:area|db:co
Mode: m:callout-link
Matches: db:area, db:co
Template match ≅ db:procedure
Mode: m:docbook
Matches: db:procedure
Template match ≅ db:step
Mode: m:docbook
Matches: db:step
Template match ≅ db:substeps
Mode: m:docbook
Matches: db:substeps
Template match ≅ db:stepalternatives
Mode: m:docbook
Matches: db:stepalternatives
Template match ≅ db:result
Mode: m:docbook
Matches: db:result
Template match ≅ db:task|db:taskprerequisites|d…
Mode: m:docbook
Matches: db:task, db:taskprerequisites, db:taskrelated, db:tasksummary
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:db="http://docbook.org/ns/docbook"
                xmlns:dbe="http://docbook.org/ns/docbook/errors"
                xmlns:f="http://docbook.org/ns/docbook/functions"
                xmlns:fp="http://docbook.org/ns/docbook/functions/private"
                xmlns:m="http://docbook.org/ns/docbook/modes"
                xmlns:t="http://docbook.org/ns/docbook/templates"
                xmlns:tp="http://docbook.org/ns/docbook/templates/private"
                xmlns:vp="http://docbook.org/ns/docbook/variables/private"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns="http://www.w3.org/1999/xhtml"
                default-mode="m:docbook"
                exclude-result-prefixes="db dbe f fp m t tp vp xs"
                version="3.0">

<xsl:template match="db:itemizedlist">
  <xsl:variable name="compact" as="xs:boolean"
                select="@spacing = 'compact'
                        and count(db:listitem/db:para) = count(db:listitem)
                        and empty(db:listitem/*[not(self::db:para)])"/>

  <xsl:choose>
    <xsl:when test="empty(db:info/*)
                    and empty(* except (db:info|db:listitem|db:annotation))">
      <ul>
        <xsl:apply-templates select="." mode="m:attributes"/>
        <xsl:if test="@mark">
          <xsl:attribute name="db-mark" select="@mark"/>
        </xsl:if>
        <xsl:apply-templates select="node()">
          <xsl:with-param name="compact" select="$compact"/>
        </xsl:apply-templates>
      </ul>
    </xsl:when>
    <xsl:otherwise>
      <div>
        <xsl:apply-templates select="." mode="m:attributes"/>
        <xsl:apply-templates select="." mode="m:generate-titlepage"/>
        <xsl:apply-templates select="* except db:listitem"/>
        <ul>
          <xsl:if test="@mark">
            <xsl:attribute name="db-mark" select="@mark"/>
          </xsl:if>
          <xsl:apply-templates select="db:listitem">
            <xsl:with-param name="compact" select="$compact"/>
          </xsl:apply-templates>
        </ul>
      </div>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="db:orderedlist">
  <xsl:variable name="compact" as="xs:boolean"
                select="@spacing = 'compact'
                        and count(db:listitem/db:para) = count(db:listitem)
                        and empty(db:listitem/*[not(self::db:para)])"/>

  <xsl:choose>
    <xsl:when test="empty(db:info/*)
                    and empty(* except (db:info|db:listitem|db:annotation))">
      <ol>
        <xsl:apply-templates select="." mode="m:attributes"/>
        <xsl:call-template name="tp:orderedlist-properties"/>
        <xsl:apply-templates select="node()">
          <xsl:with-param name="compact" select="$compact"/>
        </xsl:apply-templates>
      </ol>
    </xsl:when>
    <xsl:otherwise>
      <div>
        <xsl:apply-templates select="." mode="m:attributes">
          <xsl:with-param name="exclude-classes"
                          select="if (@inheritnum = 'inherit')
                                  then 'inheritnum'
                                  else ()"/>
        </xsl:apply-templates>
        <xsl:apply-templates select="." mode="m:generate-titlepage"/>
        <xsl:apply-templates select="* except db:listitem"/>
        <ol>
          <xsl:if test="@inheritnum = 'inherit'">
            <xsl:attribute name="class" select="'inheritnum'"/>
          </xsl:if>
          <xsl:call-template name="tp:orderedlist-properties"/>
          <xsl:apply-templates select="db:listitem">
            <xsl:with-param name="compact" select="$compact"/>
          </xsl:apply-templates>
        </ol>
      </div>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template name="tp:orderedlist-properties">
  <xsl:if test="@startingnumber">
    <xsl:attribute name="start" select="@startingnumber"/>
  </xsl:if>
  <xsl:if test="@continuation='continues'">
    <xsl:attribute name="start" select="f:orderedlist-startingnumber(.)"/>
  </xsl:if>
  <xsl:choose>
    <xsl:when test="empty(@numeration)">
      <xsl:attribute name="type"
                     select="f:orderedlist-item-numeration(db:listitem[1])"/>
    </xsl:when>
    <xsl:when test="@numeration='arabic'">
      <xsl:attribute name="type" select="'1'"/>
    </xsl:when>
    <xsl:when test="@numeration='upperalpha'">
      <xsl:attribute name="type" select="'A'"/>
    </xsl:when>
    <xsl:when test="@numeration='loweralpha'">
      <xsl:attribute name="type" select="'a'"/>
    </xsl:when>
    <xsl:when test="@numeration='upperroman'">
      <xsl:attribute name="type" select="'I'"/>
    </xsl:when>
    <xsl:when test="@numeration='lowerroman'">
      <xsl:attribute name="type" select="'i'"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:message>Ignoring unexpected numeration: {@numeration}</xsl:message>
    </xsl:otherwise>
  </xsl:choose>

  <xsl:if test="@inheritnum and not(@inheritnum = ('ignore', 'inherit'))">
    <xsl:message>Ignoring unexpected inheritnum: {@inheritnum}</xsl:message>
  </xsl:if>
</xsl:template>

<xsl:template match="db:listitem">
  <xsl:param name="compact" as="xs:boolean" select="false()"/>

  <xsl:variable name="gi" select="if (parent::db:varlistentry)
                                  then 'dd'
                                  else 'li'"/>

  <xsl:element name="{$gi}" namespace="http://www.w3.org/1999/xhtml">
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:if test="@override">
      <xsl:choose>
        <xsl:when test="parent::db:orderedlist">
          <xsl:attribute name="value" select="@override"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:attribute name="db-mark" select="@override"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:if>
    <xsl:choose>
      <xsl:when test="$compact and count(*) = 1 and db:para">
        <xsl:apply-templates select="db:para/node()"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:element>
</xsl:template>

<xsl:template match="db:simplelist[@type='inline']">
  <span>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:for-each select="db:member">
      <xsl:if test="position() gt 1">, </xsl:if>
      <xsl:apply-templates select="."/>
    </xsl:for-each>
  </span>
</xsl:template>

<xsl:template match="db:simplelist">
  <xsl:variable name="cols" as="xs:integer">
    <xsl:choose>
      <xsl:when test="not(@columns)">
        <xsl:sequence select="1"/>
      </xsl:when>
      <xsl:when test="@columns castable as xs:integer">
        <xsl:sequence select="@columns cast as xs:integer"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:message>Treating non-numeric columns ({@columns}) as 1</xsl:message>
        <xsl:sequence select="1"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:choose>
    <xsl:when test="@type = 'horiz'">
      <div>
        <xsl:apply-templates select="." mode="m:attributes">
          <xsl:with-param name="extra-classes" select="'simplelisthoriz'"/>
        </xsl:apply-templates>
        <xsl:for-each select="db:member">
          <xsl:if test="$cols eq 1 or position() mod $cols = 1">
            <xsl:variable name="member" select="."/>
            <xsl:variable name="row" as="element(db:member)+">
              <xsl:sequence select="$member"/>
              <xsl:if test="$cols gt 1">
                <xsl:sequence select="$member/following-sibling::db:member
                                      [position() lt $cols]"/>
              </xsl:if>
            </xsl:variable>
            <div class="row">
              <xsl:apply-templates select="$row"/>
            </div>
          </xsl:if>
        </xsl:for-each>
      </div>
    </xsl:when>
    <xsl:otherwise>
      <div>
        <xsl:apply-templates select="." mode="m:attributes">
          <xsl:with-param name="extra-classes" select="'simplelistvert'"/>
        </xsl:apply-templates>

        <xsl:choose>
          <xsl:when test="$cols = 1">
            <!-- special case a single column... -->
            <xsl:for-each select="db:member">
              <div class="row">
                <xsl:apply-templates select="."/>
              </div>
            </xsl:for-each>
          </xsl:when>
          <xsl:otherwise>
            <xsl:variable name="rows" select="(count(db:member) + $cols - 1) idiv $cols"/>
            <xsl:for-each select="subsequence(db:member, 1, $rows)">
              <div class="row">
                <xsl:apply-templates select="fp:select-vert-members(., $rows)"/>
              </div>
            </xsl:for-each>
          </xsl:otherwise>
        </xsl:choose>
      </div>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<!-- 
  A B C D E => A D
               B E
               C
-->

<xsl:function name="fp:select-vert-members" as="element(db:member)*">
  <xsl:param name="member" as="element(db:member)?"/>
  <xsl:param name="rows" as="xs:integer"/>

  <xsl:variable name="next"
                select="$member/following-sibling::*[position() eq $rows]"/>

  <xsl:sequence select="$member"/>
  <xsl:if test="$next">
    <xsl:sequence select="fp:select-vert-members($next, $rows)"/>
  </xsl:if>
</xsl:function>

<xsl:template match="db:member">
  <span>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates/>
  </span>
</xsl:template>

<!-- ============================================================ -->

<xsl:template match="db:variablelist">
  <xsl:variable name="compact" as="xs:boolean"
                select="@spacing = 'compact'
                        and count(db:varlistentry/db:listitem/db:para)
                            = count(db:varlistentry/db:listitem)
                        and empty(db:varlistentry/db:listitem/*[not(self::db:para)])"/>
  <xsl:variable name="term-length"
                select="if (@termlength)
                        then @termlength/string()
                        else max((db:varlistentry ! fp:estimated-term-length(.)))"/>

  <xsl:choose>
    <xsl:when test="empty(db:info/*)
                    and empty(* except (db:info|db:varlistentry|db:annotation))">
      <dl>
        <xsl:apply-templates select="." mode="m:attributes">
          <xsl:with-param name="term-length" select="$term-length"/>
        </xsl:apply-templates>
        <xsl:apply-templates select="node()">
          <xsl:with-param name="compact" select="$compact"/>
        </xsl:apply-templates>
      </dl>
    </xsl:when>
    <xsl:otherwise>
      <div>
        <xsl:apply-templates select="." mode="m:attributes">
          <xsl:with-param name="term-length" select="$term-length"/>
        </xsl:apply-templates>
        <xsl:apply-templates select="." mode="m:generate-titlepage"/>
        <xsl:apply-templates select="* except db:varlistentry"/>
        <dl>
          <!-- repeat the class and other attributes for convenience -->
          <xsl:apply-templates select="." mode="m:attributes">
            <xsl:with-param name="term-length" select="$term-length"/>
            <xsl:with-param name="exclude-id" select="true()"/>
          </xsl:apply-templates>
          <xsl:apply-templates select="db:varlistentry">
            <xsl:with-param name="compact" select="$compact"/>
          </xsl:apply-templates>
        </dl>
      </div>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:variable name="vp:term"
              select="QName('http://docbook.org/ns/docbook', 'term')"/>

<xsl:template match="db:varlistentry">
  <xsl:param name="compact" as="xs:boolean" select="false()"/>
  <dt>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates select="db:term[1]"/>
    <xsl:choose>
      <xsl:when test="count(db:term) = 1"/>
      <xsl:when test="count(db:term) = 2">
        <xsl:apply-templates select="db:term[2]">
          <xsl:with-param name="sep"
                          select="f:gentext(db:term[2], 'separator', 'term-sep2')"/>
        </xsl:apply-templates>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates select="db:term[position() gt 1 and position() lt last()]">
          <xsl:with-param name="sep"
                          select="f:gentext(db:term[2], 'separator', 'term-sep')"/>
        </xsl:apply-templates>
        <xsl:apply-templates select="db:term[last()]">
          <xsl:with-param name="sep"
                          select="f:gentext(db:term[2], 'separator', 'term-seplast')"/>
        </xsl:apply-templates>
      </xsl:otherwise>
    </xsl:choose>
  </dt>

  <xsl:apply-templates select="db:listitem">
    <xsl:with-param name="compact" select="$compact"/>
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="db:term">
  <xsl:param name="sep" as="item()*" select="()"/>
  <xsl:if test="exists($sep) and preceding-sibling::db:term">
    <xsl:sequence select="$sep"/>
  </xsl:if>
  <span>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates/>
  </span>
</xsl:template>

<xsl:function name="fp:estimated-term-length">
  <xsl:param name="entry" as="element(db:varlistentry)"/>
  <xsl:value-of select="sum(($entry/db:term ! string-length(string(.))))"/>
</xsl:function>

<!-- ============================================================ -->

<xsl:template match="db:segmentedlist">
  <xsl:variable name="presentation"
                select="f:pi(., 'segmentedlist-style', $segmentedlist-style)"/>

  <div>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates select="." mode="m:generate-titlepage"/>

    <xsl:choose>
      <xsl:when test="$presentation = 'table'">
        <xsl:apply-templates select="." mode="m:seglist-table"/>
      </xsl:when>
      <xsl:when test="$presentation = 'list'">
        <xsl:apply-templates/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:message select="'Unrecognized segementedlist-style:', $presentation"/>
        <xsl:apply-templates/>
      </xsl:otherwise>
    </xsl:choose>
  </div>
</xsl:template>

<xsl:template match="db:segtitle"/>

<xsl:template match="db:segtitle" mode="m:segtitle-in-seg">
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="db:seglistitem">
  <div>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates/>
  </div>
</xsl:template>

<xsl:template match="db:seg">
  <xsl:variable name="segnum" select="count(preceding-sibling::db:seg)+1"/>
  <xsl:variable name="seglist" select="ancestor::db:segmentedlist"/>
  <xsl:variable name="segtitles" select="$seglist/db:segtitle"/>

  <!--
     Note: segtitle is only going to be the right thing in a well formed
     SegmentedList.  If there are too many Segs or too few SegTitles,
     you'll get something odd...maybe an error
  -->

  <div>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <strong>
      <span class="segtitle">
        <xsl:apply-templates select="$segtitles[$segnum=position()]"
                             mode="m:segtitle-in-seg"/>
        <xsl:text>: </xsl:text>
      </span>
    </strong>
    <xsl:apply-templates/>
  </div>
</xsl:template>

<xsl:template match="db:segmentedlist" mode="m:seglist-table">
  <xsl:variable name="table-summary"
                select="f:pi(., 'table-summary')"/>

  <table>
    <xsl:if test="$table-summary != ''">
      <xsl:attribute name="summary">
        <xsl:value-of select="$table-summary"/>
      </xsl:attribute>
    </xsl:if>
    <thead class="segtitles">
      <tr>
        <xsl:apply-templates select="db:segtitle" mode="m:seglist-table"/>
      </tr>
    </thead>
    <tbody>
      <xsl:apply-templates select="db:seglistitem" mode="m:seglist-table"/>
    </tbody>
  </table>
</xsl:template>

<xsl:template match="db:segtitle" mode="m:seglist-table">
  <th>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates/>
  </th>
</xsl:template>

<xsl:template match="db:seglistitem" mode="m:seglist-table">
  <xsl:variable name="seglinum">
    <xsl:number from="db:segmentedlist" count="db:seglistitem"/>
  </xsl:variable>

  <tr>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates mode="m:seglist-table"/>
  </tr>
</xsl:template>

<xsl:template match="db:seg" mode="m:seglist-table">
  <td>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates/>
  </td>
</xsl:template>

<!-- ============================================================ -->

<xsl:template match="db:calloutlist">
  <div>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates select="." mode="m:generate-titlepage"/>
    <xsl:apply-templates select="* except db:callout"/>
    <dl>
      <xsl:apply-templates select="db:callout"/>
    </dl>
  </div>
</xsl:template>

<xsl:template match="db:callout">
  <xsl:variable name="context" select="."/>
  <dt>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:for-each select="tokenize(normalize-space(@arearefs), '\s+')">
      <xsl:variable name="id" select="."/>
      <xsl:variable name="area" select="key('id', $id, root($context))"/>
      <xsl:variable name="area"
                    select="if (empty($area))
                            then root($context)//*[@xml:id = $id]
                            else $area"/>

      <xsl:choose>
        <xsl:when test="$area/parent::db:areaset
                        and $area/preceding-sibling::db:area"/>
        <xsl:when test="$area/self::db:areaset">
          <xsl:apply-templates select="$area/db:area[1]"
                               mode="m:callout-link">
            <xsl:with-param name="id" select="$id"/>
            <xsl:with-param name="target" select="$area"/>
          </xsl:apply-templates>
        </xsl:when>
        <xsl:when test="$area/self::db:area">
          <xsl:apply-templates select="$area"
                               mode="m:callout-link">
            <xsl:with-param name="id" select="$id"/>
            <xsl:with-param name="target" select="$area"/>
          </xsl:apply-templates>
        </xsl:when>
        <xsl:when test="$area/self::db:co">
          <xsl:apply-templates select="$area"
                               mode="m:callout-link">
            <xsl:with-param name="id" select="$id"/>
            <xsl:with-param name="target" select="$area"/>
          </xsl:apply-templates>
        </xsl:when>
        <xsl:otherwise>
          <xsl:sequence select="error($dbe:INVALID-AREAREFS,
                                      'Invalid area in arearefs: ' || $id)"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each>
  </dt>
  <dd>
    <xsl:apply-templates/>
  </dd>
</xsl:template>

<xsl:template match="*" mode="m:callout-link">
  <xsl:message select="'Error: processing ', node-name(.), ' in m:callout-link mode'"/>
  <span class="error">???</span>
</xsl:template>

<xsl:template match="db:area|db:co" mode="m:callout-link">
  <xsl:param name="id" as="xs:string"/>
  <xsl:param name="target" as="element()?"/>
  <a class="callout-bug" href="#{$id}">
    <xsl:apply-templates select="." mode="m:callout-bug">
      <xsl:with-param name="id" select="$id"/>
    </xsl:apply-templates>
  </a>
</xsl:template>

<!-- ============================================================ -->

<xsl:template match="db:procedure">
  <xsl:choose>
    <xsl:when test="empty(db:info/*)
                    and empty(* except (db:step|db:annotation))">
      <ol type="1">
        <xsl:apply-templates select="." mode="m:attributes"/>
        <xsl:apply-templates select="db:step"/>
      </ol>
    </xsl:when>
    <xsl:otherwise>
      <div>
        <xsl:apply-templates select="." mode="m:attributes"/>
        <xsl:apply-templates select="." mode="m:generate-titlepage"/>
        <xsl:apply-templates select="child::* except (db:step|db:result)"/>
        <ol class="{local-name(.)}" type="1">
          <xsl:apply-templates select="db:step"/>
        </ol>
        <xsl:apply-templates select="db:result"/>
      </div>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="db:step">
  <li>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates select="." mode="m:generate-titlepage"/>
    <xsl:apply-templates/>
  </li>
</xsl:template>

<xsl:template match="db:substeps">
  <div>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <ol class="procedure {local-name(.)}"
        type="{f:step-numeration(db:step[1])}">
      <xsl:apply-templates/>
    </ol>
  </div>
</xsl:template>

<xsl:template match="db:stepalternatives">
  <div>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <ul class="procedure {local-name(.)}">
      <xsl:apply-templates/>
    </ul>
  </div>
</xsl:template>

<xsl:template match="db:result">
  <div>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates/>
  </div>
</xsl:template>

<!-- ============================================================ -->

<xsl:template match="db:task|db:tasksummary|db:taskprerequisites|db:taskrelated">
  <div>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates select="." mode="m:generate-titlepage"/>
    <xsl:apply-templates/>
  </div>
</xsl:template>

</xsl:stylesheet>

blocks.xsl

24 templates

Instructions
Template match ≅ db:informalequation|db:informa…
Mode: m:docbook
Matches: db:informalequation, db:informalexample, db:informalfigure
Template match ≅ db:equation|db:example|db:figu…
Mode: m:docbook
Matches: db:equation, db:example, db:figure, db:formalgroup, db:screenshot
Template match ≅ math:*
Mode: m:docbook
Matches: math:*
Template match ≅ db:para|db:simpara
Mode: m:docbook
Matches: db:para, db:simpara
Template match ≅ db:formalpara
Mode: m:docbook
Matches: db:formalpara
Template match ≅ db:blockquote|db:epigraph
Mode: m:docbook
Matches: db:blockquote, db:epigraph
Template match ≅ db:attribution
Mode: m:docbook
Matches: db:attribution
Template match ≅ db:revhistory
Calls: f:pi()
Mode: m:docbook
Matches: db:revhistory
Template match ≅ db:revision
Mode: m:revhistory-list
Matches: db:revision
Template match ≅ db:revision
Mode: m:revhistory-table
Matches: db:revision
Template match ≅ db:revdescription
Mode: m:docbook
Matches: db:revdescription
Template match ≅ db:revremark
Mode: m:docbook
Matches: db:revremark
Template match ≅ db:sidebar
Mode: m:docbook
Matches: db:sidebar
Template match ≅ db:qandaset
Mode: m:docbook
Matches: db:qandaset
Template match ≅ db:qandadiv
Mode: m:docbook
Matches: db:qandadiv
Template match ≅ db:qandaentry
Mode: m:docbook
Matches: db:qandaentry
Template match ≅ db:question
Mode: m:docbook
Matches: db:question
Template match ≅ db:answer
Mode: m:docbook
Matches: db:answer
Template match ≅ db:qandaset
Mode: m:toc
Matches: db:qandaset
Template match ≅ db:qandadiv
Mode: m:toc
Matches: db:qandadiv
Template match ≅ db:qandaentry
Calls: f:id()
Mode: m:toc
Matches: db:qandaentry
Template match ≅ db:question
Mode: m:toc
Matches: db:question
Template match ≅ db:label
Calls: t:inline
Mode: m:docbook
Matches: db:label
Template match ≅ db:remark
Mode: m:docbook
Matches: db:remark
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:db="http://docbook.org/ns/docbook"
                xmlns:f="http://docbook.org/ns/docbook/functions"
                xmlns:h="http://www.w3.org/1999/xhtml"
                xmlns:m="http://docbook.org/ns/docbook/modes"
                xmlns:map="http://www.w3.org/2005/xpath-functions/map"
                xmlns:math="http://www.w3.org/1998/Math/MathML"
                xmlns:t="http://docbook.org/ns/docbook/templates"
                xmlns:v="http://docbook.org/ns/docbook/variables"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns="http://www.w3.org/1999/xhtml"
                default-mode="m:docbook"
                exclude-result-prefixes="db f h m map math t v xs"
                version="3.0">

<xsl:template match="db:informalfigure|db:informalequation|db:informalexample">
  <div>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates/>
  </div>
</xsl:template>

<xsl:template match="db:formalgroup
                     |db:figure|db:equation|db:example|db:screenshot">
  <xsl:variable name="placement"
                select="if (map:get($v:formal-object-title-placement, local-name(.)))
                        then map:get($v:formal-object-title-placement, local-name(.))
                        else map:get($v:formal-object-title-placement, '_default')"/>
  <div>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:choose>
      <xsl:when test="$placement = 'before'">
        <xsl:apply-templates select="." mode="m:generate-titlepage"/>
        <xsl:apply-templates/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates/>
        <xsl:apply-templates select="." mode="m:generate-titlepage"/>
      </xsl:otherwise>
    </xsl:choose>
  </div>
</xsl:template>

<xsl:template match="math:*">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates select="node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="db:para|db:simpara">
  <p>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates/>
  </p>
</xsl:template>

<xsl:template match="db:formalpara">
  <p>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates select="." mode="m:generate-titlepage"/>
    <span class="para">
      <xsl:apply-templates select="db:para" mode="m:attributes"/>
      <xsl:apply-templates select="db:para/node()"/>
    </span>
  </p>
</xsl:template>

<xsl:template match="db:blockquote|db:epigraph">
  <blockquote>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates select="." mode="m:generate-titlepage"/>
    <xsl:apply-templates select="* except db:attribution"/>
    <xsl:apply-templates select="db:attribution"/>
  </blockquote>
</xsl:template>

<xsl:template match="db:attribution">
  <div>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates/>
  </div>
</xsl:template>

<xsl:template match="db:revhistory">
  <xsl:variable name="style"
                select="f:pi(., 'revhistory-style', $revhistory-style)"/>

  <div>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates select="." mode="m:generate-titlepage"/>
    <xsl:choose>
      <xsl:when test="$style = 'table'">
        <table>
          <colgroup>
            <col class="revnumber"/>
            <col class="date" style="text-align: right;"/>
            <col class="author"/>
            <col class="revremark"/>
          </colgroup>
          <tbody>
            <xsl:apply-templates select="db:revision" mode="m:revhistory-table"/>
          </tbody>
        </table>
      </xsl:when>
      <xsl:when test="$style = 'list'">
        <ul>
          <xsl:apply-templates select="db:revision" mode="m:revhistory-list"/>
        </ul>
      </xsl:when>
      <xsl:otherwise>
        <xsl:message select="'Uknown revhistory-style: ' || $style"/>
        <ul>
          <xsl:apply-templates select="db:revision" mode="m:revhistory-list"/>
        </ul>
      </xsl:otherwise>
    </xsl:choose>
  </div>
</xsl:template>

<xsl:template match="db:revision" mode="m:revhistory-list">
  <li>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:if test="db:revnumber">
      <xsl:apply-templates select="db:revnumber"/>
      <xsl:text>, </xsl:text>
    </xsl:if>
    <xsl:apply-templates select="db:date"/>
    <xsl:for-each select="db:author|db:authorinitials">
      <xsl:text>, </xsl:text>
      <xsl:apply-templates select="."/>
    </xsl:for-each>
    <xsl:apply-templates select="db:revdescription|db:revremark"/>
  </li>
</xsl:template>

<xsl:template match="db:revision" mode="m:revhistory-table">
  <tr>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <td>
      <xsl:apply-templates select="db:revnumber"/>
    </td>
    <td>
      <xsl:apply-templates select="db:date"/>
    </td>
    <td>
      <xsl:for-each select="db:author|db:authorinitials">
        <xsl:if test="position() gt 1">
          <xsl:text>, </xsl:text>
        </xsl:if>
        <xsl:apply-templates select="."/>
      </xsl:for-each>
    </td>
    <td>
      <xsl:apply-templates select="db:revdescription|db:revremark"/>
    </td>
  </tr>
</xsl:template>

<xsl:template match="db:revdescription">
  <div>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates/>
  </div>
</xsl:template>

<xsl:template match="db:revremark">
  <p>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates/>
  </p>
</xsl:template>

<!-- ============================================================ -->

<xsl:template match="db:sidebar">
  <xsl:element name="{if ($sidebar-as-aside) then 'aside' else 'div'}"
               namespace="http://docbook.org/ns/docbook">
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates select="." mode="m:generate-titlepage"/>
    <xsl:apply-templates/>
  </xsl:element>
</xsl:template>

<!-- ============================================================ -->

<xsl:template match="db:qandaset">
  <xsl:variable name="pis"
                select="f:pi-attributes(processing-instruction('db'))"/>
  <div>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates select="." mode="m:generate-titlepage"/>

    <xsl:if test="(exists($pis/@toc) and f:is-true($pis/@toc))
                   or (not($pis/@toc) and f:is-true($qandaset-default-toc))">
      <xsl:apply-templates select="." mode="m:toc"/>
    </xsl:if>

    <xsl:choose>
      <xsl:when test="db:qandadiv">
        <xsl:apply-templates/>
      </xsl:when>
      <xsl:otherwise>
        <div class="qandalist">
          <xsl:apply-templates/>
        </div>
      </xsl:otherwise>
    </xsl:choose>
  </div>
</xsl:template>

<xsl:template match="db:qandadiv">
  <div>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates select="." mode="m:generate-titlepage"/>
    <xsl:choose>
      <xsl:when test="db:qandadiv">
        <xsl:apply-templates/>
      </xsl:when>
      <xsl:otherwise>
        <div class="qandalist">
          <xsl:apply-templates/>
        </div>
      </xsl:otherwise>
    </xsl:choose>
  </div>
</xsl:template>

<xsl:template match="db:qandaentry">
  <div>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <xsl:apply-templates select="." mode="m:generate-titlepage"/>
    <div class="qanda">
      <xsl:apply-templates/>
    </div>
  </div>
</xsl:template>

<xsl:template match="db:question">
  <div>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <div class="label">
      <xsl:apply-templates select="." mode="m:headline-label"/>
    </div>
    <div class="body">
      <xsl:apply-templates select="node() except db:label"/>
    </div>
  </div>
</xsl:template>

<xsl:template match="db:answer">
  <div>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <div class="label">
      <xsl:apply-templates select="." mode="m:headline-label"/>
    </div>
    <div class="body">
      <xsl:apply-templates select="node() except db:label"/>
    </div>
  </div>
</xsl:template>

<xsl:template match="db:qandaset" mode="m:toc">
  <ul class="toc">
    <xsl:apply-templates select="db:qandadiv|db:qandaentry" mode="m:toc"/>
  </ul>
</xsl:template>

<xsl:template match="db:qandadiv" mode="m:toc">
  <li>
    <a href="#{f:id(.)}">
      <xsl:apply-templates select="." mode="m:headline">
        <xsl:with-param name="purpose" select="'lot'"/>
      </xsl:apply-templates>
    </a>

    <xsl:variable name="toc" select="f:pi(., 'toc')"/>

    <xsl:if test="($toc and f:is-true($toc))
                   or (empty($toc) and f:is-true($qandadiv-default-toc))">
      <ul>
        <xsl:apply-templates select="db:qandadiv|db:qandaentry" mode="m:toc"/>
      </ul>
    </xsl:if>
  </li>
</xsl:template>

<xsl:template match="db:qandaentry" mode="m:toc">
  <li>
    <a href="#{f:id(.)}">
      <xsl:apply-templates select="db:question" mode="m:headline">
        <xsl:with-param name="purpose" select="'lot'"/>
      </xsl:apply-templates>
    </a>
  </li>
</xsl:template>

<xsl:template match="db:question" mode="m:toc">
  <xsl:choose>
    <xsl:when test="(* except db:label)[1]/self::db:para">
      <xsl:apply-templates select="(* except db:label)[1]/node()"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:message select="'No question title for ' || local-name(*[1])"/>
      <xsl:variable name="question" as="node()">
        <xsl:apply-templates select="."/>
      </xsl:variable>
      <xsl:variable name="question" select="string($question)"/>
      <xsl:sequence select="$question"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="db:label">
  <xsl:call-template name="t:inline"/>
</xsl:template>

<xsl:template match="db:remark">
  <xsl:if test="f:is-true($show-remarks)">
    <xsl:choose>
      <xsl:when test="ancestor::db:para">
        <!-- Assume it's an inline; this is not a foolproof test! -->
        <span>
          <xsl:apply-templates select="." mode="m:attributes"/>
          <xsl:apply-templates/>
        </span>
      </xsl:when>
      <xsl:otherwise>
        <div>
          <xsl:apply-templates select="." mode="m:attributes"/>
          <xsl:apply-templates/>
        </div>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:if>
</xsl:template>

</xsl:stylesheet>

admonitions.xsl

1 template

Instructions
Template match ≅ db:caution|db:danger|db:import…
Mode: m:docbook
Matches: db:caution, db:danger, db:important, db:note, db:tip, db:warning
Source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:db="http://docbook.org/ns/docbook"
                xmlns:f="http://docbook.org/ns/docbook/functions"
                xmlns:m="http://docbook.org/ns/docbook/modes"
                xmlns:t="http://docbook.org/ns/docbook/templates"
                xmlns:v="http://docbook.org/ns/docbook/variables"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns="http://www.w3.org/1999/xhtml"
                default-mode="m:docbook"
                exclude-result-prefixes="db f m t v xs"
                version="3.0">

<xsl:template match="db:note|db:tip|db:important|db:caution|db:warning|db:danger">
  <div>
    <xsl:apply-templates select="." mode="m:attributes"/>
    <div>
      <div class="icon">
        <xsl:apply-templates
            select="$v:admonition-icons/*[node-name(.) = node-name(current())]/node()"/>
      </div>
      <div class="body">
        <xsl:apply-templates select="." mode="m:generate-titlepage"/>
        <div>
          <xsl:apply-templates/>
        </div>
      </div>
    </div>
  </div>
</xsl:template>

</xsl:stylesheet>

programming.xsl

101 templates

Instructions
Template match ≅ db:productionset
Mode: m:docbook
Matches: db:productionset
Template match ≅ db:production
Mode: m:docbook
Matches: db:production
Template match ≅ db:productionrecap
Mode: m:docbook
Matches: db:productionrecap
Template match ≅ db:lhs
Mode: m:docbook
Matches: db:lhs
Template match ≅ db:production
Mode: m:production-number
Matches: db:production
Template match ≅ db:rhs
Mode: m:docbook
Priority: 10
Matches: db:rhs
Template match ≅ db:rhs
Mode: m:docbook
Matches: db:rhs
Template match ≅ db:constraint
Mode: m:docbook
Matches: db:constraint
Template match ≅ db:lineannotation
Mode: m:docbook
Matches: db:lineannotation
Template match ≅ db:sbr
Mode: m:docbook
Matches: db:sbr
Template match ≅ db:nonterminal
Mode: m:docbook
Matches: db:nonterminal
Template match ≅ db:constraintdef
Mode: m:docbook
Matches: db:constraintdef
Template match ≅ db:funcsynopsis
Calls: f:pi()
Mode: m:docbook
Matches: db:funcsynopsis
Template match ≅ element()
Mode: m:kr
Matches: element()
Template match ≅ db:funcsynopsisinfo
Mode: m:kr
Matches: db:funcsynopsisinfo
Template match ≅ db:funcprototype
Mode: m:kr
Matches: db:funcprototype
Template match ≅ db:funcdef
Mode: m:kr
Matches: db:funcdef
Template match ≅ db:type
Mode: m:kr
Matches: db:type
Template match ≅ db:function
Mode: m:kr
Matches: db:function
Template match ≅ db:void
Mode: m:kr-args
Matches: db:void
Template match ≅ db:varargs
Mode: m:kr-args
Matches: db:varargs
Template match ≅ db:paramdef
Mode: m:kr-args
Matches: db:paramdef
Template match ≅ db:parameter
Mode: m:kr-args
Matches: db:parameter
Template match ≅ db:void
Mode: m:kr
Matches: db:void
Template match ≅ db:varargs
Mode: m:kr
Matches: db:varargs
Template match ≅ db:paramdef
Mode: m:kr
Matches: db:paramdef
Template match ≅ db:parameter
Mode: m:kr
Matches: db:parameter
Template match ≅ db:funcparams
Mode: m:kr
Matches: db:funcparams
Template match ≅ text()
Mode: m:kr
Matches: text()
Template match ≅ comment()|processing-instructi…
Mode: m:kr
Matches: comment(), processing-instruction()
Template match ≅ attribute()
Mode: m:kr
Matches: attribute()
Template match ≅ text()
Mode: m:kr-args
Matches: text()
Template match ≅ comment()|processing-instructi…
Mode: m:kr-args
Matches: comment(), processing-instruction()
Template match ≅ attribute()
Mode: m:kr-args
Matches: attribute()
Template match ≅ element()
Mode: m:kr-table
Matches: element()
Template match ≅ db:funcsynopsisinfo
Mode: m:kr-table
Matches: db:funcsynopsisinfo
Template match ≅ db:funcprototype
Mode: m:kr-table
Matches: db:funcprototype
Template match ≅ db:funcdef
Mode: m:kr-table
Matches: db:funcdef
Template match ≅ db:type
Mode: m:kr-table
Matches: db:type
Template match ≅ db:function
Mode: m:kr-table
Matches: db:function
Template match ≅ db:void
Mode: m:kr-table-args
Matches: db:void
Template match ≅ db:varargs
Mode: m:kr-table-args
Matches: db:varargs
Template match ≅ db:parameter
Mode: m:kr-table-args
Matches: db:parameter
Template match ≅ db:void
Mode: m:kr-table
Matches: db:void
Template match ≅ db:varargs
Mode: m:kr-table
Matches: db:varargs
Template match ≅ db:paramdef
Mode: m:kr-table-args
Matches: db:paramdef
Template match ≅ db:paramdef
Mode: m:kr-table
Matches: db:paramdef
Template match ≅ db:parameter
Mode: m:kr-table
Matches: db:parameter
Template match ≅ db:funcparams
Mode: m:kr-table
Matches: db:funcparams
Template match ≅ text()
Mode: m:kr-table
Matches: text()
Template match ≅ comment()|processing-instructi…
Mode: m:kr-table
Matches: comment(), processing-instruction()
Template match ≅ attribute()
Mode: m:kr-table
Matches: attribute()
Template match ≅ text()
Mode: m:kr-table-args
Matches: text()
Template match ≅ comment()|processing-instructi…
Mode: m:kr-table-args
Matches: comment(), processing-instruction()
Template match ≅ attribute()|text()
Mode: m:kr-table-args
Matches: attribute(), text()
Template match ≅ element()
Mode: m:ansi
Matches: element()
Template match ≅ db:funcsynopsisinfo
Mode: m:ansi
Matches: db:funcsynopsisinfo
Template match ≅ db:funcprototype
Mode: m:ansi
Matches: db:funcprototype
Template match ≅ db:funcdef
Mode: m:ansi
Matches: db:funcdef
Template match ≅ db:type
Mode: m:ansi
Matches: db:type
Template match ≅ db:function
Mode: m:ansi
Matches: db:function
Template match ≅ db:void
Mode: m:ansi
Matches: db:void
Template match ≅ db:varargs
Mode: m:ansi
Matches: db:varargs
Template match ≅ db:paramdef
Mode: m:ansi
Matches: db:paramdef
Template match ≅ db:parameter
Mode: m:ansi
Matches: db:parameter
Template match ≅ db:funcparams
Mode: m:ansi
Matches: db:funcparams
Template match ≅ text()
Mode: m:ansi
Matches: text()
Template match ≅ comment()|processing-instructi…
Mode: m:ansi
Matches: comment(), processing-instruction()
Template match ≅ attribute()
Mode: m:ansi
Matches: attribute()
Template match ≅ element()
Mode: m:ansi-table
Matches: element()
Template match ≅ db:funcsynopsisinfo
Mode: m:ansi-table
Matches: db:funcsynopsisinfo
Template match ≅ db:funcprototype
Mode: m:ansi-table
Matches: db:funcprototype
Template match ≅ db:funcdef
Mode: m:ansi-table
Matches: db:funcdef
Template match ≅ db:type
Mode: m:ansi-table
Matches: db:type
Template match ≅ db:function
Mode: m:ansi-table
Matches: db:function
Template match ≅ db:void
Mode: m:ansi-table
Matches: db:void
Template match ≅ db:varargs
Mode: m:ansi-table
Matches: db:varargs
Template match ≅ db:paramdef
Mode: m:ansi-table
Matches: db:paramdef
Template match ≅ db:parameter
Mode: m:ansi-table
Matches: db:parameter
Template match ≅ db:funcparams
Mode: m:ansi-table
Matches: db:funcparams
Template match ≅ text()
Mode: m:ansi-table
Matches: text()
Template match ≅ comment()|processing-instructi…
Mode: m:ansi-table
Matches: comment(), processing-instruction()
Template match ≅ attribute()
Mode: m:ansi-table
Matches: attribute()
Template match ≅ db:classsynopsis|db:constructo…
Mode: m:docbook
Priority: 100
Matches: db:classsynopsis, db:constructorsynopsis, db:destructorsynopsis, db:fieldsynopsis, db:methodsynopsis
Template match ≅ db:classsynopsis
Mode: m:docbook
Matches: db:classsynopsis
Template match ≅ db:fieldsynopsis
Mode: m:docbook
Matches: db:fieldsynopsis
Template match ≅ db:fieldsynopsis
Mode: m:synopsis
Matches: db:fieldsynopsis
Template match ≅ db:varname
Mode: m:synopsis
Matches: db:varname
Template match ≅ db:initializer
Mode: m:synopsis
Matches: db:initializer
Template match ≅ db:constructorsynopsis|db:dest…
Mode: m:docbook
Matches: db:constructorsynopsis, db:destructorsynopsis, db:methodsynopsis
Template match ≅ db:constructorsynopsis|db:dest…
Calls: f:spaces()
Mode: m:synopsis
Matches: db:constructorsynopsis, db:destructorsynopsis, db:methodsynopsis
Template match ≅ db:methodparam
Mode: m:synopsis
Matches: db:methodparam
Template match ≅ db:modifier|db:type
Mode: m:synopsis
Matches: db:modifier, db:type
Template match ≅ db:classname|db:methodname|db:…
Mode: m:synopsis
Matches: db:classname, db:methodname, db:parameter
Template match ≅ db:cmdsynopsis
Mode: m:docbook
Matches: db:cmdsynopsis
Template match ≅ db:synopfragment
Mode: m:docbook
Matches: db:synopfragment
Template match ≅ db:synopfragmentref
Mode: m:docbook
Matches: db:synopfragmentref
Template match ≅ db:synopfragment
Mode: m:synopfragment-bug
Matches: db:synopfragment
Template match ≅ db:cmdsynopsis/db:command
Mode: m:docbook
Matches: db:cmdsynopsis/db:command