<xsl:template name="CreateRunWithSameProp">
<xsl:param name="mathbackground"/>
<xsl:param name="mathcolor"/>
<xsl:param name="mathvariant"/>
<xsl:param name="color"/>
<xsl:param name="font-family"/>
<xsl:param name="fontsize"/>
<xsl:param name="fontstyle"/>
<xsl:param name="fontweight"/>
<xsl:param name="mathsize"/>
<xsl:param name="ndTokenFirst"/>
<!--Given mathcolor, color, mstyle's (ancestor) color, and precedence of
said attributes, determine the actual color of the current run-->
<xsl:variable name="sColorPropCur">
<xsl:choose>
<xsl:when test="$mathcolor!=''">
<xsl:value-of select="$mathcolor"/>
</xsl:when>
<xsl:when test="$color!=''">
<xsl:value-of select="$color"/>
</xsl:when>
<xsl:when test="$ndTokenFirst/ancestor::mml:mstyle[@color][1]/@color!=''">
<xsl:value-of select="$ndTokenFirst/ancestor::mml:mstyle[@color][1]/@color"/>
</xsl:when>
<xsl:when test="$ndTokenFirst/ancestor::mml:mstyle[@mml:color][1]/@mml:color!=''">
<xsl:value-of select="$ndTokenFirst/ancestor::mml:mstyle[@color][1]/@mml:color"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="''"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!--Given mathsize, and fontsize and precedence of said attributes,
determine the actual font size of the current run-->
<xsl:variable name="sSzCur">
<xsl:choose>
<xsl:when test="$mathsize!=''">
<xsl:value-of select="$mathsize"/>
</xsl:when>
<xsl:when test="$fontsize!=''">
<xsl:value-of select="$fontsize"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="''"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!--Given mathvariant, fontstyle, and fontweight, and precedence of
the attributes, determine the actual font of the current run-->
<xsl:variable name="sFontCur">
<xsl:call-template name="GetFontCur">
<xsl:with-param name="mathvariant" select="$mathvariant"/>
<xsl:with-param name="fontstyle" select="$fontstyle"/>
<xsl:with-param name="fontweight" select="$fontweight"/>
<xsl:with-param name="ndCur" select="$ndTokenFirst"/>
</xsl:call-template>
</xsl:variable>
<!-- The omml equivalent structure for mml:mtext is an omml run with the run property m:nor (normal) set.
Therefore, we can only collect mtexts with other mtext elements. Suppose the $ndTokenFirst is an
mml:mtext, then if any of its following siblings are to be grouped, they must also be mml:text elements.
The inverse is also true, suppose the $ndTokenFirst isn't an mml:mtext, then if any of its following siblings
are to be grouped with $ndTokenFirst, they can't be mml:mtext elements-->
<xsl:variable name="fNdTokenFirstIsMText">
<xsl:choose>
<xsl:when test="$ndTokenFirst/self::mml:mtext">1</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!--In order to determine the length of the run, we will find the number of nodes before the initial node in the run and
the number of nodes before the first node that DOES NOT belong to the current run. The number of nodes that will
be printed is One Less than the difference between the latter and the former-->
<!--Find index of current node-->
<xsl:variable name="nndBeforeFirst" select="count($ndTokenFirst/preceding-sibling::*)"/>
<!--Find index of next change in run properties.
The basic idea is that we want to find the position of the last node in the longest
sequence of nodes, starting from ndTokenFirst, that can be grouped into a run. For
example, nodes A and B can be grouped together into the same run iff they have the same
props.
To accomplish this grouping, we want to find the next sibling to ndTokenFirst that shouldn't be
included in the run of text. We do this by counting the number of elements that precede the first
such element that doesn't belong. The xpath that accomplishes this is below.
Count the number of siblings the precede the first element after ndTokenFirst that shouldn't belong.
count($ndTokenFirst/following-sibling::*[ . . . ][1]/preceding-sibling::*)
Now, the hard part to this is what is represented by the '. . .' above. This conditional expression is
defining what elements *don't* belong to the current run. The conditions are as follows:
The element is not a token element (mi, mn, mo, ms, or mtext)
or
The token element contains a glyph child (this is handled separately).
or
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
with an mtext. We do this check because mtext transforms into an omml m:nor property, and thus, these mtext
token elements need to be grouped separately from other token elements.
// We do an or not( . . . ), because it was easier to define what token elements match than how they don't match.
// Thus, this inner '. . .' defines how token attributes equate to one another. We add the 'not' outside of to accomplish
// the goal of the outer '. . .', which is the find the next element that *doesn't* match.
or not(
The background colors match.
and
The current font (sFontCur) matches the mathvariant
or
sFontCur is normal and matches the current font characteristics
or
sFontCur is italic and matches the current font characteristics
or
. . .
and
The font family matches the current font family.
) // end of not().-->
<xsl:variable name="nndBeforeLim" select="count($ndTokenFirst/following-sibling::* [(not(self::mml:mi) and not(self::mml:mn) and not(self::mml:mo) and not(self::mml:ms) and not(self::mml:mtext)) or (self::mml:mi[child::mml:mglyph] or self::mml:mn[child::mml:mglyph] or self::mml:mo[child::mml:mglyph] or self::mml:ms[child::mml:mglyph] or self::mml:mtext[child::mml:mglyph]) or (($fNdTokenFirstIsMText=1 and not(self::mml:mtext)) or ($fNdTokenFirstIsMText=0 and self::mml:mtext)) or not( ((($sFontCur=@mathvariant or $sFontCur=@mml:mathvariant) or ($sFontCur='normal' and ((@mathvariant='normal' or @mml:mathvariant='normal') or (((not(@mathvariant) or @mathvariant='') and (not(@mml:mathvariant) or @mml:mathvariant='')) and ( ((@fontstyle='normal' or @mml:fontstyle='normal') and (not(@fontweight='bold') and not(@mml:fontweight='bold'))) or (self::mml:mi and string-length(normalize-space(.)) > 1) ) ) ) ) or ($sFontCur='italic' and ((@mathvariant='italic' or @mml:mathvariant='italic') or (((not(@mathvariant) or @mathvariant='') and (not(@mml:mathvariant) or @mml:mathvariant='')) and ( ((@fontstyle='italic' or @mml:fontstyle='italic') and (not(@fontweight='bold') and not(@mml:fontweight='bold'))) or (self::mml:mn or self::mml:mo or (self::mml:mi and string-length(normalize-space(.)) <= 1)) ) ) ) ) or ($sFontCur='bold' and ((@mathvariant='bold' or @mml:mathvariant='bold') or (((not(@mathvariant) or @mathvariant='') and (not(@mml:mathvariant) or @mml:mathvariant='')) and ( ((@fontweight='bold' or @mml:fontweight='bold') and ((@fontstyle='normal' or @mml:fontstyle='normal') or (self::mml:mi and string-length(normalize-space(.)) <= 1)) ) ) ) ) ) or (($sFontCur='bi' or $sFontCur='bold-italic') and ( (@mathvariant='bold-italic' or @mml:mathvariant='bold-italic') or (((not(@mathvariant) or @mathvariant='') and (not(@mml:mathvariant) or @mml:mathvariant='')) and ( ((@fontweight='bold' or @mml:fontweight='bold') and (@fontstyle='italic' or @mml:fontstyle='italic')) or ((@fontweight='bold' or @mml:fontweight='bold') and (self::mml:mn or self::mml:mo or (self::mml:mi and string-length(normalize-space(.)) <= 1))) ) ) ) ) or (($sFontCur='' and ( ((not(@mathvariant) or @mathvariant='') and (not(@mml:mathvariant) or @mml:mathvariant='') and (not(@fontstyle) or @fontstyle='') and (not(@mml:fontstyle) or @mml:fontstyle='') and (not(@fontweight)or @fontweight='') and (not(@mml:fontweight) or @mml:fontweight='') ) or (@mathvariant='italic' or @mml:mathvariant='italic') or ( ((not(@mathvariant) or @mathvariant='') and (not(@mml:mathvariant) or @mml:mathvariant='')) and ( (((@fontweight='normal' or @mml:fontweight='normal') and (@fontstyle='italic' or @mml:fontstyle='italic')) ) or ((not(@fontweight) or @fontweight='') and (not(@mml:fontweight) or @mml:fontweight='')) and (@fontstyle='italic' or @mml:fontstyle='italic') or ((not(@fontweight) or @fontweight='') and (not(@mml:fontweight) or @mml:fontweight='')) and (not(@fontstyle) or @fontstyle='') and (not(@mml:fontstyle) or @mml:fontstyle='')) ) ) )) or ($sFontCur='normal' and ((self::mml:mi and (not(@mathvariant) or @mathvariant='') and (not(@mml:mathvariant) or @mml:mathvariant) and (not(@fontstyle) or @fontstyle='') and (not(@mml:fontstyle) or @mml:fontstyle='') and (not(@fontweight) or @fontweight='') and (not(@mml:fontweight) or @mml:fontweight='') and (string-length(normalize-space(.)) > 1) ) or ((self::mml:ms or self::mml:mtext) and (not(@mathvariant) or @mathvariant='') and (not(@mml:mathvariant) or @mml:mathvariant) and (not(@fontstyle) or @fontstyle) and (not(@fontstyle) or @fontstyle='') and (not(@fontweight) or @fontweight) and (not(@mml:fontweight) or @mml:fontweight='') ) ) ) ) and (($font-family = @font-family or $font-family = @mml:font-family) or (($font-family='' or not($font-family)) and (not(@font-family) or @font-family='') and (not(@mml:font-family) or @mml:font-family='') ) ) )) ][1]/preceding-sibling::*)"/>
<xsl:variable name="cndRun" select="$nndBeforeLim - $nndBeforeFirst"/>
<!--Contiguous groups of like-property mi, mn, and mo's are separated by non- mi, mn, mo tags, or mi,mn, or mo
tags with different properties. nndBeforeLim is the number of nodes before the next tag which separates contiguous
groups of like-property mi, mn, and mo's. Knowing this delimiting tag allows for the aggregation of the correct
number of mi, mn, and mo tags.-->
<r>
<!--The beginning and ending of the current run has been established. Now we should open a run element-->
<xsl:choose>
<!--If cndRun > 0, then there is a following different prop, or non- Token,
although there may or may not have been a preceding different prop, or non-
Token-->
<xsl:when test="$cndRun > 0">
<xsl:call-template name="CreateRunProp">
<xsl:with-param name="mathvariant" select="$mathvariant"/>
<xsl:with-param name="fontstyle" select="$fontstyle"/>
<xsl:with-param name="fontweight" select="$fontweight"/>
<xsl:with-param name="mathcolor" select="$mathcolor"/>
<xsl:with-param name="mathsize" select="$mathsize"/>
<xsl:with-param name="color" select="$color"/>
<xsl:with-param name="fontsize" select="$fontsize"/>
<xsl:with-param name="ndCur" select="$ndTokenFirst"/>
<xsl:with-param name="fNor">
<xsl:call-template name="FNor">
<xsl:with-param name="ndCur" select="$ndTokenFirst"/>
</xsl:call-template>
</xsl:with-param>
<xsl:with-param name="fLit">
<xsl:call-template name="FLit">
<xsl:with-param name="ndCur" select="$ndTokenFirst"/>
</xsl:call-template>
</xsl:with-param>
</xsl:call-template>
<t>
<xsl:call-template name="OutputText">
<xsl:with-param name="sInput">
<xsl:choose>
<xsl:when test="namespace-uri($ndTokenFirst) = 'http://www.w3.org/1998/Math/MathML' and local-name($ndTokenFirst) = 'ms'">
<xsl:call-template name="OutputMs">
<xsl:with-param name="msCur" select="$ndTokenFirst"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="normalize-space($ndTokenFirst)"/>
</xsl:otherwise>
</xsl:choose>
<xsl:for-each select="$ndTokenFirst/following-sibling::*[position() < $cndRun]">
<xsl:choose>
<xsl:when test="namespace-uri(.) = 'http://www.w3.org/1998/Math/MathML' and local-name(.) = 'ms'">
<xsl:call-template name="OutputMs">
<xsl:with-param name="msCur" select="."/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="normalize-space(.)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:with-param>
</xsl:call-template>
</t>
</xsl:when>
<xsl:otherwise>
<!--if cndRun lt;= 0, then iNextNonToken = 0,
and iPrecNonToken gt;= 0. In either case, b/c there
is no next different property or non-Token
(which is implied by the nndBeforeLast being equal to 0)
you can put all the remaining mi, mn, and mo's into one
group.-->
<xsl:call-template name="CreateRunProp">
<xsl:with-param name="mathvariant" select="$mathvariant"/>
<xsl:with-param name="fontstyle" select="$fontstyle"/>
<xsl:with-param name="fontweight" select="$fontweight"/>
<xsl:with-param name="mathcolor" select="$mathcolor"/>
<xsl:with-param name="mathsize" select="$mathsize"/>
<xsl:with-param name="color" select="$color"/>
<xsl:with-param name="fontsize" select="$fontsize"/>
<xsl:with-param name="ndCur" select="$ndTokenFirst"/>
<xsl:with-param name="fNor">
<xsl:call-template name="FNor">
<xsl:with-param name="ndCur" select="$ndTokenFirst"/>
</xsl:call-template>
</xsl:with-param>
<xsl:with-param name="fLit">
<xsl:call-template name="FLit">
<xsl:with-param name="ndCur" select="$ndTokenFirst"/>
</xsl:call-template>
</xsl:with-param>
</xsl:call-template>
<t>
<!--Create the Run, first output current, then in a
for-each, because all the following siblings are
mn, mi, and mo's that conform to the run's properties,
group them together-->
<xsl:call-template name="OutputText">
<xsl:with-param name="sInput">
<xsl:choose>
<xsl:when test="namespace-uri($ndTokenFirst) = 'http://www.w3.org/1998/Math/MathML' and local-name($ndTokenFirst) = 'ms'">
<xsl:call-template name="OutputMs">
<xsl:with-param name="msCur" select="$ndTokenFirst"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="normalize-space($ndTokenFirst)"/>
</xsl:otherwise>
</xsl:choose>
<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]">
<xsl:choose>
<xsl:when test="namespace-uri(.) = 'http://www.w3.org/1998/Math/MathML' and local-name(.) = 'ms'">
<xsl:call-template name="OutputMs">
<xsl:with-param name="msCur" select="."/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="normalize-space(.)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:with-param>
</xsl:call-template>
</t>
</xsl:otherwise>
</xsl:choose>
</r>
<!--The run was terminated by an mi, mn, mo, ms, or mtext with different properties,
therefore, call-template CreateRunWithSameProp, using cndRun+1 node as new start node-->
<xsl:if test="$nndBeforeLim!=0 and ($ndTokenFirst/following-sibling::*[$cndRun]/self::mml:mi or $ndTokenFirst/following-sibling::*[$cndRun]/self::mml:mn or $ndTokenFirst/following-sibling::*[$cndRun]/self::mml:mo or $ndTokenFirst/following-sibling::*[$cndRun]/self::mml:ms or $ndTokenFirst/following-sibling::*[$cndRun]/self::mml:mtext) and (count($ndTokenFirst/following-sibling::*[$cndRun]/mml:mglyph) = 0)">
<xsl:call-template name="CreateRunWithSameProp">
<xsl:with-param name="mathbackground">
<xsl:choose>
<xsl:when test="$ndTokenFirst/following-sibling::*[$cndRun]/@mathbackground">
<xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mathbackground"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mml:mathbackground"/>
</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
<xsl:with-param name="mathcolor">
<xsl:choose>
<xsl:when test="$ndTokenFirst/following-sibling::*[$cndRun]/@mathcolor">
<xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mathcolor"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mml:mathcolor"/>
</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
<xsl:with-param name="mathvariant">
<xsl:choose>
<xsl:when test="$ndTokenFirst/following-sibling::*[$cndRun]/@mathvariant">
<xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mathvariant"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mml:mathvariant"/>
</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
<xsl:with-param name="color">
<xsl:choose>
<xsl:when test="$ndTokenFirst/following-sibling::*[$cndRun]/@color">
<xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@color"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mml:color"/>
</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
<xsl:with-param name="font-family">
<xsl:choose>
<xsl:when test="$ndTokenFirst/following-sibling::*[$cndRun]/@font-family">
<xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@font-family"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mml:font-family"/>
</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
<xsl:with-param name="fontsize">
<xsl:choose>
<xsl:when test="$ndTokenFirst/following-sibling::*[$cndRun]/@fontsize">
<xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@fontsize"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mml:fontsize"/>
</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
<xsl:with-param name="fontstyle">
<xsl:choose>
<xsl:when test="$ndTokenFirst/following-sibling::*[$cndRun]/@fontstyle">
<xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@fontstyle"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mml:fontstyle"/>
</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
<xsl:with-param name="fontweight">
<xsl:choose>
<xsl:when test="$ndTokenFirst/following-sibling::*[$cndRun]/@fontweight">
<xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@fontweight"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mml:fontweight"/>
</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
<xsl:with-param name="mathsize">
<xsl:choose>
<xsl:when test="$ndTokenFirst/following-sibling::*[$cndRun]/@mathsize">
<xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mathsize"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$ndTokenFirst/following-sibling::*[$cndRun]/@mml:mathsize"/>
</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
<xsl:with-param name="ndTokenFirst" select="$ndTokenFirst/following-sibling::*[$cndRun]"/>
</xsl:call-template>
</xsl:if>
</xsl:template> |