PartLines2.xslt

From TEIWiki
Jump to navigation Jump to search

This is a demo of one way to keep track of partial metrical lines (encoded with part=I, M, and F — this demo knows nothing of part=Y or N, nor next= and prev=, nor <join>) using XSLT 2.0. As the internal documentation says, there may well be a better way to do this, but this does seem to work.

NB that I have also posted an XSLT 1.0 version, which demonstrates that the same task can be done in XSLT 1, but is much more complicated.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
  xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:tei="http://www.tei-c.org/ns/1.0"
  xmlns="http://www.w3.org/1999/xhtml">

  <xd:doc scope="stylesheet">
    <xd:desc>
      <xd:p>This is just a proof-of-concept stylesheet that counts the nubmers
        of lines in a TEI <tt>&lt;lg></tt> element, keeping track of partial lines.</xd:p>
      <xd:p><xd:b>written</xd:b>: 2009-12-18 by Syd Bauman, based on some previous
        XSLT 2.0 grouping code I’d written and Michael Kay’s post “RE: [xsl] Number of
        elements with a given attribute” to XSL-LIST 2009-12-18 10:07-00.</xd:p>
      <xd:p><xd:b>availability</xd:b>: Copyleft 2009 Syd Bauman</xd:p>
      <xd:p><xd:b>Known Issues</xd:b>:</xd:p>
      <xd:p>Process all <tt>&lt;lg></tt> elements that have <tt>&lt;l></tt> children,
      regardless of how deeply nested they might be</xd:p>
      <xd:p>Does not process <tt>&lt;l></tt> descendants, so if you had couplets encoded,
      this stylesheet wouldn't do much useful</xd:p>
      <xd:p>This is only intended to demonstrate that this <xd:b>can</xd:b> be done in
      XSLT 2.0, not necessarily to demonstrate the best way to do it. Quite the reverse &#x2014;
      my plan is to post this to XSL-LIST and ask “is this the right way to do this”?</xd:p>
    </xd:desc>
  </xd:doc>
  
  <xsl:output method="xhtml"
    encoding="UTF-8"
    indent="yes"/>

  <xsl:template match="/">
    <html>
      <head>
        <title>table of lines</title>
        <meta content="partLines2.xslt" name="generated-by"/>
      </head>
      <body>
        <h1>Lines of poetry displayed as a set of tables</h1>
        <xsl:apply-templates select="//tei:lg[child::tei:l]"/>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="tei:lg">
    <xsl:if test="tei:head">
      <h2>
        <xsl:value-of select="tei:head[1]"/>
      </h2>
    </xsl:if>
    <table border="1">
      <thead>
        <th>#</th>
        <th>content</th>
      </thead>
      <xsl:for-each-group select="tei:l" group-starting-with="tei:l[not(@part) or @part='I']">
        <xsl:variable name="grp_pos" select="position()"/>
        <xsl:for-each select="current-group()">
          <xsl:variable name="cur_grp_cnt" select="count( current-group() )"/>
          <tr>
            <td>
              <xsl:value-of select="$grp_pos"/>
              <xsl:if test="@part">
                <xsl:text> (</xsl:text>
                <xsl:value-of select="position()"/>
                <xsl:text> of </xsl:text>
                <xsl:value-of select="$cur_grp_cnt"/>
                <xsl:text>)</xsl:text>
              </xsl:if>
            </td>
            <td><xsl:value-of select="."/></td>
          </tr>
        </xsl:for-each>
      </xsl:for-each-group>
    </table>
  </xsl:template>

</xsl:stylesheet>