From bcdf6c829c6761de02484473ebe43fa3760adcaa Mon Sep 17 00:00:00 2001
From: Norbert Preining <norbert@preining.info>
Date: Wed, 12 May 2021 03:01:15 +0000
Subject: CTAN sync 202105120301

---
 support/TeX4ht/source/tex4ht-oo-xtpipes.tex | 1981 +++++++++++++++++++++++++++
 1 file changed, 1981 insertions(+)
 create mode 100644 support/TeX4ht/source/tex4ht-oo-xtpipes.tex

(limited to 'support/TeX4ht/source/tex4ht-oo-xtpipes.tex')

diff --git a/support/TeX4ht/source/tex4ht-oo-xtpipes.tex b/support/TeX4ht/source/tex4ht-oo-xtpipes.tex
new file mode 100644
index 0000000000..efdede0a20
--- /dev/null
+++ b/support/TeX4ht/source/tex4ht-oo-xtpipes.tex
@@ -0,0 +1,1981 @@
+% $Id: tex4ht-oo-xtpipes.tex 740 2020-06-13 22:35:32Z karl $
+% htlatex tex4ht-oo-xtpipes "xhtml,next,3" "" "-d./"
+%
+% Copyright 2009-2020 TeX Users Group
+% Copyright 2001-2009 Eitan M. Gurari
+% Released under LPPL 1.3c+.
+% See tex4ht-cpright.tex for license text.
+
+\documentclass{article}
+    \Configure{ProTex}{log,<<<>>>,title,list,`,[[]]}
+    \usepackage{url}
+\begin{document}
+
+\input{common}
+\input{tex4ht-cpright}
+\input{tex4ht-dir}
+
+
+%%%%%%%%%%%%%%%%%%
+\section{Outline}
+%%%%%%%%%%%%%%%%%%
+
+
+%%%%%%%%%%%%%
+\subsection{Math}
+%%%%%%%%%%%%%
+
+
+\AtEndDocument{\OutputCodE\<oo-math.4xt\>}
+
+\Needs{"xmllint --valid --noout oo-math.4xt"} 
+
+
+
+
+
+\<oo-math.4xt\><<<
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE xtpipes SYSTEM "xtpipes.dtd" >
+<!-- oo-math.4xt (`version), generated from `jobname.tex
+     Copyright (C) 2009-2013 TeX Users Group
+     Copyright (C) `CopyYear.2006. Eitan M. Gurari
+`<TeX4ht copyright`> -->
+<xtpipes preamble="yes" signature="oo-math.4xt (`version)">
+   <sax content-handler="xtpipes.util.ScriptsManager,tex4ht.OomFilter" 
+        lexical-handler="xtpipes.util.ScriptsManagerLH" >
+      <script element="math:mtable" >
+         `<normalizing math tables`>
+      </script> 
+      <script element="math:math" >
+         `<handle mo elements`>
+         `<handle mrow elements`>
+         `<handle mspace elements`>
+      </script> 
+   </sax>
+</xtpipes>
+>>>
+
+
+
+
+
+
+
+\<handle mspace elements\><<<
+<set name="math:mspace" >
+   `<open mml xslt script`>
+   `<math:mspace templates`>
+   `<close xslt script`>
+</set>
+<xslt name="." xml="." xsl="math:mspace" />
+>>>
+
+
+\<math:mspace templates\><<<
+<xsl:template match="math:mspace" >
+  <math:mtext>  
+     <xsl:text> </xsl:text>
+  </math:mtext>
+</xsl:template> 
+>>>
+
+
+
+
+%%%%%%%%%%%%%
+\subsection{Text}
+%%%%%%%%%%%%%
+
+
+
+
+
+
+
+\AtEndDocument{\OutputCodE\<oo-text.4xt\>}
+
+\Needs{"xmllint --valid --noout oo-text.4xt"} 
+
+
+
+
+
+\<oo-text.4xt\><<<
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE xtpipes SYSTEM "xtpipes.dtd" >
+<!-- oo-text.4xt (`version), generated from `jobname.tex
+     Copyright (C) 2009-2013 TeX Users Group
+     Copyright (C) `CopyYear.2006. Eitan M. Gurari
+`<TeX4ht copyright`> -->
+<xtpipes preamble="yes" signature="oo-text.4xt (`version)">
+   <sax content-handler="xtpipes.util.ScriptsManager,tex4ht.OoFilter" 
+        lexical-handler="xtpipes.util.ScriptsManagerLH" >
+      <script element="text:bibliography-mark" >
+         `<bib mark`>
+      </script> 
+      <script element="table:table" >
+         `<normalizing text tables`>
+      </script> 
+      <script element="text:p" >
+         `<clean paragraphs`>
+      </script> 
+      <script element="text:h" >
+         `<spaces for headers`>
+      </script> 
+   </sax>
+</xtpipes>
+>>>
+
+
+%%%%%%%%%%%%%
+\subsubsection{Cross References}
+%%%%%%%%%%%%%
+
+This is not used anymore, the make4ht-t4htlinks DOM filter is used instead. The
+following code may produce broken or empty links, so it is not really usable.
+
+\<cross references\><<<
+<set name="t4ht-link" >
+   `<open oo xslt script`>
+    `<handle t4htlink elements`>
+   `<close xslt script`>
+</set>
+<xslt name="." xml="." xsl="t4ht-link" />
+>>>
+
+\<bib mark\><<<
+<set name="bib-mark" >
+   `<open oo xslt script`>
+    `<handle bib mark elements`>
+   `<close xslt script`>
+</set>
+<xslt name="." xml="." xsl="bib-mark" />
+>>>
+
+
+
+\<handle t4htlink elements\><<<
+<xsl:template match="t4htlink[ @href = concat('#',@name) ]" >
+  <xsl:apply-templates select="*|text()|comment()" />
+  <text:reference-mark>
+     <xsl:attribute name="text:name">
+        <xsl:value-of select="@name"/>
+     </xsl:attribute>
+     <xsl:text> </xsl:text>
+  </text:reference-mark>
+</xsl:template> 
+>>>
+
+\<handle t4htlink elements\><<<
+<xsl:template match="t4htlink[ not(@name) 
+                           and
+                               starts-with(@href, '#') 
+]" >
+  <xsl:apply-templates select="*|text()|comment()" />
+   <text:span>
+        <xsl:attribute name="text:style-name">
+           <xsl:text>reference-ref</xsl:text>
+        </xsl:attribute>
+     <text:reference-ref>
+        <xsl:attribute name="text:ref-name">
+           <xsl:value-of select="substring( @href, 2 )"/>
+        </xsl:attribute>
+        <xsl:attribute name="text:reference-format">
+           <xsl:text>text</xsl:text>
+        </xsl:attribute>
+        <xsl:text> </xsl:text>   
+     </text:reference-ref>
+   </text:span>
+</xsl:template> 
+>>>
+
+
+
+
+
+
+
+\<handle t4htlink elements\><<<
+<xsl:template match="t4htlink[ not(@name) 
+                           and
+                               not(starts-with(@href, '#')) 
+]" >
+  <text:a>
+     <xsl:attribute name="xlink:type">
+        <xsl:text>simple</xsl:text>
+     </xsl:attribute>
+     <xsl:attribute name="xlink:href">
+        <xsl:value-of select="@href"/>
+     </xsl:attribute>
+     <xsl:apply-templates select="*|text()|comment()" />
+  </text:a>
+</xsl:template> 
+>>>
+
+
+
+
+
+\<handle bib mark elements\><<<
+<xsl:template match="text:bibliography-mark" >
+   <xsl:copy>
+     <xsl:attribute name="text:identifier">
+        <xsl:value-of select="normalize-space(.)" />    
+     </xsl:attribute>         
+     <xsl:apply-templates select="@*" />
+   </xsl:copy>
+   <text:span>
+      <xsl:attribute name="text:style-name">
+         <xsl:text>reference-ref</xsl:text>
+      </xsl:attribute>
+      <text:reference-ref> 
+        <xsl:attribute name="text:ref-name">
+              <xsl:value-of 
+                 select="text:span/text:reference-ref/@text:ref-name"/> 
+        </xsl:attribute> 
+        <xsl:attribute name="text:reference-format">
+              <xsl:text>text</xsl:text> 
+        </xsl:attribute>         
+        <xsl:text> </xsl:text>
+      </text:reference-ref> 
+   </text:span>
+</xsl:template> 
+>>>
+
+
+
+
+
+\begin{itemize}
+\item
+External
+\begin{verbatim}
+<text:a xlink:type="simple" 
+        xlink:href="http:....">...</text:a>
+\end{verbatim}
+
+
+\item internal
+\url{http://www.linuxjournal.com/article/8112}
+
+
+\begin{verbatim}
+<text:reference-mark-start text:name="xx"/>
+is 
+<text:reference-mark-end text:name="xx"/>
+
+<text:reference-ref text:reference-format="direction" text:ref-name="xx">
+above
+</text:reference-ref> 
+\end{verbatim}
+
+\end{itemize}
+
+
+%%%%%%%%%%%%%
+\subsection{Java Utilities}
+%%%%%%%%%%%%%
+
+
+
+\AtEndDocument{\OutputCodE\<OoUtilities.java\>}
+
+\ifdojava
+  \Needs{"
+    javac OoUtilities.java -d \XTPIPES
+"}
+\fi
+
+\<OoUtilities.java\><<<
+package tex4ht;
+/* OoUtilities.java (`version), generated from `jobname.tex
+   Copyright (C) 2009-2013 TeX Users Group
+   Copyright (C) `CopyYear.2006. Eitan M. Gurari
+`<TeX4ht copyright`> */
+import org.w3c.dom.*;
+public class OoUtilities {
+  `<static void mtable(dom)`>
+  `<static void table(dom)`>
+  `<static boolean justSpace(node)`>
+}
+>>>
+
+
+  `<static boolean paragraph(node)`>
+
+
+%%%%%%%%%%%%%%%%%%
+\section{Text Table}
+%%%%%%%%%%%%%%%%%%
+
+% 
+% 
+% 
+% \<handle mrow elements\><<<
+% <set name="math:mtd" >
+%    `<open oo xslt script`>
+%    `<math:mtd templates`>
+%    `<close xslt script`>
+% </set>
+% <xslt name="." xml="." xsl="math:mtd" />
+% >>>
+% 
+% \<math:mtd templates\><<<
+% <xsl:template match="math:mtd" >
+%   <xsl:copy>
+%       <xsl:apply-templates select="*|text()" />
+%   </xsl:copy>
+% </xsl:template> 
+% >>>
+% 
+% 
+% \<math:mtd templates\><<<
+% <xsl:template match="math:mtable">
+%   <math:mtable math:columnalign="right left">
+%       <xsl:apply-templates select="*|text()" />
+%   </math:mtable>
+% </xsl:template> 
+% >>>
+% 
+% 
+% 
+
+ %%%%%%%%%%%%%
+\subsection{Outline}
+%%%%%%%%%%%%%
+
+
+
+
+
+\<normalizing text tables\><<<
+<dom name="." xml="." method="table" class="tex4ht.OoUtilities" />
+>>>
+
+
+\<static void table(dom)\><<<
+public static void table(Node dom) {
+      Node tblRow, tblCell, d;
+//      int cols = 0;
+   Node node = dom.getFirstChild();
+   `<bind text namespace prefixes in the root element`>
+   `<tblRow -= empty trailing rows`>
+   if( (tblRow != null) && (tblRow.getPreviousSibling() != null) ){
+     `<bool = is ruler row?`>
+     if( !bool ){
+        `<remove child spaces from row`>
+        `<remove trailing non-content row`>
+        tblCell = tblRow.getFirstChild();            
+        if( (tblCell != null)
+            && (tblCell.getNextSibling() == null)
+            && justSpace(tblCell)
+        ){
+          node.removeChild(tblRow); 
+   } }  } 
+   `<n := max number of cols`>
+   `<remove extra col declarations`>
+}
+>>>
+
+
+
+\begin{verbatim}
+<table:table >
+  <table:table-column table:style-name="equ-col"/> 
+  <table:table-column table:style-name="equ-num-col"/> 
+
+  <table:table-row> 
+    <table:table-cell table:style-name="equ-cell"> 
+       ....
+    </table:table-cell> 
+  </table:table-row> 
+
+  <table:table-row> 
+       ....
+  </table:table-row> 
+
+</table:table> 
+\end{verbatim}
+
+
+%%%%%%%%%%%%%
+\subsection{Remove Rows}
+%%%%%%%%%%%%%
+
+
+
+
+
+\<tblRow -= empty trailing rows\><<<
+tblRow = node.getLastChild();
+while( (tblRow != null) 
+//       && (tblRow.getNodeType() == Node.TEXT_NODE)
+//       && tblRow.getNodeValue().trim().equals("")             
+       && tblRow.getTextContent().trim().equals("")             
+){
+   node.removeChild(tblRow); 
+   tblRow = node.getLastChild();
+}
+>>>
+
+
+
+
+%%%%%%%%%%%%%
+\subsection{Remove Extra Column Declarations}
+%%%%%%%%%%%%%
+
+
+
+\<remove child spaces from row\><<<
+tblCell = tblRow.getFirstChild();    
+while( tblCell != null){
+  d = tblCell.getNextSibling();                
+  if( justSpace(tblCell) ){  tblRow.removeChild(tblCell);  }
+  tblCell = d;
+}
+>>>
+
+
+
+
+\<n := max number of cols\><<<
+int n = 0;
+tblRow = node.getFirstChild();
+while( tblRow != null ){
+   if( 
+       (tblRow.getNodeType() == Node.ELEMENT_NODE)
+     &&
+        tblRow.getNodeName().equals("table:table-row")             
+   ){
+      `<m := number of columns`>
+      if( m > n ){ n = m; }
+   }
+   tblRow = tblRow.getNextSibling();
+}  
+>>>
+
+\<m := number of columns\><<<
+int m = 0;
+tblCell = tblRow.getFirstChild();
+while( tblCell != null ){
+   if( 
+       (tblCell.getNodeType() == Node.ELEMENT_NODE)
+     &&
+        tblCell.getNodeName().equals("table:table-cell")             
+   ){
+      m++;
+      `<table:table-cell -= empty text:p`>
+   }
+   tblCell = tblCell.getNextSibling();
+}  
+>>>
+
+
+
+
+
+\<remove extra col declarations\><<<
+tblRow = node.getFirstChild();
+while( tblRow != null ){
+   d = tblRow.getNextSibling();
+   if( 
+       (tblRow.getNodeType() == Node.ELEMENT_NODE)
+     &&
+        tblRow.getNodeName().equals("table:table-column")             
+   ){
+      n--;
+      if( n < 0 ){
+        tblRow.getParentNode().removeChild(tblRow);
+  }  }  
+  tblRow = d;
+}
+>>>
+
+
+%%%%%%%%%%%%%
+\subsection{Remove Empty Paragraphs within Table Cell}
+%%%%%%%%%%%%%
+
+
+There is an exception for paragraphs that are the only child elements.
+
+
+\<table:table-cell -= empty text:p\><<<
+Node child = tblCell.getLastChild();
+while( child != null ){
+   Node prevChild = child.getPreviousSibling();
+   if( 
+       (child.getNodeType() == Node.ELEMENT_NODE)
+     &&
+        child.getNodeName().equals("text:p")             
+   ){
+     Node sibling = child.getPreviousSibling();
+     while( (sibling != null)
+            &&
+            (sibling.getNodeType() != Node.ELEMENT_NODE)
+     ){
+       sibling = sibling.getPreviousSibling();
+     }
+     if( sibling == null ){
+       sibling = child.getNextSibling();
+       while( (sibling != null)
+              &&
+              (sibling.getNodeType() != Node.ELEMENT_NODE)
+       ){
+          sibling = sibling.getNextSibling();
+     } }        
+     if( (sibling != null)
+         && child.getTextContent().trim().equals("")             
+     ){
+         tblCell.removeChild(child); 
+   } }
+   child = prevChild;
+}  
+>>>
+
+
+
+%%%%%%%%%%%%%
+\subsection{Test for Empty Nodes}
+%%%%%%%%%%%%%
+
+
+
+
+\<static boolean justSpace(node)\><<<
+static boolean justSpace(Node node){
+   if( node == null ){ return true; }
+   if( node.getNodeType() == Node.TEXT_NODE ){
+       if( !node.getNodeValue().trim().equals("") ){ return false; }
+   } else {
+       if( node.getNodeType() == Node.ELEMENT_NODE ){
+          String nm = node.getNodeName();
+          if( 
+                !nm.equals("table:table-cell")
+             && !nm.equals("text:p")
+          ){
+             return false;
+       }  }
+   }
+   if(!justSpace( node.getNextSibling() )){ return false; }
+   if(!justSpace( node.getFirstChild() )){ return false; }
+   return true;
+}
+>>>
+
+\<bool = is ruler row?\><<<
+boolean bool = false;
+if( tblRow.getNodeName().equals("table:table-row")
+    && tblRow.hasAttributes()      
+){
+   NamedNodeMap attributes = tblRow.getAttributes();
+   Node styleAttr = attributes.getNamedItem( "table:style-name" );
+   String style = (styleAttr==null)? null
+                                   : styleAttr.getNodeValue();
+   if( (style != null) 
+       && (   style.equals("hline-row")
+           || style.equals("cline-row")
+          )
+   ){
+     bool = true;
+}  }
+>>>
+
+%%%%%%%%%%%%%%%%%%
+\section{Nested Paragraphs (OoUtilities)}
+%%%%%%%%%%%%%%%%%%
+
+
+
+
+\<clean paragraphs\><<<
+<set name="text-p" >
+   `<open oo xslt script`>
+   `<remove nested text:p`>
+   `<remove nested text:p in biblatex`>
+   `<multicolumn styles`>
+   `<close xslt script`>
+</set>
+<xslt name="." xml="." xsl="text-p" />
+>>>
+
+
+
+
+\<remove nested text:p2???\><<<
+<xsl:template match="text:p[ @text:style-name = 'start_subjclass'
+                           ]" >
+   <xsl:comment>
+       <xsl:text>start-subjclass</xsl:text>
+   </xsl:comment>
+   <xsl:apply-templates select="*|text()|comment()" />
+</xsl:template> 
+<xsl:template match="text:p[ @text:style-name = 'end_subjclass'>
+   <xsl:apply-templates select="*|text()|comment()" />
+   <xsl:comment>
+       <xsl:text>end-subjclass</xsl:text>
+   </xsl:comment>
+</xsl:template> 
+>>>
+
+
+
+\<remove nested text:p\><<<
+<xsl:template match="text:p[ (count(child::*)=1)  
+                             and child::draw:frame
+                             and parent::text:p
+                           ]" >
+    <xsl:apply-templates select="child::draw:frame" />
+</xsl:template> 
+>>>
+
+
+
+\<remove nested text:p\><<<
+<xsl:template match="text:p[
+     child::text:p
+   and
+     (count(child::text:p) = count(child::*))
+ ]" >
+   <!--xsl:copy>
+      <xsl:attribute name="text:style-name">
+          <xsl:text>start_</xsl:text>
+         <xsl:value-of select="@text:style-name" />
+      </xsl:attribute-->      
+      <xsl:comment>
+          <xsl:text>start </xsl:text>
+          <xsl:value-of select=" @text:style-name " />
+     </xsl:comment>
+   <!--/xsl:copy-->
+       <xsl:apply-templates select="*|text()|comment()" mode="nested-p" />
+   <!--xsl:copy>
+      <xsl:attribute name="text:style-name">
+          <xsl:text>end</xsl:text>
+         <xsl:value-of select="@text:style-name" />
+      </xsl:attribute-->      
+      <xsl:comment>
+          <xsl:text>end_</xsl:text>
+          <xsl:value-of select=" @text:style-name " />
+     </xsl:comment>
+   <!--/xsl:copy-->
+</xsl:template> 
+>>>
+
+\<remove nested text:p\><<<
+<xsl:template match="*[not(text:p)]|text()|comment()" mode="nested-p" >
+  <xsl:copy/>
+</xsl:template> 
+>>>
+
+\<remove nested text:p\><<<
+<xsl:template match="text:p" mode="nested-p" >
+  <xsl:copy>
+      <xsl:attribute name="text:style-name">
+         <xsl:value-of select="parent::text:p/@text:style-name" />
+         <xsl:text>_</xsl:text>
+         <xsl:value-of select="@text:style-name" />
+         <xsl:text>_</xsl:text>
+         <xsl:value-of select="child::*[1]/@text:style-name" />
+      </xsl:attribute>      
+      <xsl:apply-templates select="@*[ name() != 'text:style-name' ]" />
+      <xsl:apply-templates select="*|text()|comment()" />
+  </xsl:copy>
+</xsl:template> 
+>>>
+
+\<remove nested text:p in biblatex\><<<
+<xsl:template
+    match="text:p[
+              parent::text:p/@text:style-name='printthebibliography-dd'
+          ]" 
+    mode="nested-p" >
+  <xsl:copy>
+      <xsl:attribute name="text:style-name">
+         <xsl:value-of select="'printthebibliography-dd'" />
+      </xsl:attribute>      
+      <xsl:apply-templates select="@*[ name() != 'text:style-name' ]" />
+      <xsl:apply-templates select="*|text()|comment()" />
+  </xsl:copy>
+</xsl:template> 
+>>>
+
+
+
+
+
+
+
+
+
+
+
+
+\<multicolumn styles\><<<
+<xsl:template match="text:p[  child::text:span[ 
+                       starts-with(@text:style-name, 'multicolumn-') 
+                     ] ]" >
+   <xsl:copy>
+       <xsl:apply-templates 
+            select="child::text:span[ 
+                       starts-with(@text:style-name, 'multicolumn-') ]
+                    /@*
+                   " />
+       <xsl:apply-templates select="*|text()|comment()" />
+   </xsl:copy>
+</xsl:template> 
+<xsl:template match="text:span[ 
+                       starts-with(@text:style-name, 'multicolumn-') ]" />
+>>>
+
+
+\<handle mixed content\><<<
+System.out.println("handle mixed content " + name);
+      int i=0;
+      for( Node nd = first; nd != null; nd = nd.getNextSibling() ){ 
+        nodeType = nd.getNodeType();
+        `<trace mixed content`>
+        i++;
+      }
+System.out.println("end handle mixed content " + name);
+>>>
+
+\<text:p into text:section\><<<
+System.out.println("text:p into text:section");
+>>>
+
+
+
+
+\<trace mixed content\><<<
+System.out.println(
+i + "     "+  ((Boolean)v.get(i))
++
+
+((nodeType == Node.TEXT_NODE)? 
+    ("  TEXT: " + nd.getNodeValue() )
+   : 
+(
+(nodeType == Node.ELEMENT_NODE)? 
+     ("  " + nd.getNodeName())
+     :
+     ""
+)
+));
+>>>>
+
+
+
+
+
+
+
+%%%%%%%%%%%%%%%%%%
+\section{Spaces for Headers}
+%%%%%%%%%%%%%%%%%%
+
+\<spaces for headers\><<<
+<set name="headers" >
+   `<open oo xslt script`>
+   `<algorithmic templates`>
+   `<biblatex bib templates`>
+   `<close xslt script`>
+</set>
+<xslt name="." xml="." xsl="headers" />
+>>>
+
+\<algorithmic templates\><<<
+<xsl:template match="text:h[@text:style-name='algorithmic-dt']" >
+  <xsl:copy>
+      <xsl:apply-templates select="@*" />
+      <xsl:apply-templates select="*|text()|comment()" mode="algorithmic"/>
+  </xsl:copy>
+</xsl:template> 
+>>>
+
+
+\<algorithmic templates\><<<
+<xsl:template match="*|@*|comment()" mode="algorithmic" >
+  <xsl:copy>
+      <xsl:apply-templates select="@*" />
+      <xsl:apply-templates select="*|text()|comment()" mode="algorithmic"/>
+  </xsl:copy>
+</xsl:template> 
+>>>
+
+
+
+\<algorithmic templates\><<<
+<xsl:template match="text()" mode="algorithmic" >
+   <xsl:value-of select="translate(.,' ','&#xA0;')"/>
+</xsl:template> 
+>>>
+
+
+\<biblatex bib templates\><<<
+<xsl:template match="text:h[
+     (@text:style-name='printthebibliography-dt')
+     and
+     (normalize-space()='')
+]" >
+</xsl:template> 
+>>>
+
+
+%%%%%%%%%%%%%%%%%%
+\section{mo}
+%%%%%%%%%%%%%%%%%%
+
+\<handle mo elements\><<<
+<set name="math:mo" >
+   `<open mml xslt script`>
+   <xsl:template match=" math:mo" >
+   <xsl:choose>
+     `<xsl:when mo...`>
+     `<xsl:when mo length ...`>
+     <xsl:otherwise>
+        <math:mo>
+           <xsl:apply-templates select="@*" />
+           <xsl:value-of select="normalize-space(.)" />
+        </math:mo>
+     </xsl:otherwise>
+   </xsl:choose>
+   </xsl:template> 
+   `<close xslt script`>
+</set>
+<xslt name="." xml="." xsl="math:mo" />
+>>>
+
+
+
+
+
+A translation of
+
+\begin{verbatim}
+          <math:mrow> 
+            <math:mn>2</math:mn> 
+            <math:mo>+</math:mo> 
+          </math:mrow> 
+\end{verbatim}
+
+to
+
+\begin{verbatim}
+          <math:mrow> 
+            <math:mn>2</math:mn> 
+            <math:mo form="postfix">+</math:mo> 
+          </math:mrow> 
+\end{verbatim}
+
+fails to satisfy OO. So the following alternative is offered
+
+\begin{verbatim}
+          <math:mrow> 
+            <math:mn>2</math:mn> 
+            <math:mtext>+</math:mtext> 
+          </math:mrow> 
+\end{verbatim}
+
+
+\<xsl:when mo...\><<<
+<xsl:when test=" 
+   (preceding-sibling::math:mn or preceding-sibling::math:mi)
+   and not(following-sibling::*)
+" >
+   <math:mtext>
+      <xsl:apply-templates select="*|@*|text()" />
+   </math:mtext>
+</xsl:when> 
+>>>
+
+
+
+
+Isolated mo elements are problematic (e.g., 
+\verb'<mtd><mo form="...">=</mo></mtd>') in OpenOffice
+(\url{http://lists.w3.org/Archives/Public/www-math/2006Jul/0012.html})
+so they are converted into mtext elements.
+
+
+
+
+\<xsl:when mo...\><<<
+<xsl:when test=" 
+   not((preceding-sibling::*) or following-sibling::*)
+" >
+   <math:mtext>
+      <xsl:apply-templates select="*|@*|text()" />
+   </math:mtext>
+</xsl:when> 
+>>>
+
+The original condition 
+   `not(preceding-sibling::* or following-sibling::*)'
+failed with java 1.6 at a MS OS. 
+
+
+\begin{verbatim}
+<?xml version="1.0" encoding="UTF-8"?> 
+<xsl:stylesheet version="1.0"
+      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+      xmlns:xlink="http://www.w3.org/1999/xlink"
+   >
+      <xsl:output omit-xml-declaration = "yes" />
+<xsl:template match="mo" >
+   <xsl:choose>
+      <xsl:when test="preceding-sibling::* or following-sibling::*" >
+      </xsl:when>
+    </xsl:choose>
+</xsl:template>
+</xsl:stylesheet>
+
+
+import java.io.*;
+import javax.xml.transform.*;
+import javax.xml.transform.stream.*;
+
+public class Test {
+   public static void main(String[] args)
+        throws TransformerConfigurationException,
+              TransformerException  {
+    try{
+       StreamSource xslt = new StreamSource(new File("test.xslt"));
+       TransformerFactory fc = TransformerFactory.newInstance();
+       Transformer transformer = fc.newTransformer( xslt );
+    } catch (javax.xml.transform.TransformerConfigurationException e){
+       
+    } catch (Exception e){
+       System.err.println(e);
+} } }
+\end{verbatim}
+
+
+
+
+Failes on braces within mo elements \verb+<math:mo>{</math:mo>+.
+Accepts them within mtext elements.
+
+
+\<xsl:when mo...\><<<
+<xsl:when test=" 
+   (.='{') or (.='}')
+" >
+   <math:mtext>
+      <xsl:apply-templates select="*|@*|text()" />
+   </math:mtext>
+</xsl:when> 
+>>>
+
+
+
+\begin{verbatim}
+A \begin{eqnarray}a&=&b\end{eqnarray} is translated by tex4ht into 
+ 
+    <mi>a</mi><mo>=</mo><mi>b</mi> 
+ 
+and is loaded as 
+ 
+     matrix {a # = # b} 
+ 
+by OO2 into a broken display.  The xtpipe phase `fixes' the problem by 
+producing improper mathml output 
+ 
+    <mi>a</mi><mtext>=</mtext><mi>b</mi> 
+ 
+which OO2 loads as 
+ 
+    matrix {a # "=" # b} 
+ 
+and provides proper display.  
+\end{verbatim}
+
+
+
+
+
+\<xsl:when mo...\><<<
+<xsl:when test="  . = '='" >
+  <xsl:choose>
+     <xsl:when test="   not(preceding-sibling::*)
+                     or not(following-sibling::*)
+                     or preceding-sibling::*[1] / self::math:mo
+     ">
+        <math:mtext>
+           <xsl:apply-templates select="*|@*|text()" />
+        </math:mtext>
+     </xsl:when>
+     <xsl:otherwise>
+        <math:mo>
+           <xsl:apply-templates select="*|@*|text()" />
+        </math:mo>
+     </xsl:otherwise>
+  </xsl:choose>
+
+</xsl:when> 
+>>>
+
+
+
+
+In cases like \verb!$m \bmod  n$!, OpenOffice swallos the characters following the first one.
+
+\<xsl:when mo length ...\><<<
+<xsl:when test=" string-length() &gt; 1 " >
+   <math:mtext>
+      <xsl:value-of select="normalize-space(.)" />
+   </math:mtext>
+</xsl:when> 
+>>>
+
+
+%%%%%%%%%%%%%%%%%%
+\section{mrow}
+%%%%%%%%%%%%%%%%%%
+
+
+
+OpenOffice 2 loads
+
+\begin{verbatim}
+<math:msub> 
+    <math:mrow> 
+      <math:mi>x</math:mi> 
+    </math:mrow> 
+    <math:mrow> 
+      <math:msub> 
+        <math:mrow> 
+          <math:mi>i</math:mi> 
+        </math:mrow> 
+        <math:mrow> 
+          <math:mi>j</math:mi> 
+        </math:mrow> 
+      </math:msub> 
+    </math:mrow> 
+  </math:msub> 
+\end{verbatim}
+
+and 
+ 
+\begin{verbatim}
+    <math:msub>  
+      <math:mi>x</math:mi>  
+      <math:msub>  
+        <math:mi>i</math:mi>  
+        <math:mi>j</math:mi>  
+      </math:msub>  
+    </math:msub>  
+\end{verbatim}
+
+into \verb'x_i_j' which is a broken expression. Editing in OpenOffice the source
+into 
+\verb'x_{i_j}'
+or
+\verb'{x}_{{i}_{j}}'
+
+
+
+
+
+
+
+
+\<handle mrow elements NO\><<<
+<set name="math:mrow" >
+   `<open mml xslt script`>
+   `<math:mrow templates`>
+   `<close xslt script`>
+</set>
+<xslt name="." xml="." xsl="math:mrow" />
+>>>
+
+
+
+
+
+\<math:mrow templates\><<<
+<xsl:template match=" math:mrow[ count(child::*)=1 ]" >
+      <xsl:apply-templates select="*|@*|text()" />  
+</xsl:template> 
+>>>
+
+
+\begin{verbatim}
+The output of tex4ht on $x_{i_j}$ is  
+ 
+   <math:msub> 
+       <math:mrow> 
+         <math:mi>x</math:mi> 
+       </math:mrow> 
+       <math:mrow> 
+         <math:msub> 
+           <math:mrow> 
+             <math:mi>i</math:mi> 
+           </math:mrow> 
+           <math:mrow> 
+             <math:mi>j</math:mi> 
+           </math:mrow> 
+         </math:msub> 
+       </math:mrow> 
+     </math:msub> 
+    
+and OO2 loads the code into a broken format and view x_i_j.  The same 
+outcome occurs when tex4ht is modified to produce the following output. 
+        
+       <math:msub> 
+         <math:mi>x</math:mi> 
+         <math:msub> 
+           <math:mi>i</math:mi> 
+           <math:mi>j</math:mi> 
+         </math:msub> 
+       </math:msub> 
+ 
+A manual editing of x_i_j into {x}_{{i}_{j}} or x_{i_j} provides the 
+proper display (and identical mathml code). 
+\end{verbatim}
+
+
+%%%%%%%%%%%%%%%%%%
+\section{Dimenstions of Math Tables}
+%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%
+\subsection{Background}
+%%%%%%%%%%%%%
+
+
+
+
+
+All columns explicitly require identical number of columns.
+
+Broken: 
+
+\begin{verbatim}
+<math:mtable > 
+  <math:mtr> 
+    <math:mtd columnalign="left"><math:mn>1</math:mn></math:mtd> 
+    <math:mtd columnalign="left"><math:mn>2</math:mn></math:mtd> 
+  </math:mtr> 
+  <math:mtr> 
+    <math:mtd columnalign="left"><math:mn>1</math:mn></math:mtd> 
+  </math:mtr> 
+</math:mtable> 
+\end{verbatim}
+
+Works:
+
+\begin{verbatim}
+<math:mtable > 
+  <math:mtr> 
+    <math:mtd columnalign="left"><math:mn>1</math:mn></math:mtd> 
+    <math:mtd columnalign="left"><math:mn>2</math:mn></math:mtd> 
+  </math:mtr> 
+  <math:mtr> 
+    <math:mtd columnalign="left"><math:mn>1</math:mn></math:mtd> 
+    <math:mtd columnalign="left"></math:mtd> 
+  </math:mtr> 
+</math:mtable> 
+\end{verbatim}
+
+
+The last \verb+\\+ produces extra line with single entry and no data.
+
+\begin{verbatim}
+$ 
+\begin{cases}  
+    1 & 2\\ 
+    3 & 4\\ 
+\end{cases} 
+$ 
+\end{verbatim}
+
+Singlton mspace breaks math tables:
+
+\begin{verbatim}
+<math:mtable> 
+  <math:mtr> 
+      <math:mtd><math:mn>1</math:mn></math:mtd> 
+      <math:mtd><math:mspace width="1em"/></math:mtd> 
+  </math:mtr> 
+</math:mtable> 
+\end{verbatim}
+
+%%%%%%%%%%%%%
+\subsection{Outline}
+%%%%%%%%%%%%%
+
+\<normalizing math tables\><<<
+<dom name="." xml="." method="mtable" class="tex4ht.OoUtilities" />
+>>>
+
+
+\<static void mtable(dom)\><<<
+public static void mtable(Node dom) {
+      Node mtr, mtd, d;
+      int cols = 0;
+  Node node = dom.getFirstChild();
+   `<remove trailing non-content entries`>
+   `<fill rows`>
+}
+>>>
+
+
+ 
+
+
+
+
+%%%%%%%%%%%%%
+\subsection{Remove Trailing Entries}
+%%%%%%%%%%%%%
+
+\<remove trailing non-content entries\><<<
+if (node.hasChildNodes()) {
+   mtr = node.getLastChild();
+   while( mtr != null){
+      if( mtr.getNodeType() == Node.ELEMENT_NODE ){
+         if (mtr.hasChildNodes()) {
+           mtd = mtr.getLastChild();            
+           int count = 0;
+           while( mtd != null){
+             if( mtd.getNodeType() == Node.ELEMENT_NODE ){
+                count++;
+                d = mtd.getFirstChild();                
+                if( d != null ){  
+                   `<remove mspace-only content`>
+                }
+                if( d != null ){  
+                   `<remove d, if white space text`>         
+             }  }
+             d = mtd;
+             mtd = mtd.getPreviousSibling();
+             `<remove d, if white space text`>
+             if( (d != null) 
+                  && (d.getNodeType() == Node.ELEMENT_NODE) ){
+               `<remove d, if trailing and childless node`>
+               if( d == null ){ count--; }
+           } } 
+           if( count > cols ){ cols = count; }
+      } }  
+      d = mtr;
+      mtr = mtr.getPreviousSibling();
+      `<remove d, if white space text`>         
+      if( d != null ){
+         `<remove d, if trailing and childless node`>
+}  }  }
+>>>
+
+
+\<remove d, if white space text\><<<
+if( 
+    (d.getNodeType() == Node.TEXT_NODE)
+    && d.getNodeValue().trim().equals("")
+){
+    d.getParentNode().removeChild(d); 
+    d = null;
+}
+>>>
+
+\<remove d, if trailing and childless node\><<<
+if( (d.getNextSibling()==null) 
+    && (d.getFirstChild()==null)  ){
+   d.getParentNode().removeChild(d); 
+   d = null;
+}
+>>>
+
+
+
+
+
+%%%%%%%%%%%%%
+\subsection{Fill Rows}
+%%%%%%%%%%%%%
+
+
+
+
+
+\<fill rows\><<<
+if (node.hasChildNodes()) {
+   mtr = node.getFirstChild();
+   while( mtr != null){
+      if( mtr.getNodeType() == Node.ELEMENT_NODE ){
+         int count = 0;
+         if (mtr.hasChildNodes()) {
+           mtd = mtr.getFirstChild(); 
+           while( mtd != null){
+             if( mtd.getNodeType() == Node.ELEMENT_NODE ){
+                `<insert new line text node`>
+                count++;
+             }  
+             mtd = mtd.getNextSibling();
+           }
+         } 
+         if( count < cols ){ 
+            `<fill with empty mtd nodes`>
+      }  }
+      mtr = mtr.getNextSibling();
+}  }  
+>>>
+
+\<fill with empty mtd nodes\><<<
+for(int i = count; i < cols; i++){
+  mtr.appendChild( ((Document) dom).createElement("math:mtd") );
+}
+>>>
+
+\<insert new line text node\><<<
+mtr.insertBefore( ((Document) dom).createTextNode("\n"), mtd );
+>>>
+
+
+%%%%%%%%%%%%%
+\subsection{mspace}
+%%%%%%%%%%%%%
+
+
+\<remove mspace-only content\><<<
+boolean remove = true;
+for(Node i=d; i!=null; i=i.getNextSibling() ){
+   if( (i.getNodeType() == Node.ELEMENT_NODE)  
+       && !i.getNodeName().equals("math:mspace") ) {
+      remove = false; break;
+}  }
+if( remove ){
+   while( d != null ){
+     mtd.removeChild(d); 
+     d = mtd.getFirstChild();
+}  }
+>>>
+
+%%%%%%%%%%%%%%%%%%
+\section{Shared}
+%%%%%%%%%%%%%%%%%%
+
+
+
+%%%%%%%%%%%%%
+\subsection{XSLT Setup}
+%%%%%%%%%%%%%
+
+
+
+
+
+\<open oo xslt script\><<<
+<![CDATA[ 
+   <xsl:stylesheet version="1.0"
+      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+
+      xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"   
+      xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"   
+      xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"   
+      xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"   
+      xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"   
+      xmlns:fo="http://www.w3.org/1999/XSL/Format"   
+      xmlns:xlink="http://www.w3.org/1999/xlink"   
+      xmlns:dc="http://purl.org/dc/elements/1.1/"   
+      xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0"   
+      xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"  
+      xmlns:svg="http://www.w3.org/2000/svg"   
+      xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0"   
+      xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"   
+      xmlns:math="http://www.w3.org/1998/Math/MathML"   
+      xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0"   
+      xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0"   
+      xmlns:ooo="http://openoffice.org/2004/office"   
+      xmlns:ooow="http://openoffice.org/2004/writer"   
+      xmlns:oooc="http://openoffice.org/2004/calc"   
+      xmlns:dom="http://www.w3.org/2001/xml-events"   
+      xmlns:xforms="http://www.w3.org/2002/xforms"   
+      xmlns:xsd="http://www.w3.org/2001/XMLSchema"   
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   >
+      <xsl:output omit-xml-declaration = "yes" />
+>>>
+
+
+
+\<open mml xslt script\><<<
+<![CDATA[ 
+   <xsl:stylesheet version="1.0"
+      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+      xmlns:math="http://www.w3.org/1998/Math/MathML"   
+      xmlns:xlink="http://www.w3.org/1999/xlink"   
+   >
+      <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> 
+]]>
+>>>
+
+
+
+
+%%%%%%%%%%%%%
+\subsection{Text Namespaces}
+%%%%%%%%%%%%%
+
+
+\<bind text namespace prefixes in the root elementNO\><<<
+((Element) node).setAttribute(
+      "xmlns:office",
+      "urn:oasis:names:tc:opendocument:xmlns:office:1.0"   
+);
+((Element) node).setAttribute(
+      "xmlns:style",
+      "urn:oasis:names:tc:opendocument:xmlns:style:1.0"   
+);
+((Element) node).setAttribute(
+      "xmlns:text",
+      "urn:oasis:names:tc:opendocument:xmlns:text:1.0"   
+);
+((Element) node).setAttribute(
+      "xmlns:table",
+      "urn:oasis:names:tc:opendocument:xmlns:table:1.0"   
+);
+((Element) node).setAttribute(
+      "xmlns:draw",
+      "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"   
+);
+((Element) node).setAttribute(
+      "xmlns:fo",
+      "http://www.w3.org/1999/XSL/Format"   
+);
+((Element) node).setAttribute(
+      "xmlns:xlink",
+      "http://www.w3.org/1999/xlink"   
+);
+((Element) node).setAttribute(
+      "xmlns:dc",
+      "http://purl.org/dc/elements/1.1/"   
+);
+((Element) node).setAttribute(
+      "xmlns:meta",
+      "urn:oasis:names:tc:opendocument:xmlns:meta:1.0"   
+);
+((Element) node).setAttribute(
+      "xmlns:number",
+      "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"  
+);
+((Element) node).setAttribute(
+      "xmlns:svg",
+      "http://www.w3.org/2000/svg"   
+);
+((Element) node).setAttribute(
+      "xmlns:chart",
+      "urn:oasis:names:tc:opendocument:xmlns:chart:1.0"   
+);
+((Element) node).setAttribute(
+      "xmlns:dr3d",
+      "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"   
+);
+((Element) node).setAttribute(
+      "xmlns:math",
+      "http://www.w3.org/1998/Math/MathML"   
+);
+((Element) node).setAttribute(
+      "xmlns:form",
+      "urn:oasis:names:tc:opendocument:xmlns:form:1.0"   
+);
+((Element) node).setAttribute(
+      "xmlns:script",
+      "urn:oasis:names:tc:opendocument:xmlns:script:1.0"   
+);
+((Element) node).setAttribute(
+      "xmlns:ooo",
+      "http://openoffice.org/2004/office"   
+);
+((Element) node).setAttribute(
+      "xmlns:ooow",
+      "http://openoffice.org/2004/writer"   
+);
+((Element) node).setAttribute(
+      "xmlns:oooc",
+      "http://openoffice.org/2004/calc"   
+);
+((Element) node).setAttribute(
+      "xmlns:dom",
+      "http://www.w3.org/2001/xml-events"   
+);
+((Element) node).setAttribute(
+      "xmlns:xforms",
+      "http://www.w3.org/2002/xforms"   
+);
+((Element) node).setAttribute(
+      "xmlns:xsd",
+      "http://www.w3.org/2001/XMLSchema"   
+);
+((Element) node).setAttribute(
+      "xmlns:xsi",
+      "http://www.w3.org/2001/XMLSchema-instance"
+);
+>>>
+
+
+%%%%%%%%%%%%%%%%%%
+\section{Unicode in mtex}
+%%%%%%%%%%%%%%%%%%
+
+Openoffice dies on non-breaking space characters \verb+&#xA0;+ within
+mtext.
+ 
+
+\begin{verbatim}
+\documentclass{amsart} 
+\begin{document} 
+  $\text{ the number of spanning trees of }$ 
+\end{document} 
+\end{verbatim}
+
+
+
+\AtEndDocument{\OutputCodE\<OomFilter.java\>}
+
+\ifdojava
+  \Needs{"
+    javac OomFilter.java     -d \XTPIPES
+"}
+\fi
+
+\<OomFilter.java\><<<
+package tex4ht;
+/* OomFilter.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 OomFilter extends XMLFilterImpl {
+     PrintWriter out = null;
+     boolean mtext = false;
+   public OomFilter( PrintWriter out, 
+                     PrintWriter log, boolean trace ){
+     this.out = out;
+   }
+   public void startElement(String ns, String sName,
+                           String qName, Attributes attr) {
+      if( qName.equals( "math:mtext" ) ){ mtext = true; }
+      try{
+           super.startElement(ns, sName, qName, attr);
+      } catch( Exception e ){
+        System.err.println( "--- OomFilter Error 1 --- " + e);
+      }  
+   }
+   public void endElement(String ns, String sName, String qName){
+      if( qName.equals( "math:mtext" ) ){ mtext = false; }
+      try{
+        super.endElement(ns, sName, qName);
+      } catch( Exception e ){
+        System.err.println( "--- OomFilter Error 2 --- " + e);
+   }  }
+   public void characters(char[] ch, int start, int length){
+      try{
+        if ( mtext ) {
+           for(int i = start; i<start+length; i++){
+              if( ch[i] == 160 ){ ch[i] = ' '; }
+        }  }
+        super.characters(ch, start, length);
+      } catch( Exception e ){
+        System.out.println( "--- OomFilter Error 3 --- " + e);
+}  }  }
+>>>
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{OoFilter}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+%%%%%%%%%%%%%
+\subsection{Outline}
+%%%%%%%%%%%%%
+
+
+\AtEndDocument{\OutputCodE\<OoFilter.java\>}
+
+\ifdojava
+  \Needs{"
+    javac OoFilter.java      -d \XTPIPES
+"}
+\fi
+
+\<OoFilter.java\><<<
+package tex4ht;
+/* OoFilter.java (`version), generated from `jobname.tex
+   Copyright (C) 2009-2010 TeX Users Group
+   Copyright (C) `CopyYear.2002. Eitan M. Gurari
+`<TeX4ht copyright`> */
+`<OoFilter imports`>
+public class OoFilter extends XMLFilterImpl {
+     PrintWriter out = null;
+   public OoFilter( PrintWriter out, 
+                    PrintWriter log, boolean trace ){
+     this.out = out;
+   }
+   public void startElement(String ns, String sName,
+                           String qName, Attributes attr) {
+      if( qName.equals( "draw:frame" ) ){ 
+        `<set dimensions of figures`>
+      }
+      try{
+           super.startElement(ns, sName, qName, attr);
+      } catch( Exception e ){
+        System.err.println( "--- OoFilter Error 1 --- " + e);      
+   }  }
+   public void processingInstruction(String target, String fileName) {
+      if( target.equals("tex4ht-lg") ){
+         fileName = fileName.trim();
+         if( fileName.replaceAll(" ","").startsWith("file=") ){
+            `<load font vars`>
+            `<load font styles`>
+   }  }  }
+}
+>>>
+
+
+
+%%%%%%%%%%%%%
+\subsection{Dimensions for Figures}
+%%%%%%%%%%%%%
+
+\<set dimensions of figures\><<<
+String name = attr.getValue("draw:name");
+if( (name != null) 
+    && (attr.getValue("svg:width") == null) 
+    && (attr.getValue("svg:height") == null) 
+){ 
+  java.awt.Image image = new javax.swing.ImageIcon(name).getImage(); 
+  int width = image.getWidth(null); 
+  int height = image.getHeight(null); 
+  if( (width>0) && (height>0) ){
+     org.xml.sax.helpers.AttributesImpl attrs = 
+                   new  org.xml.sax.helpers.AttributesImpl( attr );
+     attrs.addAttribute(null, "svg:width", "svg:width",
+                                 "String", (width * 72 / 110) + "pt");
+     attrs.addAttribute(null, "svg:width", "svg:height",
+                                 "String", (height * 72 / 110) + "pt");
+     attr = attrs; 
+} }
+>>>
+
+
+%%%%%%%%%%%%%
+\subsection{Font Styles}
+%%%%%%%%%%%%%
+
+
+
+
+\<load font styles\><<<
+int length = fileName.length();
+int loc = fileName.indexOf(fileName.charAt(length-1));           
+fileName = fileName.substring(loc+1,length-1);
+try{ 
+   String s = "";
+   FileReader fr  = new FileReader( fileName ); 
+   BufferedReader in = new BufferedReader( fr ); 
+                      `<htfcss from lg`>
+   `<rewind lg file`> `<font=(...) from lg`>
+   `<rewind lg file`> `<Font-css-base: ...`>
+   `<rewind lg file`> `<process Font-Size: ...`>
+   `<rewind lg file`> `<process Font(...)`>
+} catch(Exception e){ 
+   System.err.println( "--- OoFilter Error 2 --- " + e);      
+}  
+>>>
+
+\<rewind lg file\><<<
+in.close();
+fr  = new FileReader( fileName ); 
+in = new BufferedReader( fr ); 
+>>>
+
+
+
+
+
+
+
+
+\<htfcss from lg\><<<
+try{
+   String key = "", body = "";
+   while( (s=in.readLine()) != null ){ 
+     if( s.startsWith("htfcss: ") ){
+        s = s.substring(8);
+        int idx = s.indexOf(' ');
+        if( idx == 0 ){
+           body += s;
+        } else {
+           `<map += (key, body)`>
+           if( idx == -1 ){
+              key = s; body = "";
+           } else {
+              key = s.substring(0,idx);
+              body = s.substring(idx);
+   } }  }  }
+   `<map += (key, body)`>
+} catch(java.lang.NumberFormatException e){ 
+   System.err.println( "--- OoFilter Error 3 --- Improper record: " + s);
+}
+>>>
+
+
+
+
+\<map += (key, body)\><<<
+body = body.trim();
+if( body.startsWith( "@media " ) ){   
+   body = body.substring(7).trim();
+   if( body.startsWith("print ") ){
+     body = body.substring(6).trim();
+   } else { key = ""; }
+}
+if( !key.equals("") ){
+   String [] property = body.split(";");
+   for( int i=0; i<property.length; i++ ){
+      if( !property[i].trim().equals("") ){
+         int indx = property[i].indexOf(":");
+         if( indx != -1 ){
+            String name = property[i].substring(0,indx).trim();
+            String value = (property[i]+' ').substring(indx+1).trim();
+            if( !name.equals("") && !value.equals("") ){
+               `<map[key] += (name,value)`>
+}  }  }  }  }
+>>>
+
+
+\<map[key] += (name,value)\><<<
+if( map.containsKey(key) ){
+   HashMap <String,String> entry = map.get(key);
+   entry.put(name,value);
+}
+else
+{
+   HashMap <String,String> entry = new HashMap <String,String>();
+   entry.put(name,value);
+   map.put(key,entry);
+}
+>>>
+
+
+\<load font vars\><<<
+HashMap <String,HashMap <String,String>> map
+       = new HashMap<String,HashMap <String,String>>();
+>>>
+
+
+
+
+
+
+
+\<Font-css-base: ...\><<<
+try{
+   while( (s=in.readLine()) != null ){ 
+     if( s.startsWith("Font_css_base: ") ){
+       int idx = s.indexOf("Font_css_mag: ");
+       if( idx != -1 ){
+          String [] pattern = s.substring(15,idx).trim().split("%s");
+          if( pattern.length == 3 ){ font_css_base = pattern; }
+          pattern = (s+' ').substring(idx).trim().split("%s");
+          if( pattern.length == 2 ){ font_css_mag = pattern; }
+   } } }
+} catch(Exception e){ 
+   System.err.println( "--- OoFilter Error 4 --- Improper record: " + s);
+}
+>>>
+
+
+
+
+\<process Font-Size: ...\><<<
+try{
+   while( (s=in.readLine()) != null ){ 
+     if( s.startsWith("Font_Size:") ){
+        base_font_size = Integer.parseInt( s.substring(10).trim() ); 
+   } } 
+} catch(java.lang.NumberFormatException e){ 
+   System.err.println( "--- OoFilter Error 5 --- Improper record: " + s);
+}
+>>>
+
+\<process Font(...)\><<<
+try{
+   while( (s=in.readLine()) != null ){ 
+     if( s.startsWith("Font(") ){
+        String [] match = s.split("\"");
+        match[1] = match[1].trim();
+        match[2] = match[3].trim();
+        match[3] = match[5].trim();
+        match[4] = match[7].trim();
+        `<get font size`>
+        `<get font style`>
+   } } 
+} catch(Exception e){ 
+   System.err.println( "--- OoFilter Error 6 --- Improper record: " + s);
+}
+>>>
+
+
+
+
+\<get font style\><<<
+HashMap <String,String> entry = map.get(match[1]);
+if( (entry != null) || (second < 98) || (second > 102) ){
+   String styleName = font_css_base[0] + match[1] +
+                      font_css_base[1] + match[2] +
+                      font_css_base[2];
+   if( !match[4].equals("100") ){ 
+      styleName += font_css_mag[0] + match[4] + font_css_mag[1]; 
+   }
+   `<attr[style:style] := ...`>
+   super.startElement(null, "style:style", "style:style", attr);
+   `<attr[style:text-properties] := ...`>
+   super.startElement(null, "style:text-properties", 
+                                 "style:text-properties", attr);
+   super.endElement(null, "style:text-properties",
+                                       "style:text-properties");
+   super.endElement(null, "style:style", "style:style");
+}
+>>>
+
+
+\<attr[style:style] := ...\><<<
+org.xml.sax.helpers.AttributesImpl attr =
+                      new org.xml.sax.helpers.AttributesImpl();
+attr.addAttribute("", "style:name", "style:name", "String", styleName);
+attr.addAttribute("", "style:family", "style:family", "String", "text");
+>>>
+
+\<attr[style:text-properties] := ...\><<<
+attr = new org.xml.sax.helpers.AttributesImpl();
+if( entry != null ){
+   Object [] name = entry.keySet().toArray();
+   for(int i=0; i < name.length; i++){
+      String value = entry.get(name[i]);
+      attr.addAttribute("", "fo:" + (String) name[i],
+                            "fo:" + (String) name[i],
+                                                "String", value);
+}  }
+if( (second < 98) || (second > 102) ){
+   attr.addAttribute("", "fo:font-size", "fo:font-size", 
+                                  "String", (second / 10.0) + "pt");
+}
+>>>
+
+    
+%                     style:font-family-generic=\"swiss\"  
+%                     style:font-pitch=\"variable\"
+
+\<load font vars\><<<
+String [] font_css_base = {"" , "-", ""};
+String [] font_css_mag = {"x-x-", ""};
+>>>
+
+
+\<print font style css\><<<
+(IGNORED) fprintf(css_file, 
+   (Font_css_base == NULL)? ".%s-%s" : Font_css_base,
+   match[1], match[2]);
+if( !eq_str(match[4],"100") ){ 
+   (IGNORED) fprintf(css_file,
+   (Font_css_mag == NULL)? "x-x-%s" : Font_css_mag,
+   match[4]);
+}
+(IGNORED) fprintf(css_file, "{");
+if( (second < 98) || (second > 102) ){
+   (IGNORED) fprintf(css_file, "font-size:%d%c;", second, '%');
+}
+if( font_sty  ) {
+   (IGNORED) fprintf(css_file, font_sty->body);
+}
+(IGNORED) fprintf(css_file, "}\n");
+>>>
+
+
+
+
+
+\<get font size\><<<
+{  
+   if( match[3].replaceAll("[0-9]","").equals("") ){
+      second =   (int) 
+              (  Integer.parseInt( match[3] )
+               * Long.parseLong( match[4] )
+               / base_font_size
+              );
+      while( second > 700 ){  second /= 10; }
+   } else { second = 100; }
+   `<inspect font-size argument`>
+}
+>>>
+
+The following case handles cases like that of 
+`\verb'Font("ecti","1095","10","100")'', where
+\verb=base_font_size= is 11.
+
+\<inspect font-size argument\><<<
+if(  (int) (  Double.parseDouble(match[2])
+            / Long.parseLong(match[4])
+            + 0.5
+           )
+      == base_font_size
+){
+   second = 100;
+};
+>>>
+
+
+
+\<load font vars\><<<
+int base_font_size = 10;
+int second;
+>>>
+
+
+\<OoFilter imports\><<<
+import java.util.*;
+import org.xml.sax.helpers.*;
+import org.xml.sax.*;
+import java.io.PrintWriter;
+import java.io.BufferedReader;
+import java.io.FileReader;
+>>>
+
+
+\ifdojava
+\AtEndDocument{\Needs{%
+    "pushd \XTPIPES || exit 1
+     ;  
+     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}
-- 
cgit v1.2.3

