html2doc 0.8.2 → 0.8.3

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