% $Id: tex4ht-jsml-xtpipes.tex 740 2020-06-13 22:35:32Z karl $
% htlatex tex4ht-jsml-xtpipes "xhtml,next,3" "" "-d./"
%
% Copyright 2009-2020 TeX Users Group
% Copyright 2002-2009 Eitan M. Gurari
% Released under LPPL 1.3c+.
% See tex4ht-cpright.tex for license text.
\documentclass{article}
\Configure{ProTex}{log,<<<>>>,title,list,`,[[]]}
\begin{document}
\input{common}
\input{tex4ht-cpright}
\input{tex4ht-dir}
%%%%%%%%%%%%%%%%%%
\part{Script for xtpipes}
%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%
\section{Outline}
%%%%%%%%%%%%%%%%%%
\AtEndDocument{\OutputCodE\<jsml.4xt\>}
\Needs{"xmllint --valid --noout jsml.4xt"}
\<jsml.4xt\><<<
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE xtpipes SYSTEM "xtpipes.dtd" >
<!-- jsml.4xt (`version), generated from `jobname.tex
Copyright (C) 2009-2010 TeX Users Group
Copyright (C) `CopyYear.2002. Eitan M. Gurari
`<TeX4ht copyright`> -->
<xtpipes signature="jsml.4xt (`version)">
<sax content-handler="xtpipes.util.ScriptsManager, tex4ht.GroupMn, tex4ht.JsmlFilter"
lexical-handler="xtpipes.util.ScriptsManagerLH" >
`<numbers in math`>
`<special sub and super scripts`>
`<span frac elements`>
`<short cut modifiers`>
`<over and under scripts`>
`<bold math`>
`<capital math letters`>
`<remove multline eqnum cell`>
`<inline math`>
`<display math`>
`<replace characters`>
`<remove empty split entries`>
`<boundaries on theorems`>
`<br into BREAK`>
`<short notation for empty elements`>
</sax>
</xtpipes>
>>>
`<non short tag br elements`>
`<inline math`>
`<display math`>
`<measure tables`>
\<inline math\><<<
<script element="span::inline-math" >
`<compress numeric subscripts`>
`<set levels for hyper complex fracs`>
`<set levels for sub and sup scripts`>
`<set levels for roots`>
<set name="inline-math" >
`<open xslt script`>
`<shared display and inline math 1`>
`<eliminate inline math narrative`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="inline-math" />
`<eliminate extra math pauses`>
<set name="inline-math-2" >
`<open xslt script`>
`<shared display and inline math 2`>
`<eliminate inline math narrative 2`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="inline-math-2" />
</script>
>>>
\<display math\><<<
<script element="div::display-math" >
`<compress numeric subscripts`>
`<set levels for hyper complex fracs`>
`<set levels for sub and sup scripts`>
`<set levels for roots`>
<set name="display-math" >
`<open xslt script`>
`<shared display and inline math 1`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="display-math" />
`<eliminate extra math pauses`>
<set name="display-math-2" >
`<open xslt script`>
`<shared display and inline math 2`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="display-math-2" />
`<set empty elements for the w3 browser`>
</script>
>>>
\<shared display and inline math 1\><<<
`<remove super mn-group`>
`<sayas punctuation`>
`<sayas digits`>
`<sayas math letters`>
`<get content template`>
`<eliminate baseline script marks`>
`<clean begin and mid script marks`>
`<mixed fractions`>
`<'minus' into 'negative'`>
`<compress limit script`>
`<remove scrip indicators from primes`>
`<remove scrip indicators from degree`>
>>>
\<shared display and inline math 2\><<<
`<get content template`>
`<replace nested baseline script marks`>
`<remove marks on empty scripts`>
`<eliminate begin script marks`>
>>>
\AtEndDocument{\OutputCodE\<HtJsml.java\>}
\ifdojava
\Needs{"
javac HtJsml.java -d \XTPIPES
"}
\fi
\<HtJsml.java\><<<
package tex4ht;
/* HtJsml.java (`version), generated from `jobname.tex
Copyright (C) 2009-2010 TeX Users Group
Copyright (C) `CopyYear.2002. Eitan M. Gurari
`<TeX4ht copyright`> */
import org.w3c.dom.*;
public class HtJsml {
`<HtJsml utility members`>
`<static void mnGroup(dom)`>
`<static void fracLevel(dom)`>
`<static void scriptLevel(dom)`>
`<static void rootLevel(dom)`>
}
>>>
%%%%%%%%%%%%%%%%%%
\section{Numbers in Math}
%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%
\subsection{Group MN / MO-Punctuation}
%%%%%%%%%%%%%
\AtEndDocument{%
\OutputCodE\<GroupMn.java\>
}
\ifdojava
\Needs{"
javac GroupMn.java -d \XTPIPES
"}
\fi
\<GroupMn.java\><<<
package tex4ht;
/* GroupMn.java (`version), generated from `jobname.tex
Copyright (C) 2009-2010 TeX Users Group
Copyright (C) `CopyYear.2002. Eitan M. Gurari
`<TeX4ht copyright`> */
import org.xml.sax.helpers.*;
import org.xml.sax.*;
import java.io.PrintWriter;
public class GroupMn extends XMLFilterImpl {
PrintWriter out = null;
boolean inMn = false;
String ns;
int level = -1;
public GroupMn( PrintWriter out, PrintWriter log, boolean trace){
this.out = out;
}
public void startElement(String ns, String sName,
String qName, Attributes attr) {
level++;
try{
if( inMn ){
if( level == 0 ){ `<consider end of num`> }
} else { `<consider start of num`> }
super.startElement(ns, sName, qName, attr);
} catch( Exception e ){
System.out.println( "--- GroupMn Error 1 --- " + e);
}
}
public void endElement(String ns, String sName, String qName){
try{
if( level < 0) {
`<endElement: consider end of num`>
}
super.endElement(ns, sName, qName);
} catch( Exception e ){
System.out.println( "--- GroupMn Error 2 --- " + e);
}
level--;
}
public void characters(char[] ch, int start, int length){
try{
if ( inMn && (level < 0) ) {
String s = new String(ch, start, length);
if (!s.trim().equals("")) {
inMn = false;
super.endElement(ns, "mn-group", "mn-group");
} }
super.characters(ch, start, length);
} catch( Exception e ){
System.out.println( "--- GroupMn Error 3 --- " + e);
} } }
>>>
\<consider start of num\><<<
if( qName.equals( "mn" ) ){
inMn = true; level = 0;
Attributes att = new AttributesImpl();
super.startElement(ns, "mn-group", "mn-group", att);
this.ns = ns;
} else if( qName.equals( "mo" ) ){
String cls = attr.getValue( "class" );
if( (cls != null) && cls.equals("MathClass-punc") ){
inMn = true; level = 0;
Attributes att = new AttributesImpl();
super.startElement(ns, "mn-group", "mn-group", att);
this.ns = ns;
} }
>>>
\<consider end of num\><<<
if( !qName.equals( "mn" ) ){
if( qName.equals( "mo" ) ){
String cls = attr.getValue( "class" );
if( (cls == null) || !cls.equals("MathClass-punc") ){
inMn = false;
super.endElement(ns, "mn-group", "mn-group");
}
} else {
inMn = false;
super.endElement(ns, "mn-group", "mn-group");
} }
>>>
\<endElement: consider end of num\><<<
if( inMn ){
inMn = false;
super.endElement(ns, "mn-group", "mn-group");
}
>>>
%%%%%%%%%%%%%
\subsection{Outline of Post Original Partition}
%%%%%%%%%%%%%
\<numbers in math\><<<
<script element="mn-group" >
`<missed partitions to mn groups`>
<set name="merge" >
`<open xslt script`>
`<merge digits`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="merge" />
</script>
>>>
\<missed partitions to mn groups\><<<
<dom name="." xml="." method="mnGroup" class="tex4ht.HtJsml" />
`<remove xml declaration`>
>>>
\<static void mnGroup(dom)\><<<
private static Document dom;
public static void mnGroup(Node d) {
dom = (Document) d;
setMnGroup(dom.getFirstChild());
}
private static void setMnGroup(Node node) {
if( node.getNodeName().equals( "mn-group" ) ){
boolean bool = false;
`<get mn characters`>
if( bool ){
`<mark remove commas, if comma after period`>
`<mark remove commas, if not spaced correctly`>
`<cond remove commas`>
`<remove punc, on consecutive periods`>
`<remove punc at end`>
}
`<reset mn-group`>
} else if (node.hasChildNodes()) {
NodeList children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE) {
setMnGroup(child);
} } } }
>>>
%%%%%%%%%%%%%
\subsection{Mark Partition of MN Group}
%%%%%%%%%%%%%
Consecutive digits and punctation characters are grouped together, and
then ungrouped at characters that are marked by `x'.
\<get mn characters\><<<
NodeList children = node.getChildNodes();
int n = children.getLength();
char [] digit = new char[n];
for (int i = 0; i < n; i++) {
Node child = children.item(i).getFirstChild();
if( child == null ){
digit[i] = 'x';
} else if( child.getNodeType() != Node.TEXT_NODE ){
digit[i] = 'x';
} else {
String s = child.getNodeValue();
if( s.length() != 1 ){
digit[i] = 'x';
} else {
char ch = s.charAt(0);
if( (ch >= '0') && (ch <= '9') ){
digit[i] = '0'; bool = true;
} else if( (ch == '.') || (ch == ',') ){ digit[i] = ch; }
else { digit[i] = 'x';}
} } }
>>>
\<mark remove commas, if comma after period\><<<
bool = false;
for (int i = 0; i < n; i++) {
if( digit[i] == '.' ){
for (; i < n; i++) {
if( digit[i] == ',' ){
bool = true; break;
} }
break;
} }
>>>
\<mark remove commas, if not spaced correctly\><<<
if( !bool ){
for (int i = 0; i < n; i++) {
if( digit[i] == ',' ){
if( ( ((i+3) >= n)
|| (digit[i+1] != '0')
|| (digit[i+2] != '0')
|| (digit[i+3] != '0')
)
||
(
((i+4) < n) && (digit[i+4] == '0')
)
||
(
(i>3) && (digit[i-4] == '0')
)
){ bool = true; break;
} else { i += 3; }
} } }
>>>
\<cond remove commas\><<<
if( bool ){
for (int i = 0; i < n; i++) {
if( digit[i] == ',' ){ digit[i] = 'x'; }
} }
>>>
\<remove punc, on consecutive periods\><<<
bool = false;
for (int i = 0; i < n; i++) {
if( (digit[i] == 'x')
|| (digit[i] == ',') ){ bool = false; }
else if( digit[i] == '.' ){
if( bool ){
for (int j = 0; j < n; j++) {
if( (digit[j] == '.') || (digit[j] == ',') ){
digit[j] = 'x';
} }
break;
}
bool = true;
} }
>>>
\<remove punc at end\><<<
if( digit[n-1] == '.' ){ digit[n-1] = 'x'; }
>>>
%%%%%%%%%%%%%
\subsection{Realize the Sub Partition}
%%%%%%%%%%%%%
\<reset mn-group\><<<
Node parent = node.getParentNode();
Element g = dom.createElement( "mn-group-s" );
Element cur = dom.createElement( "mn-group" );
for(int i=0; i<n; i++ ){
Node child = node.getFirstChild();
node.removeChild( child );
if( digit[i] == 'x' ){
if( cur.hasChildNodes() ){ g.appendChild( cur ); }
g.appendChild( child );
cur = dom.createElement( "mn-group" );
} else {
cur.appendChild( child );
} }
if( cur.hasChildNodes() ){ g.appendChild( cur ); }
parent.replaceChild( g, node );
>>>
%%%%%%%%%%%%%
\subsection{Reset MNs}
%%%%%%%%%%%%%
\<merge digits\><<<
<xsl:template match="mn-group" >
<xsl:choose>
<xsl:when test=" not(child::mn) ">
<xsl:apply-templates select="*|text()" />
</xsl:when>
<xsl:otherwise>
<mn>
<xsl:value-of select="." />
</mn>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
>>>
\<remove super mn-group\><<<
<xsl:template match="mn-group-s" >
<xsl:apply-templates select="*|@*|text()|comment()" />
</xsl:template>
>>>
%%%%%%%%%%%%%
\subsection{Pronounced Letters}
%%%%%%%%%%%%%
\<sayas math letters \><<<
<xsl:template match="mi[ .='a' ]" >
<xsl:copy>
<xsl:apply-templates select="@*" />
<SAYAS SUB="aih">a</SAYAS>
</xsl:copy>
</xsl:template>
>>>
%%%%%%%%%%%%%
\subsection{Pronounced Punctuation in math}
%%%%%%%%%%%%%
TTSs might ignore punctuation marks. We want these
symbols in math.
\<sayas punctuation\><<<
<xsl:template match="mo[
(@class='MathClass-punc')
and ( (.='.') or (.=',') or (.='!')
or (.=';') or (.=':') or (.='?') )
]" >
<xsl:copy>
<xsl:apply-templates select="@*" />
<BREAK SIZE="small"/>
<xsl:choose>
<xsl:when test=" .='.' " >
<SAYAS SUB="dot">.</SAYAS>
</xsl:when>
<xsl:when test=" .=',' " >
<SAYAS SUB="comma">,</SAYAS>
</xsl:when>
<xsl:when test=" .=';' " >
<SAYAS SUB="semicolon">;</SAYAS>
</xsl:when>
<xsl:when test=" .=':' " >
<SAYAS SUB="colon">:</SAYAS>
</xsl:when>
<xsl:when test=" .='!' " >
<SAYAS SUB="exclamation mark">!</SAYAS>
</xsl:when>
<xsl:when test=" .='?' " >
<SAYAS SUB="question mark">?</SAYAS>
</xsl:when>
</xsl:choose>
<BREAK SIZE="small"/>
</xsl:copy>
</xsl:template>
>>>
\<sayas digits\><<<
<xsl:template match="mn[
`<mn modified above`>
or
`<mn modified under`>
]" >
<xsl:copy>
<SAYAS CLASS="digits">
<xsl:value-of select="." />
</SAYAS>
</xsl:copy>
</xsl:template>
>>>
\<mn modified above\><<<
ancestor::mover[
not( descendant::*[
(count( `<math content element`> ) > 1)
])
and
(
preceding-sibling::*[1][self::dot or self::mn-group-s]
or
following-sibling::*[1][self::dot or self::mn-group-s]
)
]
>>>
\<mn modified under\><<<
ancestor::munder[
not( descendant::*[
(count( `<math content element`> ) > 1)
])
and
(
preceding-sibling::*[1][self::dot or self::mn-group-s]
or
following-sibling::*[1][self::dot or self::mn-group-s]
)
]
>>>
%%%%%%%%%%%%%%%%%%
\section{Process Characters}
%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%
\subsection{'minus' into 'negative'}
%%%%%%%%%%%%%
\<'minus' into 'negative'\><<<
<xsl:template match="mo[
(@class = 'MathClass-bin')
and
( normalize-space(.) =
normalize-space(descendant::span[@class = 'ch 2212'])
)
and
( preceding-sibling::*[1][
(@title='speech-extra')
or (@class='MathClass-bin')
or (@class='MathClass-rel')
or (@class='MathClass-punc')
or (@class='MathClass-op')
or self::mn-group-s [ child::* [
(position() = last())
and
(@class='MathClass-punc')
] ] ]
and
(
following-sibling::*[1][ self::mn-group-s
or self::mi ]
or
(count(following-sibling::*[
not(@title = 'speech-extra')
]) = 1)
)
or
not(preceding-sibling::*) and following-sibling::*
)
]" >
<xsl:copy>
<xsl:attribute name="class">
<xsl:text>mo-unary</xsl:text>
</xsl:attribute>
<xsl:apply-templates select="*|text()|comment()"
mode="minus-neg" />
</xsl:copy>
</xsl:template>
>>>
\<'minus' into 'negative'\><<<
<xsl:template match="*|@*|text()|comment()" mode="minus-neg" >
<xsl:copy>
<xsl:apply-templates select="*|@*|text()|comment()"
mode="minus-neg" />
</xsl:copy>
</xsl:template>
>>>
\begin{verbatim}
<span class="begin-script"> subscript </span>
<mo class="MathClass-bin">
<span class="char">
<span class="ch 2212">minus</span>
</span>
</mo>
<mn>2</mn>
\end{verbatim}
\<'minus' into 'negative'\><<<
<xsl:template match="text()" mode="minus-neg" >
<xsl:choose>
<xsl:when test=" . = 'minus' " >
<xsl:text>negative</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="." />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
>>>
%%%%%%%%%%%%%%%%%%
\subsection{Capital Letters in Math}
%%%%%%%%%%%%%%%%%%
\<capital math letters\><<<
<script element="mi" >
<set name="math-cap" >
`<open xslt script`>
`<span.mi cap letters`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="math-cap" />
</script>
>>>
\<span.mi cap letters\><<<
<xsl:template match="mi" >
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:if test=" string-length(.) = 1 " >
<xsl:if test="
(translate(.,'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'') = '' )
" >
<span class="capital-description"
title="speech-extra" >
<xsl:text> capital </xsl:text>
</span>
</xsl:if>
</xsl:if>
<xsl:apply-templates select="*|text()|comment()" />
</xsl:copy>
</xsl:template>
>>>
%%%%%%%%%%%%%
\subsection{Right Apostrophes}
%%%%%%%%%%%%%
\<replace characters\><<<
<script element="PARA" >
<set name="apostro" >
`<open xslt script`>
`<right apostrophe in prose`>
`<delimiters in marks of enumerated lists`>
`<remove empty paragraphs`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="apostro" />
</script>
>>>
\<right apostrophe in prose\><<<
<xsl:template match="span[
(@class = 'char-del')
and child::span [ @class = 'ch 2019' ]
]" >
<xsl:text>'</xsl:text>
</xsl:template>
>>>
%%%%%%%%%%%%%
\subsection{Delimiters on List Marks}
%%%%%%%%%%%%%
\<delimiters in marks of enumerated lists\><<<
<xsl:template match="PROS[ parent::SENT[@class='ol-mark'] ]" >
<xsl:copy>
<xsl:apply-templates
select="*[not(@class='char-del')]|@*|text()|comment()" />
</xsl:copy>
</xsl:template>
>>>
%%%%%%%%%%%%%%%%%%
\section{Clean Up}
%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%
\subsection{Extra Math Pauses}
%%%%%%%%%%%%%
Deletes pauses that are not separated by text from their immediate
predecessors.
An earlier XSLT-based approach was very slow, and died
on nodes with large numbers of children.
\<eliminate extra math pauses\><<<
<sax name="." xml="." content-handler="tex4ht.JsmlMathBreak" />
>>>
\AtEndDocument{%
\OutputCodE\<JsmlMathBreak.java\>
}
\ifdojava
\Needs{"
javac -classpath \LIB xtpipes.jar
JsmlMathBreak.java
-d \XTPIPES .
"}
\fi
\<JsmlMathBreak.java\><<<
package tex4ht;
/* JsmlMathBreak.java (`version), generated from `jobname.tex
Copyright (C) 2009-2010 TeX Users Group
Copyright (C) `CopyYear.2002. Eitan M. Gurari
`<TeX4ht copyright`> */
import xtpipes.XtpipesUni;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import java.io.*;
import java.lang.reflect.*;
import java.util.HashMap;
public class JsmlMathBreak extends DefaultHandler {
PrintWriter out = null;
boolean delete = false;
public JsmlMathBreak(PrintWriter out,
HashMap<String,Object> scripts,
Method method, PrintWriter log, boolean trace) {
this.out = out;
}
public void characters(char[] ch, int start, int length) {
String s = XtpipesUni.toUni(ch, start, length, "<>&");
out.print( s );
if( !s.trim().equals("") ){
delete = false;
} }
public void startElement(String ns, String sName,
String qName,
Attributes atts) {
if( !( delete && qName.equals("BREAK") ) ){
String s = "<" + qName + "\n";
for (int i = 0; i < atts.getLength(); i++) {
String name = atts.getQName(i);
if (name != "xmlns") {
s += (" " + name + "=\""
+ XtpipesUni.toUni(atts.getValue(i), "<>&\"")
+ "\"");
} }
if( qName.equals( "BREAK" ) ){
s += "/";
delete = true;
}
s += ">";
out.print(s);
} }
public void endElement(String ns, String sName, String qName) {
if( !qName.equals( "BREAK" ) ){
String s = "</" + qName + ">";
out.print(s);
} } }
>>>
\begin{verbatim}
</mrow>
<span class="end-root" title="speech-extra">
<BREAK SIZE="medium"/>
<level prefix="end" depth="1">end end root</level>
<BREAK SIZE="medium"/>
</span>
</mroot>
<span class="end-math" title="speech-extra">
<BREAK SIZE="small"/>
<PROS PITCH="-5">end math</PROS>
<BREAK SIZE="medium"/>
\end{verbatim}
%%%%%%%%%%%%%
\subsection{Line Breaks}
%%%%%%%%%%%%%
\<br into BREAK\><<<
<script element="br" >
<set name="br" >
`<open xslt script`>
`<append br with BREAK`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="br" />
</script>
>>>
\<append br with BREAK\><<<
<xsl:template match="br" >
<xsl:copy>
<xsl:apply-templates select="@*" />
</xsl:copy>
<BREAK SIZE="small"/>
</xsl:template>
>>>
>>>
%%%%%%%%%%%%%%%%%%
\subsection{Empty Elements}
%%%%%%%%%%%%%%%%%%
\marginpar{??????}
Can we avoid empty non-empty representations without of the
following(Example:
\verb+\documentclass{article} \begin{document} \section{Section One} This is Section 1 \end{document} +
)
\<short notation for empty elements\><<<
<script element="BREAK" >
<set name="BREAK" >
`<open xslt script`>
`<empty BREAK`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="BREAK" />
</script>
>>>
\<empty BREAK\><<<
<xsl:template match="BREAK" >
<xsl:copy>
<xsl:apply-templates select="@*" />
</xsl:copy>
</xsl:template>
>>>
%%%%%%%%%%%%%
\subsection{Empty Array Cells}
%%%%%%%%%%%%%
Empty array celles at end of rows can make it more difficult to
detect deletable baseline indicators.
\<remove multline eqnum cell\><<<
<script element="tr" >
<set name="eqnum" >
`<open xslt script`>
`<remove empty cells from rows`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="eqnum" />
</script>
>>>
\<remove multline eqnum cell\><<<
<script element="mtr" >
<set name="eqnum" >
`<open xslt script`>
`<remove empty cells from rows`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="eqnum" />
</script>
>>>
\<remove empty cells from rows\><<<
<xsl:template match="div[
(parent::tr or parent::mtr)
and ( normalize-space(.) = '' )
and not( normalize-space(following-sibling::*) != '' )
]" >
</xsl:template>
>>>
%%%%%%%%%%%%%
\subsection{Paragraphs (JsmlFilter.java)}
%%%%%%%%%%%%%
\<remove empty paragraphs\><<<
<xsl:template match=" PARA[ normalize-space(.) = '' ] " >
</xsl:template>
>>>
The following adds PARA on `p' paragraphs, ul.
\AtEndDocument{ %
\OutputCodE\<JsmlFilter.java\>
}
\ifdojava
\Needs{"
javac JsmlFilter.java -d \XTPIPES
"}
\fi
\<JsmlFilter.java\><<<
package tex4ht;
/* JsmlFilter.java (`version), generated from `jobname.tex
Copyright (C) 2009-2010 TeX Users Group
Copyright (C) `CopyYear.2002. Eitan M. Gurari
`<TeX4ht copyright`> */
import org.xml.sax.helpers.*;
import org.xml.sax.*;
import java.io.PrintWriter;
public class JsmlFilter extends XMLFilterImpl {
PrintWriter out = null;
public JsmlFilter( PrintWriter out, PrintWriter log, boolean trace ){
this.out = out;
}
public void startElement(String ns, String sName,
String qName, Attributes attr) {
try{
if( `<elements for PARA?`> ){
Attributes att = new AttributesImpl();
super.startElement(ns, "PARA", "PARA", att);
}
super.startElement(ns, sName, qName, attr);
} catch( Exception e ){
System.out.println( "--- JsmlFilter Error 1 --- " + e);
} }
public void endElement(String ns, String sName, String qName){
try{
super.endElement(ns, sName, qName);
if( `<elements for PARA?`> ){
super.endElement(ns, "PARA", "PARA");
}
} catch( Exception e ){
System.out.println( "--- JsmlFilter Error 2 --- " + e);
} } }
>>>
\<elements for PARA?\><<<
qName.equals( "p" )
|| qName.equals( "h2" )
|| qName.equals( "h3" )
|| qName.equals( "h4" )
|| qName.equals( "ul" )
|| qName.equals( "ol" )
|| qName.equals( "li" )
|| qName.equals( "dd" )
|| qName.equals( "dl" )
>>>
%%%%%%%%%%%%%
\subsection{Remove Split Arrays}
%%%%%%%%%%%%%
\<remove empty split entries\><<<
<script element="div::split-side" >
<set name="clean-split" >
`<open xslt script`>
`<get content template`>
`<clean math split`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="clean-split" />
</script>
>>>
\<clean math split\><<<
<xsl:template match=" div[ @class='split-side' ]
" >
<xsl:variable name="content">
<xsl:apply-templates select="*" mode="content" />
</xsl:variable>
<xsl:if test="
string-length( normalize-space( $content )) != 0
" >
<xsl:copy>
<xsl:apply-templates select=" *|@*|text()|comment() " />
</xsl:copy>
</xsl:if>
</xsl:template>
>>>
%%%%%%%%%%%%%
\section{Eliminate Inline Math Narrative}
%%%%%%%%%%%%%
%%%%%%%%%%%%%
\subsection{Core Content of One Element}
%%%%%%%%%%%%%
\<eliminate inline math narrative NO\><<<
<xsl:template match="span[
(@class = 'inline-math')
and
(count( `<math content element`> ) = 1)
]" >
<xsl:copy>
<xsl:choose>
<xsl:when test="child::mfrac or child::msqrt
or child::mover or child::munder
">
<xsl:attribute name="class">
<xsl:text>semi-math</xsl:text>
</xsl:attribute>
<BREAK SIZE="small"/>
<xsl:apply-templates
select="`<math content element`>" />
</xsl:when>
<xsl:otherwise>
`<non-adjacent narrative`>
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
>>>
\<non-adjacent narrative\><<<
<xsl:variable name="content">
<xsl:apply-templates
select="`<math content element`>"
mode="content" />
</xsl:variable>
<xsl:choose>
`<math narrative of length one`>
`<math narrative of just one element`>
`<simple sub or sup`>
<xsl:otherwise>
<xsl:apply-templates
select="*|@*|text()|comment()" />
</xsl:otherwise>
</xsl:choose>
>>>
\<math content element\><<<
child::*[ not(@title = 'speech-extra')
and not( self::BREAK )
]
>>>
\<math narrative of length one\><<<
<xsl:when test="
string-length( normalize-space( $content )) = 1
" >
<xsl:attribute name="class">
<xsl:text>semi-math</xsl:text>
</xsl:attribute>
<xsl:apply-templates
select="`<math content element`>" />
</xsl:when>
>>>
\<math narrative of just one element\><<<
<xsl:when test="
not(`<math content element`>
/ descendant::* [
count(child::*[
not(self::BREAK)
] ) > 1
] )
" >
<xsl:attribute name="class">
<xsl:text>semi-math</xsl:text>
</xsl:attribute>
<PROS PITCH="-5">
<BREAK SIZE="small"/>
<xsl:apply-templates
select="`<math content element`>" />
<BREAK SIZE="small"/>
</PROS>
</xsl:when>
>>>
\<simple sub or sup\><<<
<xsl:when test=" child::*[
(position() = 2)
and
(self::msub or self::msup or self::msubsup)
]" >
<xsl:variable name="content">
<xsl:apply-templates
select="child::*[2] / child::*[
(@class = 'mrow-base')
or (@class = 'limits-mrow-base') ]"
mode="content" />
</xsl:variable>
<xsl:choose>
<xsl:when test="
string-length( normalize-space( $content )) = 1
or
(translate($content,'0123456789 ','') = '')
" >
<xsl:attribute name="class">
<xsl:text>semi-math</xsl:text>
</xsl:attribute>
<PROS PITCH="-5">
<BREAK SIZE="small"/>
<xsl:apply-templates select="*[2]" />
<BREAK SIZE="small"/>
</PROS>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="*|@*|text()" />
</xsl:otherwise>
</xsl:choose>
</xsl:when>
>>>
\begin{verbatim}
<span class="inline-math">
<msub>
<mrow class="mrow-base">
<mi>C</mi>
</mrow>
<mrow class="mrow-sub">
<mi>i</mi>
</mrow>
</msub>
</span>
\end{verbatim}
%%%%%%%%%%%%%
\subsection{Unary Op}
%%%%%%%%%%%%%
The `mo-unary' is established in the first pass over inline-math,
so we need to wait for the second pass with the following.
\<eliminate inline math narrative NO 2\><<<
<xsl:template match="span[
(@class = 'inline-math')
and
(count( `<math content element`> ) = 2)
and
( child::mo[
(@class = 'mo-unary')
and
following-sibling::*[1]
/ self::mi
]
or
child::mi[
following-sibling::*[1]
[ (@class = 'MathClass-open-close')
and
not(child::*[2]
/ child::*[ not(self::BREAK) ]
/ child::*[ not(self::BREAK) ] )
] ]
)
]" >
<xsl:copy>
<xsl:choose>
`<when func on shallow arg`>
<xsl:otherwise>
`<unary op on short content`>
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
>>>
\<when func on shallow arg\><<<
<xsl:when test="
child::mrow[ @class = 'MathClass-open-close' ]
" >
<xsl:attribute name="class">
<xsl:text>semi-math</xsl:text>
</xsl:attribute>
<PROS PITCH="-5">
<BREAK SIZE="small"/>
<xsl:apply-templates
select="`<math content element`>" />
<BREAK SIZE="small"/>
</PROS>
</xsl:when>
>>>
\<unary op on short content\><<<
<xsl:attribute name="class">
<xsl:text>semi-math</xsl:text>
</xsl:attribute>
<PROS PITCH="-5">
<BREAK SIZE="small"/>
<xsl:apply-templates
select="`<math content element`>" />
<BREAK SIZE="small"/>
</PROS>
>>>
%%%%%%%%%%%%%
\subsection{Shallow Expression}
%%%%%%%%%%%%%
\<eliminate inline math narrative NO 2\><<<
<xsl:template match="span[
(@class = 'inline-math')
and
not( child::*[
not(self::mo)
and not(self::mi)
and not(self::mn)
and not(self::mn-group-s)
and not( @title='speech-extra' )
and not( self::mfrac[
preceding-sibling::*[1][self::mn ]
]
)
and not( self::msub
/ child::*[1][
child::mo[ @class = 'MathClass-op' ]
and
not(child::*[2])
]
)
] )
]" >
<xsl:copy>
`<shallow expression`>
</xsl:copy>
</xsl:template>
>>>
\<shallow expression\><<<
<xsl:attribute name="class">
<xsl:text>semi-math</xsl:text>
</xsl:attribute>
<PROS PITCH="-5">
<BREAK SIZE="small"/>
<xsl:apply-templates
select="`<math content element`> | text()" />
<BREAK SIZE="small"/>
</PROS>
>>>
%%%%%%%%%%%%%
\subsection{Shallow Delimited Expression}
%%%%%%%%%%%%%
\<eliminate inline math narrative NO 2\><<<
<xsl:template match="span[
(@class = 'inline-math')
and
(count( `<math content element`> ) = 1)
and
child::mrow[ @class='MathClass-open-close' ]
/ child::mrow[
not( child::*[
not(self::mo) and not(self::mn-group-s)
and not(self::mi) and not(self::BREAK)
and not( @title='speech-extra' )
])
]
]" >
<xsl:copy>
`<shallow delimited expression`>
</xsl:copy>
</xsl:template>
>>>
\<shallow delimited expression\><<<
<xsl:attribute name="class">
<xsl:text>semi-math</xsl:text>
</xsl:attribute>
<PROS PITCH="-5">
<BREAK SIZE="small"/>
<xsl:apply-templates select="mrow" />
<BREAK SIZE="small"/>
</PROS>
>>>
%%%%%%%%%%%%%%%%%%
\section{Superscripts and Subscripts}
%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%
\subsection{Insert Sub-Levels Info}
%%%%%%%%%%%%%
\<set levels for sub and sup scripts\><<<
<dom name="." xml="." method="scriptLevel" class="tex4ht.HtJsml" />
`<remove xml declaration`>
>>>
\<static void scriptLevel(dom)\><<<
public static void scriptLevel(Node dom) {
setScriptLevel(dom.getFirstChild(), "");
}
private static void setScriptLevel(Node node, String prefix) {
String clName = null;
if (node.hasChildNodes()) {
if (node.hasAttributes()) {
Node cl = node.getAttributes().getNamedItem("class");
if (cl != null) {
clName = cl.getNodeValue();
if( clName.equals("mrow-sub")
||
clName.equals("mrow-super")
){
`<append script prefix`>
} } }
String ndName = node.getNodeName();
if(
ndName.equals("msqrt")
||
ndName.equals("mroot")
){ prefix = ""; }
`<script invoke children`>
} }
>>>
\<script invoke children\><<<
NodeList children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE) {
setScriptLevel(child, prefix);
} }
>>>
\<append script prefix\><<<
if( !prefix.equals("") ){
`<use current script prefix`>
}
if( clName.equals( "mrow-sub" ) ){
prefix += " sub ";
} else if( clName.equals( "mrow-super" ) ){
prefix += " super ";
}
>>>
\<use current script prefix\><<<
Node child = node.getFirstChild();
if( (child.getNodeType() == Node.ELEMENT_NODE)
&&
child.hasAttributes()
){
Node cls = child.getAttributes().getNamedItem("class");
if (cls != null) {
String clsName = cls.getNodeValue();
if ( clsName.equals("begin-script")
||
clsName.equals("mid-script")
) {
child = child.getFirstChild();
String s = child.getNodeValue();
((org.w3c.dom.Text) child).setData( prefix + s );
} } }
>>>
%%%%%%%%%%%%%
\subsection{Eliminate End Script Marks}
%%%%%%%%%%%%%
The following takes care of end-scripts that semantically can be
merged into other end markers.
\<eliminate baseline script marks\><<<
<xsl:template match="span[
(@class = 'end-script')
and
ancestor::* [ following-sibling::* [
not( @class = 'content-less' )
]
][1]
/ following-sibling::* [
not( @class = 'content-less' )
][1]
/ self::*
[
(@class = 'end-math')
or
(@class = 'end-script')
or
(@class = 'end-root')
or
(@class = 'end-stack')
or
(@class = 'mid-stack')
or
(@class = 'end-array')
or
self::td or self::mtd or self::tr or self::mtr
or
(@title = 'implicit-baseline')
]
]" >
<BREAK SIZE="small"/>
</xsl:template>
>>>
The following deals with endscripts before left sides of
tensors.
\<eliminate baseline script marks\><<<
<xsl:template match="span[
(@class = 'end-script')
and
parent::mrow / parent::msub
and
ancestor::* [ following-sibling::* ][1]
/ following-sibling::* [ normalize-space(.) != '' ][1]
[
(self::msub or self::msubsup)
and
(normalize-space(child::mrow[
@class = 'mrow-base' ]) = '')
]
]" >
<BREAK SIZE="small"/>
</xsl:template>
>>>
\<eliminate baseline script marks\><<<
<xsl:template match="span[
(@class = 'end-script')
and
parent::mrow /parent::*[ self::msup or self::msubsup]
and
ancestor::* [ following-sibling::* ][1]
/ following-sibling::* [ normalize-space(.) != '' ][1]
[
self::msup
and
(normalize-space(child::mrow[
@class = 'mrow-base' ]) = '')
]
]" >
<BREAK SIZE="small"/>
</xsl:template>
>>>
\begin{verbatim}
<span class="end-script" title="speech-extra">
<PROS PITCH="-5">
<BREAK SIZE="medium"/>
<span class="scripts-extra"> baseline </span>
<BREAK SIZE="small"/>
</PROS>
</span>
</mrow>
</msup>
<span class="tiny-space"/>
<msup>
<mrow class="mrow-base"/>
<mrow class="mrow-super">
\end{verbatim}
%%%%%%%%%%%%%
\subsection{Clean Script Marks}
%%%%%%%%%%%%%
\<clean begin and mid script marks\><<<
<xsl:template match="span[
(@class = 'begin-script')
or (@class = 'mid-script')
]" >
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:apply-templates select="*|text()|comment()"
mode="clean-script" />
</xsl:copy>
</xsl:template>
<xsl:template match="*" mode="clean-script" >
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:apply-templates select="*|text()|comment()"
mode="clean-script" />
</xsl:copy>
</xsl:template>
<xsl:template match="text()" mode="clean-script" >
</xsl:template>
<xsl:template match="span[@class = 'scripts-extra']"
mode="clean-script" >
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:value-of select="
ancestor::span[
(@class = 'begin-script')
or (@class = 'mid-script') ] [1]
" />
</xsl:copy>
</xsl:template>
>>>
The following is for script annotation on empty msu::base.
\<remove marks on empty scripts\><<<
<xsl:template match="span[
((@class = 'begin-script') or (@class = 'mid-script'))
and
following-sibling::*
/ following-sibling::span[ @class = 'end-script' ]
and
following-sibling::*[1]
/ descendant-or-self::*[ not(self::PROS) ][1]
/ child::*[1][
(@class = 'mrow-base')
and
(normalize-space(.)='')
]
]" >
</xsl:template>
>>>
\begin{verbatim}
<span class="begin-script" title="speech-extra">
...
</span>
<PROS PITCH="+10">
<msub>
<mrow class="mrow-base"/>
<mrow class="mrow-sub">
...
</mrow>
</msub>
<mi>n</mi>
</PROS>
<span class="end-script" title="speech-extra">
...
\end{verbatim}
%%%%%%%%%%%%%
\subsection{Replace Nested Baseline Script Marks}
%%%%%%%%%%%%%
\<replace nested baseline script marks\><<<
<xsl:template match="span[
(@class = 'end-script')
and
ancestor::*[ preceding-sibling::* [
((@class = 'begin-script') or (@class = 'mid-script')) ]]
]" >
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:apply-templates select="
ancestor::*[ preceding-sibling::* [
((@class = 'begin-script') or
(@class = 'mid-script')) ]][1]
/ preceding-sibling::* [
((@class = 'begin-script') or
(@class = 'mid-script')) ][1]
" mode="script-copy" />
</xsl:copy>
</xsl:template>
>>>
\<replace nested baseline script marks\><<<
<xsl:template match="*|@*|text()|comment()"
mode="script-copy" >
<xsl:copy>
<xsl:apply-templates select="*|@*|text()|comment()" />
</xsl:copy>
</xsl:template>
<xsl:template match="span[
(@class = 'begin-script') or
(@class = 'mid-script') ]" mode="script-copy" >
<xsl:apply-templates select="*|text()|comment()" />
</xsl:template>
>>>
%%%%%%%%%%%%%
\subsection{Eliminate Begin Script Marks}
%%%%%%%%%%%%%
\<eliminate begin script marks\><<<
<xsl:template match="span[
(@class = 'begin-script')
and
following-sibling::* [1] / child::*[
(position() = 1)
and
(@class = 'mrow-base')
and
( normalize-space(.) = '' )
]
]" >
</xsl:template>
>>>
%%%%%%%%%%%%%
\subsection{Undo Empty Scripts}
%%%%%%%%%%%%%
\<special sub and super scripts\><<<
<script element="msup" >
<set name="m-sub-sup" >
`<open xslt script`>
`<undo if empty su`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="m-sub-sup" />
`<superscript 2 and 3 into verbose`>
</script>
<script element="msub" >
`<sub script`>
</script>
<script element="msubsup" >
`<subsup prime`>
`<sub sup script`>
`<sub superscript 2 and 3 into verbose`>
</script>
>>>
\<sub sup script\><<<
<set name="m-sub-sup" >
`<open xslt script`>
`<undo if empty su`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="m-sub-sup" />
>>>
\<sub script\><<<
<set name="m-sub-sup" >
`<open xslt script`>
`<undo if empty su`>
`<msub of log`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="m-sub-sup" />
>>>
\<undo if empty su\><<<
<xsl:template match="*[
(self::msup or self::msub or self::msubsup)
and
not(
child::mrow[ @class = 'mrow-sub' ]
/ child::*[ not(@title = 'speech-extra')
and
(normalize-space(.) != '')
]
)
and
not(
child::mrow[ @class = 'mrow-super' ]
/ child::*[ not(@title = 'speech-extra')
and
(normalize-space(.) != '')
]
)
]" >
<xsl:apply-templates select="child::mrow[
@class = 'mrow-base' ]/*" />
</xsl:template>
>>>
\begin{verbatim}
<msup>
<mrow class="mrow-base">
.........
</mrow>
<wrow class="mrow-super">
<span class="begin-script"> superscript </span>
<span class="end-script"> baseline </span>
</mrow>
</msup>
\end{verbatim}
%%%%%%%%%%%%%
\section{Special Subscripts and Superscripts}
%%%%%%%%%%%%%
%%%%%%%%%%%%%
\subsection{Squared}
%%%%%%%%%%%%%
\<superscript 2 and 3 into verbose\><<<
<set name="m-sup-2-3" >
`<open xslt script`>
`<superscript into squared and cube`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="m-sup-2-3" />
>>>
\<superscript into squared and cube\><<<
<xsl:template match="msup[
(normalize-space(
child::mrow[ (@class = 'mrow-super') ]
/ child::*[ not (@class = 'begin-script')
and
not (@class = 'end-script')
]
) = '2')
and `<su verbose not on op`>
and (normalize-space(mrow[@class = 'mrow-base']) != '' )
]" >
<xsl:copy>
<xsl:apply-templates select="*|@*|text()|comment()"
mode="squared" />
</xsl:copy>
</xsl:template>
>>>
\<su verbose not on op\><<<
not(
child::mrow[ @class = 'mrow-base' ]
/ child::span[ not( @title = 'speech-extra' ) ]
[ position() = last() ]
/ self::* [ @class = 'mo-op' ]
)
>>>
\<superscript into squared and cube\><<<
<xsl:template match="*|@*|text()|comment()"
mode="squared" >
<xsl:copy>
<xsl:choose>
<xsl:when test=" @class = 'mrow-super' ">
<xsl:apply-templates select="@*" />
<mo class="mo-op">
<xsl:text> squared </xsl:text>
</mo>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="*|@*|text()" />
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
>>>
\begin{verbatim}
<msup>
<mrow class="mrow-base">
<mo class="mo-op">cos</mo>
</mrow>
<mrow class="mrow-super">
<span class="begin-script"> superscript </span>
<span class="mn">2</span>
<span class="end-script"> baseline </span>
</mrow>
</msup>
\end{verbatim}
\<superscript into squared and cube\><<<
<xsl:template match="msup[
(normalize-space(
child::mrow[ (@class = 'mrow-super') ]
/ child::*[ not (@class = 'begin-script')
and
not (@class = 'end-script')
]
) = '3')
and `<su verbose not on op`>
and (normalize-space(mrow[@class = 'mrow-base']) != '' )
]" >
<xsl:copy>
<xsl:apply-templates select="*|@*|text()|comment()"
mode="cube" />
</xsl:copy>
</xsl:template>
>>>
\<superscript into squared and cube\><<<
<xsl:template match="*|@*|text()|comment()"
mode="cube" >
<xsl:copy>
<xsl:choose>
<xsl:when test=" @class = 'mrow-super' ">
<xsl:apply-templates select="@*" />
<mo class="mo-op">
<xsl:text> cube </xsl:text>
</mo>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="*|@*|text()" />
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
>>>
\<sub superscript 2 and 3 into verbose\><<<
<set name="m-subsup-2-3" >
`<open xslt script`>
`<subsup into sub squared and cube`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="m-subsup-2-3" />
>>>
\<subsup into sub squared and cube\><<<
<xsl:template match="msubsup[
(normalize-space(
child::mrow[ (@class = 'mrow-super') ]
/ child::span[ (@class != 'mid-script')
and
(@class != 'end-script')
]
) = '2')
and `<su verbose not on op`>
]" >
<xsl:copy>
<xsl:attribute name="class" >
<xsl:text>msub</xsl:text>
</xsl:attribute>
<xsl:apply-templates select="*|text()|comment()"
mode="sub-squared" />
</xsl:copy>
</xsl:template>
>>>
\<subsup into sub squared and cube\><<<
<xsl:template match="*|@*|text()|comment()"
mode="sub-squared" >
<xsl:copy>
<xsl:choose>
<xsl:when test=" @class = 'mrow-sub' ">
<xsl:apply-templates select="*[
not( @class = 'end-script' )
]
|@*|text()|comment()" />
<xsl:apply-templates select="
following-sibling::*[1] / *[
@class = 'end-script'
] " />
</xsl:when>
<xsl:when test=" @class = 'mrow-super' ">
<xsl:attribute name="class" >
<xsl:text>squared-super</xsl:text>
</xsl:attribute>
<mo class="mo-op">
<xsl:text> squared </xsl:text>
</mo>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="*|@*|text()|comment()" />
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
>>>
\<subsup into sub squared and cube\><<<
<xsl:template match="msubsup[
(normalize-space(
child::mrow[ (@class = 'mrow-super') ]
/ child::span[ (@class != 'mid-script')
and
(@class != 'end-script')
]
) = '3')
and `<su verbose not on op`>
]" >
<xsl:copy>
<xsl:attribute name="class" >
<xsl:text>msub</xsl:text>
</xsl:attribute>
<xsl:apply-templates select="*|text()|comment()"
mode="sub-cube" />
</xsl:copy>
</xsl:template>
>>>
\<subsup into sub squared and cube\><<<
<xsl:template match="*|@*|text()|comment()"
mode="sub-cube" >
<xsl:copy>
<xsl:choose>
<xsl:when test=" @class = 'mrow-sub' ">
<xsl:apply-templates select="*[
not( @class = 'end-script' )
]
|@*|text()|comment()" />
<xsl:apply-templates select="
following-sibling::*[1] / *[
@class = 'end-script'
] " />
</xsl:when>
<xsl:when test=" @class = 'mrow-super' ">
<xsl:attribute name="class" >
<xsl:text>cube-super</xsl:text>
</xsl:attribute>
<mo class="mo-op">
<xsl:text> cube </xsl:text>
</mo>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="*|@*|text()|comment()" />
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
>>>
%%%%%%%%%%%%%
\subsection{Numeric Subscripts (Rule 77)}
%%%%%%%%%%%%%
\<compress numeric subscripts\><<<
<set name="num-sub" >
`<open xslt script`>
`<num sub`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="num-sub" />
>>>
\<num sub\><<<
<xsl:template match="msub[
(
`<num sub on non-primed base`>
or
`<num sub on primed base`>
)
and
child::mrow[ @class = 'mrow-sub' ]
/ child::*[ not(@title = 'speech-extra') ][1]
/ self::*[
normalize-space(.)
= normalize-space( descendant::mn ) ]
]" >
<xsl:copy>
<xsl:apply-templates select="@*" />
<BREAK SIZE="small"/>
<xsl:apply-templates select="*[1]" />
<mrow class="mrow-sub">
<xsl:apply-templates
select="*[2] / *[
not(@title = 'speech-extra')
]" />
<BREAK SIZE="small"/>
</mrow>
</xsl:copy>
</xsl:template>
>>>
\<num sub on non-primed base\><<<
(count( child::mrow[ @class = 'mrow-base' ]
/ child::* ) = 1 )
and child::mrow[ @class = 'mrow-base' ] / descendant::mi
and not( ancestor::*[
self::msub or self::msup or self::msubsup
] )
>>>
\<num sub on primed base\><<<
(
count( child::mrow[ @class = 'mrow-base' ]
/ child::* [
not(self::BREAK)
]
) = 2 )
and child::mrow[ @class = 'mrow-base' ] [
child::*[1][ self::mi ]
and
child::*[
(position() > 1)
and
(normalize-space(.) =
normalize-space(
descendant-or-self::span[
(@class = 'ch 2032') or (@class = 'ch 2033')
or (@class = 'ch 2034')
]
))
]
]
and not( ancestor::*[
self::msub or self::msup or self::msubsup
] )
>>>
\begin{verbatim}
<msub>
<mrow class="mrow-base">
<mi>x</mi>
</mrow>
<mrow class="mrow-sub">
<span class="begin-script" title="speech-extra"> subscript </span>
<mn>1</mn>
<span class="end-script" title="speech-extra"> baseline </span>
</mrow>
</msub>
\end{verbatim}
\<num sub\><<<
<xsl:template match="msubsup[
(
`<num sub on non-primed base`>
)
and
child::mrow[ @class = 'mrow-sub' ]
/ child::*[ not(@title = 'speech-extra') ][1]
/ self::*[
normalize-space(.)
= normalize-space( descendant::mn ) ]
]" >
<msup>
<BREAK SIZE="small"/>
<xsl:apply-templates select="*[1]" />
<mrow class="mrow-sub">
<xsl:apply-templates
select="*[2] / *[
not(@title = 'speech-extra')
]" />
<BREAK SIZE="small"/>
</mrow>
<xsl:apply-templates select="*[3]" />
</msup>
</xsl:template>
>>>
%%%%%%%%%%%%%
\subsection{Primes}
%%%%%%%%%%%%%
\<remove scrip indicators from primes\><<<
<xsl:template match="span[
(@class = 'begin-script')
and
following-sibling::*[ not(@title = 'speech-extra') ] [1]
/ descendant-or-self::*[ not( self::PROS ) ][1]
/
child::span / child::span[
(@class = 'ch 2032') or (@class = 'ch 2033')
or (@class = 'ch 2034')
]
]" >
<BREAK SIZE="small"/>
</xsl:template>
>>>
\<remove scrip indicators from primes\><<<
<xsl:template match="span[
(@class = 'end-script')
and
preceding-sibling::*[ not(@title = 'speech-extra') ] [1]
/ descendant-or-self::*[ not( self::PROS ) ][1]
/
child::span / child::span[
(@class = 'ch 2032') or (@class = 'ch 2033')
or (@class = 'ch 2034')
]
]" >
<BREAK SIZE="small"/>
</xsl:template>
>>>
\begin{verbatim}
<span class="msup">
<span class="mrow-base">
<span class="mi">x</span>
</span>
<span class="mrow-super">
<span class="begin-script"> superscript </span>
<span class="mo-op">
<span class="char">
<span class="ch 2033">double prime</span>
</span>
</span>
<span class="end-script"> baseline </span>
</span>
</span>
\end{verbatim}
\<subsup prime\><<<
<set name="subsup-prime" >
`<open xslt script`>
`<compress subsup prime`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="subsup-prime" />
>>>
\<compress subsup prime\><<<
<xsl:template match="msubsup[
(count(
child::mrow [ @class='mrow-super' ]
/ child::* [ not(@title = 'speech-extra') ]
) = 1)
and
not(
child::mrow [ @class='mrow-super' ]
/ child::* [ not(@title = 'speech-extra') ]
/ descendant::*[ preceding-sibling::*
or following-sibling::*]
)
and
child::mrow [ @class='mrow-super' ]
/ child::* [ not(@title = 'speech-extra') ]
/ descendant-or-self::span[ @class='char' ]
/ child::span[
(@class = 'ch 2032') or (@class = 'ch 2033')
or (@class = 'ch 2034')
]
]" >
<msub>
<mrow class="mrow-base">
<xsl:apply-templates select="
child::mrow[@class = 'mrow-base'] / *
" />
<BREAK SIZE="small"/>
<xsl:apply-templates select="
child::mrow[@class = 'mrow-super']
/ child::* [ not(@title = 'speech-extra') ]
" />
</mrow>
<mrow class="mrow-sub">
<xsl:apply-templates
select="*[@class = 'mrow-sub'] /* " />
<xsl:apply-templates select="
child::mrow[@class = 'mrow-super']
/ child::* [ @class = 'end-script' ]
" />
</mrow>
</msub>
</xsl:template>
>>>
\begin{verbatim}
<span class="msubsup">
<span class="mrow-base">
<span class="mi">x</span>
</span>
<span class="mrow-sub">
......
</span>
<span class="mrow-super">
<span class="mid-script" title="speech-extra"> superscript </span>
<span class="mi">
<span class="char" title="ch-verbose">
<span class="ch 2032" title="ch-verbose">prime</span>
</span>
</span>
</span>
</span>
\end{verbatim}
%%%%%%%%%%%%%
\subsection{Degree}
%%%%%%%%%%%%%
\<remove scrip indicators from degree\><<<
<xsl:template match="mrow[
(@class = 'mrow-super')
and
parent::msup
and
(count( `<math content element`> ) = 1)
and
`<math content element`> [1][
normalize-space(.)
=
normalize-space(
descendant::span[@class = 'ch 2218']
)
]
]" >
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:apply-templates
select="*[not(@title = 'speech-extra')
and
not(self::BREAK)
]"
mode="degree" />
<BREAK SIZE="small"/>
</xsl:copy>
</xsl:template>
>>>
\<remove scrip indicators from degree\><<<
<xsl:template match="*" mode="degree" >
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:choose>
<xsl:when test="self::span[ @class='ch 2218' ]" >
<xsl:text>degree</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates
select="*[not(self::BREAK)]|text()"
mode="degree"/>
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
>>>
%%%%%%%%%%%%%
\subsection{Logarithms}
%%%%%%%%%%%%%
\<msub of log\><<<
<xsl:template match="
msub [
normalize-space(child::*[1]) = 'log'
or
normalize-space(child::*[1]) = 'ln'
]" >
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:apply-templates select="child::*[1]" />
<xsl:apply-templates select="child::*[2]"
mode="log" />
</xsl:copy>
</xsl:template>
>>>
\<msub of log\><<<
<xsl:template match="*" mode="log" >
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:choose>
<xsl:when test="parent::mrow[ @class = 'mrow-sub' ]" >
<BREAK SIZE="small"/>
<xsl:apply-templates select="*" />
<BREAK SIZE="small"/>
<span title="speech-extra">
<xsl:text>of</xsl:text>
</span>
<BREAK SIZE="small"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates
select="*[ not(@title = 'speech-extra') ]"
mode="log" />
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
>>>
\begin{verbatim}
<msub>
<mrow class="mrow-base">
<mo class="MathClass-op">log<BREAK SIZE="small"/></mo>
</mrow>
<mrow class="mrow-sub">
<span class="begin-script" title="speech-extra">
...
</span>
<PROS PITCH="-10">
<mn>2</mn>
</PROS>
<span class="end-script" title="speech-extra">
...
</span>
</mrow>
</msub>
<mi>x</mi>
\end{verbatim}
%%%%%%%%%%%%%%%%%%
\section{Fractions (Stage 1)}
%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%
\subsection{Outline}
%%%%%%%%%%%%%
\<span frac elements\><<<
<script element="mfrac" >
<set name="mfrac" >
`<open xslt script`>
`<frac templates`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="mfrac" />
</script>
>>>
\<frac templates\><<<
<xsl:template match="mfrac" >
<xsl:copy>
<xsl:choose>
`<word fracs`>
`<prepend continued fractions`>
`<tail continued fractions`>
<xsl:otherwise>
<xsl:apply-templates select="*|@*|text()|comment()" />
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
>>>
%%%%%%%%%%%%%
\subsection{Word Fractions}
%%%%%%%%%%%%%
Example: `\verb+1 \ove 2+' int `one half'
\<word fracs\><<<
<xsl:when test="
(string-length(
normalize-space(child::mrow[ @class = 'mrow-numerator' ][1])
) = 1)
and
(string-length(
normalize-space(child::mrow[ @class = 'mrow-enumerator' ][1])
) = 1)
">
`<a := numerator; b := enumerator`>
<xsl:choose>
<xsl:when test="
(translate($a,'123456789','') != '')
or
(translate($b,'123456789','') != '')
" >
<xsl:apply-templates select="*|@*|text()|comment()" />
</xsl:when>
<xsl:when test=" $a < $b ">
<xsl:attribute name="class">
<xsl:text>word-frac</xsl:text>
</xsl:attribute>
`<word numerator`>
`<word enumerator`>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="*|@*|text()|comment()" />
</xsl:otherwise>
</xsl:choose>
</xsl:when>
>>>
\<a := numerator; b := enumerator\><<<
<xsl:variable name="a">
<xsl:value-of select="
normalize-space(child::mrow[ @class = 'mrow-numerator' ][1])
" />
</xsl:variable>
<xsl:variable name="b">
<xsl:value-of select="
normalize-space(child::mrow[ @class = 'mrow-enumerator' ][1])
" />
</xsl:variable>
>>>
\<word numerator\><<<
<xsl:choose>
<xsl:when test=" $a = 1 "><xsl:text> one </xsl:text></xsl:when>
<xsl:when test=" $a = 2 "><xsl:text> two </xsl:text></xsl:when>
<xsl:when test=" $a = 3 "><xsl:text> three </xsl:text></xsl:when>
<xsl:when test=" $a = 4 "><xsl:text> four </xsl:text></xsl:when>
<xsl:when test=" $a = 5 "><xsl:text> five </xsl:text></xsl:when>
<xsl:when test=" $a = 6 "><xsl:text> six </xsl:text></xsl:when>
<xsl:when test=" $a = 7 "><xsl:text> seven </xsl:text></xsl:when>
<xsl:when test=" $a = 8 "><xsl:text> eight </xsl:text></xsl:when>
<xsl:when test=" $a = 9 "><xsl:text> nine </xsl:text></xsl:when>
</xsl:choose>
>>>
\<word enumerator\><<<
<xsl:choose>
<xsl:when test=" $b = 2 "><xsl:text> half</xsl:text></xsl:when>
<xsl:when test=" $b = 3 "><xsl:text> third</xsl:text></xsl:when>
<xsl:when test=" $b = 4 "><xsl:text> fourth</xsl:text></xsl:when>
<xsl:when test=" $b = 5 "><xsl:text> fifth</xsl:text></xsl:when>
<xsl:when test=" $b = 6 "><xsl:text> sixth</xsl:text></xsl:when>
<xsl:when test=" $b = 7 "><xsl:text> seventh</xsl:text></xsl:when>
<xsl:when test=" $b = 8 "><xsl:text> eighth</xsl:text></xsl:when>
<xsl:when test=" $b = 9 "><xsl:text> nineth</xsl:text></xsl:when>
</xsl:choose>
<xsl:if test=" $a > 1 "><xsl:text>s</xsl:text></xsl:if>
<xsl:text> </xsl:text>
>>>
%%%%%%%%%%%%%
\subsection{Mixed Fractions}
%%%%%%%%%%%%%
Examples: `\verb+2{3\over 4}+'
into `2 and three forth',
and `\verb+10{25\over 39}+' into `10 and 25 over 39'.
\<mixed fractions\><<<
<xsl:template match="mfrac[
(
(translate(
concat(
mrow[ (@class = 'mrow-numerator')],
mrow[ (@class = 'mrow-enumerator')]
) ,'0123456789','') = '')
and
not(descendant::*/descendant::*
/descendant::mn-group-s)
or
(@class = 'word-frac')
)
and
preceding-sibling::*[1]
/ self::mn-group-s[ child::*[
(position() = last())
and
self::mn
] ]
]" >
<xsl:text> and </xsl:text>
<xsl:copy>
<xsl:apply-templates select="*|@*|text()|comment()" />
</xsl:copy>
</xsl:template>
>>>
%%%%%%%%%%%%%
\subsection{Continued Fractions Conditions (Rule 69)}
%%%%%%%%%%%%%
\begin{verbatim}
1
1 + ---------------------------------------
1
2 + ---------------------------------------
1
2 + ---------------------------------------
2 + ...
\end{verbatim}
The fractions are processed recusrively from inside out. The `tail'
is the one to discover the inner most part of a continued fraction
(i.e., the bottom rows). Higher levels add to the nucleous built
already under them.
In Stage 1 the members of the continued fractions are marked as
such. In the second stage they being are procesed.
The minimum conditions here are three un-interrupted levels of
fractions.
\begin{verbatim}
<mfrac>
<mrow class="mrow-enumerator">
<mn>1</mn>
<mo class="MathClass-bin">...</mo>
<mfrac>
<span class="begin-end" ...>begin fraction</span>
<mrow class="mrow-numerator"> ... </mrow>
<span class="begin-end" ...>over</span>
<mrow class="mrow-enumerator">...</mrow>
<span class="begin-end" ...>end fraction</span>
</mfrac>
\end{verbatim}
\<a,b := top 2 pre op values\><<<
<xsl:variable name="a">
<xsl:apply-templates select="
child::mrow[ @class = 'mrow-enumerator' ] /
child::mfrac /
preceding-sibling::*[2]
" mode="enum-op" />
</xsl:variable>
<xsl:variable name="b">
<xsl:apply-templates select="
child::mrow[ @class = 'mrow-enumerator' ] /
child::mfrac /
child::mrow[ @class = 'mrow-enumerator' ] /
child::mfrac /
preceding-sibling::*[2]
" mode="enum-op" />
</xsl:variable>
<xsl:variable name="c">
<xsl:value-of select="
normalize-space(
child::mrow[ @class = 'mrow-enumerator' ] /
child::mfrac /
child::mrow[ @class = 'mrow-enumerator' ] /
child::mfrac /
child::mrow[ @class = 'mrow-enumerator' ] )
" />
</xsl:variable>
>>>
\<frac templates\><<<
<xsl:template match="*" mode="enum-op">
<xsl:if test="preceding-sibling::*" >
<xsl:apply-templates select=" preceding-sibling::*[1] " />
</xsl:if>
<xsl:value-of select="." />
</xsl:template>
>>>
%%%%%%%%%%%%%
\subsection{Nucleous of Continued Fractions}
%%%%%%%%%%%%%
We are looking for the three most internal (bottom) fractions that
belong to a continued fraction.
\<tail continued fractions\><<<
<xsl:when test=" `%check numeral numerator`%
(translate(
normalize-space(
child::mrow[ @class = 'mrow-numerator' ]),
'0123456789','')= '')
and `<check equality of numerators`>
and `<check ops before two top fracs`>
">
`<a,b := top 2 pre op values`>
<xsl:choose>
<xsl:when test="
( translate($a,'0123456789 ','') = '')
and (normalize-space($a)=normalize-space($b))
and starts-with( $c, normalize-space( $a ))
and starts-with(
normalize-space(
substring-after( $c, normalize-space( $a )) )
,
normalize-space(
child::mrow[ @class = 'mrow-enumerator' ] /
child::mfrac /
preceding-sibling::*[1] )
)
" >
<xsl:attribute name="class">
<xsl:value-of select=" 'continued-mfrac' " />
</xsl:attribute>
<xsl:apply-templates select="*|text()|comment()" />
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="*|@*|text()|comment()" />
</xsl:otherwise>
</xsl:choose>
</xsl:when>
>>>
\<check equality of numerators\><<<
( normalize-space(
child::mrow[ @class = 'mrow-numerator' ])
and
normalize-space(
child::mrow[ @class = 'mrow-enumerator' ] /
child::mfrac /
child::mrow[ @class = 'mrow-numerator' ])
)
and
( normalize-space(
child::mrow[ @class = 'mrow-enumerator' ] /
child::mfrac /
child::mrow[ @class = 'mrow-numerator' ])
and
normalize-space(
child::mrow[ @class = 'mrow-enumerator' ] /
child::mfrac /
child::mrow[ @class = 'mrow-enumerator' ] /
child::mfrac /
child::mrow[ @class = 'mrow-numerator' ])
)
>>>
\<check ops before two top fracs\><<<
( child::mrow[ @class = 'mrow-enumerator' ] /
child::mfrac /
preceding-sibling::*[1][@class = 'MathClass-bin']
)
and
( normalize-space(
child::mrow[ @class = 'mrow-enumerator' ] /
child::mfrac /
preceding-sibling::*[1] )
=
normalize-space(
child::mrow[ @class = 'mrow-enumerator' ] /
child::mfrac /
child::mrow[ @class = 'mrow-enumerator' ] /
child::mfrac /
preceding-sibling::*[1] )
)
>>>
%%%%%%%%%%%%%
\subsection{Prepend Existing Continued Fractions}
%%%%%%%%%%%%%
\<prepend continued fractions\><<<
<xsl:when test="
self::mfrac
and
child::mrow[ @class = 'mrow-enumerator' ]
/ child::mfrac[ @class = 'continued-mfrac' ]
and
( normalize-space(
child::mrow[ @class = 'mrow-numerator' ]
)
=
normalize-space(
child::mrow[ @class = 'mrow-enumerator' ]
/ child::mfrac[ @class = 'continued-mfrac' ]
/ child::mrow[ @class = 'mrow-numerator' ]
)
)
and `<check equality of op with cont frac`>
" >
`<a,b := cont top 2 pre op values`>
<xsl:choose>
<xsl:when test="
normalize-space($a)=normalize-space($b)
" >
<xsl:attribute name="class">
<xsl:value-of select=" 'continued-mfrac' " />
</xsl:attribute>
<xsl:apply-templates select="*|text()|comment()" />
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="*|@*|text()|comment()" />
</xsl:otherwise>
</xsl:choose>
</xsl:when>
>>>
\<check equality of op with cont frac\><<<
(
normalize-space(
child::span[ @class = 'mrow-enumerator' ] /
child::mfrac /
preceding-sibling::*[1] )
=
normalize-space(
child::span[ @class = 'mrow-enumerator' ] /
child::mfrac /
child::span[ @class = 'mrow-enumerator' ] /
child::span[ @class = 'continued-mfrac' ] /
preceding-sibling::*[1] )
)
>>>
\<a,b := cont top 2 pre op values\><<<
<xsl:variable name="a">
<xsl:apply-templates select="
child::span[ @class = 'mrow-enumerator' ] /
child::span[ @class = 'mcontinued-mfrac' ] /
preceding-sibling::*[2]
" mode="enum-op" />
</xsl:variable>
<xsl:variable name="b">
<xsl:apply-templates select="
child::span[ @class = 'mrow-enumerator' ] /
child::span[ @class = 'mcontinued-mfrac' ] /
child::span[ @class = 'mrow-enumerator' ] /
child::span[
self::mfrac or (@class = 'mcontinued-mfrac')
] /
preceding-sibling::*[2]
" mode="enum-op" />
</xsl:variable>
>>>
%%%%%%%%%%%%%%%%%%
\section{Fractions (Stage 2)}
%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%
\subsection{Outline}
%%%%%%%%%%%%%
\<set levels for hyper complex fracs\><<<
<dom name="." xml="." method="fracLevel" class="tex4ht.HtJsml" />
`<remove xml declaration`>
>>>
\<static void fracLevel(dom)\><<<
public static void fracLevel(Node d) {
dom = (Document) d;
setFracLevel(dom.getFirstChild(), 0);
}
private static int setFracLevel(Node node, int cont) {
int level = 0;
if (node.hasChildNodes()) {
String ndName = node.getNodeName();
int prevCont = cont;
String clValue = null;
if (ndName.equals("mfrac")) {
`<clValue := class of mfrac`>
`<cont := distance from mfrac(continued-frac)`>
}
`<level += inherited from children`>
`<return 0 if barier`>
if (ndName.equals("mfrac")) {
`<return 0 if mfrac barier`>
if( cont > 0 ){
if ( prevCont == 0 ){
`<set start continued fracs mark`>
}
`<remove end of non-tail continued frac`>
level = 0;
} else if ( prevCont > 0 ){
`<set end continued fracs mark`>
level = 0;
} else
if( level > 0 ){
`<set extra levels for frac`>
}
level++;
} }
return level;
}
>>>
%%%%%%%%%%%%%%%%%%
\subsection{Level Indicators for Nesting (Hyper Complex Fractions)}
%%%%%%%%%%%%%%%%%%
\begin{verbatim}
${a\over b}\over c$
begin begin fraction
begin fraction a
over b
end fraction
over over c
end end fraction
\end{verbatim}
\<set extra levels for frac\><<<
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE) {
Node cls = child.getAttributes()
.getNamedItem("class");
if (cls != null) {
String clsName = cls.getNodeValue();
if (clsName.equals("begin-end")) {
insertLevelPrefix(child, level);
} } } }
>>>
\<HtJsml utility members\><<<
private static void insertLevelPrefix(Node node, int level){
if( level == 0 ){ return; }
if (node.getNodeType() == Node.ELEMENT_NODE) {
if( node.getNodeName().equals( "level" ) ){
`<insert level prefixes`>
} else {
NodeList children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
insertLevelPrefix(child, level);
} } } }
>>>
\<insert level prefixes\><<<
Node attr = node.getAttributes().getNamedItem("prefix");
if( attr != null ){
String prefix = attr.getNodeValue();
String s = "";
for(int j=0; j<level; j++){
s += prefix + " ";
}
((org.w3c.dom.Element) node).setAttribute( "depth", ""+level);
Node child = node.getFirstChild();
if( child != null ){
node.insertBefore( dom.createTextNode(s), child );
} }
>>>
\<level += inherited from children\><<<
NodeList children = node.getChildNodes();
int max = 0;
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE) {
int d = setFracLevel(child,
`<continued level counter`>);
if (d > max) { max = d; }
} }
level += max;
>>>
%%%%%%%%%%%%%
\subsection{Level Terminators: Scripts, Word Fracs}
%%%%%%%%%%%%%
\<return 0 if barier\><<<
if( ndName.equals("msub")
|| ndName.equals("msup")
|| ndName.equals("msubsup")
) {
return 0;
}
>>>
\<return 0 if mfrac barier\><<<
if( (clValue != null) && clValue.equals("word-frac")
) {
return 0;
}
>>>
%%%%%%%%%%%%%
\subsection{Bookeeping for Continued Fractions}
%%%%%%%%%%%%%
\<continued level counter\><<<
cont
>>>
In the first phase, the mfrac elements in a group carry
attributes as in
\begin{verbatim}
<mfrac class="continued-mfrac">
\end{verbatim}
with the exception of the bottom (internal) most leveles.
The `cont' parameter is for determining whether the parent and the
grandparent are frac elements marked as continued.
\<clValue := class of mfrac\><<<
if (node.hasAttributes()) {
Node cl = node.getAttributes().getNamedItem("class");
if (cl != null) { clValue = cl.getNodeValue(); }
}
>>>
\<cont := distance from mfrac(continued-frac)\><<<
if( (clValue != null)
&& clValue.equals("continued-mfrac") ) {
cont = 2;
} else { cont--; }
>>>
%%%%%%%%%%%%%
\subsection{Modifications for Continued Fractions}
%%%%%%%%%%%%%
\<remove end of non-tail continued frac\><<<
Node child = node.getLastChild();
if (child.getNodeType() == Node.ELEMENT_NODE) {
Node cls = child.getAttributes() .getNamedItem("class");
if (cls != null) {
String clsName = cls.getNodeValue();
if ( clsName.equals("begin-end")) {
node.removeChild( child );
} } }
>>>
\<set end continued fracs mark\><<<
Node child = node.getLastChild();
if (child.getNodeType() == Node.ELEMENT_NODE) {
Node cls = child.getAttributes() .getNamedItem("class");
if (cls != null) {
String clsName = cls.getNodeValue();
if ( clsName.equals("begin-end")) {
setContinuedNote(child);
} } }
>>>
\<set start continued fracs mark\><<<
Node child = node.getFirstChild();
if (child.getNodeType() == Node.ELEMENT_NODE) {
Node cls = child.getAttributes() .getNamedItem("class");
if (cls != null) {
String clsName = cls.getNodeValue();
if ( clsName.equals("begin-end")) {
setContinuedNote(child);
} } }
>>>
\<HtJsml utility members\><<<
private static void setContinuedNote(Node node){
if (node.getNodeType() == Node.ELEMENT_NODE) {
if( node.getNodeName().equals( "level" ) ){
`<fix end continued note`>
} else {
NodeList children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
setContinuedNote(child);
} } } }
>>>
\<fix end continued note\><<<
Node attr = node.getAttributes().getNamedItem("continued");
if (attr != null) {
node = node.getFirstChild();
if( node != null ){
((org.w3c.dom.Text) node).setData( attr.getNodeValue() );
} }
>>>
%%%%%%%%%%%%%
\section{Set Levels on Roots}
%%%%%%%%%%%%%
\<set levels for roots\><<<
<dom name="." xml="." method="rootLevel" class="tex4ht.HtJsml" />
`<remove xml declaration`>
>>>
\<static void rootLevel(dom)\><<<
public static void rootLevel(Node d) {
dom = (Document) d;
setRootLevel(d.getFirstChild());
}
private static int setRootLevel( Node node ){
int level = 0;
// String clName = null;
if (node.hasChildNodes()) {
`<count root levels inherited from children`>
String ndName = node.getNodeName();
`<block for roots`>
if( ndName.equals("msqrt") || ndName.equals("mroot") ){
`<set extra levels for roots`>
level++;
} }
return level;
}
>>>
\<count root levels inherited from children\><<<
NodeList children = node.getChildNodes();
int max = 0;
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE) {
int d = setRootLevel(child);
if( d > max ){ max = d; }
} }
level += max;
>>>
\<block for roots\><<<
if( ndName.equals("msub") || ndName.equals("msup") ||
ndName.equals("msubsup")
) {
return 0;
}
>>>
\<set extra levels for roots\><<<
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE) {
Node cls = child.getAttributes()
.getNamedItem("class");
if (cls != null) {
String clsName = cls.getNodeValue();
if( clsName.equals("begin-root")
|| clsName.equals("mid-root")
|| clsName.equals("end-root")
){
insertLevelPrefix(child, level);
} } } }
>>>
%%%%%%%%%%%%%
\section{Modifiers}
%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%
\subsection{Over and Under Limit Scripts}
%%%%%%%%%%%%%%%%%%
\<over and under scripts\><<<
<script element="msub::limits-msub-msup" >
<set name="smash" >
`<open xslt script`>
`<smash over and under scripts`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="smash" />
</script>
>>>
\<over and under scripts\><<<
<script element="msup::limits-msub-msup" >
<set name="smash" >
`<open xslt script`>
`<smash over and under scripts`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="smash" />
</script>
>>>
\<over and under scripts\><<<
<script element="msubsup::limits-msub-msup" >
<set name="smash" >
`<open xslt script`>
`<smash over and under scripts`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="smash" />
</script>
>>>
\<smash over and under scripts\><<<
<xsl:template match="*[
(@class = 'limits-msub-msup')
and
child::*[ (position() = 1)
and (@class = 'limits-mrow-base')
and child::*[ (position() = 1)
and (@class = 'limits-msub-msup')
] ]
]" >
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:apply-templates select="
*[1]
/ *[1]
/ *[ not(@class='limits-mrow-super') ] " />
<xsl:apply-templates select=" *[
preceding-sibling::*
and
not(@class='limits-mrow-super') ]" />
<xsl:apply-templates select="
*[1]
/ *[1]
/ *[@class='limits-mrow-super' ] " />
<xsl:apply-templates select=" *[
preceding-sibling::*
and
(@class='limits-mrow-super') ]" />
</xsl:copy>
</xsl:template>
>>>
\<compress limit script\><<<
<xsl:template match="span[ @class = 'end-limits-script' ]" >
<xsl:if test=" parent::*[ not(following-sibling::*) ] ">
<xsl:copy>
<xsl:apply-templates select=" @* " />
<xsl:choose>
<xsl:when test="
parent::*[ preceding-sibling::mrow[
@class != 'limits-mrow-base'
] ]
" >
<BREAK SIZE="small"/>
<xsl:text> end scripts </xsl:text>
<BREAK SIZE="small"/>
</xsl:when>
<xsl:otherwise>
<BREAK SIZE="small"/>
<xsl:text> end script </xsl:text>
<BREAK SIZE="small"/>
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:if>
</xsl:template>
>>>
\<compress limit script\><<<
<xsl:template match="span[ @class = 'begin-limits-script' ]" >
<xsl:copy>
<xsl:apply-templates select=" @* " />
<xsl:choose>
<xsl:when test="
parent::*[ @class = 'limits-mrow-super' ]
" >
<xsl:apply-templates
select=" parent::*
/ preceding-sibling::*[1] "
mode = "extra-over" />
</xsl:when>
<xsl:when test="
parent::*[ @class = 'limits-mrow-sub' ]
" >
<xsl:apply-templates
select=" parent::*
/ preceding-sibling::*[1] "
mode = "extra-under" />
</xsl:when>
</xsl:choose>
<xsl:apply-templates select="*|text()|comment()" />
</xsl:copy>
</xsl:template>
>>>
\<compress limit script\><<<
<xsl:template match="*" mode="extra-over" >
<xsl:if test = " self::mrow[ @class = 'limits-mrow-super' ] " >
<xsl:text> over </xsl:text>
<xsl:apply-templates select=" preceding-sibling::*[1] "
mode = "extra-over" />
</xsl:if>
</xsl:template>
>>>
\<compress limit script\><<<
<xsl:template match="*" mode="extra-under" >
<xsl:if test = " self::mrow[ @class = 'limits-mrow-sub' ] " >
<xsl:text> under </xsl:text>
<xsl:apply-templates select=" preceding-sibling::*[1] "
mode = "extra-under" />
</xsl:if>
</xsl:template>
>>>
%%%%%%%%%%%%%
\subsection{Short Cuts for Math Underline}
%%%%%%%%%%%%%
\<short cut modifiers\><<<
<script element="munder::munder-underline" >
<set name="munder" >
`<open xslt script`>
`<get content template`>
`<under modifier templates`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="munder" />
</script>
>>>
\<under modifier templates\><<<
<xsl:template match="munder[
(@class = 'munder-underline')
and
child::mrow[
(@class = 'mo-0332')
and
descendant::mi
]
]" >
<xsl:variable name="content">
<xsl:apply-templates select="*" mode="content" />
</xsl:variable>
<xsl:choose>
<xsl:when test="
string-length( normalize-space( $content )) = 1
" >
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:apply-templates
select=" *[ @class != 'begin-end' ] " />
<span class="begin-end" title="speech-extra" >
<BREAK SIZE="small"/>
<xsl:text> under bar </xsl:text>
<BREAK SIZE="small"/>
</span>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
`<set munder`>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
>>>
The following code makes to push the munder's under the mover's.
\<set munder\><<<
<xsl:choose>
<xsl:when test="child::mrow / child::mover">
<xsl:apply-templates select="child::mrow / child::mover"
mode="under-mover" />
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select=" *|@*|text() " />
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
>>>
\<under modifier templates\><<<
<xsl:template match="*" mode="under-mover" >
<xsl:choose>
<xsl:when test="self::mover">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:apply-templates select="*" mode="under-mover" />
</xsl:copy>
</xsl:when>
<xsl:when test="self::mrow[ parent::mover ]">
<xsl:copy>
<xsl:apply-templates select="@*" />
`<cont under-mover`>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="." />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
>>>
\<cont under-mover\><<<
<xsl:choose>
<xsl:when test="child::mover">
<xsl:apply-templates select="*" mode="under-mover" />
</xsl:when>
<xsl:otherwise>
<munder class="munder-underline">
`<munder prefix`>
<mrow class="mo-0032">
<xsl:apply-templates select="*" />
</mrow>
`<munder postfix`>
</munder>
</xsl:otherwise>
</xsl:choose>
>>>
\<munder prefix\><<<
<xsl:apply-templates select="
ancestor::munder[1] / child::*[following-sibling::mrow]
"/>
>>>
\<munder postfix\><<<
<xsl:apply-templates select="
ancestor::munder[1] / child::*[preceding-sibling::mrow]
"/>
>>>
\begin{verbatim}
<munder class="munder-underline">
<span class="begin-end" title="speech-extra" > modified under </span>
<mrow class="mo-0332">
<mi>x</mi>
</mrow>
<span class="begin-end" title="speech-extra" > with bar </span>
</munder>
\end{verbatim}
%%%%%%%%%%%%%
\subsection{Short Cuts for Math Overline}
%%%%%%%%%%%%%
\<short cut modifiers\><<<
<script element="mover::mover-overline" >
<set name="mover" >
`<open xslt script`>
`<get content template`>
`<over modifier templates`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="mover" />
</script>
>>>
\<over modifier templates\><<<
<xsl:template match="mover[
(@class = 'mover-overline')
and
child::mrow[
(@class = 'mo-00AF')
and
descendant::mi
]
]" >
<xsl:variable name="content">
<xsl:apply-templates select="*" mode="content" />
</xsl:variable>
<xsl:choose>
<xsl:when test="
string-length( normalize-space( $content )) = 1
" >
`<set mover short cut`>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:apply-templates
select="*|text()|comment()" />
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
>>>
The following code makes to push the mover's under the munder's.
\<set mover short cut\><<<
<BREAK SIZE="small"/>
<xsl:choose>
<xsl:when test="child::mrow / child::munder">
<xsl:apply-templates select="child::mrow / child::munder"
mode="under-munder" />
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:apply-templates
select=" *[ @class != 'begin-end' ] " />
`<mover bar short cut`>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
>>>
\<over modifier templates\><<<
<xsl:template match="*" mode="under-munder" >
<xsl:choose>
<xsl:when test="self::munder">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:apply-templates select="*" mode="under-munder" />
</xsl:copy>
</xsl:when>
<xsl:when test="self::mrow[ parent::munder ]">
<xsl:copy>
<xsl:apply-templates select="@*" />
`<cont under-munder`>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="." />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
>>>
\<cont under-munder\><<<
<xsl:choose>
<xsl:when test="child::munder">
<xsl:apply-templates select="*" mode="under-munder" />
</xsl:when>
<xsl:otherwise>
<mover class="mover-overline">
<mrow class="mo-00AF">
<xsl:apply-templates select="*" />
</mrow>
`<mover bar short cut`>
</mover>
</xsl:otherwise>
</xsl:choose>
>>>
\<mover bar short cut\><<<
<span class="begin-end" title="speech-extra" >
<BREAK SIZE="small"/>
<xsl:text> over bar </xsl:text>
<BREAK SIZE="small"/>
</span>
>>>
\begin{verbatim}
<mover class="mover-overline">
<span class="begin-end" title="speech-extra"> modified above </span>
<mrow class="mo-00AF">
<span class="mathvariant-bold">
<span title="speech-extra" class="begin-end"> bold </span>
<mi class="mi">
<span title="speech-extra"
class="capital-description"> capital </span>
Z
</mi>
</span>
</mrow>
<span class="begin-end" title="speech-extra"> with bar </span>
</mover>
\end{verbatim}
%%%%%%%%%%%%%
\section{New Theorems}
%%%%%%%%%%%%%
\<boundaries on theorems\><<<
<script element="div::newtheorem" >
<set name="newtheorem" >
`<open xslt script`>
`<annotate bounderies of theorems`>
`<tags for empty templates`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="newtheorem" />
</script>
>>>
\<annotate bounderies of theorems\><<<
<xsl:template match="
div[ (@class='newtheorem')
and
descendant::*[ self::p ][1]
/ descendant::*[ self::span ][1]
[ @class = 'theorem-head' ]
]
" >
<xsl:copy>
<xsl:apply-templates select="*|@*|text()|comment()" />
<div class="begin-end" title="speech-extra">
<BREAK SIZE="small"/>
<xsl:value-of select="
concat( ' end ',
substring-before(`<new theorem header`>, ' ')
) " />
</div>
</xsl:copy>
</xsl:template>
>>>
\<new theorem header\><<<
concat(
normalize-space(
string(
descendant::*[ self::p ][1]
/ descendant::*[ self::span ][1]
[ @class = 'theorem-head' ]
) )
, ' '
)
>>>
%%%%%%%%%%%%%%%%%%
\section{Shared}
%%%%%%%%%%%%%%%%%%
\<open xslt script\><<<
<![CDATA[
<xsl:stylesheet version="1.0"
xmlns:xsl="
http://www.w3.org/1999/XSL/Transform"
>
<xsl:output omit-xml-declaration = "yes" />
>>>
\<close xslt script\><<<
<xsl:template match="*|@*|text()|comment()" >
<xsl:copy>
<xsl:apply-templates select="*|@*|text()|comment()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
]]>
>>>
\<get content template\><<<
<xsl:template match="*" mode="content" >
<xsl:choose>
<xsl:when test=" @class = 'char' " >
<xsl:if test="not( child::*[
(@class = 'ch 2032') or (@class = 'ch 2033')
or (@class = 'ch 2034')
] )">
<xsl:text>x</xsl:text>
</xsl:if>
</xsl:when>
<xsl:when test=" not(
(@title = 'speech-extra') or (@class = 'accent-char')
) " >
<xsl:apply-templates select="*|text()" mode="content" />
</xsl:when>
</xsl:choose>
</xsl:template>
>>>
\marginpar{Can dom be prevented from creating an xml declaration in
the output? The xslt part is there just to remove the undesirable
declaration.}
\<remove xml declaration\><<<
<set name="rmXmlDecl" >
`<open xslt script`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="rmXmlDecl" />
>>>
\ifdojava
\AtEndDocument{\Needs{%
"pushd \XTPIPES
;
jar cf tex4ht.jar *
;
popd
;
mv \XTPIPES tex4ht.jar \TEXMFTEXivBIN
;
if [ ! -d \TEXMFTEXivXTPIPES\space]; then exit 1; fi
;
cp \XTPIPES xtpipes/lib/*
\TEXMFTEXivXTPIPES
"}}
\fi
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{document}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%
\section{Odd Ends}
%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%
\subsection{Font Decorations}
%%%%%%%%%%%%%
\<bold math\><<<
<script element="span::mathvariant-bold" >
<set name="bold" >
`<open xslt script`>
`<get content template`>
`<math bold templates`>
`<close xslt script`>
</set>
<xslt name="." xml="." xsl="bold" />
</script>
>>>
\<math bold templates\><<<
<xsl:template match="span[ @class = 'mathvariant-bold' ]" >
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:variable name="content">
<xsl:apply-templates select="*" mode="content" />
</xsl:variable>
<xsl:choose>
<xsl:when test="
string-length( normalize-space( $content )) = 1
" >
<span class="begin-end" title="speech-extra" >
<xsl:text> bold </xsl:text>
</span>
<xsl:apply-templates select="*|text()|comment()" />
</xsl:when>
<xsl:otherwise>
<span class="begin-end" title="speech-extra" >
<xsl:text> begin bold </xsl:text>
</span>
<xsl:apply-templates select="*|text()|comment()" />
<span class="begin-end" title="speech-extra" >
<xsl:text> end bold </xsl:text>
</span>
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
>>>
%%%%%%%%%%%%%%%%%%
\section{Empty Elements}
%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%
\section{Prose}
%%%%%%%%%%%%%%%%%%