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