| Server IP : 121.121.20.254 / Your IP : 216.73.217.109 Web Server : Microsoft-IIS/10.0 System : Windows NT WEB-SERVER 10.0 build 20348 (Windows Server 2022) AMD64 User : IUSR ( 0) PHP Version : 8.3.28 Disable Function : NONE MySQL : ON | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : C:/Program Files/Microsoft Office/root/Office16/ |
Upload File : |
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1998/Math/MathML"
xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" exclude-result-prefixes="m">
<xsl:output method="xml" encoding="UTF-16" />
<!-- %% Global Definitions -->
<!-- Every single unicode character that is recognized by OMML as an operator -->
<xsl:variable name="sOperators"
select="concat(
'¨!"#&()+,-./:',
';<=>?@[\]^_`{',
'|}~¡¦¬¯°±²³´·¹¿',
'×~÷ˇ˘˙˜˝̀́̂̃̄̅̆̇̈̉',
'̊̋̌̍̎̏̐̑̒̓̔̕',
'̡̛̖̗̘̙̜̝̞̟̠̚',
'̢̧̨̣̤̥̦̩̪̫̬̭',
'̴̵̶̷̸̮̯̰̱̲̳̿',
'         ‐‒–',
'—‖†‡•․‥…′″‴‼',
'⁀⁄⁎⁏⁐⁗⁡⁢⁣⁰⁴⁵',
'⁶⁷⁸⁹⁺⁻⁼⁽⁾₀₁₂',
'₃₄₅₆₇₈₉₊₋₌₍₎',
'⃒⃓⃘⃙⃚⃐⃑⃔⃕⃖⃗⃛',
'⃜⃝⃞⃟⃠⃡⃤⃥⃦⃨⃧⃩',
'⃪⅀ⅆ←↑→↓↔↕↖↗↘↙',
'↚↛↜↝↞↟↠↡↢↣↤↥',
'↦↧↨↩↪↫↬↭↮↯↰↱',
'↲↳↶↷↺↻↼↽↾↿⇀⇁',
'⇂⇃⇄⇅⇆⇇⇈⇉⇊⇋⇌⇍',
'⇎⇏⇐⇑⇒⇓⇔⇕⇖⇗⇘⇙',
'⇚⇛⇜⇝⇞⇟⇠⇡⇢⇣⇤⇥',
'⇦⇧⇨⇩⇳⇴⇵⇶⇷⇸⇹⇺',
'⇻⇼⇽⇾⇿∀∁∂∃∄∆∇',
'∈∉∊∋∌∍∏∐∑−∓∔',
'∕∖∗∘∙√∛∜∝∣∤∥',
'∦∧∨∩∪∫∬∭∮∯∰∱',
'∲∳∴∵∶∷∸∹∺∻∼∽',
'∾≀≁≂≃≄≅≆≇≈≉≊',
'≋≌≍≎≏≐≑≒≓≔≕≖',
'≗≘≙≚≛≜≝≞≟≠≡≢',
'≣≤≥≦≧≨≩≪≫≬≭≮',
'≯≰≱≲≳≴≵≶≷≸≹≺',
'≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆',
'⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒',
'⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊝⊞',
'⊟⊠⊡⊢⊣⊥⊦⊧⊨⊩⊪⊫',
'⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷',
'⊸⊹⊺⊻⊼⊽⋀⋁⋂⋃⋄⋅',
'⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑',
'⋒⋓⋔⋕⋖⋗⋘⋙⋚⋛⋜⋝',
'⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩',
'⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵',
'⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿⌅⌆',
'⌈⌉⌊⌋⌜⌝⌞⌟⌢⌣〈〉',
'⌽⌿⎰⎱⏜⏝⏞⏟⏠│├┤',
'┬┴▁█▒■□▭▲△▴▵',
'▶▷▸▹▼▽▾▿◀◁◂◃',
'◄◅◊○◦◫◬◸◹◺◻◼',
'◽◾◿★☆❲❳⟑⟒⟓⟔⟕',
'⟖⟗⟘⟙⟚⟛⟜⟝⟞⟟⟠⟡',
'⟢⟣⟤⟥⟦⟧⟨⟩⟪⟫⟰⟱',
'⟲⟳⟴⟵⟶⟷⟸⟹⟺⟻⟼⟽',
'⟾⟿⤀⤁⤂⤃⤄⤅⤆⤇⤈⤉',
'⤊⤋⤌⤍⤎⤏⤐⤑⤒⤓⤔⤕',
'⤖⤗⤘⤙⤚⤛⤜⤝⤞⤟⤠⤡',
'⤢⤣⤤⤥⤦⤧⤨⤩⤪⤫⤬⤭',
'⤮⤯⤰⤱⤲⤳⤴⤵⤶⤷⤸⤹',
'⤺⤻⤼⤽⤾⤿⥀⥁⥂⥃⥄⥅',
'⥆⥇⥈⥉⥊⥋⥌⥍⥎⥏⥐⥑',
'⥒⥓⥔⥕⥖⥗⥘⥙⥚⥛⥜⥝',
'⥞⥟⥠⥡⥢⥣⥤⥥⥦⥧⥨⥩',
'⥪⥫⥬⥭⥮⥯⥰⥱⥲⥳⥴⥵',
'⥶⥷⥸⥹⥺⥻⥼⥽⥾⥿⦀⦂',
'⦃⦄⦅⦆⦇⦈⦉⦊⦋⦌⦍⦎',
'⦏⦐⦑⦒⦓⦔⦕⦖⦗⦘⦙⦚',
'⦶⦷⦸⦹⧀⧁⧄⧅⧆⧇⧈⧎',
'⧏⧐⧑⧒⧓⧔⧕⧖⧗⧘⧙⧚',
'⧛⧟⧡⧢⧣⧤⧥⧦⧫⧴⧵⧶',
'⧷⧸⧹⧺⧻⧼⧽⧾⧿⨀⨁⨂',
'⨃⨄⨅⨆⨇⨈⨉⨊⨋⨌⨍⨎',
'⨏⨐⨑⨒⨓⨔⨕⨖⨗⨘⨙⨚',
'⨛⨜⨝⨞⨟⨠⨡⨢⨣⨤⨥⨦',
'⨧⨨⨩⨪⨫⨬⨭⨮⨯⨰⨱⨲',
'⨳⨴⨵⨶⨷⨸⨹⨺⨻⨼⨽⨾',
'⨿⩀⩁⩂⩃⩄⩅⩆⩇⩈⩉⩊',
'⩋⩌⩍⩎⩏⩐⩑⩒⩓⩔⩕⩖',
'⩗⩘⩙⩚⩛⩜⩝⩞⩟⩠⩡⩢',
'⩣⩤⩥⩦⩧⩨⩩⩪⩫⩬⩭⩮',
'⩯⩰⩱⩲⩳⩴⩵⩶⩷⩸⩹⩺',
'⩻⩼⩽⩾⩿⪀⪁⪂⪃⪄⪅⪆',
'⪇⪈⪉⪊⪋⪌⪍⪎⪏⪐⪑⪒',
'⪓⪔⪕⪖⪗⪘⪙⪚⪛⪜⪝⪞',
'⪟⪠⪡⪢⪣⪤⪥⪦⪧⪨⪩⪪',
'⪫⪬⪭⪮⪯⪰⪱⪲⪳⪴⪵⪶',
'⪷⪸⪹⪺⪻⪼⪽⪾⪿⫀⫁⫂',
'⫃⫄⫅⫆⫇⫈⫉⫊⫋⫌⫍⫎',
'⫏⫐⫑⫒⫓⫔⫕⫖⫗⫘⫙⫚',
'⫛⫝̸⫝⫞⫟⫠⫢⫣⫤⫥⫦⫧',
'⫨⫩⫪⫫⫬⫭⫮⫯⫰⫲⫳⫴',
'⫵⫶⫷⫸⫹⫺⫻⫼⫽⫾⫿⬄',
'⬆⬇⬌⬍〔〕〖〗〘〙!&',
'()+,-./:;<=>',
'?@[\]^_{|}')" />
<!-- A string of '-'s repeated exactly as many times as the operators above -->
<xsl:variable name="sMinuses">
<xsl:call-template name="SRepeatChar">
<xsl:with-param name="cchRequired" select="string-length($sOperators)" />
<xsl:with-param name="ch" select="'-'" />
</xsl:call-template>
</xsl:variable>
<!-- Every single unicode character that is recognized by OMML as a number -->
<xsl:variable name="sNumbers" select="'0123456789'" />
<!-- A string of '0's repeated exactly as many times as the list of numbers above -->
<xsl:variable name="sZeros">
<xsl:call-template name="SRepeatChar">
<xsl:with-param name="cchRequired" select="string-length($sNumbers)" />
<xsl:with-param name="ch" select="'0'" />
</xsl:call-template>
</xsl:variable>
<!-- %% Math Alphanumeric Lookup Tables
52 math-alphanumeric characters (A-Z, a-z) per
variant. SMP chars are UTF-16 surrogate pairs in
.NET (string-length=2 each). BMP exceptions
count as 1. Use position-based substring(). -->
<xsl:variable name="sUpperAlpha"
select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
<xsl:variable name="sLowerAlpha"
select="'abcdefghijklmnopqrstuvwxyz'" />
<!-- Math Bold: U+1D400 (A-Z), U+1D41A (a-z) -->
<xsl:variable name="s_math_bold"
select="concat(
'𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉',
'𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓',
'𝐔𝐕𝐖𝐗𝐘𝐙𝐚𝐛𝐜𝐝',
'𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧',
'𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱',
'𝐲𝐳'
)" />
<!-- Math Italic: U+1D434 (A-Z, a-z). BMP: h=U+210E -->
<xsl:variable name="s_math_italic"
select="concat(
'𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽',
'𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇',
'𝑈𝑉𝑊𝑋𝑌𝑍𝑎𝑏𝑐𝑑',
'𝑒𝑓𝑔ℎ𝑖𝑗𝑘𝑙𝑚𝑛',
'𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥',
'𝑦𝑧'
)" />
<!-- Math Bold Italic: U+1D468 (A-Z, a-z) -->
<xsl:variable name="s_math_bold_italic"
select="concat(
'𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱',
'𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻',
'𝑼𝑽𝑾𝑿𝒀𝒁𝒂𝒃𝒄𝒅',
'𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏',
'𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙',
'𝒚𝒛'
)" />
<!-- Math Script (A-Z, a-z). BMP: B E F H I L M R e g o -->
<xsl:variable name="s_math_script"
select="concat(
'𝒜ℬ𝒞𝒟ℰℱ𝒢ℋℐ𝒥',
'𝒦ℒℳ𝒩𝒪𝒫𝒬ℛ𝒮𝒯',
'𝒰𝒱𝒲𝒳𝒴𝒵𝒶𝒷𝒸𝒹',
'ℯ𝒻ℊ𝒽𝒾𝒿𝓀𝓁𝓂𝓃',
'ℴ𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍',
'𝓎𝓏'
)" />
<!-- Math Bold Script: U+1D4D0 (A-Z, a-z) -->
<xsl:variable name="s_math_bold_script"
select="concat(
'𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙',
'𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣',
'𝓤𝓥𝓦𝓧𝓨𝓩𝓪𝓫𝓬𝓭',
'𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷',
'𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁',
'𝔂𝔃'
)" />
<!-- Math Fraktur (A-Z, a-z). BMP: C H I R Z -->
<xsl:variable name="s_math_fraktur"
select="concat(
'𝔄𝔅ℭ𝔇𝔈𝔉𝔊ℌℑ𝔍',
'𝔎𝔏𝔐𝔑𝔒𝔓𝔔ℜ𝔖𝔗',
'𝔘𝔙𝔚𝔛𝔜ℨ𝔞𝔟𝔠𝔡',
'𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫',
'𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵',
'𝔶𝔷'
)" />
<!-- Math Bold Fraktur: U+1D56C (A-Z, a-z) -->
<xsl:variable name="s_math_bold_fraktur"
select="concat(
'𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵',
'𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿',
'𝖀𝖁𝖂𝖃𝖄𝖅𝖆𝖇𝖈𝖉',
'𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓',
'𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝',
'𝖞𝖟'
)" />
<!-- Math Double-Struck (A-Z, a-z). BMP: C H N P Q R Z -->
<xsl:variable name="s_math_double_struck"
select="concat(
'𝔸𝔹ℂ𝔻𝔼𝔽𝔾ℍ𝕀𝕁',
'𝕂𝕃𝕄ℕ𝕆ℙℚℝ𝕊𝕋',
'𝕌𝕍𝕎𝕏𝕐ℤ𝕒𝕓𝕔𝕕',
'𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟',
'𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩',
'𝕪𝕫'
)" />
<!-- Math Sans-Serif: U+1D5A0 (A-Z, a-z) -->
<xsl:variable name="s_math_sans_serif"
select="concat(
'𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩',
'𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳',
'𝖴𝖵𝖶𝖷𝖸𝖹𝖺𝖻𝖼𝖽',
'𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇',
'𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑',
'𝗒𝗓'
)" />
<!-- Math Bold Sans-Serif: U+1D5D4 (A-Z, a-z) -->
<xsl:variable name="s_math_bold_sans_serif"
select="concat(
'𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝',
'𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧',
'𝗨𝗩𝗪𝗫𝗬𝗭𝗮𝗯𝗰𝗱',
'𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻',
'𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅',
'𝘆𝘇'
)" />
<!-- Math Sans-Serif Italic: U+1D608 (A-Z, a-z) -->
<xsl:variable name="s_math_sans_serif_italic"
select="concat(
'𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑',
'𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛',
'𝘜𝘝𝘞𝘟𝘠𝘡𝘢𝘣𝘤𝘥',
'𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯',
'𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹',
'𝘺𝘻'
)" />
<!-- Sans-Serif Bold Italic: U+1D63C (A-Z, a-z) -->
<xsl:variable name="s_math_sans_serif_bold_italic"
select="concat(
'𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅',
'𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏',
'𝙐𝙑𝙒𝙓𝙔𝙕𝙖𝙗𝙘𝙙',
'𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣',
'𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭',
'𝙮𝙯'
)" />
<!-- Math Monospace: U+1D670 (A-Z, a-z) -->
<xsl:variable name="s_math_monospace"
select="concat(
'𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹',
'𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃',
'𝚄𝚅𝚆𝚇𝚈𝚉𝚊𝚋𝚌𝚍',
'𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗',
'𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡',
'𝚢𝚣'
)" />
<!-- %%Template: SReplace
Replace all occurences of sOrig in sInput with sReplacement
and return the resulting string. -->
<xsl:template name="SReplace">
<xsl:param name="sInput" />
<xsl:param name="sOrig" />
<xsl:param name="sReplacement" />
<xsl:choose>
<xsl:when test="not(contains($sInput, $sOrig))">
<xsl:value-of select="$sInput" />
</xsl:when>
<xsl:otherwise>
<xsl:variable name="sBefore" select="substring-before($sInput, $sOrig)" />
<xsl:variable name="sAfter" select="substring-after($sInput, $sOrig)" />
<xsl:variable name="sAfterProcessed">
<xsl:call-template name="SReplace">
<xsl:with-param name="sInput" select="$sAfter" />
<xsl:with-param name="sOrig" select="$sOrig" />
<xsl:with-param name="sReplacement" select="$sReplacement" />
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="concat($sBefore, concat($sReplacement, $sAfterProcessed))" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Templates -->
<xsl:template match="/m:oMathPara">
<math display="block">
<xsl:apply-templates select="*" />
</math>
</xsl:template>
<xsl:template match="/*[not(self::m:oMathPara)]">
<math>
<xsl:apply-templates select="*" />
</math>
</xsl:template>
<xsl:template match="m:borderBox">
<!-- Get Lowercase versions of properties -->
<xsl:variable name="sLowerCaseHideTop" select="translate(m:borderBoxPr[last()]/m:hideTop[last()]/@m:val, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:variable name="sLowerCaseHideBot" select="translate(m:borderBoxPr[last()]/m:hideBot[last()]/@m:val, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:variable name="sLowerCaseHideLeft" select="translate(m:borderBoxPr[last()]/m:hideLeft[last()]/@m:val, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:variable name="sLowerCaseHideRight" select="translate(m:borderBoxPr[last()]/m:hideRight[last()]/@m:val, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:variable name="sLowerCaseStrikeH" select="translate(m:borderBoxPr[last()]/m:strikeH[last()]/@m:val, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:variable name="sLowerCaseStrikeV" select="translate(m:borderBoxPr[last()]/m:strikeV[last()]/@m:val, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:variable name="sLowerCaseStrikeBLTR" select="translate(m:borderBoxPr[last()]/m:strikeBLTR[last()]/@m:val, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:variable name="sLowerCaseStrikeTLBR" select="translate(m:borderBoxPr[last()]/m:strikeTLBR[last()]/@m:val, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:variable name="fHideTop">
<xsl:call-template name="ForceTrueStrVal">
<xsl:with-param name="str" select="$sLowerCaseHideTop" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="fHideBot">
<xsl:call-template name="ForceTrueStrVal">
<xsl:with-param name="str" select="$sLowerCaseHideBot" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="fHideLeft">
<xsl:call-template name="ForceTrueStrVal">
<xsl:with-param name="str" select="$sLowerCaseHideLeft" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="fHideRight">
<xsl:call-template name="ForceTrueStrVal">
<xsl:with-param name="str" select="$sLowerCaseHideRight" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="fStrikeH">
<xsl:call-template name="ForceTrueStrVal">
<xsl:with-param name="str" select="$sLowerCaseStrikeH" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="fStrikeV">
<xsl:call-template name="ForceTrueStrVal">
<xsl:with-param name="str" select="$sLowerCaseStrikeV" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="fStrikeBLTR">
<xsl:call-template name="ForceTrueStrVal">
<xsl:with-param name="str" select="$sLowerCaseStrikeBLTR" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="fStrikeTLBR">
<xsl:call-template name="ForceTrueStrVal">
<xsl:with-param name="str" select="$sLowerCaseStrikeTLBR" />
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$fHideTop=1
and $fHideBot=1
and $fHideLeft=1
and $fHideRight=1
and $fStrikeH=0
and $fStrikeV=0
and $fStrikeBLTR=0
and $fStrikeTLBR=0">
<mrow>
<xsl:apply-templates select="m:e[1]" />
</mrow>
</xsl:when>
<xsl:otherwise>
<menclose>
<xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
<xsl:with-param name="fHideTop" select="$fHideTop" />
<xsl:with-param name="fHideBot" select="$fHideBot" />
<xsl:with-param name="fHideLeft" select="$fHideLeft" />
<xsl:with-param name="fHideRight" select="$fHideRight" />
<xsl:with-param name="fStrikeH" select="$fStrikeH" />
<xsl:with-param name="fStrikeV" select="$fStrikeV" />
<xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
<xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
</xsl:call-template>
<xsl:apply-templates select="m:e[1]" />
</menclose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="*">
<xsl:apply-templates select="*" />
</xsl:template>
<!--
{ Non-combining, Upper-combining, Lower-combining }
{U+02D8, U+0306, U+032E}, // BREVE
{U+00B8, U+0312, U+0327}, // CEDILLA
{U+0060, U+0300, U+0316}, // GRAVE ACCENT
{U+002D, U+0305, U+0332}, // HYPHEN-MINUS/OVERLINE
{U+2212, U+0305, U+0332}, // MINUS SIGN/OVERLINE
{U+002E, U+0305, U+0323}, // FULL STOP/DOT ABOVE
{U+02D9, U+0307, U+0323}, // DOT ABOVE
{U+02DD, U+030B, U+02DD}, // DOUBLE ACUTE ACCENT
{U+00B4, U+0301, U+0317}, // ACUTE ACCENT
{U+007E, U+0303, U+0330}, // TILDE
{U+02DC, U+0303, U+0330}, // SMALL TILDE
{U+00A8, U+0308, U+0324}, // DIAERESIS
{U+02C7, U+030C, U+032C}, // CARON
{U+005E, U+0302, U+032D}, // CIRCUMFLEX ACCENT
{U+00AF, U+0305, ::::::}, // MACRON
{U+005F, ::::::, U+0332}, // LOW LINE
{U+2192, U+20D7, U+20EF}, // RIGHTWARDS ARROW
{U+27F6, U+20D7, U+20EF}, // LONG RIGHTWARDS ARROW
{U+2190, U+20D6, U+20EE}, // LEFT ARROW
-->
<xsl:template name="ToNonCombining">
<xsl:param name="ch" />
<xsl:choose>
<!-- BREVE -->
<xsl:when test="$ch='̆' or $ch='̮'">˘</xsl:when>
<!-- CEDILLA -->
<xsl:when test="$ch='̒' or $ch='̧'">¸</xsl:when>
<!-- GRAVE ACCENT -->
<xsl:when test="$ch='̀' or $ch='̖'">`</xsl:when>
<!-- HYPHEN-MINUS/OVERLINE -->
<xsl:when test="$ch='̅' or $ch='̲'">-</xsl:when>
<!-- MINUS SIGN/OVERLINE -->
<xsl:when test="$ch='̅' or $ch='̲'">−</xsl:when>
<!-- FULL STOP/DOT ABOVE -->
<xsl:when test="$ch='̅' or $ch='̣'">.</xsl:when>
<!-- DOT ABOVE -->
<xsl:when test="$ch='̇' or $ch='̣'">˙</xsl:when>
<!-- DOUBLE ACUTE ACCENT -->
<xsl:when test="$ch='̋' or $ch='˝'">˝</xsl:when>
<!-- ACUTE ACCENT -->
<xsl:when test="$ch='́' or $ch='̗'">´</xsl:when>
<!-- TILDE -->
<xsl:when test="$ch='̃' or $ch='̰'">~</xsl:when>
<!-- SMALL TILDE -->
<xsl:when test="$ch='̃' or $ch='̰'">˜</xsl:when>
<!-- DIAERESIS -->
<xsl:when test="$ch='̈' or $ch='̤'">¨</xsl:when>
<!-- CARON -->
<xsl:when test="$ch='̌' or $ch='̬'">ˇ</xsl:when>
<!-- CIRCUMFLEX ACCENT -->
<xsl:when test="$ch='̂' or $ch='̭'">^</xsl:when>
<!-- MACRON -->
<xsl:when test="$ch='̅' ">¯</xsl:when>
<!-- LOW LINE -->
<xsl:when test=" $ch='̲'">_</xsl:when>
<!-- RIGHTWARDS ARROW -->
<xsl:when test="$ch='⃗' or $ch='⃯'">→</xsl:when>
<!-- LONG RIGHTWARDS ARROW -->
<xsl:when test="$ch='⃗' or $ch='⃯'">⟶</xsl:when>
<!-- LEFT ARROW -->
<xsl:when test="$ch='⃖' or $ch='⃮'">←</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$ch"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="m:acc">
<mover>
<xsl:attribute name="accent">true</xsl:attribute>
<mrow>
<xsl:apply-templates select="m:e[1]" />
</mrow>
<xsl:variable name="chAcc">
<xsl:choose>
<xsl:when test="not(m:accPr[last()]/m:chr)">
<xsl:value-of select="'̂'" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring(m:accPr/m:chr/@m:val,1,1)" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="chNonComb">
<xsl:call-template name="ToNonCombining">
<xsl:with-param name="ch" select="$chAcc" />
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="string-length($chAcc)=0">
<mo/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="ParseMt">
<xsl:with-param name="sToParse" select="$chNonComb" />
<xsl:with-param name="scr" select="m:e[1]/*/m:rPr[last()]/m:scr/@m:val" />
<xsl:with-param name="sty" select="m:e[1]/*/m:rPr[last()]/m:sty/@m:val" />
<xsl:with-param name="nor">
<xsl:choose>
<xsl:when test="count(m:e[1]/*/m:rPr[last()]/m:nor) = 0">0</xsl:when>
<xsl:otherwise>
<xsl:call-template name="ForceFalseStrVal">
<xsl:with-param name="str" select="translate(m:e[1]/*/m:rPr[last()]/m:nor/@m:val,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</mover>
</xsl:template>
<xsl:template name="OutputScript">
<xsl:param name="ndCur" select="." />
<xsl:choose>
<!-- Only output contents of $ndCur if $ndCur exists
and $ndCur has children -->
<xsl:when test="count($ndCur/*) > 0">
<mrow>
<xsl:apply-templates select="$ndCur" />
</mrow>
</xsl:when>
<xsl:otherwise>
<none />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="m:sPre">
<mmultiscripts>
<mrow>
<xsl:apply-templates select="m:e[1]" />
</mrow>
<mprescripts />
<xsl:call-template name="OutputScript">
<xsl:with-param name="ndCur" select="m:sub[1]"/>
</xsl:call-template>
<xsl:call-template name="OutputScript">
<xsl:with-param name="ndCur" select="m:sup[1]" />
</xsl:call-template>
</mmultiscripts>
</xsl:template>
<xsl:template match="m:m">
<mtable>
<xsl:call-template name="CreateMathMLMatrixAttr">
<xsl:with-param name="mcJc" select="m:mPr[last()]/m:mcs/m:mc/m:mcPr[last()]/m:mcJc/@m:val" />
</xsl:call-template>
<xsl:for-each select="m:mr">
<mtr>
<xsl:for-each select="m:e">
<mtd>
<xsl:apply-templates select="." />
</mtd>
</xsl:for-each>
</mtr>
</xsl:for-each>
</mtable>
</xsl:template>
<xsl:template name="CreateMathMLMatrixAttr">
<xsl:param name="mcJc" />
<xsl:variable name="sLowerCaseMcjc" select="translate($mcJc, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:choose>
<xsl:when test="$sLowerCaseMcjc='left'">
<xsl:attribute name="columnalign">left</xsl:attribute>
</xsl:when>
<xsl:when test="$sLowerCaseMcjc='right'">
<xsl:attribute name="columnalign">right</xsl:attribute>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="m:phant">
<xsl:variable name="sLowerCaseZeroWidVal" select="translate(m:phantPr[last()]/m:zeroWid[last()]/@m:val,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:variable name="sLowerCaseZeroAscVal" select="translate(m:phantPr[last()]/m:zeroAsc[last()]/@m:val,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:variable name="sLowerCaseZeroDescVal" select="translate(m:phantPr[last()]/m:zeroDesc[last()]/@m:val,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:variable name="sLowerCaseShowVal" select="translate(m:phantPr[last()]/m:show[last()]/@m:val,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<!-- The following properties default to 'yes' unless the last value equals 'no' or there isn't any node for
the property -->
<xsl:variable name="fZeroWid">
<xsl:choose>
<xsl:when test="count(m:phantPr[last()]/m:zeroWid[last()]) = 0">0</xsl:when>
<xsl:otherwise>
<xsl:call-template name="ForceFalseStrVal">
<xsl:with-param name="str" select="$sLowerCaseZeroWidVal" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="fZeroAsc">
<xsl:choose>
<xsl:when test="count(m:phantPr[last()]/m:zeroAsc[last()]) = 0">0</xsl:when>
<xsl:otherwise>
<xsl:call-template name="ForceFalseStrVal">
<xsl:with-param name="str" select="$sLowerCaseZeroAscVal" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="fZeroDesc">
<xsl:choose>
<xsl:when test="count(m:phantPr[last()]/m:zeroDesc[last()]) = 0">0</xsl:when>
<xsl:otherwise>
<xsl:call-template name="ForceFalseStrVal">
<xsl:with-param name="str" select="$sLowerCaseZeroDescVal" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- The show property defaults to 'on' unless there exists a show property and its value is 'off' -->
<xsl:variable name="fShow">
<xsl:call-template name="ForceFalseStrVal">
<xsl:with-param name="str" select="$sLowerCaseShowVal" />
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<!-- Show the phantom contents, therefore, just use mpadded. -->
<xsl:when test="$fShow = 1">
<xsl:element name="mpadded">
<xsl:call-template name="CreateMpaddedAttributes">
<xsl:with-param name="fZeroWid" select="$fZeroWid" />
<xsl:with-param name="fZeroAsc" select="$fZeroAsc" />
<xsl:with-param name="fZeroDesc" select="$fZeroDesc" />
</xsl:call-template>
<mrow>
<xsl:apply-templates select="m:e" />
</mrow>
</xsl:element>
</xsl:when>
<!-- Don't show phantom contents, but don't smash anything, therefore, just
use mphantom -->
<xsl:when test="$fZeroWid=0 and $fZeroAsc=0 and $fZeroDesc=0">
<xsl:element name="mphantom">
<mrow>
<xsl:apply-templates select="m:e" />
</mrow>
</xsl:element>
</xsl:when>
<!-- Combination -->
<xsl:otherwise>
<xsl:element name="mphantom">
<xsl:element name="mpadded">
<xsl:call-template name="CreateMpaddedAttributes">
<xsl:with-param name="fZeroWid" select="$fZeroWid" />
<xsl:with-param name="fZeroAsc" select="$fZeroAsc" />
<xsl:with-param name="fZeroDesc" select="$fZeroDesc" />
</xsl:call-template>
<mrow>
<xsl:apply-templates select="m:e" />
</mrow>
</xsl:element>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="CreateMpaddedAttributes">
<xsl:param name="fZeroWid" />
<xsl:param name="fZeroAsc" />
<xsl:param name="fZeroDesc" />
<xsl:if test="$fZeroWid=1">
<xsl:attribute name="width">0in</xsl:attribute>
</xsl:if>
<xsl:if test="$fZeroAsc=1">
<xsl:attribute name="height">0in</xsl:attribute>
</xsl:if>
<xsl:if test="$fZeroDesc=1">
<xsl:attribute name="depth">0in</xsl:attribute>
</xsl:if>
</xsl:template>
<xsl:template match="m:rad">
<xsl:variable name="fDegHide">
<xsl:choose>
<xsl:when test="count(m:radPr[last()]/m:degHide)=0">0</xsl:when>
<xsl:otherwise>
<xsl:call-template name="ForceFalseStrVal">
<xsl:with-param name="str" select="translate(m:radPr[last()]/m:degHide/@m:val,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="$fDegHide=1">
<msqrt>
<xsl:apply-templates select="m:e[1]" />
</msqrt>
</xsl:when>
<xsl:otherwise>
<mroot>
<mrow>
<xsl:apply-templates select="m:e[1]" />
</mrow>
<mrow>
<xsl:apply-templates select="m:deg[1]" />
</mrow>
</mroot>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="OutputNaryMo">
<xsl:param name="ndCur" select="." />
<xsl:param name="fGrow" select="0" />
<mo>
<xsl:choose>
<xsl:when test="$fGrow=1">
<xsl:attribute name="stretchy">true</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="stretchy">false</xsl:attribute>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="not($ndCur/m:naryPr[last()]/m:chr/@m:val) or
$ndCur/m:naryPr[last()]/m:chr/@m:val=''">
<xsl:text>∫</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$ndCur/m:naryPr[last()]/m:chr/@m:val" />
</xsl:otherwise>
</xsl:choose>
</mo>
</xsl:template>
<!-- %%Template match m:nary
Process an n-ary.
Decides, based on which arguments are supplied, between
using an mo, msup, msub, or msubsup for the n-ary operator
-->
<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:variable name="sLowerCaseLimLoc">
<xsl:value-of select="translate(m:naryPr[last()]/m:limLoc/@m:val,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
</xsl:variable>
<xsl:variable name="sLowerGrow">
<xsl:choose>
<xsl:when test="count(m:naryPr[last()]/m:grow)=0">off</xsl:when>
<xsl:otherwise>
<xsl:value-of select="translate(m:naryPr[last()]/m:grow/@m:val,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="fLimLocSubSup">
<xsl:choose>
<xsl:when test="count(m:naryPr[last()]/m:limLoc)=0 or $sLowerCaseLimLoc='subsup'">1</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="fGrow">
<xsl:call-template name="ForceFalseStrVal">
<xsl:with-param name="str" select="$sLowerGrow" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="fSupHide">
<xsl:call-template name="ForceFalseStrVal">
<xsl:with-param name="str" select="$sLowerCaseSupHide" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="fSubHide">
<xsl:call-template name="ForceFalseStrVal">
<xsl:with-param name="str" select="$sLowerCaseSubHide" />
</xsl:call-template>
</xsl:variable>
<mrow>
<xsl:choose>
<xsl:when test="$fSupHide=1 and $fSubHide=1">
<xsl:call-template name="OutputNaryMo">
<xsl:with-param name="ndCur" select="." />
<xsl:with-param name="fGrow" select="$fGrow" />
</xsl:call-template>
</xsl:when>
<xsl:when test="$fSubHide=1">
<xsl:choose>
<xsl:when test="$fLimLocSubSup=1">
<msup>
<xsl:call-template name="OutputNaryMo">
<xsl:with-param name="ndCur" select="." />
<xsl:with-param name="fGrow" select="$fGrow" />
</xsl:call-template>
<mrow>
<xsl:apply-templates select="m:sup[1]" />
</mrow>
</msup>
</xsl:when>
<xsl:otherwise>
<mover>
<xsl:call-template name="OutputNaryMo">
<xsl:with-param name="ndCur" select="." />
<xsl:with-param name="fGrow" select="$fGrow" />
</xsl:call-template>
<mrow>
<xsl:apply-templates select="m:sup[1]" />
</mrow>
</mover>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$fSupHide=1">
<xsl:choose>
<xsl:when test="$fLimLocSubSup=1">
<msub>
<xsl:call-template name="OutputNaryMo">
<xsl:with-param name="ndCur" select="." />
<xsl:with-param name="fGrow" select="$fGrow" />
</xsl:call-template>
<mrow>
<xsl:apply-templates select="m:sub[1]" />
</mrow>
</msub>
</xsl:when>
<xsl:otherwise>
<munder>
<xsl:call-template name="OutputNaryMo">
<xsl:with-param name="ndCur" select="." />
<xsl:with-param name="fGrow" select="$fGrow" />
</xsl:call-template>
<mrow>
<xsl:apply-templates select="m:sub[1]" />
</mrow>
</munder>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$fLimLocSubSup=1">
<msubsup>
<xsl:call-template name="OutputNaryMo">
<xsl:with-param name="ndCur" select="." />
<xsl:with-param name="fGrow" select="$fGrow" />
</xsl:call-template>
<mrow>
<xsl:apply-templates select="m:sub[1]" />
</mrow>
<mrow>
<xsl:apply-templates select="m:sup[1]" />
</mrow>
</msubsup>
</xsl:when>
<xsl:otherwise>
<munderover>
<xsl:call-template name="OutputNaryMo">
<xsl:with-param name="ndCur" select="." />
<xsl:with-param name="fGrow" select="$fGrow" />
</xsl:call-template>
<mrow>
<xsl:apply-templates select="m:sub[1]" />
</mrow>
<mrow>
<xsl:apply-templates select="m:sup[1]" />
</mrow>
</munderover>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
<mrow>
<xsl:apply-templates select="m:e[1]" />
</mrow>
</mrow>
</xsl:template>
<xsl:template match="m:limLow">
<munder>
<mrow>
<xsl:apply-templates select="m:e[1]" />
</mrow>
<mrow>
<xsl:apply-templates select="m:lim[1]" />
</mrow>
</munder>
</xsl:template>
<xsl:template match="m:limUpp">
<mover>
<mrow>
<xsl:apply-templates select="m:e[1]" />
</mrow>
<mrow>
<xsl:apply-templates select="m:lim[1]" />
</mrow>
</mover>
</xsl:template>
<xsl:template match="m:sSub">
<msub>
<mrow>
<xsl:apply-templates select="m:e[1]" />
</mrow>
<mrow>
<xsl:apply-templates select="m:sub[1]" />
</mrow>
</msub>
</xsl:template>
<xsl:template match="m:sSup">
<msup>
<mrow>
<xsl:apply-templates select="m:e[1]" />
</mrow>
<mrow>
<xsl:apply-templates select="m:sup[1]" />
</mrow>
</msup>
</xsl:template>
<xsl:template match="m:sSubSup">
<msubsup>
<mrow>
<xsl:apply-templates select="m:e[1]" />
</mrow>
<mrow>
<xsl:apply-templates select="m:sub[1]" />
</mrow>
<mrow>
<xsl:apply-templates select="m:sup[1]" />
</mrow>
</msubsup>
</xsl:template>
<xsl:template match="m:groupChr">
<xsl:variable name="ndLastGroupChrPr" select="m:groupChrPr[last()]" />
<xsl:variable name="sLowerCasePos" select="translate($ndLastGroupChrPr/m:pos/@m:val,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:variable name="sLowerCaseVertJc" select="translate($ndLastGroupChrPr/m:vertJc/@m:val,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:variable name="ndLastChr" select="$ndLastGroupChrPr/m:chr" />
<xsl:variable name="chr">
<xsl:choose>
<xsl:when test="$ndLastChr and (not($ndLastChr/@m:val) or string-length($ndLastChr/@m:val) = 0)"></xsl:when>
<xsl:when test="string-length($ndLastChr/@m:val) >= 1">
<xsl:value-of select="substring($ndLastChr/@m:val,1,1)" />
</xsl:when>
<xsl:otherwise>
<xsl:text>⏟</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="$sLowerCasePos = 'top'">
<xsl:choose>
<xsl:when test="$sLowerCaseVertJc = 'bot'">
<mover accent="false">
<mrow>
<xsl:apply-templates select="m:e[1]" />
</mrow>
<mo>
<xsl:value-of select="$chr" />
</mo>
</mover>
</xsl:when>
<xsl:otherwise>
<munder accentunder="false">
<mo>
<xsl:value-of select="$chr" />
</mo>
<mrow>
<xsl:apply-templates select="m:e[1]" />
</mrow>
</munder>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$sLowerCaseVertJc = 'bot'">
<mover accent="false">
<mo>
<xsl:value-of select="$chr" />
</mo>
<mrow>
<xsl:apply-templates select="m:e[1]" />
</mrow>
</mover>
</xsl:when>
<xsl:otherwise>
<munder accentunder="false">
<mrow>
<xsl:apply-templates select="m:e[1]" />
</mrow>
<mo>
<xsl:value-of select="$chr" />
</mo>
</munder>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="fName">
<xsl:for-each select="m:fName/*">
<xsl:apply-templates select="." />
</xsl:for-each>
</xsl:template>
<xsl:template match="m:func">
<mrow>
<mrow>
<xsl:call-template name="fName" />
</mrow>
<mo>⁡</mo>
<mrow>
<xsl:apply-templates select="m:e" />
</mrow>
</mrow>
</xsl:template>
<!-- %%Template: match m:f
m:f maps directly to mfrac.
-->
<xsl:template match="m:f">
<xsl:variable name="sLowerCaseType" select="translate(m:fPr[last()]/m:type/@m:val, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" />
<xsl:choose>
<xsl:when test="$sLowerCaseType='lin'">
<mrow>
<mrow>
<xsl:apply-templates select="m:num[1]" />
</mrow>
<mo>/</mo>
<mrow>
<xsl:apply-templates select="m:den[1]" />
</mrow>
</mrow>
</xsl:when>
<xsl:otherwise>
<mfrac>
<xsl:call-template name="CreateMathMLFracProp">
<xsl:with-param name="type" select="$sLowerCaseType" />
</xsl:call-template>
<mrow>
<xsl:apply-templates select="m:num[1]" />
</mrow>
<mrow>
<xsl:apply-templates select="m:den[1]" />
</mrow>
</mfrac>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- %%Template: CreateMathMLFracProp
Make fraction properties based on supplied parameters.
OMML differentiates between a linear fraction and a skewed
one. For MathML, we write both as bevelled.
-->
<xsl:template name="CreateMathMLFracProp">
<xsl:param name="type" />
<xsl:variable name="sLowerCaseType" select="translate($type, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" />
<xsl:if test="$sLowerCaseType='skw' or $sLowerCaseType='lin'">
<xsl:attribute name="bevelled">true</xsl:attribute>
</xsl:if>
<xsl:if test="$sLowerCaseType='nobar'">
<xsl:attribute name="linethickness">0pt</xsl:attribute>
</xsl:if>
<xsl:choose>
<xsl:when test="sLowerCaseNumJc='right'">
<xsl:attribute name="numalign">right</xsl:attribute>
</xsl:when>
<xsl:when test="sLowerCaseNumJc='left'">
<xsl:attribute name="numalign">left</xsl:attribute>
</xsl:when>
</xsl:choose>
<xsl:choose>
<xsl:when test="sLowerCaseDenJc='right'">
<xsl:attribute name="numalign">right</xsl:attribute>
</xsl:when>
<xsl:when test="sLowerCaseDenJc='left'">
<xsl:attribute name="numalign">left</xsl:attribute>
</xsl:when>
</xsl:choose>
</xsl:template>
<!-- %%Template: match m:e | m:den | m:num | m:lim | m:sup | m:sub
These element delinate parts of an expression (like the numerator). -->
<xsl:template match="m:e | m:den | m:num | m:lim | m:sup | m:sub">
<xsl:choose>
<!-- If there is no scriptLevel specified, just call through -->
<xsl:when test="not(m:argPr[last()]/m:scrLvl/@m:val)">
<xsl:apply-templates select="*" />
</xsl:when>
<!-- Otherwise, create an mstyle and set the script level -->
<xsl:otherwise>
<mstyle>
<xsl:attribute name="scriptlevel">
<xsl:value-of select="m:argPr[last()]/m:scrLvl/@m:val" />
</xsl:attribute>
<xsl:apply-templates select="*" />
</mstyle>
</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:variable name="fTop">
<xsl:choose>
<xsl:when test="$sLowerCasePos='top'">1</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="$fTop=1">
<mover accent="false">
<mrow>
<xsl:apply-templates select="m:e[1]" />
</mrow>
<mo>
<xsl:text>¯</xsl:text>
</mo>
</mover>
</xsl:when>
<xsl:otherwise>
<munder underaccent="false">
<mrow>
<xsl:apply-templates select="m:e[1]" />
</mrow>
<mo>
<xsl:text>_</xsl:text>
</mo>
</munder>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- %%Template match m:d
Process a delimiter.
-->
<xsl:template match="m:d">
<mrow>
<!-- open: default is '(' for OMML -->
<mo>
<xsl:choose>
<xsl:when test="m:dPr[1]/m:begChr/@m:val">
<xsl:value-of select="m:dPr[1]/m:begChr/@m:val" />
</xsl:when>
<xsl:otherwise>
<xsl:text>(</xsl:text>
</xsl:otherwise>
</xsl:choose>
</mo>
<!-- now write all the children. Put each one into an mrow
just in case it produces multiple runs, etc -->
<xsl:for-each select="m:e">
<xsl:if test="position()>1">
<!-- separator: the default is ',' for MathML, and '|' for OMML -->
<mo>
<xsl:choose>
<!-- OMML default: | -->
<xsl:when test="not(m:dPr[1]/m:sepChr/@m:val)">
<xsl:value-of select="'|'" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="m:dPr[1]/m:sepChr/@m:val" />
</xsl:otherwise>
</xsl:choose>
</mo>
</xsl:if>
<mrow>
<xsl:apply-templates select="." />
</mrow>
</xsl:for-each>
<!-- close: default is ')' for OMML -->
<mo>
<xsl:choose>
<xsl:when test="m:dPr[1]/m:endChr/@m:val">
<xsl:value-of select="m:dPr[1]/m:endChr/@m:val" />
</xsl:when>
<xsl:otherwise>
<xsl:text>)</xsl:text>
</xsl:otherwise>
</xsl:choose>
</mo>
</mrow>
</xsl:template>
<xsl:template match="m:r">
<xsl:variable name="fNor">
<xsl:choose>
<xsl:when test="count(child::m:rPr[last()]/m:nor) = 0">0</xsl:when>
<xsl:otherwise>
<xsl:call-template name="ForceFalseStrVal">
<xsl:with-param name="str" select="translate(child::m:rPr[last()]/m:nor/@m:val, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="$fNor=1">
<mtext>
<xsl:variable name="sOutput" select="translate(.//m:t, ' ', ' ')" />
<xsl:value-of select="$sOutput" />
</mtext>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select=".//m:t">
<xsl:call-template name="ParseMt">
<xsl:with-param name="sToParse" select="text()" />
<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">0</xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- %%Template: ComputeMathVariant
Given scr, sty, and sTokenType, compute the mathvariant name.
Returns: variant name (e.g. "bold", "italic") or empty string. -->
<xsl:template name="ComputeMathVariant">
<xsl:param name="scr" />
<xsl:param name="sty" />
<xsl:param name="sTokenType" />
<xsl:choose>
<xsl:when test="$sTokenType='mn'" />
<xsl:when test="$scr='monospace'">monospace</xsl:when>
<xsl:when test="$scr='sans-serif' and $sty='b'">bold-sans-serif</xsl:when>
<xsl:when test="$scr='sans-serif' and $sty='bi'">sans-serif-bold-italic</xsl:when>
<xsl:when test="$scr='sans-serif' and $sty='p'">sans-serif</xsl:when>
<xsl:when test="$scr='sans-serif'">sans-serif-italic</xsl:when>
<xsl:when test="$scr='fraktur' and ($sty='b' or $sty='bi')">bold-fraktur</xsl:when>
<xsl:when test="$scr='fraktur'">fraktur</xsl:when>
<xsl:when test="$scr='double-struck'">double-struck</xsl:when>
<xsl:when test="$scr='script' and ($sty='b' or $sty='bi')">bold-script</xsl:when>
<xsl:when test="$scr='script'">script</xsl:when>
<xsl:when test="($scr='roman' or not($scr) or $scr='') and $sty='b'">bold</xsl:when>
<xsl:when test="($scr='roman' or not($scr) or $scr='') and $sty='i'">italic</xsl:when>
<xsl:when test="($scr='roman' or not($scr) or $scr='') and $sty='p'">normal</xsl:when>
<xsl:when test="($scr='roman' or not($scr) or $scr='') and $sty='bi'">bold-italic</xsl:when>
<xsl:otherwise />
</xsl:choose>
</xsl:template>
<!-- %%Template: LookupPositionInAlpha
Given a single ASCII letter, returns its 0-based position (A=0..Z=25, a=26..z=51)
or -1 if the character is not an ASCII letter. -->
<xsl:template name="LookupPositionInAlpha">
<xsl:param name="ch" />
<xsl:variable name="upperPos" select="string-length(substring-before($sUpperAlpha, $ch))" />
<xsl:variable name="lowerPos" select="string-length(substring-before($sLowerAlpha, $ch))" />
<xsl:choose>
<xsl:when test="contains($sUpperAlpha, $ch)">
<xsl:value-of select="$upperPos" />
</xsl:when>
<xsl:when test="contains($sLowerAlpha, $ch)">
<xsl:value-of select="26 + $lowerPos" />
</xsl:when>
<xsl:otherwise>-1</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- %%Template: OutputMathVariantChar
Converts a single ASCII letter to its Unicode math alphanumeric equivalent
for the given variant. Non-ASCII-letter characters pass through unchanged.
The lookup string for each variant contains all 52 chars (A-Z, a-z) in order.
BMP chars take 1 position in the string, SMP chars take 2 (surrogate pair).
We use substring-before on the lookup string truncated to find our char's position. -->
<xsl:template name="OutputMathVariantChar">
<xsl:param name="ch" />
<xsl:param name="variant" />
<xsl:variable name="pos">
<xsl:call-template name="LookupPositionInAlpha">
<xsl:with-param name="ch" select="$ch" />
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$pos = -1">
<!-- Not an ASCII letter, pass through -->
<xsl:value-of select="$ch" />
</xsl:when>
<xsl:otherwise>
<!-- Select the right lookup string -->
<xsl:variable name="lookupStr">
<xsl:choose>
<xsl:when test="$variant='bold'">
<xsl:value-of select="$s_math_bold" />
</xsl:when>
<xsl:when test="$variant='italic'">
<xsl:value-of select="$s_math_italic" />
</xsl:when>
<xsl:when test="$variant='bold-italic'">
<xsl:value-of select="$s_math_bold_italic" />
</xsl:when>
<xsl:when test="$variant='script'">
<xsl:value-of select="$s_math_script" />
</xsl:when>
<xsl:when test="$variant='bold-script'">
<xsl:value-of select="$s_math_bold_script" />
</xsl:when>
<xsl:when test="$variant='fraktur'">
<xsl:value-of select="$s_math_fraktur" />
</xsl:when>
<xsl:when test="$variant='bold-fraktur'">
<xsl:value-of select="$s_math_bold_fraktur" />
</xsl:when>
<xsl:when test="$variant='double-struck'">
<xsl:value-of select="$s_math_double_struck" />
</xsl:when>
<xsl:when test="$variant='sans-serif'">
<xsl:value-of select="$s_math_sans_serif" />
</xsl:when>
<xsl:when test="$variant='bold-sans-serif'">
<xsl:value-of select="$s_math_bold_sans_serif" />
</xsl:when>
<xsl:when test="$variant='sans-serif-italic'">
<xsl:value-of select="$s_math_sans_serif_italic" />
</xsl:when>
<xsl:when test="$variant='sans-serif-bold-italic'">
<xsl:value-of select="$s_math_sans_serif_bold_italic" />
</xsl:when>
<xsl:when test="$variant='monospace'">
<xsl:value-of select="$s_math_monospace" />
</xsl:when>
</xsl:choose>
</xsl:variable>
<!-- Build an alphabet string with the same positional encoding as lookupStr:
each letter position uses the same width (BMP=1, SMP=2) as the lookup.
We use substring on the lookup string to find position boundaries. -->
<!-- Strategy: walk through the first $pos letters to compute the string offset.
Each letter in the lookup is either 1 char (BMP) or 2 chars (surrogate pair).
We can compute the offset by taking the substring of the first N chars and
measuring where the N-th char starts.
Simpler approach: use a helper alphabet that mirrors the lookup structure.
Since we know the lookup structure at build time, and positions 0-25 are A-Z
and 26-51 are a-z, we build a position-offset string for each variant.
Simplest approach: just scan from position 0 in the lookup string.
For all-SMP variants (no BMP exceptions), offset = pos * 2, length = 2.
For mixed variants, we need a different approach. -->
<!-- For all-SMP variants, every char is a surrogate pair (2 code units) -->
<xsl:variable name="isAllSMP">
<xsl:choose>
<xsl:when test="$variant='bold' or $variant='bold-italic'
or $variant='bold-script' or $variant='bold-fraktur'
or $variant='sans-serif' or $variant='bold-sans-serif'
or $variant='sans-serif-italic'
or $variant='sans-serif-bold-italic'
or $variant='monospace'">1</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="$isAllSMP='1'">
<!-- All SMP: position = pos * 2 + 1, length = 2 -->
<xsl:value-of select="substring($lookupStr, $pos * 2 + 1, 2)" />
</xsl:when>
<xsl:otherwise>
<!-- Mixed BMP/SMP: use ScanToPosition to find the right offset -->
<xsl:call-template name="ScanToPosition">
<xsl:with-param name="str" select="$lookupStr" />
<xsl:with-param name="remaining" select="$pos" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- %%Template: ScanToPosition
Walks through a mixed BMP/SMP string to find the character at the given position
(counting logical characters, not code units). Each SMP char occupies 2 code units
(surrogate pair, high surrogate in range D800-DBFF), each BMP char occupies 1.
When remaining=0, outputs the current character (1 or 2 code units). -->
<xsl:template name="ScanToPosition">
<xsl:param name="str" />
<xsl:param name="remaining" />
<!-- Check if current code unit is a high surrogate (D800-DBFF).
We test by checking if the first char of str is NOT in the BMP printable range.
High surrogates have code points D800-DBFF. We can detect them by checking
if the character is in a known high-surrogate variable.
Simpler: a high surrogate followed by a low surrogate forms a pair.
We know all our SMP chars have high surrogate D835. We can extract it from
a known lookup variable. But we also need to handle other high surrogates generically.
Most reliable approach: check string-length of the first "character" by testing
if the first code unit, when followed by a second code unit in the D800-DBFF/DC00-DFFF
range, forms a surrogate pair. In XSLT 1.0 we can use a trick:
if the lookup string has known structure, we can just check if the first
code unit matches any known high surrogate.
Since all our SMP chars share high surrogate D835, extract it from $s_math_bold. -->
<xsl:variable name="highSurrogate" select="substring($s_math_bold, 1, 1)" />
<xsl:variable name="firstUnit" select="substring($str, 1, 1)" />
<xsl:variable name="charWidth">
<xsl:choose>
<xsl:when test="$firstUnit = $highSurrogate">2</xsl:when>
<xsl:otherwise>1</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="$remaining = 0">
<xsl:value-of select="substring($str, 1, $charWidth)" />
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="ScanToPosition">
<xsl:with-param name="str" select="substring($str, $charWidth + 1)" />
<xsl:with-param name="remaining" select="$remaining - 1" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- %%Template: ConvertToMathAlphanumeric
Recursively processes a string, converting each ASCII letter to its
Unicode math alphanumeric equivalent for the given variant.
Handles UTF-16 surrogate pairs: if the first code unit is a high surrogate,
both code units are passed through together to avoid lone surrogates in output. -->
<xsl:template name="ConvertToMathAlphanumeric">
<xsl:param name="str" />
<xsl:param name="variant" />
<xsl:if test="string-length($str) > 0">
<!-- Extract a known high surrogate (D835) from a lookup string for comparison -->
<xsl:variable name="highSurrogate" select="substring($s_math_bold, 1, 1)" />
<xsl:variable name="firstUnit" select="substring($str, 1, 1)" />
<xsl:choose>
<xsl:when test="$firstUnit = $highSurrogate">
<!-- This is a surrogate pair (SMP char) — pass through both code units together -->
<xsl:value-of select="substring($str, 1, 2)" />
<xsl:call-template name="ConvertToMathAlphanumeric">
<xsl:with-param name="str" select="substring($str, 3)" />
<xsl:with-param name="variant" select="$variant" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="OutputMathVariantChar">
<xsl:with-param name="ch" select="$firstUnit" />
<xsl:with-param name="variant" select="$variant" />
</xsl:call-template>
<xsl:call-template name="ConvertToMathAlphanumeric">
<xsl:with-param name="str" select="substring($str, 2)" />
<xsl:with-param name="variant" select="$variant" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
<xsl:template name="CreateTokenAttributes">
<xsl:param name="scr" />
<xsl:param name="sty" />
<xsl:param name="nor" />
<xsl:param name="nCharToPrint" />
<xsl:param name="sTokenType" />
<!-- Non-normal variants use Unicode math alphanumeric characters instead of
the mathvariant attribute. Only mathvariant="normal" is output explicitly. -->
<xsl:if test="$nor != 1">
<xsl:variable name="mathvariant">
<xsl:call-template name="ComputeMathVariant">
<xsl:with-param name="scr" select="$scr" />
<xsl:with-param name="sty" select="$sty" />
<xsl:with-param name="sTokenType" select="$sTokenType" />
</xsl:call-template>
</xsl:variable>
<xsl:if test="$mathvariant = 'normal'">
<xsl:attribute name="mathvariant">normal</xsl:attribute>
</xsl:if>
</xsl:if>
</xsl:template>
<xsl:template match="m:eqArr">
<mtable>
<xsl:for-each select="m:e">
<mtr>
<mtd>
<xsl:choose>
<xsl:when test="m:argPr[last()]/m:scrLvl/@m:val!='0' or
not(m:argPr[last()]/m:scrLvl/@m:val) or
m:argPr[last()]/m:scrLvl/@m:val=''">
<mrow>
<maligngroup />
<xsl:call-template name="CreateEqArrRow">
<xsl:with-param name="align" select="1" />
<xsl:with-param name="ndCur" select="*[1]" />
</xsl:call-template>
</mrow>
</xsl:when>
<xsl:otherwise>
<mstyle>
<xsl:attribute name="scriptlevel">
<xsl:value-of select="m:argPr[last()]/m:scrLvl/@m:val" />
</xsl:attribute>
<maligngroup />
<xsl:call-template name="CreateEqArrRow">
<xsl:with-param name="align" select="1" />
<xsl:with-param name="ndCur" select="*[1]" />
</xsl:call-template>
</mstyle>
</xsl:otherwise>
</xsl:choose>
</mtd>
</mtr>
</xsl:for-each>
</mtable>
</xsl:template>
<xsl:template name="CreateEqArrRow">
<xsl:param name="align" />
<xsl:param name="ndCur" />
<xsl:variable name="sAllMt">
<xsl:for-each select="$ndCur/m:t">
<xsl:value-of select="." />
</xsl:for-each>
</xsl:variable>
<xsl:choose>
<xsl:when test="$ndCur/self::m:r">
<xsl:call-template name="ParseEqArrMr">
<xsl:with-param name="sToParse" select="$sAllMt" />
<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">
<xsl:choose>
<xsl:when test="count($ndCur/m:rPr[last()]/m:nor) = 0">0</xsl:when>
<xsl:otherwise>
<xsl:call-template name="ForceFalseStrVal">
<xsl:with-param name="str" select="translate($ndCur/m:rPr[last()]/m:nor/@m:val,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
<xsl:with-param name="align" select="$align" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="$ndCur" />
</xsl:otherwise>
</xsl:choose>
<xsl:if test="count($ndCur/following-sibling::*) > 0">
<xsl:variable name="cAmp">
<xsl:call-template name="CountAmp">
<xsl:with-param name="sAllMt" select="$sAllMt" />
<xsl:with-param name="cAmp" select="0" />
</xsl:call-template>
</xsl:variable>
<xsl:call-template name="CreateEqArrRow">
<xsl:with-param name="align" select="($align+($cAmp mod 2)) mod 2" />
<xsl:with-param name="ndCur" select="$ndCur/following-sibling::*[1]" />
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="CountAmp">
<xsl:param name="sAllMt" />
<xsl:param name="cAmp" />
<xsl:choose>
<xsl:when test="string-length(substring-after($sAllMt, '&')) > 0 or
substring($sAllMt, string-length($sAllMt))='&'">
<xsl:call-template name="CountAmp">
<xsl:with-param name="sAllMt" select="substring-after($sAllMt, '&')" />
<xsl:with-param name="cAmp" select="$cAmp+1" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$cAmp" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- %%Template: ParseEqArrMr
Similar to ParseMt, but this one has to do more for an equation array.
In equation arrays & is a special character which denotes alignment.
The & in an equation works by alternating between meaning insert alignment spacing
and insert alignment mark. For each equation in the equation array
there is an implied align space at the beginning of the equation. Within each equation,
the first & means alignmark, the second, align space, the third, alignmark, etc.
For this reason when parsing m:r's in equation arrays it is important to keep track of what
the next ampersand will mean.
$align=0 => Omml's align space, which is similar to MathML's maligngroup.
$align=1 => Omml's alignment mark, which is similar to MathML's malignmark.
-->
<xsl:template name="ParseEqArrMr">
<xsl:param name="sToParse" />
<xsl:param name="sty" />
<xsl:param name="scr" />
<xsl:param name="nor" />
<xsl:param name="align" />
<xsl:if test="string-length($sToParse) > 0">
<xsl:choose>
<xsl:when test="substring($sToParse,1,1) = '&'">
<xsl:choose>
<xsl:when test="$align='0'">
<maligngroup />
</xsl:when>
<xsl:when test="$align='1'">
<malignmark />
</xsl:when>
</xsl:choose>
<xsl:call-template name="ParseEqArrMr">
<xsl:with-param name="sToParse" select="substring($sToParse,2)" />
<xsl:with-param name="scr" select="$scr" />
<xsl:with-param name="sty" select="$sty" />
<xsl:with-param name="nor" select="$nor" />
<xsl:with-param name="align">
<xsl:choose>
<xsl:when test="$align='1'">0</xsl:when>
<xsl:otherwise>1</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="sRepNumWith0">
<xsl:call-template name="SReplaceNumWithZero">
<xsl:with-param name="sToParse" select="$sToParse" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="sRepOperWith-">
<xsl:call-template name="SReplaceOperWithMinus">
<xsl:with-param name="sToParse" select="$sRepNumWith0" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="iFirstOper" select="string-length($sRepOperWith-) - string-length(substring-after($sRepOperWith-, '-'))" />
<xsl:variable name="iFirstNum" select="string-length($sRepOperWith-) - string-length(substring-after($sRepOperWith-, '0'))" />
<xsl:variable name="iFirstAmp" select="string-length($sRepOperWith-) - string-length(substring-after($sRepOperWith-, '&'))" />
<xsl:variable name="fNumAtPos1">
<xsl:choose>
<xsl:when test="substring($sRepOperWith-,1,1)='0'">1</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="fOperAtPos1">
<xsl:choose>
<xsl:when test="substring($sRepOperWith-,1,1)='-'">1</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<!-- Case I: The string begins with neither a number, nor an operator -->
<xsl:when test="$fNumAtPos1='0' and $fOperAtPos1='0'">
<xsl:variable name="sOutput"
select="translate(substring($sToParse, 1, 1), ' ', ' ')" />
<xsl:variable name="effectiveVariant">
<xsl:if test="$nor = 0">
<xsl:call-template name="ComputeMathVariant">
<xsl:with-param name="scr" select="$scr" />
<xsl:with-param name="sty" select="$sty" />
<xsl:with-param name="sTokenType" select="'mi'" />
</xsl:call-template>
</xsl:if>
</xsl:variable>
<xsl:variable name="convertVariant">
<xsl:choose>
<xsl:when test="$nor != 0"></xsl:when>
<xsl:when test="$effectiveVariant='' or $effectiveVariant='italic'"></xsl:when>
<xsl:when test="$effectiveVariant='normal'"></xsl:when>
<xsl:otherwise><xsl:value-of select="$effectiveVariant" /></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Use mtext for upright characters (nor=1) -->
<xsl:choose>
<xsl:when test="$nor != 0">
<mtext>
<xsl:value-of select="$sOutput" />
</mtext>
</xsl:when>
<xsl:otherwise>
<mi>
<xsl:call-template name="CreateTokenAttributes">
<xsl:with-param name="scr" select="$scr" />
<xsl:with-param name="sty" select="$sty" />
<xsl:with-param name="nor" select="$nor" />
<xsl:with-param name="nCharToPrint" select="1" />
<xsl:with-param name="sTokenType" select="'mi'" />
</xsl:call-template>
<xsl:choose>
<xsl:when test="$convertVariant != ''">
<xsl:call-template name="ConvertToMathAlphanumeric">
<xsl:with-param name="str" select="$sOutput" />
<xsl:with-param name="variant" select="$convertVariant" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$sOutput" />
</xsl:otherwise>
</xsl:choose>
</mi>
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="ParseEqArrMr">
<xsl:with-param name="sToParse" select="substring($sToParse, 2)" />
<xsl:with-param name="scr" select="$scr" />
<xsl:with-param name="sty" select="$sty" />
<xsl:with-param name="nor" select="$nor" />
<xsl:with-param name="align" select="$align" />
</xsl:call-template>
</xsl:when>
<!-- Case II: There is an operator at position 1 -->
<xsl:when test="$fOperAtPos1='1'">
<xsl:choose>
<xsl:when test="$nor = 0">
<mo>
<xsl:call-template name="CreateTokenAttributes">
<xsl:with-param name="scr" />
<xsl:with-param name="sty" />
<xsl:with-param name="nor" select="$nor" />
<xsl:with-param name="sTokenType" select="'mo'" />
</xsl:call-template>
<xsl:value-of select="substring($sToParse,1,1)" />
</mo>
</xsl:when>
<xsl:otherwise>
<mtext>
<xsl:value-of select="substring($sToParse,1,1)" />
</mtext>
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="ParseEqArrMr">
<xsl:with-param name="sToParse" select="substring($sToParse, 2)" />
<xsl:with-param name="scr" select="$scr" />
<xsl:with-param name="sty" select="$sty" />
<xsl:with-param name="nor" select="$nor" />
<xsl:with-param name="align" select="$align" />
</xsl:call-template>
</xsl:when>
<!-- Case III: There is a number at position 1 -->
<xsl:otherwise>
<xsl:variable name="sConsecNum">
<xsl:call-template name="SNumStart">
<xsl:with-param name="sToParse" select="$sToParse" />
<xsl:with-param name="sPattern" select="$sRepNumWith0" />
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$nor = 0">
<mn>
<xsl:call-template name="CreateTokenAttributes">
<xsl:with-param name="scr" />
<xsl:with-param name="sty" select="'p'"/>
<xsl:with-param name="nor" select="$nor" />
<xsl:with-param name="sTokenType" select="'mn'" />
</xsl:call-template>
<xsl:value-of select="$sConsecNum" />
</mn>
</xsl:when>
<xsl:otherwise>
<mtext>
<xsl:value-of select="$sConsecNum" />
</mtext>
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="ParseEqArrMr">
<xsl:with-param name="sToParse" select="substring-after($sToParse, $sConsecNum)" />
<xsl:with-param name="scr" select="$scr" />
<xsl:with-param name="sty" select="$sty" />
<xsl:with-param name="nor" select="$nor" />
<xsl:with-param name="align" select="$align" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
<!-- %%Template: ParseMt
Produce a run of text. Technically, OMML makes no distinction
between numbers, operators, and other characters in a run. For
MathML we need to break these into mi, mn, or mo elements.
See also ParseEqArrMr
-->
<xsl:template name="ParseMt">
<xsl:param name="sToParse" />
<xsl:param name="sty" />
<xsl:param name="scr" />
<xsl:param name="nor" />
<xsl:if test="string-length($sToParse) > 0">
<xsl:variable name="sRepNumWith0">
<xsl:call-template name="SReplaceNumWithZero">
<xsl:with-param name="sToParse" select="$sToParse" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="sRepOperWith-">
<xsl:call-template name="SReplaceOperWithMinus">
<xsl:with-param name="sToParse" select="$sRepNumWith0" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="iFirstOper" select="string-length($sRepOperWith-) - string-length(substring-after($sRepOperWith-, '-'))" />
<xsl:variable name="iFirstNum" select="string-length($sRepOperWith-) - string-length(substring-after($sRepOperWith-, '0'))" />
<xsl:variable name="fNumAtPos1">
<xsl:choose>
<xsl:when test="substring($sRepOperWith-,1,1)='0'">1</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="fOperAtPos1">
<xsl:choose>
<xsl:when test="substring($sRepOperWith-,1,1)='-'">1</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<!-- nor=1: output entire run as mtext -->
<xsl:when test="$nor = 1">
<mtext>
<xsl:value-of select="translate($sToParse, ' ', ' ')" />
</mtext>
</xsl:when>
<!-- Case I: The string begins with neither a number, nor an operator -->
<xsl:when test="$fOperAtPos1='0' and $fNumAtPos1='0'">
<xsl:variable name="nCharToPrint">
<xsl:choose>
<xsl:when test="ancestor::m:fName">
<xsl:choose>
<xsl:when test="($iFirstOper=$iFirstNum) and
($iFirstOper=string-length($sToParse)) and
(substring($sRepOperWith-, string-length($sRepOperWith-))!='0') and
(substring($sRepOperWith-, string-length($sRepOperWith-))!='-')">
<xsl:value-of select="string-length($sToParse)" />
</xsl:when>
<xsl:when test="$iFirstOper < $iFirstNum">
<xsl:value-of select="$iFirstOper - 1" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$iFirstNum - 1" />
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>1</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="sWrite"
select="translate(substring($sToParse, 1, $nCharToPrint), ' ', ' ')" />
<xsl:variable name="effectiveVariant">
<xsl:call-template name="ComputeMathVariant">
<xsl:with-param name="scr" select="$scr" />
<xsl:with-param name="sty" select="$sty" />
<xsl:with-param name="sTokenType" select="'mi'" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="convertVariant">
<xsl:choose>
<!-- Multi-char mi with default/italic: convert to italic Unicode -->
<xsl:when test="$nCharToPrint > 1
and ($effectiveVariant='' or $effectiveVariant='italic')
">italic</xsl:when>
<!-- Single-char mi with default/italic: no conversion -->
<xsl:when test="$nCharToPrint = 1
and ($effectiveVariant='' or $effectiveVariant='italic')
"></xsl:when>
<!-- Normal: no conversion needed -->
<xsl:when test="$effectiveVariant='normal'"></xsl:when>
<!-- All other variants: convert -->
<xsl:otherwise><xsl:value-of select="$effectiveVariant" /></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<mi>
<xsl:call-template name="CreateTokenAttributes">
<xsl:with-param name="scr" select="$scr" />
<xsl:with-param name="sty" select="$sty" />
<xsl:with-param name="nor" select="$nor" />
<xsl:with-param name="nCharToPrint" select="$nCharToPrint" />
<xsl:with-param name="sTokenType" select="'mi'" />
</xsl:call-template>
<xsl:choose>
<xsl:when test="$convertVariant != ''">
<xsl:call-template name="ConvertToMathAlphanumeric">
<xsl:with-param name="str" select="$sWrite" />
<xsl:with-param name="variant" select="$convertVariant" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$sWrite" />
</xsl:otherwise>
</xsl:choose>
</mi>
<xsl:call-template name="ParseMt">
<xsl:with-param name="sToParse" select="substring($sToParse, $nCharToPrint+1)" />
<xsl:with-param name="scr" select="$scr" />
<xsl:with-param name="sty" select="$sty" />
<xsl:with-param name="nor" select="$nor" />
</xsl:call-template>
</xsl:when>
<!-- Case II: There is an operator at position 1 -->
<xsl:when test="$fOperAtPos1='1'">
<mo>
<xsl:call-template name="CreateTokenAttributes">
<xsl:with-param name="scr" />
<xsl:with-param name="sty" />
<xsl:with-param name="nor" select="$nor" />
<xsl:with-param name="sTokenType" select="'mo'" />
</xsl:call-template>
<xsl:value-of select="substring($sToParse,1,1)" />
</mo>
<xsl:call-template name="ParseMt">
<xsl:with-param name="sToParse" select="substring($sToParse, 2)" />
<xsl:with-param name="scr" select="$scr" />
<xsl:with-param name="sty" select="$sty" />
<xsl:with-param name="nor" select="$nor" />
</xsl:call-template>
</xsl:when>
<!-- Case III: There is a number at position 1 -->
<xsl:otherwise>
<xsl:variable name="sConsecNum">
<xsl:call-template name="SNumStart">
<xsl:with-param name="sToParse" select="$sToParse" />
<xsl:with-param name="sPattern" select="$sRepNumWith0" />
</xsl:call-template>
</xsl:variable>
<mn>
<xsl:call-template name="CreateTokenAttributes">
<xsl:with-param name="scr" select="$scr" />
<xsl:with-param name="sty" select="'p'" />
<xsl:with-param name="nor" select="$nor" />
<xsl:with-param name="sTokenType" select="'mn'" />
</xsl:call-template>
<xsl:value-of select="$sConsecNum" />
</mn>
<xsl:call-template name="ParseMt">
<xsl:with-param name="sToParse" select="substring-after($sToParse, $sConsecNum)" />
<xsl:with-param name="scr" select="$scr" />
<xsl:with-param name="sty" select="$sty" />
<xsl:with-param name="nor" select="$nor" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
<!-- %%Template: SNumStart
Return the longest substring of sToParse starting from the
start of sToParse that is a number. In addition, it takes the
pattern string, which is sToParse with all of its numbers
replaced with a 0. sPattern should be the same length
as sToParse
-->
<xsl:template name="SNumStart">
<xsl:param name="sToParse" select="''" />
<!-- if we don't get anything, take the string itself -->
<xsl:param name="sPattern" select="'$sToParse'" />
<xsl:choose>
<!-- the pattern says this is a number, recurse with the rest -->
<xsl:when test="substring($sPattern, 1, 1) = '0'">
<xsl:call-template name="SNumStart">
<xsl:with-param name="sToParse" select="$sToParse" />
<xsl:with-param name="sPattern" select="substring($sPattern, 2)" />
</xsl:call-template>
</xsl:when>
<!-- the pattern says we've run out of numbers. Take as many
characters from sToParse as we shaved off sPattern -->
<xsl:otherwise>
<xsl:value-of select="substring($sToParse, 1, string-length($sToParse) - string-length($sPattern))" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- %%Template SRepeatCharAcc
The core of SRepeatChar with an accumulator. The current
string is in param $acc, and we will double and recurse,
if we're less than half of the required length or else just
add the right amount of characters to the accumulator and
return
-->
<xsl:template name="SRepeatCharAcc">
<xsl:param name="cchRequired" select="1" />
<xsl:param name="ch" select="'-'" />
<xsl:param name="acc" select="$ch" />
<xsl:variable name="cchAcc" select="string-length($acc)" />
<xsl:choose>
<xsl:when test="(2 * $cchAcc) < $cchRequired">
<xsl:call-template name="SRepeatCharAcc">
<xsl:with-param name="cchRequired" select="$cchRequired" />
<xsl:with-param name="ch" select="$ch" />
<xsl:with-param name="acc" select="concat($acc, $acc)" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat($acc, substring($acc, 1, $cchRequired - $cchAcc))" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- %%Template SRepeatChar
Generates a string nchRequired long by repeating the given character ch
-->
<xsl:template name="SRepeatChar">
<xsl:param name="cchRequired" select="1" />
<xsl:param name="ch" select="'-'" />
<xsl:call-template name="SRepeatCharAcc">
<xsl:with-param name="cchRequired" select="$cchRequired" />
<xsl:with-param name="ch" select="$ch" />
<xsl:with-param name="acc" select="$ch" />
</xsl:call-template>
</xsl:template>
<!-- %%Template SReplaceOperWithMinus
Go through the given string and replace every instance
of an operator with a minus '-'. This helps quickly identify
the first instance of an operator.
-->
<xsl:template name="SReplaceOperWithMinus">
<xsl:param name="sToParse" select="''" />
<xsl:value-of select="translate($sToParse, $sOperators, $sMinuses)" />
</xsl:template>
<!-- %%Template SReplaceNumWithZero
Go through the given string and replace every instance
of an number with a zero '0'. This helps quickly identify
the first occurence of a number.
Considers the '.' and ',' part of a number iff they are sandwiched
between two other numbers. 0.3 will be recognized as a number,
x.3 will not be. Since these characters can also be an operator, this
should be called before SReplaceOperWithMinus.
-->
<xsl:template name="SReplaceNumWithZero">
<xsl:param name="sToParse" select="''" />
<!-- First do a simple replace. Numbers will all be come 0's.
After this point, the pattern involving the . or , that
we are looking for will become 0.0 or 0,0 -->
<xsl:variable name="sSimpleReplace" select="translate($sToParse, $sNumbers, $sZeros)" />
<!-- And then, replace 0.0 with just 000. This means that the . will
become part of the number -->
<xsl:variable name="sReplacePeriod">
<xsl:call-template name="SReplace">
<xsl:with-param name="sInput" select="$sSimpleReplace" />
<xsl:with-param name="sOrig" select="'0.0'" />
<xsl:with-param name="sReplacement" select="'000'" />
</xsl:call-template>
</xsl:variable>
<!-- And then, replace 0,0 with just 000. This means that the , will
become part of the number -->
<xsl:call-template name="SReplace">
<xsl:with-param name="sInput" select="$sReplacePeriod" />
<xsl:with-param name="sOrig" select="'0,0'" />
<xsl:with-param name="sReplacement" select="'000'" />
</xsl:call-template>
</xsl:template>
<!-- Template to translate Word's borderBox properties into the menclose notation attribute
The initial call to this SHOULD NOT pass an sAttribute. Subsequent calls to
CreateMencloseNotationAttrFromBorderBoxAttr by CreateMencloseNotationAttrFromBorderBoxAttr will
update the sAttribute as appropriate.
CreateMencloseNotationAttrFromBorderBoxAttr looks at each attribute (fHideTop, fHideBot, etc.) one at a time
in the order they are listed and passes a modified sAttribute to CreateMencloseNotationAttrFromBorderBoxAttr.
Each successive call to CreateMencloseNotationAttrFromBorderBoxAttr knows which attribute to look at because
the previous call should have omitted passing the attribute it just analyzed. This is why as you read lower
and lower in the template that each call to CreateMencloseNotationAttrFromBorderBoxAttr has fewer and fewer attributes.
-->
<xsl:template name="CreateMencloseNotationAttrFromBorderBoxAttr">
<xsl:param name="fHideTop" />
<xsl:param name="fHideBot" />
<xsl:param name="fHideLeft" />
<xsl:param name="fHideRight" />
<xsl:param name="fStrikeH" />
<xsl:param name="fStrikeV" />
<xsl:param name="fStrikeBLTR" />
<xsl:param name="fStrikeTLBR" />
<xsl:param name="sAttribute" />
<xsl:choose>
<xsl:when test="string-length($sAttribute) = 0">
<xsl:choose>
<xsl:when test="string-length($fHideTop) > 0
and string-length($fHideBot) > 0
and string-length($fHideLeft) > 0
and string-length($fHideRight) > 0">
<xsl:choose>
<xsl:when test="$fHideTop = 0
and $fHideBot = 0
and $fHideLeft = 0
and $fHideRight = 0">
<!-- We can use 'box' instead of top, bot, left, and right. Therefore,
replace sAttribute with 'box' and begin analyzing params fStrikeH
and below. -->
<xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
<xsl:with-param name="fStrikeH" select="$fStrikeH" />
<xsl:with-param name="fStrikeV" select="$fStrikeV" />
<xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
<xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
<xsl:with-param name="sAttribute">
<xsl:text>box</xsl:text>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!-- Can't use 'box', theremore, must analyze all attributes -->
<xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
<xsl:with-param name="fHideTop" select="$fHideTop" />
<xsl:with-param name="fHideBot" select="$fHideBot" />
<xsl:with-param name="fHideLeft" select="$fHideLeft" />
<xsl:with-param name="fHideRight" select="$fHideRight" />
<xsl:with-param name="fStrikeH" select="$fStrikeH" />
<xsl:with-param name="fStrikeV" select="$fStrikeV" />
<xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
<xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
<xsl:with-param name="sAttribute">
<!-- Assume using all four (left right top bottom). Subsequent calls
will remove the sides which aren't to be includes. -->
<xsl:text>left right top bottom</xsl:text>
</xsl:with-param>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="string-length($fHideTop) > 0">
<xsl:choose>
<xsl:when test="$fHideTop=1">
<xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
<xsl:with-param name="fHideBot" select="$fHideBot" />
<xsl:with-param name="fHideLeft" select="$fHideLeft" />
<xsl:with-param name="fHideRight" select="$fHideRight" />
<xsl:with-param name="fStrikeH" select="$fStrikeH" />
<xsl:with-param name="fStrikeV" select="$fStrikeV" />
<xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
<xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
<xsl:with-param name="sAttribute">
<xsl:call-template name="SReplace">
<xsl:with-param name="sInput" select="$sAttribute" />
<xsl:with-param name="sOrig" select="'top'" />
<xsl:with-param name="sReplacement" select="''" />
</xsl:call-template>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
<xsl:with-param name="fHideBot" select="$fHideBot" />
<xsl:with-param name="fHideLeft" select="$fHideLeft" />
<xsl:with-param name="fHideRight" select="$fHideRight" />
<xsl:with-param name="fStrikeH" select="$fStrikeH" />
<xsl:with-param name="fStrikeV" select="$fStrikeV" />
<xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
<xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
<xsl:with-param name="sAttribute" select="$sAttribute" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="string-length($fHideBot) > 0">
<xsl:choose>
<xsl:when test="$fHideBot=1">
<xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
<xsl:with-param name="fHideLeft" select="$fHideLeft" />
<xsl:with-param name="fHideRight" select="$fHideRight" />
<xsl:with-param name="fStrikeH" select="$fStrikeH" />
<xsl:with-param name="fStrikeV" select="$fStrikeV" />
<xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
<xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
<xsl:with-param name="sAttribute">
<xsl:call-template name="SReplace">
<xsl:with-param name="sInput" select="$sAttribute" />
<xsl:with-param name="sOrig" select="'bottom'" />
<xsl:with-param name="sReplacement" select="''" />
</xsl:call-template>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
<xsl:with-param name="fHideLeft" select="$fHideLeft" />
<xsl:with-param name="fHideRight" select="$fHideRight" />
<xsl:with-param name="fStrikeH" select="$fStrikeH" />
<xsl:with-param name="fStrikeV" select="$fStrikeV" />
<xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
<xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
<xsl:with-param name="sAttribute" select="$sAttribute" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="string-length($fHideLeft) > 0">
<xsl:choose>
<xsl:when test="$fHideLeft=1">
<xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
<xsl:with-param name="fHideRight" select="$fHideRight" />
<xsl:with-param name="fStrikeH" select="$fStrikeH" />
<xsl:with-param name="fStrikeV" select="$fStrikeV" />
<xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
<xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
<xsl:with-param name="sAttribute">
<xsl:call-template name="SReplace">
<xsl:with-param name="sInput" select="$sAttribute" />
<xsl:with-param name="sOrig" select="'left'" />
<xsl:with-param name="sReplacement" select="''" />
</xsl:call-template>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
<xsl:with-param name="fHideRight" select="$fHideRight" />
<xsl:with-param name="fStrikeH" select="$fStrikeH" />
<xsl:with-param name="fStrikeV" select="$fStrikeV" />
<xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
<xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
<xsl:with-param name="sAttribute" select="$sAttribute" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="string-length($fHideRight) > 0">
<xsl:choose>
<xsl:when test="$fHideRight=1">
<xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
<xsl:with-param name="fStrikeH" select="$fStrikeH" />
<xsl:with-param name="fStrikeV" select="$fStrikeV" />
<xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
<xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
<xsl:with-param name="sAttribute">
<xsl:call-template name="SReplace">
<xsl:with-param name="sInput" select="$sAttribute" />
<xsl:with-param name="sOrig" select="'right'" />
<xsl:with-param name="sReplacement" select="''" />
</xsl:call-template>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
<xsl:with-param name="fStrikeH" select="$fStrikeH" />
<xsl:with-param name="fStrikeV" select="$fStrikeV" />
<xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
<xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
<xsl:with-param name="sAttribute" select="$sAttribute" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="string-length($fStrikeH) > 0">
<xsl:choose>
<xsl:when test="$fStrikeH=1">
<xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
<xsl:with-param name="fStrikeV" select="$fStrikeV" />
<xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
<xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
<xsl:with-param name="sAttribute" select="concat($sAttribute, ' horizontalstrike')" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
<xsl:with-param name="fStrikeV" select="$fStrikeV" />
<xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
<xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
<xsl:with-param name="sAttribute" select="$sAttribute" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="string-length($fStrikeV) > 0">
<xsl:choose>
<xsl:when test="$fStrikeV=1">
<xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
<xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
<xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
<xsl:with-param name="sAttribute" select="concat($sAttribute, ' verticalstrike')" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
<xsl:with-param name="fStrikeBLTR" select="$fStrikeBLTR" />
<xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
<xsl:with-param name="sAttribute" select="$sAttribute" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="string-length($fStrikeBLTR) > 0">
<xsl:choose>
<xsl:when test="$fStrikeBLTR=1">
<xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
<xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
<xsl:with-param name="sAttribute" select="concat($sAttribute, ' updiagonalstrike')" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
<xsl:with-param name="fStrikeTLBR" select="$fStrikeTLBR" />
<xsl:with-param name="sAttribute" select="$sAttribute" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="string-length($fStrikeTLBR) > 0">
<xsl:choose>
<xsl:when test="$fStrikeTLBR=1">
<xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
<xsl:with-param name="sAttribute" select="concat($sAttribute, ' downdiagonalstrike')" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="CreateMencloseNotationAttrFromBorderBoxAttr">
<xsl:with-param name="sAttribute" select="$sAttribute" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="notation">
<xsl:value-of select="normalize-space($sAttribute)" />
</xsl:attribute>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Tristate (true, false, neither) from string value -->
<xsl:template name="TFromStrVal">
<xsl:param name="str" />
<xsl:choose>
<xsl:when test="$str = 'on' or $str = '1' or $str = 'true'">1</xsl:when>
<xsl:when test="$str = 'off' or $str = '0' or $str = 'false'">0</xsl:when>
<xsl:otherwise>-1</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Return 0 iff $str is explicitly set to a false value.
Return true otherwise -->
<xsl:template name="ForceFalseStrVal">
<xsl:param name="str" />
<xsl:variable name="tValue">
<xsl:call-template name="TFromStrVal">
<xsl:with-param name="str" select="$str"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$tValue = '0'">0</xsl:when>
<xsl:otherwise>1</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Return 1 iff $str is explicitly set to a true value.
Return false otherwise -->
<xsl:template name="ForceTrueStrVal">
<xsl:param name="str" />
<xsl:variable name="tValue">
<xsl:call-template name="TFromStrVal">
<xsl:with-param name="str" select="$str"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$tValue = '1'">1</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>