2 <!DOCTYPE xsl:stylesheet
4 <!ENTITY % mmlalias PUBLIC "MathML alias" "ent/mmlalias.ent"> %mmlalias;
5 <!ENTITY % mmlextra PUBLIC "MathML extra" "ent/mmlextra.ent"> %mmlextra;
7 <!--#############################################################################
8 |- #############################################################################
10 | PURPOSE: MathML presentation markup.
11 | Note: these elements are not part of the DocBook DTD. I have extended
12 | the docbook DTD in order to support this tags, so that's why I have these
15 | MathML namespace used -> mml
16 + ############################################################################## -->
18 <xsl:stylesheet version='1.0'
19 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
20 xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns="http://www.w3.org/1998/Math/MathML">
22 <xsl:template match="mml:mrow">
23 <xsl:text>{</xsl:text> <xsl:apply-templates/> <xsl:text>}</xsl:text>
26 <xsl:variable name="latex.entities.xml" select="document('latex.entities.xml')"/>
30 <!-- Math Identifier -->
31 <xsl:template match="mml:mi">
32 <xsl:variable name="fontstyle" select="@fontstyle"/>
33 <xsl:variable name="identifier" select="normalize-space(.)"/>
34 <xsl:variable name="equivalent">
35 <xsl:if test="string-length($identifier)=1">
36 <xsl:value-of select="$latex.entities.xml/latex/character[@entity=$identifier]"/>
40 <xsl:when test="$identifier='ⅇ'">
41 <xsl:text>\textrm{e}</xsl:text>
43 <xsl:when test="$identifier='ⅈ'">
44 <xsl:text>\textrm{i}</xsl:text>
46 <xsl:when test="$identifier='∞'"><!--/infty infinity -->
47 <xsl:text>\infty</xsl:text>
49 <!-- currently tries to map single-character identifiers only -->
50 <xsl:when test="$equivalent!=''">
51 <xsl:text>{</xsl:text>
52 <xsl:copy-of select="$equivalent"/>
53 <xsl:text>}</xsl:text>
56 <xsl:if test="$fontstyle='normal' or string-length($identifier)>1">
57 <xsl:text>\textrm</xsl:text>
59 <xsl:text>{</xsl:text>
60 <xsl:copy-of select="$identifier"/>
61 <xsl:text>}</xsl:text>
67 <xsl:template match="mml:mn">
68 <xsl:copy-of select="normalize-space(.)"/>
72 <xsl:template match="mml:mphantom">
73 <xsl:apply-templates/>
76 <!-- Empty unless $character is a single character -->
77 <xsl:template name="generate.equivalent">
78 <xsl:param name="arguments" select="0"/>
79 <xsl:param name="character"/>
80 <xsl:if test="string-length($character)=1">
82 <xsl:when test="$arguments>0">
83 <xsl:value-of select="$latex.entities.xml/latex/character[@entity=$character and @arguments=$arguments]"/>
86 <xsl:value-of select="$latex.entities.xml/latex/character[@entity=$character and @arguments='']"/>
92 <!-- Math Operator -->
93 <xsl:template match="mml:mo">
94 <xsl:variable name="operator" select="normalize-space(.)"/>
95 <xsl:variable name="equivalent">
96 <xsl:call-template name="generate.equivalent">
97 <xsl:with-param name="character" select="$operator"/>
101 <xsl:when test="$operator='⁡'">
102 <xsl:text></xsl:text>
104 <xsl:when test="$operator='⁣'">
105 <xsl:text>\thinspace</xsl:text>
107 <xsl:when test="$operator='⁢'">
108 <xsl:text>\thinspace</xsl:text>
110 <xsl:when test="$operator='∫'">
111 <xsl:text>\int</xsl:text>
113 <xsl:when test="$operator='∏'">
114 <xsl:text>\prod</xsl:text>
116 <xsl:when test="$operator='∑'">
117 <xsl:text>\sum</xsl:text>
119 <xsl:when test="$operator='^'">
120 <xsl:text>\sphat</xsl:text>
122 <xsl:when test="$operator='→'">
123 <xsl:text>\longrightarrow</xsl:text>
125 <xsl:when test="$operator='∈'">
126 <xsl:text>\in</xsl:text>
128 <xsl:when test="$operator='∣'">
129 <xsl:text>|</xsl:text>
131 <xsl:when test="$operator='ⅆ'">
132 <xsl:text>\textrm{d}</xsl:text>
134 <xsl:when test="$operator='('">
135 <xsl:text> {\left( </xsl:text>
137 <xsl:when test="$operator=')'">
138 <xsl:text> \right)} </xsl:text>
140 <xsl:when test="$operator='{'">
141 <xsl:text> {\left\{ </xsl:text>
143 <xsl:when test="$operator='}'">
144 <xsl:text> \right\}} </xsl:text>
146 <xsl:when test="$operator='['">
147 <xsl:text> {\left[ </xsl:text>
149 <xsl:when test="$operator=']'">
150 <xsl:text> \right]} </xsl:text>
152 <xsl:when test="$operator='max'">
153 <xsl:text> \max </xsl:text>
155 <xsl:when test="$operator='min'">
156 <xsl:text> \min </xsl:text>
158 <xsl:when test="$operator='+' or $operator='-' or $operator='/' or $operator='*'">
159 <xsl:value-of select="$operator"/>
161 <xsl:when test="$equivalent">
162 <xsl:value-of select="$equivalent"/>
165 <xsl:text>\operatorname{</xsl:text>
166 <xsl:value-of select="$operator" />
167 <xsl:text>}</xsl:text>
173 <xsl:template match="mml:ms">
174 <xsl:text>\textrm{</xsl:text>
175 <xsl:copy-of select="normalize-space(.)" />
176 <xsl:text>}</xsl:text>
180 <xsl:template match="mml:mtext">
181 <xsl:message>RCAS mtext, <xsl:copy-of select="."/> </xsl:message>
182 <xsl:text>\textrm{</xsl:text>
183 <xsl:copy-of select="." />
184 <xsl:text>}</xsl:text>
188 <xsl:template match="mml:mspace">
189 <xsl:if test="@width!='' and not(contains(@width,'%'))">
190 <xsl:text>\textrm{\hspace{</xsl:text><!-- kludge! -->
191 <xsl:value-of select="@width"/>
192 <xsl:text>}}</xsl:text>
194 <xsl:if test="@height!='' or @depth!=''">
195 <xsl:message>Warning: mspace support does not include height or depth.</xsl:message>
203 <xsl:template match="mml:msup">
204 <xsl:apply-templates select="*[1]"/>
205 <xsl:text>^{</xsl:text><xsl:apply-templates select="*[2]"/><xsl:text>}</xsl:text>
208 <xsl:template match="mml:msub">
209 <xsl:apply-templates select="*[1]"/>
210 <xsl:text>_{</xsl:text><xsl:apply-templates select="*[2]"/><xsl:text>}</xsl:text>
213 <xsl:template match="mml:msubsup">
215 <xsl:when test="name(*[1])='mo'">
216 <xsl:apply-templates select="*[1]"/>
218 <xsl:text>_{</xsl:text><xsl:apply-templates select="*[2]"/><xsl:text>}</xsl:text>
220 <xsl:text>^{</xsl:text><xsl:apply-templates select="*[3]"/><xsl:text>}</xsl:text>
224 <xsl:text>{</xsl:text><xsl:apply-templates select="*[1]"/><xsl:text>}</xsl:text>
226 <xsl:text>_{</xsl:text><xsl:apply-templates select="*[2]"/><xsl:text>}</xsl:text>
228 <xsl:text>^{</xsl:text><xsl:apply-templates select="*[3]"/><xsl:text>}</xsl:text>
233 <xsl:template match="mml:mmultiscripts">
236 <xsl:template match="mml:munder">
239 <xsl:when test="*[2] = ̲">
240 <xsl:text>\underline{</xsl:text><xsl:apply-templates select="*[1]"/><xsl:text>}</xsl:text>
242 <xsl:when test="normalize-space(*[2]) = ︸">
243 <xsl:text>\underbrace{</xsl:text><xsl:apply-templates select="*[1]"/><xsl:text>}</xsl:text>
245 <xsl:when test="normalize-space(*[2]) = ⎵">
246 <xsl:text>\underbrace{</xsl:text><xsl:apply-templates select="*[1]"/><xsl:text>}</xsl:text>
249 <xsl:text>\underset{</xsl:text>
250 <xsl:apply-templates select="*[2]"/>
251 <xsl:text>}{</xsl:text>
252 <xsl:apply-templates select="*[1]"/>
253 <xsl:text>}</xsl:text>
255 <xsl:text>{</xsl:text>
256 <xsl:apply-templates select="*[1]"/>
257 <xsl:text>_{</xsl:text>
258 <xsl:apply-templates select="*[2]"/>
259 <xsl:text>}}</xsl:text>
265 <xsl:template match="mml:mover">
267 <xsl:when test="normalize-space(*[2]) = ¯">
268 <xsl:text>\overline{</xsl:text><xsl:apply-templates select="*[1]"/><xsl:text>}</xsl:text>
270 <xsl:when test="normalize-space(*[2]) = ︷">
271 <xsl:text>\overbrace{</xsl:text><xsl:apply-templates select="*[1]"/><xsl:text>}</xsl:text>
273 <xsl:when test="normalize-space(*[2]) = ︵">
274 <xsl:text>\widehat{</xsl:text><xsl:apply-templates select="*[1]"/><xsl:text>}</xsl:text>
276 <xsl:when test="normalize-space(*[2]) = ⎴">
277 <xsl:text>\widehat{</xsl:text><xsl:apply-templates select="*[1]"/><xsl:text>}</xsl:text>
283 <xsl:when test="@accent='true' or ( local-name(*[2])='mo' and not(@accent='false'))">
284 <xsl:variable name="equivalent">
285 <xsl:call-template name="generate.equivalent">
286 <xsl:with-param name="arguments" select="1"/>
287 <xsl:with-param name="character" select="normalize-space(*[2])"/>
291 <xsl:when test="$equivalent!=''">
292 <xsl:text>{</xsl:text>
293 <xsl:value-of select="$equivalent"/>
294 <xsl:text>{</xsl:text>
295 <xsl:apply-templates select="*[1]"/>
296 <xsl:text>}}</xsl:text>
299 <xsl:text>{</xsl:text>
300 <xsl:apply-templates select="*[1]"/>
301 <xsl:text>^{</xsl:text>
302 <xsl:apply-templates select="*[2]"/>
303 <xsl:text>}}</xsl:text>
308 <xsl:text>{</xsl:text>
309 <xsl:apply-templates select="*[1]"/>
310 <xsl:text>^{</xsl:text>
311 <xsl:apply-templates select="*[2]"/>
312 <xsl:text>}}</xsl:text>
319 <!-- Math UnderOver -->
320 <xsl:template match="mml:munderover">
321 <xsl:text>{</xsl:text>
322 <xsl:apply-templates select="*[1]"/>
323 <xsl:text>_{</xsl:text>
324 <xsl:apply-templates select="*[2]"/>
325 <xsl:text>}</xsl:text>
326 <xsl:text>^{</xsl:text>
327 <xsl:apply-templates select="*[3]"/>
328 <xsl:text>}}</xsl:text>
330 <xsl:text>\overset{</xsl:text>
331 <xsl:apply-templates select="*[3]"/>
332 <xsl:text>}{\underset{</xsl:text>
333 <xsl:apply-templates select="*[2]"/>
334 <xsl:text>}{</xsl:text>
335 <xsl:apply-templates select="*[1]"/>
336 <xsl:text>}}</xsl:text>
343 <xsl:template match="mml:mfenced">
344 <!-- get open,close, separators att -->
346 <xsl:when test="@open='('">
347 <xsl:text> {\left( </xsl:text>
349 <xsl:when test="@open='{'">
350 <xsl:text> {\left\{ </xsl:text>
352 <xsl:when test="@open='['">
353 <xsl:text> {\left[\, </xsl:text>
356 <xsl:text> {\left( </xsl:text>
359 <xsl:apply-templates select="*[1]"/>
361 <xsl:when test="@close=')'">
362 <xsl:text> \right)} </xsl:text>
364 <xsl:when test="@close='}'">
365 <xsl:text> \right\}} </xsl:text>
367 <xsl:when test="@close=']'">
368 <xsl:text> \,\right]} </xsl:text>
371 <xsl:text> \right)} </xsl:text>
379 <xsl:template match="mml:mfrac">
381 <xsl:when test="@linethickness">
383 <xsl:when test="@linethickness='thin'">
384 <xsl:text> \frac[1pt]{ </xsl:text>
386 <xsl:when test="@linethickness='medium'">
387 <xsl:text> \frac[1.1pt]{ </xsl:text>
389 <xsl:when test="@linethickness='thick'">
390 <xsl:text> \frac[1.2pt]{ </xsl:text>
393 <xsl:text> \frac[</xsl:text><xsl:value-of select="@linethickness"/><xsl:text>]{ </xsl:text>
398 <xsl:text> \frac{ </xsl:text>
401 <!-- <xsl:value-of select="*[1]"/> -->
402 <xsl:apply-templates select="*[1]"/>
403 <xsl:text> }{ </xsl:text>
404 <!-- <xsl:value-of select="*[2]"/> -->
405 <xsl:apply-templates select="*[2]"/>
406 <xsl:text> }</xsl:text>
411 <xsl:template match="mml:msqrt">
412 <xsl:text> \sqrt{ </xsl:text>
413 <xsl:apply-templates/>
414 <xsl:text> }</xsl:text>
419 <xsl:template match="mml:mroot">
420 <xsl:text> \sqrt[</xsl:text><xsl:apply-templates select="*[1]"/><xsl:text>]{</xsl:text>
421 <xsl:apply-templates select="*[2]"/><xsl:text> }</xsl:text>
426 <xsl:template name="mtable.format.tabular">
427 <xsl:param name="cols" select="1"/>
428 <xsl:param name="i" select="1"/>
430 <!-- Out of the recursive iteration -->
431 <xsl:when test="$i > $cols"></xsl:when>
432 <!-- There are still columns to count -->
434 <xsl:text>c</xsl:text>
435 <!-- Recursive for next column -->
436 <xsl:call-template name="mtable.format.tabular">
437 <xsl:with-param name="i" select="$i+1"/>
438 <xsl:with-param name="cols" select="$cols"/>
445 <xsl:template match="mml:mtable">
446 <xsl:variable name="rows" select="mml:mtr"/>
447 \begin{array}{<xsl:text></xsl:text>
448 <xsl:call-template name="mtable.format.tabular"><xsl:with-param name="cols" select="count($rows)"/></xsl:call-template>
449 <xsl:text>}\hline </xsl:text>
450 <xsl:apply-templates/>
451 <xsl:text>\end{array} </xsl:text>
454 <xsl:template match="mml:mtr">
455 <!-- Row starts here -->
456 <xsl:apply-templates/>
457 <!-- End Row here -->
460 <xsl:template match="mml:mtd">
461 <xsl:apply-templates/><xsl:text> & </xsl:text>
464 <xsl:template match="mml:mtd[position()=last()]">
465 <xsl:apply-templates/>\\ \hline
468 <xsl:template match="mml:mtd[position()=last()]">
469 <xsl:apply-templates/>\\ \hline
472 <xsl:template match="mml:mphantom">
473 <xsl:apply-templates mode="phantom"/>
476 <xsl:template match="mml:mi" mode="phantom">
477 <xsl:variable name="fontstyle" select="@fontstyle"/>
478 <xsl:variable name="identifier" select="normalize-space(.)"/>
480 <xsl:when test="$identifier='ⅇ'">
481 <xsl:text>\textrm{e}</xsl:text>
483 <xsl:when test="$identifier='ⅈ'">
484 <xsl:text>\textrm{i}</xsl:text>
487 <xsl:text>\textrm{</xsl:text> <xsl:copy-of select="$identifier"/> <xsl:text>}</xsl:text>