TEI stylesheet for making Word docx files from TEI XML
Stylesheet documentation
template modes
get-style
License
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You
should have received a copy of the GNU Lesser General Public License along with this
library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite
330, Boston, MA 02111-1307 USA
<xsl:template name="create-document-dot-xml"><w:document><w:body><!-- Front --><xsl:call-template name="write-document-dot-xml-frontmatter"/><!-- Main --><xsl:call-template name="write-document-dot-xml-maincontent"/><!-- Back --><xsl:call-template name="write-document-dot-xml-backmatter"/><!-- Clearing up at the end --><xsl:call-template name="write-document-dot-xml-postclearing"/></w:body></w:document></xsl:template>
<xsl:template name="write-document-dot-xml-frontmatter"><!-- are there specific titlepages --><xsl:call-template name="titlepages"/><!-- header components --><xsl:call-template name="headerParts"/><!-- The front matter --><xsl:apply-templates select="tei:text/tei:front"/></xsl:template>
<xsl:template name="write-document-dot-xml-maincontent"><!-- document title --><xsl:call-template name="document-title"/><!-- Describes the main part of the document --><xsl:apply-templates select="tei:text/tei:body"/></xsl:template>
<xsl:template name="write-document-dot-xml-backmatter"><!-- Describes the back matter of the document --><xsl:apply-templates select="tei:text/tei:back"/></xsl:template>
<xsl:template name="write-document-dot-xml-postclearing"><!-- write out final sectPr .. if exists --><xsl:choose><xsl:when test="tei:text/tei:milestone"><xsl:apply-templates select="tei:text/tei:milestone[1]"><xsl:with-param name="final-section">true</xsl:with-param></xsl:apply-templates></xsl:when><xsl:otherwise><xsl:apply-templates select="document($defaultHeaderFooterFile)/tei:TEI/tei:text/tei:milestone"><xsl:with-param name="final-section">true</xsl:with-param></xsl:apply-templates></xsl:otherwise></xsl:choose></xsl:template>
This template processes block elements (or better to say the children of a block element)
and should never be called directly
(call block-element instead). The function processes all children and puts
all inline elements into one w:p. If it encounters a nested block element
(e.g. a note inside a p) then it closes the previous w:p processes that block
element and then again starts putting all following inline elements into another
w:p element.
@see block-element
<xsl:template name="_process-blockelement"><xsl:param name="style"/><xsl:param name="pPr"/><xsl:param name="nop"/><xsl:param name="bookmark-id"/><xsl:param name="bookmark-name"/><!-- bookmark --><xsl:if test="string-length($bookmark-name) > 0 and string-length($bookmark-id) > 0"><w:bookmarkStart w:id="{$bookmark-id}" w:name="{$bookmark-name}"/></xsl:if><!-- Process Child elements --><xsl:for-each-group select="current-group()" group-starting-with="*[not(teidocx:is-inline(.))]"><xsl:choose><!-- if the current item is a block element, we process that one,
and then take call this function recursively was all the other
elements --><xsl:when test="self::*[not(teidocx:is-inline(.))]"><!-- process block element --><xsl:apply-templates select="."><xsl:with-param name="style" select="$style"/><xsl:with-param name="pPr" select="$pPr"/><xsl:with-param name="nop" select="$nop"/></xsl:apply-templates><!-- process all the other elements in the current group --><xsl:for-each-group select="current-group() except ." group-adjacent="1"><xsl:call-template name="_process-blockelement"><xsl:with-param name="style" select="$style"/><xsl:with-param name="pPr" select="$pPr"/><xsl:with-param name="nop" select="$nop"/></xsl:call-template></xsl:for-each-group></xsl:when><!-- we encountered an inline element. This means that the current group only
contains inline elements --><xsl:otherwise><!-- <xsl:message>+@@ <xsl:value-of select="name()"/>: pPr: <xsl:if test="not(empty($pPr))"><xsl:copy-of
select="$pPr"/></xsl:if>; style: <xsl:if
test="not(empty($style))"><xsl:copy-of
select="$style"/></xsl:if></xsl:message>
--><!-- create all text runs for each item in the current group. we will later
on decide whether we are grouping them together in a w:p or not. --><xsl:variable name="innerRuns"><!-- add paragraph properties (if nobody else created a w:p ($nop)) --><xsl:if test="$nop!='true'"><xsl:choose><xsl:when test="not($style='')"><w:pPr><w:pStyle><xsl:attribute name="w:val" select="$style"/></w:pStyle></w:pPr></xsl:when><xsl:when test="not(empty($pPr))"><xsl:copy-of select="$pPr"/></xsl:when></xsl:choose></xsl:if><!-- Create text runs --><xsl:for-each select="current-group()"><xsl:apply-templates select="."><xsl:with-param name="style" select="$style"/><xsl:with-param name="pPr" select="$pPr"/></xsl:apply-templates></xsl:for-each></xsl:variable><!-- write out text runs.
if someone has already created a w:p ($nop) we may not create another one. --><xsl:choose><xsl:when test="$nop='true'"><xsl:copy-of select="$innerRuns"/></xsl:when><xsl:otherwise><w:p><xsl:copy-of select="$innerRuns"/></w:p></xsl:otherwise></xsl:choose></xsl:otherwise></xsl:choose></xsl:for-each-group><!-- end process children --><!-- bookmark end--><xsl:if test="string-length($bookmark-name) > 0 and string-length($bookmark-id) > 0"><w:bookmarkEnd w:id="{$bookmark-id}"/></xsl:if></xsl:template>
Template for all simple block elements.
This template looks for a style definition template (mode="get-style") that
matches the block element that is currently processed. If none is specified
it copies the style definition from the parent element.
If some special rendering is required you should overwrite this template.
Template for all simple inline elements
This template looks for a character style definition template (mode="get-style")
for the currently processed element.
Description
end template simple block elements: *[not(teidocx:is-inline(.))]
Tests whether to add rendering elements to a run.
Word styles cannot not be added in applyRend. If you want to add
a style go for a get-style template. The order of these
elements in Word does matter, by the way.
Template
tei:head[parent::tei:div or parent::tei:div1 or parent::tei:div2 or parent::tei:div3 or parent::tei:div4 or parent::tei:div5
or parent::tei:div6 or parent::tei:div7]
Documentation
Description
Headers and Sections
Namespace
No namespace
Match
tei:head[parent::tei:div or parent::tei:div1 or parent::tei:div2 or parent::tei:div3 or parent::tei:div4 or parent::tei:div5
or parent::tei:div6 or parent::tei:div7]
<xsl:template match="tei:head[parent::tei:div or parent::tei:div1 or parent::tei:div2 or parent::tei:div3 or parent::tei:div4 or parent::tei:div5 or parent::tei:div6 or parent::tei:div7]"><xsl:param name="pPr"/><!-- find out what level we are at --><xsl:variable name="level"><xsl:value-of select="count(ancestor-or-self::tei:div| ancestor-or-self::tei:div1| ancestor-or-self::tei:div2| ancestor-or-self::tei:div3| ancestor-or-self::tei:div4| ancestor-or-self::tei:div5| ancestor-or-self::tei:div6| ancestor-or-self::tei:div7)"/></xsl:variable><xsl:variable name="number"><xsl:number level="any"/></xsl:variable><xsl:variable name="getstyle" select="teidocx:get-headingstyle(.,$level)"/><xsl:call-template name="block-element"><!-- we want a bookmark for referencing this section --><xsl:with-param name="bookmark-id"><xsl:value-of select="1000+$number"/></xsl:with-param><xsl:with-param name="bookmark-name"><xsl:text>_SECTION_</xsl:text><xsl:value-of select="1000+$number"/></xsl:with-param><!-- find the correct header style --><xsl:with-param name="style"><xsl:choose><xsl:when test="not($pPr instance of xs:string)"><xsl:value-of select="$pPr/w:pPr/w:pStyle/@w:val"/></xsl:when><xsl:when test="string-length($getstyle) > 0"><xsl:call-template name="getStyleName"><xsl:with-param name="in" select="$getstyle"/></xsl:call-template></xsl:when><xsl:when test="parent::tei:div/parent::tei:back"><xsl:text>ANNEX</xsl:text></xsl:when><xsl:when test="ancestor::tei:back"><xsl:value-of select="concat('a',$level)"/></xsl:when><xsl:otherwise><xsl:call-template name="getStyleName"><xsl:with-param name="in"><xsl:text>heading </xsl:text><xsl:value-of select="$level"/></xsl:with-param></xsl:call-template></xsl:otherwise></xsl:choose></xsl:with-param></xsl:call-template></xsl:template>
<xsl:template match="tei:cell"><w:tc><xsl:choose><xsl:when test="w:tcPr"><xsl:copy-of select="w:tcPr"/></xsl:when><xsl:otherwise><w:tcPr><!--w:tcW w:w="1915" w:type="dxa"/--><xsl:if test="@cols"><w:gridSpan w:val="{@cols}"/></xsl:if></w:tcPr></xsl:otherwise></xsl:choose><xsl:choose><xsl:when test="tei:note"><xsl:apply-templates/></xsl:when><xsl:otherwise><xsl:call-template name="block-element"><xsl:with-param name="pPr"><w:pPr><xsl:choose><xsl:when test="@rend"><xsl:variable name="sName"><xsl:call-template name="getStyleName"><xsl:with-param name="in" select="@rend"/></xsl:call-template></xsl:variable><xsl:choose><xsl:when test="$sName=''"><w:pStyle w:val="{$TableText}"/></xsl:when><xsl:otherwise><w:pStyle w:val="{$sName}"/></xsl:otherwise></xsl:choose></xsl:when><xsl:otherwise><w:pStyle w:val="{$TableText}"/></xsl:otherwise></xsl:choose><xsl:choose><xsl:when test="@teidocx:align"><w:jc w:val="{@teidocx:align}"/></xsl:when><xsl:when test="parent::tei:row[@role='label'] or @role='label'"><w:jc w:val="left"/></xsl:when><xsl:when test="starts-with(.,'[0-9]')"><w:jc w:val="right"/></xsl:when><xsl:otherwise><w:jc w:val="left"/></xsl:otherwise></xsl:choose></w:pPr></xsl:with-param></xsl:call-template></xsl:otherwise></xsl:choose><!-- If we have no children, put an empty p here --><xsl:if test="not(descendant::text())"><w:p><w:pPr><w:pStyle w:val="Tabletext9"/></w:pPr><w:r><w:t/></w:r></w:p></xsl:if></w:tc></xsl:template>
<xsl:template match="cals:entry" mode="contents"><xsl:call-template name="block-element"><xsl:with-param name="pPr"><w:pPr><xsl:choose><xsl:when test="@rend"><xsl:variable name="sName"><xsl:call-template name="getStyleName"><xsl:with-param name="in" select="@rend"/></xsl:call-template></xsl:variable><xsl:choose><xsl:when test="$sName=''"><w:pStyle w:val="{$TableText}"/></xsl:when><xsl:otherwise><w:pStyle w:val="{$sName}"/></xsl:otherwise></xsl:choose></xsl:when><xsl:otherwise><w:pStyle w:val="{$TableText}"/></xsl:otherwise></xsl:choose><xsl:choose><xsl:when test="@align"><w:jc w:val="{@align}"/></xsl:when><xsl:when test="parent::tei:row[@role='label'] or @role='label'"><w:jc w:val="left"/></xsl:when><xsl:when test="starts-with(.,'[0-9]')"><w:jc w:val="right"/></xsl:when><xsl:otherwise><w:jc w:val="left"/></xsl:otherwise></xsl:choose></w:pPr></xsl:with-param><xsl:with-param name="nop"><xsl:choose><xsl:when test="not(text()) and tei:note[(not(@place))]">true</xsl:when><xsl:when test="not(text()) and tei:note[@place='foot']">true</xsl:when><xsl:otherwise>false</xsl:otherwise></xsl:choose></xsl:with-param></xsl:call-template><!-- If we have no children, put an empty p here --><xsl:choose><xsl:when test="*"/><xsl:when test="text()"/><xsl:otherwise><w:p><w:pPr><w:pStyle w:val="Tabletext9"/></w:pPr><w:r><w:t/></w:r></w:p></xsl:otherwise></xsl:choose></xsl:template>
<xsl:template name="linkMe"><xsl:param name="anchor"/><!-- create the field codes for the complex field --><!-- based on information in tei:ref/@tei:rend --><xsl:variable name="instrText"><xsl:choose><xsl:when test="starts-with(@target,'#')"><xsl:choose><xsl:when test="contains(@rend,'noteref')"><xsl:text>NOTEREF _</xsl:text></xsl:when><xsl:otherwise><xsl:text>REF _</xsl:text></xsl:otherwise></xsl:choose><xsl:value-of select="substring(@target,2)"/><xsl:if test="contains(@rend,'instr_f')"><xsl:text> \f</xsl:text></xsl:if><xsl:if test="contains(@rend,'instr_r')"><xsl:text> \r</xsl:text></xsl:if><xsl:if test="contains(@rend,'instr_n')"><xsl:text> \n</xsl:text></xsl:if><xsl:text> \h </xsl:text><xsl:if test="contains(@rend,'mergeformat')"><xsl:text> \* MERGEFORMAT</xsl:text></xsl:if></xsl:when><xsl:otherwise><xsl:text>HYPERLINK "</xsl:text><xsl:value-of select="@target"/><xsl:text>" \h</xsl:text></xsl:otherwise></xsl:choose></xsl:variable><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText><xsl:value-of select="$instrText"/></w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><xsl:variable name="rPr"><xsl:apply-templates><xsl:with-param name="character-style" select="@iso:class"/></xsl:apply-templates></xsl:variable><w:rPr><xsl:if test="$rPr/w:r/w:rPr/w:rStyle/@w:val"><w:rStyle w:val="{$rPr/w:r/w:rPr/w:rStyle/@w:val}"/></xsl:if><xsl:copy-of select="$anchor/w:r/w:rPr/*[not(self::w:rStyle)]"/><!-- oucs0037: why are we overriding special font styles??
Comment this out for now! --><!-- <xsl:if test="ancestor::tei:p[@rend='Special']">
<w:rFonts w:ascii="Courier New" w:hAnsi="Courier New"/>
</xsl:if> --><xsl:if test="$rPr/w:r/w:rPr/w:rStyle/@w:val='Hyperlink'"><w:u w:val="none"/></xsl:if></w:rPr><xsl:choose><xsl:when test="$anchor/w:r"><xsl:copy-of select="$anchor/w:r/w:t"/></xsl:when><xsl:otherwise><w:t><xsl:copy-of select="$anchor"/></w:t></xsl:otherwise></xsl:choose></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></xsl:template>