PartLines1.xslt

From TEIWiki
Jump to navigation Jump to search

This is a proof-of-concept that it is possible 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 1.0. As the internal documentation says, I bet there’s a better way to do this. I’m kinda hoping that by posting here someone will replace this with an improved version. (In which case, please just replace the content of this page, rather than make a new one.)

NB that I have also posted an XSLT 2.0 version, which is much simpler.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.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
      nasty XPaths to do this sort of thing</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 1.0, not ot demonstrate a good way to do it. Quite the reverse — my
      plan is to post this to XSL-LIST and ask “what’s the right way to do this”?, since
      this clearly isn’t.</xd:p>
    </xd:desc>
  </xd:doc>
  
  <xsl:output method="xml"
    doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
    doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
    encoding="UTF-8"
    indent="yes"/>

  <xsl:template match="/">
    <html>
      <head>
        <title>table of lines</title>
        <meta content="lineParts1.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:apply-templates select="tei:l"/>
    </table>
  </xsl:template>

  <xsl:template match="tei:l">
    <xsl:choose>
      <xsl:when test="not(@part)">
        <tr>
          <td>
            <xsl:value-of select="count(preceding-sibling::tei:l[ not(@part) or @part='I' ]) +1"/>
          </td>
          <td>
            <xsl:value-of select="."/>
          </td>
        </tr>
      </xsl:when>
      <xsl:when test="@part='I'">
        <tr>
          <td>
            <xsl:value-of select="count(preceding-sibling::tei:l[ not(@part) or @part='I' ]) +1"/>
            <xsl:text> (1 of </xsl:text>
            <xsl:value-of
              select="count(
              following-sibling::tei:l[@part='M'][
                preceding-sibling::tei:l[@part='I'][1][
                  generate-id(current()) = generate-id(.)
                  ]
                ]
              ) + 2"
            />
            <xsl:text>)</xsl:text>
          </td>
          <td>
            <xsl:value-of select="."/>
          </td>
        </tr>
      </xsl:when>
      <xsl:when test="@part='M'">
        <xsl:variable name="myI" select="preceding-sibling::tei:l[@part='I'][1]"/>
        <xsl:variable name="myIID" select="generate-id( $myI )"/>
        <xsl:variable name="position"
          select="count(              
            preceding-sibling::tei:l
              [@part='M']
              [generate-id( preceding-sibling::tei:l[@part='I'][1] ) = $myIID ]
            ) +2"/>
        <tr>
          <td>
            <xsl:value-of select="count(preceding-sibling::tei:l[ not(@part) or @part='I' ])"/>
            <xsl:text> (</xsl:text>
            <xsl:value-of select="$position"/>
            <xsl:text> of </xsl:text>
            <xsl:value-of
              select="$position + count(
                following-sibling::tei:l[@part='M'][
                  preceding-sibling::tei:l[@part='I'][1][
                    $myIID = generate-id( . )
                    ]
                  ]
                ) +1"
            />
            <xsl:text>)</xsl:text>
          </td>
          <td>
            <xsl:value-of select="."/>
          </td>
        </tr>
      </xsl:when>
      <xsl:when test="@part='F'">
        <xsl:variable name="myI" select="preceding-sibling::tei:l[@part='I'][1]"/>
        <xsl:variable name="myIID" select="generate-id( $myI )"/>
        <xsl:variable name="position"
          select="count(              
            preceding-sibling::tei:l
              [@part='M']
              [generate-id( preceding-sibling::tei:l[@part='I'][1] ) = $myIID ]
            ) +2"/>
        <tr>
          <td>
            <xsl:value-of select="count(preceding-sibling::tei:l[ not(@part) or @part='I' ])"/>
            <xsl:text> (</xsl:text>
            <xsl:value-of select="$position"/>
            <xsl:text> of </xsl:text>
            <xsl:value-of
              select="count(
                following-sibling::tei:l
                  [@part='M']
                  [ preceding-sibling::tei:l[ generate-id(current()) = $myIID ] ]
                 ) + $position"
            />
            <xsl:text>)</xsl:text>
          </td>
          <td>
            <xsl:value-of select="."/>
          </td>
        </tr>
      </xsl:when>
    </xsl:choose>

  </xsl:template>

</xsl:stylesheet>