6.5 Hyper Complex Fractions

<..set levels for hyper complex fracs..>
 <dom name="." xml="." method="fracLevel" class="tex4ht.HtSpk" />
 <.remove xml declaration.>
-_-_-

<..static void fracLevel(dom)..>
 public static void fracLevel(Node dom) {
    setFracLevel(dom.getFirstChild(), 0);
 }
 private static int setFracLevel(Node node, int cont) {
   int level = 0;
   String clName = null;
   if (node.hasChildNodes()) {
     if (node.hasAttributes()) {
       Node cl = node.getAttributes().getNamedItem("class");
       if (cl != null) { clName = cl.getNodeValue(); }
     }
     <.count levels inherited from children.>
     if( clName != null ){
       <.block on sub and super scripts.>
       <.deal with continuou fracs.>
       if (clName.equals("mfrac")) {
         if( cont > 0 ){
           <.remove end of nested continuous frac.>
         } else if( level > 0 ){
           <.set extra levels for frac.>
         }
         level++;
   } } }
   return level;
 }
-_-_-

<..count 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 = setFracLevel(child,
            (clName != null) &&
             clName.equals("continuous-mfrac")?
             2 :
             ((clName != null) &&
               clName.equals("continuous-mfrac")?
                 (cont-1) : cont)
         );
       if (d > max) { max = d; }
 }  }
 level += max;
-_-_-

The ‘cont’ parameter is for determining whether the parent and the grandparent are frac elements marked as continuous.

<..block on sub and super scripts..>
 if( clName.equals("msub") || clName.equals("msup") ||
     clName.equals("msubsup")
 ) {
    return 0;
 }
-_-_-

<..deal with continuou fracs..>
 if( clName.equals("continuous-mfrac") ) {
    if( cont > 0 ){
      <.remove end of nested continuous frac.>
    } else { <.set continuous frac.> } root of continuous chain
    return 0;
 }
-_-_-

<..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")) {
          child = child.getFirstChild();
          String s = child.getNodeValue();
          String bg = "", ov = "", en = "";
          for(int j=0; j<level; j++){
             bg += " begin "; ov += " over "; en += " end ";
          }
          s = s.replaceFirst("begin", bg + "begin");
          s = s.replaceFirst("over", ov + "over");
          s = s.replaceFirst("end", en + "end");
          ((org.w3c.dom.Text) child).setData(s);
 } } } }
-_-_-

<..set continuous 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")) {
           child = child.getFirstChild();
           String s = child.getNodeValue();
           s = s.replaceFirst("begin", "begin continued");
           s = s.replaceFirst("end", "end continued");
           ((org.w3c.dom.Text) child).setData(s);
 } } } }
-_-_-

<..remove end of nested continuous 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  );
 }  }  }
-_-_-