<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:html="http://www.w3.org/1999/xhtml"
exclude-result-prefixes="html">
  <xsl:output method="xml" indent="yes" />
  <xsl:variable name="lowercase"
  select="'abcdefghijklmnopqrstuvwxyz'" />
  <xsl:variable name="uppercase"
  select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
  <!-- Used only once, but I keep it -->
  <xsl:variable name="title">
    <xsl:value-of select="//title" />
  </xsl:variable>
  <!-- Entry point for the transformation -->
  <xsl:template match="/">
    <!-- handles the root-tag -->
    <fo:root font-family="Classica, Helvetica, ZapfDingbats, Symbol">
      <fo:layout-master-set>
        <fo:simple-page-master master-name="A4-portrait"
        page-height="29.7cm" page-width="21.0cm" margin="2cm">
          <fo:region-body margin-bottom="1cm" />
          <fo:region-after extent="1cm" />
        </fo:simple-page-master>
      </fo:layout-master-set>
      <fo:bookmark-tree>
        <xsl:call-template name="bookmark" />
      </fo:bookmark-tree>
      <fo:page-sequence master-reference="A4-portrait">
        <fo:title>
          <xsl:value-of select="$title" />
        </fo:title>
        <fo:static-content flow-name="xsl-region-after">
          <fo:block>
            <fo:table space-before="1em" margin-left="0"
            padding="0" width="100%"
            border-top="0.5pt solid darkgreen">
              <fo:table-column />
              <fo:table-column />
              <fo:table-body>
                <fo:table-row>
                  <fo:table-cell>
                    <fo:block margin-left="2em">
                      <xsl:call-template name="footer-left" />
                    </fo:block>
                  </fo:table-cell>
                  <fo:table-cell>
                    <fo:block>
                      <xsl:call-template name="footer-right" />
                    </fo:block>
                  </fo:table-cell>
                </fo:table-row>
              </fo:table-body>
            </fo:table>
          </fo:block>
        </fo:static-content>
        <fo:flow flow-name='xsl-region-body'>
          <fo:block>
            <xsl:apply-templates select="/html:html/html:body" />
          </fo:block>
        </fo:flow>
      </fo:page-sequence>
    </fo:root>
  </xsl:template>
  <!-- matches the body-tag  -->
  <xsl:template match="html:body">
    <xsl:apply-templates select="//html:main" />
  </xsl:template>
  <!-- This explicitly creates a footer.-->
  <xsl:template name="footer-left">
    <fo:basic-link color="#005000" text-decoration="underline">
    <xsl:choose>
      <xsl:when test="//h1[@class='title'] = 'flnews'">
        <xsl:attribute name="external-destination">
        url(https://micha.freeshell.org/flnews/)</xsl:attribute>
      </xsl:when>
      <xsl:otherwise>
        <xsl:attribute name="external-destination">
        url(https://www.uplawski.eu/software)</xsl:attribute>
      </xsl:otherwise>
    </xsl:choose>Web-Site</fo:basic-link>
  </xsl:template>
  <xsl:template name="footer-right">
    <!-- currently unused -->
  </xsl:template>
  <xsl:template match="b[@id='omega']">
    <fo:inline padding-left="5em" font-weight="bold"
    page-break-before="avoid" keep-with-previous="always"
    color="#800080">Ω</fo:inline>
  </xsl:template>
  <!-- template for the bookmark-tree 
    This bookmark tree is dynamically created, based
    only on the actual structure of the input document.

    Using for-each to endow each bookmark with a yet
    hypothetical destination-ID. 
    Takes care of the structure created by Docutils:
    <section><h[n]></h[n]></section>
    The IDs come from the <section/> tag, but is altered
    to allow internal links to point at the same position.
  -->
  <xsl:template name="bookmark">
    <xsl:message>[DEBUG]in the bookmark template</xsl:message>
    <xsl:for-each select="//html:h1">
      <xsl:variable name="h1_id" select="../@id" />
      <xsl:message>bookmarking h1 id <xsl:value-of select="$h1_id"/></xsl:message>
      <fo:bookmark internal-destination="bk_{$h1_id}">
        <fo:bookmark-title>
          <xsl:value-of select="." />
        </fo:bookmark-title>
        <xsl:for-each select="following-sibling::html:section[@id]/html:h2">
          <xsl:variable name="h2_id" select="../@id" />
          <fo:bookmark internal-destination="bk_{$h2_id}">
            <xsl:message>bookmarking h2 id <xsl:value-of select="$h2_id"/></xsl:message>
            <fo:bookmark-title>
              <xsl:value-of select="." />
            </fo:bookmark-title>
            <xsl:for-each select="following-sibling::html:section[@id]/html:h3">
              <xsl:variable name="h3_id" select="../@id" />
              <xsl:message><xsl:text>    </xsl:text>bookmarking h3 id <xsl:value-of select="$h3_id"/></xsl:message>
              <fo:bookmark internal-destination="bk_{$h3_id}">
                <fo:bookmark-title>
                  <xsl:value-of select="." />
                </fo:bookmark-title>
                <xsl:for-each select="following-sibling::html:section[@id]/html:h4">
                  <xsl:message><xsl:text>       </xsl:text>bookmarking h4</xsl:message>
                  <xsl:variable name="h4_id" select="../@id" />
                  <fo:bookmark internal-destination="bk_{$h4_id}">
                    <fo:bookmark-title>
                      <xsl:value-of select="." />
                    </fo:bookmark-title>
                    <xsl:for-each select="following-sibling::html:section[@id]/html:h5">
                      <xsl:message><xsl:text>         </xsl:text>bookmarking h5</xsl:message>
                      <xsl:variable name="h5_id" select="../@id" />
                      <fo:bookmark internal-destination="bk_{$h5_id}">
                        <fo:bookmark-title>
                          <xsl:value-of select="." />
                        </fo:bookmark-title>
                      </fo:bookmark>
                    </xsl:for-each>
                    <!-- h5 done -->
                  </fo:bookmark>
                </xsl:for-each>
                <!-- h4 done -->
              </fo:bookmark>
            </xsl:for-each>
            <!-- h3 done -->
          </fo:bookmark>
        </xsl:for-each>
        <!-- h2 done -->
      </fo:bookmark>
      <!-- h1 -->
    </xsl:for-each>
  </xsl:template>
  <!-- starting to work on the actual content -->
  <xsl:template match="html:main">
    <xsl:apply-templates />
  </xsl:template>
  <!-- h1 tags generated by DOCUTILS.  -->
  <xsl:template match="html:h1">
    <xsl:variable name="h1_id">
      <xsl:value-of select="../@id" />
    </xsl:variable>
    <xsl:choose>
      <xsl:when test="@class='title'">
        <fo:block id="bk_{$h1_id}" keep-with-next="always"
        color="#800080" font-size="19pt" margin-bottom='1em'
        font-weight="bold">
          <xsl:value-of select="." />
        </fo:block>
      </xsl:when>
      <xsl:otherwise>
        <fo:block id="{$h1_id}" color="blue" font-size="13pt"
        margin-top="1em" font-weight="bold"
        keep-with-next="always">
          <xsl:value-of select="." />
        </fo:block>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  <!-- sub title below the page title.
    XSLT 2.0 compliant attribute match.
  -->
  <xsl:template match="html:p[@class='subtitle']">
    <fo:block id="{@id}" color="#600080" font-size="13pt"
    margin-bottom='1em' keep-with-next="always">
      <xsl:value-of select="." />
    </fo:block>
  </xsl:template>
  <!-- nav -->
  <!-- I want a bookmark-tree, not a table of contents -->
  <xsl:template match="html:nav">
    <!-- Do nothing -->
  </xsl:template>
  <!-- h2 -->
  <xsl:template match="html:h2">
    <xsl:variable name="id">
      <xsl:value-of select="../@id" />
    </xsl:variable>
    <fo:block id="bk_{$id}" font-weight="bold" color="#a00060"
    font-size="13pt" margin-bottom='1em' margin-top="1em"
    keep-with-next="always">
      <xsl:value-of select="." />
    </fo:block>
  </xsl:template>
  <xsl:template match="html:h3">
    <xsl:variable name="id">
      <xsl:value-of select="../@id" />
    </xsl:variable>
    <fo:block id="bk_{$id}" color="#a00040" font-size="13pt"
    margin-bottom='1em' margin-top="1em" margin-left="1.5em"
    keep-with-next.within-page="always">
      <xsl:value-of select="." />
    </fo:block>
  </xsl:template>
  <xsl:template match="html:h4">
    <xsl:variable name="id">
      <xsl:value-of select="../@id" />
    </xsl:variable>
    <fo:block id="bk_{$id}" color="#700040" font-weight="bold"
    font-size="12pt" margin-bottom='1em' margin-top="1em"
    margin-left="2em" keep-with-next="always">
      <xsl:value-of select="." />
    </fo:block>
  </xsl:template>
  <!-- a definition list -->
  <xsl:template match="html:dl">
    <fo:block>
      <xsl:apply-templates />
    </fo:block>
  </xsl:template>
  <!-- title of a definition item 
    XSLT 2.0 compliant syntax. 
  -->
  <xsl:template match="html:dt">
    <fo:block id="{@id}" keep-with-next.within-page="always"
    font-weight="bold" margin-left="2em" margin-top="0.5em">
      <xsl:value-of select="." />
    </fo:block>
  </xsl:template>
  <!-- Definition -->
  <xsl:template match="html:dd">
    <fo:block margin-left="4em" keep-together.within-page="always">
      <xsl:apply-templates />
    </fo:block>
  </xsl:template>
  <!-- paragraph inside defintion item 
  XSLT 2.0 compliant attribute match. -->
  <xsl:template match="html:p[ancestor::html:dd[1]]">
    <xsl:apply-templates />
  </xsl:template>
  <!-- <p/> in table cell or table header -->
  <xsl:template match="html:p[ancestor::html:table[1]]">
    <fo:block id="{@id}">
      <xsl:apply-templates />
    </fo:block>
  </xsl:template>
  <!-- Default for paragraphs -->
  <xsl:template match="html:p">
    <fo:block id="{@id}" margin-left="2em" margin-top="0.5em">
      <xsl:if test="@id">
        <xsl:attribute name="keep-with-next">always</xsl:attribute>
        <!-- jump targets should not look different.
        <xsl:attribute name="color">#8000a0</xsl:attribute>
        -->
      </xsl:if>
      <xsl:apply-templates />
    </fo:block>
  </xsl:template>
  <!-- tables -->
  <xsl:template match="html:table">
    <fo:table keep-together.within-page="auto" margin-top="0.5em"
    font-size="0.9em" padding="0.5em" border-collapse="separate"
    table-layout="fixed" width="90%" margin-left="2em"
    border="1pt dotted crimson">
      <xsl:apply-templates />
    </fo:table>
  </xsl:template>
  <xsl:template match="html:tbody">
    <fo:table-body>
      <xsl:apply-templates />
    </fo:table-body>
  </xsl:template>
  <xsl:template match="html:thead">
    <fo:table-header>
      <xsl:apply-templates />
    </fo:table-header>
  </xsl:template>
  <xsl:template match="html:th">
    <xsl:choose>
      <xsl:when test="normalize-space(.) != ''">
        <fo:table-cell font-weight="bold" empty-cells="show">
          <xsl:apply-templates />
        </fo:table-cell>
      </xsl:when>
      <xsl:otherwise>
        <fo:table-cell empty-cells="show">
          <fo:block white-space-treatment="preserve">
            <fo:leader />
          </fo:block>
        </fo:table-cell>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  <!-- table rows -->
  <!-- this can be modified to use a <xsl:choose/>
            but only, if the tbody template explicitly
            calls <template match="html:tr"/> -->
  <xsl:template match="html:tr[position() &lt; 5]">
    <fo:table-row keep-with-next="always">
      <xsl:apply-templates />
    </fo:table-row>
  </xsl:template>
  <xsl:template match="html:tr[position() &gt; (last() - 5)]">
    <fo:table-row keep-with-previous="always">
      <xsl:apply-templates />
    </fo:table-row>
  </xsl:template>
  <xsl:template match="html:tr">
    <fo:table-row>
      <xsl:apply-templates />
    </fo:table-row>
  </xsl:template>
  <!-- END tr -->
  <xsl:template match="html:td">
    <xsl:choose>
      <xsl:when test="normalize-space(.) != ''">
        <fo:table-cell padding-before="0" padding-start="0"
        empty-cells="show">
          <xsl:apply-templates />
        </fo:table-cell>
      </xsl:when>
      <xsl:otherwise>
        <fo:table-cell empty-cells="show">
          <fo:block white-space-treatment="preserve">
            <fo:leader />
          </fo:block>
        </fo:table-cell>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  <!-- Unordered list -->
  <xsl:template match="html:ul">
    <fo:list-block provisional-distance-between-starts="10mm"
    end-indent="10mm" start-indent="10mm">
      <!-- change to <xsl:apply-templates select="html:li"/>
      if the position() of list-items becomes important -->
      <xsl:apply-templates />
    </fo:list-block>
  </xsl:template>
  <!-- Unordered list item -->
  <xsl:template match="html:ul/html:li">
    <fo:list-item keep-together.within-page='always'>
      <fo:list-item-label end-indent='label-end()'>
        <fo:block margin-top='0.5em' font-family='DejaVu Sans'>&#x25B8;</fo:block>
      </fo:list-item-label>
      <fo:list-item-body start-indent='body-start()'>
        <fo:block margin-top='0.5em'>
          <xsl:apply-templates />
        </fo:block>
      </fo:list-item-body>
    </fo:list-item>
  </xsl:template>
  <!-- Ordered list -->
  <xsl:template match="html:ol">
    <fo:list-block provisional-distance-between-starts="10mm"
    end-indent="10mm" start-indent="10mm">
      <!-- change to <xsl:apply-templates select="html:li"/>
      if the position() of list-items becomes important -->
      <xsl:apply-templates />
    </fo:list-block>
  </xsl:template>
  <!-- Ordered list item -->
  <xsl:template match="html:ol/html:li">
    <fo:list-item keep-together.within-page='always'>
      <fo:list-item-label end-indent='label-end()'>
        <fo:block margin-top='0.5em'>
          <xsl:number format='1.' />
        </fo:block>
      </fo:list-item-label>
      <fo:list-item-body start-indent='body-start()'>
        <fo:block margin-top='0.5em'>
          <xsl:apply-templates />
        </fo:block>
      </fo:list-item-body>
    </fo:list-item>
  </xsl:template>
  <!-- literal block -->
  <xsl:template match="html:pre[@class='literal-block']">
    <fo:block 
    background-color="#d0d0ff" 
    margin="0.5em 2em 0.5em 2em"
    padding="0.5em"
    white-space-collapse="false"
    linefeed-treatment="preserve"
    white-space-treatment="preserve"
    wrap-option="wrap"
    font-family="AnonymousPro"
    font-size="0.9em">
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>
<!-- span. Unsure if they merit to be merged-->
  <xsl:template match="html:span">
    <fo:inline id="{@id}">
      <xsl:value-of select="." />
    </fo:inline>
  </xsl:template>
  <xsl:template match="html:span[@class='docutils literal']">
    <fo:inline id="{@id}" font-family='AnonymousPro' color="darkblue">
      <xsl:value-of select="." />
    </fo:inline>
  </xsl:template>
  <xsl:template match="html:span[@class='pre']">
    <fo:inline id="{@id}" font-family='AnoymousPro' color="darkblue">
      <xsl:value-of select="." />
    </fo:inline>
  </xsl:template>
  <!-- end span -->
  <!-- italic -->
  <xsl:template match="html:em">
    <fo:inline font-style="italic">
      <xsl:value-of select="." />
    </fo:inline>
  </xsl:template>
  <!-- apply a heavy font -->
  <xsl:template match="html:strong">
    <fo:inline font-weight="bold">
      <xsl:value-of select="." />
    </fo:inline>
  </xsl:template>
  <!-- Hyperlinks -->
  <xsl:template match="html:a">
    <xsl:choose>
      <xsl:when test="starts-with(@href, '#')">
        <xsl:variable name="dest">
          <xsl:value-of select="substring-after(./@href, '#')" />
        </xsl:variable>
        <fo:basic-link internal-destination="{$dest}"
        color="#300030" text-decoration="underline">
          <xsl:value-of select="." />
          <xsl:message> internal destination  <xsl:value-of select="." />,
          <xsl:value-of select="substring-after(./@href, '#')" /></xsl:message>
        </fo:basic-link>
      </xsl:when>
      <xsl:otherwise>
        <xsl:variable name="dest">
          <xsl:value-of select="./@href" />
        </xsl:variable>
        <fo:basic-link external-destination="{$dest}"
        color="#300030" text-decoration="underline">
          <xsl:value-of select="." />
        </fo:basic-link>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  <!-- id attributes -->
  <!-- Ω -->
</xsl:stylesheet>