<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">% $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,&lt;&lt;&lt;&gt;&gt;&gt;,title,list,`,[[]]}
\begin{document}


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

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


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

\AtEndDocument{\OutputCodE\&lt;jsml.4xt\&gt;}

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


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


     `&lt;non short tag br elements`&gt;     

     `&lt;inline math`&gt;
     `&lt;display math`&gt;
     `&lt;measure tables`&gt;




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


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




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


\&lt;shared display and inline math 2\&gt;&lt;&lt;&lt;
`&lt;get content template`&gt;
`&lt;replace nested baseline script marks`&gt;
`&lt;remove marks on empty scripts`&gt;
`&lt;eliminate begin script marks`&gt; 
&gt;&gt;&gt;




\AtEndDocument{\OutputCodE\&lt;HtJsml.java\&gt;}

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

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




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


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


\AtEndDocument{%
   \OutputCodE\&lt;GroupMn.java\&gt; 
 }
\ifdojava 
  \Needs{"
    javac GroupMn.java -d \XTPIPES
"} 
\fi
 
\&lt;GroupMn.java\&gt;&lt;&lt;&lt; 
package tex4ht;
/* GroupMn.java (`version), generated from `jobname.tex
   Copyright (C) 2009-2010 TeX Users Group
   Copyright (C) `CopyYear.2002. Eitan M. Gurari
`&lt;TeX4ht copyright`&gt; */
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 ){ `&lt;consider end of num`&gt; }
        } else { `&lt;consider start of num`&gt; } 
        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 &lt; 0) { 
          `&lt;endElement: consider end of num`&gt;
        }
        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  &amp;&amp; (level &lt; 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);
}  }  } 
&gt;&gt;&gt; 

\&lt;consider start of num\&gt;&lt;&lt;&lt;
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) &amp;&amp; cls.equals("MathClass-punc") ){
      inMn = true; level = 0;
      Attributes att = new AttributesImpl();
      super.startElement(ns, "mn-group", "mn-group", att); 
      this.ns = ns;
}  }
&gt;&gt;&gt;

\&lt;consider end of num\&gt;&lt;&lt;&lt;
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"); 
} }
&gt;&gt;&gt;

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

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


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



\&lt;missed partitions to mn groups\&gt;&lt;&lt;&lt;
&lt;dom name="." xml="." method="mnGroup" class="tex4ht.HtJsml" /&gt;
`&lt;remove xml declaration`&gt;
&gt;&gt;&gt;


\&lt;static void mnGroup(dom)\&gt;&lt;&lt;&lt;
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;
    `&lt;get mn characters`&gt;
    if( bool ){
      `&lt;mark remove commas, if comma after period`&gt;
      `&lt;mark remove commas, if not spaced correctly`&gt;
      `&lt;cond remove commas`&gt;
      `&lt;remove punc, on consecutive periods`&gt;
      `&lt;remove punc at end`&gt;
    }
    `&lt;reset mn-group`&gt;
  } else if (node.hasChildNodes()) {
     NodeList children = node.getChildNodes();
     for (int i = 0; i &lt; children.getLength(); i++) {
        Node child = children.item(i);
        if (child.getNodeType() == Node.ELEMENT_NODE) {
           setMnGroup(child);
} }  }  }
&gt;&gt;&gt;

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

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


\&lt;get mn characters\&gt;&lt;&lt;&lt;
NodeList children = node.getChildNodes();
int n = children.getLength();
char [] digit = new char[n];
for (int i = 0; i &lt; 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 &gt;= '0') &amp;&amp; (ch &lt;= '9') ){
          digit[i] = '0'; bool = true;
       } else if( (ch == '.') || (ch == ',') ){ digit[i] = ch; }
       else                                 { digit[i] = 'x';}
} }  }
&gt;&gt;&gt;

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

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

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


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

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

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


\&lt;reset mn-group\&gt;&lt;&lt;&lt;
Node parent = node.getParentNode();
Element g = dom.createElement( "mn-group-s" );
Element cur = dom.createElement( "mn-group" );
for(int i=0;  i&lt;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 );
&gt;&gt;&gt;


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




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








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



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



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


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

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

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


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


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



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


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





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



\&lt;'minus' into 'negative'\&gt;&lt;&lt;&lt;
&lt;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::*
    )
]" &gt;
  &lt;xsl:copy&gt;
    &lt;xsl:attribute name="class"&gt;
       &lt;xsl:text&gt;mo-unary&lt;/xsl:text&gt;
    &lt;/xsl:attribute&gt;
    &lt;xsl:apply-templates select="*|text()|comment()" 
                         mode="minus-neg" /&gt;
  &lt;/xsl:copy&gt;
&lt;/xsl:template&gt; 
&gt;&gt;&gt;


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

\begin{verbatim}
&lt;span class="begin-script"&gt; subscript &lt;/span&gt;
&lt;mo class="MathClass-bin"&gt;
  &lt;span class="char"&gt;
    &lt;span class="ch 2212"&gt;minus&lt;/span&gt;
  &lt;/span&gt;
&lt;/mo&gt;
&lt;mn&gt;2&lt;/mn&gt;
\end{verbatim}




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


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

\&lt;capital math letters\&gt;&lt;&lt;&lt;
&lt;script element="mi" &gt;
  &lt;set name="math-cap" &gt;
     `&lt;open xslt script`&gt;
     `&lt;span.mi cap letters`&gt; 
     `&lt;close xslt script`&gt;
  &lt;/set&gt;
  &lt;xslt name="." xml="." xsl="math-cap" /&gt;
&lt;/script&gt; 
&gt;&gt;&gt;


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



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



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


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


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



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


%%%%%%%%%%%%%%%%%%
\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.


\&lt;eliminate extra math pauses\&gt;&lt;&lt;&lt;
&lt;sax name="." xml="." content-handler="tex4ht.JsmlMathBreak" /&gt;
&gt;&gt;&gt;


\AtEndDocument{%
   \OutputCodE\&lt;JsmlMathBreak.java\&gt; 
 }

\ifdojava
  \Needs{"
    javac -classpath \LIB xtpipes.jar
          JsmlMathBreak.java
          -d \XTPIPES . 
"}
\fi
 
\&lt;JsmlMathBreak.java\&gt;&lt;&lt;&lt; 
package tex4ht;
/* JsmlMathBreak.java (`version), generated from `jobname.tex
   Copyright (C) 2009-2010 TeX Users Group
   Copyright (C) `CopyYear.2002. Eitan M. Gurari
`&lt;TeX4ht copyright`&gt; */

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&lt;String,Object&gt; 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, "&lt;&gt;&amp;");
    out.print( s );
    if( !s.trim().equals("") ){
       delete = false;
  } }
  public void startElement(String ns, String sName,
                                      String qName,
                                      Attributes atts) {
    if( !( delete &amp;&amp; qName.equals("BREAK") ) ){
      String s = "&lt;" + qName + "\n";
      for (int i = 0; i &lt; atts.getLength(); i++) {
        String name = atts.getQName(i);
        if (name != "xmlns") {
          s += (" " + name + "=\"" 
              + XtpipesUni.toUni(atts.getValue(i), "&lt;&gt;&amp;\"")
              + "\"");
      } }
      if( qName.equals( "BREAK" ) ){
        s += "/";
        delete = true;
      }
      s += "&gt;";
      out.print(s);
  } }
  public void endElement(String ns, String sName, String qName) {
    if( !qName.equals( "BREAK" ) ){
      String s = "&lt;/" + qName + "&gt;";
      out.print(s);
} } }
&gt;&gt;&gt;



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


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


\&lt;br into BREAK\&gt;&lt;&lt;&lt;
&lt;script element="br" &gt;
  &lt;set name="br" &gt;
     `&lt;open xslt script`&gt;
     `&lt;append br with BREAK`&gt;
     `&lt;close xslt script`&gt;
  &lt;/set&gt;
  &lt;xslt name="." xml="." xsl="br" /&gt;
&lt;/script&gt; 
&gt;&gt;&gt;


\&lt;append br with BREAK\&gt;&lt;&lt;&lt;
&lt;xsl:template match="br" &gt;
   &lt;xsl:copy&gt;
       &lt;xsl:apply-templates select="@*" /&gt;
   &lt;/xsl:copy&gt;
   &lt;BREAK SIZE="small"/&gt; 
&lt;/xsl:template&gt; 
&gt;&gt;&gt;
&gt;&gt;&gt;


%%%%%%%%%%%%%%%%%%
\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} +
)


\&lt;short notation for empty elements\&gt;&lt;&lt;&lt;
&lt;script element="BREAK" &gt;
  &lt;set name="BREAK" &gt;
     `&lt;open xslt script`&gt;
     `&lt;empty BREAK`&gt;
     `&lt;close xslt script`&gt;
  &lt;/set&gt;
  &lt;xslt name="." xml="." xsl="BREAK" /&gt;
&lt;/script&gt; 
&gt;&gt;&gt;


\&lt;empty BREAK\&gt;&lt;&lt;&lt;
&lt;xsl:template match="BREAK" &gt;
   &lt;xsl:copy&gt;
       &lt;xsl:apply-templates select="@*" /&gt;
   &lt;/xsl:copy&gt;
&lt;/xsl:template&gt; 
&gt;&gt;&gt;



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

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



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

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

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


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

\&lt;remove empty paragraphs\&gt;&lt;&lt;&lt;
&lt;xsl:template match=" PARA[ normalize-space(.) = '' ] " &gt;
&lt;/xsl:template&gt; 
&gt;&gt;&gt;


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




\AtEndDocument{ %
   \OutputCodE\&lt;JsmlFilter.java\&gt; 
 }
\ifdojava
  \Needs{"
    javac JsmlFilter.java -d \XTPIPES
"}
\fi 
 
\&lt;JsmlFilter.java\&gt;&lt;&lt;&lt; 
package tex4ht;
/* JsmlFilter.java (`version), generated from `jobname.tex
   Copyright (C) 2009-2010 TeX Users Group
   Copyright (C) `CopyYear.2002. Eitan M. Gurari
`&lt;TeX4ht copyright`&gt; */
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( `&lt;elements for PARA?`&gt; ){
          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( `&lt;elements for PARA?`&gt; ){
             super.endElement(ns, "PARA", "PARA"); 
        }
      } catch( Exception e ){
        System.out.println( "--- JsmlFilter Error 2 --- " + e);
}  }  } 
&gt;&gt;&gt; 




\&lt;elements for PARA?\&gt;&lt;&lt;&lt;
   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" )
&gt;&gt;&gt;


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

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


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


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


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


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



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





\&lt;math content element\&gt;&lt;&lt;&lt;
child::*[ not(@title = 'speech-extra') 
          and not( self::BREAK )
        ]
&gt;&gt;&gt;




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

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


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


\begin{verbatim}
&lt;span class="inline-math"&gt;
  &lt;msub&gt;
    &lt;mrow class="mrow-base"&gt;
      &lt;mi&gt;C&lt;/mi&gt;
    &lt;/mrow&gt;
    &lt;mrow class="mrow-sub"&gt;
      &lt;mi&gt;i&lt;/mi&gt;
    &lt;/mrow&gt;
  &lt;/msub&gt;
&lt;/span&gt;
\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.


\&lt;eliminate inline math narrative NO 2\&gt;&lt;&lt;&lt;
&lt;xsl:template match="span[
    (@class = 'inline-math')
  and
    (count( `&lt;math content element`&gt; ) = 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) ] )
       ]  ]
    )
]" &gt;
  &lt;xsl:copy&gt;
    &lt;xsl:choose&gt;
       `&lt;when func on shallow arg`&gt;
       &lt;xsl:otherwise&gt;
          `&lt;unary op on short content`&gt;
       &lt;/xsl:otherwise&gt;
    &lt;/xsl:choose&gt;
  &lt;/xsl:copy&gt;
&lt;/xsl:template&gt; 
&gt;&gt;&gt;

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

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



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


\&lt;eliminate inline math narrative NO 2\&gt;&lt;&lt;&lt;
&lt;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])
                    ]
         )
     ]  )
]" &gt;
  &lt;xsl:copy&gt;
    `&lt;shallow expression`&gt;
  &lt;/xsl:copy&gt;
&lt;/xsl:template&gt; 
&gt;&gt;&gt;

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




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


\&lt;eliminate inline math narrative NO 2\&gt;&lt;&lt;&lt;
&lt;xsl:template match="span[
    (@class = 'inline-math')
  and
    (count( `&lt;math content element`&gt; ) = 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' ) 
       ])
    ]
]" &gt;
  &lt;xsl:copy&gt;
    `&lt;shallow delimited expression`&gt;
  &lt;/xsl:copy&gt;
&lt;/xsl:template&gt; 
&gt;&gt;&gt;

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



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

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




\&lt;set levels for sub and sup scripts\&gt;&lt;&lt;&lt;
&lt;dom name="." xml="." method="scriptLevel" class="tex4ht.HtJsml" /&gt;
`&lt;remove xml declaration`&gt;
&gt;&gt;&gt;



\&lt;static void scriptLevel(dom)\&gt;&lt;&lt;&lt;
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")
        ){
          `&lt;append script prefix`&gt;
    } } }
    String ndName = node.getNodeName();
    if( 
      ndName.equals("msqrt")
      ||
      ndName.equals("mroot")
    ){  prefix = ""; }
    `&lt;script invoke children`&gt;
} }
&gt;&gt;&gt;

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

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


\&lt;use current script prefix\&gt;&lt;&lt;&lt;
Node child = node.getFirstChild();
if( (child.getNodeType() == Node.ELEMENT_NODE) 
    &amp;&amp;
    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 );
}  }  }
&gt;&gt;&gt;
 


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


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

\&lt;eliminate baseline script marks\&gt;&lt;&lt;&lt;
&lt;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') 
    ]
]"  &gt;
  &lt;BREAK SIZE="small"/&gt;
&lt;/xsl:template&gt; 
&gt;&gt;&gt;






The following deals with endscripts before left sides of
tensors.



\&lt;eliminate baseline script marks\&gt;&lt;&lt;&lt;
&lt;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' ]) = '')
    ]
]"  &gt;
  &lt;BREAK SIZE="small"/&gt;
&lt;/xsl:template&gt; 
&gt;&gt;&gt;



\&lt;eliminate baseline script marks\&gt;&lt;&lt;&lt;
&lt;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' ]) = '')
    ]
]"  &gt;
  &lt;BREAK SIZE="small"/&gt;
&lt;/xsl:template&gt; 
&gt;&gt;&gt;








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

\end{verbatim}

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


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

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

\&lt;remove marks on empty scripts\&gt;&lt;&lt;&lt;
&lt;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(.)='')
       ]
]" &gt;
&lt;/xsl:template&gt;   
&gt;&gt;&gt;

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



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


\&lt;replace nested baseline script marks\&gt;&lt;&lt;&lt;
&lt;xsl:template match="span[
     (@class = 'end-script')
   and
     ancestor::*[ preceding-sibling::* [
       ((@class = 'begin-script') or (@class = 'mid-script')) ]]
]" &gt;
  &lt;xsl:copy&gt;
     &lt;xsl:apply-templates select="@*" /&gt;
     &lt;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" /&gt;
  &lt;/xsl:copy&gt;
&lt;/xsl:template&gt;   
&gt;&gt;&gt;



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


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



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



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




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

\&lt;sub sup script\&gt;&lt;&lt;&lt;
&lt;set name="m-sub-sup" &gt;
  `&lt;open xslt script`&gt;
  `&lt;undo if empty su`&gt; 
  `&lt;close xslt script`&gt;
&lt;/set&gt;
&lt;xslt name="." xml="." xsl="m-sub-sup" /&gt;
&gt;&gt;&gt;



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

\&lt;undo if empty su\&gt;&lt;&lt;&lt;
&lt;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(.) != '')
                  ]
    )
]" &gt;
   &lt;xsl:apply-templates select="child::mrow[ 
                          @class = 'mrow-base' ]/*" /&gt;
&lt;/xsl:template&gt; 
&gt;&gt;&gt;



\begin{verbatim}
&lt;msup&gt;
   &lt;mrow class="mrow-base"&gt;
     .........
   &lt;/mrow&gt;
   &lt;wrow class="mrow-super"&gt;
     &lt;span class="begin-script"&gt; superscript &lt;/span&gt;
     &lt;span class="end-script"&gt; baseline &lt;/span&gt;
   &lt;/mrow&gt;
&lt;/msup&gt;
\end{verbatim}




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

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



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

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


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




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






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




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



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


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





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



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


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



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



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

\&lt;compress numeric subscripts\&gt;&lt;&lt;&lt;
  &lt;set name="num-sub" &gt;
     `&lt;open xslt script`&gt;
     `&lt;num sub`&gt; 
     `&lt;close xslt script`&gt;
  &lt;/set&gt;
  &lt;xslt name="." xml="." xsl="num-sub" /&gt;
&gt;&gt;&gt;



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

\&lt;num sub on non-primed base\&gt;&lt;&lt;&lt;
(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
    ] )
&gt;&gt;&gt;

\&lt;num sub on primed base\&gt;&lt;&lt;&lt;
(
  count( child::mrow[ @class = 'mrow-base' ] 
        / child::* [
          not(self::BREAK)
        ]
  ) = 2 )
  and child::mrow[ @class = 'mrow-base' ] [
         child::*[1][ self::mi ]
         and
         child::*[
           (position() &amp;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
    ] )
&gt;&gt;&gt;

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



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

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

\&lt;remove scrip indicators from primes\&gt;&lt;&lt;&lt;
&lt;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')
    ]    
]" &gt;
  &lt;BREAK SIZE="small"/&gt; 
&lt;/xsl:template&gt; 
&gt;&gt;&gt;


\&lt;remove scrip indicators from primes\&gt;&lt;&lt;&lt;
&lt;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')
    ]    
]" &gt;
  &lt;BREAK SIZE="small"/&gt; 
&lt;/xsl:template&gt; 
&gt;&gt;&gt;



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

\&lt;subsup prime\&gt;&lt;&lt;&lt;
&lt;set name="subsup-prime" &gt;
   `&lt;open xslt script`&gt;
   `&lt;compress subsup prime`&gt; 
   `&lt;close xslt script`&gt;
&lt;/set&gt;
&lt;xslt name="." xml="." xsl="subsup-prime" /&gt;
&gt;&gt;&gt;


\&lt;compress subsup prime\&gt;&lt;&lt;&lt;
&lt;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') 
         ]  
]" &gt;  
  &lt;msub&gt;
    &lt;mrow class="mrow-base"&gt; 
       &lt;xsl:apply-templates select="
             child::mrow[@class = 'mrow-base'] / *
          " /&gt;    
       &lt;BREAK SIZE="small"/&gt;
       &lt;xsl:apply-templates select="
             child::mrow[@class = 'mrow-super']
             / child::* [ not(@title = 'speech-extra') ] 
          " /&gt;    
    &lt;/mrow&gt; 
    &lt;mrow class="mrow-sub"&gt; 
       &lt;xsl:apply-templates 
             select="*[@class = 'mrow-sub'] /* " /&gt;
       &lt;xsl:apply-templates select="
             child::mrow[@class = 'mrow-super']
             / child::* [ @class = 'end-script' ] 
          " /&gt;    
    &lt;/mrow&gt;
  &lt;/msub&gt;
&lt;/xsl:template&gt; 
&gt;&gt;&gt;



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



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

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

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





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

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

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

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


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

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



\&lt;span frac elements\&gt;&lt;&lt;&lt;
&lt;script element="mfrac" &gt;
  &lt;set name="mfrac" &gt;
     `&lt;open xslt script`&gt;
     `&lt;frac templates`&gt; 
     `&lt;close xslt script`&gt;
  &lt;/set&gt;
  &lt;xslt name="." xml="." xsl="mfrac" /&gt;
&lt;/script&gt; 
&gt;&gt;&gt;

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


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

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

\&lt;word fracs\&gt;&lt;&lt;&lt;
&lt;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)
"&gt;
   `&lt;a := numerator; b := enumerator`&gt;
   &lt;xsl:choose&gt;
      &lt;xsl:when test=" 
           (translate($a,'123456789','') != '')
           or
           (translate($b,'123456789','') != '')
       " &gt;
         &lt;xsl:apply-templates select="*|@*|text()|comment()" /&gt;
      &lt;/xsl:when&gt;
      &lt;xsl:when test=" $a &amp;lt; $b "&gt;
         &lt;xsl:attribute  name="class"&gt;
             &lt;xsl:text&gt;word-frac&lt;/xsl:text&gt;
         &lt;/xsl:attribute&gt;
         `&lt;word numerator`&gt;
         `&lt;word enumerator`&gt;
      &lt;/xsl:when&gt;
      &lt;xsl:otherwise&gt;
         &lt;xsl:apply-templates select="*|@*|text()|comment()" /&gt;
      &lt;/xsl:otherwise&gt;
   &lt;/xsl:choose&gt;    
&lt;/xsl:when&gt;
&gt;&gt;&gt;


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


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


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



%%%%%%%%%%%%%
\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'.

\&lt;mixed fractions\&gt;&lt;&lt;&lt;
&lt;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
         ] ]
 ]" &gt;
  &lt;xsl:text&gt; and &lt;/xsl:text&gt;
  &lt;xsl:copy&gt;
    &lt;xsl:apply-templates select="*|@*|text()|comment()" /&gt;
  &lt;/xsl:copy&gt;
&lt;/xsl:template&gt; 
&gt;&gt;&gt;




%%%%%%%%%%%%%
\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}
&lt;mfrac&gt;
   &lt;mrow class="mrow-enumerator"&gt; 
      &lt;mn&gt;1&lt;/mn&gt; 
      &lt;mo class="MathClass-bin"&gt;...&lt;/mo&gt; 
      &lt;mfrac&gt; 
        &lt;span class="begin-end" ...&gt;begin fraction&lt;/span&gt; 
        &lt;mrow class="mrow-numerator"&gt; ... &lt;/mrow&gt;
        &lt;span class="begin-end" ...&gt;over&lt;/span&gt; 
        &lt;mrow class="mrow-enumerator"&gt;...&lt;/mrow&gt; 
        &lt;span class="begin-end" ...&gt;end fraction&lt;/span&gt; 
      &lt;/mfrac&gt;
\end{verbatim}

\&lt;a,b := top 2 pre op values\&gt;&lt;&lt;&lt;
&lt;xsl:variable name="a"&gt;
   &lt;xsl:apply-templates select="
         child::mrow[ @class = 'mrow-enumerator' ] /
         child::mfrac /
         preceding-sibling::*[2] 
   "  mode="enum-op" /&gt;  
&lt;/xsl:variable&gt;
&lt;xsl:variable name="b"&gt;
   &lt;xsl:apply-templates select="
         child::mrow[ @class = 'mrow-enumerator' ] /
         child::mfrac /
         child::mrow[ @class = 'mrow-enumerator' ] /
         child::mfrac /
         preceding-sibling::*[2] 
   "  mode="enum-op" /&gt;  
&lt;/xsl:variable&gt;
&lt;xsl:variable name="c"&gt;
   &lt;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' ] )
   "  /&gt;  
&lt;/xsl:variable&gt;
&gt;&gt;&gt;

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





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

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


\&lt;tail continued fractions\&gt;&lt;&lt;&lt;
&lt;xsl:when test="          `%check numeral numerator`%
   (translate(
      normalize-space(
      child::mrow[ @class = 'mrow-numerator' ]),
                              '0123456789','')= '')
   and `&lt;check equality of numerators`&gt;
   and `&lt;check ops before two top fracs`&gt;
"&gt;
  `&lt;a,b := top 2 pre op values`&gt;
  &lt;xsl:choose&gt;
     &lt;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]                  )
             )
     " &gt;
         &lt;xsl:attribute name="class"&gt;
            &lt;xsl:value-of select=" 'continued-mfrac' " /&gt;
         &lt;/xsl:attribute&gt;         
         &lt;xsl:apply-templates select="*|text()|comment()" /&gt;
     &lt;/xsl:when&gt;
     &lt;xsl:otherwise&gt;
         &lt;xsl:apply-templates select="*|@*|text()|comment()" /&gt;
     &lt;/xsl:otherwise&gt;
  &lt;/xsl:choose&gt;
&lt;/xsl:when&gt;
&gt;&gt;&gt;





\&lt;check equality of numerators\&gt;&lt;&lt;&lt;
(  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' ])
)
&gt;&gt;&gt;



\&lt;check ops before two top fracs\&gt;&lt;&lt;&lt;
(  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] )
)
&gt;&gt;&gt;




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


\&lt;prepend continued fractions\&gt;&lt;&lt;&lt;
&lt;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 `&lt;check equality of op with cont frac`&gt;
" &gt;
  `&lt;a,b := cont top 2 pre op values`&gt;
  &lt;xsl:choose&gt;
     &lt;xsl:when test="
         normalize-space($a)=normalize-space($b)
     " &gt;
         &lt;xsl:attribute name="class"&gt;
            &lt;xsl:value-of select=" 'continued-mfrac' " /&gt;
         &lt;/xsl:attribute&gt;         
         &lt;xsl:apply-templates select="*|text()|comment()" /&gt;
     &lt;/xsl:when&gt;
     &lt;xsl:otherwise&gt;
         &lt;xsl:apply-templates select="*|@*|text()|comment()" /&gt;
     &lt;/xsl:otherwise&gt;
  &lt;/xsl:choose&gt;
&lt;/xsl:when&gt; 
&gt;&gt;&gt;



\&lt;check equality of op with cont frac\&gt;&lt;&lt;&lt;
(
   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] )
)
&gt;&gt;&gt;


\&lt;a,b := cont top 2 pre op values\&gt;&lt;&lt;&lt;
&lt;xsl:variable name="a"&gt;
   &lt;xsl:apply-templates select="
         child::span[ @class = 'mrow-enumerator' ] /
         child::span[ @class = 'mcontinued-mfrac' ] /
         preceding-sibling::*[2] 
   "  mode="enum-op" /&gt;  
&lt;/xsl:variable&gt;
&lt;xsl:variable name="b"&gt;
   &lt;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" /&gt;  
&lt;/xsl:variable&gt;
&gt;&gt;&gt;




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

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


\&lt;set levels for hyper complex fracs\&gt;&lt;&lt;&lt;
&lt;dom name="." xml="." method="fracLevel" class="tex4ht.HtJsml" /&gt;
`&lt;remove xml declaration`&gt;
&gt;&gt;&gt;



\&lt;static void fracLevel(dom)\&gt;&lt;&lt;&lt;
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")) {        
      `&lt;clValue := class of mfrac`&gt;
      `&lt;cont := distance from mfrac(continued-frac)`&gt;
    }
    `&lt;level += inherited from children`&gt;
    `&lt;return 0 if barier`&gt;
    if (ndName.equals("mfrac")) {
      `&lt;return 0 if mfrac barier`&gt;
      if( cont &gt; 0 ){
          if ( prevCont == 0 ){
             `&lt;set start continued fracs mark`&gt;
          }
          `&lt;remove end of non-tail continued frac`&gt; 
          level = 0;
      } else if ( prevCont &gt; 0 ){
          `&lt;set end continued fracs mark`&gt;
          level = 0;
      } else
        if( level &gt; 0 ){
          `&lt;set extra levels for frac`&gt;
        }
        level++;
  } }
  return level;
}
&gt;&gt;&gt;



%%%%%%%%%%%%%%%%%%
\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}

\&lt;set extra levels for frac\&gt;&lt;&lt;&lt;
for (int i = 0; i &lt; 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);
}  }  }  }
&gt;&gt;&gt;

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


   

\&lt;insert level prefixes\&gt;&lt;&lt;&lt;
Node attr = node.getAttributes().getNamedItem("prefix");
if( attr != null ){
  String prefix = attr.getNodeValue();
  String  s = "";
  for(int j=0; j&lt;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 );
} }
&gt;&gt;&gt;



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


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


\&lt;return 0 if barier\&gt;&lt;&lt;&lt;
if(    ndName.equals("msub")
    || ndName.equals("msup") 
    || ndName.equals("msubsup") 
) {
   return 0;
}
&gt;&gt;&gt;


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










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

\&lt;continued level counter\&gt;&lt;&lt;&lt;
cont
&gt;&gt;&gt;


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

\begin{verbatim}
       &lt;mfrac class="continued-mfrac"&gt; 
\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.



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

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



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

\&lt;remove end of non-tail continued frac\&gt;&lt;&lt;&lt;
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  );
}  }  }
&gt;&gt;&gt;

\&lt;set end continued fracs mark\&gt;&lt;&lt;&lt;
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);
}  }  }
&gt;&gt;&gt;

\&lt;set start continued fracs mark\&gt;&lt;&lt;&lt;
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);
}  }  }
&gt;&gt;&gt;


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

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




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

\&lt;set levels for roots\&gt;&lt;&lt;&lt;
&lt;dom name="." xml="." method="rootLevel" class="tex4ht.HtJsml" /&gt;
`&lt;remove xml declaration`&gt;
&gt;&gt;&gt;

\&lt;static void rootLevel(dom)\&gt;&lt;&lt;&lt;
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()) {
    `&lt;count root levels inherited from children`&gt;
    String ndName =  node.getNodeName();
    `&lt;block for roots`&gt;
    if( ndName.equals("msqrt") || ndName.equals("mroot") ){
        `&lt;set extra levels for roots`&gt;
        level++;
  } } 
  return level;
}
&gt;&gt;&gt;


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


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




\&lt;set extra levels for roots\&gt;&lt;&lt;&lt;
for (int i = 0; i &lt; 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);
} } } }
&gt;&gt;&gt;




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



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


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

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

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







\&lt;smash over and under scripts\&gt;&lt;&lt;&lt;
&lt;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')
       ]             ]
]" &gt;
  &lt;xsl:copy&gt;
     &lt;xsl:apply-templates select="@*" /&gt;
     &lt;xsl:apply-templates select="
                   *[1]
                   / *[1] 
                   / *[ not(@class='limits-mrow-super') ]  " /&gt;
     &lt;xsl:apply-templates select=" *[
                   preceding-sibling::* 
                 and
                   not(@class='limits-mrow-super') ]" /&gt;
     &lt;xsl:apply-templates select="
                   *[1]
                   / *[1]
                   / *[@class='limits-mrow-super' ]  " /&gt;
     &lt;xsl:apply-templates select=" *[
                   preceding-sibling::* 
                 and
                   (@class='limits-mrow-super') ]" /&gt;
  &lt;/xsl:copy&gt;
&lt;/xsl:template&gt; 
&gt;&gt;&gt;


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


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



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


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




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



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

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




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

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

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

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



\&lt;munder prefix\&gt;&lt;&lt;&lt;
&lt;xsl:apply-templates select="
  ancestor::munder[1] / child::*[following-sibling::mrow]
"/&gt;
&gt;&gt;&gt;



\&lt;munder postfix\&gt;&lt;&lt;&lt;
&lt;xsl:apply-templates select="
  ancestor::munder[1] / child::*[preceding-sibling::mrow]
"/&gt;
&gt;&gt;&gt;



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



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


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




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


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

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

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

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





\&lt;mover bar short cut\&gt;&lt;&lt;&lt;
&lt;span class="begin-end" title="speech-extra" &gt; 
   &lt;BREAK SIZE="small"/&gt;
   &lt;xsl:text&gt; over bar &lt;/xsl:text&gt;
   &lt;BREAK SIZE="small"/&gt;
&lt;/span&gt;
&gt;&gt;&gt;




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







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

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


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


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


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



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

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


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





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


\&lt;remove xml declaration\&gt;&lt;&lt;&lt;
&lt;set name="rmXmlDecl" &gt;
  `&lt;open xslt script`&gt;
  `&lt;close xslt script`&gt;
&lt;/set&gt;
&lt;xslt name="." xml="." xsl="rmXmlDecl" /&gt;
&gt;&gt;&gt;








\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}
%%%%%%%%%%%%%

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



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

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



%%%%%%%%%%%%%%%%%%
\section{Prose}
%%%%%%%%%%%%%%%%%%
</pre></body></html>