<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
  version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:tei="http://www.tei-c.org/ns/1.0"
  xmlns:dsp="http://www.digitalhumanities.org/dhq/namespace/util"
  xmlns:m="http://www.w3.org/1998/Math/MathML"
  exclude-result-prefixes="#all" >

  <!--

    *** TEI to (X)HTML display stylesheet for DHQ review ***
        Wendell Piez, Feb 2006, March 2008
        Jarom McDonald, Feb 2006
        (others add names here)

        please validate your output!

        if extending the stylesheet, please test
        and assure output is valid XHTML/CSS
        (required for DHQ distribution)

    design/development strategy:

    PRINCIPLES:
      display doesn't have to be perfect
        (this is just for peer review, not publication)
      but it should be easily extensible
        (where possible, on the CSS layer)

    ACCORDINGLY, to extend
      first, look at the output
        when div or span plus @class gives you a hook,
        write CSS to it
      when that isn't sufficient, extend the XSLT
        (in the unnamed or default mode)

    default mode is for final display
    initial pass is for prep tagging
      (elements to be marked as block or inline, then
       split when necessary to support valid XHTML

    the aim is for XHTML "in all but name"
    (that is, validate in testing but do not export
     xml or DOCTYPE declarations; instead, target
     "browser ecumenism")

punchlist:
    x fallback superstructure
      x div/span mappings
      x parameter-driven debugging (show otherwise unmatched tagging)
    x element splitting logic
      promoting p/list and such
    o body elements
    o header
    o front matter
    o back matter

  -->

  <xsl:output method="xml" indent="yes"
    doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
    doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"/>

  <xsl:param name="diagnose" select="false()"/>

  <xsl:param name="css" select="'DHQ-TEI-html.css'"/>

  <xsl:variable name="scrubbed">
    <xsl:apply-templates select="/node()" mode="scrub"/>
  </xsl:variable>

  <xsl:variable name="prepared">
    <xsl:apply-templates select="$scrubbed/node()" mode="prep"/>
  </xsl:variable>

  <xsl:variable name="display-title" select="$prepared/*/teiHeader/fileDesc/titleStmt/title"/>
  <!-- pls fix as necessary -->
  
  <xsl:template match="/">
    <!--<xsl:copy-of select="$scrubbed"/>-->
    <!--<xsl:copy-of select="$prepared"/>-->
    <xsl:apply-templates select="$prepared/node()"/>
    <!-- skip the document node of the intermediate result
         to avoid looping -->
  </xsl:template>

  <xsl:template match="tei:*" mode="scrub">
    <xsl:element name="{local-name()}" namespace="">
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates mode="scrub"/>
    </xsl:element>
  </xsl:template>
  
  <xsl:template match="*" mode="scrub">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates mode="scrub"/>
    </xsl:copy>
  </xsl:template>
  
  <xsl:template match="*" mode="prep">
    <!-- prep mode normalizes all kinds of div to plain div, plus
      does any other necessary normalizing -->
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates select="." mode="annotate"/>
      <xsl:apply-templates mode="prep"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*" mode="annotate">
    <!-- used to mark elements as block or inline, if necessary -->
  </xsl:template>

  <xsl:template match="p/list | p/eg" mode="annotate">
    <!-- add elements to the match here that should be 'promoted' -->
    <xsl:attribute name="dsp:level">block</xsl:attribute>
    <!-- these elements will be 'split' out of p element parents,
      where they occur: see templates matching p -->
  </xsl:template>


  <xsl:template match="div | div0 | div1 | div2 | div3 | div4
                           | div5 | div6 | div7 | div8 | div9" mode="prep">
    <!-- prep mode normalizes all kinds of div to plain div, plus
      does any other necessary normalizing -->
    <xsl:element name="div" namespace="">
      <!-- the null namespace has to be given, or we'll end up in HTML -->
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates mode="prep"/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="TEI.2 | TEI">
    <html>
      <head>
        <title>
          <xsl:value-of select="$display-title"/>
        </title>
        <link rel="stylesheet" href="{$css}" type="text/css"/>
        <script type = "text/javascript">
          function popUpLayer(colophon) {
          var colophonWindow = document.getElementById("teiHeader");
          colophonWindow.style.visibility = "visible";
          }

          function closeLayer(closeButton) {
          var colophonWindow = document.getElementById("teiHeader");
          colophonWindow.style.visibility = "hidden";
          }
        </script>
      </head>
      <body>
        <xsl:apply-templates/>
      </body>
    </html>
  </xsl:template>


  <!--<xsl:template match="teiHeader">
    <h3>(Header information suppressed for Peer Review)</h3>
  </xsl:template>-->
  
  <xsl:template match="teiHeader">
    <p><a  href="#" onclick="popUpLayer(this);">Full Header Information</a></p>
    <div class="teiHeader" id="teiHeader">
      <div class="headercontrol"><button class="close" onclick="closeLayer(this);">Close Window</button></div>
      <xsl:apply-templates/>
    </div>
  </xsl:template>


  <xsl:template match="teiHeader/*" priority="2">
    <div class="{local-name()}">
      <h5 style="margin-bottom:0em">
        <xsl:value-of select="local-name()"/>
        <xsl:text>:</xsl:text>
      </h5>
      <xsl:apply-templates/>
    </div>
  </xsl:template>

  <xsl:template match="publicationStmt/authority" priority="2"/>

  <xsl:template match="text">
    <div class="text" id="text">
      <xsl:for-each select="$display-title">
        <h1>
          <xsl:apply-templates/>
        </h1>
      </xsl:for-each>
      <xsl:apply-templates/>
    </div>
  </xsl:template>

  <xsl:template match="div">
    <!-- numbered divs do not need to be matched, as they have been
         normalized into plain div in the prep phase -->
    <div class="div">
      <xsl:apply-templates/>
      <xsl:for-each select=".//note">
        <span class="note">
          <a>
            <xsl:attribute name="name">note<xsl:value-of select="@n"/></xsl:attribute>
          </a>
          <br/>
          <sup>
            <xsl:value-of select="position()"/>
          </sup>
          <xsl:apply-templates/>
        </span>
        <br/>
      </xsl:for-each>
    </div>
  </xsl:template>

  <xsl:template match="titlePart">
    <h4 class="titlePart">
      <xsl:apply-templates/>
    </h4>
  </xsl:template>

  <xsl:template match="head">
    <h4 class="{local-name(..)}-head">
      <xsl:apply-templates/>
    </h4>
  </xsl:template>

  <xsl:template match="div/head">
    <xsl:variable name="level" select="count(ancestor::div)"/>
    <xsl:if test="$level > 5">
      <xsl:message>
        <xsl:text>Warning: div level deeper than 5 results in 'h</xsl:text>
        <xsl:value-of select="$level + 1"/>
        <xsl:text>' tagging (pls fix for HTML conformance)</xsl:text>
      </xsl:message>
    </xsl:if>
    <xsl:element name="h{$level + 1}">
      <xsl:attribute name="class">
        <xsl:text>div</xsl:text>
        <xsl:value-of select="$level"/>
        <xsl:text>-head</xsl:text>
      </xsl:attribute>
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="p">
    <!-- strictly speaking we don't need this template, but in theory we gain
         efficiencies by working more simply where we can -->
    <p class="p">
      <xsl:if test="not(preceding-sibling::*)">
        <xsl:attribute name="class">first-p</xsl:attribute>
      </xsl:if>
      <xsl:apply-templates/>
    </p>
  </xsl:template>

  <xsl:template match="p[*[@dsp:level='block']]">
    <xsl:for-each-group select="node()" group-starting-with="*[@dsp:level='block']">
      <!-- now we handle our blocks and the nodes between them -->
      <xsl:apply-templates select="current-group()[@dsp:level='block']"/>
      <!-- first applying templates to the block w/o a wrapper -->
      <xsl:if test="current-group()[not(@dsp:level='block')]">
        <p class="p">
          <!-- now wrapping any nodes after the block in their own p -->
          <xsl:apply-templates select="current-group()[not(@dsp:level='block')]"/>
        </p>
      </xsl:if>
    </xsl:for-each-group>
  </xsl:template>

  <xsl:template match="list">
    <xsl:apply-templates select="head"/>
    <xsl:variable name="gi">
      <xsl:choose>
        <xsl:when test="@type='ordered'">ol</xsl:when>
        <xsl:otherwise>ul</xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <xsl:element name="{$gi}">
      <xsl:apply-templates select="item"/>
    </xsl:element>
    <xsl:if test="* except (head|item)">
      <xsl:message>Warning: unexpected list content encountered (not a head or an item)</xsl:message>
    </xsl:if>
  </xsl:template>

  <xsl:template match="item">
    <li>
      <xsl:apply-templates/>
    </li>
  </xsl:template>

  <xsl:template match="eg">
    <pre class="eg">
      <xsl:apply-templates/>
    </pre>
  </xsl:template>

  <xsl:template match="graphic">
    <xsl:variable name="filename" select="tokenize(@url,'/')[last()]"/>
    <img src="{$filename}"/>
  </xsl:template>
  
  <xsl:template match="*">
    <xsl:call-template name="mark">
      <xsl:with-param name="content">
        <div class="{local-name()}">
          <xsl:apply-templates/>
        </div>
      </xsl:with-param>
    </xsl:call-template>
  </xsl:template>

  <xsl:template match="*[../text()[normalize-space()]]" priority="-0.25">
    <xsl:call-template name="mark">
      <xsl:with-param name="content">
        <span class="{local-name()}">
          <xsl:apply-templates/>
        </span>
      </xsl:with-param>
    </xsl:call-template>
  </xsl:template>

  <xsl:template name="mark">
    <xsl:param name="content" select="()"/>
    <xsl:if test="$diagnose">
      <span style="color:darkred;font-size:80%">
        <xsl:text>&lt;</xsl:text>
        <xsl:value-of select="local-name()"/>
        <xsl:text>&gt;</xsl:text>
      </span>
    </xsl:if>
    <xsl:copy-of select="$content"/>
    <xsl:if test="$diagnose">
      <span style="color:darkred;font-size:80%">
        <xsl:text>&lt;/</xsl:text>
        <xsl:value-of select="local-name()"/>
        <xsl:text>&gt;</xsl:text>
      </span>
    </xsl:if>
  </xsl:template>

  <!-- CSS extensions for various elements that might have a 'rend' attribute -->

  <xsl:template name="render">
    <xsl:param name="style"/>
    <span class="{$style} {local-name()}">
      <xsl:apply-templates/>
    </span>
  </xsl:template>

  <xsl:template match="hi|emph|soCalled|title|name|foreign|mentioned|rs|term|q|abbr">
    <xsl:choose>
      <xsl:when test="@rend">
        <xsl:call-template name="render">
          <xsl:with-param name="style" select="@rend"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <span class="{local-name()}">
          <xsl:apply-templates/>
         </span>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <!-- mappings for 'problem' elements -->

  <xsl:template match="title/*">
    <span class="{local-name()}">
      <xsl:apply-templates/>
    </span>
  </xsl:template>

  <xsl:template match="lb">
    <br/>
  </xsl:template>

<!-- MathML copy -->
  
   <xsl:template match="m:*" priority="999">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>
  
  
</xsl:stylesheet>
