(* vim: set sw=8 ts=8 et: *)
open Parser
open Tex
open Util


let tex_part = function
    HTMLABLE (_,t,_) -> t
  | HTMLABLEM (_,t,_) -> t
  | HTMLABLEC (_,t,_) -> t
  | MHTMLABLEC (_,t,_,_,_) -> t
  | HTMLABLE_BIG (t,_) -> t
  | TEX_ONLY t -> t

let rec render_tex = function
    TEX_FQ (a,b,c) -> (render_tex a) ^ "_{" ^ (render_tex  b) ^ "}^{" ^ (render_tex  c) ^ "}"
  | TEX_DQ (a,b) -> (render_tex a) ^ "_{" ^ (render_tex  b) ^ "}"
  | TEX_UQ (a,b) -> (render_tex a) ^ "^{" ^ (render_tex  b) ^ "}"
  | TEX_FQN (a,b) -> "_{" ^ (render_tex  a) ^ "}^{" ^ (render_tex  b) ^ "}"
  | TEX_DQN (a) -> "_{" ^ (render_tex  a) ^ "}"
  | TEX_UQN (a) -> "^{" ^ (render_tex  a) ^ "}"
  | TEX_LITERAL s -> tex_part s
  | TEX_FUN1 (f,a) -> "{" ^ f ^ " " ^ (render_tex a) ^ "}"
  | TEX_FUN1nb (f,a) -> f ^ " " ^ (render_tex a)
  | TEX_FUN1hl (f,_,a) -> "{" ^ f ^ " " ^ (render_tex a) ^ "}"
  | TEX_FUN1hf (f,_,a) -> "{" ^ f ^ " " ^ (render_tex a) ^ "}"
  | TEX_DECLh (f,_,a) -> "{" ^ f ^ "{" ^ (mapjoin render_tex a) ^ "}}"
  | TEX_FUN2 (f,a,b)    -> "{" ^ f ^ " " ^ (render_tex a) ^ (render_tex b) ^ "}"
  | TEX_FUN2h (f,_,a,b) -> "{" ^ f ^ " " ^ (render_tex a) ^ (render_tex b) ^ "}"
  | TEX_FUN2nb (f,a,b) -> f ^ (render_tex a) ^ (render_tex b)

  | TEX_FUN2sq (f,a,b) -> "{" ^ f ^ "[ " ^ (render_tex a) ^ "]" ^ (render_tex b) ^ "}"
  | TEX_CURLY (tl) -> "{" ^ (mapjoin render_tex tl) ^ "}"
  | TEX_INFIX (s,ll,rl) -> "{" ^ (mapjoin render_tex ll) ^ " " ^ s ^ "" ^ (mapjoin render_tex rl) ^ "}"
  | TEX_INFIXh (s,_,ll,rl) -> "{" ^ (mapjoin render_tex ll) ^ " " ^ s ^ "" ^ (mapjoin render_tex rl) ^ "}"
  | TEX_BOX (bt,s) -> "{"^bt^"{" ^ s ^ "}}"
  | TEX_BIG (bt,d) -> "{"^bt^(tex_part d)^"}"
  | TEX_MATRIX (t,rows) -> "{\\begin{"^t^"}"^(mapjoine "\\\\" (mapjoine "&" (mapjoin render_tex)) rows)^"\\end{"^t^"}}"
  | TEX_LR (l,r,tl) -> "\\left"^(tex_part l)^(mapjoin render_tex tl)^"\\right"^(tex_part r)


(* Turn that into hash table lookup *)
exception Illegal_tex_function of string

let find cmd = match cmd with
  "\\AA"
  | "\\aleph"
  | "\\alpha"
  | "\\amalg"
  | "\\And"
  | "\\angle"
  | "\\approx"
  | "\\approxeq"
  | "\\ast"
  | "\\asymp"
  | "\\backepsilon"
  | "\\backprime"
  | "\\backsim"
  | "\\backsimeq"
  | "\\barwedge"
  | "\\Bbbk"
  | "\\because"
  | "\\beta"
  | "\\beth"
  | "\\between"
  | "\\bigcap"
  | "\\bigcirc"
  | "\\bigcup"
  | "\\bigodot"
  | "\\bigoplus"
  | "\\bigotimes"
  | "\\bigsqcup"
  | "\\bigstar"
  | "\\bigtriangledown"
  | "\\bigtriangleup"
  | "\\biguplus"
  | "\\bigvee"
  | "\\bigwedge"
  | "\\blacklozenge"
  | "\\blacksquare"
  | "\\blacktriangle"
  | "\\blacktriangledown"
  | "\\blacktriangleleft"
  | "\\blacktriangleright"
  | "\\bot"
  | "\\bowtie"
  | "\\Box"
  | "\\boxdot"
  | "\\boxminus"
  | "\\boxplus"
  | "\\boxtimes"
  | "\\bullet"
  | "\\bumpeq"
  | "\\Bumpeq"
  | "\\cap"
  | "\\Cap"
  | "\\cdot"
  | "\\cdots"
  | "\\centerdot"
  | "\\checkmark"
  | "\\chi"
  | "\\circ"
  | "\\circeq"
  | "\\circlearrowleft"
  | "\\circlearrowright"
  | "\\circledast"
  | "\\circledcirc"
  | "\\circleddash"
  | "\\circledS"
  | "\\clubsuit"
  | "\\colon"
  | "\\color"
  | "\\complement"
  | "\\cong"
  | "\\coprod"
  | "\\cup"
  | "\\Cup"
  | "\\curlyeqprec"
  | "\\curlyeqsucc"
  | "\\curlyvee"
  | "\\curlywedge"
  | "\\curvearrowleft"
  | "\\curvearrowright"
  | "\\dagger"
  | "\\daleth"
  | "\\dashv"
  | "\\ddagger"
  | "\\ddots"
  | "\\definecolor"
  | "\\delta"
  | "\\Delta"
  | "\\diagdown"
  | "\\diagup"
  | "\\diamond"
  | "\\Diamond"
  | "\\diamondsuit"
  | "\\digamma"
  | "\\displaystyle"
  | "\\div"
  | "\\divideontimes"
  | "\\doteq"
  | "\\doteqdot"
  | "\\dotplus"
  | "\\dots"
  | "\\dotsb"
  | "\\dotsc"
  | "\\dotsi"
  | "\\dotsm"
  | "\\dotso"
  | "\\doublebarwedge"
  | "\\downdownarrows"
  | "\\downharpoonleft"
  | "\\downharpoonright"
  | "\\ell"
  | "\\emptyset"
  | "\\epsilon"
  | "\\eqcirc"
  | "\\eqsim"
  | "\\eqslantgtr"
  | "\\eqslantless"
  | "\\equiv"
  | "\\eta"
  | "\\eth"
  | "\\exists"
  | "\\fallingdotseq"
  | "\\Finv"
  | "\\flat"
  | "\\forall"
  | "\\frown"
  | "\\Game"
  | "\\gamma"
  | "\\Gamma"
  | "\\geq"
  | "\\geqq"
  | "\\geqslant"
  | "\\gets"
  | "\\gg"
  | "\\ggg"
  | "\\gimel"
  | "\\gnapprox"
  | "\\gneq"
  | "\\gneqq"
  | "\\gnsim"
  | "\\gtrapprox"
  | "\\gtrdot"
  | "\\gtreqless"
  | "\\gtreqqless"
  | "\\gtrless"
  | "\\gtrsim"
  | "\\gvertneqq"
  | "\\hbar"
  | "\\heartsuit"
  | "\\hline"
  | "\\hookleftarrow"
  | "\\hookrightarrow"
  | "\\hslash"
  | "\\iff"
  | "\\iiiint"
  | "\\iiint"
  | "\\iint"
  | "\\Im"
  | "\\imath"
  | "\\implies"
  | "\\in"
  | "\\infty"
  | "\\injlim"
  | "\\int"
  | "\\intercal"
  | "\\iota"
  | "\\jmath"
  | "\\kappa"
  | "\\lambda"
  | "\\Lambda"
  | "\\land"
  | "\\ldots"
  | "\\leftarrow"
  | "\\Leftarrow"
  | "\\leftarrowtail"
  | "\\leftharpoondown"
  | "\\leftharpoonup"
  | "\\leftleftarrows"
  | "\\leftrightarrow"
  | "\\Leftrightarrow"
  | "\\leftrightarrows"
  | "\\leftrightharpoons"
  | "\\leftrightsquigarrow"
  | "\\leftthreetimes"
  | "\\leq"
  | "\\leqq"
  | "\\leqslant"
  | "\\lessapprox"
  | "\\lessdot"
  | "\\lesseqgtr"
  | "\\lesseqqgtr"
  | "\\lessgtr"
  | "\\lesssim"
  | "\\limits"
  | "\\ll"
  | "\\Lleftarrow"
  | "\\lll"
  | "\\lnapprox"
  | "\\lneq"
  | "\\lneqq"
  | "\\lnot"
  | "\\lnsim"
  | "\\longleftarrow"
  | "\\Longleftarrow"
  | "\\longleftrightarrow"
  | "\\Longleftrightarrow"
  | "\\longmapsto"
  | "\\longrightarrow"
  | "\\Longrightarrow"
  | "\\looparrowleft"
  | "\\looparrowright"
  | "\\lor"
  | "\\lozenge"
  | "\\Lsh"
  | "\\ltimes"
  | "\\lVert"
  | "\\lvertneqq"
  | "\\mapsto"
  | "\\measuredangle"
  | "\\mho"
  | "\\mid"
  | "\\mod"
  | "\\models"
  | "\\mp"
  | "\\mu"
  | "\\multimap"
  | "\\nabla"
  | "\\natural"
  | "\\ncong"
  | "\\nearrow"
  | "\\neg"
  | "\\neq"
  | "\\nexists"
  | "\\ngeq"
  | "\\ngeqq"
  | "\\ngeqslant"
  | "\\ngtr"
  | "\\ni"
  | "\\nleftarrow"
  | "\\nLeftarrow"
  | "\\nleftrightarrow"
  | "\\nLeftrightarrow"
  | "\\nleq"
  | "\\nleqq"
  | "\\nleqslant"
  | "\\nless"
  | "\\nmid"
  | "\\nolimits"
  | "\\not"
  | "\\notin"
  | "\\nparallel"
  | "\\nprec"
  | "\\npreceq"
  | "\\nrightarrow"
  | "\\nRightarrow"
  | "\\nshortmid"
  | "\\nshortparallel"
  | "\\nsim"
  | "\\nsubseteq"
  | "\\nsubseteqq"
  | "\\nsucc"
  | "\\nsucceq"
  | "\\nsupseteq"
  | "\\nsupseteqq"
  | "\\ntriangleleft"
  | "\\ntrianglelefteq"
  | "\\ntriangleright"
  | "\\ntrianglerighteq"
  | "\\nu"
  | "\\nvdash"
  | "\\nVdash"
  | "\\nvDash"
  | "\\nVDash"
  | "\\nwarrow"
  | "\\odot"
  | "\\oint"
  | "\\omega"
  | "\\Omega"
  | "\\ominus"
  | "\\oplus"
  | "\\oslash"
  | "\\otimes"
  | "\\overbrace"
  | "\\overleftarrow"
  | "\\overleftrightarrow"
  | "\\overline"
  | "\\overrightarrow"
  | "\\P"
  | "\\pagecolor"
  | "\\parallel"
  | "\\partial"
  | "\\perp"
  | "\\phi"
  | "\\Phi"
  | "\\pi"
  | "\\Pi"
  | "\\pitchfork"
  | "\\pm"
  | "\\prec"
  | "\\precapprox"
  | "\\preccurlyeq"
  | "\\preceq"
  | "\\precnapprox"
  | "\\precneqq"
  | "\\precnsim"
  | "\\precsim"
  | "\\prime"
  | "\\prod"
  | "\\projlim"
  | "\\propto"
  | "\\psi"
  | "\\Psi"
  | "\\qquad"
  | "\\quad"
  | "\\Re"
  | "\\rho"
  | "\\rightarrow"
  | "\\Rightarrow"
  | "\\rightarrowtail"
  | "\\rightharpoondown"
  | "\\rightharpoonup"
  | "\\rightleftarrows"
  | "\\rightrightarrows"
  | "\\rightsquigarrow"
  | "\\rightthreetimes"
  | "\\risingdotseq"
  | "\\Rrightarrow"
  | "\\Rsh"
  | "\\rtimes"
  | "\\rVert"
  | "\\S"
  | "\\scriptscriptstyle"
  | "\\scriptstyle"
  | "\\searrow"
  | "\\setminus"
  | "\\sharp"
  | "\\shortmid"
  | "\\shortparallel"
  | "\\sigma"
  | "\\Sigma"
  | "\\sim"
  | "\\simeq"
  | "\\smallfrown"
  | "\\smallsetminus"
  | "\\smallsmile"
  | "\\smile"
  | "\\spadesuit"
  | "\\sphericalangle"
  | "\\sqcap"
  | "\\sqcup"
  | "\\sqsubset"
  | "\\sqsubseteq"
  | "\\sqsupset"
  | "\\sqsupseteq"
  | "\\square"
  | "\\star"
  | "\\subset"
  | "\\Subset"
  | "\\subseteq"
  | "\\subseteqq"
  | "\\subsetneq"
  | "\\subsetneqq"
  | "\\succ"
  | "\\succapprox"
  | "\\succcurlyeq"
  | "\\succeq"
  | "\\succnapprox"
  | "\\succneqq"
  | "\\succnsim"
  | "\\succsim"
  | "\\sum"
  | "\\supset"
  | "\\Supset"
  | "\\supseteq"
  | "\\supseteqq"
  | "\\supsetneq"
  | "\\supsetneqq"
  | "\\surd"
  | "\\swarrow"
  | "\\tau"
  | "\\textstyle"
  | "\\textvisiblespace"
  | "\\therefore"
  | "\\theta"
  | "\\Theta"
  | "\\thickapprox"
  | "\\thicksim"
  | "\\times"
  | "\\to"
  | "\\top"
  | "\\triangle"
  | "\\triangledown"
  | "\\triangleleft"
  | "\\trianglelefteq"
  | "\\triangleq"
  | "\\triangleright"
  | "\\trianglerighteq"
  | "\\underbrace"
  | "\\underline"
  | "\\upharpoonleft"
  | "\\upharpoonright"
  | "\\uplus"
  | "\\upsilon"
  | "\\Upsilon"
  | "\\upuparrows"
  | "\\varepsilon"
  | "\\varinjlim"
  | "\\varkappa"
  | "\\varliminf"
  | "\\varlimsup"
  | "\\varnothing"
  | "\\varphi"
  | "\\varpi"
  | "\\varprojlim"
  | "\\varpropto"
  | "\\varrho"
  | "\\varsigma"
  | "\\varsubsetneq"
  | "\\varsubsetneqq"
  | "\\varsupsetneq"
  | "\\varsupsetneqq"
  | "\\vartheta"
  | "\\vartriangle"
  | "\\vartriangleleft"
  | "\\vartriangleright"
  | "\\vdash"
  | "\\Vdash"
  | "\\vDash"
  | "\\vdots"
  | "\\vee"
  | "\\veebar"
  | "\\vline"
  | "\\Vvdash"
  | "\\wedge"
  | "\\widehat"
  | "\\widetilde"
  | "\\wp"
  | "\\wr"
  | "\\xi"
  | "\\Xi"
  | "\\zeta"
  -> LITERAL ( TEX_ONLY( cmd ^ " " ) )

  | "\\big"
  | "\\Big"
  | "\\bigg"
  | "\\Bigg"
  | "\\biggl"
  | "\\Biggl"
  | "\\biggr"
  | "\\Biggr"
  | "\\bigl"
  | "\\Bigl"
  | "\\bigr"
  | "\\Bigr"
  -> BIG (  cmd ^ " " )

  | "\\backslash"
  | "\\downarrow"
  | "\\Downarrow"
  | "\\langle"
  | "\\lbrace"
  | "\\lceil"
  | "\\lfloor"
  | "\\llcorner"
  | "\\lrcorner"
  | "\\rangle"
  | "\\rbrace"
  | "\\rceil"
  | "\\rfloor"
  | "\\rightleftharpoons"
  | "\\twoheadleftarrow"
  | "\\twoheadrightarrow"
  | "\\ulcorner"
  | "\\uparrow"
  | "\\Uparrow"
  | "\\updownarrow"
  | "\\Updownarrow"
  | "\\urcorner"
  | "\\Vert"
  | "\\vert"
  | "\\lbrack"
  | "\\rbrack"
  -> DELIMITER( TEX_ONLY( cmd ^ " ") )

  | "\\acute"
  | "\\bar"
  | "\\bcancel"
  | "\\bmod"
  | "\\boldsymbol"
  | "\\breve"
  | "\\cancel"
  | "\\check"
  | "\\ddot"
  | "\\dot"
  | "\\emph"
  | "\\grave"
  | "\\hat"
  | "\\mathbb"
  | "\\mathbf"
  | "\\mathbin"
  | "\\mathcal"
  | "\\mathclose"
  | "\\mathfrak"
  | "\\mathit"
  | "\\mathop"
  | "\\mathopen"
  | "\\mathord"
  | "\\mathpunct"
  | "\\mathrel"
  | "\\mathrm"
  | "\\mathsf"
  | "\\mathtt"
  | "\\operatorname"
  | "\\pmod"
  | "\\sqrt"
  | "\\textbf"
  | "\\textit"
  | "\\textrm"
  | "\\textsf"
  | "\\texttt"
  | "\\tilde"
  | "\\vec"
  | "\\xcancel"
  | "\\xleftarrow"
  | "\\xrightarrow"
  -> FUN_AR1( cmd ^ " " )

  | "\\binom"
  | "\\cancelto"
  | "\\cfrac"
  | "\\dbinom"
  | "\\dfrac"
  | "\\frac"
  | "\\overset"
  | "\\stackrel"
  | "\\tbinom"
  | "\\tfrac"
  | "\\underset"
  -> FUN_AR2( cmd ^ " " )
  | "\\atop"
  | "\\choose"
  | "\\over"
  -> FUN_INFIX( cmd ^ " " )

  | "\\Coppa"
  | "\\coppa"
  | "\\Digamma"
  | "\\euro"
  | "\\geneuro"
  | "\\geneuronarrow"
  | "\\geneurowide"
  | "\\Koppa"
  | "\\koppa"
  | "\\officialeuro"
  | "\\Sampi"
  | "\\sampi"
  | "\\Stigma"
  | "\\stigma"
  | "\\varstigma"
  -> LITERAL ( TEX_ONLY( "\\mbox{" ^ cmd ^ "} " ) )

  | "\\C" -> LITERAL ( TEX_ONLY( "\\mathbb{C}" ^ " " ) )
  | "\\H" -> LITERAL ( TEX_ONLY( "\\mathbb{H}" ^ " " ) )
  | "\\N" -> LITERAL ( TEX_ONLY( "\\mathbb{N}" ^ " " ) )
  | "\\Q" -> LITERAL ( TEX_ONLY( "\\mathbb{Q}" ^ " " ) )
  | "\\R" -> LITERAL ( TEX_ONLY( "\\mathbb{R}" ^ " " ) )
  | "\\Z" -> LITERAL ( TEX_ONLY( "\\mathbb{Z }" ^ " " ) )

  | "\\darr" -> DELIMITER( TEX_ONLY( "\\downarrow" ^ " " ) )
  | "\\dArr" -> DELIMITER( TEX_ONLY( "\\Downarrow" ^ " " ) )
  | "\\Darr" -> DELIMITER( TEX_ONLY( "\\Downarrow" ^ " " ) )
  | "\\lang" -> DELIMITER( TEX_ONLY( "\\langle" ^ " " ) )
  | "\\rang" -> DELIMITER( TEX_ONLY( "\\rangle" ^ " " ) )
  | "\\uarr" -> DELIMITER( TEX_ONLY( "\\uparrow" ^ " " ) )
  | "\\uArr" -> DELIMITER( TEX_ONLY( "\\Uparrow" ^ " " ) )
  | "\\Uarr" -> DELIMITER( TEX_ONLY( "\\Uparrow" ^ " " ) )

  | "\\Bbb" -> FUN_AR1( "\\mathbb" ^ " " )
  | "\\bold" -> FUN_AR1( "\\mathbf" ^ " " )

  | "\\alef" -> LITERAL ( TEX_ONLY( "\\aleph" ^ " " ) )
  | "\\alefsym" -> LITERAL ( TEX_ONLY( "\\aleph" ^ " " ) )
  | "\\Alpha" -> LITERAL ( TEX_ONLY( "\\mathrm{A}" ^ " " ) )
  | "\\and" -> LITERAL ( TEX_ONLY( "\\land" ^ " " ) )
  | "\\ang" -> LITERAL ( TEX_ONLY( "\\angle" ^ " " ) )
  | "\\Beta" -> LITERAL ( TEX_ONLY( "\\mathrm{B}" ^ " " ) )
  | "\\bull" -> LITERAL ( TEX_ONLY( "\\bullet" ^ " " ) )
  | "\\Chi" -> LITERAL ( TEX_ONLY( "\\mathrm{X}" ^ " " ) )
  | "\\clubs" -> LITERAL ( TEX_ONLY( "\\clubsuit" ^ " " ) )
  | "\\cnums" -> LITERAL ( TEX_ONLY( "\\mathbb{C}" ^ " " ) )
  | "\\Complex" -> LITERAL ( TEX_ONLY( "\\mathbb{C}" ^ " " ) )
  | "\\Dagger" -> LITERAL ( TEX_ONLY( "\\ddagger" ^ " " ) )
  | "\\diamonds" -> LITERAL ( TEX_ONLY( "\\diamondsuit" ^ " " ) )
  | "\\Doteq" -> LITERAL ( TEX_ONLY( "\\doteqdot" ^ " " ) )
  | "\\doublecap" -> LITERAL ( TEX_ONLY( "\\Cap" ^ " " ) )
  | "\\doublecup" -> LITERAL ( TEX_ONLY( "\\Cup" ^ " " ) )
  | "\\empty" -> LITERAL ( TEX_ONLY( "\\emptyset" ^ " " ) )
  | "\\Epsilon" -> LITERAL ( TEX_ONLY( "\\mathrm{E}" ^ " " ) )
  | "\\Eta" -> LITERAL ( TEX_ONLY( "\\mathrm{H}" ^ " " ) )
  | "\\exist" -> LITERAL ( TEX_ONLY( "\\exists" ^ " " ) )
  | "\\ge" -> LITERAL ( TEX_ONLY( "\\geq" ^ " " ) )
  | "\\gggtr" -> LITERAL ( TEX_ONLY( "\\ggg" ^ " " ) )
  | "\\hAar" -> LITERAL ( TEX_ONLY( "\\Leftrightarrow" ^ " " ) )
  | "\\harr" -> LITERAL ( TEX_ONLY( "\\leftrightarrow" ^ " " ) )
  | "\\Harr" -> LITERAL ( TEX_ONLY( "\\Leftrightarrow" ^ " " ) )
  | "\\hearts" -> LITERAL ( TEX_ONLY( "\\heartsuit" ^ " " ) )
  | "\\image" -> LITERAL ( TEX_ONLY( "\\Im" ^ " " ) )
  | "\\infin" -> LITERAL ( TEX_ONLY( "\\infty" ^ " " ) )
  | "\\Iota" -> LITERAL ( TEX_ONLY( "\\mathrm{I}" ^ " " ) )
  | "\\isin" -> LITERAL ( TEX_ONLY( "\\in" ^ " " ) )
  | "\\Kappa" -> LITERAL ( TEX_ONLY( "\\mathrm{K}" ^ " " ) )
  | "\\larr" -> LITERAL ( TEX_ONLY( "\\leftarrow" ^ " " ) )
  | "\\Larr" -> LITERAL ( TEX_ONLY( "\\Leftarrow" ^ " " ) )
  | "\\lArr" -> LITERAL ( TEX_ONLY( "\\Leftarrow" ^ " " ) )
  | "\\le" -> LITERAL ( TEX_ONLY( "\\leq" ^ " " ) )
  | "\\lrarr" -> LITERAL ( TEX_ONLY( "\\leftrightarrow" ^ " " ) )
  | "\\Lrarr" -> LITERAL ( TEX_ONLY( "\\Leftrightarrow" ^ " " ) )
  | "\\lrArr" -> LITERAL ( TEX_ONLY( "\\Leftrightarrow" ^ " " ) )
  | "\\Mu" -> LITERAL ( TEX_ONLY( "\\mathrm{M}" ^ " " ) )
  | "\\natnums" -> LITERAL ( TEX_ONLY( "\\mathbb{N}" ^ " " ) )
  | "\\ne" -> LITERAL ( TEX_ONLY( "\\neq" ^ " " ) )
  | "\\Nu" -> LITERAL ( TEX_ONLY( "\\mathrm{N}" ^ " " ) )
  | "\\O" -> LITERAL ( TEX_ONLY( "\\emptyset" ^ " " ) )
  | "\\omicron" -> LITERAL ( TEX_ONLY( "\\mathrm{o}" ^ " " ) )
  | "\\Omicron" -> LITERAL ( TEX_ONLY( "\\mathrm{O}" ^ " " ) )
  | "\\or" -> LITERAL ( TEX_ONLY( "\\lor" ^ " " ) )
  | "\\part" -> LITERAL ( TEX_ONLY( "\\partial" ^ " " ) )
  | "\\plusmn" -> LITERAL ( TEX_ONLY( "\\pm" ^ " " ) )
  | "\\rarr" -> LITERAL ( TEX_ONLY( "\\rightarrow" ^ " " ) )
  | "\\Rarr" -> LITERAL ( TEX_ONLY( "\\Rightarrow" ^ " " ) )
  | "\\rArr" -> LITERAL ( TEX_ONLY( "\\Rightarrow" ^ " " ) )
  | "\\real" -> LITERAL ( TEX_ONLY( "\\Re" ^ " " ) )
  | "\\reals" -> LITERAL ( TEX_ONLY( "\\mathbb{R}" ^ " " ) )
  | "\\Reals" -> LITERAL ( TEX_ONLY( "\\mathbb{R}" ^ " " ) )
  | "\\restriction" -> LITERAL ( TEX_ONLY( "\\upharpoonright" ^ " " ) )
  | "\\Rho" -> LITERAL ( TEX_ONLY( "\\mathrm{P}" ^ " " ) )
  | "\\sdot" -> LITERAL ( TEX_ONLY( "\\cdot" ^ " " ) )
  | "\\sect" -> LITERAL ( TEX_ONLY( "\\S" ^ " " ) )
  | "\\spades" -> LITERAL ( TEX_ONLY( "\\spadesuit" ^ " " ) )
  | "\\sub" -> LITERAL ( TEX_ONLY( "\\subset" ^ " " ) )
  | "\\sube" -> LITERAL ( TEX_ONLY( "\\subseteq" ^ " " ) )
  | "\\supe" -> LITERAL ( TEX_ONLY( "\\supseteq" ^ " " ) )
  | "\\Tau" -> LITERAL ( TEX_ONLY( "\\mathrm{T}" ^ " " ) )
  | "\\thetasym" -> LITERAL ( TEX_ONLY( "\\vartheta" ^ " " ) )
  | "\\varcoppa" -> LITERAL ( TEX_ONLY( "\\mbox{coppa}" ^ " " ) )
  | "\\weierp" -> LITERAL ( TEX_ONLY( "\\wp" ^ " " ) )
  | "\\Zeta" -> LITERAL ( TEX_ONLY( "\\mathrm{Z}" ^ " " ) )

  | "\\rm"
  | "\\it"
  | "\\cal"
  | "\\bf"
  -> DECLh ( cmd ^ " ", FONTFORCE_RM ) (* see bug 54818 *)

  | "\\sideset" -> FUN_AR2nb "\\sideset "
  | "\\left" -> LEFT
  | "\\right" -> RIGHT

  | "\\text"
  | "\\mbox"
  | "\\vbox"
  | "\\hbox"
  -> raise (Failure ("malformatted " ^ cmd))

  | s -> raise (Illegal_tex_function s)