% $Id: tex4ht-jsml-xtpipes.tex 740 2020-06-13 22:35:32Z karl $
% htlatex tex4ht-jsml-xtpipes "xhtml,next,3" "" "-d./"
%
% Copyright 2009-2020 TeX Users Group
% Copyright 2002-2009 Eitan M. Gurari
% Released under LPPL 1.3c+.
% See tex4ht-cpright.tex for license text.

\documentclass{article}
   \Configure{ProTex}{log,<<<>>>,title,list,`,[[]]}
\begin{document}


\input{common}
\input{tex4ht-cpright}
\input{tex4ht-dir}

%%%%%%%%%%%%%%%%%%
\part{Script for xtpipes}
%%%%%%%%%%%%%%%%%%


%%%%%%%%%%%%%%%%%%
\section{Outline}
%%%%%%%%%%%%%%%%%%

\AtEndDocument{\OutputCodE\<jsml.4xt\>}

\Needs{"xmllint --valid --noout jsml.4xt"}


\<jsml.4xt\><<<
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE xtpipes SYSTEM "xtpipes.dtd" >
<!-- jsml.4xt (`version), generated from `jobname.tex
    Copyright (C) 2009-2010 TeX Users Group
    Copyright (C) `CopyYear.2002. Eitan M. Gurari
`<TeX4ht copyright`> -->
<xtpipes signature="jsml.4xt (`version)">
  <sax content-handler="xtpipes.util.ScriptsManager, tex4ht.GroupMn, tex4ht.JsmlFilter"
       lexical-handler="xtpipes.util.ScriptsManagerLH" >
    `<numbers in math`>
    `<special sub and super scripts`>
    `<span frac elements`>
    `<short cut modifiers`>
    `<over and under scripts`>
    `<bold math`>
    `<capital math letters`>
    `<remove multline eqnum cell`>
    `<inline math`>
    `<display math`>
    `<replace characters`>
    `<remove empty split entries`>
    `<boundaries on theorems`>
    `<br into BREAK`>
    `<short notation for empty elements`>
  </sax>
</xtpipes>
>>>


    `<non short tag br elements`>

    `<inline math`>
    `<display math`>
    `<measure tables`>




\<inline math\><<<
<script element="span::inline-math" >
 `<compress numeric subscripts`>
 `<set levels for hyper complex fracs`>
 `<set levels for sub and sup scripts`>
 `<set levels for roots`>
 <set name="inline-math" >
    `<open xslt script`>
    `<shared display and inline math 1`>
    `<eliminate inline math narrative`>
    `<close xslt script`>
 </set>
 <xslt name="." xml="." xsl="inline-math" />
 `<eliminate extra math pauses`>
 <set name="inline-math-2" >
    `<open xslt script`>
    `<shared display and inline math 2`>
    `<eliminate inline math narrative 2`>
    `<close xslt script`>
 </set>
 <xslt name="." xml="." xsl="inline-math-2" />
</script>
>>>


\<display math\><<<
<script element="div::display-math" >
 `<compress numeric subscripts`>
 `<set levels for hyper complex fracs`>
 `<set levels for sub and sup scripts`>
 `<set levels for roots`>
 <set name="display-math" >
    `<open xslt script`>
    `<shared display and inline math 1`>
    `<close xslt script`>
 </set>
 <xslt name="." xml="." xsl="display-math" />
 `<eliminate extra math pauses`>
 <set name="display-math-2" >
    `<open xslt script`>
    `<shared display and inline math 2`>
    `<close xslt script`>
 </set>
 <xslt name="." xml="." xsl="display-math-2" />
 `<set empty elements for the w3 browser`>
</script>
>>>




\<shared display and inline math 1\><<<
`<remove super mn-group`>
`<sayas punctuation`>
`<sayas digits`>
`<sayas math letters`>
`<get content template`>
`<eliminate baseline script marks`>
`<clean begin and mid script marks`>
`<mixed fractions`>
`<'minus' into 'negative'`>
`<compress limit script`>
`<remove scrip indicators from primes`>
`<remove scrip indicators from degree`>
>>>


\<shared display and inline math 2\><<<
`<get content template`>
`<replace nested baseline script marks`>
`<remove marks on empty scripts`>
`<eliminate begin script marks`>
>>>




\AtEndDocument{\OutputCodE\<HtJsml.java\>}

\ifdojava
 \Needs{"
   javac HtJsml.java -d \XTPIPES
"}
\fi

\<HtJsml.java\><<<
package tex4ht;
/* HtJsml.java (`version), generated from `jobname.tex
  Copyright (C) 2009-2010 TeX Users Group
  Copyright (C) `CopyYear.2002. Eitan M. Gurari
`<TeX4ht copyright`> */
import org.w3c.dom.*;
public class HtJsml {
 `<HtJsml utility members`>
 `<static void mnGroup(dom)`>
 `<static void fracLevel(dom)`>
 `<static void scriptLevel(dom)`>
 `<static void rootLevel(dom)`>
}
>>>




%%%%%%%%%%%%%%%%%%
\section{Numbers in Math}
%%%%%%%%%%%%%%%%%%


%%%%%%%%%%%%%
\subsection{Group MN / MO-Punctuation}
%%%%%%%%%%%%%


\AtEndDocument{%
  \OutputCodE\<GroupMn.java\>
}
\ifdojava
 \Needs{"
   javac GroupMn.java -d \XTPIPES
"}
\fi

\<GroupMn.java\><<<
package tex4ht;
/* GroupMn.java (`version), generated from `jobname.tex
  Copyright (C) 2009-2010 TeX Users Group
  Copyright (C) `CopyYear.2002. Eitan M. Gurari
`<TeX4ht copyright`> */
import org.xml.sax.helpers.*;
import org.xml.sax.*;
import java.io.PrintWriter;

public class GroupMn extends XMLFilterImpl {
    PrintWriter out = null;
    boolean inMn = false;
    String ns;
    int level = -1;
  public GroupMn( PrintWriter out, PrintWriter log, boolean trace){
    this.out = out;
  }
  public void startElement(String ns, String sName,
                          String qName, Attributes attr) {
     level++;
     try{
       if( inMn ){
          if( level == 0 ){ `<consider end of num`> }
       } else { `<consider start of num`> }
       super.startElement(ns, sName, qName, attr);
     } catch( Exception e ){
       System.out.println( "--- GroupMn Error 1 --- " + e);
     }
  }
  public void endElement(String ns, String sName, String qName){
     try{
       if( level < 0) {
         `<endElement: consider end of num`>
       }
       super.endElement(ns, sName, qName);
     } catch( Exception e ){
       System.out.println( "--- GroupMn Error 2 --- " + e);
     }
     level--;
  }
  public void characters(char[] ch, int start, int length){
     try{
       if ( inMn  && (level < 0) ) {
          String s = new String(ch, start, length);
          if (!s.trim().equals("")) {
            inMn = false;
            super.endElement(ns, "mn-group", "mn-group");
       }  }
       super.characters(ch, start, length);
     } catch( Exception e ){
       System.out.println( "--- GroupMn Error 3 --- " + e);
}  }  }
>>>

\<consider start of num\><<<
if( qName.equals( "mn" ) ){
  inMn = true; level = 0;
  Attributes att = new AttributesImpl();
  super.startElement(ns, "mn-group", "mn-group", att);
  this.ns = ns;
} else if( qName.equals( "mo" ) ){
  String cls = attr.getValue( "class" );
  if( (cls != null) && cls.equals("MathClass-punc") ){
     inMn = true; level = 0;
     Attributes att = new AttributesImpl();
     super.startElement(ns, "mn-group", "mn-group", att);
     this.ns = ns;
}  }
>>>

\<consider end of num\><<<
if( !qName.equals( "mn" ) ){
 if( qName.equals( "mo" ) ){
    String cls = attr.getValue( "class" );
    if( (cls == null) || !cls.equals("MathClass-punc") ){
       inMn = false;
       super.endElement(ns, "mn-group", "mn-group");
    }
 } else {
    inMn = false;
    super.endElement(ns, "mn-group", "mn-group");
} }
>>>

\<endElement: consider end of num\><<<
if( inMn ){
  inMn = false;
  super.endElement(ns, "mn-group", "mn-group");
}
>>>

%%%%%%%%%%%%%
\subsection{Outline of Post Original Partition}
%%%%%%%%%%%%%


\<numbers in math\><<<
<script element="mn-group" >
  `<missed partitions to mn groups`>
  <set name="merge" >
     `<open xslt script`>
     `<merge digits`>
     `<close xslt script`>
  </set>
  <xslt name="." xml="." xsl="merge" />
</script>
>>>



\<missed partitions to mn groups\><<<
<dom name="." xml="." method="mnGroup" class="tex4ht.HtJsml" />
`<remove xml declaration`>
>>>


\<static void mnGroup(dom)\><<<
private static Document dom;
public static void mnGroup(Node d) {
 dom = (Document) d;
 setMnGroup(dom.getFirstChild());
}
private static void setMnGroup(Node node) {
 if( node.getNodeName().equals( "mn-group" ) ){
        boolean bool = false;
   `<get mn characters`>
   if( bool ){
     `<mark remove commas, if comma after period`>
     `<mark remove commas, if not spaced correctly`>
     `<cond remove commas`>
     `<remove punc, on consecutive periods`>
     `<remove punc at end`>
   }
   `<reset mn-group`>
 } else if (node.hasChildNodes()) {
    NodeList children = node.getChildNodes();
    for (int i = 0; i < children.getLength(); i++) {
       Node child = children.item(i);
       if (child.getNodeType() == Node.ELEMENT_NODE) {
          setMnGroup(child);
} }  }  }
>>>

%%%%%%%%%%%%%
\subsection{Mark Partition of MN Group}
%%%%%%%%%%%%%

Consecutive digits and punctation characters are grouped together, and
then ungrouped at characters that are marked by `x'.


\<get mn characters\><<<
NodeList children = node.getChildNodes();
int n = children.getLength();
char [] digit = new char[n];
for (int i = 0; i < n; i++) {
 Node child = children.item(i).getFirstChild();
 if( child == null ){
    digit[i] = 'x';
 } else if( child.getNodeType() != Node.TEXT_NODE ){
    digit[i] = 'x';
 } else {
    String s = child.getNodeValue();
    if( s.length() != 1 ){
      digit[i] = 'x';
    } else {
      char ch = s.charAt(0);
      if(      (ch >= '0') && (ch <= '9') ){
         digit[i] = '0'; bool = true;
      } else if( (ch == '.') || (ch == ',') ){ digit[i] = ch; }
      else                                 { digit[i] = 'x';}
} }  }
>>>

\<mark remove commas, if comma after period\><<<
bool = false;
for (int i = 0; i < n; i++) {
 if( digit[i] == '.' ){
    for (; i < n; i++) {
      if( digit[i] == ',' ){
         bool = true; break;
    } }
    break;
} }
>>>

\<mark remove commas, if not spaced correctly\><<<
if( !bool ){
 for (int i = 0; i < n; i++) {
   if( digit[i] == ',' ){
      if( ( ((i+3) >= n)
            || (digit[i+1] != '0')
            || (digit[i+2] != '0')
            || (digit[i+3] != '0')
          )
          ||
          (
            ((i+4) < n) && (digit[i+4] == '0')
          )
          ||
          (
            (i>3) && (digit[i-4] == '0')
          )
      ){  bool = true; break;
      } else { i += 3; }
} } }
>>>

\<cond remove commas\><<<
if( bool ){
 for (int i = 0; i < n; i++) {
   if( digit[i] == ',' ){ digit[i] = 'x'; }
} }
>>>


\<remove punc, on consecutive periods\><<<
bool = false;
for (int i = 0; i < n; i++) {
 if( (digit[i] == 'x')
     || (digit[i] == ',') ){ bool = false; }
 else if( digit[i] == '.' ){
   if( bool ){
      for (int j = 0; j < n; j++) {
        if( (digit[j] == '.') || (digit[j] == ',') ){
           digit[j] = 'x';
      } }
      break;
   }
   bool = true;
} }
>>>

\<remove punc at end\><<<
if( digit[n-1] == '.' ){ digit[n-1] = 'x'; }
>>>

%%%%%%%%%%%%%
\subsection{Realize the Sub Partition}
%%%%%%%%%%%%%


\<reset mn-group\><<<
Node parent = node.getParentNode();
Element g = dom.createElement( "mn-group-s" );
Element cur = dom.createElement( "mn-group" );
for(int i=0;  i<n; i++ ){
  Node child = node.getFirstChild();
  node.removeChild( child );
  if( digit[i] == 'x' ){
     if( cur.hasChildNodes() ){ g.appendChild( cur ); }
     g.appendChild( child );
     cur = dom.createElement( "mn-group" );
  } else {
     cur.appendChild( child );
}  }
if( cur.hasChildNodes() ){ g.appendChild( cur ); }
parent.replaceChild( g, node );
>>>


%%%%%%%%%%%%%
\subsection{Reset MNs}
%%%%%%%%%%%%%




\<merge digits\><<<
<xsl:template match="mn-group" >
  <xsl:choose>
     <xsl:when test=" not(child::mn) ">
       <xsl:apply-templates select="*|text()" />
     </xsl:when>
     <xsl:otherwise>
        <mn>
          <xsl:value-of select="." />
        </mn>
     </xsl:otherwise>
  </xsl:choose>
</xsl:template>
>>>








\<remove super mn-group\><<<
<xsl:template match="mn-group-s" >
 <xsl:apply-templates select="*|@*|text()|comment()" />
</xsl:template>
>>>



%%%%%%%%%%%%%
\subsection{Pronounced Letters}
%%%%%%%%%%%%%



\<sayas math letters \><<<
<xsl:template match="mi[ .='a' ]" >
 <xsl:copy>
   <xsl:apply-templates select="@*" />
   <SAYAS SUB="aih">a</SAYAS>
 </xsl:copy>
</xsl:template>
>>>


%%%%%%%%%%%%%
\subsection{Pronounced Punctuation in math}
%%%%%%%%%%%%%

TTSs might ignore punctuation marks. We want these
symbols in math.

\<sayas punctuation\><<<
<xsl:template match="mo[
   (@class='MathClass-punc')
   and ( (.='.') or (.=',')  or (.='!')
         or (.=';') or (.=':') or (.='?') )
]" >
 <xsl:copy>
   <xsl:apply-templates select="@*" />
   <BREAK SIZE="small"/>
   <xsl:choose>
      <xsl:when test=" .='.' " >
         <SAYAS SUB="dot">.</SAYAS>
      </xsl:when>
      <xsl:when test=" .=',' " >
         <SAYAS SUB="comma">,</SAYAS>
      </xsl:when>
      <xsl:when test=" .=';' " >
         <SAYAS SUB="semicolon">;</SAYAS>
      </xsl:when>
      <xsl:when test=" .=':' " >
         <SAYAS SUB="colon">:</SAYAS>
      </xsl:when>
      <xsl:when test=" .='!' " >
         <SAYAS SUB="exclamation mark">!</SAYAS>
      </xsl:when>
      <xsl:when test=" .='?' " >
         <SAYAS SUB="question mark">?</SAYAS>
      </xsl:when>
   </xsl:choose>
   <BREAK SIZE="small"/>
 </xsl:copy>
</xsl:template>
>>>


\<sayas digits\><<<
<xsl:template match="mn[
  `<mn modified above`>
  or
  `<mn modified under`>
]" >
 <xsl:copy>
   <SAYAS CLASS="digits">
     <xsl:value-of select="." />
   </SAYAS>
 </xsl:copy>
</xsl:template>
>>>


\<mn modified above\><<<
ancestor::mover[
 not( descendant::*[
       (count( `<math content element`> ) &gt; 1)
    ])
 and
 (
    preceding-sibling::*[1][self::dot or self::mn-group-s]
    or
    following-sibling::*[1][self::dot or self::mn-group-s]
 )
]
>>>



\<mn modified under\><<<
ancestor::munder[
 not( descendant::*[
       (count( `<math content element`> ) &gt; 1)
    ])
 and
 (
    preceding-sibling::*[1][self::dot or self::mn-group-s]
    or
    following-sibling::*[1][self::dot or self::mn-group-s]
 )
]
>>>


%%%%%%%%%%%%%%%%%%
\section{Process Characters}
%%%%%%%%%%%%%%%%%%





%%%%%%%%%%%%%
\subsection{'minus' into 'negative'}
%%%%%%%%%%%%%



\<'minus' into 'negative'\><<<
<xsl:template match="mo[
   (@class = 'MathClass-bin')
 and
   ( normalize-space(.) =
     normalize-space(descendant::span[@class = 'ch 2212'])
   )
 and
   (   preceding-sibling::*[1][
            (@title='speech-extra')
            or (@class='MathClass-bin')
            or (@class='MathClass-rel')
            or (@class='MathClass-punc')
            or (@class='MathClass-op')
            or self::mn-group-s [ child::* [
                  (position() = last())
                 and
                  (@class='MathClass-punc')
       ]       ] ]
       and
       (
          following-sibling::*[1][ self::mn-group-s
                                or self::mi ]
         or
          (count(following-sibling::*[
              not(@title = 'speech-extra')
           ]) = 1)
       )
     or
       not(preceding-sibling::*) and following-sibling::*
   )
]" >
 <xsl:copy>
   <xsl:attribute name="class">
      <xsl:text>mo-unary</xsl:text>
   </xsl:attribute>
   <xsl:apply-templates select="*|text()|comment()"
                        mode="minus-neg" />
 </xsl:copy>
</xsl:template>
>>>


\<'minus' into 'negative'\><<<
<xsl:template match="*|@*|text()|comment()" mode="minus-neg" >
 <xsl:copy>
   <xsl:apply-templates select="*|@*|text()|comment()"
                        mode="minus-neg" />
 </xsl:copy>
</xsl:template>
>>>

\begin{verbatim}
<span class="begin-script"> subscript </span>
<mo class="MathClass-bin">
 <span class="char">
   <span class="ch 2212">minus</span>
 </span>
</mo>
<mn>2</mn>
\end{verbatim}




\<'minus' into 'negative'\><<<
<xsl:template match="text()" mode="minus-neg" >
 <xsl:choose>
   <xsl:when test=" . = 'minus' " >
     <xsl:text>negative</xsl:text>
   </xsl:when>
   <xsl:otherwise>
     <xsl:value-of select="." />
   </xsl:otherwise>
 </xsl:choose>
</xsl:template>
>>>


%%%%%%%%%%%%%%%%%%
\subsection{Capital Letters in Math}
%%%%%%%%%%%%%%%%%%

\<capital math letters\><<<
<script element="mi" >
 <set name="math-cap" >
    `<open xslt script`>
    `<span.mi cap letters`>
    `<close xslt script`>
 </set>
 <xslt name="." xml="." xsl="math-cap" />
</script>
>>>


\<span.mi cap letters\><<<
<xsl:template match="mi" >
 <xsl:copy>
     <xsl:apply-templates select="@*" />
     <xsl:if test=" string-length(.) = 1 " >
        <xsl:if test="
                    (translate(.,'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
                                 '') = '' )
                 " >
           <span class="capital-description"
                 title="speech-extra" >
              <xsl:text> capital </xsl:text>
           </span>
        </xsl:if>
     </xsl:if>
     <xsl:apply-templates select="*|text()|comment()" />
 </xsl:copy>
</xsl:template>
>>>



%%%%%%%%%%%%%
\subsection{Right Apostrophes}
%%%%%%%%%%%%%



\<replace characters\><<<
<script element="PARA" >
 <set name="apostro" >
    `<open xslt script`>
    `<right apostrophe in prose`>
    `<delimiters in marks of enumerated lists`>
    `<remove empty paragraphs`>
    `<close xslt script`>
 </set>
 <xslt name="." xml="." xsl="apostro" />
</script>
>>>


\<right apostrophe in prose\><<<
<xsl:template match="span[
    (@class = 'char-del')
   and  child::span [ @class = 'ch 2019' ]
]" >
  <xsl:text>'</xsl:text>
</xsl:template>
>>>


%%%%%%%%%%%%%
\subsection{Delimiters on List Marks}
%%%%%%%%%%%%%



\<delimiters in marks of enumerated lists\><<<
<xsl:template match="PROS[  parent::SENT[@class='ol-mark'] ]" >
  <xsl:copy>
     <xsl:apply-templates
          select="*[not(@class='char-del')]|@*|text()|comment()" />
  </xsl:copy>
</xsl:template>
>>>


%%%%%%%%%%%%%%%%%%
\section{Clean Up}
%%%%%%%%%%%%%%%%%%


%%%%%%%%%%%%%
\subsection{Extra Math Pauses}
%%%%%%%%%%%%%


Deletes pauses that are not separated by text from their immediate
predecessors.

An earlier XSLT-based approach was very slow, and died
on nodes with large numbers of children.


\<eliminate extra math pauses\><<<
<sax name="." xml="." content-handler="tex4ht.JsmlMathBreak" />
>>>


\AtEndDocument{%
  \OutputCodE\<JsmlMathBreak.java\>
}

\ifdojava
 \Needs{"
   javac -classpath \LIB xtpipes.jar
         JsmlMathBreak.java
         -d \XTPIPES .
"}
\fi

\<JsmlMathBreak.java\><<<
package tex4ht;
/* JsmlMathBreak.java (`version), generated from `jobname.tex
  Copyright (C) 2009-2010 TeX Users Group
  Copyright (C) `CopyYear.2002. Eitan M. Gurari
`<TeX4ht copyright`> */

import xtpipes.XtpipesUni;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import java.io.*;
import java.lang.reflect.*;
import java.util.HashMap;

public class JsmlMathBreak extends DefaultHandler {
       PrintWriter out = null;
       boolean delete = false;
 public JsmlMathBreak(PrintWriter out,
                      HashMap<String,Object> scripts,
                      Method method, PrintWriter log, boolean trace) {
   this.out = out;
 }
 public void characters(char[] ch, int start, int length) {
   String s = XtpipesUni.toUni(ch, start, length, "<>&");
   out.print( s );
   if( !s.trim().equals("") ){
      delete = false;
 } }
 public void startElement(String ns, String sName,
                                     String qName,
                                     Attributes atts) {
   if( !( delete && qName.equals("BREAK") ) ){
     String s = "<" + qName + "\n";
     for (int i = 0; i < atts.getLength(); i++) {
       String name = atts.getQName(i);
       if (name != "xmlns") {
         s += (" " + name + "=\""
             + XtpipesUni.toUni(atts.getValue(i), "<>&\"")
             + "\"");
     } }
     if( qName.equals( "BREAK" ) ){
       s += "/";
       delete = true;
     }
     s += ">";
     out.print(s);
 } }
 public void endElement(String ns, String sName, String qName) {
   if( !qName.equals( "BREAK" ) ){
     String s = "</" + qName + ">";
     out.print(s);
} } }
>>>



\begin{verbatim}
 </mrow>
 <span class="end-root" title="speech-extra">
   <BREAK SIZE="medium"/>
   <level prefix="end" depth="1">end end root</level>
   <BREAK SIZE="medium"/>
 </span>
</mroot>
<span class="end-math" title="speech-extra">
 <BREAK SIZE="small"/>
 <PROS PITCH="-5">end math</PROS>
 <BREAK SIZE="medium"/>
\end{verbatim}


%%%%%%%%%%%%%
\subsection{Line Breaks}
%%%%%%%%%%%%%


\<br into BREAK\><<<
<script element="br" >
 <set name="br" >
    `<open xslt script`>
    `<append br with BREAK`>
    `<close xslt script`>
 </set>
 <xslt name="." xml="." xsl="br" />
</script>
>>>


\<append br with BREAK\><<<
<xsl:template match="br" >
  <xsl:copy>
      <xsl:apply-templates select="@*" />
  </xsl:copy>
  <BREAK SIZE="small"/>
</xsl:template>
>>>
>>>


%%%%%%%%%%%%%%%%%%
\subsection{Empty Elements}
%%%%%%%%%%%%%%%%%%



\marginpar{??????}

Can we avoid empty non-empty representations without of the
following(Example:
\verb+\documentclass{article} \begin{document} \section{Section One} This is Section 1 \end{document} +
)


\<short notation for empty elements\><<<
<script element="BREAK" >
 <set name="BREAK" >
    `<open xslt script`>
    `<empty BREAK`>
    `<close xslt script`>
 </set>
 <xslt name="." xml="." xsl="BREAK" />
</script>
>>>


\<empty BREAK\><<<
<xsl:template match="BREAK" >
  <xsl:copy>
      <xsl:apply-templates select="@*" />
  </xsl:copy>
</xsl:template>
>>>



%%%%%%%%%%%%%
\subsection{Empty Array Cells}
%%%%%%%%%%%%%

Empty array celles at end of rows can make it more difficult to
detect deletable baseline indicators.



\<remove multline eqnum cell\><<<
<script element="tr" >
 <set name="eqnum" >
    `<open xslt script`>
    `<remove empty cells from rows`>
    `<close xslt script`>
 </set>
 <xslt name="." xml="." xsl="eqnum" />
</script>
>>>

\<remove multline eqnum cell\><<<
<script element="mtr" >
 <set name="eqnum" >
    `<open xslt script`>
    `<remove empty cells from rows`>
    `<close xslt script`>
 </set>
 <xslt name="." xml="." xsl="eqnum" />
</script>
>>>

\<remove empty cells from rows\><<<
<xsl:template match="div[
   (parent::tr or parent::mtr)
   and ( normalize-space(.) = '' )
   and not( normalize-space(following-sibling::*) != '' )
]" >
</xsl:template>
>>>


%%%%%%%%%%%%%
\subsection{Paragraphs (JsmlFilter.java)}
%%%%%%%%%%%%%

\<remove empty paragraphs\><<<
<xsl:template match=" PARA[ normalize-space(.) = '' ] " >
</xsl:template>
>>>


The following adds PARA on `p' paragraphs, ul.




\AtEndDocument{ %
  \OutputCodE\<JsmlFilter.java\>
}
\ifdojava
 \Needs{"
   javac JsmlFilter.java -d \XTPIPES
"}
\fi

\<JsmlFilter.java\><<<
package tex4ht;
/* JsmlFilter.java (`version), generated from `jobname.tex
  Copyright (C) 2009-2010 TeX Users Group
  Copyright (C) `CopyYear.2002. Eitan M. Gurari
`<TeX4ht copyright`> */
import org.xml.sax.helpers.*;
import org.xml.sax.*;
import java.io.PrintWriter;

public class JsmlFilter extends XMLFilterImpl {
    PrintWriter out = null;
  public JsmlFilter( PrintWriter out, PrintWriter log, boolean trace ){
    this.out = out;
  }
  public void startElement(String ns, String sName,
                          String qName, Attributes attr) {
     try{
       if( `<elements for PARA?`> ){
         Attributes att = new AttributesImpl();
         super.startElement(ns, "PARA", "PARA", att);
       }
       super.startElement(ns, sName, qName, attr);
     } catch( Exception e ){
       System.out.println( "--- JsmlFilter Error 1 --- " + e);
  }  }
  public void endElement(String ns, String sName, String qName){
     try{
       super.endElement(ns, sName, qName);
       if( `<elements for PARA?`> ){
            super.endElement(ns, "PARA", "PARA");
       }
     } catch( Exception e ){
       System.out.println( "--- JsmlFilter Error 2 --- " + e);
}  }  }
>>>




\<elements for PARA?\><<<
  qName.equals( "p" )
|| qName.equals( "h2" )
|| qName.equals( "h3" )
|| qName.equals( "h4" )
|| qName.equals( "ul" )
|| qName.equals( "ol" )
|| qName.equals( "li" )
|| qName.equals( "dd" )
|| qName.equals( "dl" )
>>>


%%%%%%%%%%%%%
\subsection{Remove Split Arrays}
%%%%%%%%%%%%%

\<remove empty split entries\><<<
<script element="div::split-side" >
 <set name="clean-split" >
    `<open xslt script`>
    `<get content template`>
    `<clean math split`>
    `<close xslt script`>
 </set>
 <xslt name="." xml="." xsl="clean-split" />
</script>
>>>


\<clean math split\><<<
<xsl:template match=" div[ @class='split-side' ]
" >
   <xsl:variable name="content">
      <xsl:apply-templates select="*" mode="content" />
   </xsl:variable>
   <xsl:if test="
      string-length( normalize-space( $content )) != 0
   " >
      <xsl:copy>
         <xsl:apply-templates select=" *|@*|text()|comment() " />
      </xsl:copy>
   </xsl:if>
</xsl:template>
>>>


%%%%%%%%%%%%%
\section{Eliminate Inline Math Narrative}
%%%%%%%%%%%%%


%%%%%%%%%%%%%
\subsection{Core Content of  One Element}
%%%%%%%%%%%%%


\<eliminate inline math narrative NO\><<<
<xsl:template match="span[
   (@class = 'inline-math')
 and
   (count( `<math content element`> ) = 1)
]" >
 <xsl:copy>
   <xsl:choose>
      <xsl:when test="child::mfrac or child::msqrt
                   or child::mover or child::munder
      ">
         <xsl:attribute name="class">
            <xsl:text>semi-math</xsl:text>
         </xsl:attribute>
         <BREAK SIZE="small"/>
         <xsl:apply-templates
             select="`<math content element`>" />
      </xsl:when>
      <xsl:otherwise>
         `<non-adjacent narrative`>
      </xsl:otherwise>
   </xsl:choose>
 </xsl:copy>
</xsl:template>
>>>



\<non-adjacent narrative\><<<
<xsl:variable name="content">
  <xsl:apply-templates
      select="`<math content element`>"
        mode="content" />
</xsl:variable>
<xsl:choose>
  `<math narrative of length one`>
  `<math narrative of just one element`>
  `<simple sub or sup`>
  <xsl:otherwise>
     <xsl:apply-templates
                   select="*|@*|text()|comment()" />
  </xsl:otherwise>
</xsl:choose>
>>>





\<math content element\><<<
child::*[ not(@title = 'speech-extra')
         and not( self::BREAK )
       ]
>>>




\<math narrative of length one\><<<
<xsl:when test="
  string-length( normalize-space( $content )) = 1
" >
  <xsl:attribute name="class">
     <xsl:text>semi-math</xsl:text>
  </xsl:attribute>
  <xsl:apply-templates
             select="`<math content element`>" />
</xsl:when>
>>>

\<math narrative of just one element\><<<
<xsl:when test="
  not(`<math content element`>
       / descendant::* [
           count(child::*[
               not(self::BREAK)
           ] ) &gt; 1
         ] )
" >
  <xsl:attribute name="class">
     <xsl:text>semi-math</xsl:text>
  </xsl:attribute>
  <PROS PITCH="-5">
  <BREAK SIZE="small"/>
     <xsl:apply-templates
             select="`<math content element`>" />
  <BREAK SIZE="small"/>
  </PROS>
</xsl:when>
>>>


\<simple sub or sup\><<<
<xsl:when test="  child::*[
    (position() = 2)
  and
    (self::msub or self::msup or self::msubsup)
]" >
   <xsl:variable name="content">
      <xsl:apply-templates
          select="child::*[2] / child::*[
                  (@class = 'mrow-base')
               or (@class = 'limits-mrow-base') ]"
            mode="content" />
   </xsl:variable>
   <xsl:choose>
      <xsl:when test="
         string-length( normalize-space( $content )) = 1
        or
         (translate($content,'0123456789 ','') = '')
      " >
         <xsl:attribute name="class">
            <xsl:text>semi-math</xsl:text>
         </xsl:attribute>
         <PROS PITCH="-5">
         <BREAK SIZE="small"/>
            <xsl:apply-templates select="*[2]" />
         <BREAK SIZE="small"/>
         </PROS>
     </xsl:when>
      <xsl:otherwise>
         <xsl:apply-templates select="*|@*|text()" />
      </xsl:otherwise>
   </xsl:choose>
</xsl:when>
>>>


\begin{verbatim}
<span class="inline-math">
 <msub>
   <mrow class="mrow-base">
     <mi>C</mi>
   </mrow>
   <mrow class="mrow-sub">
     <mi>i</mi>
   </mrow>
 </msub>
</span>
\end{verbatim}




%%%%%%%%%%%%%
\subsection{Unary Op}
%%%%%%%%%%%%%

The `mo-unary' is established in the first pass over inline-math,
so we need to wait for the second pass with the following.


\<eliminate inline math narrative NO 2\><<<
<xsl:template match="span[
   (@class = 'inline-math')
 and
   (count( `<math content element`> ) = 2)
 and
   (  child::mo[
         (@class = 'mo-unary')
       and
         following-sibling::*[1]
         / self::mi
      ]
     or
      child::mi[
         following-sibling::*[1]
         [ (@class = 'MathClass-open-close')
           and
           not(child::*[2]
               / child::*[ not(self::BREAK) ]
               / child::*[ not(self::BREAK) ] )
      ]  ]
   )
]" >
 <xsl:copy>
   <xsl:choose>
      `<when func on shallow arg`>
      <xsl:otherwise>
         `<unary op on short content`>
      </xsl:otherwise>
   </xsl:choose>
 </xsl:copy>
</xsl:template>
>>>

\<when func on shallow arg\><<<
<xsl:when test="
  child::mrow[ @class = 'MathClass-open-close' ]
" >
  <xsl:attribute name="class">
     <xsl:text>semi-math</xsl:text>
  </xsl:attribute>
  <PROS PITCH="-5">
  <BREAK SIZE="small"/>
     <xsl:apply-templates
             select="`<math content element`>" />
  <BREAK SIZE="small"/>
  </PROS>
</xsl:when>
>>>

\<unary op on short content\><<<
<xsl:attribute name="class">
  <xsl:text>semi-math</xsl:text>
</xsl:attribute>
<PROS PITCH="-5">
<BREAK SIZE="small"/>
  <xsl:apply-templates
          select="`<math content element`>" />
<BREAK SIZE="small"/>
</PROS>
>>>



%%%%%%%%%%%%%
\subsection{Shallow Expression}
%%%%%%%%%%%%%


\<eliminate inline math narrative NO 2\><<<
<xsl:template match="span[
   (@class = 'inline-math')
 and
    not( child::*[
        not(self::mo)
        and not(self::mi)
        and not(self::mn)
        and not(self::mn-group-s)
        and not( @title='speech-extra' )
        and not( self::mfrac[
           preceding-sibling::*[1][self::mn ]
          ]
        )
        and not( self::msub
                 / child::*[1][
                      child::mo[ @class = 'MathClass-op' ]
                      and
                      not(child::*[2])
                   ]
        )
    ]  )
]" >
 <xsl:copy>
   `<shallow expression`>
 </xsl:copy>
</xsl:template>
>>>

\<shallow expression\><<<
<xsl:attribute name="class">
  <xsl:text>semi-math</xsl:text>
</xsl:attribute>
<PROS PITCH="-5">
<BREAK SIZE="small"/>
  <xsl:apply-templates
          select="`<math content element`> | text()" />
<BREAK SIZE="small"/>
</PROS>
>>>




%%%%%%%%%%%%%
\subsection{Shallow Delimited Expression}
%%%%%%%%%%%%%


\<eliminate inline math narrative NO 2\><<<
<xsl:template match="span[
   (@class = 'inline-math')
 and
   (count( `<math content element`> ) = 1)
 and
   child::mrow[ @class='MathClass-open-close' ]
   / child::mrow[
      not( child::*[
        not(self::mo) and not(self::mn-group-s)
        and not(self::mi) and not(self::BREAK)
        and not( @title='speech-extra' )
      ])
   ]
]" >
 <xsl:copy>
   `<shallow delimited expression`>
 </xsl:copy>
</xsl:template>
>>>

\<shallow delimited expression\><<<
<xsl:attribute name="class">
  <xsl:text>semi-math</xsl:text>
</xsl:attribute>
<PROS PITCH="-5">
<BREAK SIZE="small"/>
  <xsl:apply-templates select="mrow" />
<BREAK SIZE="small"/>
</PROS>
>>>



%%%%%%%%%%%%%%%%%%
\section{Superscripts and Subscripts}
%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%
\subsection{Insert Sub-Levels Info}
%%%%%%%%%%%%%




\<set levels for sub and sup scripts\><<<
<dom name="." xml="." method="scriptLevel" class="tex4ht.HtJsml" />
`<remove xml declaration`>
>>>



\<static void scriptLevel(dom)\><<<
public static void scriptLevel(Node dom) {
  setScriptLevel(dom.getFirstChild(), "");
}
private static void setScriptLevel(Node node, String prefix) {
 String clName = null;
 if (node.hasChildNodes()) {
   if (node.hasAttributes()) {
     Node cl = node.getAttributes().getNamedItem("class");
     if (cl != null) {
       clName = cl.getNodeValue();
       if( clName.equals("mrow-sub")
           ||
           clName.equals("mrow-super")
       ){
         `<append script prefix`>
   } } }
   String ndName = node.getNodeName();
   if(
     ndName.equals("msqrt")
     ||
     ndName.equals("mroot")
   ){  prefix = ""; }
   `<script invoke children`>
} }
>>>

\<script invoke children\><<<
NodeList children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
  Node child = children.item(i);
  if (child.getNodeType() == Node.ELEMENT_NODE) {
     setScriptLevel(child, prefix);
}  }
>>>

\<append script prefix\><<<
if( !prefix.equals("") ){
 `<use current script prefix`>
}
if( clName.equals( "mrow-sub" ) ){
   prefix += " sub ";
} else if( clName.equals( "mrow-super" ) ){
   prefix += " super ";
}
>>>


\<use current script prefix\><<<
Node child = node.getFirstChild();
if( (child.getNodeType() == Node.ELEMENT_NODE)
   &&
   child.hasAttributes()
){
  Node cls = child.getAttributes().getNamedItem("class");
  if (cls != null) {
     String clsName = cls.getNodeValue();
     if ( clsName.equals("begin-script")
          ||
          clsName.equals("mid-script")
     ) {
        child = child.getFirstChild();
        String s = child.getNodeValue();
        ((org.w3c.dom.Text) child).setData( prefix + s );
}  }  }
>>>



%%%%%%%%%%%%%
\subsection{Eliminate  End Script Marks}
%%%%%%%%%%%%%


The following takes care of end-scripts that semantically can be
merged into other end markers.

\<eliminate baseline script marks\><<<
<xsl:template match="span[
  (@class = 'end-script')
  and
  ancestor::* [ following-sibling::* [
                        not( @class = 'content-less' )
                     ]
              ][1]
          / following-sibling::* [
                        not( @class = 'content-less' )
                    ][1]
          / self::*
   [
      (@class = 'end-math')
      or
      (@class = 'end-script')
      or
      (@class = 'end-root')
      or
      (@class = 'end-stack')
      or
      (@class = 'mid-stack')
      or
      (@class = 'end-array')
      or
       self::td or self::mtd or self::tr or self::mtr
      or
      (@title = 'implicit-baseline')
   ]
]"  >
 <BREAK SIZE="small"/>
</xsl:template>
>>>






The following deals with endscripts before left sides of
tensors.



\<eliminate baseline script marks\><<<
<xsl:template match="span[
  (@class = 'end-script')
  and
   parent::mrow / parent::msub
  and
  ancestor::* [ following-sibling::* ][1]
  / following-sibling::* [ normalize-space(.) != '' ][1]
   [
      (self::msub or self::msubsup)
    and
      (normalize-space(child::mrow[
         @class = 'mrow-base' ]) = '')
   ]
]"  >
 <BREAK SIZE="small"/>
</xsl:template>
>>>



\<eliminate baseline script marks\><<<
<xsl:template match="span[
  (@class = 'end-script')
  and
    parent::mrow /parent::*[ self::msup or self::msubsup]
  and
  ancestor::* [ following-sibling::* ][1]
  / following-sibling::* [ normalize-space(.) != '' ][1]
   [
      self::msup
    and
      (normalize-space(child::mrow[
         @class = 'mrow-base' ]) = '')
   ]
]"  >
 <BREAK SIZE="small"/>
</xsl:template>
>>>








\begin{verbatim}
   <span class="end-script" title="speech-extra">
     <PROS PITCH="-5">
       <BREAK SIZE="medium"/>
       <span class="scripts-extra"> baseline </span>
       <BREAK SIZE="small"/>
     </PROS>
   </span>
 </mrow>
</msup>
<span class="tiny-space"/>
<msup>
 <mrow class="mrow-base"/>
 <mrow class="mrow-super">

\end{verbatim}

%%%%%%%%%%%%%
\subsection{Clean Script Marks}
%%%%%%%%%%%%%


\<clean begin and mid script marks\><<<
<xsl:template match="span[
  (@class = 'begin-script')
  or (@class = 'mid-script')
]" >
 <xsl:copy>
    <xsl:apply-templates select="@*" />
    <xsl:apply-templates select="*|text()|comment()"
                         mode="clean-script" />
 </xsl:copy>
</xsl:template>
<xsl:template match="*"  mode="clean-script" >
 <xsl:copy>
    <xsl:apply-templates select="@*" />
    <xsl:apply-templates select="*|text()|comment()"
                         mode="clean-script" />
 </xsl:copy>
</xsl:template>
<xsl:template match="text()"  mode="clean-script" >
</xsl:template>
<xsl:template match="span[@class = 'scripts-extra']"
              mode="clean-script" >
 <xsl:copy>
    <xsl:apply-templates select="@*" />
    <xsl:value-of select="
       ancestor::span[
         (@class = 'begin-script')
          or (@class = 'mid-script') ] [1]
     " />
 </xsl:copy>
</xsl:template>
>>>

The following is for script annotation on empty msu::base.

\<remove marks on empty scripts\><<<
<xsl:template match="span[
    ((@class = 'begin-script') or (@class = 'mid-script'))
  and
    following-sibling::*
    / following-sibling::span[ @class = 'end-script' ]
  and
    following-sibling::*[1]
    / descendant-or-self::*[ not(self::PROS) ][1]
    / child::*[1][
          (@class = 'mrow-base')
        and
          (normalize-space(.)='')
      ]
]" >
</xsl:template>
>>>

\begin{verbatim}
<span class="begin-script" title="speech-extra">
 ...
</span>
<PROS PITCH="+10">
 <msub>
   <mrow class="mrow-base"/>
   <mrow class="mrow-sub">
     ...
   </mrow>
 </msub>
 <mi>n</mi>
</PROS>
<span class="end-script" title="speech-extra">
 ...
\end{verbatim}



%%%%%%%%%%%%%
\subsection{Replace Nested Baseline Script Marks}
%%%%%%%%%%%%%


\<replace nested baseline script marks\><<<
<xsl:template match="span[
    (@class = 'end-script')
  and
    ancestor::*[ preceding-sibling::* [
      ((@class = 'begin-script') or (@class = 'mid-script')) ]]
]" >
 <xsl:copy>
    <xsl:apply-templates select="@*" />
    <xsl:apply-templates select="
           ancestor::*[ preceding-sibling::* [
                          ((@class = 'begin-script') or
                           (@class = 'mid-script'))     ]][1]
           / preceding-sibling::* [
                          ((@class = 'begin-script') or
                           (@class = 'mid-script'))  ][1]
     "  mode="script-copy" />
 </xsl:copy>
</xsl:template>
>>>



\<replace nested baseline script marks\><<<
<xsl:template match="*|@*|text()|comment()"
              mode="script-copy" >
 <xsl:copy>
    <xsl:apply-templates select="*|@*|text()|comment()" />
 </xsl:copy>
</xsl:template>
<xsl:template match="span[
    (@class = 'begin-script') or
    (@class = 'mid-script')       ]"  mode="script-copy" >
  <xsl:apply-templates select="*|text()|comment()" />
</xsl:template>
>>>


%%%%%%%%%%%%%
\subsection{Eliminate  Begin Script Marks}
%%%%%%%%%%%%%



\<eliminate begin script marks\><<<
<xsl:template match="span[
    (@class = 'begin-script')
  and
    following-sibling::* [1] / child::*[
      (position() = 1)
      and
      (@class = 'mrow-base')
      and
      ( normalize-space(.) = '' )
    ]
]"  >
</xsl:template>
>>>



%%%%%%%%%%%%%
\subsection{Undo Empty Scripts}
%%%%%%%%%%%%%




\<special sub and super scripts\><<<
<script element="msup" >
  <set name="m-sub-sup" >
    `<open xslt script`>
    `<undo if empty su`>
    `<close xslt script`>
  </set>
  <xslt name="." xml="." xsl="m-sub-sup" />
  `<superscript 2 and 3 into verbose`>
</script>
<script element="msub" >
 `<sub script`>
</script>
<script element="msubsup" >
 `<subsup prime`>
 `<sub sup script`>
 `<sub superscript 2 and 3 into verbose`>
</script>
>>>

\<sub sup script\><<<
<set name="m-sub-sup" >
 `<open xslt script`>
 `<undo if empty su`>
 `<close xslt script`>
</set>
<xslt name="." xml="." xsl="m-sub-sup" />
>>>



\<sub script\><<<
<set name="m-sub-sup" >
 `<open xslt script`>
 `<undo if empty su`>
 `<msub of log`>
 `<close xslt script`>
</set>
<xslt name="." xml="." xsl="m-sub-sup" />
>>>

\<undo if empty su\><<<
<xsl:template match="*[
   (self::msup or self::msub or self::msubsup)
 and
   not(
       child::mrow[ @class = 'mrow-sub' ]
       / child::*[ not(@title = 'speech-extra')
                   and
                   (normalize-space(.) != '')
                 ]
   )
 and
   not(
       child::mrow[ @class = 'mrow-super' ]
       / child::*[ not(@title = 'speech-extra')
                   and
                   (normalize-space(.) != '')
                 ]
   )
]" >
  <xsl:apply-templates select="child::mrow[
                         @class = 'mrow-base' ]/*" />
</xsl:template>
>>>



\begin{verbatim}
<msup>
  <mrow class="mrow-base">
    .........
  </mrow>
  <wrow class="mrow-super">
    <span class="begin-script"> superscript </span>
    <span class="end-script"> baseline </span>
  </mrow>
</msup>
\end{verbatim}




%%%%%%%%%%%%%
\section{Special Subscripts and Superscripts}
%%%%%%%%%%%%%

%%%%%%%%%%%%%
\subsection{Squared}
%%%%%%%%%%%%%



\<superscript 2 and 3 into verbose\><<<
<set name="m-sup-2-3" >
 `<open xslt script`>
 `<superscript into squared and cube`>
 `<close xslt script`>
</set>
<xslt name="." xml="." xsl="m-sup-2-3" />
>>>

\<superscript into squared and cube\><<<
<xsl:template match="msup[
   (normalize-space(
     child::mrow[ (@class = 'mrow-super') ]
       / child::*[ not (@class = 'begin-script')
                   and
                   not (@class = 'end-script')
                 ]
    ) = '2')
 and `<su verbose not on op`>
 and (normalize-space(mrow[@class = 'mrow-base']) != '' )
]" >
  <xsl:copy>
     <xsl:apply-templates select="*|@*|text()|comment()"
                          mode="squared" />
  </xsl:copy>
</xsl:template>
>>>


\<su verbose not on op\><<<
not(
 child::mrow[ @class = 'mrow-base' ]
   / child::span[ not( @title = 'speech-extra' ) ]
                [ position() = last() ]
   / self::* [ @class = 'mo-op' ]
)
>>>




\<superscript into squared and cube\><<<
<xsl:template match="*|@*|text()|comment()"
                          mode="squared" >
  <xsl:copy>
    <xsl:choose>
       <xsl:when test=" @class = 'mrow-super' ">
          <xsl:apply-templates select="@*" />
          <mo class="mo-op">
            <xsl:text> squared </xsl:text>
          </mo>
      </xsl:when>
       <xsl:otherwise>
          <xsl:apply-templates select="*|@*|text()" />
       </xsl:otherwise>
    </xsl:choose>
  </xsl:copy>
</xsl:template>
>>>






\begin{verbatim}
<msup>
 <mrow class="mrow-base">
   <mo class="mo-op">cos</mo>
 </mrow>
 <mrow class="mrow-super">
   <span class="begin-script"> superscript </span>
   <span class="mn">2</span>
   <span class="end-script"> baseline </span>
 </mrow>
</msup>
\end{verbatim}




\<superscript into squared and cube\><<<
<xsl:template match="msup[
   (normalize-space(
     child::mrow[ (@class = 'mrow-super') ]
       / child::*[ not (@class = 'begin-script')
                   and
                   not (@class = 'end-script')
                 ]
    ) = '3')
 and `<su verbose not on op`>
 and (normalize-space(mrow[@class = 'mrow-base']) != '' )
]" >
  <xsl:copy>
     <xsl:apply-templates select="*|@*|text()|comment()"
                          mode="cube" />
  </xsl:copy>
</xsl:template>
>>>



\<superscript into squared and cube\><<<
<xsl:template match="*|@*|text()|comment()"
                          mode="cube" >
  <xsl:copy>
    <xsl:choose>
       <xsl:when test=" @class = 'mrow-super' ">
          <xsl:apply-templates select="@*" />
          <mo class="mo-op">
            <xsl:text> cube </xsl:text>
          </mo>
       </xsl:when>
       <xsl:otherwise>
          <xsl:apply-templates select="*|@*|text()" />
       </xsl:otherwise>
    </xsl:choose>
  </xsl:copy>
</xsl:template>
>>>


\<sub superscript 2 and 3 into verbose\><<<
<set name="m-subsup-2-3" >
 `<open xslt script`>
 `<subsup into sub squared and cube`>
 `<close xslt script`>
</set>
<xslt name="." xml="." xsl="m-subsup-2-3" />
>>>





\<subsup into sub squared and cube\><<<
<xsl:template match="msubsup[
   (normalize-space(
     child::mrow[ (@class = 'mrow-super') ]
       / child::span[ (@class != 'mid-script')
                      and
                      (@class != 'end-script')
                    ]
    ) = '2')
 and `<su verbose not on op`>
]" >
  <xsl:copy>
     <xsl:attribute name="class" >
        <xsl:text>msub</xsl:text>
     </xsl:attribute>
     <xsl:apply-templates select="*|text()|comment()"
                          mode="sub-squared" />
  </xsl:copy>
</xsl:template>
>>>



\<subsup into sub squared and cube\><<<
<xsl:template match="*|@*|text()|comment()"
                          mode="sub-squared" >
  <xsl:copy>
    <xsl:choose>
       <xsl:when test=" @class = 'mrow-sub' ">
          <xsl:apply-templates select="*[
                      not( @class = 'end-script' )
                    ]
                          |@*|text()|comment()" />
          <xsl:apply-templates select="
              following-sibling::*[1] / *[
                       @class = 'end-script'
                 ] " />
       </xsl:when>
       <xsl:when test=" @class = 'mrow-super' ">
          <xsl:attribute name="class" >
              <xsl:text>squared-super</xsl:text>
          </xsl:attribute>
          <mo class="mo-op">
            <xsl:text> squared </xsl:text>
          </mo>
       </xsl:when>
       <xsl:otherwise>
          <xsl:apply-templates select="*|@*|text()|comment()" />
       </xsl:otherwise>
    </xsl:choose>
  </xsl:copy>
</xsl:template>
>>>


\<subsup into sub squared and cube\><<<
<xsl:template match="msubsup[
   (normalize-space(
     child::mrow[ (@class = 'mrow-super') ]
       / child::span[ (@class != 'mid-script')
                      and
                      (@class != 'end-script')
                    ]
    ) = '3')
 and `<su verbose not on op`>
]" >
  <xsl:copy>
     <xsl:attribute name="class" >
        <xsl:text>msub</xsl:text>
     </xsl:attribute>
     <xsl:apply-templates select="*|text()|comment()"
                          mode="sub-cube" />
  </xsl:copy>
</xsl:template>
>>>



\<subsup into sub squared and cube\><<<
<xsl:template match="*|@*|text()|comment()"
                          mode="sub-cube" >
  <xsl:copy>
    <xsl:choose>
       <xsl:when test=" @class = 'mrow-sub' ">
          <xsl:apply-templates select="*[
                      not( @class = 'end-script' )
                    ]
                          |@*|text()|comment()" />
          <xsl:apply-templates select="
              following-sibling::*[1] / *[
                       @class = 'end-script'
                 ] " />
       </xsl:when>
       <xsl:when test=" @class = 'mrow-super' ">
          <xsl:attribute name="class" >
              <xsl:text>cube-super</xsl:text>
          </xsl:attribute>
          <mo class="mo-op">
            <xsl:text> cube </xsl:text>
          </mo>
       </xsl:when>
       <xsl:otherwise>
          <xsl:apply-templates select="*|@*|text()|comment()" />
       </xsl:otherwise>
    </xsl:choose>
  </xsl:copy>
</xsl:template>
>>>



%%%%%%%%%%%%%
\subsection{Numeric Subscripts (Rule 77)}
%%%%%%%%%%%%%

\<compress numeric subscripts\><<<
 <set name="num-sub" >
    `<open xslt script`>
    `<num sub`>
    `<close xslt script`>
 </set>
 <xslt name="." xml="." xsl="num-sub" />
>>>



\<num sub\><<<
<xsl:template match="msub[
 (
   `<num sub on non-primed base`>
   or
   `<num sub on primed base`>
 )
 and
   child::mrow[ @class = 'mrow-sub' ]
   / child::*[ not(@title = 'speech-extra') ][1]
   / self::*[
         normalize-space(.)
         = normalize-space( descendant::mn ) ]
]" >
 <xsl:copy>
    <xsl:apply-templates select="@*" />
    <BREAK SIZE="small"/>
    <xsl:apply-templates select="*[1]" />
    <mrow class="mrow-sub">
       <xsl:apply-templates
          select="*[2] / *[
                   not(@title = 'speech-extra')
         ]" />
       <BREAK SIZE="small"/>
    </mrow>
 </xsl:copy>
</xsl:template>
>>>

\<num sub on non-primed base\><<<
(count( child::mrow[ @class = 'mrow-base' ]
          / child::* ) = 1 )
 and child::mrow[ @class = 'mrow-base' ] / descendant::mi
 and not( ancestor::*[
     self::msub or self::msup or self::msubsup
   ] )
>>>

\<num sub on primed base\><<<
(
 count( child::mrow[ @class = 'mrow-base' ]
       / child::* [
         not(self::BREAK)
       ]
 ) = 2 )
 and child::mrow[ @class = 'mrow-base' ] [
        child::*[1][ self::mi ]
        and
        child::*[
          (position() &gt; 1)
          and
          (normalize-space(.) =
           normalize-space(
              descendant-or-self::span[
                 (@class = 'ch 2032') or (@class = 'ch 2033')
                                or (@class = 'ch 2034')
              ]
           ))
        ]
     ]
  and not( ancestor::*[
     self::msub or self::msup or self::msubsup
   ] )
>>>

\begin{verbatim}
<msub>
 <mrow class="mrow-base">
   <mi>x</mi>
 </mrow>
 <mrow class="mrow-sub">
   <span class="begin-script" title="speech-extra"> subscript </span>
   <mn>1</mn>
   <span class="end-script" title="speech-extra"> baseline </span>
 </mrow>
</msub>
\end{verbatim}



\<num sub\><<<
<xsl:template match="msubsup[
 (
   `<num sub on non-primed base`>
 )
 and
   child::mrow[ @class = 'mrow-sub' ]
   / child::*[ not(@title = 'speech-extra') ][1]
   / self::*[
         normalize-space(.)
         = normalize-space( descendant::mn ) ]
]" >
 <msup>
    <BREAK SIZE="small"/>
    <xsl:apply-templates select="*[1]" />
    <mrow class="mrow-sub">
       <xsl:apply-templates
          select="*[2] / *[
                   not(@title = 'speech-extra')
         ]" />
       <BREAK SIZE="small"/>
    </mrow>
    <xsl:apply-templates select="*[3]" />
 </msup>
</xsl:template>
>>>

%%%%%%%%%%%%%
\subsection{Primes}
%%%%%%%%%%%%%

\<remove scrip indicators from primes\><<<
<xsl:template match="span[
   (@class = 'begin-script')
 and
   following-sibling::*[ not(@title = 'speech-extra') ] [1]
   / descendant-or-self::*[ not( self::PROS ) ][1]
   /
        child::span / child::span[
           (@class = 'ch 2032') or (@class = 'ch 2033')
                                or (@class = 'ch 2034')
   ]
]" >
 <BREAK SIZE="small"/>
</xsl:template>
>>>


\<remove scrip indicators from primes\><<<
<xsl:template match="span[
   (@class = 'end-script')
 and
   preceding-sibling::*[ not(@title = 'speech-extra') ] [1]
   / descendant-or-self::*[ not( self::PROS ) ][1]
   /
        child::span / child::span[
           (@class = 'ch 2032') or (@class = 'ch 2033')
                                or (@class = 'ch 2034')
   ]
]" >
 <BREAK SIZE="small"/>
</xsl:template>
>>>



\begin{verbatim}
<span class="msup">
 <span class="mrow-base">
   <span class="mi">x</span>
 </span>
 <span class="mrow-super">
   <span class="begin-script"> superscript </span>
   <span class="mo-op">
     <span class="char">
       <span class="ch 2033">double prime</span>
     </span>
   </span>
   <span class="end-script"> baseline </span>
 </span>
</span>
\end{verbatim}

\<subsup prime\><<<
<set name="subsup-prime" >
  `<open xslt script`>
  `<compress subsup prime`>
  `<close xslt script`>
</set>
<xslt name="." xml="." xsl="subsup-prime" />
>>>


\<compress subsup prime\><<<
<xsl:template match="msubsup[
   (count(
       child::mrow [ @class='mrow-super' ]
      / child::* [ not(@title = 'speech-extra') ]
   ) = 1)
 and
   not(
       child::mrow [ @class='mrow-super' ]
      / child::* [ not(@title = 'speech-extra') ]
      / descendant::*[ preceding-sibling::*
                       or following-sibling::*]
   )
 and
   child::mrow [ @class='mrow-super' ]
      / child::* [ not(@title = 'speech-extra') ]
      / descendant-or-self::span[ @class='char' ]
      / child::span[
           (@class = 'ch 2032') or (@class = 'ch 2033')
                                or (@class = 'ch 2034')
        ]
]" >
 <msub>
   <mrow class="mrow-base">
      <xsl:apply-templates select="
            child::mrow[@class = 'mrow-base'] / *
         " />
      <BREAK SIZE="small"/>
      <xsl:apply-templates select="
            child::mrow[@class = 'mrow-super']
            / child::* [ not(@title = 'speech-extra') ]
         " />
   </mrow>
   <mrow class="mrow-sub">
      <xsl:apply-templates
            select="*[@class = 'mrow-sub'] /* " />
      <xsl:apply-templates select="
            child::mrow[@class = 'mrow-super']
            / child::* [ @class = 'end-script' ]
         " />
   </mrow>
 </msub>
</xsl:template>
>>>



\begin{verbatim}
<span class="msubsup">
 <span class="mrow-base">
   <span class="mi">x</span>
 </span>
 <span class="mrow-sub">
   ......
 </span>
 <span class="mrow-super">
   <span class="mid-script" title="speech-extra"> superscript </span>
   <span class="mi">
     <span class="char" title="ch-verbose">
       <span class="ch 2032" title="ch-verbose">prime</span>
     </span>
   </span>
 </span>
</span>
\end{verbatim}



%%%%%%%%%%%%%
\subsection{Degree}
%%%%%%%%%%%%%

\<remove scrip indicators from degree\><<<
<xsl:template match="mrow[
  (@class = 'mrow-super')
 and
   parent::msup
 and
   (count( `<math content element`> ) = 1)
 and
   `<math content element`> [1][
      normalize-space(.)
      =
      normalize-space(
         descendant::span[@class = 'ch 2218']
      )
   ]
]" >
 <xsl:copy>
   <xsl:apply-templates select="@*" />
   <xsl:apply-templates
         select="*[not(@title = 'speech-extra')
                   and
                   not(self::BREAK)
                  ]"
                          mode="degree" />
   <BREAK SIZE="small"/>
 </xsl:copy>
</xsl:template>
>>>

\<remove scrip indicators from degree\><<<
<xsl:template match="*" mode="degree" >
 <xsl:copy>
   <xsl:apply-templates select="@*" />
   <xsl:choose>
      <xsl:when test="self::span[ @class='ch 2218' ]" >
        <xsl:text>degree</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates
               select="*[not(self::BREAK)]|text()"
               mode="degree"/>
      </xsl:otherwise>
   </xsl:choose>
  </xsl:copy>
</xsl:template>
>>>





%%%%%%%%%%%%%
\subsection{Logarithms}
%%%%%%%%%%%%%

\<msub of log\><<<
<xsl:template match="
  msub [
   normalize-space(child::*[1]) = 'log'
  or
   normalize-space(child::*[1]) = 'ln'
]" >
 <xsl:copy>
   <xsl:apply-templates select="@*" />
   <xsl:apply-templates select="child::*[1]" />
   <xsl:apply-templates select="child::*[2]"
                        mode="log" />
 </xsl:copy>
</xsl:template>
>>>

\<msub of log\><<<
<xsl:template match="*" mode="log" >
 <xsl:copy>
   <xsl:apply-templates select="@*" />
   <xsl:choose>
      <xsl:when test="parent::mrow[ @class = 'mrow-sub' ]" >
        <BREAK SIZE="small"/>
        <xsl:apply-templates select="*" />
        <BREAK SIZE="small"/>
        <span title="speech-extra">
            <xsl:text>of</xsl:text>
        </span>
        <BREAK SIZE="small"/>
      </xsl:when>
      <xsl:otherwise>
         <xsl:apply-templates
                select="*[ not(@title = 'speech-extra') ]"
                mode="log" />
      </xsl:otherwise>
   </xsl:choose>
  </xsl:copy>
</xsl:template>
>>>

\begin{verbatim}
<msub>
 <mrow class="mrow-base">
   <mo class="MathClass-op">log<BREAK SIZE="small"/></mo>
 </mrow>
 <mrow class="mrow-sub">
   <span class="begin-script" title="speech-extra">
     ...
   </span>
   <PROS PITCH="-10">
     <mn>2</mn>
   </PROS>
   <span class="end-script" title="speech-extra">
     ...
   </span>
 </mrow>
</msub>
<mi>x</mi>
\end{verbatim}


%%%%%%%%%%%%%%%%%%
\section{Fractions (Stage 1)}
%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%
\subsection{Outline}
%%%%%%%%%%%%%



\<span frac elements\><<<
<script element="mfrac" >
 <set name="mfrac" >
    `<open xslt script`>
    `<frac templates`>
    `<close xslt script`>
 </set>
 <xslt name="." xml="." xsl="mfrac" />
</script>
>>>

\<frac templates\><<<
<xsl:template match="mfrac" >
 <xsl:copy>
   <xsl:choose>
      `<word fracs`>
      `<prepend continued fractions`>
      `<tail continued fractions`>
      <xsl:otherwise>
        <xsl:apply-templates select="*|@*|text()|comment()" />
      </xsl:otherwise>
   </xsl:choose>
 </xsl:copy>
</xsl:template>
>>>


%%%%%%%%%%%%%
\subsection{Word Fractions}
%%%%%%%%%%%%%

Example: `\verb+1 \ove 2+' int `one half'

\<word fracs\><<<
<xsl:when test="
  (string-length(
     normalize-space(child::mrow[ @class = 'mrow-numerator' ][1])
    ) = 1)
  and
  (string-length(
    normalize-space(child::mrow[ @class = 'mrow-enumerator' ][1])
    ) = 1)
">
  `<a := numerator; b := enumerator`>
  <xsl:choose>
     <xsl:when test="
          (translate($a,'123456789','') != '')
          or
          (translate($b,'123456789','') != '')
      " >
        <xsl:apply-templates select="*|@*|text()|comment()" />
     </xsl:when>
     <xsl:when test=" $a &lt; $b ">
        <xsl:attribute  name="class">
            <xsl:text>word-frac</xsl:text>
        </xsl:attribute>
        `<word numerator`>
        `<word enumerator`>
     </xsl:when>
     <xsl:otherwise>
        <xsl:apply-templates select="*|@*|text()|comment()" />
     </xsl:otherwise>
  </xsl:choose>
</xsl:when>
>>>


\<a := numerator; b := enumerator\><<<
<xsl:variable name="a">
  <xsl:value-of select="
     normalize-space(child::mrow[ @class = 'mrow-numerator' ][1])
  " />
</xsl:variable>
<xsl:variable name="b">
  <xsl:value-of select="
     normalize-space(child::mrow[ @class = 'mrow-enumerator' ][1])
  " />
</xsl:variable>
>>>


\<word numerator\><<<
<xsl:choose>
  <xsl:when test=" $a = 1 "><xsl:text> one </xsl:text></xsl:when>
  <xsl:when test=" $a = 2 "><xsl:text> two </xsl:text></xsl:when>
  <xsl:when test=" $a = 3 "><xsl:text> three </xsl:text></xsl:when>
  <xsl:when test=" $a = 4 "><xsl:text> four </xsl:text></xsl:when>
  <xsl:when test=" $a = 5 "><xsl:text> five </xsl:text></xsl:when>
  <xsl:when test=" $a = 6 "><xsl:text> six </xsl:text></xsl:when>
  <xsl:when test=" $a = 7 "><xsl:text> seven </xsl:text></xsl:when>
  <xsl:when test=" $a = 8 "><xsl:text> eight </xsl:text></xsl:when>
  <xsl:when test=" $a = 9 "><xsl:text> nine </xsl:text></xsl:when>
</xsl:choose>
>>>


\<word enumerator\><<<
<xsl:choose>
  <xsl:when test=" $b = 2 "><xsl:text> half</xsl:text></xsl:when>
  <xsl:when test=" $b = 3 "><xsl:text> third</xsl:text></xsl:when>
  <xsl:when test=" $b = 4 "><xsl:text> fourth</xsl:text></xsl:when>
  <xsl:when test=" $b = 5 "><xsl:text> fifth</xsl:text></xsl:when>
  <xsl:when test=" $b = 6 "><xsl:text> sixth</xsl:text></xsl:when>
  <xsl:when test=" $b = 7 "><xsl:text> seventh</xsl:text></xsl:when>
  <xsl:when test=" $b = 8 "><xsl:text> eighth</xsl:text></xsl:when>
  <xsl:when test=" $b = 9 "><xsl:text> nineth</xsl:text></xsl:when>
</xsl:choose>
<xsl:if test=" $a &gt; 1 "><xsl:text>s</xsl:text></xsl:if>
<xsl:text> </xsl:text>
>>>



%%%%%%%%%%%%%
\subsection{Mixed Fractions}
%%%%%%%%%%%%%

Examples: `\verb+2{3\over 4}+'
into `2 and three forth',
and `\verb+10{25\over 39}+' into `10 and 25 over 39'.

\<mixed fractions\><<<
<xsl:template match="mfrac[
  (
     (translate(
        concat(
          mrow[ (@class = 'mrow-numerator')],
          mrow[ (@class = 'mrow-enumerator')]
        )  ,'0123456789','') = '')
     and
        not(descendant::*/descendant::*
                         /descendant::mn-group-s)
     or
        (@class = 'word-frac')
  )
  and
    preceding-sibling::*[1]
      / self::mn-group-s[ child::*[
           (position() = last())
           and
           self::mn
        ] ]
]" >
 <xsl:text> and </xsl:text>
 <xsl:copy>
   <xsl:apply-templates select="*|@*|text()|comment()" />
 </xsl:copy>
</xsl:template>
>>>




%%%%%%%%%%%%%
\subsection{Continued Fractions Conditions (Rule 69)}
%%%%%%%%%%%%%



\begin{verbatim}
         1
1 + ---------------------------------------
             1
   2 + ---------------------------------------
                 1
       2 + ---------------------------------------
             2 + ...
\end{verbatim}


The fractions are processed recusrively from inside out.  The `tail'
is the one to discover the inner most part of a continued fraction
(i.e., the bottom rows).  Higher levels add to the nucleous built
already under them.

In Stage 1 the members of the continued fractions are marked as
such. In the second stage they being are procesed.


The minimum conditions here are three un-interrupted levels of
fractions.

\begin{verbatim}
<mfrac>
  <mrow class="mrow-enumerator">
     <mn>1</mn>
     <mo class="MathClass-bin">...</mo>
     <mfrac>
       <span class="begin-end" ...>begin fraction</span>
       <mrow class="mrow-numerator"> ... </mrow>
       <span class="begin-end" ...>over</span>
       <mrow class="mrow-enumerator">...</mrow>
       <span class="begin-end" ...>end fraction</span>
     </mfrac>
\end{verbatim}

\<a,b := top 2 pre op values\><<<
<xsl:variable name="a">
  <xsl:apply-templates select="
        child::mrow[ @class = 'mrow-enumerator' ] /
        child::mfrac /
        preceding-sibling::*[2]
  "  mode="enum-op" />
</xsl:variable>
<xsl:variable name="b">
  <xsl:apply-templates select="
        child::mrow[ @class = 'mrow-enumerator' ] /
        child::mfrac /
        child::mrow[ @class = 'mrow-enumerator' ] /
        child::mfrac /
        preceding-sibling::*[2]
  "  mode="enum-op" />
</xsl:variable>
<xsl:variable name="c">
  <xsl:value-of select="
   normalize-space(
     child::mrow[ @class = 'mrow-enumerator' ] /
     child::mfrac /
     child::mrow[ @class = 'mrow-enumerator' ] /
     child::mfrac /
     child::mrow[ @class = 'mrow-enumerator' ] )
  "  />
</xsl:variable>
>>>

\<frac templates\><<<
<xsl:template match="*" mode="enum-op">
  <xsl:if test="preceding-sibling::*" >
     <xsl:apply-templates select=" preceding-sibling::*[1] " />
  </xsl:if>
  <xsl:value-of select="." />
</xsl:template>
>>>





%%%%%%%%%%%%%
\subsection{Nucleous of Continued Fractions}
%%%%%%%%%%%%%

We are looking for the three most internal (bottom) fractions that
belong to a continued fraction.


\<tail continued fractions\><<<
<xsl:when test="          `%check numeral numerator`%
  (translate(
     normalize-space(
     child::mrow[ @class = 'mrow-numerator' ]),
                             '0123456789','')= '')
  and `<check equality of numerators`>
  and `<check ops before two top fracs`>
">
 `<a,b := top 2 pre op values`>
 <xsl:choose>
    <xsl:when test="
        ( translate($a,'0123456789 ','') = '')
        and (normalize-space($a)=normalize-space($b))
        and starts-with( $c, normalize-space( $a ))
        and starts-with(
              normalize-space(
                substring-after( $c, normalize-space( $a )) )
              ,
              normalize-space(
                   child::mrow[ @class = 'mrow-enumerator' ] /
                   child::mfrac /
                   preceding-sibling::*[1]                  )
            )
    " >
        <xsl:attribute name="class">
           <xsl:value-of select=" 'continued-mfrac' " />
        </xsl:attribute>
        <xsl:apply-templates select="*|text()|comment()" />
    </xsl:when>
    <xsl:otherwise>
        <xsl:apply-templates select="*|@*|text()|comment()" />
    </xsl:otherwise>
 </xsl:choose>
</xsl:when>
>>>





\<check equality of numerators\><<<
(  normalize-space(
  child::mrow[ @class = 'mrow-numerator' ])
 and
  normalize-space(
  child::mrow[ @class = 'mrow-enumerator' ] /
  child::mfrac /
  child::mrow[ @class = 'mrow-numerator' ])
)
and
(  normalize-space(
  child::mrow[ @class = 'mrow-enumerator' ] /
  child::mfrac /
  child::mrow[ @class = 'mrow-numerator' ])
 and
  normalize-space(
  child::mrow[ @class = 'mrow-enumerator' ] /
  child::mfrac /
  child::mrow[ @class = 'mrow-enumerator' ] /
  child::mfrac /
  child::mrow[ @class = 'mrow-numerator' ])
)
>>>



\<check ops before two top fracs\><<<
(  child::mrow[ @class = 'mrow-enumerator' ] /
  child::mfrac /
  preceding-sibling::*[1][@class = 'MathClass-bin']
)
and
(  normalize-space(
  child::mrow[ @class = 'mrow-enumerator' ] /
  child::mfrac /
  preceding-sibling::*[1] )
  =
  normalize-space(
  child::mrow[ @class = 'mrow-enumerator' ] /
  child::mfrac /
  child::mrow[ @class = 'mrow-enumerator' ] /
  child::mfrac /
  preceding-sibling::*[1] )
)
>>>




%%%%%%%%%%%%%
\subsection{Prepend Existing Continued Fractions}
%%%%%%%%%%%%%


\<prepend continued fractions\><<<
<xsl:when test="
     self::mfrac
   and
     child::mrow[ @class = 'mrow-enumerator' ]
       / child::mfrac[ @class = 'continued-mfrac' ]
   and
     ( normalize-space(
         child::mrow[ @class = 'mrow-numerator' ]
       )
       =
       normalize-space(
         child::mrow[ @class = 'mrow-enumerator' ]
          / child::mfrac[ @class = 'continued-mfrac' ]
          / child::mrow[ @class = 'mrow-numerator' ]
       )
     )
   and `<check equality of op with cont frac`>
" >
 `<a,b := cont top 2 pre op values`>
 <xsl:choose>
    <xsl:when test="
        normalize-space($a)=normalize-space($b)
    " >
        <xsl:attribute name="class">
           <xsl:value-of select=" 'continued-mfrac' " />
        </xsl:attribute>
        <xsl:apply-templates select="*|text()|comment()" />
    </xsl:when>
    <xsl:otherwise>
        <xsl:apply-templates select="*|@*|text()|comment()" />
    </xsl:otherwise>
 </xsl:choose>
</xsl:when>
>>>



\<check equality of op with cont frac\><<<
(
  normalize-space(
  child::span[ @class = 'mrow-enumerator' ] /
  child::mfrac /
  preceding-sibling::*[1] )
  =
  normalize-space(
  child::span[ @class = 'mrow-enumerator' ] /
  child::mfrac /
  child::span[ @class = 'mrow-enumerator' ] /
  child::span[ @class = 'continued-mfrac' ] /
  preceding-sibling::*[1] )
)
>>>


\<a,b := cont top 2 pre op values\><<<
<xsl:variable name="a">
  <xsl:apply-templates select="
        child::span[ @class = 'mrow-enumerator' ] /
        child::span[ @class = 'mcontinued-mfrac' ] /
        preceding-sibling::*[2]
  "  mode="enum-op" />
</xsl:variable>
<xsl:variable name="b">
  <xsl:apply-templates select="
        child::span[ @class = 'mrow-enumerator' ] /
        child::span[ @class = 'mcontinued-mfrac' ] /
        child::span[ @class = 'mrow-enumerator' ] /
        child::span[
          self::mfrac or (@class = 'mcontinued-mfrac')
        ] /
        preceding-sibling::*[2]
  "  mode="enum-op" />
</xsl:variable>
>>>




%%%%%%%%%%%%%%%%%%
\section{Fractions (Stage 2)}
%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%
\subsection{Outline}
%%%%%%%%%%%%%


\<set levels for hyper complex fracs\><<<
<dom name="." xml="." method="fracLevel" class="tex4ht.HtJsml" />
`<remove xml declaration`>
>>>



\<static void fracLevel(dom)\><<<
public static void fracLevel(Node d) {
  dom = (Document) d;
  setFracLevel(dom.getFirstChild(), 0);
}
private static int setFracLevel(Node node, int cont) {
 int level = 0;
 if (node.hasChildNodes()) {
       String ndName = node.getNodeName();
   int prevCont = cont;
   String clValue = null;
   if (ndName.equals("mfrac")) {
     `<clValue := class of mfrac`>
     `<cont := distance from mfrac(continued-frac)`>
   }
   `<level += inherited from children`>
   `<return 0 if barier`>
   if (ndName.equals("mfrac")) {
     `<return 0 if mfrac barier`>
     if( cont > 0 ){
         if ( prevCont == 0 ){
            `<set start continued fracs mark`>
         }
         `<remove end of non-tail continued frac`>
         level = 0;
     } else if ( prevCont > 0 ){
         `<set end continued fracs mark`>
         level = 0;
     } else
       if( level > 0 ){
         `<set extra levels for frac`>
       }
       level++;
 } }
 return level;
}
>>>



%%%%%%%%%%%%%%%%%%
\subsection{Level Indicators for Nesting (Hyper Complex Fractions)}
%%%%%%%%%%%%%%%%%%

\begin{verbatim}
                 ${a\over b}\over c$

begin begin fraction
                    begin fraction   a
                    over             b
                    end fraction
over over          c
end end fraction
\end{verbatim}

\<set extra levels for frac\><<<
for (int i = 0; i < children.getLength(); i++) {
  Node child = children.item(i);
  if (child.getNodeType() == Node.ELEMENT_NODE) {
     Node cls = child.getAttributes()
                     .getNamedItem("class");
     if (cls != null) {
        String clsName = cls.getNodeValue();
        if (clsName.equals("begin-end")) {
           insertLevelPrefix(child, level);
}  }  }  }
>>>

\<HtJsml utility members\><<<
private static void insertLevelPrefix(Node node, int level){
  if( level == 0 ){ return; }
  if (node.getNodeType() == Node.ELEMENT_NODE) {
    if( node.getNodeName().equals( "level" ) ){
       `<insert level prefixes`>
    } else {
       NodeList children = node.getChildNodes();
       for (int i = 0; i < children.getLength(); i++) {
          Node child = children.item(i);
          insertLevelPrefix(child, level);
}  }  } }
>>>




\<insert level prefixes\><<<
Node attr = node.getAttributes().getNamedItem("prefix");
if( attr != null ){
 String prefix = attr.getNodeValue();
 String  s = "";
 for(int j=0; j<level; j++){
    s += prefix + " ";
 }
 ((org.w3c.dom.Element) node).setAttribute( "depth", ""+level);
 Node child = node.getFirstChild();
 if( child != null ){
    node.insertBefore( dom.createTextNode(s), child );
} }
>>>



\<level += inherited from children\><<<
NodeList children = node.getChildNodes();
int max = 0;
for (int i = 0; i < children.getLength(); i++) {
  Node child = children.item(i);
  if (child.getNodeType() == Node.ELEMENT_NODE) {
     int d = setFracLevel(child,
                          `<continued level counter`>);
     if (d > max) { max = d; }
}  }
level += max;
>>>


%%%%%%%%%%%%%
\subsection{Level Terminators: Scripts, Word Fracs}
%%%%%%%%%%%%%


\<return 0 if barier\><<<
if(    ndName.equals("msub")
   || ndName.equals("msup")
   || ndName.equals("msubsup")
) {
  return 0;
}
>>>


\<return 0 if mfrac barier\><<<
if( (clValue != null) && clValue.equals("word-frac")
) {
  return 0;
}
>>>










%%%%%%%%%%%%%
\subsection{Bookeeping for Continued Fractions}
%%%%%%%%%%%%%

\<continued level counter\><<<
cont
>>>


In the first phase, the mfrac elements in a group carry
attributes as in

\begin{verbatim}
      <mfrac class="continued-mfrac">
\end{verbatim}


with the exception of the bottom (internal) most leveles.
The `cont' parameter is for determining whether the parent and the
grandparent are frac elements marked as continued.



\<clValue := class of mfrac\><<<
if (node.hasAttributes()) {
  Node cl = node.getAttributes().getNamedItem("class");
  if (cl != null) { clValue = cl.getNodeValue(); }
}
>>>

\<cont := distance from mfrac(continued-frac)\><<<
if( (clValue != null)
   && clValue.equals("continued-mfrac") ) {
 cont = 2;
} else { cont--; }
>>>



%%%%%%%%%%%%%
\subsection{Modifications for Continued Fractions}
%%%%%%%%%%%%%

\<remove end of non-tail continued frac\><<<
Node child = node.getLastChild();
if (child.getNodeType() == Node.ELEMENT_NODE) {
  Node cls = child.getAttributes() .getNamedItem("class");
  if (cls != null) {
     String clsName = cls.getNodeValue();
     if ( clsName.equals("begin-end")) {
        node.removeChild( child  );
}  }  }
>>>

\<set end continued fracs mark\><<<
Node child = node.getLastChild();
if (child.getNodeType() == Node.ELEMENT_NODE) {
  Node cls = child.getAttributes() .getNamedItem("class");
  if (cls != null) {
     String clsName = cls.getNodeValue();
     if ( clsName.equals("begin-end")) {
        setContinuedNote(child);
}  }  }
>>>

\<set start continued fracs mark\><<<
Node child = node.getFirstChild();
if (child.getNodeType() == Node.ELEMENT_NODE) {
  Node cls = child.getAttributes() .getNamedItem("class");
  if (cls != null) {
     String clsName = cls.getNodeValue();
     if ( clsName.equals("begin-end")) {
        setContinuedNote(child);
}  }  }
>>>


\<HtJsml utility members\><<<
private static void setContinuedNote(Node node){
  if (node.getNodeType() == Node.ELEMENT_NODE) {
    if( node.getNodeName().equals( "level" ) ){
       `<fix end continued note`>
    } else {
       NodeList children = node.getChildNodes();
       for (int i = 0; i < children.getLength(); i++) {
          Node child = children.item(i);
          setContinuedNote(child);
}  }  } }
>>>

\<fix end continued note\><<<
Node attr = node.getAttributes().getNamedItem("continued");
if (attr != null) {
 node = node.getFirstChild();
 if( node != null ){
    ((org.w3c.dom.Text) node).setData( attr.getNodeValue() );
} }
>>>




%%%%%%%%%%%%%
\section{Set Levels on Roots}
%%%%%%%%%%%%%

\<set levels for roots\><<<
<dom name="." xml="." method="rootLevel" class="tex4ht.HtJsml" />
`<remove xml declaration`>
>>>

\<static void rootLevel(dom)\><<<
public static void rootLevel(Node d) {
  dom = (Document) d;
  setRootLevel(d.getFirstChild());
}
private static int setRootLevel( Node node ){
 int level = 0;
//  String clName = null;
 if (node.hasChildNodes()) {
   `<count root levels inherited from children`>
   String ndName =  node.getNodeName();
   `<block for roots`>
   if( ndName.equals("msqrt") || ndName.equals("mroot") ){
       `<set extra levels for roots`>
       level++;
 } }
 return level;
}
>>>


\<count root levels inherited from children\><<<
NodeList children = node.getChildNodes();
int max = 0;
for (int i = 0; i < children.getLength(); i++) {
 Node child = children.item(i);
 if (child.getNodeType() == Node.ELEMENT_NODE) {
   int d = setRootLevel(child);
   if( d > max ){ max = d; }
} }
level += max;
>>>


\<block for roots\><<<
if( ndName.equals("msub") || ndName.equals("msup") ||
   ndName.equals("msubsup")
) {
  return 0;
}
>>>




\<set extra levels for roots\><<<
for (int i = 0; i < children.getLength(); i++) {
 Node child = children.item(i);
 if (child.getNodeType() == Node.ELEMENT_NODE) {
   Node cls = child.getAttributes()
                   .getNamedItem("class");
   if (cls != null) {
     String clsName = cls.getNodeValue();
     if( clsName.equals("begin-root")
         || clsName.equals("mid-root")
         || clsName.equals("end-root")
     ){
        insertLevelPrefix(child, level);
} } } }
>>>




%%%%%%%%%%%%%
\section{Modifiers}
%%%%%%%%%%%%%



%%%%%%%%%%%%%%%%%%
\subsection{Over and Under Limit Scripts}
%%%%%%%%%%%%%%%%%%


\<over and under scripts\><<<
<script element="msub::limits-msub-msup" >
 <set name="smash" >
    `<open xslt script`>
    `<smash over and under scripts`>
    `<close xslt script`>
 </set>
 <xslt name="." xml="." xsl="smash" />
</script>
>>>

\<over and under scripts\><<<
<script element="msup::limits-msub-msup" >
 <set name="smash" >
    `<open xslt script`>
    `<smash over and under scripts`>
    `<close xslt script`>
 </set>
 <xslt name="." xml="." xsl="smash" />
</script>
>>>

\<over and under scripts\><<<
<script element="msubsup::limits-msub-msup" >
 <set name="smash" >
    `<open xslt script`>
    `<smash over and under scripts`>
    `<close xslt script`>
 </set>
 <xslt name="." xml="." xsl="smash" />
</script>
>>>







\<smash over and under scripts\><<<
<xsl:template match="*[
      (@class = 'limits-msub-msup')
    and
      child::*[ (position() = 1)
                and (@class = 'limits-mrow-base')
                and child::*[ (position() = 1)
                        and (@class = 'limits-msub-msup')
      ]             ]
]" >
 <xsl:copy>
    <xsl:apply-templates select="@*" />
    <xsl:apply-templates select="
                  *[1]
                  / *[1]
                  / *[ not(@class='limits-mrow-super') ]  " />
    <xsl:apply-templates select=" *[
                  preceding-sibling::*
                and
                  not(@class='limits-mrow-super') ]" />
    <xsl:apply-templates select="
                  *[1]
                  / *[1]
                  / *[@class='limits-mrow-super' ]  " />
    <xsl:apply-templates select=" *[
                  preceding-sibling::*
                and
                  (@class='limits-mrow-super') ]" />
 </xsl:copy>
</xsl:template>
>>>


\<compress limit script\><<<
<xsl:template match="span[ @class = 'end-limits-script' ]" >
 <xsl:if test=" parent::*[ not(following-sibling::*) ] ">
   <xsl:copy>
      <xsl:apply-templates select=" @* " />
      <xsl:choose>
         <xsl:when test="
               parent::*[ preceding-sibling::mrow[
                                 @class != 'limits-mrow-base'
                        ]  ]
           " >
           <BREAK SIZE="small"/>
           <xsl:text> end scripts </xsl:text>
           <BREAK SIZE="small"/>
         </xsl:when>
         <xsl:otherwise>
           <BREAK SIZE="small"/>
           <xsl:text> end script </xsl:text>
           <BREAK SIZE="small"/>
         </xsl:otherwise>
      </xsl:choose>
   </xsl:copy>
 </xsl:if>
</xsl:template>
>>>


\<compress limit script\><<<
<xsl:template match="span[ @class = 'begin-limits-script' ]" >
   <xsl:copy>
      <xsl:apply-templates select=" @* " />
      <xsl:choose>
         <xsl:when test="
               parent::*[ @class = 'limits-mrow-super'  ]
         " >
             <xsl:apply-templates
                 select=" parent::*
                          / preceding-sibling::*[1] "
                 mode = "extra-over" />
         </xsl:when>
         <xsl:when test="
               parent::*[ @class = 'limits-mrow-sub'  ]
         " >
             <xsl:apply-templates
                 select=" parent::*
                          / preceding-sibling::*[1] "
                 mode = "extra-under" />
         </xsl:when>
      </xsl:choose>
      <xsl:apply-templates select="*|text()|comment()" />
   </xsl:copy>
</xsl:template>
>>>



\<compress limit script\><<<
<xsl:template match="*" mode="extra-over" >
  <xsl:if   test = " self::mrow[ @class = 'limits-mrow-super' ] " >
    <xsl:text> over </xsl:text>
    <xsl:apply-templates select=" preceding-sibling::*[1] "
                   mode = "extra-over" />
  </xsl:if>
</xsl:template>
>>>


\<compress limit script\><<<
<xsl:template match="*" mode="extra-under" >
  <xsl:if   test = " self::mrow[ @class = 'limits-mrow-sub' ] " >
    <xsl:text> under </xsl:text>
    <xsl:apply-templates select=" preceding-sibling::*[1] "
                   mode = "extra-under" />
  </xsl:if>
</xsl:template>
>>>




%%%%%%%%%%%%%
\subsection{Short Cuts for Math Underline}
%%%%%%%%%%%%%



\<short cut modifiers\><<<
<script element="munder::munder-underline" >
 <set name="munder" >
    `<open xslt script`>
    `<get content template`>
    `<under modifier templates`>
    `<close xslt script`>
 </set>
 <xslt name="." xml="." xsl="munder" />
</script>
>>>

\<under modifier templates\><<<
<xsl:template match="munder[
   (@class = 'munder-underline')
  and
   child::mrow[
      (@class = 'mo-0332')
      and
      descendant::mi
  ]
]" >
   <xsl:variable name="content">
      <xsl:apply-templates select="*" mode="content" />
   </xsl:variable>
   <xsl:choose>
      <xsl:when test="
         string-length( normalize-space( $content )) = 1
      " >
          <xsl:copy>
             <xsl:apply-templates select="@*" />
             <xsl:apply-templates
                select=" *[ @class != 'begin-end' ] " />
             <span class="begin-end" title="speech-extra" >
                <BREAK SIZE="small"/>
                <xsl:text> under bar </xsl:text>
                <BREAK SIZE="small"/>
             </span>
          </xsl:copy>
      </xsl:when>
      <xsl:otherwise>
         `<set munder`>
      </xsl:otherwise>
   </xsl:choose>
</xsl:template>
>>>




The following code makes to push the munder's under the mover's.

\<set munder\><<<
<xsl:choose>
  <xsl:when test="child::mrow / child::mover">
        <xsl:apply-templates select="child::mrow / child::mover"
                               mode="under-mover" />
  </xsl:when>
  <xsl:otherwise>
    <xsl:copy>
       <xsl:apply-templates select=" *|@*|text() " />
    </xsl:copy>
  </xsl:otherwise>
</xsl:choose>
>>>

\<under modifier templates\><<<
<xsl:template match="*" mode="under-mover" >
  <xsl:choose>
     <xsl:when test="self::mover">
        <xsl:copy>
          <xsl:apply-templates select="@*" />
          <xsl:apply-templates select="*" mode="under-mover" />
        </xsl:copy>
     </xsl:when>
     <xsl:when test="self::mrow[ parent::mover ]">
        <xsl:copy>
          <xsl:apply-templates select="@*" />
          `<cont under-mover`>
        </xsl:copy>
     </xsl:when>
     <xsl:otherwise>
        <xsl:apply-templates select="." />
     </xsl:otherwise>
  </xsl:choose>
</xsl:template>
>>>

\<cont under-mover\><<<
<xsl:choose>
  <xsl:when test="child::mover">
     <xsl:apply-templates select="*" mode="under-mover" />
  </xsl:when>
  <xsl:otherwise>
     <munder class="munder-underline">
        `<munder prefix`>
        <mrow class="mo-0032">
           <xsl:apply-templates select="*"  />
        </mrow>
        `<munder postfix`>
     </munder>
  </xsl:otherwise>
</xsl:choose>
>>>



\<munder prefix\><<<
<xsl:apply-templates select="
 ancestor::munder[1] / child::*[following-sibling::mrow]
"/>
>>>



\<munder postfix\><<<
<xsl:apply-templates select="
 ancestor::munder[1] / child::*[preceding-sibling::mrow]
"/>
>>>



\begin{verbatim}
<munder class="munder-underline">
 <span class="begin-end" title="speech-extra" > modified under </span>
 <mrow class="mo-0332">
   <mi>x</mi>
 </mrow>
 <span class="begin-end" title="speech-extra" > with bar </span>
</munder>
\end{verbatim}



%%%%%%%%%%%%%
\subsection{Short Cuts for Math Overline}
%%%%%%%%%%%%%


\<short cut modifiers\><<<
<script element="mover::mover-overline" >
 <set name="mover" >
    `<open xslt script`>
    `<get content template`>
    `<over modifier templates`>
    `<close xslt script`>
 </set>
 <xslt name="." xml="." xsl="mover" />
</script>
>>>




\<over modifier templates\><<<
<xsl:template match="mover[
   (@class = 'mover-overline')
  and
   child::mrow[
      (@class = 'mo-00AF')
      and
      descendant::mi
  ]
]" >
   <xsl:variable name="content">
      <xsl:apply-templates select="*" mode="content" />
   </xsl:variable>
   <xsl:choose>
      <xsl:when test="
         string-length( normalize-space( $content )) = 1
      " >
         `<set mover short cut`>
      </xsl:when>
      <xsl:otherwise>
         <xsl:copy>
            <xsl:apply-templates select="@*" />
            <xsl:apply-templates
                    select="*|text()|comment()" />
         </xsl:copy>
      </xsl:otherwise>
   </xsl:choose>
</xsl:template>
>>>


The following code makes to push the mover's under the munder's.

\<set mover short cut\><<<
<BREAK SIZE="small"/>
<xsl:choose>
  <xsl:when test="child::mrow / child::munder">
        <xsl:apply-templates select="child::mrow / child::munder"
                      mode="under-munder" />
  </xsl:when>
  <xsl:otherwise>
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:apply-templates
          select=" *[ @class != 'begin-end' ] " />
        `<mover bar short cut`>
    </xsl:copy>
  </xsl:otherwise>
</xsl:choose>
>>>

\<over modifier templates\><<<
<xsl:template match="*" mode="under-munder" >
  <xsl:choose>
     <xsl:when test="self::munder">
        <xsl:copy>
          <xsl:apply-templates select="@*" />
          <xsl:apply-templates select="*" mode="under-munder" />
        </xsl:copy>
     </xsl:when>
     <xsl:when test="self::mrow[ parent::munder ]">
        <xsl:copy>
          <xsl:apply-templates select="@*" />
          `<cont under-munder`>
        </xsl:copy>
     </xsl:when>
     <xsl:otherwise>
        <xsl:apply-templates select="." />
     </xsl:otherwise>
  </xsl:choose>
</xsl:template>
>>>

\<cont under-munder\><<<
<xsl:choose>
  <xsl:when test="child::munder">
     <xsl:apply-templates select="*" mode="under-munder" />
  </xsl:when>
  <xsl:otherwise>
     <mover class="mover-overline">
        <mrow class="mo-00AF">
           <xsl:apply-templates select="*"  />
        </mrow>
        `<mover bar short cut`>
     </mover>
  </xsl:otherwise>
</xsl:choose>
>>>





\<mover bar short cut\><<<
<span class="begin-end" title="speech-extra" >
  <BREAK SIZE="small"/>
  <xsl:text> over bar </xsl:text>
  <BREAK SIZE="small"/>
</span>
>>>




\begin{verbatim}
<mover class="mover-overline">
 <span class="begin-end" title="speech-extra"> modified above </span>
 <mrow class="mo-00AF">
   <span class="mathvariant-bold">
     <span title="speech-extra" class="begin-end"> bold </span>
     <mi class="mi">
         <span title="speech-extra"
               class="capital-description"> capital </span>
         Z
     </mi>
   </span>
 </mrow>
 <span class="begin-end" title="speech-extra"> with bar </span>
</mover>
\end{verbatim}







%%%%%%%%%%%%%
\section{New Theorems}
%%%%%%%%%%%%%

\<boundaries on theorems\><<<
<script element="div::newtheorem" >
 <set name="newtheorem" >
    `<open xslt script`>
    `<annotate bounderies of theorems`>
    `<tags for empty templates`>
    `<close xslt script`>
 </set>
 <xslt name="." xml="." xsl="newtheorem" />
</script>
>>>


\<annotate bounderies of theorems\><<<
<xsl:template match="
   div[   (@class='newtheorem')
        and
          descendant::*[ self::p ][1]
          / descendant::*[ self::span ][1]
                         [ @class = 'theorem-head' ]
   ]
" >
  <xsl:copy>
    <xsl:apply-templates select="*|@*|text()|comment()" />
    <div class="begin-end" title="speech-extra">
       <BREAK SIZE="small"/>
       <xsl:value-of select="
          concat( ' end ',
             substring-before(`<new theorem header`>, ' ')
          ) " />
    </div>
  </xsl:copy>
</xsl:template>
>>>


\<new theorem header\><<<
concat(
 normalize-space(
   string(
      descendant::*[ self::p ][1]
      / descendant::*[ self::span ][1]
                     [ @class = 'theorem-head' ]
 ) )
 , ' '
)
>>>


%%%%%%%%%%%%%%%%%%
\section{Shared}
%%%%%%%%%%%%%%%%%%



\<open xslt script\><<<
<![CDATA[
  <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  >
     <xsl:output omit-xml-declaration = "yes" />
>>>

\<close xslt script\><<<
     <xsl:template match="*|@*|text()|comment()" >
       <xsl:copy>
         <xsl:apply-templates select="*|@*|text()|comment()" />
       </xsl:copy>
     </xsl:template>
  </xsl:stylesheet>
]]>
>>>


\<get content template\><<<
<xsl:template match="*" mode="content" >
 <xsl:choose>
    <xsl:when test=" @class = 'char' " >
      <xsl:if test="not( child::*[
           (@class = 'ch 2032') or (@class = 'ch 2033')
                                or (@class = 'ch 2034')
      ] )">
        <xsl:text>x</xsl:text>
      </xsl:if>
    </xsl:when>
    <xsl:when test=" not(
           (@title = 'speech-extra') or (@class = 'accent-char')
        ) " >
      <xsl:apply-templates select="*|text()" mode="content" />
    </xsl:when>
 </xsl:choose>
</xsl:template>
>>>





\marginpar{Can dom be prevented from creating an xml declaration in
 the output? The xslt part is there just to remove the undesirable
 declaration.}


\<remove xml declaration\><<<
<set name="rmXmlDecl" >
 `<open xslt script`>
 `<close xslt script`>
</set>
<xslt name="." xml="." xsl="rmXmlDecl" />
>>>








\ifdojava
\AtEndDocument{\Needs{%
   "pushd \XTPIPES
    ;
    jar cf tex4ht.jar *
    ;
    popd
    ;
    mv \XTPIPES tex4ht.jar \TEXMFTEXivBIN
    ;
    if [ ! -d \TEXMFTEXivXTPIPES\space]; then exit 1; fi
    ;
    cp \XTPIPES xtpipes/lib/*
       \TEXMFTEXivXTPIPES
"}}
\fi


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{document}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



%%%%%%%%%%%%%%%%%%
\section{Odd Ends}
%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%
\subsection{Font Decorations}
%%%%%%%%%%%%%

\<bold math\><<<
<script element="span::mathvariant-bold" >
 <set name="bold" >
    `<open xslt script`>
    `<get content template`>
    `<math bold templates`>
    `<close xslt script`>
 </set>
 <xslt name="." xml="." xsl="bold" />
</script>
>>>



\<math bold templates\><<<
<xsl:template match="span[ @class = 'mathvariant-bold' ]" >
 <xsl:copy>
   <xsl:apply-templates select="@*" />
   <xsl:variable name="content">
      <xsl:apply-templates select="*" mode="content" />
   </xsl:variable>
   <xsl:choose>
      <xsl:when test="
         string-length( normalize-space( $content )) = 1
      " >
         <span class="begin-end" title="speech-extra" >
            <xsl:text> bold </xsl:text>
         </span>
         <xsl:apply-templates select="*|text()|comment()" />
      </xsl:when>
      <xsl:otherwise>
         <span class="begin-end" title="speech-extra" >
            <xsl:text> begin bold </xsl:text>
         </span>
         <xsl:apply-templates select="*|text()|comment()" />
         <span class="begin-end" title="speech-extra" >
            <xsl:text> end bold </xsl:text>
         </span>
      </xsl:otherwise>
   </xsl:choose>
 </xsl:copy>
</xsl:template>
>>>

%%%%%%%%%%%%%%%%%%
\section{Empty Elements}
%%%%%%%%%%%%%%%%%%



%%%%%%%%%%%%%%%%%%
\section{Prose}
%%%%%%%%%%%%%%%%%%