740 lines
21 KiB
XML
740 lines
21 KiB
XML
<?xml version="1.0" encoding="ISO-8859-1"?>
|
|
<!--
|
|
Handles calculation output in LaTeX format for styling by Mathjax
|
|
|
|
Copyright (C) 2016, 2017 R-T Specialty, LLC.
|
|
|
|
This file is part of TAME.
|
|
|
|
TAME is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see
|
|
<http://www.gnu.org/licenses/>.
|
|
-->
|
|
<xsl:stylesheet version="1.0"
|
|
xmlns="http://www.w3.org/1999/xhtml"
|
|
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
|
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
|
xmlns:lv="http://www.lovullo.com/rater"
|
|
xmlns:c="http://www.lovullo.com/calc"
|
|
xmlns:preproc="http://www.lovullo.com/rater/preproc">
|
|
|
|
|
|
<!--
|
|
Recursively apply any child equations and then do the same in calc-after mode
|
|
|
|
@return LaTeX equation
|
|
-->
|
|
<xsl:template match="c:*" mode="calc-recurse">
|
|
<xsl:apply-templates select="./c:*" />
|
|
|
|
<!-- invoke `after' templates, which allows inserting data for display after
|
|
the initial equation -->
|
|
<xsl:apply-templates select="./c:*" mode="calc-after" />
|
|
</xsl:template>
|
|
|
|
|
|
<!--
|
|
Style sum of values as a LaTeX equation
|
|
|
|
Note that this does not deal with the summation of a series; that's left to
|
|
the handling of the @of attribute.
|
|
|
|
@return LaTeX equation
|
|
-->
|
|
<xsl:template match="c:sum">
|
|
<xsl:apply-templates select="." mode="sum-body" />
|
|
</xsl:template>
|
|
|
|
<xsl:template match="c:sum" mode="sum-body">
|
|
<xsl:for-each select="./c:*">
|
|
<!-- get value to display -->
|
|
<xsl:variable name="display">
|
|
<xsl:apply-templates select="." />
|
|
</xsl:variable>
|
|
|
|
<!-- delimit with +s if not first; if we're adding a negative, omit the
|
|
addition symbol as well (unless we're displaying a product, since
|
|
multiplying by a negative would otherwise appear to be subtraction) -->
|
|
<xsl:if test="
|
|
( position() > 1 )
|
|
and (
|
|
not( substring( $display, 1, 1 ) = '-' )
|
|
or ( local-name() = 'product' )
|
|
)
|
|
">
|
|
|
|
<xsl:text> + </xsl:text>
|
|
</xsl:if>
|
|
|
|
<!-- the only reason we would have a sum within a sum (that doesn't use
|
|
sigma-notation) is for grouping -->
|
|
<xsl:if test="( local-name() = 'sum' ) and not( @of )">
|
|
<xsl:text>\left(</xsl:text>
|
|
</xsl:if>
|
|
|
|
<xsl:copy-of select="$display" />
|
|
|
|
<xsl:if test="( local-name() = 'sum' ) and not( @of )">
|
|
<xsl:text>\right)</xsl:text>
|
|
</xsl:if>
|
|
</xsl:for-each>
|
|
|
|
<!-- since we looped manually, we must also invoke `after' templates
|
|
manually -->
|
|
<xsl:apply-templates select="./c:*" mode="calc-after" />
|
|
</xsl:template>
|
|
|
|
|
|
<!--
|
|
Style summation of a set as a LaTeX equation
|
|
|
|
Note that @of deals witht summation of sets only (rather, using the index of a
|
|
set to sum over the provided calculation). See the other template(s) for
|
|
summing values without a set.
|
|
|
|
An index may optionally be provided via an @index attribute; otherwise, one
|
|
will be chosen for you. The index is used for the lower limit; the upper limit
|
|
is omitted. The child nodes are then used to generate the equation to be
|
|
applied by the summation.
|
|
|
|
If no child nodes are provided, then the summation is meant to imply that each
|
|
value in the set should be summed. Adding child nodes overrides this behavior.
|
|
|
|
@return LaTeX equation
|
|
-->
|
|
<xsl:template match="c:sum[@of]">
|
|
<xsl:variable name="of" select="@of" />
|
|
|
|
<!-- if no index is provided, simply use its symbol to indicate all values
|
|
within its domain -->
|
|
<xsl:variable name="index">
|
|
<xsl:choose>
|
|
<xsl:when test="@index">
|
|
<xsl:value-of select="preproc:tex-index( @index )" />
|
|
</xsl:when>
|
|
|
|
<xsl:otherwise>
|
|
<!-- TODO: Determine an index that is not in use -->
|
|
<xsl:text>k</xsl:text>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
|
|
<xsl:variable name="ref">
|
|
<xsl:value-of select="@of" />
|
|
</xsl:variable>
|
|
|
|
<!-- retrieve the symbol associated with this value (no index) -->
|
|
<xsl:variable name="symbol">
|
|
<xsl:call-template name="get-symbol">
|
|
<xsl:with-param name="name" select="$ref" />
|
|
<xsl:with-param name="search" select="/" />
|
|
</xsl:call-template>
|
|
</xsl:variable>
|
|
|
|
<!-- also retrieve the symbol without its index -->
|
|
|
|
<!-- if an index was provided, set the lower limit to 0 (we do this in a
|
|
separate variable so that we can display the symbol on its own elsewhere)
|
|
-->
|
|
<xsl:variable name="index-limit">
|
|
<xsl:value-of select="$index" />
|
|
|
|
<!-- we only need the explicit notation if we are summing more than the
|
|
set -->
|
|
<xsl:if test="./c:*">
|
|
<xsl:text>=0</xsl:text>
|
|
</xsl:if>
|
|
</xsl:variable>
|
|
|
|
<xsl:text>\sum \limits_{</xsl:text>
|
|
<xsl:value-of select="$index-limit" />
|
|
<xsl:text>}</xsl:text>
|
|
|
|
<!-- upper limit is only necessary for clarification if they have provided a
|
|
more complex expression; if we're only summing over a single set, then
|
|
the extra notation is unnecessary and will just clutter -->
|
|
<xsl:if test="./c:*">
|
|
<!-- the upper limit of the summation will be denoted by #S, where S is the
|
|
symbol for a given set -->
|
|
<xsl:text>^{\left|</xsl:text>
|
|
<xsl:copy-of select="$symbol" />
|
|
<xsl:text>\right|-1}</xsl:text>
|
|
</xsl:if>
|
|
|
|
<!-- if no children are provided, just sum @of -->
|
|
<xsl:if test="not(./c:*)">
|
|
<!-- output the symbol followed by its index, only if an index was provided
|
|
(and is therefore necessary) -->
|
|
<xsl:call-template name="get-symbol">
|
|
<xsl:with-param name="name" select="$ref" />
|
|
<xsl:with-param name="index-symbol" select="$index" />
|
|
<xsl:with-param name="search" select="/" />
|
|
</xsl:call-template>
|
|
</xsl:if>
|
|
|
|
<!-- output any additional expressions, if any -->
|
|
<xsl:apply-templates select="." mode="sum-body" />
|
|
</xsl:template>
|
|
|
|
|
|
<xsl:function name="preproc:tex-index" as="xs:string?">
|
|
<xsl:param name="index" as="xs:string?" />
|
|
|
|
<!-- TODO: there are potential display conflicts with the below
|
|
replacement -->
|
|
|
|
<!-- underscores are frequently used for internal names, but the display
|
|
is lousy, so just remove this. -->
|
|
<xsl:sequence select="if ( $index ) then
|
|
replace( $index, '_', '' )
|
|
else
|
|
()" />
|
|
</xsl:function>
|
|
|
|
|
|
<!--
|
|
Style product of values as a LaTeX equation
|
|
|
|
Note that this does not deal with the product of a series; that's left to
|
|
the handling of the @of attribute (TODO: @of not yet implemented for
|
|
products).
|
|
|
|
@return LaTeX equation
|
|
-->
|
|
<xsl:template match="c:product">
|
|
<xsl:variable name="enclose" select="
|
|
@dot='true'
|
|
and (
|
|
preceding-sibling::c:*
|
|
or following-sibling::c:*
|
|
)
|
|
" />
|
|
|
|
<xsl:if test="$enclose">
|
|
<xsl:text>(</xsl:text>
|
|
</xsl:if>
|
|
|
|
<xsl:for-each select="./c:*">
|
|
<!-- Function symbols can have multiple chars, so we'll need to add the
|
|
multiplication symbol. Adjacent constants should also be separated by a
|
|
dot, otherwise it'll look like one giant number. -->
|
|
<xsl:if test="
|
|
(
|
|
local-name() = 'apply'
|
|
or ../@dot = 'true'
|
|
or (
|
|
( local-name() = 'const' )
|
|
and ( local-name( preceding-sibling::*[1] ) = 'const' )
|
|
)
|
|
)
|
|
and ( position() > 1 )
|
|
">
|
|
<xsl:text> \,\cdot\, </xsl:text>
|
|
</xsl:if>
|
|
|
|
<!-- if precedence of this operation is lower, we will need to include
|
|
parenthesis -->
|
|
<!-- XXX: Relies on hard-coded precedence rules in multiple locations;
|
|
refactor! -->
|
|
<xsl:if test="
|
|
( local-name() = 'sum' )
|
|
or ( ( local-name() = 'product' ) and not( @of ) )
|
|
">
|
|
<xsl:text>\left(</xsl:text>
|
|
</xsl:if>
|
|
|
|
<xsl:apply-templates select="." />
|
|
|
|
<!-- close parenthesis -->
|
|
<xsl:if test="
|
|
( local-name() = 'sum' )
|
|
or ( ( local-name() = 'product' ) and not( @of ) )
|
|
">
|
|
<xsl:text>\right)</xsl:text>
|
|
</xsl:if>
|
|
</xsl:for-each>
|
|
|
|
<xsl:if test="$enclose">
|
|
<xsl:text>)</xsl:text>
|
|
</xsl:if>
|
|
|
|
<!-- since we looped manually, we must also invoke `after' templates
|
|
manually -->
|
|
<xsl:apply-templates select="./c:*" mode="calc-after" />
|
|
</xsl:template>
|
|
|
|
|
|
<!--
|
|
Style quotient of two values as a LaTeX equation
|
|
|
|
This is used to divide two values and will be styled as a fraction. The
|
|
numerator should be the first calculation node and the denominator the second;
|
|
there should be no additional nodes.
|
|
|
|
@return LaTeX equation
|
|
-->
|
|
<xsl:template match="c:quotient">
|
|
<!-- numerator (first child) -->
|
|
<xsl:text>\frac{</xsl:text>
|
|
<xsl:apply-templates select="./c:*[1]" />
|
|
|
|
<!-- denominator (second child) -->
|
|
<xsl:text>}{</xsl:text>
|
|
<xsl:apply-templates select="./c:*[2]" />
|
|
<xsl:text>}</xsl:text>
|
|
|
|
<!-- since we processed manually, we must also invoke `after' templates
|
|
manually -->
|
|
<xsl:apply-templates select="./c:*" mode="calc-after" />
|
|
</xsl:template>
|
|
|
|
|
|
<xsl:template match="c:let">
|
|
<!-- process the body of the let expression (the variables should have been
|
|
processed separately) -->
|
|
<xsl:apply-templates select="c:*" />
|
|
</xsl:template>
|
|
|
|
|
|
<!--
|
|
Style a value for display within a LaTeX equation
|
|
|
|
Forwards to calc-get-value template.
|
|
-->
|
|
<xsl:template match="c:value-of">
|
|
<xsl:apply-templates select="." mode="calc-get-value" />
|
|
</xsl:template>
|
|
|
|
|
|
<!--
|
|
Values from a c:let must have their names altered before looking up the symbol
|
|
-->
|
|
<xsl:template match="c:*[ @name=ancestor::c:let/c:values/c:value/@name ]" mode="calc-get-value">
|
|
<xsl:call-template name="calc-get-value">
|
|
<!-- :<let-name>:<our-name> -->
|
|
<xsl:with-param name="name" select="
|
|
concat( ':', ancestor::c:let[1]/@name, ':', @name )
|
|
" />
|
|
</xsl:call-template>
|
|
</xsl:template>
|
|
|
|
|
|
<!--
|
|
Style a value for display within a LaTeX equation
|
|
|
|
By default, the symbol for the given value (variable) will be rendered in
|
|
place of this node.
|
|
|
|
This element is not expected to have any children.
|
|
|
|
XXX: Refactor me; there are more clear and less convoluted ways to accomplish
|
|
this.
|
|
|
|
@return LaTeX equation
|
|
-->
|
|
<xsl:template name="calc-get-value" match="c:*" mode="calc-get-value">
|
|
<xsl:param name="name" select="@name" />
|
|
|
|
<xsl:variable name="index-symbol">
|
|
<xsl:if test="./c:index">
|
|
<xsl:for-each select="./c:index">
|
|
<!-- separate multiple indexes with commas -->
|
|
<xsl:if test="position() > 1">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:if>
|
|
|
|
<xsl:apply-templates select="./c:*[1]" />
|
|
</xsl:for-each>
|
|
</xsl:if>
|
|
</xsl:variable>
|
|
|
|
<xsl:variable name="sym" select="
|
|
/lv:*/preproc:symtable/preproc:sym[
|
|
@name=$name
|
|
]
|
|
" />
|
|
|
|
|
|
<xsl:variable name="value">
|
|
<xsl:choose>
|
|
<!-- for scalar constants that do not have a symbol, simply inline their
|
|
value (if they have a symbol, then it is assumed that their symbolic
|
|
meaning is more meaningful than its value) -->
|
|
<xsl:when test="
|
|
$sym[
|
|
@type='const'
|
|
and @dim='0'
|
|
and ( not( @text ) or @tex='' )
|
|
]
|
|
">
|
|
<xsl:value-of select="$sym/@value" />
|
|
</xsl:when>
|
|
|
|
<!-- local index (generated with @of) -->
|
|
<xsl:when test="ancestor::c:*[ @of and @index=$name ]">
|
|
<xsl:value-of select="$name" />
|
|
</xsl:when>
|
|
|
|
<xsl:otherwise>
|
|
<xsl:call-template name="get-symbol">
|
|
<xsl:with-param name="name" select="$name" />
|
|
<xsl:with-param name="index" select="preproc:tex-index( @index )" />
|
|
<xsl:with-param name="index-symbol" select="$index-symbol" />
|
|
</xsl:call-template>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:variable>
|
|
|
|
<xsl:copy-of select="$value" />
|
|
|
|
<!-- yes, a value still may have things to appear after it -->
|
|
<xsl:apply-templates select="./c:*" mode="calc-after" />
|
|
</xsl:template>
|
|
|
|
|
|
<!--
|
|
Style a constant value for use in a LaTeX equation
|
|
|
|
Constant values are not treated as variables; instead, their value (rather
|
|
than their symbol) is immediately rendered.
|
|
|
|
Use this only if the value itself makes more sense (and is more clear) than a
|
|
variable.
|
|
|
|
This element is not expected to have any children.
|
|
|
|
@return LaTeX equation
|
|
-->
|
|
<xsl:template match="c:const">
|
|
<!-- a constant value of 1 with Iverson's brackets is redundant -->
|
|
<xsl:if test="not( ( @value = '1' ) and ./c:when )">
|
|
<!-- display constant value -->
|
|
<xsl:value-of select="@value" />
|
|
</xsl:if>
|
|
|
|
<!-- a constant may still have things to appear after it -->
|
|
<xsl:apply-templates select="./c:*" mode="calc-after" />
|
|
</xsl:template>
|
|
|
|
|
|
<xsl:template match="c:ceil|c:floor">
|
|
<xsl:text>\left\l</xsl:text>
|
|
<xsl:value-of select="local-name()" />
|
|
<xsl:text> </xsl:text>
|
|
<xsl:apply-templates select="." mode="calc-recurse" />
|
|
<xsl:text>\right\r</xsl:text>
|
|
<xsl:value-of select="local-name()" />
|
|
</xsl:template>
|
|
|
|
|
|
<!--
|
|
Styles a function application for display in a LaTeX equation
|
|
|
|
Indicates a function application. A call to the function, with each of its
|
|
arguments in parenthesis, will be rendered.
|
|
|
|
@return LaTeX equation
|
|
-->
|
|
<xsl:template match="c:apply">
|
|
<xsl:variable name="self" select="." />
|
|
<xsl:variable name="name" select="@name" />
|
|
<xsl:variable name="fsym" select="//lv:function[@name=$name]/@sym" />
|
|
|
|
<xsl:call-template name="get-symbol">
|
|
<xsl:with-param name="name" select="@name" />
|
|
<xsl:with-param name="search" select="/" />
|
|
</xsl:call-template>
|
|
|
|
<!-- if a symbol is provided, then omit the parenthesis -->
|
|
<xsl:if test="not( $fsym )">
|
|
<xsl:text>\left(</xsl:text>
|
|
</xsl:if>
|
|
|
|
<!-- output the symbol associated with the value of each argument -->
|
|
<xsl:for-each select="./c:arg">
|
|
<!-- delimit params with a comma -->
|
|
<xsl:if test="position() > 1">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:if>
|
|
|
|
<xsl:variable name="valname" select="./c:*[1]/@name" />
|
|
|
|
<xsl:choose>
|
|
<!-- if this variable has been defined as an index, then simply output
|
|
it -->
|
|
<xsl:when test="ancestor::c:*[ @of and @index=$valname ]">
|
|
<xsl:value-of select="$valname" />
|
|
</xsl:when>
|
|
|
|
<!-- display the value of constants -->
|
|
<xsl:when test="local-name( ./c:*[1] ) = 'const'">
|
|
<xsl:value-of select="./c:*[1]/@value" />
|
|
</xsl:when>
|
|
|
|
<!-- otherwise, it's some other variable and we must look up its
|
|
symbol -->
|
|
<xsl:otherwise>
|
|
<xsl:apply-templates select="./c:*[1]" />
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
|
|
<!-- we may have c:when, etc (args are their own sub-equations) -->
|
|
<xsl:apply-templates select="./c:*[1]/c:*" mode="calc-after" />
|
|
</xsl:for-each>
|
|
|
|
<xsl:if test="not( $fsym )">
|
|
<xsl:text>\right)</xsl:text>
|
|
</xsl:if>
|
|
|
|
<xsl:apply-templates select="./c:*" mode="calc-after" />
|
|
</xsl:template>
|
|
|
|
|
|
<!--
|
|
Outputs Iverson's brackets only if forced; see calc-after mode
|
|
|
|
This is hidden by default until calc-after to ensure that this is display
|
|
*after* the equation is output.
|
|
|
|
@param boolean force-show optionally force the display of the notation
|
|
|
|
@return LaTeX equation
|
|
-->
|
|
<xsl:template match="c:when">
|
|
<xsl:param name="force-show" select="false()" />
|
|
<xsl:param name="standalone" select="false()" />
|
|
|
|
<!-- by default, we want to defer showing this until after the equation has
|
|
been output; however, the caller can force it to be displayed if needed -->
|
|
<xsl:if test="$force-show = true()">
|
|
<xsl:apply-templates select="." mode="calc-after">
|
|
<xsl:with-param name="standalone" select="$standalone" />
|
|
</xsl:apply-templates>
|
|
</xsl:if>
|
|
</xsl:template>
|
|
|
|
|
|
<!--
|
|
Outputs Iverson's brackets
|
|
|
|
This is called *after* the equation is output
|
|
|
|
@return LaTeX equation
|
|
-->
|
|
<xsl:template match="c:when" mode="calc-after" priority="5">
|
|
<xsl:param name="brackets" select="true()" />
|
|
<xsl:param name="standalone" select="false()" />
|
|
|
|
<xsl:variable name="preceding" select="preceding-sibling::c:when" />
|
|
|
|
<!-- output bracket only if (a) requested and (b) first in set -->
|
|
<xsl:if test="$brackets and ( $standalone or not( $preceding ) )">
|
|
<xsl:text>\left[</xsl:text>
|
|
</xsl:if>
|
|
|
|
<!-- if we do have a preceding sibling, prefix with "and" -->
|
|
<xsl:if test="not( $standalone ) and $preceding">
|
|
<xsl:text>\text{ and }</xsl:text>
|
|
</xsl:if>
|
|
|
|
<!-- output the symbol for the variable we are comparing against -->
|
|
<xsl:apply-templates select="." mode="calc-get-value" />
|
|
|
|
<xsl:text> </xsl:text>
|
|
<xsl:apply-templates select="./c:*" mode="calc-iversons" />
|
|
|
|
<!-- output bracket only if (a) requested and (b) last in set -->
|
|
<xsl:if test="
|
|
$brackets and ( $standalone or not( following-sibling::c:when ) )
|
|
">
|
|
|
|
<xsl:text>\right]</xsl:text>
|
|
</xsl:if>
|
|
</xsl:template>
|
|
|
|
|
|
<xsl:template match="c:cases">
|
|
<xsl:text>\begin{cases}</xsl:text>
|
|
<xsl:apply-templates select="./c:case|./c:otherwise" />
|
|
<xsl:text>\end{cases}</xsl:text>
|
|
|
|
<!-- if any equations immediately follow, add some extra space so as not to
|
|
confuse the reader -->
|
|
<xsl:if test="following-sibling::c:*">
|
|
<xsl:text>\;\;\;</xsl:text>
|
|
</xsl:if>
|
|
</xsl:template>
|
|
|
|
|
|
<!--
|
|
Generate a case
|
|
|
|
When $force-show is provided, as it is when displaying only small portions of
|
|
an equation, it will display the line using Iverson's brackets.
|
|
-->
|
|
<xsl:template match="c:cases/c:case|c:cases/c:otherwise">
|
|
<xsl:param name="force-show" select="false()" />
|
|
|
|
<!-- generate value -->
|
|
<xsl:apply-templates select="./c:*[ not( local-name() = 'when' ) ][1]" />
|
|
|
|
<xsl:choose>
|
|
<xsl:when test="not( $force-show )">
|
|
<xsl:text> & </xsl:text>
|
|
</xsl:when>
|
|
|
|
<xsl:otherwise>
|
|
<xsl:text> [</xsl:text>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
|
|
<xsl:choose>
|
|
<xsl:when test="local-name() != 'otherwise'">
|
|
<xsl:if test="not( $force-show )">
|
|
<xsl:text>\text{if } </xsl:text>
|
|
</xsl:if>
|
|
|
|
<!-- generate condition under which this value will apply -->
|
|
<xsl:apply-templates select="./c:when" mode="calc-after">
|
|
<xsl:with-param name="brackets" select="false()" />
|
|
</xsl:apply-templates>
|
|
</xsl:when>
|
|
|
|
<xsl:otherwise>
|
|
<xsl:text>\text{otherwise}</xsl:text>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
|
|
<!-- determine how we end the line (more cases or end?) -->
|
|
<xsl:choose>
|
|
<xsl:when test="$force-show">
|
|
<xsl:text>]</xsl:text>
|
|
</xsl:when>
|
|
|
|
<xsl:when test="following-sibling::c:case|following-sibling::c:otherwise">
|
|
<xsl:text>; \\</xsl:text>
|
|
</xsl:when>
|
|
|
|
<xsl:otherwise>
|
|
<xsl:text>.</xsl:text>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:template>
|
|
|
|
|
|
<!--
|
|
Do nothing with calc-after for any unmatched calculations
|
|
-->
|
|
<xsl:template match="c:*" mode="calc-after" priority="1">
|
|
<!-- make sure nothing is done for all other nodes with calc-after -->
|
|
</xsl:template>
|
|
|
|
|
|
<!--
|
|
Display a notation intended for use within Iverson's brackets
|
|
|
|
@return LaTeX equation
|
|
-->
|
|
<xsl:template match="c:eq|c:ne|c:gt|c:lt|c:gte|c:lte" mode="calc-iversons">
|
|
<xsl:param name="recurse" select="true()" />
|
|
|
|
<xsl:variable name="name" select="local-name()" />
|
|
|
|
<!-- map to LaTeX equivalent -->
|
|
<xsl:variable name="map">
|
|
<c id="eq">=</c>
|
|
<c id="ne">\not=\;</c>
|
|
<c id="gt">\gt</c>
|
|
<c id="lt">\lt</c>
|
|
<c id="gte">\geq</c>
|
|
<c id="lte">\leq</c>
|
|
</xsl:variable>
|
|
|
|
<xsl:value-of select="$map/*[ @id=$name ]" />
|
|
<xsl:text> </xsl:text>
|
|
|
|
<xsl:if test="$recurse">
|
|
<xsl:apply-templates select="." mode="calc-recurse" />
|
|
</xsl:if>
|
|
</xsl:template>
|
|
|
|
|
|
<!--
|
|
TODO: Technically this is incorrect; sets cannot have duplicate values. This
|
|
would be best styled as a vector/matrix/etc.
|
|
-->
|
|
<xsl:template match="c:set" priority="1">
|
|
<xsl:text>\left[</xsl:text>
|
|
<xsl:for-each select="./c:*">
|
|
<xsl:if test="position() > 1">
|
|
<xsl:text>,</xsl:text>
|
|
</xsl:if>
|
|
|
|
<xsl:apply-templates select="." />
|
|
</xsl:for-each>
|
|
<xsl:text>\right]^T</xsl:text>
|
|
</xsl:template>
|
|
|
|
<!-- style subsets as matrices (easier to read) -->
|
|
<xsl:template match="c:set[ ./c:set ]" priority="5">
|
|
<xsl:text>\left[\begin{array}\\</xsl:text>
|
|
|
|
<xsl:for-each select="./c:set">
|
|
<xsl:if test="position() > 1">
|
|
<xsl:text>\\</xsl:text>
|
|
</xsl:if>
|
|
|
|
<xsl:for-each select="./c:*">
|
|
<xsl:if test="position() > 1">
|
|
<xsl:text disable-output-escaping="yes"> & </xsl:text>
|
|
</xsl:if>
|
|
|
|
<xsl:text>{</xsl:text>
|
|
<xsl:apply-templates select="." />
|
|
<xsl:text>}</xsl:text>
|
|
</xsl:for-each>
|
|
</xsl:for-each>
|
|
|
|
<xsl:text>\end{array}\right]</xsl:text>
|
|
</xsl:template>
|
|
|
|
|
|
<xsl:template match="c:length-of">
|
|
<xsl:text>\left|\left(</xsl:text>
|
|
<xsl:apply-templates select="./c:*[1]" />
|
|
<xsl:text>\right)\right|</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="c:cons">
|
|
<xsl:text>\textrm{cons}\left(</xsl:text>
|
|
<xsl:apply-templates select="./c:*[1]" />
|
|
<xsl:text>,</xsl:text>
|
|
<xsl:apply-templates select="./c:*[2]" />
|
|
<xsl:text>\right)</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="c:car">
|
|
<xsl:text>\left(</xsl:text>
|
|
<xsl:apply-templates select="./c:*[1]" />
|
|
<xsl:text>\right)_0</xsl:text>
|
|
</xsl:template>
|
|
|
|
<xsl:template match="c:cdr">
|
|
<xsl:text>\textrm{cdr}\left(</xsl:text>
|
|
<xsl:apply-templates select="./c:*[1]" />
|
|
<xsl:text>\right)</xsl:text>
|
|
</xsl:template>
|
|
|
|
</xsl:stylesheet>
|