MovePB.xslt

From TEIWiki
Jump to navigation Jump to search

The Best Practices for TEI in Libraries produced by the TEI SIG:Libraries is a helpful document indeed. However, there is at least one recommendation made with which I vehemently disagree: that a page break that occurs between divisions be encoded at the top of the following division, rather than between them (or at the bottom of the previous division, which would be just as bad). See section 3.6.

This stylesheet moves <pb> elements placed as the first child of a <div> to just before the start-tag of said <div>.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xpath-default-namespace="http://www.tei-c.org/ns/1.0"
  xmlns="http://www.tei-c.org/ns/1.0">

  <!-- Copyleft 2012-03 by Syd Bauman -->

  <!-- identity transform (using 2 templates to be efficient) -->
  <xsl:template match="*">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="text()|processing-instruction()|comment()|@*">
    <xsl:copy/>
  </xsl:template>

  <!-- <pb>-moving template -->
  <!-- Match any element whose 1st child <pb> element both -->
  <!-- is the first child element (i.e., has no preceding element siblings) -->
  <!-- and is not preceded by text (other than whitespace) -->
  <xsl:template match="*[                                    (: match all elements whose :)
       child::pb[1][                                         (:   first child 'pb' :)
         not( preceding-sibling::* )                         (:   has no preceding element siblings :)
         and                                                 (:   and also has :)
         not( preceding-sibling::text()[normalize-space()] ) (:   no preceding text nodes with non-whitespace characters :)
       ] ]">
    <!-- I am an element with a 1st child <pb>, so first copy over said child <pb> ... -->
    <xsl:apply-templates select="child::pb[1]"/>
    <!-- ... and then copy over myself -->
    <xsl:copy>                                             <!-- copy me w/o children or attrs -->
      <xsl:apply-templates select="@*"/>                   <!-- copy over attrs -->
      <xsl:apply-templates select="node()[
           not( . is current()/child::pb[1] )
           ]"/>                                            <!-- copy over my content *except* that 1st <pb> -->
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>