html2doc 0.6.6 → 0.6.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 12bd3e1d492aa03c842f52352b18c0145650bb84
4
- data.tar.gz: c45c11401392dcdc05f03d4ca4c1ff71326e329c
3
+ metadata.gz: 9709cfb136997d399cd9860899bb0e63f5f9affc
4
+ data.tar.gz: 8b908e328af8b8b52e47171a23bd79e5dc1404c2
5
5
  SHA512:
6
- metadata.gz: 522afed658b3d1cc6c853f6efad77874400778bce23b68f186721bc7660bab3041ceaa96291ef3af7d4c49bf297c4a26b5080fcd80e1d58e2f513e42ffb13fd0
7
- data.tar.gz: 12e5759f2558959ca6abd89f8c7329bcba74151b7849dc698cc0af8094d2d76e38c60d1f557f0b1dae60d8bf159b53eabfbf0c9f5630f796524e3c9d57c08b9f
6
+ metadata.gz: 01dccf40b7e8c3a25b342d19144092b81569ea84c4782ac1a8ba91966ff5ed2c4c75a1e9f32ded919d74f0ac8428563072287225237954d9a4aac2937aff69d6
7
+ data.tar.gz: 532c6186f6805f37b6e8b5a954ca7881ef0040445395aaade0db30ff6be5e477463445d1e9397c6115edd4db45565aa1a959c0353945e6f1a58bd10f3f476128
data/README.adoc CHANGED
@@ -17,6 +17,8 @@ The gem currently does the following:
17
17
  ** The gem does attempt to repair the MathML input, to bring it in line with Word's OOXML's expectations. If you find any issues with AsciiMath or MathML input, please raise an issue.
18
18
  * Identify any footnotes in the document (defined as hyperlinks with attributes `class = "Footnote"` or `epub:type = "footnote"`), and render them as Microsoft Word footnotes.
19
19
  * Resize any images in the HTML file to fit within the maximum page size. (Word will otherwise crash on reading the document.)
20
+ * Optionally apply list styles with predefined bullet and numbering from a Word CSS to the unordered and ordered lists in the document, restarting numbering for each ordered list.
21
+ * Convert any internal `@id` anchors to `a@name` anchors; Word only hyperlinks to the latter.
20
22
  * Generate a filelist.xml listing of all files to be bundled into the Word document.
21
23
  * Assign the class `MsoNormal` to any paragraphs that do not have a class, so that they can be treated as Normal Style when editing the Word document.
22
24
  * Inject Microsoft Word-specific CSS into the HTML document. If a CSS file is not supplied, the CSS file used is at `lib/html2doc/wordstyle.css` is used by default. Microsoft Word HTML has particular requirements from its CSS, and you should review the sample CSS before replacing it with your own. (This generic CSS can be overridden by CSS already in the HTML document, since the generic CSS is injected at the top of the document.)
@@ -54,13 +56,29 @@ dir:: is the folder that any ancillary files (images, headers, filelist) are to
54
56
  asciimathdelims:: are the AsciiMath delimiters used in the text (an array of an opening and a closing delimiter). If none are provided, no AsciiMath conversion is attempted.
55
57
  liststyles:: a hash of list style labels in Word CSS, which are used to define the behaviour of list item labels (e.g. _i)_ vs _i._). The gem recognises the hash keys `ul`, `ol`. So if the appearance of an ordered list's item labels in the supplied stylesheet is governed by style `@list l1` (e.g. `@list l1:level1 {mso-level-text:"%1\)";}` appears in the stylesheet), call the method with `liststyles:{ol: "l1"}`.
56
58
 
57
- Note that the local CSS stylesheet file contains a variable `FILENAME` for the location of footnote/endnote separators and headers/footers, which are provided in the header HTML file. The gem replaces `FILENAME` with the file nane that the document will be saved as. If you supply your own stylesheet and also wish to use separators or headers/footers, you will likewise need to replace the document name mentioned in your stylesheet with a `FILENAME` string.
59
+ Note that the local CSS stylesheet file contains a variable `FILENAME` for the location of footnote/endnote separators and headers/footers, which are provided in the header HTML file. The gem replaces `FILENAME` with the file name that the document will be saved as. If you supply your own stylesheet and also wish to use separators or headers/footers, you will likewise need to replace the document name mentioned in your stylesheet with a `FILENAME` string.
58
60
 
59
- == Caveat
61
+ == Caveats
62
+
63
+ === HTML
64
+
65
+ The good news is that Word understands HTML.
66
+
67
+ The bad news is that Word's understanding of HTML is HTML 4. In order for bookmarks to work, for example, this gem has to translate `<p id="">` back down into `<p><a name="">`. Word (and this gem) will not do much with HTML 5-specific elements, and if you're generating HTML for automated generation of Word documents, keep your HTML old-fashioned.
68
+
69
+ === CSS
60
70
 
61
71
  The good news with generating a Word document via HTML is that Word understands CSS, and you can determine much of what the Word document looks like by manipulating that CSS. That extends to features that are not part of HTML CSS: if you want to work out how to get Word to do something in CSS, save a Word document that already does what you want as HTML, and inspect the HTML and CSS you get.
62
72
 
63
- The bad news is that Word's implementation of CSS is poorly documented (even if Office HTML is documented in a 1300 page document (online at https://stigmortenmyre.no/mso/, https://www.rodriguezcommaj.com/assets/resources/microsoft-office-html-and-xml-reference.pdf), and the CSS selectors are only partially and selectively implemented. For list styles, for example, `mso-level-text` governs how the list label is displayed; but it is only recognised in a `@list` style: it is ignored in a CSS rule like `ol li`, or in a `style` attribute on a node. Working out the right CSS for what you want will take some trial and error, and you are better placed to try to do things Word's way than the right way.
73
+ The bad news is that Word's implementation of CSS is poorly documented -- even if Office HTML is documented in a 1300 page document (online at https://stigmortenmyre.no/mso/, https://www.rodriguezcommaj.com/assets/resources/microsoft-office-html-and-xml-reference.pdf), and the CSS selectors are only partially and selectively implemented. For list styles, for example, `mso-level-text` governs how the list label is displayed; but it is only recognised in a `@list` style: it is ignored in a CSS rule like `ol li`, or in a `style` attribute on a node. Working out the right CSS for what you want will take some trial and error, and you are better placed to try to do things Word's way than the right way.
74
+
75
+ === XSLT
76
+
77
+ This gem is published with an early draft of the XSLT stylesheet transforming MathML into OOXML, `mml2omml.xsl`, that has published for several years now as part of the https://github.com/TEIC/Stylesheets[TEI stylesheet set]. (We have made some further minor edits to the stylesheet.) The stylesheets have been published under a dual Creative Commons Sharealike/BSD licence.
78
+
79
+ The good news is that the stylesheet is not identical to the stylesheet `mathml2omml.xsl` that is published with Microsoft Word, so it can and has been redistributed.
80
+
81
+ The bad news is that the stylesheet is not identical to the stylesheet `mathml2omml.xsl` that is published with Microsoft Word, so it isn't guaranteed to have identical output. If you want to make sure that your MathML import is identical to what Word currently uses, replace `mml2omml.xsl` with `mathml2omml.xsl`, and edit the gem accordingly for your local installation. On Windows, you will find the stylesheet in the same directory as the `winword.exe` executable. On Mac, right-click on the Word application, and select "Show Package Contents"; you will find the stylesheet under `Contents/Resources`.
64
82
 
65
83
  == Example
66
84
 
data/lib/html2doc/base.rb CHANGED
@@ -43,6 +43,7 @@ module Html2Doc
43
43
  mathml_to_ooml(docxml)
44
44
  lists(docxml, hash[:liststyles])
45
45
  footnotes(docxml)
46
+ bookmarks(docxml)
46
47
  msonormal(docxml)
47
48
  docxml
48
49
  end
@@ -157,6 +158,18 @@ module Html2Doc
157
158
  root.add_namespace(nil, "http://www.w3.org/TR/REC-html40")
158
159
  end
159
160
 
161
+ def self.bookmarks(docxml)
162
+ docxml.xpath("//*[@id][not(@name)][not(@style = 'mso-element:footnote')]").each do |x|
163
+ next if x["id"].empty?
164
+ if x.children.empty?
165
+ x.add_child("<a name='#{x["id"]}'></a>")
166
+ else
167
+ x.children.first.previous = "<a name='#{x["id"]}'></a>"
168
+ end
169
+ x.delete("id")
170
+ end
171
+ end
172
+
160
173
  def self.msonormal(docxml)
161
174
  docxml.xpath("//*[local-name() = 'p'][not(self::*[@class])]").each do |p|
162
175
  p["class"] = "MsoNormal"
data/lib/html2doc/math.rb CHANGED
@@ -7,7 +7,8 @@ require "pp"
7
7
 
8
8
  module Html2Doc
9
9
  @xslt = XML::XSLT.new
10
- @xslt.xsl = File.read(File.join(File.dirname(__FILE__), "mathml2omml.xsl"))
10
+ #@xslt.xsl = File.read(File.join(File.dirname(__FILE__), "mathml2omml.xsl"))
11
+ @xslt.xsl = File.read(File.join(File.dirname(__FILE__), "mml2omml.xsl"))
11
12
 
12
13
  def self.asciimath_to_mathml1(x)
13
14
  AsciiMath.parse(HTMLEntities.new.decode(x)).to_mathml.
@@ -23,7 +24,7 @@ module Html2Doc
23
24
  end.join
24
25
  end
25
26
 
26
- # random fixes that OOXML needs to render properly
27
+ # random fixes to MathML input that OOXML needs to render properly
27
28
  def self.ooxml_cleanup(m)
28
29
  m.xpath(".//xmlns:msup[name(preceding-sibling::*[1])='munderover']",
29
30
  m.document.collect_namespaces).each do |x|
@@ -38,7 +39,8 @@ module Html2Doc
38
39
  docxml.xpath("//*[local-name() = 'math']").each do |m|
39
40
  @xslt.xml = ooxml_cleanup(m)
40
41
  ooxml = @xslt.serve.gsub(/<\?[^>]+>\s*/, "").
41
- gsub(/ xmlns:[^=]+="[^"]+"/, "")
42
+ gsub(/ xmlns(:[^=]+)?="[^"]+"/, "").
43
+ gsub(%r{<(/)?([a-z])}, "<\\1m:\\2")
42
44
  m.swap(ooxml)
43
45
  end
44
46
  end
@@ -0,0 +1,3726 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Beta Version 070708 --><xsl:stylesheet xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
3
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
4
+ xmlns:mml="http://www.w3.org/1998/Math/MathML"
5
+ xmlns="http://www.w3.org/1998/Math/MathML"
6
+ xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"
7
+ version="1.0"
8
+ >
9
+ <!--
10
+ exclude-result-prefixes="mml m w">
11
+ -->
12
+ <xsl:output method="xml" encoding="UTF-8"/>
13
+
14
+
15
+ <xsl:variable name="StrUCAlphabet">ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:variable>
16
+ <xsl:variable name="StrLCAlphabet">abcdefghijklmnopqrstuvwxyz</xsl:variable>
17
+
18
+
19
+ <xsl:template match="/">
20
+ <oMath>
21
+ <xsl:apply-templates mode="mml" />
22
+ </oMath>
23
+ </xsl:template>
24
+
25
+ <!-- %%Template: SReplace
26
+
27
+ Replace all occurences of sOrig in sInput with sReplacement
28
+ and return the resulting string. -->
29
+ <xsl:template name="SReplace">
30
+ <xsl:param name="sInput"/>
31
+ <xsl:param name="sOrig"/>
32
+ <xsl:param name="sReplacement"/>
33
+
34
+ <xsl:choose>
35
+ <xsl:when test="not(contains($sInput, $sOrig))">
36
+ <xsl:value-of select="$sInput"/>
37
+ </xsl:when>
38
+ <xsl:otherwise>
39
+ <xsl:variable name="sBefore" select="substring-before($sInput, $sOrig)"/>
40
+ <xsl:variable name="sAfter" select="substring-after($sInput, $sOrig)"/>
41
+ <xsl:variable name="sAfterProcessed">
42
+ <xsl:call-template name="SReplace">
43
+ <xsl:with-param name="sInput" select="$sAfter"/>
44
+ <xsl:with-param name="sOrig" select="$sOrig"/>
45
+ <xsl:with-param name="sReplacement" select="$sReplacement"/>
46
+ </xsl:call-template>
47
+ </xsl:variable>
48
+
49
+ <xsl:value-of select="concat($sBefore, concat($sReplacement, $sAfterProcessed))"/>
50
+ </xsl:otherwise>
51
+ </xsl:choose>
52
+ </xsl:template>
53
+
54
+ <!-- %%Template: OutputText
55
+
56
+ Post processing on the string given and otherwise do
57
+ a xsl:value-of on it -->
58
+ <xsl:template name="OutputText">
59
+ <xsl:param name="sInput"/>
60
+
61
+ <!-- Add local Variable as you add new post processing tasks -->
62
+
63
+ <!-- 1. Remove any unwanted characters -->
64
+ <xsl:variable name="sCharStrip">
65
+ <xsl:value-of select="translate($sInput, '⁢​', '')"/>
66
+ </xsl:variable>
67
+
68
+ <!-- 2. Replace any characters as needed -->
69
+ <!-- Replace &#x2A75; <-> == -->
70
+ <xsl:variable name="sCharReplace">
71
+ <xsl:call-template name="SReplace">
72
+ <xsl:with-param name="sInput" select="$sCharStrip"/>
73
+ <xsl:with-param name="sOrig" select="'⩵'"/>
74
+ <xsl:with-param name="sReplacement" select="'=='"/>
75
+ </xsl:call-template>
76
+ </xsl:variable>
77
+
78
+ <!-- Finally, return the last value -->
79
+ <xsl:value-of select="$sCharReplace"/>
80
+ </xsl:template>
81
+
82
+
83
+ <!-- Template that determines whether or the given node
84
+ ndCur is a token element that doesn't have an mglyph as
85
+ a child.
86
+ -->
87
+ <xsl:template name="FNonGlyphToken">
88
+ <xsl:param name="ndCur" select="."/>
89
+ <xsl:choose>
90
+ <xsl:when test="$ndCur/self::mml:mi[not(child::mml:mglyph)] | $ndCur/self::mml:mn[not(child::mml:mglyph)] | $ndCur/self::mml:mo[not(child::mml:mglyph)] | $ndCur/self::mml:ms[not(child::mml:mglyph)] | $ndCur/self::mml:mtext[not(child::mml:mglyph)]">1</xsl:when>
91
+ <xsl:otherwise>0</xsl:otherwise>
92
+ </xsl:choose>
93
+ </xsl:template>
94
+
95
+
96
+ <!-- Template used to determine if the current token element (ndCur) is the beginning of a run.
97
+ A token element is the beginning of if:
98
+
99
+ the count of preceding elements is 0
100
+ or
101
+ the directory preceding element is not a non-glyph token.
102
+ -->
103
+ <xsl:template name="FStartOfRun">
104
+ <xsl:param name="ndCur" select="."/>
105
+ <xsl:variable name="fPrecSibNonGlyphToken">
106
+ <xsl:call-template name="FNonGlyphToken">
107
+ <xsl:with-param name="ndCur" select="$ndCur/preceding-sibling::*[1]"/>
108
+ </xsl:call-template>
109
+ </xsl:variable>
110
+ <xsl:choose>
111
+ <xsl:when test="count($ndCur/preceding-sibling::*)=0 or $fPrecSibNonGlyphToken=0">1</xsl:when>
112
+ <xsl:otherwise>0</xsl:otherwise>
113
+ </xsl:choose>
114
+ </xsl:template>
115
+
116
+ <!-- Template that determines if ndCur is the argument of an nary expression.
117
+
118
+ ndCur is the argument of an nary expression if:
119
+
120
+ 1. The preceding sibling is one of the following: munder, mover, msub, msup, munder, msubsup, munderover
121
+ and
122
+ 2. The preceding sibling's child is an nary char as specified by the template "isNary"
123
+ -->
124
+ <xsl:template name="FIsNaryArgument">
125
+ <xsl:param name="ndCur" select="."/>
126
+
127
+ <xsl:variable name="fNary">
128
+ <xsl:call-template name="isNary">
129
+ <xsl:with-param name="ndCur" select="$ndCur/preceding-sibling::*[1]/child::*[1]"/>
130
+ </xsl:call-template>
131
+ </xsl:variable>
132
+ <xsl:choose>
133
+ <xsl:when test="preceding-sibling::*[1][self::mml:munder or self::mml:mover or self::mml:munderover or self::mml:msub or self::mml:msup or self::mml:msubsup] and $fNary='true'">1</xsl:when>
134
+ <xsl:otherwise>0</xsl:otherwise>
135
+ </xsl:choose>
136
+ </xsl:template>
137
+
138
+ <!-- %%Template: mml:mrow | mml:mstyle
139
+
140
+ if this row is the next sibling of an n-ary (i.e. any of
141
+ mover, munder, munderover, msupsub, msup, or msub with
142
+ the base being an n-ary operator) then ignore this. Otherwise
143
+ pass through -->
144
+ <xsl:template mode="mml" match="mml:mrow|mml:mstyle">
145
+ <xsl:variable name="fNaryArgument">
146
+ <xsl:call-template name="FIsNaryArgument">
147
+ <xsl:with-param name="ndCur" select="."/>
148
+ </xsl:call-template>
149
+ </xsl:variable>
150
+ <xsl:if test="$fNaryArgument=0">
151
+ <xsl:variable name="fLinearFrac">
152
+ <xsl:call-template name="FLinearFrac">
153
+ <xsl:with-param name="ndCur" select="."/>
154
+ </xsl:call-template>
155
+ </xsl:variable>
156
+ <xsl:choose>
157
+ <xsl:when test="$fLinearFrac=1">
158
+ <xsl:call-template name="MakeLinearFraction">
159
+ <xsl:with-param name="ndCur" select="."/>
160
+ </xsl:call-template>
161
+ </xsl:when>
162
+ <xsl:otherwise>
163
+ <xsl:variable name="fFunc">
164
+ <xsl:call-template name="FIsFunc">
165
+ <xsl:with-param name="ndCur" select="."/>
166
+ </xsl:call-template>
167
+ </xsl:variable>
168
+ <xsl:choose>
169
+ <xsl:when test="$fFunc=1">
170
+ <xsl:call-template name="WriteFunc">
171
+ <xsl:with-param name="ndCur" select="."/>
172
+ </xsl:call-template>
173
+ </xsl:when>
174
+ <xsl:otherwise>
175
+ <xsl:apply-templates mode="mml"/>
176
+ </xsl:otherwise>
177
+ </xsl:choose>
178
+ </xsl:otherwise>
179
+ </xsl:choose>
180
+ </xsl:if>
181
+ </xsl:template>
182
+ <xsl:template mode="mml"
183
+ match="mml:mi[not(child::mml:mglyph)] | mml:mn[not(child::mml:mglyph)] | mml:mo[not(child::mml:mglyph)] | mml:ms[not(child::mml:mglyph)] | mml:mtext[not(child::mml:mglyph)]">
184
+
185
+ <!-- tokens with mglyphs as children are tranformed
186
+ in a different manner than "normal" token elements.
187
+ Where normal token elements are token elements that
188
+ contain only text -->
189
+ <xsl:variable name="fStartOfRun">
190
+ <xsl:call-template name="FStartOfRun">
191
+ <xsl:with-param name="ndCur" select="."/>
192
+ </xsl:call-template>
193
+ </xsl:variable>
194
+
195
+ <!--In MathML, successive characters that are all part of one string are sometimes listed as separate
196
+ tags based on their type (identifier (mi), name (mn), operator (mo), quoted (ms), literal text (mtext)),
197
+ where said tags act to link one another into one logical run. In order to wrap the text of successive mi's,
198
+ mn's, and mo's into one m:t, we need to denote where a run begins. The beginning of a run is the first mi, mn,
199
+ or mo whose immediately preceding sibling either doesn't exist or is something other than a "normal" mi, mn, mo,
200
+ ms, or mtext tag-->
201
+
202
+ <!-- If this mi/mo/mn/ms . . . is part the numerator or denominator of a linear fraction, then don't collect. -->
203
+ <xsl:variable name="fLinearFracParent">
204
+ <xsl:call-template name="FLinearFrac">
205
+ <xsl:with-param name="ndCur" select="parent::*"/>
206
+ </xsl:call-template>
207
+ </xsl:variable>
208
+ <!-- If this mi/mo/mn/ms . . . is part of the name of a function, then don't collect. -->
209
+ <xsl:variable name="fFunctionName">
210
+ <xsl:call-template name="FIsFunc">
211
+ <xsl:with-param name="ndCur" select="parent::*"/>
212
+ </xsl:call-template>
213
+ </xsl:variable>
214
+ <xsl:variable name="fShouldCollect"
215
+ select="($fLinearFracParent=0 and $fFunctionName=0) and (parent::mml:mrow or parent::mml:mstyle or parent::mml:msqrt or parent::mml:menclose or parent::mml:math or parent::mml:mphantom or parent::mml:mtd or parent::mml:maction)"/>
216
+
217
+ <!--In MathML, the meaning of the different parts that make up mathematical structures, such as a fraction
218
+ having a numerator and a denominator, is determined by the relative order of those different parts.
219
+ For instance, In a fraction, the numerator is the first child and the denominator is the second child.
220
+ To allow for more complex structures, MathML allows one to link a group of mi, mn, and mo's together
221
+ using the mrow, or mstyle tags. The mi, mn, and mo's found within any of the above tags are considered
222
+ one run. Therefore, if the parent of any mi, mn, or mo is found to be an mrow or mstyle, then the contiguous
223
+ mi, mn, and mo's will be considered one run.-->
224
+ <xsl:choose>
225
+ <xsl:when test="$fShouldCollect">
226
+ <xsl:choose>
227
+ <xsl:when test="$fStartOfRun=1">
228
+ <!--If this is the beginning of the run, pass all run attributes to CreateRunWithSameProp.-->
229
+ <xsl:call-template name="CreateRunWithSameProp">
230
+ <xsl:with-param name="mathbackground">
231
+ <!-- Look for the unqualified mathml attribute mathbackground.
232
+ Fall back to the qualified mathml attribute if necessary.
233
+ This priority of unqualified over qualified will be
234
+ followed throughout this xslt. -->
235
+ <xsl:choose>
236
+ <xsl:when test="@mathbackground">
237
+ <xsl:value-of select="@mathbackground"/>
238
+ </xsl:when>
239
+ <xsl:otherwise>
240
+ <xsl:value-of select="@mml:mathbackground"/>
241
+ </xsl:otherwise>
242
+ </xsl:choose>
243
+ </xsl:with-param>
244
+ <xsl:with-param name="mathcolor">
245
+ <xsl:choose>
246
+ <xsl:when test="@mathcolor">
247
+ <xsl:value-of select="@mathcolor"/>
248
+ </xsl:when>
249
+ <xsl:otherwise>
250
+ <xsl:value-of select="@mml:mathcolor"/>
251
+ </xsl:otherwise>
252
+ </xsl:choose>
253
+ </xsl:with-param>
254
+ <xsl:with-param name="mathvariant">
255
+ <xsl:choose>
256
+ <xsl:when test="@mathvariant">
257
+ <xsl:value-of select="@mathvariant"/>
258
+ </xsl:when>
259
+ <xsl:otherwise>
260
+ <xsl:value-of select="@mml:mathvariant"/>
261
+ </xsl:otherwise>
262
+ </xsl:choose>
263
+ </xsl:with-param>
264
+ <xsl:with-param name="color">
265
+ <xsl:choose>
266
+ <xsl:when test="@color">
267
+ <xsl:value-of select="@color"/>
268
+ </xsl:when>
269
+ <xsl:otherwise>
270
+ <xsl:value-of select="@mml:color"/>
271
+ </xsl:otherwise>
272
+ </xsl:choose>
273
+ </xsl:with-param>
274
+ <xsl:with-param name="font-family">
275
+ <xsl:choose>
276
+ <xsl:when test="@font-family">
277
+ <xsl:value-of select="@font-family"/>
278
+ </xsl:when>
279
+ <xsl:otherwise>
280
+ <xsl:value-of select="@mml:font-family"/>
281
+ </xsl:otherwise>
282
+ </xsl:choose>
283
+ </xsl:with-param>
284
+ <xsl:with-param name="fontsize">
285
+ <xsl:choose>
286
+ <xsl:when test="@fontsize">
287
+ <xsl:value-of select="@fontsize"/>
288
+ </xsl:when>
289
+ <xsl:otherwise>
290
+ <xsl:value-of select="@mml:fontsize"/>
291
+ </xsl:otherwise>
292
+ </xsl:choose>
293
+ </xsl:with-param>
294
+ <xsl:with-param name="fontstyle">
295
+ <xsl:choose>
296
+ <xsl:when test="@fontstyle">
297
+ <xsl:value-of select="@fontstyle"/>
298
+ </xsl:when>
299
+ <xsl:otherwise>
300
+ <xsl:value-of select="@mml:fontstyle"/>
301
+ </xsl:otherwise>
302
+ </xsl:choose>
303
+ </xsl:with-param>
304
+ <xsl:with-param name="fontweight">
305
+ <xsl:choose>
306
+ <xsl:when test="@fontweight">
307
+ <xsl:value-of select="@fontweight"/>
308
+ </xsl:when>
309
+ <xsl:otherwise>
310
+ <xsl:value-of select="@mml:fontweight"/>
311
+ </xsl:otherwise>
312
+ </xsl:choose>
313
+ </xsl:with-param>
314
+ <xsl:with-param name="mathsize">
315
+ <xsl:choose>
316
+ <xsl:when test="@mathsize">
317
+ <xsl:value-of select="@mathsize"/>
318
+ </xsl:when>
319
+ <xsl:otherwise>
320
+ <xsl:value-of select="@mml:mathsize"/>
321
+ </xsl:otherwise>
322
+ </xsl:choose>
323
+ </xsl:with-param>
324
+ <xsl:with-param name="ndTokenFirst" select="."/>
325
+ </xsl:call-template>
326
+ </xsl:when>
327
+ </xsl:choose>
328
+ </xsl:when>
329
+ <xsl:otherwise>
330
+ <!--Only one element will be part of run-->
331
+ <r>
332
+ <!--Create Run Properties based on current node's attributes-->
333
+ <xsl:call-template name="CreateRunProp">
334
+ <xsl:with-param name="mathvariant">
335
+ <xsl:choose>
336
+ <xsl:when test="@mathvariant">
337
+ <xsl:value-of select="@mathvariant"/>
338
+ </xsl:when>
339
+ <xsl:otherwise>
340
+ <xsl:value-of select="@mml:mathvariant"/>
341
+ </xsl:otherwise>
342
+ </xsl:choose>
343
+ </xsl:with-param>
344
+ <xsl:with-param name="fontstyle">
345
+ <xsl:choose>
346
+ <xsl:when test="@fontstyle">
347
+ <xsl:value-of select="@fontstyle"/>
348
+ </xsl:when>
349
+ <xsl:otherwise>
350
+ <xsl:value-of select="@mml:fontstyle"/>
351
+ </xsl:otherwise>
352
+ </xsl:choose>
353
+ </xsl:with-param>
354
+ <xsl:with-param name="fontweight">
355
+ <xsl:choose>
356
+ <xsl:when test="@fontweight">
357
+ <xsl:value-of select="@fontweight"/>
358
+ </xsl:when>
359
+ <xsl:otherwise>
360
+ <xsl:value-of select="@mml:fontweight"/>
361
+ </xsl:otherwise>
362
+ </xsl:choose>
363
+ </xsl:with-param>
364
+ <xsl:with-param name="mathcolor">
365
+ <xsl:choose>
366
+ <xsl:when test="@mathcolor">
367
+ <xsl:value-of select="@mathcolor"/>
368
+ </xsl:when>
369
+ <xsl:otherwise>
370
+ <xsl:value-of select="@mml:mathcolor"/>
371
+ </xsl:otherwise>
372
+ </xsl:choose>
373
+ </xsl:with-param>
374
+ <xsl:with-param name="mathsize">
375
+ <xsl:choose>
376
+ <xsl:when test="@mathsize">
377
+ <xsl:value-of select="@mathsize"/>
378
+ </xsl:when>
379
+ <xsl:otherwise>
380
+ <xsl:value-of select="@mml:mathsize"/>
381
+ </xsl:otherwise>
382
+ </xsl:choose>
383
+ </xsl:with-param>
384
+ <xsl:with-param name="color">
385
+ <xsl:choose>
386
+ <xsl:when test="@color">
387
+ <xsl:value-of select="@color"/>
388
+ </xsl:when>
389
+ <xsl:otherwise>
390
+ <xsl:value-of select="@mml:color"/>
391
+ </xsl:otherwise>
392
+ </xsl:choose>
393
+ </xsl:with-param>
394
+ <xsl:with-param name="fontsize">
395
+ <xsl:choose>
396
+ <xsl:when test="@fontsize">
397
+ <xsl:value-of select="@fontsize"/>
398
+ </xsl:when>
399
+ <xsl:otherwise>
400
+ <xsl:value-of select="@mml:fontsize"/>
401
+ </xsl:otherwise>
402
+ </xsl:choose>
403
+ </xsl:with-param>
404
+ <xsl:with-param name="ndCur" select="."/>
405
+ <xsl:with-param name="fNor">
406
+ <xsl:call-template name="FNor">
407
+ <xsl:with-param name="ndCur" select="."/>
408
+ </xsl:call-template>
409
+ </xsl:with-param>
410
+ <xsl:with-param name="fLit">
411
+ <xsl:call-template name="FLit">
412
+ <xsl:with-param name="ndCur" select="."/>
413
+ </xsl:call-template>
414
+ </xsl:with-param>
415
+ </xsl:call-template>
416
+ <t>
417
+ <xsl:call-template name="OutputText">
418
+ <xsl:with-param name="sInput" select="normalize-space(.)"/>
419
+ </xsl:call-template>
420
+ </t>
421
+ </r>
422
+ </xsl:otherwise>
423
+ </xsl:choose>
424
+ </xsl:template>
425
+
426
+ <!-- %%Template: CreateRunWithSameProp
427
+ -->
428
+ <xsl:template name="CreateRunWithSameProp">
429
+ <xsl:param name="mathbackground"/>
430
+ <xsl:param name="mathcolor"/>
431
+ <xsl:param name="mathvariant"/>
432
+ <xsl:param name="color"/>
433
+ <xsl:param name="font-family"/>
434
+ <xsl:param name="fontsize"/>
435
+ <xsl:param name="fontstyle"/>
436
+ <xsl:param name="fontweight"/>
437
+ <xsl:param name="mathsize"/>
438
+ <xsl:param name="ndTokenFirst"/>
439
+
440
+ <!--Given mathcolor, color, mstyle's (ancestor) color, and precedence of
441
+ said attributes, determine the actual color of the current run-->
442
+ <xsl:variable name="sColorPropCur">
443
+ <xsl:choose>
444
+ <xsl:when test="$mathcolor!=''">
445
+ <xsl:value-of select="$mathcolor"/>
446
+ </xsl:when>
447
+ <xsl:when test="$color!=''">
448
+ <xsl:value-of select="$color"/>
449
+ </xsl:when>
450
+ <xsl:when test="$ndTokenFirst/ancestor::mml:mstyle[@color][1]/@color!=''">
451
+ <xsl:value-of select="$ndTokenFirst/ancestor::mml:mstyle[@color][1]/@color"/>
452
+ </xsl:when>
453
+ <xsl:when test="$ndTokenFirst/ancestor::mml:mstyle[@mml:color][1]/@mml:color!=''">
454
+ <xsl:value-of select="$ndTokenFirst/ancestor::mml:mstyle[@color][1]/@mml:color"/>
455
+ </xsl:when>
456
+ <xsl:otherwise>
457
+ <xsl:value-of select="''"/>
458
+ </xsl:otherwise>
459
+ </xsl:choose>
460
+ </xsl:variable>
461
+
462
+ <!--Given mathsize, and fontsize and precedence of said attributes,
463
+ determine the actual font size of the current run-->
464
+ <xsl:variable name="sSzCur">
465
+ <xsl:choose>
466
+ <xsl:when test="$mathsize!=''">
467
+ <xsl:value-of select="$mathsize"/>
468
+ </xsl:when>
469
+ <xsl:when test="$fontsize!=''">
470
+ <xsl:value-of select="$fontsize"/>
471
+ </xsl:when>
472
+ <xsl:otherwise>
473
+ <xsl:value-of select="''"/>
474
+ </xsl:otherwise>
475
+ </xsl:choose>
476
+ </xsl:variable>
477
+
478
+ <!--Given mathvariant, fontstyle, and fontweight, and precedence of
479
+ the attributes, determine the actual font of the current run-->
480
+ <xsl:variable name="sFontCur">
481
+ <xsl:call-template name="GetFontCur">
482
+ <xsl:with-param name="mathvariant" select="$mathvariant"/>
483
+ <xsl:with-param name="fontstyle" select="$fontstyle"/>
484
+ <xsl:with-param name="fontweight" select="$fontweight"/>
485
+ <xsl:with-param name="ndCur" select="$ndTokenFirst"/>
486
+ </xsl:call-template>
487
+ </xsl:variable>
488
+
489
+ <!-- The omml equivalent structure for mml:mtext is an omml run with the run property m:nor (normal) set.
490
+ Therefore, we can only collect mtexts with other mtext elements. Suppose the $ndTokenFirst is an
491
+ mml:mtext, then if any of its following siblings are to be grouped, they must also be mml:text elements.
492
+ The inverse is also true, suppose the $ndTokenFirst isn't an mml:mtext, then if any of its following siblings
493
+ are to be grouped with $ndTokenFirst, they can't be mml:mtext elements-->
494
+ <xsl:variable name="fNdTokenFirstIsMText">
495
+ <xsl:choose>
496
+ <xsl:when test="$ndTokenFirst/self::mml:mtext">1</xsl:when>
497
+ <xsl:otherwise>0</xsl:otherwise>
498
+ </xsl:choose>
499
+ </xsl:variable>
500
+
501
+ <!--In order to determine the length of the run, we will find the number of nodes before the inital node in the run and
502
+ the number of nodes before the first node that DOES NOT belong to the current run. The number of nodes that will
503
+ be printed is One Less than the difference between the latter and the former-->
504
+
505
+ <!--Find index of current node-->
506
+ <xsl:variable name="nndBeforeFirst" select="count($ndTokenFirst/preceding-sibling::*)"/>
507
+
508
+ <!--Find index of next change in run properties.
509
+
510
+ The basic idea is that we want to find the position of the last node in the longest
511
+ sequence of nodes, starting from ndTokenFirst, that can be grouped into a run. For
512
+ example, nodes A and B can be grouped together into the same run iff they have the same
513
+ props.
514
+
515
+ To accomplish this grouping, we want to find the next sibling to ndTokenFirst that shouldn't be
516
+ included in the run of text. We do this by counting the number of elements that precede the first
517
+ such element that doesn't belong. The xpath that accomplishes this is below.
518
+
519
+ Count the number of siblings the precede the first element after ndTokenFirst that shouldn't belong.
520
+ count($ndTokenFirst/following-sibling::*[ . . . ][1]/preceding-sibling::*)
521
+
522
+ Now, the hard part to this is what is represented by the '. . .' above. This conditional expression is
523
+ defining what elements *don't* belong to the current run. The conditions are as follows:
524
+
525
+ The element is not a token element (mi, mn, mo, ms, or mtext)
526
+
527
+ or
528
+
529
+ The token element contains a glyph child (this is handled separately).
530
+
531
+ or
532
+
533
+ The token is an mtext and the run didn't start with an mtext, or the token isn't an mtext and the run started
534
+ with an mtext. We do this check because mtext transforms into an omml m:nor property, and thus, these mtext
535
+ token elements need to be grouped separately from other token elements.
536
+
537
+ // We do an or not( . . . ), because it was easier to define what token elements match than how they don't match.
538
+ // Thus, this inner '. . .' defines how token attributes equate to one another. We add the 'not' outside of to accomplish
539
+ // the goal of the outer '. . .', which is the find the next element that *doesn't* match.
540
+ or not(
541
+ The background colors match.
542
+
543
+ and
544
+
545
+ The current font (sFontCur) matches the mathvariant
546
+
547
+ or
548
+
549
+ sFontCur is normal and matches the current font characteristics
550
+
551
+ or
552
+
553
+ sFontCur is italic and matches the current font characteristics
554
+
555
+ or
556
+
557
+ . . .
558
+
559
+ and
560
+
561
+ The font family matches the current font family.
562
+ ) // end of not().-->
563
+ <xsl:variable name="nndBeforeLim"
564
+ select="count($ndTokenFirst/following-sibling::* [(not(self::mml:mi) and not(self::mml:mn) and not(self::mml:mo) and not(self::mml:ms) and not(self::mml:mtext)) or (self::mml:mi[child::mml:mglyph] or self::mml:mn[child::mml:mglyph] or self::mml:mo[child::mml:mglyph] or self::mml:ms[child::mml:mglyph] or self::mml:mtext[child::mml:mglyph]) or (($fNdTokenFirstIsMText=1 and not(self::mml:mtext)) or ($fNdTokenFirstIsMText=0 and self::mml:mtext)) or not( ((($sFontCur=@mathvariant or $sFontCur=@mml:mathvariant) or ($sFontCur='normal' and ((@mathvariant='normal' or @mml:mathvariant='normal') or (((not(@mathvariant) or @mathvariant='') and (not(@mml:mathvariant) or @mml:mathvariant='')) and ( ((@fontstyle='normal' or @mml:fontstyle='normal') and (not(@fontweight='bold') and not(@mml:fontweight='bold'))) or (self::mml:mi and string-length(normalize-space(.)) &gt; 1) ) ) ) ) or ($sFontCur='italic' and ((@mathvariant='italic' or @mml:mathvariant='italic') or (((not(@mathvariant) or @mathvariant='') and (not(@mml:mathvariant) or @mml:mathvariant='')) and ( ((@fontstyle='italic' or @mml:fontstyle='italic') and (not(@fontweight='bold') and not(@mml:fontweight='bold'))) or (self::mml:mn or self::mml:mo or (self::mml:mi and string-length(normalize-space(.)) &lt;= 1)) ) ) ) ) or ($sFontCur='bold' and ((@mathvariant='bold' or @mml:mathvariant='bold') or (((not(@mathvariant) or @mathvariant='') and (not(@mml:mathvariant) or @mml:mathvariant='')) and ( ((@fontweight='bold' or @mml:fontweight='bold') and ((@fontstyle='normal' or @mml:fontstyle='normal') or (self::mml:mi and string-length(normalize-space(.)) &lt;= 1)) ) ) ) ) ) or (($sFontCur='bi' or $sFontCur='bold-italic') and ( (@mathvariant='bold-italic' or @mml:mathvariant='bold-italic') or (((not(@mathvariant) or @mathvariant='') and (not(@mml:mathvariant) or @mml:mathvariant='')) and ( ((@fontweight='bold' or @mml:fontweight='bold') and (@fontstyle='italic' or @mml:fontstyle='italic')) or ((@fontweight='bold' or @mml:fontweight='bold') and (self::mml:mn or self::mml:mo or (self::mml:mi and string-length(normalize-space(.)) &lt;= 1))) ) ) ) ) or (($sFontCur='' and ( ((not(@mathvariant) or @mathvariant='') and (not(@mml:mathvariant) or @mml:mathvariant='') and (not(@fontstyle) or @fontstyle='') and (not(@mml:fontstyle) or @mml:fontstyle='') and (not(@fontweight)or @fontweight='') and (not(@mml:fontweight) or @mml:fontweight='') ) or (@mathvariant='italic' or @mml:mathvariant='italic') or ( ((not(@mathvariant) or @mathvariant='') and (not(@mml:mathvariant) or @mml:mathvariant='')) and ( (((@fontweight='normal' or @mml:fontweight='normal') and (@fontstyle='italic' or @mml:fontstyle='italic')) ) or ((not(@fontweight) or @fontweight='') and (not(@mml:fontweight) or @mml:fontweight='')) and (@fontstyle='italic' or @mml:fontstyle='italic') or ((not(@fontweight) or @fontweight='') and (not(@mml:fontweight) or @mml:fontweight='')) and (not(@fontstyle) or @fontstyle='') and (not(@mml:fontstyle) or @mml:fontstyle='')) ) ) )) or ($sFontCur='normal' and ((self::mml:mi and (not(@mathvariant) or @mathvariant='') and (not(@mml:mathvariant) or @mml:mathvariant) and (not(@fontstyle) or @fontstyle='') and (not(@mml:fontstyle) or @mml:fontstyle='') and (not(@fontweight) or @fontweight='') and (not(@mml:fontweight) or @mml:fontweight='') and (string-length(normalize-space(.)) &gt; 1) ) or ((self::mml:ms or self::mml:mtext) and (not(@mathvariant) or @mathvariant='') and (not(@mml:mathvariant) or @mml:mathvariant) and (not(@fontstyle) or @fontstyle) and (not(@fontstyle) or @fontstyle='') and (not(@fontweight) or @fontweight) and (not(@mml:fontweight) or @mml:fontweight='') ) ) ) ) and (($font-family = @font-family or $font-family = @mml:font-family) or (($font-family='' or not($font-family)) and (not(@font-family) or @font-family='') and (not(@mml:font-family) or @mml:font-family='') ) ) )) ][1]/preceding-sibling::*)"/>
565
+
566
+ <xsl:variable name="cndRun" select="$nndBeforeLim - $nndBeforeFirst"/>
567
+
568
+ <!--Contiguous groups of like-property mi, mn, and mo's are separated by non- mi, mn, mo tags, or mi,mn, or mo
569
+ tags with different properties. nndBeforeLim is the number of nodes before the next tag which separates contiguous
570
+ groups of like-property mi, mn, and mo's. Knowing this delimiting tag allows for the aggregation of the correct
571
+ number of mi, mn, and mo tags.-->
572
+ <r>
573
+
574
+ <!--The beginning and ending of the current run has been established. Now we should open a run element-->
575
+ <xsl:choose>
576
+
577
+ <!--If cndRun > 0, then there is a following diffrent prop, or non- Token,
578
+ although there may or may not have been a preceding different prop, or non-
579
+ Token-->
580
+ <xsl:when test="$cndRun &gt; 0">
581
+ <xsl:call-template name="CreateRunProp">
582
+ <xsl:with-param name="mathvariant" select="$mathvariant"/>
583
+ <xsl:with-param name="fontstyle" select="$fontstyle"/>
584
+ <xsl:with-param name="fontweight" select="$fontweight"/>
585
+ <xsl:with-param name="mathcolor" select="$mathcolor"/>
586
+ <xsl:with-param name="mathsize" select="$mathsize"/>
587
+ <xsl:with-param name="color" select="$color"/>
588
+ <xsl:with-param name="fontsize" select="$fontsize"/>
589
+ <xsl:with-param name="ndCur" select="$ndTokenFirst"/>
590
+ <xsl:with-param name="fNor">
591
+ <xsl:call-template name="FNor">
592
+ <xsl:with-param name="ndCur" select="$ndTokenFirst"/>
593
+ </xsl:call-template>
594
+ </xsl:with-param>
595
+ <xsl:with-param name="fLit">
596
+ <xsl:call-template name="FLit">
597
+ <xsl:with-param name="ndCur" select="$ndTokenFirst"/>
598
+ </xsl:call-template>
599
+ </xsl:with-param>
600
+ </xsl:call-template>
601
+ <t>
602
+ <xsl:call-template name="OutputText">
603
+ <xsl:with-param name="sInput">
604
+ <xsl:choose>
605
+ <xsl:when test="namespace-uri($ndTokenFirst) = 'http://www.w3.org/1998/Math/MathML' and local-name($ndTokenFirst) = 'ms'">
606
+ <xsl:call-template name="OutputMs">
607
+ <xsl:with-param name="msCur" select="$ndTokenFirst"/>
608
+ </xsl:call-template>
609
+ </xsl:when>
610
+ <xsl:otherwise>
611
+ <xsl:value-of select="normalize-space($ndTokenFirst)"/>
612
+ </xsl:otherwise>
613
+ </xsl:choose>
614
+ <xsl:for-each select="$ndTokenFirst/following-sibling::*[position() &lt; $cndRun]">
615
+ <xsl:choose>
616
+ <xsl:when test="namespace-uri(.) = 'http://www.w3.org/1998/Math/MathML' and local-name(.) = 'ms'">
617
+ <xsl:call-template name="OutputMs">
618
+ <xsl:with-param name="msCur" select="."/>
619
+ </xsl:call-template>
620
+ </xsl:when>
621
+ <xsl:otherwise>
622
+ <xsl:value-of select="normalize-space(.)"/>
623
+ </xsl:otherwise>
624
+ </xsl:choose>
625
+ </xsl:for-each>
626
+ </xsl:with-param>
627
+ </xsl:call-template>
628
+ </t>
629
+ </xsl:when>
630
+ <xsl:otherwise>
631
+
632
+ <!--if cndRun lt;= 0, then iNextNonToken = 0,
633
+ and iPrecNonToken gt;= 0. In either case, b/c there
634
+ is no next different property or non-Token
635
+ (which is implied by the nndBeforeLast being equal to 0)
636
+ you can put all the remaining mi, mn, and mo's into one
637
+ group.-->
638
+ <xsl:call-template name="CreateRunProp">
639
+ <xsl:with-param name="mathvariant" select="$mathvariant"/>
640
+ <xsl:with-param name="fontstyle" select="$fontstyle"/>
641
+ <xsl:with-param name="fontweight" select="$fontweight"/>
642
+ <xsl:with-param name="mathcolor" select="$mathcolor"/>
643
+ <xsl:with-param name="mathsize" select="$mathsize"/>
644
+ <xsl:with-param name="color" select="$color"/>
645
+ <xsl:with-param name="fontsize" select="$fontsize"/>
646
+ <xsl:with-param name="ndCur" select="$ndTokenFirst"/>
647
+ <xsl:with-param name="fNor">
648
+ <xsl:call-template name="FNor">
649
+ <xsl:with-param name="ndCur" select="$ndTokenFirst"/>
650
+ </xsl:call-template>
651
+ </xsl:with-param>
652
+ <xsl:with-param name="fLit">
653
+ <xsl:call-template name="FLit">
654
+ <xsl:with-param name="ndCur" select="$ndTokenFirst"/>
655
+ </xsl:call-template>
656
+ </xsl:with-param>
657
+ </xsl:call-template>
658
+ <t>
659
+
660
+ <!--Create the Run, first output current, then in a
661
+ for-each, because all the following siblings are
662
+ mn, mi, and mo's that conform to the run's properties,
663
+ group them together-->
664
+ <xsl:call-template name="OutputText">
665
+ <xsl:with-param name="sInput">
666
+ <xsl:choose>
667
+ <xsl:when test="namespace-uri($ndTokenFirst) = 'http://www.w3.org/1998/Math/MathML' and local-name($ndTokenFirst) = 'ms'">
668
+ <xsl:call-template name="OutputMs">
669
+ <xsl:with-param name="msCur" select="$ndTokenFirst"/>
670
+ </xsl:call-template>
671
+ </xsl:when>
672
+ <xsl:otherwise>
673
+ <xsl:value-of select="normalize-space($ndTokenFirst)"/>
674
+ </xsl:otherwise>
675
+ </xsl:choose>
676
+ <xsl:for-each select="$ndTokenFirst/following-sibling::*[self::mml:mi or self::mml:mn or self::mml:mo or self::mml:ms or self::mml:mtext]">
677
+ <xsl:choose>
678
+ <xsl:when test="namespace-uri(.) = 'http://www.w3.org/1998/Math/MathML' and local-name(.) = 'ms'">
679
+ <xsl:call-template name="OutputMs">
680
+ <xsl:with-param name="msCur" select="."/>
681
+ </xsl:call-template>
682
+ </xsl:when>
683
+ <xsl:otherwise>
684
+ <xsl:value-of select="normalize-space(.)"/>
685
+ </xsl:otherwise>
686
+ </xsl:choose>
687
+ </xsl:for-each>
688
+ </xsl:with-param>
689
+ </xsl:call-template>
690
+ </t>
691
+ </xsl:otherwise>
692
+ </xsl:choose>
693
+ </r>
694
+
695
+ <!--The run was terminated by an mi, mn, mo, ms, or mtext with different properties,
696
+ therefore, call-template CreateRunWithSameProp, using cndRun+1 node as new start node-->
697
+ <xsl:if test="$nndBeforeLim!=0 and ($ndTokenFirst/following-sibling::*[$cndRun]/self::mml:mi or $ndTokenFirst/following-sibling::*[$cndRun]/self::mml:mn or $ndTokenFirst/following-sibling::*[$cndRun]/self::mml:mo or $ndTokenFirst/following-sibling::*[$cndRun]/self::mml:ms or $ndTokenFirst/following-sibling::*[$cndRun]/self::mml:mtext) and (count($ndTokenFirst/following-sibling::*[$cndRun]/mml:mglyph) = 0)">
698
+ <xsl:call-template name="CreateRunWithSameProp">
699
+ <xsl:with-param name="mathbackground">
700
+ <xsl:choose>
701
+ <xsl:when test="$ndTokenFirst/following-sibling::*[$cndRun]/@mathbackground">
702
+ <xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mathbackground"/>
703
+ </xsl:when>
704
+ <xsl:otherwise>
705
+ <xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mml:mathbackground"/>
706
+ </xsl:otherwise>
707
+ </xsl:choose>
708
+ </xsl:with-param>
709
+ <xsl:with-param name="mathcolor">
710
+ <xsl:choose>
711
+ <xsl:when test="$ndTokenFirst/following-sibling::*[$cndRun]/@mathcolor">
712
+ <xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mathcolor"/>
713
+ </xsl:when>
714
+ <xsl:otherwise>
715
+ <xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mml:mathcolor"/>
716
+ </xsl:otherwise>
717
+ </xsl:choose>
718
+ </xsl:with-param>
719
+ <xsl:with-param name="mathvariant">
720
+ <xsl:choose>
721
+ <xsl:when test="$ndTokenFirst/following-sibling::*[$cndRun]/@mathvariant">
722
+ <xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mathvariant"/>
723
+ </xsl:when>
724
+ <xsl:otherwise>
725
+ <xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mml:mathvariant"/>
726
+ </xsl:otherwise>
727
+ </xsl:choose>
728
+ </xsl:with-param>
729
+ <xsl:with-param name="color">
730
+ <xsl:choose>
731
+ <xsl:when test="$ndTokenFirst/following-sibling::*[$cndRun]/@color">
732
+ <xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@color"/>
733
+ </xsl:when>
734
+ <xsl:otherwise>
735
+ <xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mml:color"/>
736
+ </xsl:otherwise>
737
+ </xsl:choose>
738
+ </xsl:with-param>
739
+ <xsl:with-param name="font-family">
740
+ <xsl:choose>
741
+ <xsl:when test="$ndTokenFirst/following-sibling::*[$cndRun]/@font-family">
742
+ <xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@font-family"/>
743
+ </xsl:when>
744
+ <xsl:otherwise>
745
+ <xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mml:font-family"/>
746
+ </xsl:otherwise>
747
+ </xsl:choose>
748
+ </xsl:with-param>
749
+ <xsl:with-param name="fontsize">
750
+ <xsl:choose>
751
+ <xsl:when test="$ndTokenFirst/following-sibling::*[$cndRun]/@fontsize">
752
+ <xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@fontsize"/>
753
+ </xsl:when>
754
+ <xsl:otherwise>
755
+ <xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mml:fontsize"/>
756
+ </xsl:otherwise>
757
+ </xsl:choose>
758
+ </xsl:with-param>
759
+ <xsl:with-param name="fontstyle">
760
+ <xsl:choose>
761
+ <xsl:when test="$ndTokenFirst/following-sibling::*[$cndRun]/@fontstyle">
762
+ <xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@fontstyle"/>
763
+ </xsl:when>
764
+ <xsl:otherwise>
765
+ <xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mml:fontstyle"/>
766
+ </xsl:otherwise>
767
+ </xsl:choose>
768
+ </xsl:with-param>
769
+ <xsl:with-param name="fontweight">
770
+ <xsl:choose>
771
+ <xsl:when test="$ndTokenFirst/following-sibling::*[$cndRun]/@fontweight">
772
+ <xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@fontweight"/>
773
+ </xsl:when>
774
+ <xsl:otherwise>
775
+ <xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mml:fontweight"/>
776
+ </xsl:otherwise>
777
+ </xsl:choose>
778
+ </xsl:with-param>
779
+ <xsl:with-param name="mathsize">
780
+ <xsl:choose>
781
+ <xsl:when test="$ndTokenFirst/following-sibling::*[$cndRun]/@mathsize">
782
+ <xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mathsize"/>
783
+ </xsl:when>
784
+ <xsl:otherwise>
785
+ <xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mml:mathsize"/>
786
+ </xsl:otherwise>
787
+ </xsl:choose>
788
+ </xsl:with-param>
789
+ <xsl:with-param name="ndTokenFirst" select="$ndTokenFirst/following-sibling::*[$cndRun]"/>
790
+ </xsl:call-template>
791
+ </xsl:if>
792
+ </xsl:template>
793
+
794
+ <!-- %%Template: FNor
795
+ Given the context of ndCur, determine if ndCur should be omml's normal style.
796
+ -->
797
+ <xsl:template name="FNor">
798
+ <xsl:param name="ndCur" select="."/>
799
+ <xsl:choose>
800
+ <!-- Is the current node an mml:mtext, or if this is an mglyph whose parent is
801
+ an mml:mtext. -->
802
+ <xsl:when test="$ndCur/self::mml:mtext or ($ndCur/self::mml:mglyph and parent::mml:mtext)">1</xsl:when>
803
+ <xsl:otherwise>0</xsl:otherwise>
804
+ </xsl:choose>
805
+ </xsl:template>
806
+
807
+ <!-- %%Template: FLit
808
+ Given the context of ndCur, determine if ndCur should have the
809
+ run omml property of lit (literal, no build up).
810
+ -->
811
+ <xsl:template name="FLit">
812
+ <xsl:param name="ndCur" select="."/>
813
+ <xsl:variable name="sLowerActiontype">
814
+ <xsl:choose>
815
+ <xsl:when test="$ndCur/ancestor::mml:maction[@actiontype='lit']/@actiontype">
816
+ <xsl:value-of select="translate($ndCur/ancestor::mml:maction[@actiontype='lit']/@actiontype, $StrUCAlphabet, $StrLCAlphabet)"/>
817
+ </xsl:when>
818
+ <xsl:otherwise>
819
+ <xsl:value-of select="translate($ndCur/ancestor::mml:maction[@actiontype='lit']/@mml:actiontype, $StrUCAlphabet, $StrLCAlphabet)"/>
820
+ </xsl:otherwise>
821
+ </xsl:choose>
822
+ </xsl:variable>
823
+ <xsl:choose>
824
+ <xsl:when test="$sLowerActiontype='lit'">1</xsl:when>
825
+ <xsl:otherwise>0</xsl:otherwise>
826
+ </xsl:choose>
827
+ </xsl:template>
828
+
829
+ <!-- %%Template: CreateRunProp
830
+ -->
831
+ <xsl:template name="CreateRunProp">
832
+ <xsl:param name="mathbackground"/>
833
+ <xsl:param name="mathcolor"/>
834
+ <xsl:param name="mathvariant"/>
835
+ <xsl:param name="color"/>
836
+ <xsl:param name="font-family">Cambria Math</xsl:param>
837
+ <xsl:param name="fontsize"/>
838
+ <xsl:param name="fontstyle"/>
839
+ <xsl:param name="fontweight"/>
840
+ <xsl:param name="mathsize"/>
841
+ <xsl:param name="ndCur"/>
842
+ <xsl:param name="fNor"/>
843
+ <xsl:param name="fLit"/>
844
+ <!-- NN 20180315 Yuck. Get that away from here -->
845
+ <!--
846
+ <w:rPr>
847
+ <xsl:call-template name="mathrRpHook"/>
848
+ <w:rFonts w:ascii="{$font-family}" w:eastAsia="{$font-family}" w:hAnsi="{$font-family}"
849
+ w:cs="{$font-family}"/>
850
+ <xsl:choose>
851
+ <xsl:when test="$fontweight=''"/>
852
+ <xsl:when test="$fontweight='bold'">
853
+ <w:b/>
854
+ </xsl:when>
855
+ <xsl:when test="$fontweight='normal'">
856
+ <w:b w:val="0"/>
857
+ </xsl:when>
858
+ </xsl:choose>
859
+ <xsl:choose>
860
+ <xsl:when test="$fontstyle=''"/>
861
+ <xsl:when test="$fontstyle='italic'">
862
+ <w:i/>
863
+ </xsl:when>
864
+ <xsl:when test="$fontstyle='normal'">
865
+ <w:i w:val="0"/>
866
+ </xsl:when>
867
+ </xsl:choose>
868
+ </w:rPr>
869
+ -->
870
+ <xsl:variable name="mstyleColor">
871
+ <xsl:if test="not(not($ndCur))">
872
+ <xsl:choose>
873
+ <xsl:when test="$ndCur/ancestor::mml:mstyle[@color][1]/@color">
874
+ <xsl:value-of select="$ndCur/ancestor::mml:mstyle[@color][1]/@color"/>
875
+ </xsl:when>
876
+ <xsl:otherwise>
877
+ <xsl:value-of select="$ndCur/ancestor::mml:mstyle[@color][1]/@mml:color"/>
878
+ </xsl:otherwise>
879
+ </xsl:choose>
880
+ </xsl:if>
881
+ </xsl:variable>
882
+ <xsl:call-template name="CreateMathRPR">
883
+ <xsl:with-param name="mathvariant" select="$mathvariant"/>
884
+ <xsl:with-param name="fontstyle" select="$fontstyle"/>
885
+ <xsl:with-param name="fontweight" select="$fontweight"/>
886
+ <xsl:with-param name="ndCur" select="$ndCur"/>
887
+ <xsl:with-param name="fNor" select="$fNor"/>
888
+ <xsl:with-param name="fLit" select="$fLit"/>
889
+ </xsl:call-template>
890
+ </xsl:template>
891
+
892
+ <!-- %%Template: CreateMathRPR
893
+ -->
894
+ <xsl:template name="CreateMathRPR">
895
+ <xsl:param name="mathvariant"/>
896
+ <xsl:param name="fontstyle"/>
897
+ <xsl:param name="fontweight"/>
898
+ <xsl:param name="ndCur"/>
899
+ <xsl:param name="fNor"/>
900
+ <xsl:param name="fLit"/>
901
+ <xsl:variable name="sFontCur">
902
+ <xsl:call-template name="GetFontCur">
903
+ <xsl:with-param name="mathvariant" select="$mathvariant"/>
904
+ <xsl:with-param name="fontstyle" select="$fontstyle"/>
905
+ <xsl:with-param name="fontweight" select="$fontweight"/>
906
+ <xsl:with-param name="ndCur" select="$ndCur"/>
907
+ </xsl:call-template>
908
+ </xsl:variable>
909
+ <xsl:if test="$fLit=1 or $fNor=1 or ($sFontCur!='italic' and $sFontCur!='')">
910
+ <rPr>
911
+ <xsl:if test="$fNor=1">
912
+ <nor/>
913
+ </xsl:if>
914
+ <xsl:if test="$fLit=1">
915
+ <lit/>
916
+ </xsl:if>
917
+ <xsl:call-template name="CreateMathScrStyProp">
918
+ <xsl:with-param name="font" select="$sFontCur"/>
919
+ <xsl:with-param name="fNor" select="$fNor"/>
920
+ </xsl:call-template>
921
+ </rPr>
922
+ </xsl:if>
923
+ </xsl:template>
924
+
925
+ <!-- %%Template: GetFontCur
926
+ -->
927
+ <xsl:template name="GetFontCur">
928
+ <xsl:param name="ndCur"/>
929
+ <xsl:param name="mathvariant"/>
930
+ <xsl:param name="fontstyle"/>
931
+ <xsl:param name="fontweight"/>
932
+ <xsl:choose>
933
+ <xsl:when test="$mathvariant!=''">
934
+ <xsl:value-of select="$mathvariant"/>
935
+ </xsl:when>
936
+ <xsl:when test="not($ndCur)">
937
+ <xsl:value-of select="'italic'"/>
938
+ </xsl:when>
939
+ <xsl:when test="$ndCur/self::mml:mi and (string-length(normalize-space($ndCur)) &lt;= 1) or $ndCur/self::mml:mn and string(number($ndCur/text()))!='NaN' or $ndCur/self::mml:mo">
940
+
941
+ <!-- The default for the above three cases is fontstyle=italic fontweight=normal.-->
942
+ <xsl:choose>
943
+ <xsl:when test="$fontstyle='normal' and $fontweight='bold'">
944
+ <!-- In omml, a sty of 'b' (which is what bold is translated into)
945
+ implies a normal fontstyle -->
946
+ <xsl:value-of select="'bold'"/>
947
+ </xsl:when>
948
+ <xsl:when test="$fontstyle='normal'">
949
+ <xsl:value-of select="'normal'"/>
950
+ </xsl:when>
951
+ <xsl:when test="$fontweight='bold'">
952
+ <xsl:value-of select="'bi'"/>
953
+ </xsl:when>
954
+ <xsl:when test="$fontweight='normal'">
955
+ <xsl:value-of select="'i'"/>
956
+ </xsl:when>
957
+ <xsl:otherwise>
958
+ <xsl:value-of select="'italic'"/>
959
+ </xsl:otherwise>
960
+ </xsl:choose>
961
+ </xsl:when>
962
+ <xsl:otherwise>
963
+ <!--Default is fontweight = 'normal' and fontstyle='normal'-->
964
+ <xsl:choose>
965
+ <xsl:when test="$fontstyle='italic' and $fontweight='bold'">
966
+ <xsl:value-of select="'bi'"/>
967
+ </xsl:when>
968
+ <xsl:when test="$fontstyle='italic'">
969
+ <xsl:value-of select="'italic'"/>
970
+ </xsl:when>
971
+ <xsl:when test="$fontweight='normal'">
972
+ <xsl:value-of select="'italic'"/>
973
+ </xsl:when>
974
+ <xsl:when test="$fontweight='bold'">
975
+ <xsl:value-of select="'bold'"/>
976
+ </xsl:when>
977
+ <xsl:otherwise>
978
+ <xsl:value-of select="'normal'"/>
979
+ </xsl:otherwise>
980
+ </xsl:choose>
981
+ </xsl:otherwise>
982
+ </xsl:choose>
983
+ </xsl:template>
984
+
985
+
986
+ <!-- %%Template: CreateMathScrStyProp
987
+ -->
988
+ <xsl:template name="CreateMathScrStyProp">
989
+ <xsl:param name="font"/>
990
+ <xsl:param name="fNor" select="0"/>
991
+ <xsl:choose>
992
+ <xsl:when test="$font='normal' and $fNor=0">
993
+ <sty>
994
+ <xsl:attribute name="m:val">p</xsl:attribute>
995
+ </sty>
996
+ </xsl:when>
997
+ <xsl:when test="$font='bold'">
998
+ <sty>
999
+ <xsl:attribute name="m:val">b</xsl:attribute>
1000
+ </sty>
1001
+ </xsl:when>
1002
+ <xsl:when test="$font='italic'">
1003
+ </xsl:when>
1004
+ <xsl:when test="$font='script'">
1005
+ <scr>
1006
+ <xsl:attribute name="m:val">script</xsl:attribute>
1007
+ </scr>
1008
+ </xsl:when>
1009
+ <xsl:when test="$font='bold-script'">
1010
+ <scr>
1011
+ <xsl:attribute name="m:val">script</xsl:attribute>
1012
+ </scr>
1013
+ <sty>
1014
+ <xsl:attribute name="m:val">b</xsl:attribute>
1015
+ </sty>
1016
+ </xsl:when>
1017
+ <xsl:when test="$font='double-struck'">
1018
+ <scr>
1019
+ <xsl:attribute name="m:val">double-struck</xsl:attribute>
1020
+ </scr>
1021
+ <sty>
1022
+ <xsl:attribute name="m:val">p</xsl:attribute>
1023
+ </sty>
1024
+ </xsl:when>
1025
+ <xsl:when test="$font='fraktur'">
1026
+ <scr>
1027
+ <xsl:attribute name="m:val">fraktur</xsl:attribute>
1028
+ </scr>
1029
+ <sty>
1030
+ <xsl:attribute name="m:val">p</xsl:attribute>
1031
+ </sty>
1032
+ </xsl:when>
1033
+ <xsl:when test="$font='bold-fraktur'">
1034
+ <scr>
1035
+ <xsl:attribute name="m:val">fraktur</xsl:attribute>
1036
+ </scr>
1037
+ <sty>
1038
+ <xsl:attribute name="m:val">b</xsl:attribute>
1039
+ </sty>
1040
+ </xsl:when>
1041
+ <xsl:when test="$font='sans-serif'">
1042
+ <scr>
1043
+ <xsl:attribute name="m:val">sans-serif</xsl:attribute>
1044
+ </scr>
1045
+ <sty>
1046
+ <xsl:attribute name="m:val">p</xsl:attribute>
1047
+ </sty>
1048
+ </xsl:when>
1049
+ <xsl:when test="$font='bold-sans-serif'">
1050
+ <scr>
1051
+ <xsl:attribute name="m:val">sans-serif</xsl:attribute>
1052
+ </scr>
1053
+ <sty>
1054
+ <xsl:attribute name="m:val">b</xsl:attribute>
1055
+ </sty>
1056
+ </xsl:when>
1057
+ <xsl:when test="$font='sans-serif-italic'">
1058
+ <scr>
1059
+ <xsl:attribute name="m:val">sans-serif</xsl:attribute>
1060
+ </scr>
1061
+ </xsl:when>
1062
+ <xsl:when test="$font='sans-serif-bold-italic'">
1063
+ <scr>
1064
+ <xsl:attribute name="m:val">sans-serif</xsl:attribute>
1065
+ </scr>
1066
+ <sty>
1067
+ <xsl:attribute name="m:val">bi</xsl:attribute>
1068
+ </sty>
1069
+ </xsl:when>
1070
+ <xsl:when test="$font='monospace'"/>
1071
+ <!-- We can't do monospace, so leave empty -->
1072
+ <xsl:when test="$font='bold'">
1073
+ <sty>
1074
+ <xsl:attribute name="m:val">b</xsl:attribute>
1075
+ </sty>
1076
+ </xsl:when>
1077
+ <xsl:when test="$font='bi' or $font='bold-italic'">
1078
+ <sty>
1079
+ <xsl:attribute name="m:val">bi</xsl:attribute>
1080
+ </sty>
1081
+ </xsl:when>
1082
+ </xsl:choose>
1083
+ </xsl:template>
1084
+
1085
+ <xsl:template name="FBar">
1086
+ <xsl:param name="sLineThickness"/>
1087
+ <xsl:variable name="sLowerLineThickness"
1088
+ select="translate($sLineThickness, $StrUCAlphabet, $StrLCAlphabet)"/>
1089
+ <xsl:choose>
1090
+ <xsl:when test="string-length($sLowerLineThickness)=0 or $sLowerLineThickness='thin' or $sLowerLineThickness='medium' or $sLowerLineThickness='thick'">1</xsl:when>
1091
+ <xsl:otherwise>
1092
+ <xsl:variable name="fStrContainsNonZeroDigit">
1093
+ <xsl:call-template name="FStrContainsNonZeroDigit">
1094
+ <xsl:with-param name="s" select="$sLowerLineThickness"/>
1095
+ </xsl:call-template>
1096
+ </xsl:variable>
1097
+ <xsl:choose>
1098
+ <xsl:when test="$fStrContainsNonZeroDigit=1">1</xsl:when>
1099
+ <xsl:otherwise>0</xsl:otherwise>
1100
+ </xsl:choose>
1101
+ </xsl:otherwise>
1102
+ </xsl:choose>
1103
+ </xsl:template>
1104
+
1105
+
1106
+ <!-- %%Template: match mfrac
1107
+ -->
1108
+ <xsl:template mode="mml" match="mml:mfrac">
1109
+ <xsl:variable name="fBar">
1110
+ <xsl:call-template name="FBar">
1111
+ <xsl:with-param name="sLineThickness">
1112
+ <xsl:choose>
1113
+ <xsl:when test="@linethickness">
1114
+ <xsl:value-of select="@linethickness"/>
1115
+ </xsl:when>
1116
+ <xsl:otherwise>
1117
+ <xsl:value-of select="@mml:linethickness"/>
1118
+ </xsl:otherwise>
1119
+ </xsl:choose>
1120
+ </xsl:with-param>
1121
+ </xsl:call-template>
1122
+ </xsl:variable>
1123
+
1124
+ <f>
1125
+ <fPr>
1126
+ <type>
1127
+ <xsl:attribute name="m:val">
1128
+ <xsl:choose>
1129
+ <xsl:when test="$fBar=0">noBar</xsl:when>
1130
+ <xsl:when test="@bevelled='true' or @mml:bevelled='true'">skw</xsl:when>
1131
+ <xsl:otherwise>bar</xsl:otherwise>
1132
+ </xsl:choose>
1133
+ </xsl:attribute>
1134
+ </type>
1135
+ </fPr>
1136
+ <num>
1137
+ <xsl:call-template name="CreateArgProp"/>
1138
+ <xsl:apply-templates mode="mml" select="child::*[1]"/>
1139
+ </num>
1140
+ <den>
1141
+ <xsl:call-template name="CreateArgProp"/>
1142
+ <xsl:apply-templates mode="mml" select="child::*[2]"/>
1143
+ </den>
1144
+ </f>
1145
+ </xsl:template>
1146
+
1147
+ <!-- %%Template: match menclose msqrt
1148
+ -->
1149
+ <xsl:template mode="mml" match="mml:menclose | mml:msqrt">
1150
+ <xsl:variable name="sLowerCaseNotation">
1151
+ <xsl:choose>
1152
+ <xsl:when test="@notation">
1153
+ <xsl:value-of select="translate(@notation, $StrUCAlphabet, $StrLCAlphabet)"/>
1154
+ </xsl:when>
1155
+ <xsl:otherwise>
1156
+ <xsl:value-of select="translate(@mml:notation, $StrUCAlphabet, $StrLCAlphabet)"/>
1157
+ </xsl:otherwise>
1158
+ </xsl:choose>
1159
+ </xsl:variable>
1160
+ <xsl:choose>
1161
+ <!-- Take care of default -->
1162
+ <xsl:when test="$sLowerCaseNotation='radical' or not($sLowerCaseNotation) or $sLowerCaseNotation='' or self::mml:msqrt">
1163
+ <rad>
1164
+ <radPr>
1165
+ <degHide>
1166
+ <xsl:attribute name="m:val">on</xsl:attribute>
1167
+ </degHide>
1168
+ </radPr>
1169
+ <deg>
1170
+ <xsl:call-template name="CreateArgProp"/>
1171
+ </deg>
1172
+ <e>
1173
+ <xsl:call-template name="CreateArgProp"/>
1174
+ <xsl:apply-templates mode="mml"/>
1175
+ </e>
1176
+ </rad>
1177
+ </xsl:when>
1178
+ <xsl:otherwise>
1179
+ <xsl:choose>
1180
+ <xsl:when test="$sLowerCaseNotation='actuarial' or $sLowerCaseNotation='longdiv'"/>
1181
+ <xsl:otherwise>
1182
+ <borderBox>
1183
+ <!-- Dealing with more complex notation attribute -->
1184
+ <xsl:variable name="fBox">
1185
+ <xsl:choose>
1186
+ <!-- Word doesn't have circle and roundedbox concepts, therefore, map both to a
1187
+ box. -->
1188
+ <xsl:when test="contains($sLowerCaseNotation, 'box') or contains($sLowerCaseNotation, 'circle') or contains($sLowerCaseNotation, 'roundedbox')">1</xsl:when>
1189
+ <xsl:otherwise>0</xsl:otherwise>
1190
+ </xsl:choose>
1191
+ </xsl:variable>
1192
+ <xsl:variable name="fTop">
1193
+ <xsl:choose>
1194
+ <xsl:when test="contains($sLowerCaseNotation, 'top')">1</xsl:when>
1195
+ <xsl:otherwise>0</xsl:otherwise>
1196
+ </xsl:choose>
1197
+ </xsl:variable>
1198
+ <xsl:variable name="fBot">
1199
+ <xsl:choose>
1200
+ <xsl:when test="contains($sLowerCaseNotation, 'bottom')">1</xsl:when>
1201
+ <xsl:otherwise>0</xsl:otherwise>
1202
+ </xsl:choose>
1203
+ </xsl:variable>
1204
+ <xsl:variable name="fLeft">
1205
+ <xsl:choose>
1206
+ <xsl:when test="contains($sLowerCaseNotation, 'left')">1</xsl:when>
1207
+ <xsl:otherwise>0</xsl:otherwise>
1208
+ </xsl:choose>
1209
+ </xsl:variable>
1210
+ <xsl:variable name="fRight">
1211
+ <xsl:choose>
1212
+ <xsl:when test="contains($sLowerCaseNotation, 'right')">1</xsl:when>
1213
+ <xsl:otherwise>0</xsl:otherwise>
1214
+ </xsl:choose>
1215
+ </xsl:variable>
1216
+ <xsl:variable name="fStrikeH">
1217
+ <xsl:choose>
1218
+ <xsl:when test="contains($sLowerCaseNotation, 'horizontalstrike')">1</xsl:when>
1219
+ <xsl:otherwise>0</xsl:otherwise>
1220
+ </xsl:choose>
1221
+ </xsl:variable>
1222
+ <xsl:variable name="fStrikeV">
1223
+ <xsl:choose>
1224
+ <xsl:when test="contains($sLowerCaseNotation, 'verticalstrike')">1</xsl:when>
1225
+ <xsl:otherwise>0</xsl:otherwise>
1226
+ </xsl:choose>
1227
+ </xsl:variable>
1228
+ <xsl:variable name="fStrikeBLTR">
1229
+ <xsl:choose>
1230
+ <xsl:when test="contains($sLowerCaseNotation, 'updiagonalstrike')">1</xsl:when>
1231
+ <xsl:otherwise>0</xsl:otherwise>
1232
+ </xsl:choose>
1233
+ </xsl:variable>
1234
+ <xsl:variable name="fStrikeTLBR">
1235
+ <xsl:choose>
1236
+ <xsl:when test="contains($sLowerCaseNotation, 'downdiagonalstrike')">1</xsl:when>
1237
+ <xsl:otherwise>0</xsl:otherwise>
1238
+ </xsl:choose>
1239
+ </xsl:variable>
1240
+
1241
+ <!-- Should we create borderBoxPr?
1242
+ We should if the enclosure isn't Word's default, which is
1243
+ a plain box -->
1244
+ <xsl:if test="$fStrikeH=1 or $fStrikeV=1 or $fStrikeBLTR=1 or $fStrikeTLBR=1 or ($fBox=0 and not($fTop=1 and $fBot=1 and $fLeft=1 and $fRight=1) )">
1245
+ <borderBoxPr>
1246
+ <xsl:if test="$fBox=0">
1247
+ <xsl:if test="$fTop=0">
1248
+ <hideTop>
1249
+ <xsl:attribute name="m:val">on</xsl:attribute>
1250
+ </hideTop>
1251
+ </xsl:if>
1252
+ <xsl:if test="$fBot=0">
1253
+ <hideBot>
1254
+ <xsl:attribute name="m:val">on</xsl:attribute>
1255
+ </hideBot>
1256
+ </xsl:if>
1257
+ <xsl:if test="$fLeft=0">
1258
+ <hideLeft>
1259
+ <xsl:attribute name="m:val">on</xsl:attribute>
1260
+ </hideLeft>
1261
+ </xsl:if>
1262
+ <xsl:if test="$fRight=0">
1263
+ <hideRight>
1264
+ <xsl:attribute name="m:val">on</xsl:attribute>
1265
+ </hideRight>
1266
+ </xsl:if>
1267
+ </xsl:if>
1268
+ <xsl:if test="$fStrikeH=1">
1269
+ <strikeH>
1270
+ <xsl:attribute name="m:val">on</xsl:attribute>
1271
+ </strikeH>
1272
+ </xsl:if>
1273
+ <xsl:if test="$fStrikeV=1">
1274
+ <strikeV>
1275
+ <xsl:attribute name="m:val">on</xsl:attribute>
1276
+ </strikeV>
1277
+ </xsl:if>
1278
+ <xsl:if test="$fStrikeBLTR=1">
1279
+ <strikeBLTR>
1280
+ <xsl:attribute name="m:val">on</xsl:attribute>
1281
+ </strikeBLTR>
1282
+ </xsl:if>
1283
+ <xsl:if test="$fStrikeTLBR=1">
1284
+ <strikeTLBR>
1285
+ <xsl:attribute name="m:val">on</xsl:attribute>
1286
+ </strikeTLBR>
1287
+ </xsl:if>
1288
+ </borderBoxPr>
1289
+ </xsl:if>
1290
+ <e>
1291
+ <xsl:call-template name="CreateArgProp"/>
1292
+ <xsl:apply-templates mode="mml"/>
1293
+ </e>
1294
+ </borderBox>
1295
+ </xsl:otherwise>
1296
+ </xsl:choose>
1297
+ </xsl:otherwise>
1298
+ </xsl:choose>
1299
+ </xsl:template>
1300
+
1301
+ <!-- %%Template: CreateArgProp
1302
+ -->
1303
+ <xsl:template name="CreateArgProp">
1304
+ <xsl:if test="not(count(ancestor-or-self::mml:mstyle[@scriptlevel='0' or @scriptlevel='1' or @scriptlevel='2'])=0) or not(count(ancestor-or-self::mml:mstyle[@mml:scriptlevel='0' or @mml:scriptlevel='1' or @mml:scriptlevel='2'])=0)">
1305
+ <argPr>
1306
+ <scrLvl>
1307
+ <xsl:attribute name="m:val">
1308
+ <xsl:choose>
1309
+ <xsl:when test="ancestor-or-self::mml:mstyle[@scriptlevel][1]/@scriptlevel">
1310
+ <xsl:value-of select="ancestor-or-self::mml:mstyle[@scriptlevel][1]/@scriptlevel"/>
1311
+ </xsl:when>
1312
+ <xsl:otherwise>
1313
+ <xsl:value-of select="ancestor-or-self::mml:mstyle[@scriptlevel][1]/@mml:scriptlevel"/>
1314
+ </xsl:otherwise>
1315
+ </xsl:choose>
1316
+ </xsl:attribute>
1317
+ </scrLvl>
1318
+ </argPr>
1319
+ </xsl:if>
1320
+ </xsl:template>
1321
+
1322
+ <!-- %%Template: match mroot
1323
+ -->
1324
+ <xsl:template mode="mml" match="mml:mroot">
1325
+ <rad>
1326
+ <radPr>
1327
+ <degHide>
1328
+ <xsl:attribute name="m:val">off</xsl:attribute>
1329
+ </degHide>
1330
+ </radPr>
1331
+ <deg>
1332
+ <xsl:call-template name="CreateArgProp"/>
1333
+ <xsl:apply-templates mode="mml" select="child::*[2]"/>
1334
+ </deg>
1335
+ <e>
1336
+ <xsl:call-template name="CreateArgProp"/>
1337
+ <xsl:apply-templates mode="mml" select="child::*[1]"/>
1338
+ </e>
1339
+ </rad>
1340
+ </xsl:template>
1341
+
1342
+ <!-- MathML has no concept of a linear fraction. When transforming a linear fraction
1343
+ from Omml to MathML, we create the following MathML:
1344
+
1345
+ <mml:mrow>
1346
+ <mml:mrow>
1347
+ // numerator
1348
+ </mml:mrow>
1349
+ <mml:mo>/</mml:mo>
1350
+ <mml:mrow>
1351
+ // denominator
1352
+ </mml:mrow>
1353
+ </mml:mrow>
1354
+
1355
+ This template looks for four things:
1356
+ 1. ndCur is an mml:mrow
1357
+ 2. ndCur has three children
1358
+ 3. The second child is an <mml:mo>
1359
+ 4. The second child's text is '/'
1360
+
1361
+ -->
1362
+ <xsl:template name="FLinearFrac">
1363
+ <xsl:param name="ndCur" select="."/>
1364
+ <xsl:variable name="sNdText">
1365
+ <xsl:value-of select="normalize-space($ndCur/*[2])"/>
1366
+ </xsl:variable>
1367
+
1368
+ <xsl:choose>
1369
+ <!-- I spy a linear fraction -->
1370
+ <xsl:when test="$ndCur/self::mml:mrow and count($ndCur/*)=3 and $ndCur/*[2][self::mml:mo] and $sNdText='/'">1</xsl:when>
1371
+ <xsl:otherwise>0</xsl:otherwise>
1372
+ </xsl:choose>
1373
+ </xsl:template>
1374
+
1375
+
1376
+ <!-- Though presentation mathml can certainly typeset any generic function with the
1377
+ appropriate function operator spacing, presentation MathML has no concept of
1378
+ a function structure like omml does. In order to preserve the omml <func>
1379
+ element, we must establish how an omml <func> element looks in mml. This
1380
+ is shown below:
1381
+
1382
+ <mml:mrow>
1383
+ <mml:mrow>
1384
+ // function name
1385
+ </mml:mrow>
1386
+ <mml:mo>&#x02061;</mml:mo>
1387
+ <mml:mrow>
1388
+ // function argument
1389
+ </mml:mrow>
1390
+ </mml:mrow>
1391
+
1392
+ This template looks for six things to be true:
1393
+ 1. ndCur is an mml:mrow
1394
+ 2. ndCur has three children
1395
+ 3. The first child is an <mml:mrow>
1396
+ 4. The second child is an <mml:mo>
1397
+ 5. The third child is an <mml:mrow>
1398
+ 6. The second child's text is '&#x02061;'
1399
+ -->
1400
+ <xsl:template name="FIsFunc">
1401
+ <xsl:param name="ndCur" select="."/>
1402
+ <xsl:variable name="sNdText">
1403
+ <xsl:value-of select="normalize-space($ndCur/*[2])"/>
1404
+ </xsl:variable>
1405
+
1406
+ <xsl:choose>
1407
+ <!-- Is this an omml function -->
1408
+ <xsl:when test="count($ndCur/*)=3 and $ndCur/self::*[self::mml:mrow] and $ndCur/*[2][self::mml:mo] and $sNdText='⁡'">1</xsl:when>
1409
+ <xsl:otherwise>0</xsl:otherwise>
1410
+ </xsl:choose>
1411
+ </xsl:template>
1412
+
1413
+
1414
+ <!-- Given the node of the linear fraction's parent mrow,
1415
+ make a linear fraction -->
1416
+ <xsl:template name="MakeLinearFraction">
1417
+ <xsl:param name="ndCur" select="."/>
1418
+ <f>
1419
+ <fPr>
1420
+ <type>
1421
+ <xsl:attribute name="m:val">lin</xsl:attribute>
1422
+ </type>
1423
+ </fPr>
1424
+ <num>
1425
+ <xsl:call-template name="CreateArgProp"/>
1426
+ <xsl:apply-templates mode="mml" select="$ndCur/*[1]"/>
1427
+ </num>
1428
+ <den>
1429
+ <xsl:call-template name="CreateArgProp"/>
1430
+ <xsl:apply-templates mode="mml" select="$ndCur/*[3]"/>
1431
+ </den>
1432
+ </f>
1433
+ </xsl:template>
1434
+
1435
+
1436
+ <!-- Given the node of the function's parent mrow,
1437
+ make an omml function -->
1438
+ <xsl:template name="WriteFunc">
1439
+ <xsl:param name="ndCur" select="."/>
1440
+
1441
+ <func>
1442
+ <fName>
1443
+ <xsl:apply-templates mode="mml" select="$ndCur/child::*[1]"/>
1444
+ </fName>
1445
+ <e>
1446
+ <xsl:apply-templates mode="mml" select="$ndCur/child::*[3]"/>
1447
+ </e>
1448
+ </func>
1449
+ </xsl:template>
1450
+
1451
+
1452
+ <!-- MathML doesn't have the concept of nAry structures. The best approximation
1453
+ to these is to have some under/over or sub/sup followed by an mrow or mstyle.
1454
+
1455
+ In the case that we've come across some under/over or sub/sup that contains an
1456
+ nAry operator, this function handles the following sibling to the nAry structure.
1457
+
1458
+ If the following sibling is:
1459
+
1460
+ mml:mstyle, then apply templates to the children of this mml:mstyle
1461
+
1462
+ mml:mrow, determine if this mrow is a linear fraction
1463
+ (see comments for FlinearFrac template).
1464
+ If so, make an Omml linear fraction.
1465
+ If not, apply templates as was done for mml:mstyle.
1466
+
1467
+ -->
1468
+ <xsl:template name="NaryHandleMrowMstyle">
1469
+ <xsl:param name="ndCur" select="."/>
1470
+ <!-- if the next sibling is an mrow, pull it in by
1471
+ doing whatever we would have done to its children.
1472
+ The mrow itself will be skipped, see template above. -->
1473
+ <xsl:choose>
1474
+ <xsl:when test="$ndCur[self::mml:mrow]">
1475
+ <!-- Check for linear fraction -->
1476
+ <xsl:variable name="fLinearFrac">
1477
+ <xsl:call-template name="FLinearFrac">
1478
+ <xsl:with-param name="ndCur" select="$ndCur"/>
1479
+ </xsl:call-template>
1480
+ </xsl:variable>
1481
+ <xsl:choose>
1482
+ <xsl:when test="$fLinearFrac=1">
1483
+ <xsl:call-template name="MakeLinearFraction">
1484
+ <xsl:with-param name="ndCur" select="$ndCur"/>
1485
+ </xsl:call-template>
1486
+ </xsl:when>
1487
+ <xsl:otherwise>
1488
+ <xsl:variable name="fFunc">
1489
+ <xsl:call-template name="FIsFunc">
1490
+ <xsl:with-param name="ndCur" select="."/>
1491
+ </xsl:call-template>
1492
+ </xsl:variable>
1493
+ <xsl:choose>
1494
+ <xsl:when test="$fFunc=1">
1495
+ <xsl:call-template name="WriteFunc">
1496
+ <xsl:with-param name="ndCur" select="."/>
1497
+ </xsl:call-template>
1498
+ </xsl:when>
1499
+ <xsl:otherwise>
1500
+ <xsl:apply-templates mode="mml" select="$ndCur/*"/>
1501
+ </xsl:otherwise>
1502
+ </xsl:choose>
1503
+ </xsl:otherwise>
1504
+ </xsl:choose>
1505
+ </xsl:when>
1506
+ <xsl:when test="$ndCur[self::mml:mstyle]">
1507
+ <xsl:apply-templates mode="mml" select="$ndCur/*"/>
1508
+ </xsl:when>
1509
+ </xsl:choose>
1510
+ </xsl:template>
1511
+
1512
+
1513
+ <!-- MathML munder/mover can represent several Omml constructs
1514
+ (m:bar, m:limLow, m:limUpp, m:acc, m:groupChr, etc.). The following
1515
+ templates (FIsBar, FIsAcc, and FIsGroupChr) are used to determine
1516
+ which of these Omml constructs an munder/mover should be translated into. -->
1517
+
1518
+ <!-- Note: ndCur should only be an munder/mover MathML element.
1519
+
1520
+ ndCur should be interpretted as an m:bar if
1521
+ 1) its respective accent attribute is not true
1522
+ 2) its second child is an mml:mo
1523
+ 3) the character of the mml:mo is the correct under/over bar. -->
1524
+ <xsl:template name="FIsBar">
1525
+ <xsl:param name="ndCur"/>
1526
+ <xsl:variable name="fUnder">
1527
+ <xsl:choose>
1528
+ <xsl:when test="$ndCur[self::mml:munder]">1</xsl:when>
1529
+ <xsl:otherwise>0</xsl:otherwise>
1530
+ </xsl:choose>
1531
+ </xsl:variable>
1532
+ <xsl:variable name="sLowerCaseAccent">
1533
+ <xsl:choose>
1534
+ <xsl:when test="$fUnder=1">
1535
+ <xsl:choose>
1536
+ <xsl:when test="$ndCur/@accentunder">
1537
+ <xsl:value-of select="translate($ndCur/@accentunder, $StrUCAlphabet, $StrLCAlphabet)"/>
1538
+ </xsl:when>
1539
+ <xsl:otherwise>
1540
+ <xsl:value-of select="translate($ndCur/@mml:accentunder, $StrUCAlphabet, $StrLCAlphabet)"/>
1541
+ </xsl:otherwise>
1542
+ </xsl:choose>
1543
+ </xsl:when>
1544
+ <xsl:otherwise>
1545
+ <xsl:choose>
1546
+ <xsl:when test="$ndCur/@accent">
1547
+ <xsl:value-of select="translate($ndCur/@accent, $StrUCAlphabet, $StrLCAlphabet)"/>
1548
+ </xsl:when>
1549
+ <xsl:otherwise>
1550
+ <xsl:value-of select="translate($ndCur/@mml:accent, $StrUCAlphabet, $StrLCAlphabet)"/>
1551
+ </xsl:otherwise>
1552
+ </xsl:choose>
1553
+ </xsl:otherwise>
1554
+ </xsl:choose>
1555
+ </xsl:variable>
1556
+ <xsl:variable name="fAccent">
1557
+ <xsl:choose>
1558
+ <xsl:when test="$sLowerCaseAccent='true'">1</xsl:when>
1559
+ <xsl:otherwise>0</xsl:otherwise>
1560
+ </xsl:choose>
1561
+ </xsl:variable>
1562
+
1563
+ <xsl:choose>
1564
+ <!-- The script is unaccented and the second child is an mo -->
1565
+ <xsl:when test="$fAccent = 0 and $ndCur/child::*[2]/self::mml:mo">
1566
+ <xsl:variable name="sOperator">
1567
+ <xsl:value-of select="$ndCur/child::*[2]"/>
1568
+ </xsl:variable>
1569
+ <xsl:choose>
1570
+ <!-- Should we write an underbar? -->
1571
+ <xsl:when test="$fUnder = 1">
1572
+ <xsl:choose>
1573
+ <xsl:when test="$sOperator = '̲'">1</xsl:when>
1574
+ <xsl:otherwise>0</xsl:otherwise>
1575
+ </xsl:choose>
1576
+ </xsl:when>
1577
+ <!-- Should we write an overbar? -->
1578
+ <xsl:otherwise>
1579
+ <xsl:choose>
1580
+ <xsl:when test="$sOperator = '¯'">1</xsl:when>
1581
+ <xsl:otherwise>0</xsl:otherwise>
1582
+ </xsl:choose>
1583
+ </xsl:otherwise>
1584
+ </xsl:choose>
1585
+ </xsl:when>
1586
+ <xsl:otherwise>0</xsl:otherwise>
1587
+ </xsl:choose>
1588
+ </xsl:template>
1589
+
1590
+ <!-- Note: ndCur should only be an mover MathML element.
1591
+
1592
+ ndCur should be interpretted as an m:acc if
1593
+ 1) its accent attribute is true
1594
+ 2) its second child is an mml:mo
1595
+ 3) there is only one character in the mml:mo -->
1596
+ <xsl:template name="FIsAcc">
1597
+ <xsl:param name="ndCur" select="."/>
1598
+
1599
+ <xsl:variable name="sLowerCaseAccent">
1600
+ <xsl:choose>
1601
+ <xsl:when test="$ndCur/@accent">
1602
+ <xsl:value-of select="translate($ndCur/@accent, $StrUCAlphabet, $StrLCAlphabet)"/>
1603
+ </xsl:when>
1604
+ <xsl:otherwise>
1605
+ <xsl:value-of select="translate($ndCur/@mml:accent, $StrUCAlphabet, $StrLCAlphabet)"/>
1606
+ </xsl:otherwise>
1607
+ </xsl:choose>
1608
+ </xsl:variable>
1609
+ <xsl:variable name="fAccent">
1610
+ <xsl:choose>
1611
+ <xsl:when test="$sLowerCaseAccent='true'">1</xsl:when>
1612
+ <xsl:otherwise>0</xsl:otherwise>
1613
+ </xsl:choose>
1614
+ </xsl:variable>
1615
+
1616
+ <xsl:choose>
1617
+ <!-- The script is accented and the second child is an mo -->
1618
+ <xsl:when test="$fAccent = 1 and $ndCur/child::*[2] = mml:mo">
1619
+ <xsl:variable name="sOperator">
1620
+ <xsl:value-of select="$ndCur/child::*[2]"/>
1621
+ </xsl:variable>
1622
+ <xsl:choose>
1623
+ <!-- There is only one operator, this is a valid Omml accent! -->
1624
+ <xsl:when test="string-length($sOperator) = 1">1</xsl:when>
1625
+ <!-- More than one accented operator. This isn't a valid
1626
+ omml accent -->
1627
+ <xsl:otherwise>0</xsl:otherwise>
1628
+ </xsl:choose>
1629
+ </xsl:when>
1630
+ <!-- Not accented, not an operator, or both, but in any case, this is
1631
+ not an Omml accent. -->
1632
+ <xsl:otherwise>0</xsl:otherwise>
1633
+ </xsl:choose>
1634
+ </xsl:template>
1635
+
1636
+
1637
+ <!-- Is ndCur a groupChr?
1638
+ ndCur is a groupChr if:
1639
+
1640
+ 1. The accent is false (note: accent attribute
1641
+ for munder is accentunder).
1642
+ 2. ndCur is an munder or mover.
1643
+ 3. ndCur has two children
1644
+ 4. Of these two children, one is an mml:mo and the other is an mml:mrow
1645
+ 5. The number of characters in the mml:mo is 1.
1646
+
1647
+ If all of the above are true, then return 1, else return 0.
1648
+ -->
1649
+ <xsl:template name="FIsGroupChr">
1650
+ <xsl:param name="ndCur" select="."/>
1651
+ <xsl:variable name="fUnder">
1652
+ <xsl:choose>
1653
+ <xsl:when test="$ndCur[self::mml:munder]">1</xsl:when>
1654
+ <xsl:otherwise>0</xsl:otherwise>
1655
+ </xsl:choose>
1656
+ </xsl:variable>
1657
+ <xsl:variable name="sLowerCaseAccent">
1658
+ <xsl:choose>
1659
+ <xsl:when test="$fUnder=1">
1660
+ <xsl:choose>
1661
+ <xsl:when test="$ndCur/@accentunder">
1662
+ <xsl:value-of select="translate($ndCur/@accentunder, $StrUCAlphabet, $StrLCAlphabet)"/>
1663
+ </xsl:when>
1664
+ <xsl:otherwise>
1665
+ <xsl:value-of select="translate($ndCur/@mml:accentunder, $StrUCAlphabet, $StrLCAlphabet)"/>
1666
+ </xsl:otherwise>
1667
+ </xsl:choose>
1668
+ </xsl:when>
1669
+ <xsl:otherwise>
1670
+ <xsl:choose>
1671
+ <xsl:when test="$ndCur/@accent">
1672
+ <xsl:value-of select="translate($ndCur/@accent, $StrUCAlphabet, $StrLCAlphabet)"/>
1673
+ </xsl:when>
1674
+ <xsl:otherwise>
1675
+ <xsl:value-of select="translate($ndCur/@mml:accent, $StrUCAlphabet, $StrLCAlphabet)"/>
1676
+ </xsl:otherwise>
1677
+ </xsl:choose>
1678
+ </xsl:otherwise>
1679
+ </xsl:choose>
1680
+ </xsl:variable>
1681
+
1682
+ <xsl:variable name="fAccentFalse">
1683
+ <xsl:choose>
1684
+ <xsl:when test="$sLowerCaseAccent='false'">1</xsl:when>
1685
+ <xsl:otherwise>0</xsl:otherwise>
1686
+ </xsl:choose>
1687
+ </xsl:variable>
1688
+
1689
+ <xsl:choose>
1690
+ <xsl:when test="$fAccentFalse=1 and $ndCur[self::mml:munder or self::mml:mover] and count($ndCur/child::*)=2 and (($ndCur/child::*[1][self::mml:mrow] and $ndCur/child::*[2][self::mml:mo]) or ($ndCur/child::*[1][self::mml:mo] and $ndCur/child::*[2][self::mml:mrow]))">
1691
+ <xsl:variable name="sOperator">
1692
+ <xsl:value-of select="$ndCur/child::mml:mo"/>
1693
+ </xsl:variable>
1694
+ <xsl:choose>
1695
+ <xsl:when test="string-length($sOperator) &lt;= 1">1</xsl:when>
1696
+ <xsl:otherwise>0</xsl:otherwise>
1697
+ </xsl:choose>
1698
+ </xsl:when>
1699
+
1700
+ <xsl:otherwise>0</xsl:otherwise>
1701
+ </xsl:choose>
1702
+ </xsl:template>
1703
+
1704
+
1705
+ <!-- %%Template: match munder
1706
+ -->
1707
+ <xsl:template mode="mml" match="mml:munder">
1708
+ <xsl:variable name="fNary">
1709
+ <xsl:call-template name="isNary">
1710
+ <xsl:with-param name="ndCur" select="child::*[1]"/>
1711
+ </xsl:call-template>
1712
+ </xsl:variable>
1713
+ <xsl:choose>
1714
+ <xsl:when test="$fNary='true'">
1715
+ <nary>
1716
+ <xsl:call-template name="CreateNaryProp">
1717
+ <xsl:with-param name="chr">
1718
+ <xsl:value-of select="normalize-space(child::*[1])"/>
1719
+ </xsl:with-param>
1720
+ <xsl:with-param name="sMathmlType" select="'munder'"/>
1721
+ </xsl:call-template>
1722
+ <sub>
1723
+ <xsl:call-template name="CreateArgProp"/>
1724
+ <xsl:apply-templates mode="mml" select="child::*[2]"/>
1725
+ </sub>
1726
+ <sup>
1727
+ <xsl:call-template name="CreateArgProp"/>
1728
+ </sup>
1729
+ <e>
1730
+ <xsl:call-template name="CreateArgProp"/>
1731
+ <xsl:call-template name="NaryHandleMrowMstyle">
1732
+ <xsl:with-param name="ndCur" select="following-sibling::*[1]"/>
1733
+ </xsl:call-template>
1734
+ </e>
1735
+ </nary>
1736
+ </xsl:when>
1737
+ <xsl:otherwise>
1738
+ <!-- Should this munder be interpreted as an OMML m:bar? -->
1739
+ <xsl:variable name="fIsBar">
1740
+ <xsl:call-template name="FIsBar">
1741
+ <xsl:with-param name="ndCur" select="."/>
1742
+ </xsl:call-template>
1743
+ </xsl:variable>
1744
+ <xsl:choose>
1745
+ <xsl:when test="$fIsBar=1">
1746
+ <bar>
1747
+ <barPr>
1748
+ <pos m:val="bot"/>
1749
+ </barPr>
1750
+ <e>
1751
+ <xsl:call-template name="CreateArgProp"/>
1752
+ <xsl:apply-templates mode="mml" select="child::*[1]"/>
1753
+ </e>
1754
+ </bar>
1755
+ </xsl:when>
1756
+ <xsl:otherwise>
1757
+ <!-- It isn't an integral or underbar, is this a groupChr? -->
1758
+ <xsl:variable name="fGroupChr">
1759
+ <xsl:call-template name="FIsGroupChr">
1760
+ <xsl:with-param name="ndCur" select="."/>
1761
+ </xsl:call-template>
1762
+ </xsl:variable>
1763
+ <xsl:choose>
1764
+ <xsl:when test="$fGroupChr=1">
1765
+ <groupChr>
1766
+ <xsl:call-template name="CreateGroupChrPr">
1767
+ <xsl:with-param name="chr">
1768
+ <xsl:value-of select="mml:mo"/>
1769
+ </xsl:with-param>
1770
+ <xsl:with-param name="pos">
1771
+ <xsl:choose>
1772
+ <xsl:when test="child::*[1][self::mml:mrow]">bot</xsl:when>
1773
+ <xsl:otherwise>top</xsl:otherwise>
1774
+ </xsl:choose>
1775
+ </xsl:with-param>
1776
+ <xsl:with-param name="vertJc">top</xsl:with-param>
1777
+ </xsl:call-template>
1778
+ <e>
1779
+ <xsl:apply-templates mode="mml" select="mml:mrow"/>
1780
+ </e>
1781
+ </groupChr>
1782
+ </xsl:when>
1783
+ <xsl:otherwise>
1784
+ <!-- Generic munder -->
1785
+ <limLow>
1786
+ <e>
1787
+ <xsl:call-template name="CreateArgProp"/>
1788
+ <xsl:apply-templates mode="mml" select="child::*[1]"/>
1789
+ </e>
1790
+ <lim>
1791
+ <xsl:call-template name="CreateArgProp"/>
1792
+ <xsl:apply-templates mode="mml" select="child::*[2]"/>
1793
+ </lim>
1794
+ </limLow>
1795
+ </xsl:otherwise>
1796
+ </xsl:choose>
1797
+ </xsl:otherwise>
1798
+ </xsl:choose>
1799
+ </xsl:otherwise>
1800
+ </xsl:choose>
1801
+ </xsl:template>
1802
+
1803
+
1804
+ <!-- Given the values for chr, pos, and vertJc, create an omml
1805
+ groupChr's groupChrPr -->
1806
+ <xsl:template name="CreateGroupChrPr">
1807
+ <xsl:param name="chr">⏟</xsl:param>
1808
+ <xsl:param name="pos" select="bot"/>
1809
+ <xsl:param name="vertJc" select="top"/>
1810
+ <groupChrPr>
1811
+ <chr>
1812
+ <xsl:attribute name="m:val">
1813
+ <xsl:value-of select="$chr"/>
1814
+ </xsl:attribute>
1815
+ </chr>
1816
+ <pos>
1817
+ <xsl:attribute name="m:val">
1818
+ <xsl:value-of select="$pos"/>
1819
+ </xsl:attribute>
1820
+ </pos>
1821
+ <vertJc>
1822
+ <xsl:attribute name="m:val">
1823
+ <xsl:value-of select="$vertJc"/>
1824
+ </xsl:attribute>
1825
+ </vertJc>
1826
+ </groupChrPr>
1827
+ </xsl:template>
1828
+
1829
+
1830
+ <!-- %%Template: match mover
1831
+ -->
1832
+ <xsl:template mode="mml" match="mml:mover">
1833
+ <xsl:variable name="fNary">
1834
+ <xsl:call-template name="isNary">
1835
+ <xsl:with-param name="ndCur" select="child::*[1]"/>
1836
+ </xsl:call-template>
1837
+ </xsl:variable>
1838
+ <xsl:choose>
1839
+ <xsl:when test="$fNary='true'">
1840
+ <nary>
1841
+ <xsl:call-template name="CreateNaryProp">
1842
+ <xsl:with-param name="chr">
1843
+ <xsl:value-of select="normalize-space(child::*[1])"/>
1844
+ </xsl:with-param>
1845
+ <xsl:with-param name="sMathmlType" select="'mover'"/>
1846
+ </xsl:call-template>
1847
+ <sub>
1848
+ <xsl:call-template name="CreateArgProp"/>
1849
+ </sub>
1850
+ <sup>
1851
+ <xsl:call-template name="CreateArgProp"/>
1852
+ <xsl:apply-templates mode="mml" select="child::*[2]"/>
1853
+ </sup>
1854
+ <e>
1855
+ <xsl:call-template name="CreateArgProp"/>
1856
+ <xsl:call-template name="NaryHandleMrowMstyle">
1857
+ <xsl:with-param name="ndCur" select="following-sibling::*[1]"/>
1858
+ </xsl:call-template>
1859
+ </e>
1860
+ </nary>
1861
+ </xsl:when>
1862
+ <xsl:otherwise>
1863
+ <!-- Should this munder be interpreted as an OMML m:bar or m:acc? -->
1864
+
1865
+ <!-- Check to see if this is an m:bar -->
1866
+ <xsl:variable name="fIsBar">
1867
+ <xsl:call-template name="FIsBar">
1868
+ <xsl:with-param name="ndCur" select="."/>
1869
+ </xsl:call-template>
1870
+ </xsl:variable>
1871
+ <xsl:choose>
1872
+ <xsl:when test="$fIsBar = 1">
1873
+ <bar>
1874
+ <barPr>
1875
+ <pos m:val="top"/>
1876
+ </barPr>
1877
+ <e>
1878
+ <xsl:call-template name="CreateArgProp"/>
1879
+ <xsl:apply-templates mode="mml" select="child::*[1]"/>
1880
+ </e>
1881
+ </bar>
1882
+ </xsl:when>
1883
+ <xsl:otherwise>
1884
+ <!-- Not an m:bar, should it be an m:acc? -->
1885
+ <xsl:variable name="fIsAcc">
1886
+ <xsl:call-template name="FIsAcc">
1887
+ <xsl:with-param name="ndCur" select="."/>
1888
+ </xsl:call-template>
1889
+ </xsl:variable>
1890
+ <xsl:choose>
1891
+ <xsl:when test="$fIsAcc=1">
1892
+ <acc>
1893
+ <accPr>
1894
+ <chr>
1895
+ <xsl:attribute name="m:val">
1896
+ <xsl:value-of select="child::*[2]"/>
1897
+ </xsl:attribute>
1898
+ </chr>
1899
+ </accPr>
1900
+ <e>
1901
+ <xsl:call-template name="CreateArgProp"/>
1902
+ <xsl:apply-templates mode="mml" select="child::*[1]"/>
1903
+ </e>
1904
+ </acc>
1905
+ </xsl:when>
1906
+ <xsl:otherwise>
1907
+ <!-- This isn't an integral, overbar or accent,
1908
+ could it be a groupChr? -->
1909
+ <xsl:variable name="fGroupChr">
1910
+ <xsl:call-template name="FIsGroupChr">
1911
+ <xsl:with-param name="ndCur" select="."/>
1912
+ </xsl:call-template>
1913
+ </xsl:variable>
1914
+ <xsl:choose>
1915
+ <xsl:when test="$fGroupChr=1">
1916
+ <groupChr>
1917
+ <xsl:call-template name="CreateGroupChrPr">
1918
+ <xsl:with-param name="chr">
1919
+ <xsl:value-of select="mml:mo"/>
1920
+ </xsl:with-param>
1921
+ <xsl:with-param name="pos">
1922
+ <xsl:choose>
1923
+ <xsl:when test="child::*[1][self::mml:mrow]">top</xsl:when>
1924
+ <xsl:otherwise>bot</xsl:otherwise>
1925
+ </xsl:choose>
1926
+ </xsl:with-param>
1927
+ <xsl:with-param name="vertJc">bot</xsl:with-param>
1928
+ </xsl:call-template>
1929
+ <e>
1930
+ <xsl:apply-templates mode="mml" select="mml:mrow"/>
1931
+ </e>
1932
+ </groupChr>
1933
+ </xsl:when>
1934
+ <xsl:otherwise>
1935
+ <!-- Generic mover -->
1936
+ <limUpp>
1937
+ <e>
1938
+ <xsl:call-template name="CreateArgProp"/>
1939
+ <xsl:apply-templates mode="mml" select="child::*[1]"/>
1940
+ </e>
1941
+ <lim>
1942
+ <xsl:call-template name="CreateArgProp"/>
1943
+ <xsl:apply-templates mode="mml" select="child::*[2]"/>
1944
+ </lim>
1945
+ </limUpp>
1946
+ </xsl:otherwise>
1947
+ </xsl:choose>
1948
+ </xsl:otherwise>
1949
+ </xsl:choose>
1950
+ </xsl:otherwise>
1951
+ </xsl:choose>
1952
+ </xsl:otherwise>
1953
+ </xsl:choose>
1954
+ </xsl:template>
1955
+
1956
+
1957
+ <!-- %%Template: match munderover
1958
+ -->
1959
+ <xsl:template mode="mml" match="mml:munderover">
1960
+ <xsl:variable name="fNary">
1961
+ <xsl:call-template name="isNary">
1962
+ <xsl:with-param name="ndCur" select="child::*[1]"/>
1963
+ </xsl:call-template>
1964
+ </xsl:variable>
1965
+ <xsl:choose>
1966
+ <xsl:when test="$fNary='true'">
1967
+ <nary>
1968
+ <xsl:call-template name="CreateNaryProp">
1969
+ <xsl:with-param name="chr">
1970
+ <xsl:value-of select="normalize-space(child::*[1])"/>
1971
+ </xsl:with-param>
1972
+ <xsl:with-param name="sMathmlType" select="'munderover'"/>
1973
+ </xsl:call-template>
1974
+ <sub>
1975
+ <xsl:call-template name="CreateArgProp"/>
1976
+ <xsl:apply-templates mode="mml" select="child::*[2]"/>
1977
+ </sub>
1978
+ <sup>
1979
+ <xsl:call-template name="CreateArgProp"/>
1980
+ <xsl:apply-templates mode="mml" select="child::*[3]"/>
1981
+ </sup>
1982
+ <e>
1983
+ <xsl:call-template name="CreateArgProp"/>
1984
+ <xsl:call-template name="NaryHandleMrowMstyle">
1985
+ <xsl:with-param name="ndCur" select="following-sibling::*[1]"/>
1986
+ </xsl:call-template>
1987
+ </e>
1988
+ </nary>
1989
+ </xsl:when>
1990
+ <xsl:otherwise>
1991
+ <limUpp>
1992
+ <e>
1993
+ <xsl:call-template name="CreateArgProp"/>
1994
+ <limLow>
1995
+ <e>
1996
+ <xsl:call-template name="CreateArgProp"/>
1997
+ <xsl:apply-templates mode="mml" select="child::*[1]"/>
1998
+ </e>
1999
+ <lim>
2000
+ <xsl:call-template name="CreateArgProp"/>
2001
+ <xsl:apply-templates mode="mml" select="child::*[2]"/>
2002
+ </lim>
2003
+ </limLow>
2004
+ </e>
2005
+ <lim>
2006
+ <xsl:call-template name="CreateArgProp"/>
2007
+ <xsl:apply-templates mode="mml" select="child::*[3]"/>
2008
+ </lim>
2009
+ </limUpp>
2010
+ </xsl:otherwise>
2011
+ </xsl:choose>
2012
+ </xsl:template>
2013
+
2014
+ <!-- %%Template: match mfenced -->
2015
+ <xsl:template mode="mml" match="mml:mfenced">
2016
+ <d>
2017
+ <xsl:call-template name="CreateDelimProp">
2018
+ <xsl:with-param name="fChOpenValid">
2019
+ <xsl:choose>
2020
+ <xsl:when test="@open">
2021
+ <xsl:value-of select="1"/>
2022
+ </xsl:when>
2023
+ <xsl:when test="@mml:open">
2024
+ <xsl:value-of select="1"/>
2025
+ </xsl:when>
2026
+ <xsl:otherwise>
2027
+ <xsl:value-of select="0"/>
2028
+ </xsl:otherwise>
2029
+ </xsl:choose>
2030
+ </xsl:with-param>
2031
+ <xsl:with-param name="chOpen">
2032
+ <xsl:choose>
2033
+ <xsl:when test="@open">
2034
+ <xsl:value-of select="@open"/>
2035
+ </xsl:when>
2036
+ <xsl:otherwise>
2037
+ <xsl:value-of select="@mml:open"/>
2038
+ </xsl:otherwise>
2039
+ </xsl:choose>
2040
+ </xsl:with-param>
2041
+ <xsl:with-param name="fChSeparatorsValid">
2042
+ <xsl:choose>
2043
+ <xsl:when test="@separators">
2044
+ <xsl:value-of select="1"/>
2045
+ </xsl:when>
2046
+ <xsl:when test="@mml:separators">
2047
+ <xsl:value-of select="1"/>
2048
+ </xsl:when>
2049
+ <xsl:otherwise>
2050
+ <xsl:value-of select="0"/>
2051
+ </xsl:otherwise>
2052
+ </xsl:choose>
2053
+ </xsl:with-param>
2054
+ <xsl:with-param name="chSeparators">
2055
+ <xsl:choose>
2056
+ <xsl:when test="@separators">
2057
+ <xsl:value-of select="@separators"/>
2058
+ </xsl:when>
2059
+ <xsl:otherwise>
2060
+ <xsl:value-of select="@mml:separators"/>
2061
+ </xsl:otherwise>
2062
+ </xsl:choose>
2063
+ </xsl:with-param>
2064
+ <xsl:with-param name="fChCloseValid">
2065
+ <xsl:choose>
2066
+ <xsl:when test="@close">
2067
+ <xsl:value-of select="1"/>
2068
+ </xsl:when>
2069
+ <xsl:when test="@mml:close">
2070
+ <xsl:value-of select="1"/>
2071
+ </xsl:when>
2072
+ <xsl:otherwise>
2073
+ <xsl:value-of select="0"/>
2074
+ </xsl:otherwise>
2075
+ </xsl:choose>
2076
+ </xsl:with-param>
2077
+ <xsl:with-param name="chClose">
2078
+ <xsl:choose>
2079
+ <xsl:when test="@close">
2080
+ <xsl:value-of select="@close"/>
2081
+ </xsl:when>
2082
+ <xsl:otherwise>
2083
+ <xsl:value-of select="@mml:close"/>
2084
+ </xsl:otherwise>
2085
+ </xsl:choose>
2086
+ </xsl:with-param>
2087
+ </xsl:call-template>
2088
+ <xsl:for-each select="*">
2089
+ <e>
2090
+ <xsl:call-template name="CreateArgProp"/>
2091
+ <xsl:apply-templates mode="mml" select="."/>
2092
+ </e>
2093
+ </xsl:for-each>
2094
+ </d>
2095
+ </xsl:template>
2096
+
2097
+ <!-- %%Template: CreateDelimProp
2098
+
2099
+ Given the characters to use as open, close and separators for
2100
+ the delim object, create the m:dPr (delim properties).
2101
+
2102
+ MathML can have any number of separators in an mfenced object, but
2103
+ OMML can only represent one separator for each d (delim) object.
2104
+ So, we pick the first separator specified.
2105
+ -->
2106
+ <xsl:template name="CreateDelimProp">
2107
+ <xsl:param name="fChOpenValid"/>
2108
+ <xsl:param name="chOpen"/>
2109
+ <xsl:param name="fChSeparatorsValid"/>
2110
+ <xsl:param name="chSeparators"/>
2111
+ <xsl:param name="fChCloseValid"/>
2112
+ <xsl:param name="chClose"/>
2113
+ <xsl:variable name="chSep" select="substring($chSeparators, 1, 1)"/>
2114
+
2115
+ <!-- do we need a dPr at all? If everything's at its default value, then
2116
+ don't bother at all -->
2117
+ <xsl:if test="($fChOpenValid=1 and not($chOpen = '(')) or ($fChCloseValid=1 and not($chClose = ')')) or not($chSep = '|')">
2118
+ <dPr>
2119
+ <!-- the default for MathML and OMML is '('. -->
2120
+ <xsl:if test="$fChOpenValid=1 and not($chOpen = '(')">
2121
+ <begChr>
2122
+ <xsl:attribute name="m:val">
2123
+ <xsl:value-of select="$chOpen"/>
2124
+ </xsl:attribute>
2125
+ </begChr>
2126
+ </xsl:if>
2127
+
2128
+ <!-- the default for MathML is ',' and for OMML is '|' -->
2129
+
2130
+ <xsl:choose>
2131
+ <!-- matches OMML's default, don't bother to write anything out -->
2132
+ <xsl:when test="$chSep = '|'"/>
2133
+
2134
+ <!-- Not specified, use MathML's default. We test against
2135
+ the existence of the actual attribute, not the substring -->
2136
+ <xsl:when test="$fChSeparatorsValid=0">
2137
+ <sepChr m:val=","/>
2138
+ </xsl:when>
2139
+
2140
+ <xsl:otherwise>
2141
+ <sepChr>
2142
+ <xsl:attribute name="m:val">
2143
+ <xsl:value-of select="$chSep"/>
2144
+ </xsl:attribute>
2145
+ </sepChr>
2146
+ </xsl:otherwise>
2147
+ </xsl:choose>
2148
+
2149
+ <!-- the default for MathML and OMML is ')'. -->
2150
+ <xsl:if test="$fChCloseValid=1 and not($chClose = ')')">
2151
+ <endChr>
2152
+ <xsl:attribute name="m:val">
2153
+ <xsl:value-of select="$chClose"/>
2154
+ </xsl:attribute>
2155
+ </endChr>
2156
+ </xsl:if>
2157
+ </dPr>
2158
+ </xsl:if>
2159
+ </xsl:template>
2160
+
2161
+ <!-- %%Template: OutputMs
2162
+ -->
2163
+ <xsl:template name="OutputMs">
2164
+ <xsl:param name="msCur"/>
2165
+ <xsl:choose>
2166
+ <xsl:when test="(not($msCur/@lquote) or $msCur/@lquote='') and (not($msCur/@mml:lquote) or $msCur/@mml:lquote='')">
2167
+ <xsl:text>"</xsl:text>
2168
+ </xsl:when>
2169
+ <xsl:otherwise>
2170
+ <xsl:choose>
2171
+ <xsl:when test="$msCur/@lquote">
2172
+ <xsl:value-of select="$msCur/@lquote"/>
2173
+ </xsl:when>
2174
+ <xsl:otherwise>
2175
+ <xsl:value-of select="$msCur/@mml:lquote"/>
2176
+ </xsl:otherwise>
2177
+ </xsl:choose>
2178
+ </xsl:otherwise>
2179
+ </xsl:choose>
2180
+ <xsl:value-of select="normalize-space($msCur)"/>
2181
+ <xsl:choose>
2182
+ <xsl:when test="(not($msCur/@rquote) or $msCur/@rquote='') and (not($msCur/@mml:rquote) or $msCur/@mml:rquote='')">
2183
+ <xsl:text>"</xsl:text>
2184
+ </xsl:when>
2185
+ <xsl:otherwise>
2186
+ <xsl:choose>
2187
+ <xsl:when test="$msCur/@rquote">
2188
+ <xsl:value-of select="$msCur/@rquote"/>
2189
+ </xsl:when>
2190
+ <xsl:otherwise>
2191
+ <xsl:value-of select="$msCur/@mml:rquote"/>
2192
+ </xsl:otherwise>
2193
+ </xsl:choose>
2194
+ </xsl:otherwise>
2195
+ </xsl:choose>
2196
+ </xsl:template>
2197
+
2198
+ <!-- %%Template: match msub
2199
+ -->
2200
+ <xsl:template mode="mml" match="mml:msub">
2201
+ <xsl:variable name="fNary">
2202
+ <xsl:call-template name="isNary">
2203
+ <xsl:with-param name="ndCur" select="child::*[1]"/>
2204
+ </xsl:call-template>
2205
+ </xsl:variable>
2206
+ <xsl:choose>
2207
+ <xsl:when test="$fNary='true'">
2208
+ <nary>
2209
+ <xsl:call-template name="CreateNaryProp">
2210
+ <xsl:with-param name="chr">
2211
+ <xsl:value-of select="normalize-space(child::*[1])"/>
2212
+ </xsl:with-param>
2213
+ <xsl:with-param name="sMathmlType" select="'msub'"/>
2214
+ </xsl:call-template>
2215
+ <sub>
2216
+ <xsl:call-template name="CreateArgProp"/>
2217
+ <xsl:apply-templates mode="mml" select="child::*[2]"/>
2218
+ </sub>
2219
+ <sup>
2220
+ <xsl:call-template name="CreateArgProp"/>
2221
+ </sup>
2222
+ <e>
2223
+ <xsl:call-template name="CreateArgProp"/>
2224
+ <xsl:call-template name="NaryHandleMrowMstyle">
2225
+ <xsl:with-param name="ndCur" select="following-sibling::*[1]"/>
2226
+ </xsl:call-template>
2227
+ </e>
2228
+ </nary>
2229
+ </xsl:when>
2230
+ <xsl:otherwise>
2231
+ <sSub>
2232
+ <e>
2233
+ <xsl:call-template name="CreateArgProp"/>
2234
+ <xsl:apply-templates mode="mml" select="child::*[1]"/>
2235
+ </e>
2236
+ <sub>
2237
+ <xsl:call-template name="CreateArgProp"/>
2238
+ <xsl:apply-templates mode="mml" select="child::*[2]"/>
2239
+ </sub>
2240
+ </sSub>
2241
+ </xsl:otherwise>
2242
+ </xsl:choose>
2243
+ </xsl:template>
2244
+
2245
+ <!-- %%Template: match msup
2246
+ -->
2247
+ <xsl:template mode="mml" match="mml:msup">
2248
+ <xsl:variable name="fNary">
2249
+ <xsl:call-template name="isNary">
2250
+ <xsl:with-param name="ndCur" select="child::*[1]"/>
2251
+ </xsl:call-template>
2252
+ </xsl:variable>
2253
+ <xsl:choose>
2254
+ <xsl:when test="$fNary='true'">
2255
+ <nary>
2256
+ <xsl:call-template name="CreateNaryProp">
2257
+ <xsl:with-param name="chr">
2258
+ <xsl:value-of select="normalize-space(child::*[1])"/>
2259
+ </xsl:with-param>
2260
+ <xsl:with-param name="sMathmlType" select="'msup'"/>
2261
+ </xsl:call-template>
2262
+ <sub>
2263
+ <xsl:call-template name="CreateArgProp"/>
2264
+ </sub>
2265
+ <sup>
2266
+ <xsl:call-template name="CreateArgProp"/>
2267
+ <xsl:apply-templates mode="mml" select="child::*[2]"/>
2268
+ </sup>
2269
+ <e>
2270
+ <xsl:call-template name="CreateArgProp"/>
2271
+ <xsl:call-template name="NaryHandleMrowMstyle">
2272
+ <xsl:with-param name="ndCur" select="following-sibling::*[1]"/>
2273
+ </xsl:call-template>
2274
+ </e>
2275
+ </nary>
2276
+ </xsl:when>
2277
+ <xsl:otherwise>
2278
+ <sSup>
2279
+ <e>
2280
+ <xsl:call-template name="CreateArgProp"/>
2281
+ <xsl:apply-templates mode="mml" select="child::*[1]"/>
2282
+ </e>
2283
+ <sup>
2284
+ <xsl:call-template name="CreateArgProp"/>
2285
+ <xsl:apply-templates mode="mml" select="child::*[2]"/>
2286
+ </sup>
2287
+ </sSup>
2288
+ </xsl:otherwise>
2289
+ </xsl:choose>
2290
+ </xsl:template>
2291
+
2292
+ <!-- %%Template: match msubsup
2293
+ -->
2294
+ <xsl:template mode="mml" match="mml:msubsup">
2295
+ <xsl:variable name="fNary">
2296
+ <xsl:call-template name="isNary">
2297
+ <xsl:with-param name="ndCur" select="child::*[1]"/>
2298
+ </xsl:call-template>
2299
+ </xsl:variable>
2300
+ <xsl:choose>
2301
+ <xsl:when test="$fNary='true'">
2302
+ <nary>
2303
+ <xsl:call-template name="CreateNaryProp">
2304
+ <xsl:with-param name="chr">
2305
+ <xsl:value-of select="normalize-space(child::*[1])"/>
2306
+ </xsl:with-param>
2307
+ <xsl:with-param name="sMathmlType" select="'msubsup'"/>
2308
+ </xsl:call-template>
2309
+ <sub>
2310
+ <xsl:call-template name="CreateArgProp"/>
2311
+ <xsl:apply-templates mode="mml" select="child::*[2]"/>
2312
+ </sub>
2313
+ <sup>
2314
+ <xsl:call-template name="CreateArgProp"/>
2315
+ <xsl:apply-templates mode="mml" select="child::*[3]"/>
2316
+ </sup>
2317
+ <e>
2318
+ <xsl:call-template name="CreateArgProp"/>
2319
+ <xsl:call-template name="NaryHandleMrowMstyle">
2320
+ <xsl:with-param name="ndCur" select="following-sibling::*[1]"/>
2321
+ </xsl:call-template>
2322
+ </e>
2323
+ </nary>
2324
+ </xsl:when>
2325
+ <xsl:otherwise>
2326
+ <sSubSup>
2327
+ <e>
2328
+ <xsl:call-template name="CreateArgProp"/>
2329
+ <xsl:apply-templates mode="mml" select="child::*[1]"/>
2330
+ </e>
2331
+ <sub>
2332
+ <xsl:call-template name="CreateArgProp"/>
2333
+ <xsl:apply-templates mode="mml" select="child::*[2]"/>
2334
+ </sub>
2335
+ <sup>
2336
+ <xsl:call-template name="CreateArgProp"/>
2337
+ <xsl:apply-templates mode="mml" select="child::*[3]"/>
2338
+ </sup>
2339
+ </sSubSup>
2340
+ </xsl:otherwise>
2341
+ </xsl:choose>
2342
+ </xsl:template>
2343
+
2344
+ <!-- %%Template: SplitScripts
2345
+
2346
+ Takes an collection of nodes, and splits them
2347
+ odd and even into sup and sub scripts. Used for dealing with
2348
+ mmultiscript.
2349
+
2350
+ This template assumes you want to output both a sub and sup element.
2351
+ -->
2352
+ <xsl:template name="SplitScripts">
2353
+ <xsl:param name="ndScripts"/>
2354
+ <sub>
2355
+ <xsl:call-template name="CreateArgProp"/>
2356
+ <xsl:apply-templates mode="mml" select="$ndScripts[(position() mod 2) = 1]"/>
2357
+ </sub>
2358
+ <sup>
2359
+ <xsl:call-template name="CreateArgProp"/>
2360
+ <xsl:apply-templates mode="mml" select="$ndScripts[(position() mod 2) = 0]"/>
2361
+ </sup>
2362
+ </xsl:template>
2363
+
2364
+ <!-- %%Template: match mmultiscripts
2365
+
2366
+ There is some subtlety with the mml:mprescripts element. Everything that comes before
2367
+ that is considered a script (as opposed to a pre-script), but it need not be present.
2368
+ -->
2369
+ <xsl:template mode="mml" match="mml:mmultiscripts">
2370
+
2371
+ <!-- count the nodes. Everything that comes after a mml:mprescripts is considered a pre-script;
2372
+ Everything that does not have an mml:mprescript as a preceding-sibling (and is not itself
2373
+ mml:mprescript) is a script, except for the first child which is always the base.
2374
+ The mml:none element is a place holder for a sub/sup element slot.
2375
+
2376
+ mmultisript pattern:
2377
+ <mmultiscript>
2378
+ (base)
2379
+ (sub sup)* // Where <none/> can replace a sub/sup entry to preserve pattern.
2380
+ <mprescripts />
2381
+ (presub presup)*
2382
+ </mmultiscript>
2383
+ -->
2384
+ <!-- Count of presecript nodes that we'd print (this is essentially anything but the none placeholder. -->
2385
+ <xsl:variable name="cndPrescriptStrict"
2386
+ select="count(mml:mprescripts[1]/following-sibling::*[not(self::mml:none)])"/>
2387
+ <!-- Count of all super script excluding mml:none -->
2388
+ <xsl:variable name="cndSuperScript"
2389
+ select="count(*[not(preceding-sibling::mml:mprescripts) and not(self::mml:mprescripts) and ((position() mod 2) = 1) and not(self::mml:none)]) - 1"/>
2390
+ <!-- Count of all sup script excluding mml:none -->
2391
+ <xsl:variable name="cndSubScript"
2392
+ select="count(*[not(preceding-sibling::mml:mprescripts) and not(self::mml:mprescripts) and ((position() mod 2) = 0) and not(self::mml:none)])"/>
2393
+ <!-- Count of all scripts excluding mml:none -->
2394
+ <xsl:variable name="cndScriptStrict" select="$cndSuperScript + $cndSubScript"/>
2395
+ <!-- Count of all scripts including mml:none. This is essentially all nodes before the
2396
+ first mml:mprescripts except the base. -->
2397
+ <xsl:variable name="cndScript"
2398
+ select="count(*[not(preceding-sibling::mml:mprescripts) and not(self::mml:mprescripts)]) - 1"/>
2399
+
2400
+ <xsl:choose>
2401
+ <!-- The easy case first. No prescripts, and no script ... just a base -->
2402
+ <xsl:when test="$cndPrescriptStrict &lt;= 0 and $cndScriptStrict &lt;= 0">
2403
+ <xsl:apply-templates mode="mml" select="*[1]"/>
2404
+ </xsl:when>
2405
+
2406
+ <!-- Next, if there are no prescripts -->
2407
+ <xsl:when test="$cndPrescriptStrict &lt;= 0">
2408
+ <!-- we know we have some scripts or else we would have taken the earlier
2409
+ branch. -->
2410
+ <xsl:choose>
2411
+ <!-- We have both sub and super scripts-->
2412
+ <xsl:when test="$cndSuperScript &gt; 0 and $cndSubScript &gt; 0">
2413
+ <sSubSup>
2414
+ <e>
2415
+ <xsl:call-template name="CreateArgProp"/>
2416
+ <xsl:apply-templates mode="mml" select="child::*[1]"/>
2417
+ </e>
2418
+
2419
+ <!-- Every child except the first is a script. Do the split -->
2420
+ <xsl:call-template name="SplitScripts">
2421
+ <xsl:with-param name="ndScripts" select="*[position() &gt; 1]"/>
2422
+ </xsl:call-template>
2423
+ </sSubSup>
2424
+ </xsl:when>
2425
+ <!-- Just a sub script -->
2426
+ <xsl:when test="$cndSubScript &gt; 0">
2427
+ <sSub>
2428
+ <e>
2429
+ <xsl:call-template name="CreateArgProp"/>
2430
+ <xsl:apply-templates mode="mml" select="child::*[1]"/>
2431
+ </e>
2432
+
2433
+ <!-- No prescripts and no super scripts, therefore, it's a sub. -->
2434
+ <sub>
2435
+ <xsl:apply-templates mode="mml" select="*[position() &gt; 1]"/>
2436
+ </sub>
2437
+ </sSub>
2438
+ </xsl:when>
2439
+ <!-- Just super script -->
2440
+ <xsl:otherwise>
2441
+ <sSup>
2442
+ <e>
2443
+ <xsl:call-template name="CreateArgProp"/>
2444
+ <xsl:apply-templates mode="mml" select="child::*[1]"/>
2445
+ </e>
2446
+
2447
+ <!-- No prescripts and no sub scripts, therefore, it's a sup. -->
2448
+ <sup>
2449
+ <xsl:apply-templates mode="mml" select="*[position() &gt; 1]"/>
2450
+ </sup>
2451
+ </sSup>
2452
+ </xsl:otherwise>
2453
+ </xsl:choose>
2454
+ </xsl:when>
2455
+
2456
+ <!-- Next, if there are no scripts -->
2457
+ <xsl:when test="$cndScriptStrict &lt;= 0">
2458
+ <!-- we know we have some prescripts or else we would have taken the earlier
2459
+ branch. So, create an sPre and split the elements -->
2460
+ <sPre>
2461
+ <e>
2462
+ <xsl:call-template name="CreateArgProp"/>
2463
+ <xsl:apply-templates mode="mml" select="child::*[1]"/>
2464
+ </e>
2465
+
2466
+ <!-- The prescripts come after the mml:mprescript and if we get here
2467
+ we know there exists some elements after the mml:mprescript element.
2468
+
2469
+ The prescript element has no sub/subsup variation, therefore, even if
2470
+ we're only writing sub, we need to write out both the sub and sup element.
2471
+ -->
2472
+ <xsl:call-template name="SplitScripts">
2473
+ <xsl:with-param name="ndScripts" select="mml:mprescripts[1]/following-sibling::*"/>
2474
+ </xsl:call-template>
2475
+ </sPre>
2476
+ </xsl:when>
2477
+
2478
+ <!-- Finally, the case with both prescripts and scripts. Create an sPre
2479
+ element to house the prescripts, with a sub/sup/subsup element at its base. -->
2480
+ <xsl:otherwise>
2481
+ <sPre>
2482
+ <e>
2483
+ <xsl:choose>
2484
+ <!-- We have both sub and super scripts-->
2485
+ <xsl:when test="$cndSuperScript &gt; 0 and $cndSubScript &gt; 0">
2486
+ <sSubSup>
2487
+ <e>
2488
+ <xsl:call-template name="CreateArgProp"/>
2489
+ <xsl:apply-templates mode="mml" select="child::*[1]"/>
2490
+ </e>
2491
+
2492
+ <!-- scripts come before the mml:mprescript but after the first child, so their
2493
+ positions will be 2, 3, ... ($nndScript + 1) -->
2494
+ <xsl:call-template name="SplitScripts">
2495
+ <xsl:with-param name="ndScripts"
2496
+ select="*[(position() &gt; 1) and (position() &lt;= ($cndScript + 1))]"/>
2497
+ </xsl:call-template>
2498
+ </sSubSup>
2499
+ </xsl:when>
2500
+ <!-- Just a sub script -->
2501
+ <xsl:when test="$cndSubScript &gt; 0">
2502
+ <sSub>
2503
+ <e>
2504
+ <xsl:call-template name="CreateArgProp"/>
2505
+ <xsl:apply-templates mode="mml" select="child::*[1]"/>
2506
+ </e>
2507
+
2508
+ <!-- We have prescripts but no super scripts, therefore, do a sub
2509
+ and apply templates to all tokens counted by cndScript. -->
2510
+ <sub>
2511
+ <xsl:apply-templates mode="mml" select="*[position() &gt; 1 and (position() &lt;= ($cndScript + 1))]"/>
2512
+ </sub>
2513
+ </sSub>
2514
+ </xsl:when>
2515
+ <!-- Just super script -->
2516
+ <xsl:otherwise>
2517
+ <sSup>
2518
+ <e>
2519
+ <xsl:call-template name="CreateArgProp"/>
2520
+ <xsl:apply-templates mode="mml" select="child::*[1]"/>
2521
+ </e>
2522
+
2523
+ <!-- We have prescripts but no sub scripts, therefore, do a sub
2524
+ and apply templates to all tokens counted by cndScript. -->
2525
+ <sup>
2526
+ <xsl:apply-templates mode="mml" select="*[position() &gt; 1 and (position() &lt;= ($cndScript + 1))]"/>
2527
+ </sup>
2528
+ </sSup>
2529
+ </xsl:otherwise>
2530
+ </xsl:choose>
2531
+ </e>
2532
+
2533
+ <!-- The prescripts come after the mml:mprescript and if we get here
2534
+ we know there exists one such element -->
2535
+ <xsl:call-template name="SplitScripts">
2536
+ <xsl:with-param name="ndScripts" select="mml:mprescripts[1]/following-sibling::*"/>
2537
+ </xsl:call-template>
2538
+ </sPre>
2539
+ </xsl:otherwise>
2540
+ </xsl:choose>
2541
+ </xsl:template>
2542
+
2543
+ <!-- Template that determines if ndCur is an equation array.
2544
+
2545
+ ndCur is an equation array if:
2546
+
2547
+ 0. The table has a columnalign other than the default (center)
2548
+ 1. There are are no frame lines
2549
+ 2. There are no column lines
2550
+ 3. There are no row lines
2551
+ 4. There is no row with more than 1 column
2552
+ 5. There is no row with fewer than 1 column
2553
+ 6. There are no labeled rows.
2554
+
2555
+ -->
2556
+ <xsl:template name="FIsEqArray">
2557
+ <xsl:param name="ndCur" select="."/>
2558
+
2559
+ <!-- There should be no frame, columnlines, or rowlines -->
2560
+ <xsl:choose>
2561
+ <xsl:when test="@columnalign!='center'">0</xsl:when>
2562
+ <xsl:when test="(not($ndCur/@frame) or $ndCur/@frame='' or $ndCur/@frame='none')
2563
+ and (not($ndCur/@mml:frame) or $ndCur/@mml:frame='' or $ndCur/@mml:frame='none')
2564
+ and (not($ndCur/@columnlines) or $ndCur/@columnlines='' or $ndCur/@columnlines='none')
2565
+ and (not($ndCur/@mml:columnlines) or $ndCur/@mml:columnlines='' or $ndCur/@mml:columnlines='none')
2566
+ and (not($ndCur/@rowlines) or $ndCur/@rowlines='' or $ndCur/@rowlines='none')
2567
+ and (not($ndCur/@mml:rowlines) or $ndCur/@mml:rowlines='' or $ndCur/@mml:rowlines='none')
2568
+ and not($ndCur/mml:mtr[count(mml:mtd) &gt; 1])
2569
+ and not($ndCur/mml:mtr[count(mml:mtd) &lt; 1])
2570
+ and not($ndCur/mml:mlabeledtr)">1</xsl:when>
2571
+ <xsl:otherwise>0</xsl:otherwise>
2572
+ </xsl:choose>
2573
+ </xsl:template>
2574
+
2575
+ <!-- Template used to determine if we should ignore a collection when iterating through
2576
+ a mathml equation array row.
2577
+
2578
+ So far, the only thing that needs to be ignored is the argument of an nary. We
2579
+ can ignore this since it is output when we apply-templates to the munder[over]/msub[sup].
2580
+ -->
2581
+ <xsl:template name="FIgnoreCollection">
2582
+ <xsl:param name="ndCur" select="."/>
2583
+
2584
+ <xsl:variable name="fNaryArgument">
2585
+ <xsl:call-template name="FIsNaryArgument">
2586
+ <xsl:with-param name="ndCur" select="$ndCur"/>
2587
+ </xsl:call-template>
2588
+ </xsl:variable>
2589
+
2590
+ <xsl:choose>
2591
+ <xsl:when test="$fNaryArgument=1">1</xsl:when>
2592
+ <xsl:otherwise>0</xsl:otherwise>
2593
+ </xsl:choose>
2594
+ </xsl:template>
2595
+
2596
+ <!-- Template used to determine if we've already encountered an maligngroup or malignmark.
2597
+
2598
+ This is needed because omml has an implicit spacing alignment (omml spacing alignment =
2599
+ mathml's maligngroup element) at the beginning of each equation array row. Therefore,
2600
+ the first maligngroup (implied or explicit) we encounter does not need to be output.
2601
+ This template recursively searches up the xml tree and looks at previous siblings to see
2602
+ if they have a descendant that is an maligngroup or malignmark. We look for the malignmark
2603
+ to find the implicit maligngroup.
2604
+ -->
2605
+ <xsl:template name="FFirstAlignAlreadyFound">
2606
+ <xsl:param name="ndCur" select="."/>
2607
+
2608
+ <xsl:choose>
2609
+ <xsl:when test="count($ndCur/preceding-sibling::*[descendant-or-self::mml:maligngroup or descendant-or-self::mml:malignmark]) &gt; 0">1</xsl:when>
2610
+ <xsl:when test="not($ndCur/parent::mml:mtd)">
2611
+ <xsl:call-template name="FFirstAlignAlreadyFound">
2612
+ <xsl:with-param name="ndCur" select="$ndCur/parent::*"/>
2613
+ </xsl:call-template>
2614
+ </xsl:when>
2615
+ <xsl:otherwise>0</xsl:otherwise>
2616
+ </xsl:choose>
2617
+ </xsl:template>
2618
+
2619
+ <!-- This template builds a string that is result of concatenating a given string several times.
2620
+
2621
+ Given strToRepeat, create a string that has strToRepeat repeated iRepitions times.
2622
+ -->
2623
+ <xsl:template name="ConcatStringRepeat">
2624
+ <xsl:param name="strToRepeat" select="''"/>
2625
+ <xsl:param name="iRepetitions" select="0"/>
2626
+ <xsl:param name="strBuilding" select="''"/>
2627
+
2628
+ <xsl:choose>
2629
+ <xsl:when test="$iRepetitions &lt;= 0">
2630
+ <xsl:value-of select="$strBuilding"/>
2631
+ </xsl:when>
2632
+ <xsl:otherwise>
2633
+ <xsl:call-template name="ConcatStringRepeat">
2634
+ <xsl:with-param name="strToRepeat" select="$strToRepeat"/>
2635
+ <xsl:with-param name="iRepetitions" select="$iRepetitions - 1"/>
2636
+ <xsl:with-param name="strBuilding" select="concat($strBuilding, $strToRepeat)"/>
2637
+ </xsl:call-template>
2638
+ </xsl:otherwise>
2639
+ </xsl:choose>
2640
+ </xsl:template>
2641
+
2642
+ <!-- This template determines if ndCur is a special collection.
2643
+ By special collection, I mean is ndCur the outer element of some special grouping
2644
+ of mathml elements that actually represents some over all omml structure.
2645
+
2646
+ For instance, is ndCur a linear fraction, or an omml function.
2647
+ -->
2648
+ <xsl:template name="FSpecialCollection">
2649
+ <xsl:param name="ndCur" select="."/>
2650
+ <xsl:choose>
2651
+ <xsl:when test="$ndCur/self::mml:mrow">
2652
+ <xsl:variable name="fLinearFraction">
2653
+ <xsl:call-template name="FLinearFrac">
2654
+ <xsl:with-param name="ndCur" select="$ndCur"/>
2655
+ </xsl:call-template>
2656
+ </xsl:variable>
2657
+ <xsl:variable name="fFunc">
2658
+ <xsl:call-template name="FIsFunc">
2659
+ <xsl:with-param name="ndCur" select="$ndCur"/>
2660
+ </xsl:call-template>
2661
+ </xsl:variable>
2662
+ <xsl:choose>
2663
+ <xsl:when test="$fLinearFraction=1 or $fFunc=1">1</xsl:when>
2664
+ <xsl:otherwise>0</xsl:otherwise>
2665
+ </xsl:choose>
2666
+ </xsl:when>
2667
+ <xsl:otherwise>0</xsl:otherwise>
2668
+ </xsl:choose>
2669
+ </xsl:template>
2670
+
2671
+ <!-- This template iterates through the children of an equation array row (mtr) and outputs
2672
+ the equation.
2673
+
2674
+ This template does all the work to output ampersands and skip the right elements when needed.
2675
+ -->
2676
+ <xsl:template name="ProcessEqArrayRow">
2677
+ <xsl:param name="ndCur" select="."/>
2678
+
2679
+ <xsl:for-each select="$ndCur/*">
2680
+ <xsl:variable name="fSpecialCollection">
2681
+ <xsl:call-template name="FSpecialCollection">
2682
+ <xsl:with-param name="ndCur" select="."/>
2683
+ </xsl:call-template>
2684
+ </xsl:variable>
2685
+ <xsl:variable name="fIgnoreCollection">
2686
+ <xsl:call-template name="FIgnoreCollection">
2687
+ <xsl:with-param name="ndCur" select="."/>
2688
+ </xsl:call-template>
2689
+ </xsl:variable>
2690
+ <xsl:choose>
2691
+ <!-- If we have an alignment element output the ampersand. -->
2692
+ <xsl:when test="self::mml:maligngroup or self::mml:malignmark">
2693
+ <!-- Omml has an implied spacing alignment at the beginning of each equation.
2694
+ Therefore, if this is the first ampersand to be output, don't actually output. -->
2695
+ <xsl:variable name="fFirstAlignAlreadyFound">
2696
+ <xsl:call-template name="FFirstAlignAlreadyFound">
2697
+ <xsl:with-param name="ndCur" select="."/>
2698
+ </xsl:call-template>
2699
+ </xsl:variable>
2700
+ <!-- Don't output unless it is an malignmark or we have already previously found an alignment point. -->
2701
+ <xsl:if test="self::mml:malignmark or $fFirstAlignAlreadyFound=1">
2702
+ <r>
2703
+ <t>&amp;</t>
2704
+ </r>
2705
+ </xsl:if>
2706
+ </xsl:when>
2707
+ <!-- If this node is an non-special mrow or mstyle and we aren't supposed to ignore this collection, then
2708
+ go ahead an apply templates to this node. -->
2709
+ <xsl:when test="$fIgnoreCollection=0 and ((self::mml:mrow and $fSpecialCollection=0) or self::mml:mstyle)">
2710
+ <xsl:call-template name="ProcessEqArrayRow">
2711
+ <xsl:with-param name="ndCur" select="."/>
2712
+ </xsl:call-template>
2713
+ </xsl:when>
2714
+ <!-- At this point we have some mathml structure (fraction, nary, non-grouping element, etc.) -->
2715
+ <!-- If this mathml structure has alignment groups or marks as children, then extract those since
2716
+ omml can't handle that. -->
2717
+ <xsl:when test="descendant::mml:maligngroup or descendant::mml:malignmark">
2718
+ <xsl:variable name="cMalignGroups">
2719
+ <xsl:value-of select="count(descendant::mml:maligngroup)"/>
2720
+ </xsl:variable>
2721
+ <xsl:variable name="cMalignMarks">
2722
+ <xsl:value-of select="count(descendant::mml:malignmark)"/>
2723
+ </xsl:variable>
2724
+ <!-- Output all maligngroups and malignmarks as '&amp;' -->
2725
+ <xsl:if test="$cMalignGroups + $cMalignMarks &gt; 0">
2726
+ <xsl:variable name="str">
2727
+ <xsl:call-template name="ConcatStringRepeat">
2728
+ <xsl:with-param name="strToRepeat" select="'&amp;'"/>
2729
+ <xsl:with-param name="iRepetitions" select="$cMalignGroups + $cMalignMarks"/>
2730
+ <xsl:with-param name="strBuilding" select="''"/>
2731
+ </xsl:call-template>
2732
+ </xsl:variable>
2733
+ <r>
2734
+ <t>
2735
+ <xsl:call-template name="OutputText">
2736
+ <xsl:with-param name="sInput" select="$str"/>
2737
+ </xsl:call-template>
2738
+ </t>
2739
+ </r>
2740
+ </xsl:if>
2741
+ <!-- Now that the '&amp;' have been extracted, just apply-templates to this node.-->
2742
+ <xsl:apply-templates mode="mml" select="."/>
2743
+ </xsl:when>
2744
+ <!-- If there are no alignment points as descendants, then go ahead and output this node. -->
2745
+ <xsl:otherwise>
2746
+ <xsl:apply-templates mode="mml" select="."/>
2747
+ </xsl:otherwise>
2748
+ </xsl:choose>
2749
+ </xsl:for-each>
2750
+ </xsl:template>
2751
+
2752
+ <!-- This template transforms mtable into its appropriate omml type.
2753
+
2754
+ There are two possible omml constructs that an mtable can become: a matrix or
2755
+ an equation array.
2756
+
2757
+ Because omml has no generic table construct, the omml matrix is the best approximate
2758
+ for a mathml table.
2759
+
2760
+ Our equation array transformation is very simple. The main goal of this transform is to
2761
+ allow roundtripping omml eq arrays through mathml. The template ProcessEqArrayRow was never
2762
+ intended to account for many of the alignment flexibilities that are present in mathml like
2763
+ using the alig attribute, using alignmark attribute in token elements, etc.
2764
+
2765
+ The restrictions on this transform require <malignmark> and <maligngroup> elements to be outside of
2766
+ any non-grouping mathml elements (that is, mrow and mstyle). Moreover, these elements cannot be the children of
2767
+ mrows that represent linear fractions or functions. Also, <malignmark> cannot be a child
2768
+ of token attributes.
2769
+
2770
+ In the case that the above
2771
+
2772
+ -->
2773
+ <xsl:template mode="mml" match="mml:mtable">
2774
+ <xsl:variable name="fEqArray">
2775
+ <xsl:call-template name="FIsEqArray">
2776
+ <xsl:with-param name="ndCur" select="."/>
2777
+ </xsl:call-template>
2778
+ </xsl:variable>
2779
+ <xsl:variable name="alignment">
2780
+ <xsl:value-of select="@columnalign"/>
2781
+ </xsl:variable>
2782
+ <xsl:choose>
2783
+ <xsl:when test="$fEqArray=1">
2784
+ <eqArr>
2785
+ <xsl:if test="$alignment!=''">
2786
+ <eqArrPr>
2787
+ <baseJc m:val="{$alignment}"/>
2788
+ </eqArrPr>
2789
+ </xsl:if>
2790
+ <xsl:for-each select="mml:mtr">
2791
+ <e>
2792
+ <xsl:call-template name="ProcessEqArrayRow">
2793
+ <xsl:with-param name="ndCur" select="mml:mtd"/>
2794
+ </xsl:call-template>
2795
+ </e>
2796
+ </xsl:for-each>
2797
+ </eqArr>
2798
+ </xsl:when>
2799
+ <xsl:otherwise>
2800
+ <xsl:variable name="cMaxElmtsInRow">
2801
+ <xsl:call-template name="CountMaxElmtsInRow">
2802
+ <xsl:with-param name="ndCur" select="*[1]"/>
2803
+ <xsl:with-param name="cMaxElmtsInRow" select="0"/>
2804
+ </xsl:call-template>
2805
+ </xsl:variable>
2806
+ <m>
2807
+ <mPr>
2808
+ <baseJc m:val="center"/>
2809
+ <plcHide m:val="on"/>
2810
+ <mcs>
2811
+ <mc>
2812
+ <mcPr>
2813
+ <count>
2814
+ <xsl:attribute name="m:val">
2815
+ <xsl:value-of select="$cMaxElmtsInRow"/>
2816
+ </xsl:attribute>
2817
+ </count>
2818
+ <mcJc m:val="{$alignment}"/>
2819
+ </mcPr>
2820
+ </mc>
2821
+ </mcs>
2822
+ </mPr>
2823
+ <xsl:for-each select="*">
2824
+ <xsl:choose>
2825
+ <xsl:when test="self::mml:mtr or self::mml:mlabeledtr">
2826
+ <mr>
2827
+ <xsl:choose>
2828
+ <xsl:when test="self::mml:mtr">
2829
+ <xsl:for-each select="*">
2830
+ <e>
2831
+ <xsl:apply-templates mode="mml" select="."/>
2832
+ </e>
2833
+ </xsl:for-each>
2834
+ <xsl:call-template name="CreateEmptyElmt">
2835
+ <xsl:with-param name="cEmptyMtd" select="$cMaxElmtsInRow - count(*)"/>
2836
+ </xsl:call-template>
2837
+ </xsl:when>
2838
+ <xsl:otherwise>
2839
+ <xsl:for-each select="*[position() &gt; 1]">
2840
+ <e>
2841
+ <xsl:apply-templates mode="mml" select="."/>
2842
+ </e>
2843
+ </xsl:for-each>
2844
+ <xsl:call-template name="CreateEmptyElmt">
2845
+ <xsl:with-param name="cEmptyMtd" select="$cMaxElmtsInRow - (count(*) - 1)"/>
2846
+ </xsl:call-template>
2847
+ </xsl:otherwise>
2848
+ </xsl:choose>
2849
+ </mr>
2850
+ </xsl:when>
2851
+ <xsl:otherwise>
2852
+ <mr>
2853
+ <e>
2854
+ <xsl:apply-templates mode="mml" select="."/>
2855
+ </e>
2856
+ <xsl:call-template name="CreateEmptyElmt">
2857
+ <xsl:with-param name="cEmptyMtd" select="$cMaxElmtsInRow - 1"/>
2858
+ </xsl:call-template>
2859
+ </mr>
2860
+ </xsl:otherwise>
2861
+ </xsl:choose>
2862
+ </xsl:for-each>
2863
+ </m>
2864
+ </xsl:otherwise>
2865
+ </xsl:choose>
2866
+ </xsl:template>
2867
+ <xsl:template mode="mml" match="m:mtd">
2868
+ <xsl:apply-templates mode="mml"/>
2869
+ </xsl:template>
2870
+ <xsl:template name="CreateEmptyElmt">
2871
+ <xsl:param name="cEmptyMtd"/>
2872
+ <xsl:if test="$cEmptyMtd &gt; 0">
2873
+ <e/>
2874
+ <xsl:call-template name="CreateEmptyElmt">
2875
+ <xsl:with-param name="cEmptyMtd" select="$cEmptyMtd - 1"/>
2876
+ </xsl:call-template>
2877
+ </xsl:if>
2878
+ </xsl:template>
2879
+ <xsl:template name="CountMaxElmtsInRow">
2880
+ <xsl:param name="ndCur"/>
2881
+ <xsl:param name="cMaxElmtsInRow" select="0"/>
2882
+ <xsl:choose>
2883
+ <xsl:when test="not($ndCur)">
2884
+ <xsl:value-of select="$cMaxElmtsInRow"/>
2885
+ </xsl:when>
2886
+ <xsl:otherwise>
2887
+ <xsl:call-template name="CountMaxElmtsInRow">
2888
+ <xsl:with-param name="ndCur" select="$ndCur/following-sibling::*[1]"/>
2889
+ <xsl:with-param name="cMaxElmtsInRow">
2890
+ <xsl:choose>
2891
+ <xsl:when test="local-name($ndCur) = 'mlabeledtr' and namespace-uri($ndCur) = 'http://www.w3.org/1998/Math/MathML'">
2892
+ <xsl:choose>
2893
+ <xsl:when test="(count($ndCur/*) - 1) &gt; $cMaxElmtsInRow">
2894
+ <xsl:value-of select="count($ndCur/*) - 1"/>
2895
+ </xsl:when>
2896
+ <xsl:otherwise>
2897
+ <xsl:value-of select="$cMaxElmtsInRow"/>
2898
+ </xsl:otherwise>
2899
+ </xsl:choose>
2900
+ </xsl:when>
2901
+ <xsl:when test="local-name($ndCur) = 'mtr' and namespace-uri($ndCur) = 'http://www.w3.org/1998/Math/MathML'">
2902
+ <xsl:choose>
2903
+ <xsl:when test="count($ndCur/*) &gt; $cMaxElmtsInRow">
2904
+ <xsl:value-of select="count($ndCur/*)"/>
2905
+ </xsl:when>
2906
+ <xsl:otherwise>
2907
+ <xsl:value-of select="$cMaxElmtsInRow"/>
2908
+ </xsl:otherwise>
2909
+ </xsl:choose>
2910
+ </xsl:when>
2911
+ <xsl:otherwise>
2912
+ <xsl:choose>
2913
+ <xsl:when test="1 &gt; $cMaxElmtsInRow">
2914
+ <xsl:value-of select="1"/>
2915
+ </xsl:when>
2916
+ <xsl:otherwise>
2917
+ <xsl:value-of select="$cMaxElmtsInRow"/>
2918
+ </xsl:otherwise>
2919
+ </xsl:choose>
2920
+ </xsl:otherwise>
2921
+ </xsl:choose>
2922
+ </xsl:with-param>
2923
+ </xsl:call-template>
2924
+ </xsl:otherwise>
2925
+ </xsl:choose>
2926
+ </xsl:template>
2927
+ <xsl:template mode="mml" match="mml:mglyph">
2928
+ <xsl:call-template name="CreateMglyph"/>
2929
+ </xsl:template>
2930
+ <xsl:template mode="mml"
2931
+ match="mml:mi[child::mml:mglyph] | mml:mn[child::mml:mglyph] | mml:mo[child::mml:mglyph] | mml:ms[child::mml:mglyph] | mml:mtext[child::mml:mglyph]">
2932
+ <xsl:if test="string-length(normalize-space(.)) &gt; 0">
2933
+ <r>
2934
+ <xsl:call-template name="CreateRunProp">
2935
+ <xsl:with-param name="mathvariant">
2936
+ <xsl:choose>
2937
+ <xsl:when test="@mathvariant">
2938
+ <xsl:value-of select="@mathvariant"/>
2939
+ </xsl:when>
2940
+ <xsl:otherwise>
2941
+ <xsl:value-of select="@mml:mathvariant"/>
2942
+ </xsl:otherwise>
2943
+ </xsl:choose>
2944
+ </xsl:with-param>
2945
+ <xsl:with-param name="fontstyle">
2946
+ <xsl:choose>
2947
+ <xsl:when test="@fontstyle">
2948
+ <xsl:value-of select="@fontstyle"/>
2949
+ </xsl:when>
2950
+ <xsl:otherwise>
2951
+ <xsl:value-of select="@mml:fontstyle"/>
2952
+ </xsl:otherwise>
2953
+ </xsl:choose>
2954
+ </xsl:with-param>
2955
+ <xsl:with-param name="fontweight">
2956
+ <xsl:choose>
2957
+ <xsl:when test="@fontweight">
2958
+ <xsl:value-of select="@fontweight"/>
2959
+ </xsl:when>
2960
+ <xsl:otherwise>
2961
+ <xsl:value-of select="@mml:fontweight"/>
2962
+ </xsl:otherwise>
2963
+ </xsl:choose>
2964
+ </xsl:with-param>
2965
+ <xsl:with-param name="mathcolor">
2966
+ <xsl:choose>
2967
+ <xsl:when test="@mathcolor">
2968
+ <xsl:value-of select="@mathcolor"/>
2969
+ </xsl:when>
2970
+ <xsl:otherwise>
2971
+ <xsl:value-of select="@mml:mathcolor"/>
2972
+ </xsl:otherwise>
2973
+ </xsl:choose>
2974
+ </xsl:with-param>
2975
+ <xsl:with-param name="mathsize">
2976
+ <xsl:choose>
2977
+ <xsl:when test="@mathsize">
2978
+ <xsl:value-of select="@mathsize"/>
2979
+ </xsl:when>
2980
+ <xsl:otherwise>
2981
+ <xsl:value-of select="@mml:mathsize"/>
2982
+ </xsl:otherwise>
2983
+ </xsl:choose>
2984
+ </xsl:with-param>
2985
+ <xsl:with-param name="color">
2986
+ <xsl:choose>
2987
+ <xsl:when test="@color">
2988
+ <xsl:value-of select="@color"/>
2989
+ </xsl:when>
2990
+ <xsl:otherwise>
2991
+ <xsl:value-of select="@mml:color"/>
2992
+ </xsl:otherwise>
2993
+ </xsl:choose>
2994
+ </xsl:with-param>
2995
+ <xsl:with-param name="fontsize">
2996
+ <xsl:choose>
2997
+ <xsl:when test="@fontsize">
2998
+ <xsl:value-of select="@fontsize"/>
2999
+ </xsl:when>
3000
+ <xsl:otherwise>
3001
+ <xsl:value-of select="@mml:fontsize"/>
3002
+ </xsl:otherwise>
3003
+ </xsl:choose>
3004
+ </xsl:with-param>
3005
+ <xsl:with-param name="fNor">
3006
+ <xsl:call-template name="FNor">
3007
+ <xsl:with-param name="ndCur" select="."/>
3008
+ </xsl:call-template>
3009
+ </xsl:with-param>
3010
+ <xsl:with-param name="fLit">
3011
+ <xsl:call-template name="FLit">
3012
+ <xsl:with-param name="ndCur" select="."/>
3013
+ </xsl:call-template>
3014
+ </xsl:with-param>
3015
+ <xsl:with-param name="ndCur" select="."/>
3016
+ </xsl:call-template>
3017
+ <t>
3018
+ <xsl:call-template name="OutputText">
3019
+ <xsl:with-param name="sInput">
3020
+ <xsl:choose>
3021
+ <xsl:when test="self::mml:ms">
3022
+ <xsl:call-template name="OutputMs">
3023
+ <xsl:with-param name="msCur" select="."/>
3024
+ </xsl:call-template>
3025
+ </xsl:when>
3026
+ <xsl:otherwise>
3027
+ <xsl:value-of select="normalize-space(.)"/>
3028
+ </xsl:otherwise>
3029
+ </xsl:choose>
3030
+ </xsl:with-param>
3031
+ </xsl:call-template>
3032
+ </t>
3033
+ </r>
3034
+ </xsl:if>
3035
+ <xsl:for-each select="child::mml:mglyph">
3036
+ <xsl:call-template name="CreateMglyph">
3037
+ <xsl:with-param name="ndCur" select="."/>
3038
+ </xsl:call-template>
3039
+ </xsl:for-each>
3040
+ </xsl:template>
3041
+ <xsl:template name="FGlyphIndexOk">
3042
+ <xsl:param name="index"/>
3043
+ <xsl:if test="$index != ''">
3044
+ <xsl:choose>
3045
+ <xsl:when test="string(number(string(floor($index)))) = 'NaN'"/>
3046
+ <xsl:when test="number($index) &lt; 32 and not(number($index) = 9 or number($index) = 10 or number($index) = 13)"/>
3047
+ <xsl:when test="number($index) = 65534 or number($index) = 65535"/>
3048
+ <xsl:otherwise>1</xsl:otherwise>
3049
+ </xsl:choose>
3050
+ </xsl:if>
3051
+ </xsl:template>
3052
+ <xsl:template name="CreateMglyph">
3053
+ <xsl:param name="ndCur"/>
3054
+ <r>
3055
+ <xsl:call-template name="CreateRunProp">
3056
+ <xsl:with-param name="mathvariant">
3057
+ <xsl:choose>
3058
+ <xsl:when test="(not(@mathvariant) or @mathvariant='') and (not(@mml:mathvariant) or @mml:mathvariant='') and (../@mathvariant!='' or ../@mml:mathvariant!='')">
3059
+ <xsl:choose>
3060
+ <xsl:when test="../@mathvariant">
3061
+ <xsl:value-of select="../@mathvariant"/>
3062
+ </xsl:when>
3063
+ <xsl:otherwise>
3064
+ <xsl:value-of select="../mml:mathvariant"/>
3065
+ </xsl:otherwise>
3066
+ </xsl:choose>
3067
+ </xsl:when>
3068
+ <xsl:otherwise>
3069
+ <xsl:choose>
3070
+ <xsl:when test="@mathvariant">
3071
+ <xsl:value-of select="@mathvariant"/>
3072
+ </xsl:when>
3073
+ <xsl:otherwise>
3074
+ <xsl:value-of select="@mml:mathvariant"/>
3075
+ </xsl:otherwise>
3076
+ </xsl:choose>
3077
+ </xsl:otherwise>
3078
+ </xsl:choose>
3079
+ </xsl:with-param>
3080
+ <xsl:with-param name="fontstyle">
3081
+ <xsl:choose>
3082
+ <xsl:when test="(not(@fontstyle) or @fontstyle='') and (not(@mml:fontstyle) or @mml:fontstyle='') and (../@fontstyle!='' or ../@mml:fontstyle!='')">
3083
+ <xsl:choose>
3084
+ <xsl:when test="../@fontstyle">
3085
+ <xsl:value-of select="../@fontstyle"/>
3086
+ </xsl:when>
3087
+ <xsl:otherwise>
3088
+ <xsl:value-of select="../@mml:fontstyle"/>
3089
+ </xsl:otherwise>
3090
+ </xsl:choose>
3091
+ </xsl:when>
3092
+ <xsl:otherwise>
3093
+ <xsl:choose>
3094
+ <xsl:when test="@fontstyle">
3095
+ <xsl:value-of select="@fontstyle"/>
3096
+ </xsl:when>
3097
+ <xsl:otherwise>
3098
+ <xsl:value-of select="@mml:fontstyle"/>
3099
+ </xsl:otherwise>
3100
+ </xsl:choose>
3101
+ </xsl:otherwise>
3102
+ </xsl:choose>
3103
+ </xsl:with-param>
3104
+ <xsl:with-param name="fontweight">
3105
+ <xsl:choose>
3106
+ <xsl:when test="(not(@fontweight) or @fontweight='') and (not(@mml:fontweight) or @mml:fontweight='') and (../@fontweight!='' or ../@mml:fontweight!='')">
3107
+ <xsl:choose>
3108
+ <xsl:when test="../@fontweight">
3109
+ <xsl:value-of select="../@fontweight"/>
3110
+ </xsl:when>
3111
+ <xsl:otherwise>
3112
+ <xsl:value-of select="../@mml:fontweight"/>
3113
+ </xsl:otherwise>
3114
+ </xsl:choose>
3115
+ </xsl:when>
3116
+ <xsl:otherwise>
3117
+ <xsl:choose>
3118
+ <xsl:when test="@fontweight">
3119
+ <xsl:value-of select="@fontweight"/>
3120
+ </xsl:when>
3121
+ <xsl:otherwise>
3122
+ <xsl:value-of select="@mml:fontweight"/>
3123
+ </xsl:otherwise>
3124
+ </xsl:choose>
3125
+ </xsl:otherwise>
3126
+ </xsl:choose>
3127
+ </xsl:with-param>
3128
+ <xsl:with-param name="mathcolor">
3129
+ <xsl:choose>
3130
+ <xsl:when test="(not(@mathcolor) or @mathcolor='') and (not(@mml:mathcolor) or @mml:mathcolor='') and (../@mathcolor!='' or ../@mml:mathcolor!='')">
3131
+ <xsl:choose>
3132
+ <xsl:when test="../@mathcolor">
3133
+ <xsl:value-of select="../@mathcolor"/>
3134
+ </xsl:when>
3135
+ <xsl:otherwise>
3136
+ <xsl:value-of select="../@mml:mathcolor"/>
3137
+ </xsl:otherwise>
3138
+ </xsl:choose>
3139
+ </xsl:when>
3140
+ <xsl:otherwise>
3141
+ <xsl:choose>
3142
+ <xsl:when test="@mathcolor">
3143
+ <xsl:value-of select="@mathcolor"/>
3144
+ </xsl:when>
3145
+ <xsl:otherwise>
3146
+ <xsl:value-of select="@mml:mathcolor"/>
3147
+ </xsl:otherwise>
3148
+ </xsl:choose>
3149
+ </xsl:otherwise>
3150
+ </xsl:choose>
3151
+ </xsl:with-param>
3152
+ <xsl:with-param name="mathsize">
3153
+ <xsl:choose>
3154
+ <xsl:when test="(not(@mathsize) or @mathsize='') and (not(@mml:mathsize) or @mml:mathsize='') and (../@mathsize!='' or ../@mml:mathsize!='')">
3155
+ <xsl:choose>
3156
+ <xsl:when test="../@mathsize">
3157
+ <xsl:value-of select="../@mathsize"/>
3158
+ </xsl:when>
3159
+ <xsl:otherwise>
3160
+ <xsl:value-of select="../@mathsize"/>
3161
+ </xsl:otherwise>
3162
+ </xsl:choose>
3163
+ </xsl:when>
3164
+ <xsl:otherwise>
3165
+ <xsl:choose>
3166
+ <xsl:when test="@mathsize">
3167
+ <xsl:value-of select="@mathsize"/>
3168
+ </xsl:when>
3169
+ <xsl:otherwise>
3170
+ <xsl:value-of select="@mml:mathsize"/>
3171
+ </xsl:otherwise>
3172
+ </xsl:choose>
3173
+ </xsl:otherwise>
3174
+ </xsl:choose>
3175
+ </xsl:with-param>
3176
+ <xsl:with-param name="color">
3177
+ <xsl:choose>
3178
+ <xsl:when test="(not(@color) or @color='') and (not(@mml:color) or @mml:color='') and (../@color!='' or ../@mml:color!='')">
3179
+ <xsl:choose>
3180
+ <xsl:when test="../@color">
3181
+ <xsl:value-of select="../@color"/>
3182
+ </xsl:when>
3183
+ <xsl:otherwise>
3184
+ <xsl:value-of select="../@mml:color"/>
3185
+ </xsl:otherwise>
3186
+ </xsl:choose>
3187
+ </xsl:when>
3188
+ <xsl:otherwise>
3189
+ <xsl:choose>
3190
+ <xsl:when test="@color">
3191
+ <xsl:value-of select="@color"/>
3192
+ </xsl:when>
3193
+ <xsl:otherwise>
3194
+ <xsl:value-of select="@mml:color"/>
3195
+ </xsl:otherwise>
3196
+ </xsl:choose>
3197
+ </xsl:otherwise>
3198
+ </xsl:choose>
3199
+ </xsl:with-param>
3200
+ <xsl:with-param name="fontsize">
3201
+ <xsl:choose>
3202
+ <xsl:when test="(not(@fontsize) or @fontsize='') and (not(@mml:fontsize) or @mml:fontsize='') and (../@fontsize!='' or ../@mml:fontsize!='')">
3203
+ <xsl:choose>
3204
+ <xsl:when test="../@fontsize">
3205
+ <xsl:value-of select="../@fontsize"/>
3206
+ </xsl:when>
3207
+ <xsl:otherwise>
3208
+ <xsl:value-of select="../@mml:fontsize"/>
3209
+ </xsl:otherwise>
3210
+ </xsl:choose>
3211
+ </xsl:when>
3212
+ <xsl:otherwise>
3213
+ <xsl:choose>
3214
+ <xsl:when test="@fontsize">
3215
+ <xsl:value-of select="@fontsize"/>
3216
+ </xsl:when>
3217
+ <xsl:otherwise>
3218
+ <xsl:value-of select="@mml:fontsize"/>
3219
+ </xsl:otherwise>
3220
+ </xsl:choose>
3221
+ </xsl:otherwise>
3222
+ </xsl:choose>
3223
+ </xsl:with-param>
3224
+ <xsl:with-param name="ndCur" select="."/>
3225
+ <xsl:with-param name="font-family">
3226
+ <xsl:choose>
3227
+ <xsl:when test="@fontfamily">
3228
+ <xsl:value-of select="@fontfamily"/>
3229
+ </xsl:when>
3230
+ <xsl:otherwise>
3231
+ <xsl:value-of select="@mml:fontfamily"/>
3232
+ </xsl:otherwise>
3233
+ </xsl:choose>
3234
+ </xsl:with-param>
3235
+ <xsl:with-param name="fNor">
3236
+ <xsl:call-template name="FNor">
3237
+ <xsl:with-param name="ndCur" select="."/>
3238
+ </xsl:call-template>
3239
+ </xsl:with-param>
3240
+ <xsl:with-param name="fLit">
3241
+ <xsl:call-template name="FLit">
3242
+ <xsl:with-param name="ndCur" select="."/>
3243
+ </xsl:call-template>
3244
+ </xsl:with-param>
3245
+ </xsl:call-template>
3246
+ <xsl:variable name="shouldGlyphUseIndex">
3247
+ <xsl:call-template name="FGlyphIndexOk">
3248
+ <xsl:with-param name="index">
3249
+ <xsl:choose>
3250
+ <xsl:when test="@index">
3251
+ <xsl:value-of select="@index"/>
3252
+ </xsl:when>
3253
+ <xsl:otherwise>
3254
+ <xsl:value-of select="@mml:index"/>
3255
+ </xsl:otherwise>
3256
+ </xsl:choose>
3257
+ </xsl:with-param>
3258
+ </xsl:call-template>
3259
+ </xsl:variable>
3260
+ <xsl:choose>
3261
+ <xsl:when test="not($shouldGlyphUseIndex = '1')">
3262
+ <t>
3263
+ <xsl:choose>
3264
+ <xsl:when test="@alt">
3265
+ <xsl:value-of select="@alt"/>
3266
+ </xsl:when>
3267
+ <xsl:otherwise>
3268
+ <xsl:value-of select="@mml:alt"/>
3269
+ </xsl:otherwise>
3270
+ </xsl:choose>
3271
+ </t>
3272
+ </xsl:when>
3273
+ <xsl:otherwise>
3274
+ <xsl:variable name="nHexIndex">
3275
+ <xsl:call-template name="ConvertDecToHex">
3276
+ <xsl:with-param name="index">
3277
+ <xsl:choose>
3278
+ <xsl:when test="@index">
3279
+ <xsl:value-of select="@index"/>
3280
+ </xsl:when>
3281
+ <xsl:otherwise>
3282
+ <xsl:value-of select="@mml:index"/>
3283
+ </xsl:otherwise>
3284
+ </xsl:choose>
3285
+ </xsl:with-param>
3286
+ </xsl:call-template>
3287
+ </xsl:variable>
3288
+ <t>
3289
+ <xsl:text disable-output-escaping="yes">&amp;#x</xsl:text>
3290
+ <xsl:value-of select="$nHexIndex"/>
3291
+ <xsl:text>;</xsl:text>
3292
+ </t>
3293
+ </xsl:otherwise>
3294
+ </xsl:choose>
3295
+ </r>
3296
+ </xsl:template>
3297
+ <xsl:template name="ConvertDecToHex">
3298
+ <xsl:param name="index"/>
3299
+ <xsl:if test="$index &gt; 0">
3300
+ <xsl:call-template name="ConvertDecToHex">
3301
+ <xsl:with-param name="index" select="floor($index div 16)"/>
3302
+ </xsl:call-template>
3303
+ <xsl:choose>
3304
+ <xsl:when test="$index mod 16 &lt; 10">
3305
+ <xsl:value-of select="$index mod 16"/>
3306
+ </xsl:when>
3307
+ <xsl:otherwise>
3308
+ <xsl:choose>
3309
+ <xsl:when test="$index mod 16 = 10">A</xsl:when>
3310
+ <xsl:when test="$index mod 16 = 11">B</xsl:when>
3311
+ <xsl:when test="$index mod 16 = 12">C</xsl:when>
3312
+ <xsl:when test="$index mod 16 = 13">D</xsl:when>
3313
+ <xsl:when test="$index mod 16 = 14">E</xsl:when>
3314
+ <xsl:when test="$index mod 16 = 15">F</xsl:when>
3315
+ <xsl:otherwise>A</xsl:otherwise>
3316
+ </xsl:choose>
3317
+ </xsl:otherwise>
3318
+ </xsl:choose>
3319
+ </xsl:if>
3320
+ </xsl:template>
3321
+
3322
+ <xsl:template name="FStrContainsNonZeroDigit">
3323
+ <xsl:param name="s"/>
3324
+
3325
+ <!-- Translate any nonzero digit into a 9 -->
3326
+ <xsl:variable name="sNonZeroDigitsToNineDigit" select="translate($s, '12345678', '99999999')"/>
3327
+ <xsl:choose>
3328
+ <!-- Search for 9s -->
3329
+ <xsl:when test="contains($sNonZeroDigitsToNineDigit, '9')">1</xsl:when>
3330
+ <xsl:otherwise>0</xsl:otherwise>
3331
+ </xsl:choose>
3332
+ </xsl:template>
3333
+
3334
+ <xsl:template name="FStrContainsDigits">
3335
+ <xsl:param name="s"/>
3336
+
3337
+ <!-- Translate any digit into a 0 -->
3338
+ <xsl:variable name="sDigitsToZeroDigit" select="translate($s, '123456789', '000000000')"/>
3339
+ <xsl:choose>
3340
+ <!-- Search for 0s -->
3341
+ <xsl:when test="contains($sDigitsToZeroDigit, '0')">1</xsl:when>
3342
+ <xsl:otherwise>0</xsl:otherwise>
3343
+ </xsl:choose>
3344
+ </xsl:template>
3345
+
3346
+
3347
+ <!-- Used to determine if mpadded attribute {width, height, depth }
3348
+ indicates to show everything.
3349
+
3350
+ Unlike mathml, whose mpadded structure has great flexibility in modifying the
3351
+ bounding box's width, height, and depth, Word can only have zero or full width, height, and depth.
3352
+ Thus, if the width, height, or depth attributes indicate any kind of nonzero width, height,
3353
+ or depth, we'll translate that into a show full width, height, or depth for OMML. Only if the attribute
3354
+ indicates a zero width, height, or depth, will we report back FFull as false.
3355
+
3356
+ Example: s=0% -> FFull returns 0.
3357
+ s=2% -> FFull returns 1.
3358
+ s=0.1em -> FFull returns 1.
3359
+
3360
+ -->
3361
+ <xsl:template name="FFull">
3362
+ <xsl:param name="s"/>
3363
+
3364
+ <xsl:variable name="fStrContainsNonZeroDigit">
3365
+ <xsl:call-template name="FStrContainsNonZeroDigit">
3366
+ <xsl:with-param name="s" select="$s"/>
3367
+ </xsl:call-template>
3368
+ </xsl:variable>
3369
+
3370
+ <xsl:variable name="fStrContainsDigits">
3371
+ <xsl:call-template name="FStrContainsDigits">
3372
+ <xsl:with-param name="s" select="$s"/>
3373
+ </xsl:call-template>
3374
+ </xsl:variable>
3375
+
3376
+ <xsl:choose>
3377
+ <!-- String contained non-zero digit -->
3378
+ <xsl:when test="$fStrContainsNonZeroDigit=1">1</xsl:when>
3379
+ <!-- String didn't contain a non-zero digit, but it did contain digits.
3380
+ This must mean that all digits in the string were 0s. -->
3381
+ <xsl:when test="$fStrContainsDigits=1">0</xsl:when>
3382
+ <!-- Else, no digits, therefore, return true.
3383
+ We return true in the otherwise condition to take account for the possibility
3384
+ in MathML to say something like width="height". -->
3385
+ <xsl:otherwise>1</xsl:otherwise>
3386
+ </xsl:choose>
3387
+ </xsl:template>
3388
+
3389
+
3390
+ <!-- Just outputs phant properties, doesn't do any fancy
3391
+ thinking of its own, just obeys the defaults of
3392
+ phants. -->
3393
+ <xsl:template name="CreatePhantPropertiesCore">
3394
+ <xsl:param name="fShow" select="1"/>
3395
+ <xsl:param name="fFullWidth" select="1"/>
3396
+ <xsl:param name="fFullHeight" select="1"/>
3397
+ <xsl:param name="fFullDepth" select="1"/>
3398
+
3399
+ <xsl:if test="$fShow=0 or $fFullWidth=0 or $fFullHeight=0 or $fFullDepth=0">
3400
+ <phantPr>
3401
+ <xsl:if test="$fShow=0">
3402
+ <show>
3403
+ <xsl:attribute name="m:val">off</xsl:attribute>
3404
+ </show>
3405
+ </xsl:if>
3406
+ <xsl:if test="$fFullWidth=0">
3407
+ <zeroWid>
3408
+ <xsl:attribute name="m:val">on</xsl:attribute>
3409
+ </zeroWid>
3410
+ </xsl:if>
3411
+ <xsl:if test="$fFullHeight=0">
3412
+ <zeroAsc>
3413
+ <xsl:attribute name="m:val">on</xsl:attribute>
3414
+ </zeroAsc>
3415
+ </xsl:if>
3416
+ <xsl:if test="$fFullDepth=0">
3417
+ <zeroDesc>
3418
+ <xsl:attribute name="m:val">on</xsl:attribute>
3419
+ </zeroDesc>
3420
+ </xsl:if>
3421
+ </phantPr>
3422
+ </xsl:if>
3423
+ </xsl:template>
3424
+
3425
+ <!-- Figures out if we should factor in width, height, and depth attributes.
3426
+
3427
+ If so, then it
3428
+ gets these attributes, does some processing to figure out what the attributes indicate,
3429
+ then passes these indications to CreatePhantPropertiesCore.
3430
+
3431
+ If we aren't supposed to factor in width, height, or depth, then we'll just output the show
3432
+ attribute. -->
3433
+ <xsl:template name="CreatePhantProperties">
3434
+ <xsl:param name="ndCur" select="."/>
3435
+ <xsl:param name="fShow" select="1"/>
3436
+
3437
+ <xsl:choose>
3438
+ <!-- In the special case that we have an mphantom with one child which is an mpadded, then we should
3439
+ subsume the mpadded attributes into the mphantom attributes. The test statement below imples the
3440
+ 'one child which is an mpadded'. The first part, that the parent of mpadded is an mphantom, is implied
3441
+ by being in this template, which is only called when we've encountered an mphantom.
3442
+
3443
+ Word outputs its invisible phantoms with smashing as
3444
+
3445
+ <mml:mphantom>
3446
+ <mml:mpadded . . . >
3447
+
3448
+ </mml:mpadded>
3449
+ </mml:mphantom>
3450
+
3451
+ This test is used to allow roundtripping smashed invisible phantoms. -->
3452
+ <xsl:when test="count($ndCur/child::*)=1 and count($ndCur/mml:mpadded)=1">
3453
+ <xsl:variable name="sLowerCaseWidth">
3454
+ <xsl:choose>
3455
+ <xsl:when test="$ndCur/mml:mpadded/@width">
3456
+ <xsl:value-of select="translate($ndCur/mml:mpadded/@width, $StrUCAlphabet, $StrLCAlphabet)"/>
3457
+ </xsl:when>
3458
+ <xsl:otherwise>
3459
+ <xsl:value-of select="translate($ndCur/mml:mpadded/@mml:width, $StrUCAlphabet, $StrLCAlphabet)"/>
3460
+ </xsl:otherwise>
3461
+ </xsl:choose>
3462
+ </xsl:variable>
3463
+ <xsl:variable name="sLowerCaseHeight">
3464
+ <xsl:choose>
3465
+ <xsl:when test="$ndCur/mml:mpadded/@height">
3466
+ <xsl:value-of select="translate($ndCur/mml:mpadded/@height, $StrUCAlphabet, $StrLCAlphabet)"/>
3467
+ </xsl:when>
3468
+ <xsl:otherwise>
3469
+ <xsl:value-of select="translate($ndCur/mml:mpadded/@mml:height, $StrUCAlphabet, $StrLCAlphabet)"/>
3470
+ </xsl:otherwise>
3471
+ </xsl:choose>
3472
+ </xsl:variable>
3473
+ <xsl:variable name="sLowerCaseDepth">
3474
+ <xsl:choose>
3475
+ <xsl:when test="$ndCur/mml:mpadded/@depth">
3476
+ <xsl:value-of select="translate($ndCur/mml:mpadded/@depth, $StrUCAlphabet, $StrLCAlphabet)"/>
3477
+ </xsl:when>
3478
+ <xsl:otherwise>
3479
+ <xsl:value-of select="translate($ndCur/mml:mpadded/@mml:depth, $StrUCAlphabet, $StrLCAlphabet)"/>
3480
+ </xsl:otherwise>
3481
+ </xsl:choose>
3482
+ </xsl:variable>
3483
+
3484
+ <xsl:variable name="fFullWidth">
3485
+ <xsl:call-template name="FFull">
3486
+ <xsl:with-param name="s" select="$sLowerCaseWidth"/>
3487
+ </xsl:call-template>
3488
+ </xsl:variable>
3489
+ <xsl:variable name="fFullHeight">
3490
+ <xsl:call-template name="FFull">
3491
+ <xsl:with-param name="s" select="$sLowerCaseHeight"/>
3492
+ </xsl:call-template>
3493
+ </xsl:variable>
3494
+ <xsl:variable name="fFullDepth">
3495
+ <xsl:call-template name="FFull">
3496
+ <xsl:with-param name="s" select="$sLowerCaseDepth"/>
3497
+ </xsl:call-template>
3498
+ </xsl:variable>
3499
+
3500
+ <xsl:call-template name="CreatePhantPropertiesCore">
3501
+ <xsl:with-param name="fShow" select="$fShow"/>
3502
+ <xsl:with-param name="fFullWidth" select="$fFullWidth"/>
3503
+ <xsl:with-param name="fFullHeight" select="$fFullHeight"/>
3504
+ <xsl:with-param name="fFullDepth" select="$fFullDepth"/>
3505
+ </xsl:call-template>
3506
+ </xsl:when>
3507
+ <xsl:otherwise>
3508
+ <xsl:call-template name="CreatePhantPropertiesCore">
3509
+ <xsl:with-param name="fShow" select="$fShow"/>
3510
+ </xsl:call-template>
3511
+ </xsl:otherwise>
3512
+ </xsl:choose>
3513
+ </xsl:template>
3514
+
3515
+ <xsl:template mode="mml" match="mml:mpadded">
3516
+ <xsl:choose>
3517
+ <xsl:when test="count(parent::mml:mphantom)=1 and count(preceding-sibling::*)=0 and count(following-sibling::*)=0">
3518
+ <!-- This mpadded is inside an mphantom that has already setup phantom attributes, therefore, just apply templates -->
3519
+ <xsl:apply-templates mode="mml"/>
3520
+ </xsl:when>
3521
+ <xsl:otherwise>
3522
+ <xsl:variable name="sLowerCaseWidth">
3523
+ <xsl:choose>
3524
+ <xsl:when test="@width">
3525
+ <xsl:value-of select="@width"/>
3526
+ </xsl:when>
3527
+ <xsl:otherwise>
3528
+ <xsl:value-of select="@mml:width"/>
3529
+ </xsl:otherwise>
3530
+ </xsl:choose>
3531
+ </xsl:variable>
3532
+ <xsl:variable name="sLowerCaseHeight">
3533
+ <xsl:choose>
3534
+ <xsl:when test="@height">
3535
+ <xsl:value-of select="@height"/>
3536
+ </xsl:when>
3537
+ <xsl:otherwise>
3538
+ <xsl:value-of select="@mml:height"/>
3539
+ </xsl:otherwise>
3540
+ </xsl:choose>
3541
+ </xsl:variable>
3542
+ <xsl:variable name="sLowerCaseDepth">
3543
+ <xsl:choose>
3544
+ <xsl:when test="@depth">
3545
+ <xsl:value-of select="@depth"/>
3546
+ </xsl:when>
3547
+ <xsl:otherwise>
3548
+ <xsl:value-of select="@mml:depth"/>
3549
+ </xsl:otherwise>
3550
+ </xsl:choose>
3551
+ </xsl:variable>
3552
+
3553
+ <xsl:variable name="fFullWidth">
3554
+ <xsl:call-template name="FFull">
3555
+ <xsl:with-param name="s" select="$sLowerCaseWidth"/>
3556
+ </xsl:call-template>
3557
+ </xsl:variable>
3558
+ <xsl:variable name="fFullHeight">
3559
+ <xsl:call-template name="FFull">
3560
+ <xsl:with-param name="s" select="$sLowerCaseHeight"/>
3561
+ </xsl:call-template>
3562
+ </xsl:variable>
3563
+ <xsl:variable name="fFullDepth">
3564
+ <xsl:call-template name="FFull">
3565
+ <xsl:with-param name="s" select="$sLowerCaseDepth"/>
3566
+ </xsl:call-template>
3567
+ </xsl:variable>
3568
+
3569
+ <phant>
3570
+ <xsl:call-template name="CreatePhantPropertiesCore">
3571
+ <xsl:with-param name="fShow" select="1"/>
3572
+ <xsl:with-param name="fFullWidth" select="$fFullWidth"/>
3573
+ <xsl:with-param name="fFullHeight" select="$fFullHeight"/>
3574
+ <xsl:with-param name="fFullDepth" select="$fFullDepth"/>
3575
+ </xsl:call-template>
3576
+ <e>
3577
+ <xsl:apply-templates mode="mml"/>
3578
+ </e>
3579
+ </phant>
3580
+ </xsl:otherwise>
3581
+ </xsl:choose>
3582
+ </xsl:template>
3583
+
3584
+ <xsl:template mode="mml" match="mml:mphantom">
3585
+ <phant>
3586
+ <xsl:call-template name="CreatePhantProperties">
3587
+ <xsl:with-param name="ndCur" select="."/>
3588
+ <xsl:with-param name="fShow" select="0"/>
3589
+ </xsl:call-template>
3590
+ <e>
3591
+ <xsl:apply-templates mode="mml"/>
3592
+ </e>
3593
+ </phant>
3594
+ </xsl:template>
3595
+
3596
+ <xsl:template name="isNaryOper">
3597
+ <xsl:param name="sNdCur"/>
3598
+ <xsl:value-of select="($sNdCur = '∫' or $sNdCur = '∬' or $sNdCur = '∭' or $sNdCur = '∮' or $sNdCur = '∯' or $sNdCur = '∰' or $sNdCur = '∲' or $sNdCur = '∳' or $sNdCur = '∱' or $sNdCur = '∩' or $sNdCur = '∪' or $sNdCur = '∏' or $sNdCur = '∐' or $sNdCur = '∑')"/>
3599
+ </xsl:template>
3600
+
3601
+
3602
+ <xsl:template name="isNary">
3603
+ <!-- ndCur is the element around the nAry operator -->
3604
+ <xsl:param name="ndCur"/>
3605
+ <xsl:variable name="sNdCur">
3606
+ <xsl:value-of select="normalize-space($ndCur)"/>
3607
+ </xsl:variable>
3608
+
3609
+ <xsl:variable name="fNaryOper">
3610
+ <xsl:call-template name="isNaryOper">
3611
+ <xsl:with-param name="sNdCur" select="$sNdCur"/>
3612
+ </xsl:call-template>
3613
+ </xsl:variable>
3614
+
3615
+ <!-- Narys shouldn't be MathML accents. -->
3616
+ <xsl:variable name="fUnder">
3617
+ <xsl:choose>
3618
+ <xsl:when test="$ndCur/parent::*[self::mml:munder]">1</xsl:when>
3619
+ <xsl:otherwise>0</xsl:otherwise>
3620
+ </xsl:choose>
3621
+ </xsl:variable>
3622
+
3623
+ <xsl:variable name="sLowerCaseAccent">
3624
+ <xsl:choose>
3625
+ <xsl:when test="$fUnder=1">
3626
+ <xsl:choose>
3627
+ <xsl:when test="$ndCur/parent::*[self::mml:munder]/@accentunder">
3628
+ <xsl:value-of select="translate($ndCur/parent::*[self::mml:munder]/@accentunder, $StrUCAlphabet, $StrLCAlphabet)"/>
3629
+ </xsl:when>
3630
+ <xsl:otherwise>
3631
+ <xsl:value-of select="translate($ndCur/parent::*[self::mml:munder]/@mml:accentunder, $StrUCAlphabet, $StrLCAlphabet)"/>
3632
+ </xsl:otherwise>
3633
+ </xsl:choose>
3634
+ </xsl:when>
3635
+ <xsl:otherwise>
3636
+ <xsl:choose>
3637
+ <xsl:when test="$ndCur/parent::*/@accent">
3638
+ <xsl:value-of select="translate($ndCur/parent::*/@accent, $StrUCAlphabet, $StrLCAlphabet)"/>
3639
+ </xsl:when>
3640
+ <xsl:otherwise>
3641
+ <xsl:value-of select="translate($ndCur/parent::*/@mml:accent, $StrUCAlphabet, $StrLCAlphabet)"/>
3642
+ </xsl:otherwise>
3643
+ </xsl:choose>
3644
+ </xsl:otherwise>
3645
+ </xsl:choose>
3646
+ </xsl:variable>
3647
+
3648
+ <xsl:variable name="fAccent">
3649
+ <xsl:choose>
3650
+ <xsl:when test="$sLowerCaseAccent='true'">1</xsl:when>
3651
+ <xsl:otherwise>0</xsl:otherwise>
3652
+ </xsl:choose>
3653
+ </xsl:variable>
3654
+
3655
+ <xsl:choose>
3656
+ <!-- This ndCur is in fact part of an nAry if
3657
+
3658
+ 1) The last descendant of ndCur (which could be ndCur itself) is an operator.
3659
+ 2) Along that chain of descendants we only encounter mml:mo, mml:mstyle, and mml:mrow elements.
3660
+ 3) the operator in mml:mo is a valid nAry operator
3661
+ 4) The nAry is not accented.
3662
+ -->
3663
+ <xsl:when test="$fNaryOper = 'true' and $fAccent=0 and $ndCur/descendant-or-self::*[last()]/self::mml:mo and not($ndCur/descendant-or-self::*[not(self::mml:mo or self::mml:mstyle or self::mml:mrow)])">
3664
+ <xsl:value-of select="true()"/>
3665
+ </xsl:when>
3666
+ <xsl:otherwise>
3667
+ <xsl:value-of select="false()"/>
3668
+ </xsl:otherwise>
3669
+ </xsl:choose>
3670
+ </xsl:template>
3671
+
3672
+ <xsl:template name="CreateNaryProp">
3673
+ <xsl:param name="chr"/>
3674
+ <xsl:param name="sMathmlType"/>
3675
+ <naryPr>
3676
+ <chr>
3677
+ <xsl:attribute name="m:val">
3678
+ <xsl:value-of select="$chr"/>
3679
+ </xsl:attribute>
3680
+ </chr>
3681
+ <limLoc>
3682
+ <xsl:attribute name="m:val">
3683
+ <xsl:choose>
3684
+ <xsl:when test="$sMathmlType='munder' or $sMathmlType='mover' or $sMathmlType='munderover'">
3685
+ <xsl:text>undOvr</xsl:text>
3686
+ </xsl:when>
3687
+ <xsl:when test="$sMathmlType='msub' or $sMathmlType='msup' or $sMathmlType='msubsup'">
3688
+ <xsl:text>subSup</xsl:text>
3689
+ </xsl:when>
3690
+ </xsl:choose>
3691
+ </xsl:attribute>
3692
+ </limLoc>
3693
+ <grow>
3694
+ <xsl:attribute name="m:val">
3695
+ <xsl:value-of select="'on'"/>
3696
+ </xsl:attribute>
3697
+ </grow>
3698
+ <subHide>
3699
+ <xsl:attribute name="m:val">
3700
+ <xsl:choose>
3701
+ <xsl:when test="$sMathmlType='mover' or $sMathmlType='msup'">
3702
+ <xsl:text>on</xsl:text>
3703
+ </xsl:when>
3704
+ <xsl:otherwise>
3705
+ <xsl:text>off</xsl:text>
3706
+ </xsl:otherwise>
3707
+ </xsl:choose>
3708
+ </xsl:attribute>
3709
+ </subHide>
3710
+ <supHide>
3711
+ <xsl:attribute name="m:val">
3712
+ <xsl:choose>
3713
+ <xsl:when test="$sMathmlType='munder' or $sMathmlType='msub'">
3714
+ <xsl:text>on</xsl:text>
3715
+ </xsl:when>
3716
+ <xsl:otherwise>
3717
+ <xsl:text>off</xsl:text>
3718
+ </xsl:otherwise>
3719
+ </xsl:choose>
3720
+ </xsl:attribute>
3721
+ </supHide>
3722
+ </naryPr>
3723
+ </xsl:template>
3724
+
3725
+ <xsl:template name="mathrRpHook"/>
3726
+ </xsl:stylesheet>