{-# LANGUAGE DeriveDataTypeable #-}{-
Copyright (C) 2009 John MacFarlane <jgm@berkeley.edu>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-}{- | Functions for parsing a LaTeX formula to a Haskell representation.
-}moduleText.TeXMath.Parser(expr,formula,Exp(..),TeXSymbolType(..),ArrayLine,Alignment(..))whereimportControl.MonadimportData.Char(isAlphaNum,isDigit,isAscii)importqualifiedData.MapasMimportText.ParserCombinators.ParsecimportqualifiedText.ParserCombinators.Parsec.TokenasPimportText.ParserCombinators.Parsec.LanguageimportData.GenericsdataTeXSymbolType=Ord|Op|Bin|Rel|Open|Close|Pun|Accentderiving(Show,Read,Eq,Data,Typeable)dataAlignment=AlignLeft|AlignCenter|AlignRight|AlignDefaultderiving(Show,Read,Eq,Data,Typeable)typeArrayLine=[[Exp]]dataExp=ENumberString|EGrouped[Exp]|EIdentifierString|EMathOperatorString|ESymbolTeXSymbolTypeString|ESpaceString|EBinaryStringExpExp|ESubExpExp|ESuperExpExp|ESubsupExpExpExp|EOverExpExp|EUnderExpExp|EUnderoverExpExpExp|EUpExpExp|EDownExpExp|EDownupExpExpExp|EUnaryStringExp|EScaledStringExp|EStretchyExp|EArray[Alignment][ArrayLine]|ETextStringStringderiving(Show,Read,Eq,Data,Typeable)texMathDef::LanguageDefsttexMathDef=LanguageDef{commentStart="",commentEnd="",commentLine="%",nestedComments=False,identStart=letter,identLetter=letter,opStart=opLettertexMathDef,opLetter=oneOf":_+*/=^-(),;.?'~[]<>!",reservedOpNames=[],reservedNames=[],caseSensitive=True}-- The parserexpr1::GenParserCharstExpexpr1=choice[inbraces,variable,number,texSymbol,text,root,unary,binary,enclosure,array,diacritical,escaped,unicode]formula::GenParserCharst[Exp]formula=dowhiteSpacef<-manyexpreofreturnfexpr::GenParserCharstExpexpr=doa<-expr1limits<-limitsIndicatorsubSuplimitsa<|>superOrSubscriptedlimitsa<|>returnalimitsIndicator::GenParserCharst(MaybeBool)limitsIndicator=try(symbol"\\limits">>return(JustTrue))<|>try(symbol"\\nolimits">>return(JustFalse))<|>returnNothinginbraces::GenParserCharstExpinbraces=liftMEGrouped(braces$many$notFollowedBy(char'}')>>expr)texToken::GenParserCharstExptexToken=inbraces<|>inbrackets<|>doc<-anyCharspacesreturn$ifisDigitcthen(ENumber[c])else(EIdentifier[c])inbrackets::GenParserCharstExpinbrackets=liftMEGrouped(brackets$many$notFollowedBy(char']')>>expr)number::GenParserCharstExpnumber=lexeme$liftMENumber$many1digitenclosure::GenParserCharstExpenclosure=basicEnclosure<|>left<|>right<|>scaledEnclosurebasicEnclosure::GenParserCharstExpbasicEnclosure=choice$map(\(s,v)->try(symbols)>>returnv)enclosuresleft::GenParserCharstExpleft=try$dosymbol"\\left"enc<-basicEnclosure<|>(try(symbol".")>>return(ESymbolOpen"\xFEFF"))caseencof(ESymbolOpen_)->tilRightenc<|>return(EStretchyenc)_->pzeroright::GenParserCharstExpright=try$dosymbol"\\right"enc<-basicEnclosure<|>(try(symbol".")>>return(ESymbolClose"\xFEFF"))caseencof(ESymbolClosex)->return(EStretchy$ESymbolOpenx)_->pzero-- We want stuff between \left( and \right) to be in an mrow,-- so that the scaling is based just on this unit, and not the-- whole containing formula.tilRight::Exp->GenParserCharstExptilRightstart=try$docontents<-manyTillexpr(try$symbol"\\right">>lookAheadbasicEnclosure)end<-basicEnclosurereturn$EGrouped$EStretchystart:(contents++[EStretchyend])scaledEnclosure::GenParserCharstExpscaledEnclosure=try$docmd<-commandcaseM.lookupcmdscalersofJustr->liftM(EScaledr.EStretchy)basicEnclosureNothing->pzeroendLine::GenParserCharstCharendLine=try$dosymbol"\\\\"optionalinbrackets-- can contain e.g. [1.0in] for a line height, not yet supportedreturn'\n'arrayLine::GenParserCharstArrayLinearrayLine=notFollowedBy(try$char'\\'>>symbol"end">>return'\n')>>sepBy1(many(notFollowedByendLine>>expr))(symbol"&")array::GenParserCharstExparray=stdarray<|>eqnarray<|>align<|>cases<|>matrixmatrix::GenParserCharstExpmatrix=matrixWith"pmatrix""("")"<|>matrixWith"bmatrix""[""]"<|>matrixWith"Bmatrix""{""}"<|>matrixWith"vmatrix""\x2223""\x2223"<|>matrixWith"Vmatrix""\x2225""\x2225"matrixWith::String->String->String->GenParserCharstExpmatrixWithkeywdopendelimclosedelim=inEnvironmentkeywd$doaligns<-option[]arrayAlignmentslines'<-sepEndBy1arrayLineendLinereturn$EGrouped[EStretchy(ESymbolOpenopendelim),EArrayalignslines',EStretchy(ESymbolCloseclosedelim)]stdarray::GenParserCharstExpstdarray=inEnvironment"array"$doaligns<-option[]arrayAlignmentsliftM(EArrayaligns)$sepEndBy1arrayLineendLineeqnarray::GenParserCharstExpeqnarray=inEnvironment"eqnarray"$liftM(EArray[AlignRight,AlignCenter,AlignLeft])$sepEndBy1arrayLineendLinealign::GenParserCharstExpalign=inEnvironment"align"$liftM(EArray[AlignRight,AlignLeft])$sepEndBy1arrayLineendLinecases::GenParserCharstExpcases=inEnvironment"cases"$dors<-sepEndBy1arrayLineendLinereturn$EGrouped[EStretchy(ESymbolOpen"{"),EArray[]rs]arrayAlignments::GenParserCharst[Alignment]arrayAlignments=try$doas<-braces(manyletter)letletterToAlignment'l'=AlignLeftletterToAlignment'c'=AlignCenterletterToAlignment'r'=AlignRightletterToAlignment_=AlignDefaultreturn$mapletterToAlignmentasinEnvironment::String->GenParserCharstExp->GenParserCharstExpinEnvironmentenvTypep=dotry$dochar'\\'symbol"begin"braces$symbolenvType>>optional(symbol"*")result<-pchar'\\'symbol"end"braces$symbolenvType>>optional(symbol"*")returnresultvariable::GenParserCharstExpvariable=dov<-letterspacesreturn$EIdentifier[v]isConvertible::Exp->BoolisConvertible(EMathOperatorx)=x`elem`convertibleOpswhereconvertibleOps=["lim","liminf","limsup","inf","sup"]isConvertible(ESymbolRel_)=TrueisConvertible(ESymbolBin_)=TrueisConvertible(EUnder__)=TrueisConvertible(EOver__)=TrueisConvertible(EUnderover___)=TrueisConvertible(ESymbolOpx)=x`elem`convertibleSymswhereconvertibleSyms=["\x2211","\x220F","\x22C2","\x22C3","\x22C0","\x22C1","\x2A05","\x2A06","\x2210","\x2A01","\x2A02","\x2A00","\x2A04"]isConvertible_=FalsesubSup::MaybeBool->Exp->GenParserCharstExpsubSuplimitsa=try$dochar'_'b<-expr1char'^'c<-exprreturn$caselimitsofJustTrue->EUnderoverabcNothing|isConvertiblea->EDownupabc_->ESubsupabcsuperOrSubscripted::MaybeBool->Exp->GenParserCharstExpsuperOrSubscriptedlimitsa=try$doc<-oneOf"^_"b<-exprcasecof'^'->return$caselimitsofJustTrue->EOverabNothing|isConvertiblea->EUpab_->ESuperab'_'->return$caselimitsofJustTrue->EUnderabNothing|isConvertiblea->EDownab_->ESubab_->pzeroescaped::GenParserCharstExpescaped=lexeme$try$char'\\'>>liftM(ESymbolOrd.(:[]))(satisfy$not.isAlphaNum)unicode::GenParserCharstExpunicode=lexeme$liftM(ESymbolOrd.(:[]))$satisfy(not.isAscii)command::GenParserCharstStringcommand=try$char'\\'>>liftM('\\':)(identifier<|>lexeme(count1anyChar))unaryOps::[String]unaryOps=["\\sqrt","\\surd"]textOps::M.MapString(String->Exp)textOps=M.fromList[("\\textrm",EText"normal"),("\\mathrm",EText"normal"),("\\text",EText"normal"),("\\mbox",EText"normal"),("\\mathbf",EText"bold"),("\\textbf",EText"bold"),("\\mathit",EText"italic"),("\\textit",EText"italic"),("\\mathtt",EText"monospace"),("\\texttt",EText"monospace"),("\\mathsf",EText"sans-serif"),("\\mathbb",\e->maybe(EText"double-struck"e)(ESymbolPun)(M.lookupemathbb)),("\\mathcal",\e->maybe(EText"script"e)(ESymbolPun)(M.lookupemathcal)),("\\mathfrak",EText"fraktur")]diacritical::GenParserCharstExpdiacritical=try$doc<-commandcaseM.lookupcdiacriticalsofJustr->liftMrtexTokenNothing->pzerodiacriticals::M.MapString(Exp->Exp)diacriticals=M.fromList[("\\acute",\e->EOvere(ESymbolAccent"\x00B4")),("\\grave",\e->EOvere(ESymbolAccent"\x0060")),("\\breve",\e->EOvere(ESymbolAccent"\x02D8")),("\\check",\e->EOvere(ESymbolAccent"\x02C7")),("\\dot",\e->EOvere(ESymbolAccent".")),("\\ddot",\e->EOvere(ESymbolAccent"..")),("\\mathring",\e->EOvere(ESymbolAccent"\x00B0")),("\\vec",\e->EOvere(ESymbolAccent"\x20D7")),("\\overrightarrow",\e->EOvere(ESymbolAccent"\x20D7")),("\\overleftarrow",\e->EOvere(ESymbolAccent"\x20D6")),("\\hat",\e->EOvere(ESymbolAccent"\x005E")),("\\widehat",\e->EOvere(ESymbolAccent"\x0302")),("\\tilde",\e->EOvere(ESymbolAccent"~")),("\\widetilde",\e->EOvere(ESymbolAccent"\x02DC")),("\\bar",\e->EOvere(ESymbolAccent"\x203E")),("\\overbrace",\e->EOvere(ESymbolAccent"\xFE37")),("\\overbracket",\e->EOvere(ESymbolAccent"\x23B4")),("\\overline",\e->EOvere(ESymbolAccent"\x00AF")),("\\underbrace",\e->EUndere(ESymbolAccent"\xFE38")),("\\underbracket",\e->EUndere(ESymbolAccent"\x23B5")),("\\underline",\e->EUndere(ESymbolAccent"\x00AF"))]unary::GenParserCharstExpunary=try$doc<-commandunless(c`elem`unaryOps)pzeroa<-texTokenreturn$EUnarycatext::GenParserCharstExptext=try$doc<-commandcaseM.lookupctextOpsofJustf->liftMf$braces(many(noneOf"}"<|>(char'\\'>>char'}')))Nothing->pzero-- note: sqrt can be unary, \sqrt{2}, or binary, \sqrt[3]{2}root::GenParserCharstExproot=try$dotry(symbol"\\sqrt")<|>symbol"\\surd"a<-inbracketsb<-texTokenreturn$EBinary"\\sqrt"babinary::GenParserCharstExpbinary=try$doc<-commandunless(c`elem`binaryOps)pzeroa<-texTokenb<-texTokenreturn$EBinarycabtexSymbol::GenParserCharstExptexSymbol=try$dosym<-operator<|>commandcaseM.lookupsymsymbolsofJusts->returnsNothing->pzero-- The lexerlexer::P.TokenParserstlexer=P.makeTokenParsertexMathDeflexeme::CharParsersta->CharParserstalexeme=P.lexemelexerwhiteSpace::CharParserst()whiteSpace=P.whiteSpacelexeridentifier::CharParserstStringidentifier=lexeme(P.identifierlexer)operator::CharParserstStringoperator=lexeme$liftM(:[])(opLettertexMathDef)<|>many1(char'\'')symbol::String->CharParserstStringsymbol=lexeme.P.symbollexerbraces::CharParsersta->CharParserstabraces=lexeme.P.braceslexerbrackets::CharParsersta->CharParserstabrackets=lexeme.P.bracketslexerbinaryOps::[String]binaryOps=["\\frac","\\tfrac","\\dfrac","\\stackrel","\\overset","\\underset","\\binom"]scalers::M.MapStringStringscalers=M.fromList[("\\bigg","2.2"),("\\Bigg","2.9"),("\\big","1.2"),("\\Big","1.6"),("\\biggr","2.2"),("\\Biggr","2.9"),("\\bigr","1.2"),("\\Bigr","1.6"),("\\biggl","2.2"),("\\Biggl","2.9"),("\\bigl","1.2"),("\\Bigl","1.6")]enclosures::[(String,Exp)]enclosures=[("(",ESymbolOpen"("),(")",ESymbolClose")"),("[",ESymbolOpen"["),("]",ESymbolClose"]"),("\\{",ESymbolOpen"{"),("\\}",ESymbolClose"}"),("\\lbrack",ESymbolOpen"["),("\\lbrace",ESymbolOpen"{"),("\\rbrack",ESymbolClose"]"),("\\rbrace",ESymbolClose"}"),("\\llbracket",ESymbolOpen"\x27E6"),("\\rrbracket",ESymbolClose"\x230B"),("\\langle",ESymbolOpen"\x27E8"),("\\rangle",ESymbolClose"\x27E9"),("\\lfloor",ESymbolOpen"\x230A"),("\\rfloor",ESymbolClose"\x230B"),("\\lceil",ESymbolOpen"\x2308"),("\\rceil",ESymbolClose"\x2309"),("|",ESymbolOpen"\x2223"),("|",ESymbolClose"\x2223"),("\\|",ESymbolOpen"\x2225"),("\\|",ESymbolClose"\x2225"),("\\vert",ESymbolOpen"\x2223"),("\\vert",ESymbolClose"\x2223"),("\\Vert",ESymbolOpen"\x2225"),("\\Vert",ESymbolClose"\x2225")]symbols::M.MapStringExpsymbols=M.fromList[("+",ESymbolBin"+"),("-",ESymbolBin"-"),("*",ESymbolBin"*"),(",",ESymbolPun","),(".",ESymbolPun"."),(";",ESymbolPun";"),(":",ESymbolPun":"),("?",ESymbolPun"?"),(">",ESymbolRel">"),("<",ESymbolRel"<"),("!",ESymbolOrd"!"),("'",ESymbolOrd"\x02B9"),("''",ESymbolOrd"\x02BA"),("'''",ESymbolOrd"\x2034"),("''''",ESymbolOrd"\x2057"),("=",ESymbolRel"="),(":=",ESymbolRel":="),("\\mid",ESymbolBin"\x2223"),("\\parallel",ESymbolRel"\x2225"),("\\backslash",ESymbolBin"\x2216"),("/",ESymbolBin"/"),("\\setminus",ESymbolBin"\\"),("\\times",ESymbolBin"\x00D7"),("\\alpha",ESymbolOrd"\x03B1"),("\\beta",ESymbolOrd"\x03B2"),("\\chi",ESymbolOrd"\x03C7"),("\\delta",ESymbolOrd"\x03B4"),("\\Delta",ESymbolOp"\x0394"),("\\epsi",ESymbolOrd"\x03B5"),("\\varepsilon",ESymbolOrd"\x025B"),("\\eta",ESymbolOrd"\x03B7"),("\\gamma",ESymbolOrd"\x03B3"),("\\Gamma",ESymbolOp"\x0393"),("\\iota",ESymbolOrd"\x03B9"),("\\kappa",ESymbolOrd"\x03BA"),("\\lambda",ESymbolOrd"\x03BB"),("\\Lambda",ESymbolOp"\x039B"),("\\mu",ESymbolOrd"\x03BC"),("\\nu",ESymbolOrd"\x03BD"),("\\omega",ESymbolOrd"\x03C9"),("\\Omega",ESymbolOp"\x03A9"),("\\phi",ESymbolOrd"\x03C6"),("\\varphi",ESymbolOrd"\x03D5"),("\\Phi",ESymbolOp"\x03A6"),("\\pi",ESymbolOrd"\x03C0"),("\\Pi",ESymbolOp"\x03A0"),("\\psi",ESymbolOrd"\x03C8"),("\\Psi",ESymbolOrd"\x03A8"),("\\rho",ESymbolOrd"\x03C1"),("\\sigma",ESymbolOrd"\x03C3"),("\\Sigma",ESymbolOp"\x03A3"),("\\tau",ESymbolOrd"\x03C4"),("\\theta",ESymbolOrd"\x03B8"),("\\vartheta",ESymbolOrd"\x03D1"),("\\Theta",ESymbolOp"\x0398"),("\\upsilon",ESymbolOrd"\x03C5"),("\\xi",ESymbolOrd"\x03BE"),("\\Xi",ESymbolOp"\x039E"),("\\zeta",ESymbolOrd"\x03B6"),("\\frac12",ESymbolOrd"\x00BD"),("\\frac14",ESymbolOrd"\x00BC"),("\\frac34",ESymbolOrd"\x00BE"),("\\frac13",ESymbolOrd"\x2153"),("\\frac23",ESymbolOrd"\x2154"),("\\frac15",ESymbolOrd"\x2155"),("\\frac25",ESymbolOrd"\x2156"),("\\frac35",ESymbolOrd"\x2157"),("\\frac45",ESymbolOrd"\x2158"),("\\frac16",ESymbolOrd"\x2159"),("\\frac56",ESymbolOrd"\x215A"),("\\frac18",ESymbolOrd"\x215B"),("\\frac38",ESymbolOrd"\x215C"),("\\frac58",ESymbolOrd"\x215D"),("\\frac78",ESymbolOrd"\x215E"),("\\pm",ESymbolBin"\x00B1"),("\\mp",ESymbolBin"\x2213"),("\\triangleleft",ESymbolBin"\x22B2"),("\\triangleright",ESymbolBin"\x22B3"),("\\cdot",ESymbolBin"\x22C5"),("\\star",ESymbolBin"\x22C6"),("\\ast",ESymbolBin"\x002A"),("\\times",ESymbolBin"\x00D7"),("\\div",ESymbolBin"\x00F7"),("\\circ",ESymbolBin"\x2218"),("\\bullet",ESymbolBin"\x2022"),("\\oplus",ESymbolBin"\x2295"),("\\ominus",ESymbolBin"\x2296"),("\\otimes",ESymbolBin"\x2297"),("\\bigcirc",ESymbolBin"\x25CB"),("\\oslash",ESymbolBin"\x2298"),("\\odot",ESymbolBin"\x2299"),("\\land",ESymbolBin"\x2227"),("\\wedge",ESymbolBin"\x2227"),("\\lor",ESymbolBin"\x2228"),("\\vee",ESymbolBin"\x2228"),("\\cap",ESymbolBin"\x2229"),("\\cup",ESymbolBin"\x222A"),("\\sqcap",ESymbolBin"\x2293"),("\\sqcup",ESymbolBin"\x2294"),("\\uplus",ESymbolBin"\x228E"),("\\amalg",ESymbolBin"\x2210"),("\\bigtriangleup",ESymbolBin"\x25B3"),("\\bigtriangledown",ESymbolBin"\x25BD"),("\\dag",ESymbolBin"\x2020"),("\\dagger",ESymbolBin"\x2020"),("\\ddag",ESymbolBin"\x2021"),("\\ddagger",ESymbolBin"\x2021"),("\\lhd",ESymbolBin"\x22B2"),("\\rhd",ESymbolBin"\x22B3"),("\\unlhd",ESymbolBin"\x22B4"),("\\unrhd",ESymbolBin"\x22B5"),("\\lt",ESymbolRel"<"),("\\gt",ESymbolRel">"),("\\ne",ESymbolRel"\x2260"),("\\neq",ESymbolRel"\x2260"),("\\le",ESymbolRel"\x2264"),("\\leq",ESymbolRel"\x2264"),("\\leqslant",ESymbolRel"\x2264"),("\\ge",ESymbolRel"\x2265"),("\\geq",ESymbolRel"\x2265"),("\\geqslant",ESymbolRel"\x2265"),("\\equiv",ESymbolRel"\x2261"),("\\ll",ESymbolRel"\x226A"),("\\gg",ESymbolRel"\x226B"),("\\doteq",ESymbolRel"\x2250"),("\\prec",ESymbolRel"\x227A"),("\\succ",ESymbolRel"\x227B"),("\\preceq",ESymbolRel"\x227C"),("\\succeq",ESymbolRel"\x227D"),("\\subset",ESymbolRel"\x2282"),("\\supset",ESymbolRel"\x2283"),("\\subseteq",ESymbolRel"\x2286"),("\\supseteq",ESymbolRel"\x2287"),("\\sqsubset",ESymbolRel"\x228F"),("\\sqsupset",ESymbolRel"\x2290"),("\\sqsubseteq",ESymbolRel"\x2291"),("\\sqsupseteq",ESymbolRel"\x2292"),("\\sim",ESymbolRel"\x223C"),("\\simeq",ESymbolRel"\x2243"),("\\approx",ESymbolRel"\x2248"),("\\cong",ESymbolRel"\x2245"),("\\Join",ESymbolRel"\x22C8"),("\\bowtie",ESymbolRel"\x22C8"),("\\in",ESymbolRel"\x2208"),("\\ni",ESymbolRel"\x220B"),("\\owns",ESymbolRel"\x220B"),("\\propto",ESymbolRel"\x221D"),("\\vdash",ESymbolRel"\x22A2"),("\\dashv",ESymbolRel"\x22A3"),("\\models",ESymbolRel"\x22A8"),("\\perp",ESymbolRel"\x22A5"),("\\smile",ESymbolRel"\x2323"),("\\frown",ESymbolRel"\x2322"),("\\asymp",ESymbolRel"\x224D"),("\\notin",ESymbolRel"\x2209"),("\\gets",ESymbolRel"\x2190"),("\\leftarrow",ESymbolRel"\x2190"),("\\to",ESymbolRel"\x2192"),("\\rightarrow",ESymbolRel"\x2192"),("\\leftrightarrow",ESymbolRel"\x2194"),("\\uparrow",ESymbolRel"\x2191"),("\\downarrow",ESymbolRel"\x2193"),("\\updownarrow",ESymbolRel"\x2195"),("\\Leftarrow",ESymbolRel"\x21D0"),("\\Rightarrow",ESymbolRel"\x21D2"),("\\Leftrightarrow",ESymbolRel"\x21D4"),("\\iff",ESymbolRel"\x21D4"),("\\Uparrow",ESymbolRel"\x21D1"),("\\Downarrow",ESymbolRel"\x21D3"),("\\Updownarrow",ESymbolRel"\x21D5"),("\\mapsto",ESymbolRel"\x21A6"),("\\longleftarrow",ESymbolRel"\x2190"),("\\longrightarrow",ESymbolRel"\x2192"),("\\longleftrightarrow",ESymbolRel"\x2194"),("\\Longleftarrow",ESymbolRel"\x21D0"),("\\Longrightarrow",ESymbolRel"\x21D2"),("\\Longleftrightarrow",ESymbolRel"\x21D4"),("\\longmapsto",ESymbolRel"\x21A6"),("\\sum",ESymbolOp"\x2211"),("\\prod",ESymbolOp"\x220F"),("\\bigcap",ESymbolOp"\x22C2"),("\\bigcup",ESymbolOp"\x22C3"),("\\bigwedge",ESymbolOp"\x22C0"),("\\bigvee",ESymbolOp"\x22C1"),("\\bigsqcap",ESymbolOp"\x2A05"),("\\bigsqcup",ESymbolOp"\x2A06"),("\\coprod",ESymbolOp"\x2210"),("\\bigoplus",ESymbolOp"\x2A01"),("\\bigotimes",ESymbolOp"\x2A02"),("\\bigodot",ESymbolOp"\x2A00"),("\\biguplus",ESymbolOp"\x2A04"),("\\int",ESymbolOp"\x222B"),("\\iint",ESymbolOp"\x222C"),("\\iiint",ESymbolOp"\x222D"),("\\oint",ESymbolOp"\x222E"),("\\prime",ESymbolOrd"\x2032"),("\\dots",ESymbolOrd"\x2026"),("\\ldots",ESymbolOrd"\x2026"),("\\cdots",ESymbolOrd"\x22EF"),("\\vdots",ESymbolOrd"\x22EE"),("\\ddots",ESymbolOrd"\x22F1"),("\\forall",ESymbolOp"\x2200"),("\\exists",ESymbolOp"\x2203"),("\\Re",ESymbolOrd"\x211C"),("\\Im",ESymbolOrd"\x2111"),("\\aleph",ESymbolOrd"\x2135"),("\\hbar",ESymbolOrd"\x210F"),("\\ell",ESymbolOrd"\x2113"),("\\wp",ESymbolOrd"\x2118"),("\\emptyset",ESymbolOrd"\x2205"),("\\infty",ESymbolOrd"\x221E"),("\\partial",ESymbolOrd"\x2202"),("\\nabla",ESymbolOrd"\x2207"),("\\triangle",ESymbolOrd"\x25B3"),("\\therefore",ESymbolPun"\x2234"),("\\angle",ESymbolOrd"\x2220"),("\\diamond",ESymbolOp"\x22C4"),("\\Diamond",ESymbolOp"\x25C7"),("\\neg",ESymbolOp"\x00AC"),("\\lnot",ESymbolOrd"\x00AC"),("\\bot",ESymbolOrd"\x22A5"),("\\top",ESymbolOrd"\x22A4"),("\\square",ESymbolOrd"\x25AB"),("\\Box",ESymbolOp"\x25A1"),("\\wr",ESymbolOrd"\x2240"),("\\!",ESpace"-0.167em"),("\\,",ESpace"0.167em"),("\\>",ESpace"0.222em"),("\\:",ESpace"0.222em"),("\\;",ESpace"0.278em"),("~",ESpace"0.333em"),("\\quad",ESpace"1em"),("\\qquad",ESpace"2em"),("\\arccos",EMathOperator"arccos"),("\\arcsin",EMathOperator"arcsin"),("\\arctan",EMathOperator"arctan"),("\\arg",EMathOperator"arg"),("\\cos",EMathOperator"cos"),("\\cosh",EMathOperator"cosh"),("\\cot",EMathOperator"cot"),("\\coth",EMathOperator"coth"),("\\csc",EMathOperator"csc"),("\\deg",EMathOperator"deg"),("\\det",EMathOperator"det"),("\\dim",EMathOperator"dim"),("\\exp",EMathOperator"exp"),("\\gcd",EMathOperator"gcd"),("\\hom",EMathOperator"hom"),("\\inf",EMathOperator"inf"),("\\ker",EMathOperator"ker"),("\\lg",EMathOperator"lg"),("\\lim",EMathOperator"lim"),("\\liminf",EMathOperator"liminf"),("\\limsup",EMathOperator"limsup"),("\\ln",EMathOperator"ln"),("\\log",EMathOperator"log"),("\\max",EMathOperator"max"),("\\min",EMathOperator"min"),("\\Pr",EMathOperator"Pr"),("\\sec",EMathOperator"sec"),("\\sin",EMathOperator"sin"),("\\sinh",EMathOperator"sinh"),("\\sup",EMathOperator"sup"),("\\tan",EMathOperator"tan"),("\\tanh",EMathOperator"tanh")]-- MathML has a mathvariant attribute which is unimplemented in Firefox-- (see https://bugzilla.mozilla.org/show_bug.cgi?id=114365)-- Therefore, we translate mathcal to unicode symbols directly.-- This list is from http://www.w3.org/TR/MathML2/script.htmlmathcal::M.MapStringStringmathcal=M.fromList[("A","\x1D49C"),("B","\x0212C"),("C","\x1D49E"),("D","\x1D49F"),("E","\x02130"),("F","\x02131"),("G","\x1D4A2"),("H","\x0210B"),("I","\x02110"),("J","\x1D4A5"),("K","\x1D4A6"),("L","\x02112"),("M","\x02133"),("N","\x1D4A9"),("O","\x1D4AA"),("P","\x1D4AB"),("Q","\x1D4AC"),("R","\x0211B"),("S","\x1D4AE"),("T","\x1D4AF"),("U","\x1D4B0"),("V","\x1D4B1"),("W","\x1D4B2"),("X","\x1D4B3"),("Y","\x1D4B4"),("Z","\x1D4B5"),("a","\x1D4B6"),("b","\x1D4B7"),("c","\x1D4B8"),("d","\x1D4B9"),("e","\x0212F"),("f","\x1D4BB"),("g","\x0210A"),("h","\x1D4BD"),("i","\x1D4BE"),("j","\x1D4BF"),("k","\x1D4C0"),("l","\x1D4C1"),("m","\x1D4C2"),("n","\x1D4C3"),("o","\x02134"),("p","\x1D4C5"),("q","\x1D4C6"),("r","\x1D4C7"),("s","\x1D4C8"),("t","\x1D4C9"),("u","\x1D4CA"),("v","\x1D4CB"),("w","\x1D4CC"),("x","\x1D4CD"),("y","\x1D4CE"),("z","\x1D4CF")]-- Similar to mathcal above, we translate manually.-- This list is from http://www.w3.org/TR/MathML2/double-struck.htmlmathbb::M.MapStringStringmathbb=M.fromList[("A","\x1D538"),("B","\x1D539"),("C","\x02102"),("D","\x1D53B"),("E","\x1D53C"),("F","\x1D53D"),("G","\x1D53E"),("H","\x0210D"),("I","\x1D540"),("J","\x1D541"),("K","\x1D542"),("L","\x1D543"),("M","\x1D544"),("N","\x02115"),("O","\x1D546"),("P","\x02119"),("Q","\x0211A"),("R","\x0211D"),("S","\x1D54A"),("T","\x1D54B"),("U","\x1D54C"),("V","\x1D54D"),("W","\x1D54E"),("X","\x1D54F"),("Y","\x1D550"),("Z","\x02124"),("a","\x1D552"),("b","\x1D553"),("c","\x1D554"),("d","\x1D555"),("e","\x1D556"),("f","\x1D557"),("g","\x1D558"),("h","\x1D559"),("i","\x1D55A"),("j","\x1D55B"),("k","\x1D55C"),("l","\x1D55D"),("m","\x1D55E"),("n","\x1D55F"),("o","\x1D560"),("p","\x1D561"),("q","\x1D562"),("r","\x1D563"),("s","\x1D564"),("t","\x1D565"),("u","\x1D566"),("v","\x1D567"),("w","\x1D568"),("x","\x1D569"),("y","\x1D56A"),("z","\x1D56B"),("0","\x1D7D8"),("1","\x1D7D9"),("2","\x1D7DA"),("3","\x1D7DB"),("4","\x1D7DC"),("5","\x1D7DD"),("6","\x1D7DE"),("7","\x1D7DF"),("8","\x1D7E0"),("9","\x1D7E1")]