Last active
October 18, 2017 15:32
-
-
Save shaohua/9746058 to your computer and use it in GitHub Desktop.
xhtml-mathml.xsl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!-- | |
| $Id: xhtml-mathml.xsl,v 1.4 2007/05/11 00:58:31 David Carlisle Exp $ | |
| Copyright David Carlisle 2007. | |
| Use and distribution of this code are permitted under the terms of the <a | |
| href="http://www.w3.org/Consortium/Legal/copyright-software-19980720" | |
| >W3C Software Notice and License</a>. | |
| --> | |
| <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" | |
| xmlns:d="data:,dpc" | |
| xmlns:xs="http://www.w3.org/2001/XMLSchema" | |
| xmlns="http://www.w3.org/1999/xhtml" | |
| xmlns:h="http://www.w3.org/1999/xhtml" | |
| xmlns:saxon="http://saxon.sf.net/" | |
| xmlns:mml="http://www.w3.org/1998/Math/MathML" | |
| xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" | |
| exclude-result-prefixes="d h xs saxon m"> | |
| <xsl:import href="file:///Program%20Files/Microsoft%20Office/Office12/OMML2MML.XSL"/> | |
| <!-- <xsl:import href="OMML2MML.XSL"/> --> | |
| <xsl:param name="pmathml" select="'pmathml.xsl'"/> | |
| <xsl:param name="dtd" select="false()"/> | |
| <xsl:output method="xhtml" indent="yes" encoding="US-ASCII"/> | |
| <xsl:template match="/"> | |
| <xsl:if test="$pmathml"> | |
| <xsl:processing-instruction name="xml-stylesheet" | |
| >type="text/xsl" href="<xsl:value-of select="$pmathml"/>"</xsl:processing-instruction> | |
| </xsl:if> | |
| <xsl:if test="$dtd"> | |
| <xsl:text disable-output-escaping="yes"><![CDATA[ | |
| <!DOCTYPE html SYSTEM "]]></xsl:text> | |
| <xsl:value-of select="$dtd"/> | |
| <xsl:text disable-output-escaping="yes"><![CDATA[" [ | |
| <!ENTITY % MATHML.prefixed "INCLUDE" > | |
| <!ENTITY % MATHML.prefix "mml" > | |
| ]> | |
| ]]> | |
| </xsl:text> | |
| </xsl:if> | |
| <xsl:apply-templates/> | |
| </xsl:template> | |
| <xsl:template match="h:*"> | |
| <xsl:element name="{local-name()}"> | |
| <xsl:apply-templates select="@*|node()"/> | |
| </xsl:element> | |
| </xsl:template> | |
| <xsl:template match="@*"> | |
| <xsl:copy-of select=".[namespace-uri(.)=('')]"/> | |
| </xsl:template> | |
| <xsl:template match="comment()[matches(.,'^\[if gte msEquation 12\]><m:oMath(Para)?')]"> | |
| <mml:math> | |
| <xsl:if test="matches(.,'^\[if gte msEquation 12\]><m:oMathPara')"> | |
| <xsl:attribute name="display">block</xsl:attribute> | |
| </xsl:if> | |
| <xsl:variable name="mml" as="element()*"> | |
| <xsl:apply-templates select="saxon:parse( | |
| concat('<x xmlns:m=''http://schemas.openxmlformats.org/officeDocument/2006/math''>', | |
| substring-before(replace(.,'</?span[^<>]*>',''),'<![endif]'), | |
| '</x>'))/x"/> | |
| </xsl:variable> | |
| <xsl:copy-of select="$mml" copy-namespaces="no"/> | |
| </mml:math> | |
| </xsl:template> | |
| <xsl:template match="h:img[../preceding-sibling::node()[1]/self::comment()[matches(.,'^\[if gte msEquation 12\]><m:oMath(Para)?')]]"/> | |
| <!-- that should be it but some bug fixes (reported to MS) in omml2mml.xsl --> | |
| <xsl:template match="m:e | m:den | m:num | m:lim | m:sup | m:sub"> | |
| <xsl:choose> | |
| <!-- If there is no scriptLevel speified, just call through --> | |
| <xsl:when test="not(m:argPr[last()]/m:scrLvl/@m:val)"> | |
| <!-- DPC make sure only one element returned --> | |
| <mml:mrow><xsl:apply-templates select="*" /></mml:mrow> | |
| </xsl:when> | |
| <!-- Otherwise, create an mstyle and set the script level --> | |
| <xsl:otherwise> | |
| <mml:mstyle> | |
| <xsl:attribute name="scriptlevel"> | |
| <xsl:value-of select="m:argPr[last()]/m:scrLvl/@m:val" /> | |
| </xsl:attribute> | |
| <xsl:apply-templates select="*" /> | |
| </mml:mstyle> | |
| </xsl:otherwise> | |
| </xsl:choose> | |
| </xsl:template> | |
| | |
| <!-- avoid printing fnames twice --> | |
| <xsl:template match="m:func"> | |
| <mml:mrow> | |
| <mml:mrow> | |
| <xsl:apply-templates select="m:fName[1]/*" /> | |
| </mml:mrow> | |
| <mml:mo>⁡</mml:mo> | |
| <xsl:apply-templates select="m:fName[1]/following-sibling::*" /> | |
| </mml:mrow> | |
| </xsl:template> | |
| | |
| <!-- m:r reconstituted from Word comments don't have character data in m:t it is directly i m:r (and style information is in interleaved span and i elements, weird but true --> | |
| <xsl:template match="m:r[not(.//m:t)]"> | |
| <xsl:for-each select=".//text()[translate(.,' &','')]"> | |
| <xsl:call-template name="ParseMt"> | |
| <xsl:with-param name="sToParse" select="translate(.,' &','')" /> | |
| <xsl:with-param name="scr" select="../m:rPr[last()]/m:scr/@m:val" /> | |
| <xsl:with-param name="sty" select="../m:rPr[last()]/m:sty/@m:val" /> | |
| <xsl:with-param name="nor" select="../m:rPr[last()]/m:nor/@m:val" /> | |
| </xsl:call-template> | |
| </xsl:for-each> | |
| </xsl:template> | |
| <!-- | |
| MS stylesheet uses DOE which is (a) unevil, (b) non necessary, and (c) breaks the pass through a temporay tree to get rid of namespace nodes. | |
| repeat the templates here without doe (and without double quoting amp) | |
| --> | |
| <xsl:template match="m:nary"> | |
| <xsl:variable name="sLowerCaseSubHide"> | |
| <xsl:choose> | |
| <xsl:when test="count(m:naryPr[last()]/m:subHide) = 0"> | |
| <xsl:text>off</xsl:text> | |
| </xsl:when> | |
| <xsl:otherwise> | |
| <xsl:value-of select="translate(m:naryPr[last()]/m:subHide/@m:val, | |
| 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', | |
| 'abcdefghijklmnopqrstuvwxyz')" /> | |
| </xsl:otherwise> | |
| </xsl:choose> | |
| </xsl:variable> | |
| <xsl:variable name="sLowerCaseSupHide"> | |
| <xsl:choose> | |
| <xsl:when test="count(m:naryPr[last()]/m:supHide) = 0"> | |
| <xsl:text>off</xsl:text> | |
| </xsl:when> | |
| <xsl:otherwise> | |
| <xsl:value-of select="translate(m:naryPr[last()]/m:supHide/@m:val, | |
| 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', | |
| 'abcdefghijklmnopqrstuvwxyz')" /> | |
| </xsl:otherwise> | |
| </xsl:choose> | |
| </xsl:variable> | |
| <xsl:choose> | |
| <xsl:when test="not($sLowerCaseSupHide='off') and | |
| not($sLowerCaseSubHide='off')"> | |
| <mml:mo> | |
| <xsl:choose> | |
| <xsl:when test="not(m:naryPr[last()]/m:chr/@m:val) or | |
| m:naryPr[last()]/m:chr/@m:val=''"> | |
| <xsl:text disable-output-escaping="no">∫</xsl:text> | |
| </xsl:when> | |
| <xsl:otherwise> | |
| <xsl:value-of select="m:naryPr[last()]/m:chr/@m:val" /> | |
| </xsl:otherwise> | |
| </xsl:choose> | |
| </mml:mo> | |
| </xsl:when> | |
| <xsl:when test="not($sLowerCaseSubHide='off')"> | |
| <xsl:choose> | |
| <xsl:when test="m:naryPr[last()]/m:limLoc/@m:val='subSup'"> | |
| <mml:msup> | |
| <mml:mo> | |
| <xsl:choose> | |
| <xsl:when test="not(m:naryPr[last()]/m:chr/@m:val) or | |
| m:naryPr[last()]/m:chr/@m:val=''"> | |
| <xsl:text disable-output-escaping="no">∫</xsl:text> | |
| </xsl:when> | |
| <xsl:otherwise> | |
| <xsl:value-of select="m:naryPr[last()]/m:chr/@m:val" /> | |
| </xsl:otherwise> | |
| </xsl:choose> | |
| </mml:mo> | |
| <xsl:apply-templates select="m:sup[1]" /> | |
| </mml:msup> | |
| </xsl:when> | |
| <xsl:otherwise> | |
| <mml:mover> | |
| <mml:mo> | |
| <xsl:choose> | |
| <xsl:when test="not(m:naryPr[last()]/m:chr/@m:val) or | |
| m:naryPr[last()]/m:chr/@m:val=''"> | |
| <xsl:text disable-output-escaping="no">∫</xsl:text> | |
| </xsl:when> | |
| <xsl:otherwise> | |
| <xsl:value-of select="m:naryPr[last()]/m:chr/@m:val" /> | |
| </xsl:otherwise> | |
| </xsl:choose> | |
| </mml:mo> | |
| <xsl:apply-templates select="m:sup[1]" /> | |
| </mml:mover> | |
| </xsl:otherwise> | |
| </xsl:choose> | |
| </xsl:when> | |
| <xsl:when test="not($sLowerCaseSupHide='off')"> | |
| <xsl:choose> | |
| <xsl:when test="m:naryPr[last()]/m:limLoc/@m:val='subSup'"> | |
| <mml:msub> | |
| <mml:mo> | |
| <xsl:choose> | |
| <xsl:when test="not(m:naryPr[last()]/m:chr/@m:val) or | |
| m:naryPr[last()]/m:chr/@m:val=''"> | |
| <xsl:text disable-output-escaping="no">∫</xsl:text> | |
| </xsl:when> | |
| <xsl:otherwise> | |
| <xsl:value-of select="m:naryPr[last()]/m:chr/@m:val" /> | |
| </xsl:otherwise> | |
| </xsl:choose> | |
| </mml:mo> | |
| <xsl:apply-templates select="m:sub[1]" /> | |
| </mml:msub> | |
| </xsl:when> | |
| <xsl:otherwise> | |
| <mml:munder> | |
| <mml:mo> | |
| <xsl:choose> | |
| <xsl:when test="not(m:naryPr[last()]/m:chr/@m:val) or | |
| m:naryPr[last()]/m:chr/@m:val=''"> | |
| <xsl:text disable-output-escaping="no">∫</xsl:text> | |
| </xsl:when> | |
| <xsl:otherwise> | |
| <xsl:value-of select="m:naryPr[last()]/m:chr/@m:val" /> | |
| </xsl:otherwise> | |
| </xsl:choose> | |
| </mml:mo> | |
| <xsl:apply-templates select="m:sub[1]" /> | |
| </mml:munder> | |
| </xsl:otherwise> | |
| </xsl:choose> | |
| </xsl:when> | |
| <xsl:otherwise> | |
| <xsl:choose> | |
| <xsl:when test="m:naryPr[last()]/m:limLoc/@m:val='subSup'"> | |
| <mml:msubsup> | |
| <mml:mo> | |
| <xsl:choose> | |
| <xsl:when test="not(m:naryPr[last()]/m:chr/@m:val) or | |
| m:naryPr[last()]/m:chr/@m:val=''"> | |
| <xsl:text disable-output-escaping="no">∫</xsl:text> | |
| </xsl:when> | |
| <xsl:otherwise> | |
| <xsl:value-of select="m:naryPr[last()]/m:chr/@m:val" /> | |
| </xsl:otherwise> | |
| </xsl:choose> | |
| </mml:mo> | |
| <xsl:apply-templates select="m:sub[1]" /> | |
| <xsl:apply-templates select="m:sup[1]" /> | |
| </mml:msubsup> | |
| </xsl:when> | |
| <xsl:otherwise> | |
| <mml:munderover> | |
| <mml:mo> | |
| <xsl:choose> | |
| <xsl:when test="not(m:naryPr[last()]/m:chr/@m:val) or | |
| m:naryPr[last()]/m:chr/@m:val=''"> | |
| <xsl:text disable-output-escaping="no">∫</xsl:text> | |
| </xsl:when> | |
| <xsl:otherwise> | |
| <xsl:value-of select="m:naryPr[last()]/m:chr/@m:val" /> | |
| </xsl:otherwise> | |
| </xsl:choose> | |
| </mml:mo> | |
| <xsl:apply-templates select="m:sub[1]" /> | |
| <xsl:apply-templates select="m:sup[1]" /> | |
| </mml:munderover> | |
| </xsl:otherwise> | |
| </xsl:choose> | |
| </xsl:otherwise> | |
| </xsl:choose> | |
| <mml:mrow> | |
| <xsl:apply-templates select="m:e[1]" /> | |
| </mml:mrow> | |
| </xsl:template> | |
| <xsl:template name="CreateGroupChr"> | |
| <xsl:variable name="sLowerCasePos" select="translate(m:groupChrPr[last()]/m:pos/@m:val, | |
| 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', | |
| 'abcdefghijklmnopqrstuvwxyz')" /> | |
| <xsl:choose> | |
| <xsl:when test="$sLowerCasePos!='top' or | |
| not(m:groupChrPr[last()]/m:pos/@m:val) or | |
| m:groupChrPr[last()]/m:pos/@m:val=''"> | |
| <mml:munder> | |
| <xsl:apply-templates select="m:e[1]" /> | |
| <mml:mo> | |
| <xsl:choose> | |
| <xsl:when test="string-length(m:groupChrPr[last()]/m:chr/@m:val) >= 1"> | |
| <xsl:value-of select="substring(m:groupChrPr[last()]/m:chr/@m:val,1,1)" /> | |
| </xsl:when> | |
| <xsl:otherwise> | |
| <xsl:text disable-output-escaping="no">⏟</xsl:text> | |
| </xsl:otherwise> | |
| </xsl:choose> | |
| </mml:mo> | |
| </mml:munder> | |
| </xsl:when> | |
| <xsl:otherwise> | |
| <mml:mover> | |
| <xsl:apply-templates select="m:e[1]" /> | |
| <mml:mo> | |
| <xsl:choose> | |
| <xsl:when test="string-length(m:groupChrPr[last()]/m:chr/@m:val) >= 1"> | |
| <xsl:value-of select="substring(m:groupChrPr[last()]/m:chr/@m:val,1,1)" /> | |
| </xsl:when> | |
| <xsl:otherwise> | |
| <xsl:text disable-output-escaping="no">⏟</xsl:text> | |
| </xsl:otherwise> | |
| </xsl:choose> | |
| </mml:mo> | |
| </mml:mover> | |
| </xsl:otherwise> | |
| </xsl:choose> | |
| </xsl:template> | |
| | |
| <xsl:template match="m:bar"> | |
| <xsl:variable name="sLowerCasePos" select="translate(m:barPr/m:pos/@m:val, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', | |
| 'abcdefghijklmnopqrstuvwxyz')" /> | |
| <xsl:choose> | |
| <xsl:when test="$sLowerCasePos!='bot' or | |
| not($sLowerCasePos) or | |
| $sLowerCasePos='' "> | |
| <mml:mover> | |
| <xsl:attribute name="accent">true</xsl:attribute> | |
| <xsl:apply-templates select="m:e[1]" /> | |
| <mml:mo> | |
| <xsl:text disable-output-escaping="no">¯</xsl:text> | |
| </mml:mo> | |
| </mml:mover> | |
| </xsl:when> | |
| <xsl:otherwise> | |
| <mml:munder> | |
| <xsl:apply-templates select="m:e[1]" /> | |
| <mml:mo> | |
| <xsl:text disable-output-escaping="no">̲</xsl:text> | |
| </mml:mo> | |
| </mml:munder> | |
| </xsl:otherwise> | |
| </xsl:choose> | |
| </xsl:template> | |
| <!-- wrong name for (m)phantom --> | |
| | |
| <xsl:template match="m:phant"> | |
| <xsl:variable name="sLowerCaseWidth" select="translate(m:phantPr[last()]/m:width/@m:val, | |
| 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', | |
| 'abcdefghijklmnopqrstuvwxyz')" /> | |
| <xsl:variable name="sLowerCaseAsc" select="translate(m:phantPr[last()]/m:asc/@m:val, | |
| 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', | |
| 'abcdefghijklmnopqrstuvwxyz')" /> | |
| <xsl:variable name="sLowerCaseDec" select="translate(m:phantPr[last()]/m:dec/@m:val, | |
| 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', | |
| 'abcdefghijklmnopqrstuvwxyz')" /> | |
| <xsl:if test="not($sLowerCaseWidth='off' and | |
| $sLowerCaseAsc='off' and | |
| $sLowerCaseDec='off')"> | |
| <mml:mphantom> | |
| <xsl:apply-templates select="m:e[1]" /> | |
| </mml:mphantom> | |
| </xsl:if> | |
| </xsl:template> | |
| <!-- html fixes --> | |
| <xsl:template match="h:style"> | |
| <style type="text/css"> | |
| <xsl:copy-of select="@*"/> | |
| <xsl:apply-templates/> | |
| </style> | |
| </xsl:template> | |
| <xsl:template match="@lang"> | |
| <xsl:attribute name="xml:lang" select="."/> | |
| </xsl:template> | |
| <xsl:template match="@style[../(@align|@width|@clear|@nowrap|@height)]" priority="2"/> | |
| <xsl:template match="@align"> | |
| <xsl:attribute name="style"> | |
| <xsl:value-of select="../@style,concat('text-align: ',.)" separator=";"/> | |
| </xsl:attribute> | |
| </xsl:template> | |
| <xsl:template match="@width"> | |
| <xsl:attribute name="style"> | |
| <xsl:value-of select="../@style,concat('text-width: ',.)" separator=";"/> | |
| </xsl:attribute> | |
| </xsl:template> | |
| <xsl:template match="@height"> | |
| <xsl:attribute name="style"> | |
| <xsl:value-of select="../@style,concat('height: ',.)" separator=";"/> | |
| </xsl:attribute> | |
| </xsl:template> | |
| <xsl:template match="@clear"> | |
| <xsl:attribute name="style"> | |
| <xsl:value-of select="../@style,concat('clear: ',if(.='all') then 'both' else .)" separator=";"/> | |
| </xsl:attribute> | |
| </xsl:template> | |
| <xsl:template match="@nowrap"> | |
| <xsl:attribute name="style"> | |
| <xsl:value-of select="../@style,'white-space:nowrap'" separator=";"/> | |
| </xsl:attribute> | |
| </xsl:template> | |
| <xsl:template match="h:head[not(h:title)]"> | |
| <head> | |
| <xsl:copy-of select="@*"/> | |
| <title><xsl:value-of select="../h:body/descendant::*[self::h:h1|self::h2][1]"/></title> | |
| <xsl:apply-templates/> | |
| </head> | |
| </xsl:template> | |
| <xsl:template match="h:link/@target"/> | |
| <xsl:template match="h:table[h:tr and not(h:tbody)]"> | |
| <table> | |
| <xsl:copy-of select="@*"/> | |
| <xsl:apply-templates select="* except h:tr"/> | |
| <tbody> | |
| <xsl:apply-templates select="h:tr"/> | |
| </tbody> | |
| </table> | |
| </xsl:template> | |
| <xsl:template match="h:span[not(node()[2])]" priority="2"> | |
| <xsl:apply-templates/> | |
| </xsl:template> | |
| <xsl:template match="h:table[not(@*)]" priority="3"/> | |
| <xsl:template match="h:tr" priority="3"> | |
| <xsl:message> | |
| [<xsl:copy-of select="ancestor::h:table[1]/following-sibling::*[not(self::h:span[not(normalize-space())])][1]"/>] | |
| </xsl:message> | |
| <tr> | |
| <xsl:copy-of select="@*"/> | |
| <xsl:apply-templates select="h:td"/> | |
| <xsl:apply-templates select="ancestor::h:table[1]/following-sibling::*[not(self::h:span[not(normalize-space())])][1]//h:tr[not(@style)]" mode="tr"/> | |
| </tr> | |
| <xsl:apply-templates select="ancestor::h:table[1]/following-sibling::*[not(self::h:span[not(normalize-space())]) | |
| and not(self::h:table/h:tbody/h:tr[not(@style)])][1]//h:tr[@style]"/> | |
| </xsl:template> | |
| <xsl:template match="h:tr" priority="3" mode="tr"> | |
| <xsl:apply-templates select="h:td"/> | |
| <xsl:apply-templates select="ancestor::h:table[1]/following-sibling::*[not(self::h:span[not(normalize-space())])][1]//h:tr[not(@style)]" mode="tr"/> | |
| </xsl:template> | |
| </xsl:stylesheet> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment