editoria-basic.xsl 5.79 KB
Newer Older
Wendell Piez's avatar
Wendell Piez committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:xsw="http://coko.foundation/xsweet"
  xpath-default-namespace="http://www.w3.org/1999/xhtml"
  xmlns="http://www.w3.org/1999/xhtml"
  exclude-result-prefixes="#all">

  <!-- Note the default namespace for matching (given above) is
     "http://www.w3.org/1999/xhtml" -->


  <xsl:output method="xml" indent="no" omit-xml-declaration="yes"/>

  <!-- By default (when not matched with a template of higher priority)
       copy any element and its attributes. -->
  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="body">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
Wendell Piez's avatar
Wendell Piez committed
28
      <xsl:for-each-group select="div[tokenize(@class,'\s+')=('docx-footnotes','docx-endnotes')]/*" group-by="true()">
Wendell Piez's avatar
Wendell Piez committed
29
        <div id="notes">
30
          <xsl:apply-templates select="current-group()"/>
Wendell Piez's avatar
Wendell Piez committed
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
        </div>
      </xsl:for-each-group>
    </xsl:copy>
  </xsl:template>
  
  <xsl:template match="key('elements-by-class', 'docx-footnotes') | key('elements-by-class', 'docx-endnotes')"/>
    
  <xsl:template match="div[@id='docx-body'] | key('elements-by-class','docx-body')">
    <container id="main">
      <xsl:apply-templates/>  
    </container>
  </xsl:template>
  
  <xsl:template match="key('elements-by-class', 'docx-footnote') | key('elements-by-class', 'docx-endnote')">
    <note-container id="container-{@id}">
      <xsl:apply-templates/>
    </note-container>
  </xsl:template>
  
  <xsl:template match="key('elements-by-class','FootnoteReference') | key('elements-by-class','EndnoteReference')">
51
     <xsl:apply-templates/>
Wendell Piez's avatar
Wendell Piez committed
52 53
  </xsl:template>
  
54
<!-- matches the 'a' element inside a reference (span) -->
Wendell Piez's avatar
Wendell Piez committed
55
  <xsl:template match="key('elements-by-class','footnoteReference') | key('elements-by-class','endnoteReference')">
Wendell Piez's avatar
Wendell Piez committed
56
    <note data-id="{replace(@href,'^#','')}">
Wendell Piez's avatar
Wendell Piez committed
57 58 59
      <xsl:comment> implicit </xsl:comment>    
    </note>
  </xsl:template>
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92

<!-- target element types are -after- mapping of inlines as elsewhere in this XSLT
     i -> em, b -> strong etc. -->
  <xsl:variable as="element()+" name="mapped-styles">
    <em>font-style: italic</em>
    <strong>font-weight: bold</strong>
    <i>text-decoration: underline</i>
  </xsl:variable>
  
  <xsl:template match="p">
    <xsl:variable name="signals" select="xsw:style-propertyValues(.)[.=$mapped-styles]"/>
    <xsl:variable name="me" select="."/>
    <xsl:variable name="mine">
      <xsl:apply-templates/>
    </xsl:variable>
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      
        <xsl:iterate select="$mapped-styles[. = $signals]">
          <xsl:param name="contents" select="$mine"/>
          <xsl:on-completion>
            <xsl:sequence select="$contents"/>
          </xsl:on-completion>
          <xsl:next-iteration>
            <xsl:with-param name="contents">
              <xsl:element name="{name(.)}" namespace="http://www.w3.org/1999/xhtml">
                <xsl:sequence select="$contents"/>
              </xsl:element>
            </xsl:with-param>
          </xsl:next-iteration>
        </xsl:iterate>
    </xsl:copy>
  </xsl:template>
Wendell Piez's avatar
Wendell Piez committed
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
  
  <!-- Any 'i' element becomes an 'em' element; its attributes are copied. -->
  <!-- (Unwanted attributes can be removed in a subsquent step.) -->
  <xsl:template match="i">
    <em>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
    </em>
  </xsl:template>

  <!-- Any 'b' element becomes a 'strong' element; its attributes are copied. -->
  <!-- NB note that inline elements may be modified further or stripped in a subsequent 'reduce' step:
       the story is not over. -->
  <xsl:template match="b">
    <strong>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
    </strong>
  </xsl:template>

  <!-- 'u' becomes 'i' for Editoria.... -->
  <xsl:template match="u">
    <i>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
    </i>
  </xsl:template>

Wendell Piez's avatar
Wendell Piez committed
121 122 123 124
  <!-- Explicit end notes given in source are dropped for Editoria -->
  <xsl:template priority="10" match="span[@class=('footnoteRef','endnoteRef')]"/>
  
  
Wendell Piez's avatar
Wendell Piez committed
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
  <!-- We declare a key that enables us to match elements based on 'class' (attribute) values.
  Any element with a non-ws @class may be so matched (and retrieved).
  Since 'class' may be overloaded this is a many-to-many match, so template
  priority will be important.
  i.e. <p class="Quote Special"> matches with both 'Quote' and 'Special' key values.
  Note the key matches elements of any type (p, h1, span etc.) so no worries about that; only
  as assigned 'class' value (delimited by whitespace) will count. -->
  <xsl:key name="elements-by-class"
    match="*[matches(@class,'\S')]" use="tokenize(@class,'\s+')"/>

  <!-- Calling the key() function, match any element .Quote and emit 'extract', copying attributes.
       Explicit @priority assignments prevent template collisions and let us control
       the order of preference. -->
  <xsl:template match="key('elements-by-class','Quote')" priority="100">
    <extract>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
    </extract>
  </xsl:template>

145 146 147 148 149 150 151 152 153 154

  <xsl:function name="xsw:style-propertyValues" as="xs:string*">
    <!-- Returns 'font-family: Helvetica','font-size: 10pt' whatever
         properties are defined on @style -->
    <xsl:param name="e" as="element()"/>
    <xsl:sequence select="tokenize($e/@style/normalize-space(.),'\s*;\s*')"/>
  </xsl:function>
  
  <xsl:key name="elements-by-propertyValue" match="*[matches(@style,'\S')]" use="xsw:style-propertyValues(.)"/>
  
Wendell Piez's avatar
Wendell Piez committed
155
</xsl:stylesheet>