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