-
Frank Steinberg authoredFrank Steinberg authored
bjcp-2015-styleguide-doc-to-xml.xsl 30.47 KiB
<?xml version="1.0"?>
<xsl:stylesheet
version="1.0"
xmlns="http://heimbrauconvention.de/bjcp-styleguide/2015"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
xmlns:str="http://exslt.org/strings"
xmlns:math="http://exslt.org/math"
xmlns:dyn="http://exslt.org/dynamic"
xmlns:func="http://exslt.org/functions"
xmlns:b="http://frankensteiner.familie-steinberg.org/bjcp-tools"
extension-element-prefixes="exsl str math dyn func">
<xsl:variable name="add-de"></xsl:variable>
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<func:function name="b:srmToEbc">
<xsl:param name="in"/>
<!--<func:result select="round($in div 0.508 * 10) div 10"/>-->
<func:result select="round($in div 0.508)"/>
</func:function>
<func:function name="b:sgToPlato">
<xsl:param name="in"/>
<!-- https://www.brewersfriend.com/plato-to-sg-conversion-chart/ -->
<func:result select="round(((-1 * 616.868) + (1111.14 * $in) - (630.272 * math:power($in,2)) + (135.997 * math:power($in,3))) * 10) div 10"/>
</func:function>
<xsl:template match="/w:document">
<xsl:element name="styleguide">
<xsl:apply-templates select=".//w:p[w:pPr/w:pStyle/@w:val='Heading1' and w:r/w:t]" mode="chapter"/>
</xsl:element>
</xsl:template>
<xsl:template match="w:p" mode="chapter">
<xsl:variable name="s">
<xsl:for-each select="w:r/w:t">
<xsl:value-of select="text()"/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="title">
<xsl:value-of select="normalize-space($s)"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="substring($title,1,1) > 0">
<xsl:call-template name="category">
<xsl:with-param name="title">
<xsl:value-of select="$title"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="chapter">
<xsl:with-param name="title">
<xsl:value-of select="$title"/>
</xsl:with-param>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="chapter">
<xsl:param name="title"/>
<xsl:element name="chapter">
<xsl:attribute name="id">
<xsl:value-of select="translate($title,'ABCDEFGHIJKLMNOPQRSTUVWXYZ :','abcdefghijklmnopqrstuvwxyz-')"/>
</xsl:attribute>
<xsl:element name="h2">
<xsl:value-of select="$title"/>
</xsl:element>
<xsl:apply-templates select="following-sibling::w:p[1]" mode="in-chapter"/>
</xsl:element>
</xsl:template>
<xsl:template name="category">
<xsl:param name="title"/>
<xsl:element name="category">
<xsl:attribute name="id">
<xsl:value-of select="substring-before($title,'. ')"/>
</xsl:attribute>
<xsl:element name="name">
<xsl:value-of select="substring-after($title,'. ')"/>
</xsl:element>
<xsl:if test="add-de">
<xsl:element name="name">
<xsl:attribute name="lang">de</xsl:attribute>
<!-- translation to be entered here --><xsl:text> </xsl:text>
</xsl:element>
</xsl:if>
<xsl:call-template name="style-intro"/>
<xsl:apply-templates select="following-sibling::w:p[1]" mode="attribute">
<xsl:with-param name="attribute">Entry Instructions</xsl:with-param>
</xsl:apply-templates>
<xsl:apply-templates select="following-sibling::w:p[1]" mode="in-category"/>
<!--
<xsl:if test="not($id)">
<xsl:apply-templates select="following-sibling::w:p[1]" mode="in-subcategory">
<xsl:with-param name="id">
<xsl:value-of select="substring-before($title,'. ')"/>
</xsl:with-param>
</xsl:apply-templates>
</xsl:if>
-->
<xsl:apply-templates select="following-sibling::w:p[1]" mode="in-subcategory">
<xsl:with-param name="id">
<xsl:value-of select="substring-before($title,'. ')"/>
</xsl:with-param>
</xsl:apply-templates>
</xsl:element>
</xsl:template>
<xsl:template name="subcategory">
<xsl:param name="id"/>
<xsl:param name="title"/>
<xsl:variable name="id0">
<xsl:choose>
<xsl:when test="contains($title,'.')">
<xsl:value-of select="substring-before($title,'. ')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$id"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:element name="subcategory">
<xsl:attribute name="id">
<xsl:value-of select="$id0"/>
</xsl:attribute>
<xsl:element name="name">
<xsl:choose>
<xsl:when test="contains($title,'.')">
<xsl:value-of select="substring-after($title,'. ')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$title"/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
<xsl:if test="add-de">
<xsl:element name="name">
<xsl:attribute name="lang">de</xsl:attribute>
<!-- translation to be entered here --><xsl:text> </xsl:text>
</xsl:element>
</xsl:if>
<xsl:call-template name="style-intro"/>
<xsl:apply-templates select="following-sibling::w:p[1]" mode="attribute">
<xsl:with-param name="attribute">Overall Impression</xsl:with-param>
<xsl:with-param name="id"><xsl:value-of select="$id0"/></xsl:with-param>
</xsl:apply-templates>
<xsl:apply-templates select="following-sibling::w:p[1]" mode="attribute">
<xsl:with-param name="attribute">Aroma</xsl:with-param>
<xsl:with-param name="id"><xsl:value-of select="$id0"/></xsl:with-param>
</xsl:apply-templates>
<xsl:apply-templates select="following-sibling::w:p[1]" mode="attribute">
<xsl:with-param name="attribute">Appearance</xsl:with-param>
<xsl:with-param name="id"><xsl:value-of select="$id0"/></xsl:with-param>
</xsl:apply-templates>
<xsl:apply-templates select="following-sibling::w:p[1]" mode="attribute">
<xsl:with-param name="attribute">Flavor</xsl:with-param>
<xsl:with-param name="id"><xsl:value-of select="$id0"/></xsl:with-param>
</xsl:apply-templates>
<xsl:apply-templates select="following-sibling::w:p[1]" mode="attribute">
<xsl:with-param name="attribute">Mouthfeel</xsl:with-param>
<xsl:with-param name="id"><xsl:value-of select="$id0"/></xsl:with-param>
</xsl:apply-templates>
<xsl:apply-templates select="following-sibling::w:p[1]" mode="attribute">
<xsl:with-param name="attribute">Comments</xsl:with-param>
<xsl:with-param name="id"><xsl:value-of select="$id0"/></xsl:with-param>
</xsl:apply-templates>
<xsl:apply-templates select="following-sibling::w:p[1]" mode="attribute">
<xsl:with-param name="attribute">History</xsl:with-param>
<xsl:with-param name="id"><xsl:value-of select="$id0"/></xsl:with-param>
</xsl:apply-templates>
<xsl:apply-templates select="following-sibling::w:p[1]" mode="attribute">
<xsl:with-param name="attribute">Characteristic Ingredients</xsl:with-param>
<xsl:with-param name="id"><xsl:value-of select="$id0"/></xsl:with-param>
</xsl:apply-templates>
<xsl:apply-templates select="following-sibling::w:p[1]" mode="attribute">
<xsl:with-param name="attribute">Style Comparison</xsl:with-param>
<xsl:with-param name="id"><xsl:value-of select="$id0"/></xsl:with-param>
</xsl:apply-templates>
<xsl:apply-templates select="following-sibling::w:p[1]" mode="attribute">
<xsl:with-param name="attribute">Commercial Examples</xsl:with-param>
<xsl:with-param name="id"><xsl:value-of select="$id0"/></xsl:with-param>
</xsl:apply-templates>
<xsl:apply-templates select="following-sibling::w:p[1]" mode="attribute">
<xsl:with-param name="attribute">Entry Instructions</xsl:with-param>
<xsl:with-param name="id"><xsl:value-of select="$id0"/></xsl:with-param>
</xsl:apply-templates>
<!--
<xsl:apply-templates select="following-sibling::w:p[1]" mode="attribute">
<xsl:with-param name="attribute">Currently Defined Types</xsl:with-param>
<xsl:with-param name="id"><xsl:value-of select="$id0"/></xsl:with-param>
</xsl:apply-templates>
-->
<!-- TODO: Currently Defined Types sollte implizit klar sein. -->
<xsl:apply-templates select="following-sibling::w:p[1]" mode="tags">
<xsl:with-param name="id"><xsl:value-of select="$id0"/></xsl:with-param>
</xsl:apply-templates>
<xsl:apply-templates select="following-sibling::w:p[1]" mode="specs">
<xsl:with-param name="id"><xsl:value-of select="$id0"/></xsl:with-param>
</xsl:apply-templates>
<xsl:apply-templates select="following-sibling::w:p[1]" mode="strengths">
<xsl:with-param name="id"><xsl:value-of select="$id0"/></xsl:with-param>
</xsl:apply-templates>
<xsl:if test="not($id)">
<xsl:apply-templates select="following-sibling::w:p[1]" mode="in-subcategory">
<xsl:with-param name="id">
<xsl:value-of select="substring-before($title,'. ')"/>
</xsl:with-param>
</xsl:apply-templates>
</xsl:if>
</xsl:element>
</xsl:template>
<xsl:template match="w:p" mode="attribute">
<xsl:param name="attribute"/>
<xsl:param name="id"/>
<xsl:variable name="n">
<xsl:value-of select="translate($attribute,'ABCDEFGHIJKLMNOPQRSTUVWXYZ ','abcdefghijklmnopqrstuvwxyz-')"/>
</xsl:variable>
<xsl:variable name="p">
<xsl:text>document('../fix/</xsl:text>
<xsl:value-of select="$id"/>
<xsl:text>.xml')/styleguide//*[@id='</xsl:text>
<xsl:value-of select="$id"/>
<xsl:text>']/</xsl:text>
<xsl:value-of select="$n"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="(string-length($id) > 0) and (string-length(dyn:evaluate($p)/text()) > 0)">
<xsl:apply-templates select="dyn:evaluate($p)" mode="copy"/>
<xsl:if test="add-de">
<xsl:element name="{$n}">
<xsl:attribute name="lang">de</xsl:attribute>
<!-- translation to be entered here --><xsl:text> </xsl:text>
</xsl:element>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:if test="not(w:pPr/w:pStyle/@w:val='Heading1') and not(w:pPr/w:pStyle/@w:val='Heading2') and not(w:pPr/w:pStyle/@w:val='Heading2first') and not(w:pPr/w:pStyle/@w:val='Heading3') and not(w:pPr/w:pStyle/@w:val='TOC2')">
<xsl:if test="translate(substring(w:r/w:t,1,string-length($attribute)),'ABCDEFGHIJKLMNOPQRSTUVWXYZ ','abcdefghijklmnopqrstuvwxyz-') = translate($attribute,'ABCDEFGHIJKLMNOPQRSTUVWXYZ ','abcdefghijklmnopqrstuvwxyz-')">
<xsl:element name="{$n}">
<xsl:apply-templates select="w:r[position() >= 2]"/>
</xsl:element>
<xsl:if test="add-de">
<xsl:element name="{$n}">
<xsl:attribute name="lang">de</xsl:attribute>
<!-- translation to be entered here --><xsl:text> </xsl:text>
</xsl:element>
</xsl:if>
</xsl:if>
<xsl:apply-templates select="following-sibling::w:p[1]" mode="attribute">
<xsl:with-param name="attribute">
<xsl:value-of select="$attribute"/>
</xsl:with-param>
</xsl:apply-templates>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="w:p" mode="specs">
<xsl:param name="id"/>
<xsl:variable name="p">
<xsl:text>document('../fix/</xsl:text>
<xsl:value-of select="$id"/>
<xsl:text>.xml')/styleguide//*[@id='</xsl:text>
<xsl:value-of select="$id"/>
<xsl:text>']/specs</xsl:text>
</xsl:variable>
<xsl:choose>
<xsl:when test="(string-length($id) > 0) and (string-length(dyn:evaluate($p)/text()) > 0)">
<xsl:apply-templates select="dyn:evaluate($p)" mode="copy"/>
<xsl:if test="add-de">
<xsl:element name="{$n}">
<xsl:attribute name="lang">de</xsl:attribute>
<!-- translation to be entered here --><xsl:text> </xsl:text>
</xsl:element>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="s1">
<xsl:apply-templates select="." mode="specs-recur"/>
</xsl:variable>
<xsl:variable name="s2">
<xsl:value-of select="str:replace($s1,'Vital Statistics:','')"/>
</xsl:variable>
<xsl:variable name="s3">
<xsl:value-of select="str:replace($s2,'::',':')"/>
</xsl:variable>
<xsl:variable name="s4">
<xsl:value-of select="str:replace($s3,'%','')"/>
</xsl:variable>
<xsl:variable name="s5">
<xsl:value-of select="str:replace($s4,'(varies w/ fruit)','')"/>
</xsl:variable>
<xsl:variable name="s">
<xsl:value-of select="str:replace($s5,' ','')"/>
</xsl:variable>
<xsl:if test="string-length($s) > 0">
<xsl:choose>
<xsl:when test="contains($s,'IBUs:')">
<xsl:element name="specs">
<xsl:if test="contains($s,'IBUs:')">
<xsl:element name="ibu">
<xsl:choose>
<xsl:when test="contains(substring-before(substring-after($s5,'IBUs:'),':'),'–')">
<xsl:attribute name="min">
<xsl:value-of select="substring-before(substring-after($s,'IBUs:'),'–')"/>
</xsl:attribute>
<xsl:attribute name="max">
<xsl:value-of select="substring-before(substring-after(substring-after($s,'IBUs:'),'–'),':')"/>
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="normalize-space(substring-before(substring-after($s5,'IBUs:'),':'))"/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:if>
<xsl:if test="contains($s,'SRM:')">
<xsl:element name="srm">
<xsl:choose>
<xsl:when test="contains(substring-before(substring-after($s5,'SRM:'),':'),'–')">
<xsl:attribute name="min">
<xsl:value-of select="substring-before(substring-after($s,'SRM:'),'–')"/>
</xsl:attribute>
<xsl:attribute name="max">
<xsl:value-of select="substring-before(substring-after(substring-after($s,'SRM:'),'–'),':')"/>
</xsl:attribute>
<xsl:attribute name="ebc-min">
<xsl:value-of select="b:srmToEbc(substring-before(substring-after($s,'SRM:'),'–'))"/>
</xsl:attribute>
<xsl:attribute name="ebc-max">
<xsl:value-of select="b:srmToEbc(substring-before(substring-after(substring-after($s,'SRM:'),'–'),':'))"/>
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="normalize-space(substring-before(substring-after($s5,'SRM:'),':'))"/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:if>
<xsl:if test="contains($s,'OG:')">
<xsl:element name="og">
<xsl:choose>
<xsl:when test="contains(substring-before(substring-after($s5,'OG:'),':'),'–')">
<xsl:attribute name="min">
<xsl:value-of select="substring-before(substring-after($s,'OG:'),'–')"/>
</xsl:attribute>
<xsl:attribute name="max">
<xsl:value-of select="substring-before(substring-after(substring-after($s,'OG:'),'–'),':')"/>
</xsl:attribute>
<xsl:attribute name="plato-min">
<xsl:value-of select="b:sgToPlato(substring-before(substring-after($s,'OG:'),'–'))"/>
</xsl:attribute>
<xsl:attribute name="plato-max">
<xsl:value-of select="b:sgToPlato(substring-before(substring-after(substring-after($s,'OG:'),'–'),':'))"/>
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="normalize-space(substring-before(substring-after($s5,'OG:'),':'))"/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:if>
<xsl:if test="contains($s,'FG:')">
<xsl:element name="fg">
<xsl:choose>
<xsl:when test="contains(substring-before(substring-after($s5,'FG:'),':'),'–')">
<xsl:attribute name="min">
<xsl:value-of select="substring-before(substring-after($s,'FG:'),'–')"/>
</xsl:attribute>
<xsl:attribute name="max">
<xsl:value-of select="substring-before(substring-after(substring-after($s,'FG:'),'–'),':')"/>
</xsl:attribute>
<xsl:attribute name="plato-min">
<xsl:value-of select="b:sgToPlato(substring-before(substring-after($s,'FG:'),'–'))"/>
</xsl:attribute>
<xsl:attribute name="plato-max">
<xsl:value-of select="b:sgToPlato(substring-before(substring-after(substring-after($s,'FG:'),'–'),':'))"/>
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="normalize-space(substring-before(substring-after($s5,'FG:'),':'))"/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:if>
<xsl:if test="contains($s,'ABV:')">
<xsl:element name="abv">
<xsl:choose>
<xsl:when test="contains(substring-before(substring-after($s5,'ABV:'),':'),'–')">
<xsl:attribute name="min">
<xsl:value-of select="substring-before(substring-after($s,'ABV:'),'–')"/>
</xsl:attribute>
<xsl:attribute name="max">
<xsl:value-of select="substring-before(substring-after(substring-after($s,'ABV:'),'–'),':')"/>
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="normalize-space(substring-before(substring-after($s5,'ABV:'),':'))"/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:if>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="specs">
<xsl:value-of select="normalize-space(str:replace($s5,':',''))"/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="w:p" mode="specs-recur">
<xsl:if test="not(w:pPr/w:pStyle/@w:val='Heading1') and not(w:pPr/w:pStyle/@w:val='Heading2') and not(w:pPr/w:pStyle/@w:val='Heading2first') and not(w:pPr/w:pStyle/@w:val='Heading3') and not(w:pPr/w:pStyle/@w:val='TOC2') and not(w:r/w:t = 'Strength classifications:')">
<xsl:if test="w:pPr/w:pStyle/@w:val = 'Specs' or w:pPr/w:pStyle/@w:val = 'SpecsLast' or w:r/w:t = 'SRM:' or w:r/w:t = 'IBUs:' or normalize-space(w:r/w:t) = 'Vital Statistics:'">
<xsl:variable name="s">
<xsl:for-each select="w:r/w:t | w:r/w:tab">
<xsl:if test="local-name() = 'tab'">:</xsl:if>
<xsl:value-of select="text()"/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="shack"> <!-- hack for SRM in 33B -->
<xsl:value-of select="str:replace($s,':often','often')"/>
</xsl:variable>
<xsl:value-of select="$shack"/>
<xsl:text>:</xsl:text>
</xsl:if>
<xsl:apply-templates select="following-sibling::w:p[1]" mode="specs-recur"/>
</xsl:if>
</xsl:template>
<xsl:template match="w:p" mode="strengths">
<xsl:param name="id"/>
<xsl:param name="bingo"/>
<xsl:if test="not(w:pPr/w:pStyle/@w:val='Heading1') and not(w:pPr/w:pStyle/@w:val='Heading2') and not(w:pPr/w:pStyle/@w:val='Heading2first') and not(w:pPr/w:pStyle/@w:val='Heading3') and not(w:pPr/w:pStyle/@w:val='TOC2')">
<xsl:choose>
<xsl:when test="w:r/w:t = 'Strength classifications:'">
<xsl:element name="strength-classifications">
<xsl:apply-templates select="following-sibling::w:p[1]" mode="strengths">
<xsl:with-param name="bingo">yes</xsl:with-param>
</xsl:apply-templates>
</xsl:element>
</xsl:when>
<xsl:when test="$bingo">
<xsl:if test="w:pPr/w:pStyle/@w:val = 'Specs' or w:pPr/w:pStyle/@w:val = 'SpecsLast'">
<xsl:variable name="s">
<xsl:for-each select="w:r/w:t | w:r/w:tab">
<xsl:if test="local-name() = 'tab'">:</xsl:if>
<xsl:value-of select="text()"/>
</xsl:for-each>
</xsl:variable>
<xsl:element name="strength">
<xsl:value-of select="$s"/>
</xsl:element>
</xsl:if>
<xsl:apply-templates select="following-sibling::w:p[1]" mode="strengths">
<xsl:with-param name="bingo">yes</xsl:with-param>
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="following-sibling::w:p[1]" mode="strengths"/>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
<xsl:template match="w:p" mode="tags">
<xsl:param name="id"/>
<xsl:if test="not(w:pPr/w:pStyle/@w:val='Heading1') and not(w:pPr/w:pStyle/@w:val='Heading2') and not(w:pPr/w:pStyle/@w:val='Heading2first') and not(w:pPr/w:pStyle/@w:val='Heading3') and not(w:pPr/w:pStyle/@w:val='TOC2')">
<xsl:if test="substring(w:r/w:t,1,4) = 'Tags'">
<xsl:element name="tags">
<xsl:call-template name="tag">
<xsl:with-param name="tags">
<xsl:value-of select="normalize-space(translate(w:r[position() >= 2]/w:t/text(),',',''))"/>
</xsl:with-param>
</xsl:call-template>
</xsl:element>
</xsl:if>
<xsl:apply-templates select="following-sibling::w:p[1]" mode="tags"/>
</xsl:if>
</xsl:template>
<xsl:template name="tag">
<xsl:param name="tags"/>
<xsl:choose>
<xsl:when test="contains($tags, ' ')">
<xsl:element name="tag">
<!-- we have to adjust some tag names -->
<xsl:value-of select="str:replace(str:replace(str:replace(str:replace(str:replace(str:replace(substring-before($tags, ' '),'fermenting','fermented'),'fermentation','fermented'),'any-fermented','any-fermentation'),'session-beer','session-strength'),'sour-ale-family','sour'),'specialty-family','specialty-beer')"/>
</xsl:element>
<xsl:call-template name="tag">
<xsl:with-param name="tags">
<xsl:value-of select="substring-after($tags, ' ')"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:element name="tag">
<xsl:value-of select="$tags"/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="w:r">
<xsl:variable name="t">
<xsl:choose>
<xsl:when test="(position() = 1) and (substring(w:t,1,1) = ' ') and (position() = last()) and (substring(w:t,string-length(w:t),1) = ' ')">
<xsl:value-of select="substring(w:t,2,string-length(w:t)-2)"/>
</xsl:when>
<xsl:when test="(position() = 1) and (substring(w:t,1,1) = ' ')">
<xsl:value-of select="substring(w:t,2)"/>
</xsl:when>
<xsl:when test="(position() = last()) and (substring(w:t,string-length(w:t),1) = ' ')">
<xsl:value-of select="substring(w:t,1,string-length(w:t)-1)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="w:t"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:if test="string-length($t) > 0">
<xsl:choose>
<xsl:when test="w:rPr/w:b[not(@w:val='0')]">
<xsl:element name="b">
<xsl:value-of select="$t"/>
</xsl:element>
</xsl:when>
<xsl:when test="w:rPr/w:u[not(@w:val='0')]">
<xsl:element name="u">
<xsl:value-of select="$t"/>
</xsl:element>
</xsl:when>
<!-- WTF, some ° chars are italic in the original document -->
<xsl:when test="(w:rPr/w:i) and ($t != '°')">
<xsl:element name="i">
<xsl:value-of select="$t"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$t"/>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
<xsl:template match="w:p" mode="in-category">
<xsl:if test="((w:pPr/w:pStyle/@w:val='Heading2') or (w:pPr/w:pStyle/@w:val='Heading2first')) and (w:r/w:t)">
<xsl:variable name="s">
<xsl:for-each select="w:r/w:t">
<xsl:value-of select="text()"/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="title">
<xsl:value-of select="normalize-space($s)"/>
</xsl:variable>
<xsl:call-template name="subcategory">
<xsl:with-param name="title">
<xsl:value-of select="$title"/>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
<xsl:if test="not(w:pPr/w:pStyle/@w:val='Heading1')">
<xsl:apply-templates select="following-sibling::w:p[1]" mode="in-category"/>
</xsl:if>
</xsl:template>
<xsl:template match="w:p" mode="in-subcategory">
<xsl:param name="id"/>
<xsl:if test="((w:pPr/w:pStyle/@w:val='Heading3') or (w:pPr/w:pStyle/@w:val='Heading3first')) and (w:r/w:t)">
<xsl:variable name="s">
<xsl:for-each select="w:r/w:t">
<xsl:value-of select="text()"/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="title">
<xsl:value-of select="normalize-space($s)"/>
</xsl:variable>
<xsl:call-template name="subcategory">
<xsl:with-param name="id">
<xsl:value-of select="$id"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="translate(substring-after($title,': '),'ABCDEFGHIJKLMNOPQRSTUVWXYZ ','abcdefghijklmnopqrstuvwxyz-')"/>
</xsl:with-param>
<xsl:with-param name="title">
<xsl:value-of select="$title"/>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
<xsl:if test="not(w:pPr/w:pStyle/@w:val='Heading1') and not(w:pPr/w:pStyle/@w:val='Heading2')">
<xsl:apply-templates select="following-sibling::w:p[1]" mode="in-subcategory">
<xsl:with-param name="id">
<xsl:value-of select="$id"/>
</xsl:with-param>
</xsl:apply-templates>
</xsl:if>
</xsl:template>
<xsl:template name="style-intro">
<xsl:variable name="nodeset">
<xsl:apply-templates select="following-sibling::w:p[1]" mode="style-intro-recur"/>
</xsl:variable>
<xsl:if test="string-length($nodeset) >= 1">
<xsl:element name="description">
<xsl:apply-templates select="following-sibling::w:p[1]" mode="style-intro-recur"/>
</xsl:element>
</xsl:if>
</xsl:template>
<xsl:template match="w:p" mode="style-intro-recur">
<xsl:if test="not(w:pPr/w:pStyle/@w:val='Heading1') and not(w:pPr/w:pStyle/@w:val='Heading2') and not(w:pPr/w:pStyle/@w:val='Heading2first') and not(w:pPr/w:pStyle/@w:val='Heading3') and not(w:pPr/w:pStyle/@w:val='TOC2')">
<xsl:if test="((w:pPr/w:pStyle/@w:val = 'StyleIntro') or (w:pPr/w:pStyle/@w:val = 'StyleIntroLast')) and (not(w:r/w:t = 'Entry Instructions:'))">
<xsl:element name="p">
<xsl:apply-templates select="w:r"/>
</xsl:element>
<xsl:if test="add-de">
<xsl:element name="p">
<xsl:attribute name="lang">de</xsl:attribute>
<!-- translation to be entered here --><xsl:text> </xsl:text>
</xsl:element>
</xsl:if>
</xsl:if>
<xsl:apply-templates select="following-sibling::w:p[1]" mode="style-intro-recur"/>
</xsl:if>
</xsl:template>
<xsl:template match="w:p | w:tbl" mode="in-chapter">
<xsl:if test="not(w:pPr/w:pStyle/@w:val='Heading1')">
<xsl:choose>
<xsl:when test="local-name(.) = 'tbl'">
<xsl:element name="table">
<xsl:for-each select="w:tr">
<xsl:element name="tr">
<xsl:for-each select="w:tc">
<xsl:element name="td">
<xsl:value-of select="w:p/w:r/w:t"/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</xsl:element>
<xsl:apply-templates select="following-sibling::*[1]" mode="in-chapter"/>
</xsl:when>
<!-- Hack to match Color Reference table -->
<xsl:when test="w:r[1]/w:t='Straw'">
<xsl:element name="table">
<xsl:for-each select="w:r[not(w:tab)]">
<xsl:element name="tr">
<xsl:element name="td">
<xsl:value-of select="w:t"/>
</xsl:element>
<xsl:element name="td">
<xsl:value-of select="following-sibling::w:r[1]/w:t"/>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:element>
<xsl:apply-templates select="following-sibling::*[1]" mode="in-chapter"/>
</xsl:when>
<xsl:when test="w:pPr/w:pStyle/@w:val='ProseListNumbered'">
<xsl:element name="ol">
<xsl:element name="li">
<xsl:apply-templates select="w:r"/>
</xsl:element>
<xsl:apply-templates select="following-sibling::w:p[1]" mode="in-chapter-list"/>
</xsl:element>
<xsl:apply-templates select="following-sibling::*[not(w:pPr/w:pStyle/@w:val='ProseListNumbered')][1]" mode="in-chapter"/>
</xsl:when>
<xsl:when test="w:pPr/w:pStyle/@w:val='ProseList'">
<xsl:element name="ul">
<xsl:element name="li">
<xsl:apply-templates select="w:r"/>
</xsl:element>
<xsl:apply-templates select="following-sibling::w:p[1]" mode="in-chapter-list"/>
</xsl:element>
<xsl:apply-templates select="following-sibling::*[not(w:pPr/w:pStyle/@w:val='ProseList')][1]" mode="in-chapter"/>
</xsl:when>
<xsl:when test="w:pPr/w:pStyle/@w:val='ProseIntro'">
<xsl:element name="p">
<xsl:attribute name="class">intro</xsl:attribute>
<xsl:apply-templates select="w:r"/>
</xsl:element>
<xsl:apply-templates select="following-sibling::*[1]" mode="in-chapter"/>
</xsl:when>
<xsl:when test="w:pPr/w:pStyle/@w:val='ProseBody' and w:r">
<xsl:element name="p">
<xsl:attribute name="class">body</xsl:attribute>
<xsl:apply-templates select="w:r"/>
</xsl:element>
<xsl:apply-templates select="following-sibling::*[1]" mode="in-chapter"/>
</xsl:when>
<xsl:when test="w:pPr/w:pStyle/@w:val='Heading2first' or w:pPr/w:pStyle/@w:val='Heading2'">
<xsl:element name="h3">
<xsl:apply-templates select="w:r"/>
</xsl:element>
<xsl:apply-templates select="following-sibling::*[1]" mode="in-chapter"/>
</xsl:when>
<xsl:when test="w:pPr/w:pStyle/@w:val='Heading3first' or w:pPr/w:pStyle/@w:val='Heading3'">
<xsl:element name="h4">
<xsl:apply-templates select="w:r"/>
</xsl:element>
<xsl:apply-templates select="following-sibling::*[1]" mode="in-chapter"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="following-sibling::*[1]" mode="in-chapter"/>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
<xsl:template match="w:p" mode="in-chapter-list">
<xsl:if test="w:pPr/w:pStyle/@w:val='ProseListNumbered' or w:pPr/w:pStyle/@w:val='ProseList'">
<xsl:element name="li">
<xsl:apply-templates select="w:r"/>
</xsl:element>
<xsl:apply-templates select="following-sibling::w:p[1]" mode="in-chapter-list"/>
</xsl:if>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="normalize-space(.)"/>
</xsl:template>
<xsl:template match="*" mode="copy">
<xsl:element name="{local-name(.)}">
<xsl:apply-templates select="@*" mode="copy"/>
<xsl:apply-templates mode="copy"/>
</xsl:element>
</xsl:template>
<xsl:template match="@* | text()" mode="copy">
<xsl:copy>
<xsl:apply-templates select="@*" mode="copy"/>
<xsl:apply-templates mode="copy"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>