Count Metrical Lines P4.xslt

From TEIWiki
Jump to navigation Jump to search

Counting <l> elements in a TEI document is pretty easy. But when a metrical line is broken in order to handle overlap, e.g., often two or more TEI <l> elements are used to represent a single metrical line. There are several mechanisms for indicating this fact, two of the more common of which are the use of the part= attribute and the use of the next= & prev= attributes. This stylesheet counts metrical lines in a TEI P4 document, taking into consideration those that have been encoded using several <l> elements using these mechanisms. It does not take other mechanisms (e.g., <join>) into account.

<?xml version="1.0" encoding="UTF-8"?>
<!-- Count lines of poetry, P4 version -->
<!-- Conceived and written 2006-02-19 by Syd Bauman -->
<!-- Copyleft 2006 Syd Bauman -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <xsl:output method="text"/>

  <xsl:template match="/TEI.2">
    <xsl:apply-templates/>
  </xsl:template>

  <!-- Only look at <l> elements inside the outermost <text> element -->
  <!-- (Not likely that there are <l> elements in the <teiHeader>, but -->
  <!-- you never know.) -->
  <xsl:template match="/TEI.2/text">
    <xsl:text>There are </xsl:text>
    <!-- count all lines that do not claim to be continuations of another line elsewhere -->
    <xsl:value-of select="count(.//l[not(@prev) and not(@part='M') and not(@part='F')])"/>
    <xsl:text> metrical lines in “</xsl:text>
    <xsl:apply-templates
      select="/TEI.2/teiHeader/fileDesc/titleStmt/title[@type='main' or not(@type)][1]"/>
    <xsl:text>”</xsl:text>
    <!-- <l> with part="Y" are metrically incomplete lines, which need to be reported separately -->
    <xsl:variable name="incomplete" select="count(.//l[@part='Y'])"/>
    <xsl:if test="$incomplete > 0">
      <xsl:text>, of which </xsl:text>
      <xsl:value-of select="$incomplete"/>
      <!-- singular or plural? -->
      <xsl:choose>
	<xsl:when test="$incomplete = 1">
	  <xsl:text> is</xsl:text>
	</xsl:when>
	<xsl:otherwise>
	  <xsl:text> are</xsl:text>
	</xsl:otherwise>
      </xsl:choose>
      <xsl:text> incomplete</xsl:text>
    </xsl:if>
    <xsl:text>.</xsl:text>
  </xsl:template>

  <!-- for a <title>, just return the string-value of its children -->
  <!-- (We don't have to worry about this template applying except -->
  <!-- when we ask for it, above, because any other ancestor will -->
  <!-- be completely ignored anyway (see below).) -->
  <xsl:template match="title">
    <xsl:apply-templates/>
  </xsl:template>
  
  <!-- Just ignore most anything and everything else -->
  <xsl:template match="*"/>
  
</xsl:stylesheet>