1<?xml version="1.0" encoding="utf-8"?> 2<!-- 3 - DokuWiki xslfo plugin: Export single pages to PDF via XSL-FO. 4 - 5 - @license GPL 3 (http://www.gnu.org/licenses/gpl.html) 6 - @author Sam Wilson <sam@samwilson.id.au> 7 --> 8<xsl:stylesheet version="1.0" 9 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 10 xmlns:fo="http://www.w3.org/1999/XSL/Format"> 11 <xsl:variable name="tplincdir" select="document/dokuwiki/tplincdir/text()" /> 12 <xsl:variable name="mediadir" select="document/dokuwiki/mediadir/text()" /> 13 14 <xsl:template match="/"> 15 <fo:root> 16 17 <fo:layout-master-set> 18 <fo:simple-page-master master-name="A4-portrait" page-height="29.7cm" page-width="21.0cm" margin="2cm"> 19 <fo:region-body margin-top="1.5cm" margin-bottom="1.5cm"/> 20 <fo:region-before extent="2.0cm"/> 21 <fo:region-after extent="2.0cm"/> 22 </fo:simple-page-master> 23 </fo:layout-master-set> 24 25 <fo:page-sequence master-reference="A4-portrait"> 26 27 <fo:static-content flow-name="xsl-region-before"> 28 <fo:block> 29 <xsl:call-template name="header"/> 30 </fo:block> 31 </fo:static-content> 32 33 <fo:static-content flow-name="xsl-region-after"> 34 <fo:block> 35 <xsl:call-template name="footer"/> 36 </fo:block> 37 </fo:static-content> 38 39 <xsl:apply-templates select="document" /> 40 41 </fo:page-sequence> 42 43 </fo:root> 44 </xsl:template> 45 46 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> 47 <!-- Begin header and footer --> 48 <xsl:template name="header"> 49 <fo:block font-size="8pt" border-bottom="thin solid black"> 50 <fo:block-container position="absolute"> 51 <fo:block text-align="left"> 52 <xsl:value-of select="//header[@level='1']" /> 53 </fo:block> 54 </fo:block-container> 55 <fo:block text-align="center"> 56 57 </fo:block> 58 <fo:block-container position="absolute"> 59 <fo:block text-align="right"> 60 <xsl:value-of select="//dokuwiki/lastmod/text()" /> 61 </fo:block> 62 </fo:block-container> 63 </fo:block> 64 </xsl:template> 65 <xsl:template name="footer"> 66 <fo:block font-size="8pt" border-top="thin solid black" text-align="center"> 67 <fo:table table-layout="fixed"> 68 <fo:table-body> 69 <fo:table-row> 70 <fo:table-cell> 71 <fo:block text-align="left"> 72 <xsl:value-of select="//dokuwiki/url/text()" /> 73 </fo:block> 74 </fo:table-cell> 75 <fo:table-cell> 76 <fo:block text-align="right"> 77 Page <fo:page-number/> of <fo:page-number-citation ref-id="document-end" /> 78 </fo:block> 79 </fo:table-cell> 80 </fo:table-row> 81 </fo:table-body> 82 </fo:table> 83 </fo:block> 84 </xsl:template> 85 <!-- End header and footer --> 86 87 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> 88 <!-- Document and sections --> 89 <xsl:template match="document"> 90 <fo:flow flow-name="xsl-region-body"> 91 <xsl:apply-templates /> 92 <!-- End ID for total-page-count reference in header --> 93 <fo:block id="document-end"></fo:block> 94 </fo:flow> 95 </xsl:template> 96 97 <xsl:template match="section"> 98 <fo:block> 99 <xsl:apply-templates /> 100 </fo:block> 101 </xsl:template> 102 103 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> 104 <!-- Headings --> 105 <xsl:template match="header[@level='1']"> 106 <fo:block font-size="20pt" line-height="15pt" space-before="15pt" space-after="12pt" text-align="center"> 107 <xsl:apply-templates /> 108 </fo:block> 109 </xsl:template> 110 <xsl:template match="header[@level='2']"> 111 <fo:block font-size="17pt" line-height="15pt" space-before="15pt" space-after="12pt"> 112 <xsl:apply-templates /> 113 </fo:block> 114 </xsl:template> 115 <xsl:template match="header[@level='3']"> 116 <fo:block font-size="12pt" space-before="15pt" space-after="5pt"> 117 <xsl:apply-templates /> 118 </fo:block> 119 </xsl:template> 120 121 <!-- Paragraphs --> 122 <xsl:template match="p"> 123 <fo:block font-size="10pt" space-after="12pt"> 124 <xsl:apply-templates /> 125 </fo:block> 126 </xsl:template> 127 128 <!-- Inline elements: strong, emphasis, monospace, underline --> 129 <xsl:template match="strong"> 130 <fo:inline font-weight="bold"> 131 <xsl:apply-templates /> 132 </fo:inline> 133 </xsl:template> 134 135 <xsl:template match="monospace"> 136 <fo:inline font-family="monospace"> 137 <xsl:apply-templates /> 138 </fo:inline> 139 </xsl:template> 140 141 <xsl:template match="emphasis"> 142 <fo:inline font-style="italic"> 143 <xsl:apply-templates /> 144 </fo:inline> 145 </xsl:template> 146 147 <xsl:template match="underline"> 148 <fo:inline text-decoration="underline"> 149 <xsl:apply-templates /> 150 </fo:inline> 151 </xsl:template> 152 153 <xsl:template match="multiplyentity"> 154 <fo:inline> 155 <xsl:value-of select="./x" /> 156 <xsl:text>×</xsl:text> 157 <xsl:value-of select="./y" /> 158 </fo:inline> 159 </xsl:template> 160 161 <xsl:template match="preformatted|code"> 162 <fo:block font-family="monospace" font-size="9pt" space-after="12pt" 163 white-space-collapse="false" wrap-option="no-wrap" padding="3pt" 164 linefeed-treatment="preserve" white-space-treatment="preserve"> 165 <xsl:apply-templates /> 166 </fo:block> 167 </xsl:template> 168 <xsl:template match="code"> 169 <fo:block font-family="monospace" font-size="9pt" space-after="12pt" padding="3pt" 170 white-space-collapse="false" wrap-option="no-wrap" background-color="#efefef" 171 linefeed-treatment="preserve" white-space-treatment="preserve"> 172 <xsl:apply-templates /> 173 </fo:block> 174 </xsl:template> 175 <xsl:template match="file"> 176 <fo:block font-family="monospace" font-size="9pt" space-after="12pt" 177 white-space-collapse="false" wrap-option="no-wrap" padding="3pt" 178 linefeed-treatment="preserve" white-space-treatment="preserve" border="thin solid black"> 179 <xsl:apply-templates /> 180 </fo:block> 181 </xsl:template> 182 183 <xsl:template match="subscript"> 184 <fo:inline vertical-align="sub" font-size="75%"> 185 <xsl:apply-templates /> 186 </fo:inline> 187 </xsl:template> 188 189 <xsl:template match="superscript"> 190 <fo:inline vertical-align="super" font-size="75%"> 191 <xsl:apply-templates /> 192 </fo:inline> 193 </xsl:template> 194 195 <xsl:template match="delete"> 196 <fo:inline text-decoration="line-through"> 197 <xsl:apply-templates /> 198 </fo:inline> 199 </xsl:template> 200 201 <xsl:template match="linebreak"> 202 <fo:block></fo:block> 203 </xsl:template> 204 205 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> 206 <!-- Links --> 207 <xsl:template match="link"> 208 <fo:basic-link color="blue"> 209 <xsl:choose> 210 <xsl:when test="starts-with(@href, '#')"> 211 <xsl:attribute name="internal-destination"> 212 <xsl:value-of select="substring(@href, 2)"/> 213 </xsl:attribute> 214 </xsl:when> 215 <xsl:otherwise> 216 <xsl:attribute name="external-destination"> 217 <xsl:value-of select="@href"/> 218 </xsl:attribute> 219 </xsl:otherwise> 220 </xsl:choose> 221 <xsl:apply-templates /> 222 </fo:basic-link> 223 </xsl:template> 224 225 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> 226 <!-- Images and other attachments --> 227 <xsl:template match="media"> 228 <xsl:variable name="src" select="@src" /> 229 <xsl:variable name="ext" select="@ext" /> 230 <xsl:variable name="width" select="@width" /> 231 <xsl:variable name="height" select="@height" /> 232 <xsl:variable name="filename"> 233 <xsl:value-of select="//dokuwiki/media_filename[@src=$src and @width=$width and @height=$height]/text()" /> 234 </xsl:variable> 235 <fo:inline> 236 <fo:basic-link color="blue"> 237 <xsl:attribute name="external-destination"> 238 <xsl:value-of select="@href"/> 239 </xsl:attribute> 240 <xsl:choose> 241 <xsl:when test="(@ext!='jpg' and @ext!='gif') or @linking = 'linkonly'"> 242 <fo:external-graphic content-width="1em" src="url('{$tplincdir}../../images/fileicons/{$ext}.png')" /> 243 <xsl:apply-templates /> 244 </xsl:when> 245 <xsl:otherwise> 246 <fo:external-graphic src="url({$filename})" /> 247 </xsl:otherwise> 248 </xsl:choose> 249 <xsl:choose> 250 <xsl:when test="(@ext!='jpg' and @ext!='gif' and not(normalize-space(.))) or @linking = 'linkonly'"> 251 <xsl:value-of select="@basename" /> 252 </xsl:when> 253 </xsl:choose> 254 </fo:basic-link> 255 </fo:inline> 256 </xsl:template> 257 258 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> 259 <!-- Lists --> 260 <xsl:template match="listu|listo"> 261 <fo:list-block provisional-distance-between-starts="0.5cm" provisional-label-separation="0.2cm" font-size="10pt"> 262 <xsl:attribute name="start-indent"> 263 <xsl:variable name="ancestors"> 264 <xsl:choose> 265 <xsl:when test="count(ancestor::listo) or count(ancestor::listu)"> 266 <xsl:value-of select="count(ancestor::listo) + count(ancestor::listu)"/> 267 </xsl:when> 268 <xsl:otherwise> 269 <xsl:text>0</xsl:text> 270 </xsl:otherwise> 271 </xsl:choose> 272 </xsl:variable> 273 <xsl:value-of select="concat((0.5+($ancestors*0.5)), 'cm')"/> 274 </xsl:attribute> 275 <xsl:apply-templates /> 276 </fo:list-block> 277 </xsl:template> 278 279 <xsl:template match="listu/listitem"> 280 <fo:list-item> 281 <fo:list-item-label end-indent="label-end()"> 282 <fo:block> 283 <xsl:choose> 284 <xsl:when test="count(ancestor::listu)=1">•</xsl:when> 285 <xsl:when test="count(ancestor::listu)=2">–</xsl:when> 286 <xsl:otherwise>∙</xsl:otherwise> 287 </xsl:choose> 288 </fo:block> 289 </fo:list-item-label> 290 <fo:list-item-body start-indent="body-start()"> 291 <fo:block> 292 <xsl:apply-templates /> 293 </fo:block> 294 </fo:list-item-body> 295 </fo:list-item> 296 </xsl:template> 297 <xsl:template match="listo/listitem"> 298 <fo:list-item> 299 <fo:list-item-label end-indent="label-end()"> 300 <fo:block> 301 <xsl:variable name="format"> 302 <xsl:choose> 303 <xsl:when test="count(ancestor::listo)=1">1.</xsl:when> 304 <xsl:when test="count(ancestor::listo)=2">a)</xsl:when> 305 <xsl:when test="count(ancestor::listo)=3">I.</xsl:when> 306 <xsl:when test="count(ancestor::listo)=4">A)</xsl:when> 307 <xsl:when test="count(ancestor::listo)=5">i.</xsl:when> 308 <xsl:otherwise>1.</xsl:otherwise> 309 </xsl:choose> 310 </xsl:variable> 311 <xsl:number format="{$format}" /> 312 </fo:block> 313 </fo:list-item-label> 314 <fo:list-item-body start-indent="body-start()"> 315 <fo:block> 316 <xsl:apply-templates /> 317 </fo:block> 318 </fo:list-item-body> 319 </fo:list-item> 320 </xsl:template> 321 <xsl:template match="listcontent"> 322 <fo:block> 323 <xsl:apply-templates /> 324 </fo:block> 325 </xsl:template> 326 327 <!-- Definitionlist plugin - - - - - - - - - - - - - - - - - - - - - - - --> 328 <xsl:template match="dl"> 329 <fo:table table-layout="fixed" width="100%" font-size="10pt"> 330 <fo:table-body> 331 <xsl:for-each select="dt"> 332 <xsl:variable name="current-term" select="."/> 333 <fo:table-row> 334 <fo:table-cell font-weight="bold" width="5.5cm"> 335 <fo:block> 336 <xsl:apply-templates /> 337 </fo:block> 338 </fo:table-cell> 339 <fo:table-cell> 340 <fo:block> 341 <xsl:apply-templates select="following-sibling::dd[preceding-sibling::dt[1] = $current-term]" /> 342 </fo:block> 343 </fo:table-cell> 344 </fo:table-row> 345 </xsl:for-each> 346 </fo:table-body> 347 </fo:table> 348 </xsl:template> 349 <xsl:template match="dd"> 350 <fo:block> 351 <xsl:apply-templates /> 352 </fo:block> 353 </xsl:template> 354 355 <!-- Tables - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> 356 <xsl:template match="table"> 357 <fo:table table-layout="fixed" margin="1cm auto 0.8cm auto" keep-together.within-page="0.8"> 358 <xsl:attribute name="width"> 359 <xsl:value-of select="substring-before(substring-after(@style,'width:'),';')" /> 360 </xsl:attribute> 361 <xsl:apply-templates select="col" /> 362 <fo:table-body> 363 <xsl:apply-templates select="*[not(self::col)]" /> 364 </fo:table-body> 365 </fo:table> 366 </xsl:template> 367 368 <xsl:template match="col"> 369 <fo:table-column> 370 <xsl:variable name="width" select="substring-after(@style, 'width:')" /> 371 <xsl:choose> 372 <xsl:when test="$width != ''"> 373 <xsl:attribute name="column-width"> 374 <xsl:value-of select="normalize-space($width)" /> 375 </xsl:attribute> 376 </xsl:when> 377 </xsl:choose> 378 <xsl:apply-templates /> 379 </fo:table-column> 380 </xsl:template> 381 382 <xsl:template match="tablerow"> 383 <fo:table-row> 384 <xsl:apply-templates /> 385 </fo:table-row> 386 </xsl:template> 387 388 <xsl:template match="tableheader"> 389 <fo:table-cell border="thin solid black" start-indent="0" end-indent="0" 390 background-color="#efefef" display-align="after" padding="1mm"> 391 <xsl:attribute name="number-rows-spanned"> 392 <xsl:choose> 393 <xsl:when test="@rowspan"> 394 <xsl:value-of select="@rowspan" /> 395 </xsl:when> 396 <xsl:otherwise>1</xsl:otherwise> 397 </xsl:choose> 398 </xsl:attribute> 399 <xsl:attribute name="number-columns-spanned"> 400 <xsl:choose> 401 <xsl:when test="@colspan"> 402 <xsl:value-of select="@colspan" /> 403 </xsl:when> 404 <xsl:otherwise>1</xsl:otherwise> 405 </xsl:choose> 406 </xsl:attribute> 407 <fo:block font-weight="bold"> 408 <xsl:attribute name="text-align"> 409 <xsl:choose> 410 <xsl:when test="@align"> 411 <xsl:value-of select="@align" /> 412 </xsl:when> 413 <xsl:otherwise>left</xsl:otherwise> 414 </xsl:choose> 415 </xsl:attribute> 416 <xsl:apply-templates /> 417 </fo:block> 418 </fo:table-cell> 419 </xsl:template> 420 421 <xsl:template match="tablecell"> 422 <fo:table-cell border="thin solid black" start-indent="0" end-indent="0" padding="1mm"> 423 <xsl:attribute name="number-rows-spanned"> 424 <xsl:choose> 425 <xsl:when test="@rowspan"> 426 <xsl:value-of select="@rowspan" /> 427 </xsl:when> 428 <xsl:otherwise>1</xsl:otherwise> 429 </xsl:choose> 430 </xsl:attribute> 431 <xsl:attribute name="number-columns-spanned"> 432 <xsl:choose> 433 <xsl:when test="@colspan"> 434 <xsl:value-of select="@colspan" /> 435 </xsl:when> 436 <xsl:otherwise>1</xsl:otherwise> 437 </xsl:choose> 438 </xsl:attribute> 439 <fo:block> 440 <xsl:attribute name="text-align"> 441 <xsl:choose> 442 <xsl:when test="@align"> 443 <xsl:value-of select="@align" /> 444 </xsl:when> 445 <xsl:otherwise>left</xsl:otherwise> 446 </xsl:choose> 447 </xsl:attribute> 448 <xsl:value-of select="@rowspan" /> 449 <xsl:apply-templates /> 450 </fo:block> 451 </fo:table-cell> 452 </xsl:template> 453 454</xsl:stylesheet> 455