//
//  TeXML2TeX.js
//
//  transformTeXMLtoTeX(oTeXML.documentElement)
//  returns TeX-String from TeXML-Document-Node
//
//  conditional compiling since IE4's JScript3 
//  e.g. /*@if (@_jscript) IFIE @else @*/ ELSE /*@end @*/
//

    /*@cc_on @*/
	
    var isMSIEorWSH = /*@if (@_jscript) true; @else @*/ false; /*@end @*/  // TeXML2TeX.js with "MSIE" or "Windows Script Host 5.6"

    // from JsUnit/JsUtil, cf http://jsunit.berlios.de/index.html
    // MS engine does not implement ECMA standard Array.push and Array.pop until JScript 5.6

    /*@if (@_jscript)
	
            function Array_pop() {
                var obj;
                if( this instanceof Array && this.length > 0 )
                {
                    var last = parseInt( this.length ) - 1;
                    obj = this[last];
                    this.length = last;
                }
                return obj;
            }
            if( !Array.prototype.pop ) { Array.prototype.pop = Array_pop; }
			
            function Array_push() {
                var i = 0;
                if( this instanceof Array )
                {
                    i = this.length;
                    if( arguments.length > 0 )
                        this[arguments.length + this.length - 1] = null;
                    for( ; i < this.length; ++i )
                        this[i] = arguments[i - this.length + arguments.length];
                }
                return i;
            }
		   if( !Array.prototype.push ) { Array.prototype.push = Array_push; }
		   
    // END:JsUtil
	
		function Array_push_quirksmode() {
			var A_p = 0
			for (A_p = 0; A_p < arguments.length; A_p++) {
				this[this.length] = arguments[A_p]
			}
			return this.length
		}
		function Array_shift_quirksmode() {
			var A_s = 0
			var response = this[0]
			for (A_s = 0; A_s < this.length-1; A_s++) {
				this[A_s] = this[A_s + 1]
			}
			this.length--
			return response
		}
		if( !Array.prototype.shift ) { Array.prototype.shift = Array_shift_quirksmode; }
	
    @end @*/

if (typeof localNameDOMx=='undefined') {
  function localNameDOMx(o) { // /*@if (@_jscript) localNameDOMx(o) @else @*/ o.localName /*@end @*/
    return o.nodeName.split(':').pop(); } }
if (typeof hasAttributeDOMx=='undefined') {
  function hasAttributeDOMx(o,strAttrName) { // /*@if (@_jscript) hasAttributeDOMx(o,strAttrName) @else @*/ o.hasAttribute(strAttrName) /*@end @*/
    return /*@if (@_jscript) !!(o.getAttributeNode(strAttrName)); @else @*/ o.hasAttribute(strAttrName); /*@end @*/} }
if (typeof hasAttributesDOMx=='undefined') {
  function hasAttributesDOMx(o) { // /*@if (@_jscript) hasAttributesDOMx(o) @else @*/ o.hasAttributes() /*@end @*/
    return /*@if (@_jscript) !!(o.attributes && o.attributes.length); @else @*/ o.hasAttributes(); /*@end @*/} }

if (Node==null) {               //  IE4,IE5,IE6,WSH
    var Node = {
    ELEMENT_NODE:1,
    ATTRIBUTE_NODE:2,
    TEXT_NODE:3,                //  nodeName=#text
    CDATA_SECTION_NODE:4,       //  nodeName=#cdata-section
    ENTITY_REFERENCE_NODE:5,
    ENTITY_NODE:6,
    PROCESSING_INSTRUCTION_NODE:7,
    COMMENT_NODE:8,             //  nodeName=#comment
    DOCUMENT_NODE:9,            //  nodeName=#document
    DOCUMENT_TYPE_NODE:10,
    DOCUMENT_FRAGMENT_NODE:11,  //  nodeName=#document-fragment
    NOTATION_NODE:12
    } // var
}     // if



var TFpreface = new String('\n%%'+
                           '\n%%  Transformed (maybe w\/o some nodes) by'+
                           '\n%%    an experimental non-XSLT DOM\/JavaScript*'+
                           '\n%%    cf http:\/\/www.unterstein.net\/ML\/TeXML.js'+
                           '\n%%    cf http:\/\/www.unterstein.net\/ML\/TeXML2TeX.js*'+
                           '\n%%    [* variant includes MSIE6+, MSXML 3.x\/4.x, WSH 5.6]'+
                           '\n%%    cf http:\/\/www.unterstein.net\/TeXML.html#localfiles'+
                           '\n%%    \n');

function transformTeXMLtoTeX(oTeXML) { return TFpreface+TeXML2TeX(oTeXML); }

function TeXMLtoTeX(o) {  // wrapper for IE
    try {
		var result = transformTeXMLtoTeX(o.documentElement||o);
		/*@if (@_jscript) return result.replace(/\n/g,'\r\n');
		  @else @*/ return result;
		/*@end @*/
	} catch(e) { throw '[TeXMLtoTeX] '+(e.description||e.message); }
}


/*   **********************************************************
 *   JS-Object-Literals generated/transformed from entitagX.xml
 *   XML v1
 *   XSLTransformed by
 *   Transformiix
 *   http://www.mozilla.org/projects/xslt/
 */

var ent = {  //  351  Object-Literals for Entitags-Transformation

aacute:"\\'a", Aacute:"\\'A", acirc:"\\^a", Acirc:"\\^A", agrave:"\\`a",
Agrave:"\\`A", aring:"{\\aa}", Aring:"{\\AA}", atilde:"\\~a", Atilde:"\\~A",
auml:"\\\"a", Auml:"\\\"A", aelig:"{\\ae}", AElig:"{\\AE}", ccedil:"\\c{c}",
Ccedil:"\\c{C}", eth:"{\\dh}", ETH:"{\\DH}", eacute:"\\'e", Eacute:"\\'E",
ecirc:"\\^e", Ecirc:"\\^E", egrave:"\\`e", Egrave:"\\`E", euml:"\\\"e",
Euml:"\\\"E", iacute:"\\'{\\i}", Iacute:"\\'I", icirc:"\\^{\\i}", Icirc:"\\^I",
igrave:"\\`{\\i}", Igrave:"\\`I", iuml:"\\\"{\\i}", Iuml:"\\\"I", ntilde:"\\~n",
Ntilde:"\\~N", oacute:"\\'o", Oacute:"\\'O", ocirc:"\\^o", Ocirc:"\\^O",
ograve:"\\`o", Ograve:"\\`O", oslash:"{\\o}", Oslash:"{\\O}", otilde:"\\~o",
Otilde:"\\~O", ouml:"\\\"o", Ouml:"\\\"O", szlig:"{\\ss}", thorn:"{\\th}",
THORN:"{\\TH}", uacute:"\\'u", Uacute:"\\'U", ucirc:"\\^u", Ucirc:"\\^U",
ugrave:"\\`u", Ugrave:"\\`U", uuml:"\\\"u", Uuml:"\\\"U", yacute:"\\'y",
Yacute:"\\'Y", yuml:"\\\"y", abreve:"\\u{a}", Abreve:"\\u{A}", amacr:"\\=a",
Amacr:"\\=A", aogon:"\\k{a}", Aogon:"\\k{A}", cacute:"\\'c", Cacute:"\\'C",
ccaron:"\\v{c}", Ccaron:"\\v{C}", ccirc:"\\^c", Ccirc:"\\^C", cdot:"\\.c",
Cdot:"\\.C", dcaron:"\\v{d}", Dcaron:"\\v{D}", dstrok:"{\\dj}", Dstrok:"{\\DJ}",
ecaron:"\\v{e}", Ecaron:"\\v{E}", edot:"\\.e", Edot:"\\.E", emacr:"\\=e",
Emacr:"\\=E", eogon:"\\k{e}", Eogon:"\\k{E}", gacute:"\\'g", gbreve:"\\u{g}",
Gbreve:"\\u{G}", Gcedil:"\\c{G}", gcirc:"\\^g", Gcirc:"\\^G", gdot:"\\.g",
Gdot:"\\.G", hcirc:"\\^h", Hcirc:"\\^H", hstrok:"\u0127", Hstrok:"\u0126",
Idot:"\\.I", Imacr:"\\=I", imacr:"\\={\\i}", ijlig:"\\symbol{188}",
IJlig:"\\symbol{156}", inodot:"{\\i}", iogon:"\\k{i}", Iogon:"\\k{I}",
itilde:"\\~{\\i}", Itilde:"\\~I", jcirc:"\\^{\\j}", Jcirc:"\\^J",
kcedil:"\\c{k}", Kcedil:"\\c{K}", kgreen:"\u0138", lacute:"\\'l", Lacute:"\\'L",
lcaron:"\\v{l}", Lcaron:"\\v{L}", lcedil:"\\c{l}", Lcedil:"\\c{L}",
lmidot:"\u0140", Lmidot:"\u013F", longs:"{\\textlongs}", lstrok:"{\\l}", Lstrok:"{\\L}", nacute:"\\'n",
Nacute:"\\'N", eng:"{\\ng}", ENG:"{\\NG}", napos:"\u0149", ncaron:"\\v{n}",
Ncaron:"\\v{N}", ncedil:"\\c{n}", Ncedil:"\\c{N}", odblac:"\\H{o}",
Odblac:"\\H{O}", Omacr:"\\=O", omacr:"\\=o", oelig:"{\\oe}", OElig:"{\\OE}",
racute:"\\'r", Racute:"\\'R", rcaron:"\\v{r}", Rcaron:"\\v{R}", rcedil:"\\c{r}",
Rcedil:"\\c{R}", sacute:"\\'s", Sacute:"\\'S", scaron:"\\v{s}", Scaron:"\\v{S}",
scedil:"\\c{s}", Scedil:"\\c{S}", scirc:"\\^s", Scirc:"\\^S", tcaron:"\\v{t}",
Tcaron:"\\v{T}", tcedil:"\\c{t}", Tcedil:"\\c{T}", tstrok:"\u0167",
Tstrok:"\u0166", ubreve:"\\u{u}", Ubreve:"\\u{U}", udblac:"\\H{u}",
Udblac:"\\H{U}", umacr:"\\=u", Umacr:"\\=U", uogon:"\\k{u}", Uogon:"\\k{U}",
uring:"\\r{u}", Uring:"\\r{U}", utilde:"\\~u", Utilde:"\\~U", wcirc:"\\^w",
Wcirc:"\\^W", ycirc:"\\^y", Ycirc:"\\^Y", Yuml:"\\\"Y", zacute:"\\'z",
Zacute:"\\'Z", zcaron:"\\v{z}", Zcaron:"\\v{Z}", zdot:"\\.z", Zdot:"\\.Z",
half:"\\nicefrac{1}{2}", frac12:"\\nicefrac{1}{2}", frac14:"\\nicefrac{1}{4}",
frac34:"\\nicefrac{3}{4}", frac18:"\\nicefrac{1}{8}", frac38:"\\nicefrac{3}{8}",
frac58:"\\nicefrac{5}{8}", frac78:"\\nicefrac{7}{8}",
sup1:"{\\textonesuperior}", sup2:"{\\texttwosuperior}",
sup3:"{\\textthreesuperior}", plus:"\u002B", plusmn:"{\\textplusminus}",
lt:"{\\textless}", equals:"\u003D", gt:"{\\textgreater}",
divide:"{\\textdivide}", times:"{\\textmultiply}", curren:"{\\textcurrency}",
pound:"{\\pounds}", dollar:"{\\textdollar}", cent:"{\\textcent}",
yen:"{\\textyen}", num:"\\#", percnt:"\\%", amp:"\\&", ast:"\u002A",
commat:"\u0040", lsqb:"\u005B", bsol:"{\\textbackslash}", rsqb:"\u005D",
lcub:"\\{", horbar:"{\\textemdash}", verbar:"\u007C", rcub:"\\}",
micro:"{\\textmu}", ohm:"{\\textohm}", deg:"{\\textdegree}",
ordm:"{\\textordmasculine}", ordf:"{\\textordfeminine}", sect:"{\\textsection}",
para:"{\\textparagraph}", middot:"{\\textperiodcentered}",
larr:"{\\textleftpointingarrow}", rarr:"{\\textrightpointingarrow}",
uarr:"{\\textarrowup}", darr:"{\\textarrowdown}", copy:"{\\textcopyright}",
reg:"{\\textregistered}", trade:"{\\texttrademark}", brvbar:"{\\textbrokenbar}",
not:"{\\textlogicalnot}", sung:"\u2669", excl:"\u0021",
iexcl:"{\\textexclamdown}", quot:"{\\textquotedbl}", apos:"{\\textquotesingle}",
lpar:"\u0028", rpar:"\u0029", comma:"\u002C", lowbar:"\\_", hyphen:"\u002D",
period:"\u002E", sol:"\u002F", colon:"\u003A", semi:"\u003B", quest:"\u003F",
iquest:"{\\textquestiondown}", laquo:"{\\guillemotleft}",
raquo:"{\\guillemotright}", lsquo:"{\\textquoteleft}",
rsquo:"{\\textquoteright}", ldquo:"``", rdquo:"''", nbsp:"~", shy:"\\-",
emsp:"{\\kern1em}", ensp:"{\\enspace}", emsp13:"{\\kern.33em}",
emsp14:"{\\kern.25em}", numsp:"\u2007", puncsp:"{\\kern1pt}", thinsp:"\\,",
hairsp:"{\\kern.1em}", mdash:"---", ndash:"--", dash:"\u2010",
blank:"{\\textvisiblespace}", hellip:"{\\dots}", nldr:"\u2025",
frac13:"\\nicefrac{1}{3}", frac23:"\\nicefrac{2}{3}", frac15:"\\nicefrac{1}{5}",
frac25:"\\nicefrac{2}{5}", frac35:"\\nicefrac{3}{5}", frac45:"\\nicefrac{4}{5}",
frac16:"\\nicefrac{1}{6}", frac56:"\\nicefrac{5}{6}", incare:"\\nicefrac{c}{o}",
block:"\u2588", uhblk:"\u2580", lhblk:"\u2584", blk14:"\u2591", blk12:"\u2592",
blk34:"\u2593", marker:"\u25AE", cir:"\u25CB", squ:"\u25A1", rect:"\u25AD",
utri:"\u25B5", dtri:"\u25BF", star:"\u22C6", bull:"{\\textbullet}",
squf:"\u25AA", utrif:"\u25B4", dtrif:"\u25BE", ltrif:"\u25C2", rtrif:"\u25B8",
clubs:"\u2663", diams:"\u2666", hearts:"\u2665", spades:"\u2660", malt:"\u2720",
dagger:"{\\textdagger}", Dagger:"{\\textdaggerdbl}", check:"\u2713",
cross:"\u2717", sharp:"\u266F", flat:"\u266D", male:"\u2642", female:"\u2640",
phone:"\u260E", telrec:"\u2315", copysr:"\u2117", caret:"\\symbol{094}",
lsquor:"{\\quotesinglbase}", ldquor:"{\\quotedblbase}", fflig:"\uFB00",
filig:"\uFB01", ffilig:"\uFB03", ffllig:"\uFB04", fllig:"\uFB02", mldr:"\u2026",
rdquor:"{\\textquotedblleft}", rsquor:"{\\textquoteleft}", vellip:"\u22EE",
hybull:"\u2043", loz:"\u25CA", lozf:"\u2726", ltri:"\u25C3", rtri:"\u25B9",
starf:"\u2605", natur:"\u266E", rx:"{\\textrecipe}", sext:"\u2736",
target:"\u2316", dlcrop:"\u230D", drcrop:"\u230C", ulcrop:"\u230F",
urcrop:"\u230E", circ:"{\\textasciicircum}", tilde:"{\\textasciitilde}",
sbquo:"{\\quotesinglbase}", bdquo:"{\\quotedblbase}",
lsaquo:"{\\guilsinglleft}", rsaquo:"{\\guilsinglright}", euro:"{\\texteuro}" };


function TeXML2TeX(oTeXML) {  // returns String transformed from Object/Node oTeXML

var pfx = (oTeXML.prefix && oTeXML.namespaceURI=='http:\/\/www.unterstein.net\/ML\/TeXML') ? oTeXML.prefix+':' : '' ;

var t_match = {1:[],2:[],3:[],4:[],5:[],6:[],7:[],8:[],9:[],10:[],11:[],12:[]};  //  nodeType-Object/Array
    t_match[1][pfx+'TeXML'] = applyTemplates;
    t_match[1][pfx+'ANY']   = applyTemplates;
    t_match[1][pfx+'TeX']   = applyTemplates;
    t_match[1][pfx+'cmd']   = templateCMD;
    t_match[1][pfx+'env']   = templateENV;
    t_match[1][pfx+'opt']   = templateOPT;
    t_match[1][pfx+'arg']   = templateARG;
    t_match[1][pfx+'grp']   = templateGRP;
    t_match[1][pfx+'act']   = function(o) { return templateAttr(o,'on',''); }
    t_match[1][pfx+'par']   = function(o) { return applyTemplates(o)+'\n'; }
    t_match[1][pfx+'x']     = function(o) { return applyTemplates(o)+'\n'; }
    t_match[7]['TeX']       = function(o) { return o.nodeValue; }      //  processing_instruction_node
    t_match[3]['#text']          = function(o) { return o.nodeValue; } //  text_node
    t_match[4]['#cdata-section'] = function(o) { return o.nodeValue; } //  cdata_section_node
    t_match[1]['xhtml:a']        = templateA;
    t_match[1]['xhtml:img']      = function(o) { return '\\hyperimg{'+templateAttr(o,'src','')+'}'; }
    t_match[1]['xhtml:thead']    = templateTgroup;
    t_match[1]['xhtml:tfoot']    = templateTgroup;
    t_match[1]['xhtml:tbody']    = templateTgroup;
    t_match[1]['xhtml:tr']       = function(o) { o.normalize(); return applyTemplates(o)+' \\\\'; }
    t_match[1]['xhtml:td']       = templateTDTH;
    t_match[1]['xhtml:th']       = templateTDTH;
    //  isanENTITAG(o) creates t_match[1] entries on-the-fly and prefix-aware
    //  isanENTIREF(o) creates t_match[5] entries on-the-fly 

    function templateCMD(o) {  //  if not(args)+empty(cmd)+following(textnode): command<space>text  
        return [ 
        '\\'+templateAttr(o,'name','')+templateAttr(o,'args',(((!o.hasChildNodes())&&o.nextSibling&&(o.nextSibling.nodeType==Node.TEXT_NODE))?' ':'')) ,
        applyTemplates(o) 
        ].join('');
    }
    function templateENV(o) {
        var envname = new String(templateAttr(o,'bg','{')+templateAttr(o,'name','')+templateAttr(o,'eg','}'));
		return [
        templateAttr(o,'bc','\\begin')+envname+templateAttr(o,'args','') ,
        applyTemplates(o) ,
        templateAttr(o,'ec','\\end')+envname 
        ].join('');
    }
    function templateOPT(o) {
        return [
        templateAttr(o,'bg','[') ,
        applyTemplates(o) ,
        templateAttr(o,'eg',']')
        ].join('');
    }
    function templateARG(o) {
        return [
        templateAttr(o,'bg','{') ,
        applyTemplates(o) ,
        templateAttr(o,'eg','}')
        ].join('');
    }
    function templateGRP(o) {
        return [
        templateAttr(o,'bg','{')+templateAttrNMTOKENS(o,'name') ,
        applyTemplates(o) ,
        templateAttr(o,'eg','}')
        ].join('');
    }
    function templateA(o) {
        var results = new String('');
        var idlabel = templateAttr(o,'id',false);
        var hrefstr = templateAttr(o,'href',false);
        var idhyper = (o.hasChildNodes() && !hrefstr && idlabel);
        //  forematter
        if (idlabel && hrefstr)
        {
         results += '\\label{'+idlabel+'}';
        }
        //  childNodes
        if (hrefstr)
        {
         if  (hrefstr.charAt(0) == '#')
              results += '\\hyperlink{'+hrefstr.slice(1)+'}{'+applyTemplates(o)+'}';
         else results += '\\href{'+hrefstr+'}{'+applyTemplates(o)+'}';
        }
        else  //  not hrefstr
        {
         if  (idhyper)
              results += '\\hypertarget{'+idlabel+'}{'+applyTemplates(o)+'}';
         else results += '\\label{'+idlabel+'}';
        }
        //
        return results;
    }
    function templateTgroup(o) {
        var results = new String('');
        var oTgroup = new Object();
        //  childNodes
        //  if (o.localName == 'thead') return results;
        //  if (o.localName == 'tfoot') return results;
        if (localNameDOMx(o) == 'tbody')
            {
            var pfx = (isMSIEorWSH && o.prefix && o.namespaceURI=='http:\/\/www.w3.org\/1999\/xhtml') ? o.prefix+':' : '' ;
            oTgroup = o.parentNode.getElementsByTagName(pfx+'thead');
            for (var i=0; i<oTgroup.length; i++) results += applyTemplates(oTgroup[i]);
            oTgroup = o.parentNode.getElementsByTagName(pfx+'tbody');
            for (var i=0; i<oTgroup.length; i++) results += applyTemplates(oTgroup[i]);
            oTgroup = o.parentNode.getElementsByTagName(pfx+'tfoot');
            for (var i=0; i<oTgroup.length; i++) results += applyTemplates(oTgroup[i]);
            }
        //
        return results;
    }
    function templateTDTH(o) {
        var results = new String('');
        var colspan = (/*@if (@_jscript) !!(o.getAttributeNode('colspan')) @else @*/ o.hasAttribute('colspan')&&o.getAttributeNode('colspan').specified /*@end @*/) ? '\\multicolumn{'+o.getAttribute('colspan')+'}{'+templateAttr(o,'align','c').charAt(0)+'}{' : '' ;
        //  forematter
        if (colspan!='') results += colspan;
        if (localNameDOMx(o) == 'th') results += '\\bfseries ';
        //  childNodes
        results += applyTemplates(o);
        //  backmatter
        if (colspan!='') results += '}';
        if (o.nextSibling && (o.nextSibling.nodeType!=Node.TEXT_NODE || o.nextSibling.nextSibling)) results += ' & ';
        //
        return results;
    }
    function templateENTITAG(o) {
        //
        return templateAttr(o,'texcode',ent[localNameDOMx(o)]);
    }


    function templateAttr(o, strAttrName, strDefaultValue) {
        return (/*@if (@_jscript) !!(o.getAttributeNode(strAttrName)) @else @*/ o.hasAttribute(strAttrName) /*@end @*/) ? o.getAttribute(strAttrName) : strDefaultValue ;
    }
    var nmtoken = new RegExp().compile('\\s*\\b(\\S+)\\b\\s*','g');
    function templateAttrNMTOKENS(o, strAttrName) {
        var results = (/*@if (@_jscript) !!(o.getAttributeNode(strAttrName)) @else @*/ o.hasAttribute(strAttrName) /*@end @*/) ? o.getAttribute(strAttrName).replace(nmtoken,'\\$1') : '' ;
        return ((results!='') && o.hasChildNodes() && (o.firstChild.nodeType==Node.TEXT_NODE)) ? results+' ' : results ;  //  commands space contents
    }
    function templateAttrXLink(o, strAttrName, strDefaultValue) {
        /* DOM2 */    return (o.hasAttributeNS('http://www.w3.org/1999/xlink',strAttrName)) ? o.getAttributeNS('http://www.w3.org/1999/xlink',strAttrName) : strDefaultValue ;
    }

    function isTeXML(o) {
        switch (o.nodeType) {
        case Node.ELEMENT_NODE :
            return (isELofTeXML(o)) ? !isEXCLUSIVE(o,'xml') : isanENTITAG(o) ;
            break;                                                    //  1
        case Node.ATTRIBUTE_NODE :              return false; break;  //  2
        case Node.TEXT_NODE :
            return (localNameDOMx(o.parentNode)!='tr');               //    (!(o.parentNode instanceof HTMLTableRowElement));
            break;                                                    //  3  nodeName=#text
        case Node.CDATA_SECTION_NODE :          return true;  break;  //  4  nodeName=#cdata-section
        case Node.ENTITY_REFERENCE_NODE :
            return isanENTIREF(o);
            break;                                                    //  5
        case Node.ENTITY_NODE :                 return false; break;  //  6
        case Node.PROCESSING_INSTRUCTION_NODE : 
			return isPIofTeXML(o); 
			break;  												  //  7
        case Node.COMMENT_NODE :                return false; break;  //  8  nodeName=#comment
        case Node.DOCUMENT_NODE :               return false; break;  //  9  nodeName=#document
        case Node.DOCUMENT_TYPE_NODE :          return false; break;  // 10
        case Node.DOCUMENT_FRAGMENT_NODE :      return false; break;  // 11  nodeName=#document-fragment
        case Node.NOTATION_NODE :               return false; break;  // 12
        default :                               return false; break;
        }   //  switch
    }       //  function
    function isEXCLUSIVE(o,token) {
        return ((templateAttr(o,'type','')==token) || (templateAttr(o,'role','')==token) || (templateAttr(o,'mode','')==token));
    }
    function isELofTeXML(o) {
        return (o.nodeName in t_match[Node.ELEMENT_NODE]);
    }
    function isPIofTeXML(o) {
        return (o.nodeName in t_match[Node.PROCESSING_INSTRUCTION_NODE]);
    }
    function isanENTITAG(o) {  //  (o.nodeName in t_match[Node.ELEMENT_NODE]) is already false
        return (o.namespaceURI=='urn:entitags:entity-as-empty-element-tag' && localNameDOMx(o) in ent) ? (t_match[Node.ELEMENT_NODE][o.nodeName]=templateENTITAG,true) : false ;
    }
    function isanENTIREF(o) {  //  always true, but as side-effect creates t_match[Node.ENTITY_REFERENCE_NODE] entry on-the-fly
        return (o.nodeName in t_match[Node.ENTITY_REFERENCE_NODE]) ? true : (t_match[Node.ENTITY_REFERENCE_NODE][o.nodeName]=applyTemplates,true) ;
    }

    function applyTemplates(o) {
        var results = new String('');
        for (var c=o.firstChild; c!=null; c=c.nextSibling)
        {
        if (isTeXML(c)) results += t_match[c.nodeType][c.nodeName](c);
        }
        return results;
    }

    function templateROOT(o) {
        var results = new String('');
        results = (isTeXML(o)) ? t_match[o.nodeType][o.nodeName](o) : '%%  not a TeXML-object or of mode\/role\/type=\"xml\": '+o.nodeName+' '+o+'  %%' ;
        return results;
    }

    return templateROOT(oTeXML);  // returns String

}  //  TeXML2TeX Transformer

//
//  TeXML2TeX.js  EOF
//
