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 | $Id: mathml.presentation.mod.xsl,v 1.4 2004/01/18 10:39:50 j-devenish Exp $
9 |- #############################################################################
10 | $Author: j-devenish $
12 | PURPOSE: MathML presentation markup.
13 | Note: these elements are not part of the DocBook DTD. I have extended
14 | the docbook DTD in order to support this tags, so that's why I have these
17 | MathML namespace used -> mml
18 + ############################################################################## -->
20 <xsl:stylesheet version='1.0'
21 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
22 xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns="http://www.w3.org/1998/Math/MathML">
24 <xsl:template match="mml:mrow">
25 <xsl:text>{</xsl:text> <xsl:apply-templates/> <xsl:text>}</xsl:text>
28 <xsl:variable name="latex.entities.xml" select="document('latex.entities.xml')"/>
32 <!-- Math Identifier -->
33 <xsl:template match="mml:mi">
34 <xsl:variable name="fontstyle" select="@fontstyle"/>
35 <xsl:variable name="identifier" select="normalize-space(.)"/>
36 <xsl:variable name="equivalent">
37 <xsl:if test="string-length($identifier)=1">
38 <xsl:value-of select="$latex.entities.xml/latex/character[@entity=$identifier]"/>
42 <xsl:when test="$identifier='ⅇ'">
43 <xsl:text>\textrm{e}</xsl:text>
45 <xsl:when test="$identifier='ⅈ'">
46 <xsl:text>\textrm{i}</xsl:text>
48 <xsl:when test="$identifier='∞'"><!--/infty infinity -->
49 <xsl:text>\infty</xsl:text>
51 <!-- currently tries to map single-character identifiers only -->
52 <xsl:when test="$equivalent!=''">
53 <xsl:text>{</xsl:text>
54 <xsl:copy-of select="$equivalent"/>
55 <xsl:text>}</xsl:text>
58 <xsl:if test="$fontstyle='normal' or string-length($identifier)>1">
59 <xsl:text>\textrm</xsl:text>
61 <xsl:text>{</xsl:text>
62 <xsl:copy-of select="$identifier"/>
63 <xsl:text>}</xsl:text>
69 <xsl:template match="mml:mn">
70 <xsl:copy-of select="normalize-space(.)"/>
74 <xsl:template match="mml:mphantom">
75 <xsl:apply-templates/>
78 <!-- Empty unless $character is a single character -->
79 <xsl:template name="generate.equivalent">
80 <xsl:param name="arguments" select="0"/>
81 <xsl:param name="character"/>
82 <xsl:if test="string-length($character)=1">
84 <xsl:when test="$arguments>0">
85 <xsl:value-of select="$latex.entities.xml/latex/character[@entity=$character and @arguments=$arguments]"/>
88 <xsl:value-of select="$latex.entities.xml/latex/character[@entity=$character and @arguments='']"/>
94 <!-- Math Operator -->
95 <xsl:template match="mml:mo">
96 <xsl:variable name="operator" select="normalize-space(.)"/>
97 <xsl:variable name="equivalent">
98 <xsl:call-template name="generate.equivalent">
99 <xsl:with-param name="character" select="$operator"/>
103 <xsl:when test="$operator='⁡'">
104 <xsl:text></xsl:text>
106 <xsl:when test="$operator='⁣'">
107 <xsl:text>\thinspace</xsl:text>
109 <xsl:when test="$operator='⁢'">
110 <xsl:text>\thinspace</xsl:text>
112 <xsl:when test="$operator='∫'">
113 <xsl:text>\int</xsl:text>
115 <xsl:when test="$operator='∏'">
116 <xsl:text>\prod</xsl:text>
118 <xsl:when test="$operator='∑'">
119 <xsl:text>\sum</xsl:text>
121 <xsl:when test="$operator='^'">
122 <xsl:text>\sphat</xsl:text>
124 <xsl:when test="$operator='→'">
125 <xsl:text>\longrightarrow</xsl:text>
127 <xsl:when test="$operator='∈'">
128 <xsl:text>\in</xsl:text>
130 <xsl:when test="$operator='∣'">
131 <xsl:text>|</xsl:text>
133 <xsl:when test="$operator='ⅆ'">
134 <xsl:text>\textrm{d}</xsl:text>
136 <xsl:when test="$operator='('">
137 <xsl:text> {\left( </xsl:text>
139 <xsl:when test="$operator=')'">
140 <xsl:text> \right)} </xsl:text>
142 <xsl:when test="$operator='{'">
143 <xsl:text> {\left\{ </xsl:text>
145 <xsl:when test="$operator='}'">
146 <xsl:text> \right\}} </xsl:text>
148 <xsl:when test="$operator='['">
149 <xsl:text> {\left[ </xsl:text>
151 <xsl:when test="$operator=']'">
152 <xsl:text> \right]} </xsl:text>
154 <xsl:when test="$operator='max'">
155 <xsl:text> \max </xsl:text>
157 <xsl:when test="$operator='min'">
158 <xsl:text> \min </xsl:text>
160 <xsl:when test="$operator='+' or $operator='-' or $operator='/' or $operator='*'">
161 <xsl:value-of select="$operator"/>
163 <xsl:when test="$equivalent">
164 <xsl:value-of select="$equivalent"/>
167 <xsl:text>\operatorname{</xsl:text>
168 <xsl:value-of select="$operator" />
169 <xsl:text>}</xsl:text>
175 <xsl:template match="mml:ms">
176 <xsl:text>\textrm{</xsl:text>
177 <xsl:copy-of select="normalize-space(.)" />
178 <xsl:text>}</xsl:text>
182 <xsl:template match="mml:mtext">
183 <xsl:message>RCAS mtext, <xsl:copy-of select="."/> </xsl:message>
184 <xsl:text>\textrm{</xsl:text>
185 <xsl:copy-of select="." />
186 <xsl:text>}</xsl:text>
190 <xsl:template match="mml:mspace">
191 <xsl:if test="@width!='' and not(contains(@width,'%'))">
192 <xsl:text>\textrm{\hspace{</xsl:text><!-- kludge! -->
193 <xsl:value-of select="@width"/>
194 <xsl:text>}}</xsl:text>
196 <xsl:if test="@height!='' or @depth!=''">
197 <xsl:message>Warning: mspace support does not include height or depth.</xsl:message>
205 <xsl:template match="mml:msup">
206 <xsl:apply-templates select="*[1]"/>
207 <xsl:text>^{</xsl:text><xsl:apply-templates select="*[2]"/><xsl:text>}</xsl:text>
210 <xsl:template match="mml:msub">
211 <xsl:apply-templates select="*[1]"/>
212 <xsl:text>_{</xsl:text><xsl:apply-templates select="*[2]"/><xsl:text>}</xsl:text>
215 <xsl:template match="mml:msubsup">
217 <xsl:when test="name(*[1])='mo'">
218 <xsl:apply-templates select="*[1]"/>
220 <xsl:text>_{</xsl:text><xsl:apply-templates select="*[2]"/><xsl:text>}</xsl:text>
222 <xsl:text>^{</xsl:text><xsl:apply-templates select="*[3]"/><xsl:text>}</xsl:text>
226 <xsl:text>{</xsl:text><xsl:apply-templates select="*[1]"/><xsl:text>}</xsl:text>
228 <xsl:text>_{</xsl:text><xsl:apply-templates select="*[2]"/><xsl:text>}</xsl:text>
230 <xsl:text>^{</xsl:text><xsl:apply-templates select="*[3]"/><xsl:text>}</xsl:text>
235 <xsl:template match="mml:mmultiscripts">
238 <xsl:template match="mml:munder">
241 <xsl:when test="*[2] = ̲">
242 <xsl:text>\underline{</xsl:text><xsl:apply-templates select="*[1]"/><xsl:text>}</xsl:text>
244 <xsl:when test="normalize-space(*[2]) = ︸">
245 <xsl:text>\underbrace{</xsl:text><xsl:apply-templates select="*[1]"/><xsl:text>}</xsl:text>
247 <xsl:when test="normalize-space(*[2]) = ⎵">
248 <xsl:text>\underbrace{</xsl:text><xsl:apply-templates select="*[1]"/><xsl:text>}</xsl:text>
251 <xsl:text>\underset{</xsl:text>
252 <xsl:apply-templates select="*[2]"/>
253 <xsl:text>}{</xsl:text>
254 <xsl:apply-templates select="*[1]"/>
255 <xsl:text>}</xsl:text>
257 <xsl:text>{</xsl:text>
258 <xsl:apply-templates select="*[1]"/>
259 <xsl:text>_{</xsl:text>
260 <xsl:apply-templates select="*[2]"/>
261 <xsl:text>}}</xsl:text>
267 <xsl:template match="mml:mover">
269 <xsl:when test="normalize-space(*[2]) = ¯">
270 <xsl:text>\overline{</xsl:text><xsl:apply-templates select="*[1]"/><xsl:text>}</xsl:text>
272 <xsl:when test="normalize-space(*[2]) = ︷">
273 <xsl:text>\overbrace{</xsl:text><xsl:apply-templates select="*[1]"/><xsl:text>}</xsl:text>
275 <xsl:when test="normalize-space(*[2]) = ︵">
276 <xsl:text>\widehat{</xsl:text><xsl:apply-templates select="*[1]"/><xsl:text>}</xsl:text>
278 <xsl:when test="normalize-space(*[2]) = ⎴">
279 <xsl:text>\widehat{</xsl:text><xsl:apply-templates select="*[1]"/><xsl:text>}</xsl:text>
285 <xsl:when test="@accent='true' or ( local-name(*[2])='mo' and not(@accent='false'))">
286 <xsl:variable name="equivalent">
287 <xsl:call-template name="generate.equivalent">
288 <xsl:with-param name="arguments" select="1"/>
289 <xsl:with-param name="character" select="normalize-space(*[2])"/>
293 <xsl:when test="$equivalent!=''">
294 <xsl:text>{</xsl:text>
295 <xsl:value-of select="$equivalent"/>
296 <xsl:text>{</xsl:text>
297 <xsl:apply-templates select="*[1]"/>
298 <xsl:text>}}</xsl:text>
301 <xsl:text>{</xsl:text>
302 <xsl:apply-templates select="*[1]"/>
303 <xsl:text>^{</xsl:text>
304 <xsl:apply-templates select="*[2]"/>
305 <xsl:text>}}</xsl:text>
310 <xsl:text>{</xsl:text>
311 <xsl:apply-templates select="*[1]"/>
312 <xsl:text>^{</xsl:text>
313 <xsl:apply-templates select="*[2]"/>
314 <xsl:text>}}</xsl:text>
321 <!-- Math UnderOver -->
322 <xsl:template match="mml:munderover">
323 <xsl:text>{</xsl:text>
324 <xsl:apply-templates select="*[1]"/>
325 <xsl:text>_{</xsl:text>
326 <xsl:apply-templates select="*[2]"/>
327 <xsl:text>}</xsl:text>
328 <xsl:text>^{</xsl:text>
329 <xsl:apply-templates select="*[3]"/>
330 <xsl:text>}}</xsl:text>
332 <xsl:text>\overset{</xsl:text>
333 <xsl:apply-templates select="*[3]"/>
334 <xsl:text>}{\underset{</xsl:text>
335 <xsl:apply-templates select="*[2]"/>
336 <xsl:text>}{</xsl:text>
337 <xsl:apply-templates select="*[1]"/>
338 <xsl:text>}}</xsl:text>
345 <xsl:template match="mml:mfenced">
346 <!-- get open,close, separators att -->
348 <xsl:when test="@open='('">
349 <xsl:text> {\left( </xsl:text>
351 <xsl:when test="@open='{'">
352 <xsl:text> {\left\{ </xsl:text>
354 <xsl:when test="@open='['">
355 <xsl:text> {\left[\, </xsl:text>
358 <xsl:text> {\left( </xsl:text>
361 <xsl:apply-templates select="*[1]"/>
363 <xsl:when test="@close=')'">
364 <xsl:text> \right)} </xsl:text>
366 <xsl:when test="@close='}'">
367 <xsl:text> \right\}} </xsl:text>
369 <xsl:when test="@close=']'">
370 <xsl:text> \,\right]} </xsl:text>
373 <xsl:text> \right)} </xsl:text>
381 <xsl:template match="mml:mfrac">
383 <xsl:when test="@linethickness">
385 <xsl:when test="@linethickness='thin'">
386 <xsl:text> \frac[1pt]{ </xsl:text>
388 <xsl:when test="@linethickness='medium'">
389 <xsl:text> \frac[1.1pt]{ </xsl:text>
391 <xsl:when test="@linethickness='thick'">
392 <xsl:text> \frac[1.2pt]{ </xsl:text>
395 <xsl:text> \frac[</xsl:text><xsl:value-of select="@linethickness"/><xsl:text>]{ </xsl:text>
400 <xsl:text> \frac{ </xsl:text>
403 <!-- <xsl:value-of select="*[1]"/> -->
404 <xsl:apply-templates select="*[1]"/>
405 <xsl:text> }{ </xsl:text>
406 <!-- <xsl:value-of select="*[2]"/> -->
407 <xsl:apply-templates select="*[2]"/>
408 <xsl:text> }</xsl:text>
413 <xsl:template match="mml:msqrt">
414 <xsl:text> \sqrt{ </xsl:text>
415 <xsl:apply-templates/>
416 <xsl:text> }</xsl:text>
421 <xsl:template match="mml:mroot">
422 <xsl:text> \sqrt[</xsl:text><xsl:apply-templates select="*[1]"/><xsl:text>]{</xsl:text>
423 <xsl:apply-templates select="*[2]"/><xsl:text> }</xsl:text>
428 <xsl:template name="mtable.format.tabular">
429 <xsl:param name="cols" select="1"/>
430 <xsl:param name="i" select="1"/>
432 <!-- Out of the recursive iteration -->
433 <xsl:when test="$i > $cols"></xsl:when>
434 <!-- There are still columns to count -->
436 <xsl:text>c</xsl:text>
437 <!-- Recursive for next column -->
438 <xsl:call-template name="mtable.format.tabular">
439 <xsl:with-param name="i" select="$i+1"/>
440 <xsl:with-param name="cols" select="$cols"/>
447 <xsl:template match="mml:mtable">
448 <xsl:variable name="rows" select="mml:mtr"/>
449 <xsl:text>\begin{array}{</xsl:text>
450 <xsl:call-template name="mtable.format.tabular"><xsl:with-param name="cols" select="count($rows)"/></xsl:call-template>
451 <xsl:text>} </xsl:text>
452 <xsl:apply-templates/>
453 <xsl:text>\end{array} </xsl:text>
456 <xsl:template match="mml:mtr">
457 <!-- Row starts here -->
458 <xsl:apply-templates/>
459 <!-- End Row here -->
462 <xsl:template match="mml:mtd">
463 <xsl:apply-templates/><xsl:text> & </xsl:text>
466 <xsl:template match="mml:mtd[position()=last()]">
467 <xsl:apply-templates/><xsl:text>\\ </xsl:text>
470 <xsl:template match="mml:mtd[position()=last()]">
471 <xsl:apply-templates/><xsl:text>\\ </xsl:text>
474 <xsl:template match="mml:mphantom">
475 <xsl:apply-templates mode="phantom"/>
478 <xsl:template match="mml:mi" mode="phantom">
479 <xsl:variable name="fontstyle" select="@fontstyle"/>
480 <xsl:variable name="identifier" select="normalize-space(.)"/>
482 <xsl:when test="$identifier='ⅇ'">
483 <xsl:text>\textrm{e}</xsl:text>
485 <xsl:when test="$identifier='ⅈ'">
486 <xsl:text>\textrm{i}</xsl:text>
489 <xsl:text>\textrm{</xsl:text> <xsl:copy-of select="$identifier"/> <xsl:text>}</xsl:text>