chiark / gitweb /
108493cd6cd7d3d945b71c547fb578e054d15c7d
[elogind.git] / man / custom-html.xsl
1 <?xml version='1.0'?> <!--*-nxml-*-->
2
3 <!--
4   SPDX-License-Identifier: LGPL-2.1+
5
6   Copyright 2011 Lennart Poettering
7 -->
8
9 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
10
11 <xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl"/>
12 <!--
13   - The docbook stylesheet injects empty anchor tags into generated HTML, identified by an auto-generated ID.
14   - Ask the docbook stylesheet to generate reproducible output when generating (these) ID values.
15   - This makes the output of this stylesheet reproducible across identical invocations on the same input,
16   - which is an easy and significant win for achieving reproducible builds.
17   -
18   - It may be even better to strip the empty anchors from the document output in addition to turning on consistent IDs,
19   - for this stylesheet contains its own custom ID logic (for generating permalinks) already.
20  -->
21 <xsl:param name="generate.consistent.ids" select="1"/>
22
23 <!-- translate man page references to links to html pages -->
24 <xsl:template match="citerefentry[not(@project)]">
25   <a>
26     <xsl:attribute name="href">
27       <xsl:value-of select="refentrytitle"/><xsl:text>.html#</xsl:text>
28       <xsl:value-of select="refentrytitle/@target"/>
29     </xsl:attribute>
30     <xsl:call-template name="inline.charseq"/>
31   </a>
32 </xsl:template>
33
34 <xsl:template match="citerefentry[@project='man-pages'] | citerefentry[manvolnum='2'] | citerefentry[manvolnum='4']">
35   <a>
36     <xsl:attribute name="href">
37       <xsl:text>http://man7.org/linux/man-pages/man</xsl:text>
38       <xsl:value-of select="manvolnum"/>
39       <xsl:text>/</xsl:text>
40       <xsl:value-of select="refentrytitle"/>
41       <xsl:text>.</xsl:text>
42       <xsl:value-of select="manvolnum"/>
43       <xsl:text>.html</xsl:text>
44     </xsl:attribute>
45     <xsl:call-template name="inline.charseq"/>
46   </a>
47 </xsl:template>
48
49 <xsl:template match="citerefentry[@project='die-net']">
50   <a>
51     <xsl:attribute name="href">
52       <xsl:text>http://linux.die.net/man/</xsl:text>
53       <xsl:value-of select="manvolnum"/>
54       <xsl:text>/</xsl:text>
55       <xsl:value-of select="refentrytitle"/>
56     </xsl:attribute>
57     <xsl:call-template name="inline.charseq"/>
58   </a>
59 </xsl:template>
60
61 <xsl:template match="citerefentry[@project='wireguard']">
62   <a>
63     <xsl:attribute name="href">
64       <xsl:text>https://git.zx2c4.com/WireGuard/about/src/tools/</xsl:text>
65       <xsl:value-of select="refentrytitle"/>
66       <xsl:text>.</xsl:text>
67       <xsl:value-of select="manvolnum"/>
68     </xsl:attribute>
69     <xsl:call-template name="inline.charseq"/>
70   </a>
71 </xsl:template>
72
73 <xsl:template match="citerefentry[@project='mankier']">
74   <a>
75     <xsl:attribute name="href">
76       <xsl:text>https://www.mankier.com/</xsl:text>
77       <xsl:value-of select="manvolnum"/>
78       <xsl:text>/</xsl:text>
79       <xsl:value-of select="refentrytitle"/>
80     </xsl:attribute>
81     <xsl:call-template name="inline.charseq"/>
82   </a>
83 </xsl:template>
84
85 <xsl:template match="citerefentry[@project='archlinux']">
86   <a>
87     <xsl:attribute name="href">
88       <xsl:text>https://www.archlinux.org/</xsl:text>
89       <xsl:value-of select="refentrytitle"/>
90       <xsl:text>/</xsl:text>
91       <xsl:value-of select="refentrytitle"/>
92       <xsl:text>.</xsl:text>
93       <xsl:value-of select="manvolnum"/>
94       <xsl:text>.html</xsl:text>
95     </xsl:attribute>
96     <xsl:call-template name="inline.charseq"/>
97   </a>
98 </xsl:template>
99
100 <xsl:template match="citerefentry[@project='freebsd']">
101   <a>
102     <xsl:attribute name="href">
103       <xsl:text>https://www.freebsd.org/cgi/man.cgi?</xsl:text>
104       <xsl:value-of select="refentrytitle"/>
105       <xsl:text>(</xsl:text>
106       <xsl:value-of select="manvolnum"/>
107       <xsl:text>)</xsl:text>
108     </xsl:attribute>
109     <xsl:call-template name="inline.charseq"/>
110   </a>
111 </xsl:template>
112
113 <xsl:template match="citerefentry[@project='dbus']">
114   <a>
115     <xsl:attribute name="href">
116       <xsl:text>http://dbus.freedesktop.org/doc/</xsl:text>
117       <xsl:value-of select="refentrytitle"/>
118       <xsl:text>.</xsl:text>
119       <xsl:value-of select="manvolnum"/>
120       <xsl:text>.html</xsl:text>
121     </xsl:attribute>
122     <xsl:call-template name="inline.charseq"/>
123   </a>
124 </xsl:template>
125
126 <!--
127   - helper template to do conflict resolution between various headings with the same inferred ID attribute/tag from the headerlink template
128   - this conflict resolution is necessary to prevent malformed HTML output (multiple ID attributes with the same value)
129   - and it fixes xsltproc warnings during compilation of HTML man pages
130   -
131   - A simple top-to-bottom numbering scheme is implemented for nodes with the same ID value to derive unique ID values for HTML output.
132   - It uses two parameters:
133       templateID  the proposed ID string to use which must be checked for conflicts
134       keyNode     the context node which 'produced' the given templateID.
135   -
136   - Conflicts are detected solely based on keyNode, templateID is not taken into account for that purpose.
137  -->
138 <xsl:template name="generateID">
139   <!-- node which generatedID needs to assume as the 'source' of the ID -->
140   <xsl:param name="keyNode"/>
141   <!-- suggested value for generatedID output, a contextually meaningful ID string -->
142   <xsl:param name="templateID"/>
143   <xsl:variable name="conflictSource" select="preceding::refsect1/title|preceding::refsect1/info/title|
144                                               preceding::refsect2/title|preceding::refsect2/info/title|
145                                               preceding::varlistentry/term[1]"/>
146   <xsl:variable name="conflictCount" select="count($conflictSource[. = $keyNode])"/>
147   <xsl:choose>
148     <!-- special case conflictCount = 0 to preserve compatibility with URLs generated by previous versions of this XSL stylesheet where possible -->
149     <xsl:when test="$conflictCount = 0">
150       <xsl:value-of select="$templateID"/>
151     </xsl:when>
152     <xsl:otherwise>
153       <xsl:value-of select="concat($templateID, $conflictCount)"/>
154     </xsl:otherwise>
155   </xsl:choose>
156 </xsl:template>
157
158 <!--
159   - a helper template to abstract over the structure of generated subheading + permalink HTML output
160   - It helps reduce tedious repetition and groups all actual markup output (as opposed to URL/ID logic) in a single location.
161  -->
162 <xsl:template name="permalink">
163   <xsl:param name="nodeType"/> <!-- local name of the element node to generate, e.g. 'h2' for <h2></h2> -->
164   <xsl:param name="nodeContent"/> <!-- nodeset to apply further templates to obtain the content of the subheading/term -->
165   <xsl:param name="linkTitle"/> <!-- value for title attribute of generated permalink, e.g. 'this is a permalink' -->
166
167   <!-- parameters passed to generateID template, otherwise unused. -->
168   <xsl:param name="keyNode"/>
169   <xsl:param name="templateID"/>
170
171   <!--
172     - If stable URLs with fragment markers (references to the ID) turn out not to be important:
173     - generatedID could simply take the value of generate-id(), and various other helper templates may be dropped entirely.
174     - Alternatively, if xsltproc is patched to generate reproducible generate-id() output, the same simplifications can be
175     - applied at the cost of breaking compatibility with URLs generated from output of previous versions of this stylesheet.
176    -->
177   <xsl:variable name="generatedID">
178     <xsl:call-template name="generateID">
179       <xsl:with-param name="keyNode" select="$keyNode"/>
180       <xsl:with-param name="templateID" select="$templateID"/>
181     </xsl:call-template>
182   </xsl:variable>
183
184   <xsl:element name="{$nodeType}">
185     <xsl:attribute name="id">
186       <xsl:value-of select="$generatedID"/>
187     </xsl:attribute>
188     <xsl:apply-templates select="$nodeContent"/>
189     <a class="headerlink" title="{$linkTitle}" href="#{$generatedID}">¶</a>
190   </xsl:element>
191 </xsl:template>
192
193 <!-- simple wrapper around permalink to avoid repeating common info for each level of subheading covered by the permalink logic (h2, h3) -->
194 <xsl:template name="headerlink">
195   <xsl:param name="nodeType"/>
196   <xsl:call-template name="permalink">
197     <xsl:with-param name="nodeType" select="$nodeType"/>
198     <xsl:with-param name="linkTitle" select="'Permalink to this headline'"/>
199     <xsl:with-param name="nodeContent" select="node()"/>
200     <xsl:with-param name="keyNode" select="."/>
201     <!--
202       - To retain compatibility with IDs generated by previous versions of the template, inline.charseq must be called.
203       - The purpose of that template is to generate markup (according to docbook documentation its purpose is to mark/format something as plain text).
204       - The only reason to call this template is to get the auto-generated text such as brackets ([]) before flattening it.
205      -->
206     <xsl:with-param name="templateID">
207       <xsl:call-template name="inline.charseq"/>
208     </xsl:with-param>
209   </xsl:call-template>
210 </xsl:template>
211
212 <xsl:template match="refsect1/title|refsect1/info/title">
213   <!-- the ID is output in the block.object call for refsect1 -->
214   <xsl:call-template name="headerlink">
215     <xsl:with-param name="nodeType" select="'h2'"/>
216   </xsl:call-template>
217 </xsl:template>
218
219 <xsl:template match="refsect2/title|refsect2/info/title">
220   <xsl:call-template name="headerlink">
221     <xsl:with-param name="nodeType" select="'h3'"/>
222   </xsl:call-template>
223 </xsl:template>
224
225 <xsl:template match="varlistentry">
226   <xsl:call-template name="permalink">
227     <xsl:with-param name="nodeType" select="'dt'"/>
228     <xsl:with-param name="linkTitle" select="'Permalink to this term'"/>
229     <xsl:with-param name="nodeContent" select="term"/>
230     <xsl:with-param name="keyNode" select="term[1]"/>
231     <!--
232       - To retain compatibility with IDs generated by previous versions of the template, inline.charseq must be called.
233       - The purpose of that template is to generate markup (according to docbook documentation its purpose is to mark/format something as plain text).
234       - The only reason to call this template is to get the auto-generated text such as brackets ([]) before flattening it.
235      -->
236     <xsl:with-param name="templateID">
237       <xsl:call-template name="inline.charseq">
238         <xsl:with-param name="content" select="term[1]"/>
239       </xsl:call-template>
240     </xsl:with-param>
241   </xsl:call-template>
242   <dd>
243     <xsl:apply-templates select="listitem"/>
244   </dd>
245 </xsl:template>
246
247
248 <!-- add Index link at top of page -->
249 <xsl:template name="user.header.content">
250   <style>
251     a.headerlink {
252       color: #c60f0f;
253       font-size: 0.8em;
254       padding: 0 4px 0 4px;
255       text-decoration: none;
256       visibility: hidden;
257     }
258
259     a.headerlink:hover {
260       background-color: #c60f0f;
261       color: white;
262     }
263
264     h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, dt:hover > a.headerlink {
265       visibility: visible;
266     }
267   </style>
268
269   <a>
270     <xsl:attribute name="href">
271       <xsl:text>index.html</xsl:text>
272     </xsl:attribute>
273     <xsl:text>Index </xsl:text>
274   </a>·
275   <a>
276     <xsl:attribute name="href">
277       <xsl:text>elogind.directives.html</xsl:text>
278     </xsl:attribute>
279     <xsl:text>Directives </xsl:text>
280   </a>
281
282   <span style="float:right">
283     <xsl:text>elogind </xsl:text>
284     <xsl:value-of select="$elogind.version"/>
285   </span>
286   <hr/>
287 </xsl:template>
288
289 <xsl:template match="literal">
290   <xsl:text>"</xsl:text>
291   <xsl:call-template name="inline.monoseq"/>
292   <xsl:text>"</xsl:text>
293 </xsl:template>
294
295 <!-- Switch things to UTF-8, ISO-8859-1 is soo yesteryear -->
296 <xsl:output method="html" encoding="UTF-8" indent="no"/>
297
298 </xsl:stylesheet>