@@ -28,208 +28,64 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2828Conversion of TeX math to a list of 'Pandoc' inline elements.
2929-}
3030module Text.Pandoc.Readers.TeXMath (
31− readTeXMath
31+ readTeXMath
3232 ) where
3333
3434import Text.ParserCombinators.Parsec
3535import Text.Pandoc.Definition
36+import Text.TeXMath.Parser
3637
37−-- | Converts a string of raw TeX math to a list of 'Pandoc' inlines.
38+-- | Converts a raw TeX math formula to a list of 'Pandoc' inlines.
39+-- Defaults to raw formula between @$@ characters if entire formula
40+-- can't be converted.
3841readTeXMath :: String -- ^ String to parse (assumes @'\n'@ line endings)
3942 -> [Inline]
40−readTeXMath inp = case parse teXMath ("formula: " ++ inp) inp of
41− Left _ -> [Str inp] -- if unparseable, just include original
42− Right res -> res
43−
44−teXMath :: GenParser Char st [Inline]
45−teXMath = manyTill mathPart eof >>= return . concat
46−
47−mathPart :: GenParser Char st [Inline]
48−mathPart = whitespace <|> superscript <|> subscript <|> symbol <|>
49− argument <|> digits <|> letters <|> misc
50−
51−whitespace :: GenParser Char st [Inline]
52−whitespace = many1 space >> return []
53−
54−symbol :: GenParser Char st [Inline]
55−symbol = try $ do
56− char '\\'
57− res <- many1 letter
58− case lookup res teXsymbols of
59− Just m -> return [Str m]
60− Nothing -> return [Str $ "\\" ++ res]
61−
62−argument :: GenParser Char st [Inline]
63−argument = try $ do
64− char '{'
65− res <- many mathPart
66− char '}'
67− return $ if null res
68− then [Str " "]
69− else [Str "{"] ++ concat res ++ [Str "}"]
70−
71−digits :: GenParser Char st [Inline]
72−digits = do
73− res <- many1 digit
74− return [Str res]
75−
76−letters :: GenParser Char st [Inline]
77−letters = do
78− res <- many1 letter
79− return [Emph [Str res]]
80−
81−misc :: GenParser Char st [Inline]
82−misc = do
83− res <- noneOf "}"
84− return [Str [res]]
85−
86−scriptArg :: GenParser Char st [Inline]
87−scriptArg = try $ do
88− (try (do{char '{'; r <- many mathPart; char '}'; return $ concat r}))
89− <|> symbol
90− <|> (do{c <- (letter <|> digit); return [Str [c]]})
91−
92−superscript :: GenParser Char st [Inline]
93−superscript = try $ do
94− char '^'
95− arg <- scriptArg
96− return [Superscript arg]
97−
98−subscript :: GenParser Char st [Inline]
99−subscript = try $ do
100− char '_'
101− arg <- scriptArg
102− return [Subscript arg]
103−
104−withThinSpace :: String -> String
105−withThinSpace str = "\x2009" ++ str ++ "\x2009"
106−
107−teXsymbols :: [(String, String)]
108−teXsymbols =
109− [("alpha","\x3B1")
110− ,("beta", "\x3B2")
111− ,("chi", "\x3C7")
112− ,("delta", "\x3B4")
113− ,("Delta", "\x394")
114− ,("epsilon", "\x3B5")
115− ,("varepsilon", "\x25B")
116− ,("eta", "\x3B7")
117− ,("gamma", "\x3B3")
118− ,("Gamma", "\x393")
119− ,("iota", "\x3B9")
120− ,("kappa", "\x3BA")
121− ,("lambda", "\x3BB")
122− ,("Lambda", "\x39B")
123− ,("mu", "\x3BC")
124− ,("nu", "\x3BD")
125− ,("omega", "\x3C9")
126− ,("Omega", "\x3A9")
127− ,("phi", "\x3C6")
128− ,("varphi", "\x3D5")
129− ,("Phi", "\x3A6")
130− ,("pi", "\x3C0")
131− ,("Pi", "\x3A0")
132− ,("psi", "\x3C8")
133− ,("Psi", "\x3A8")
134− ,("rho", "\x3C1")
135− ,("sigma", "\x3C3")
136− ,("Sigma", "\x3A3")
137− ,("tau", "\x3C4")
138− ,("theta", "\x3B8")
139− ,("vartheta", "\x3D1")
140− ,("Theta", "\x398")
141− ,("upsilon", "\x3C5")
142− ,("xi", "\x3BE")
143− ,("Xi", "\x39E")
144− ,("zeta", "\x3B6")
145− ,("ne", "\x2260")
146− ,("lt", withThinSpace "<")
147− ,("le", withThinSpace "\x2264")
148− ,("leq", withThinSpace "\x2264")
149− ,("ge", withThinSpace "\x2265")
150− ,("geq", withThinSpace "\x2265")
151− ,("prec", withThinSpace "\x227A")
152− ,("succ", withThinSpace "\x227B")
153− ,("preceq", withThinSpace "\x2AAF")
154− ,("succeq", withThinSpace "\x2AB0")
155− ,("in", withThinSpace "\x2208")
156− ,("notin", withThinSpace "\x2209")
157− ,("subset", withThinSpace "\x2282")
158− ,("supset", withThinSpace "\x2283")
159− ,("subseteq", withThinSpace "\x2286")
160− ,("supseteq", withThinSpace "\x2287")
161− ,("equiv", withThinSpace "\x2261")
162− ,("cong", withThinSpace "\x2245")
163− ,("approx", withThinSpace "\x2248")
164− ,("propto", withThinSpace "\x221D")
165− ,("cdot", withThinSpace "\x22C5")
166− ,("star", withThinSpace "\x22C6")
167− ,("backslash", "\\")
168− ,("times", withThinSpace "\x00D7")
169− ,("divide", withThinSpace "\x00F7")
170− ,("circ", withThinSpace "\x2218")
171− ,("oplus", withThinSpace "\x2295")
172− ,("otimes", withThinSpace "\x2297")
173− ,("odot", withThinSpace "\x2299")
174− ,("sum", "\x2211")
175− ,("prod", "\x220F")
176− ,("wedge", withThinSpace "\x2227")
177− ,("bigwedge", withThinSpace "\x22C0")
178− ,("vee", withThinSpace "\x2228")
179− ,("bigvee", withThinSpace "\x22C1")
180− ,("cap", withThinSpace "\x2229")
181− ,("bigcap", withThinSpace "\x22C2")
182− ,("cup", withThinSpace "\x222A")
183− ,("bigcup", withThinSpace "\x22C3")
184− ,("neg", "\x00AC")
185− ,("implies", withThinSpace "\x21D2")
186− ,("iff", withThinSpace "\x21D4")
187− ,("forall", "\x2200")
188− ,("exists", "\x2203")
189− ,("bot", "\x22A5")
190− ,("top", "\x22A4")
191− ,("vdash", "\x22A2")
192− ,("models", withThinSpace "\x22A8")
193− ,("uparrow", "\x2191")
194− ,("downarrow", "\x2193")
195− ,("rightarrow", withThinSpace "\x2192")
196− ,("to", withThinSpace "\x2192")
197− ,("rightarrowtail", "\x21A3")
198− ,("twoheadrightarrow", withThinSpace "\x21A0")
199− ,("twoheadrightarrowtail", withThinSpace "\x2916")
200− ,("mapsto", withThinSpace "\x21A6")
201− ,("leftarrow", withThinSpace "\x2190")
202− ,("leftrightarrow", withThinSpace "\x2194")
203− ,("Rightarrow", withThinSpace "\x21D2")
204− ,("Leftarrow", withThinSpace "\x21D0")
205− ,("Leftrightarrow", withThinSpace "\x21D4")
206− ,("partial", "\x2202")
207− ,("nabla", "\x2207")
208− ,("pm", "\x00B1")
209− ,("emptyset", "\x2205")
210− ,("infty", "\x221E")
211− ,("aleph", "\x2135")
212− ,("ldots", "...")
213− ,("therefore", "\x2234")
214− ,("angle", "\x2220")
215− ,("quad", "\x00A0\x00A0")
216− ,("cdots", "\x22EF")
217− ,("vdots", "\x22EE")
218− ,("ddots", "\x22F1")
219− ,("diamond", "\x22C4")
220− ,("Box", "\x25A1")
221− ,("lfloor", "\x230A")
222− ,("rfloor", "\x230B")
223− ,("lceiling", "\x2308")
224− ,("rceiling", "\x2309")
225− ,("langle", "\x2329")
226− ,("rangle", "\x232A")
227− ,("int", "\8747")
228− ,("{", "{")
229− ,("}", "}")
230− ,("[", "[")
231− ,("]", "]")
232− ,("|", "|")
233− ,("||", "||")
234− ]
43+readTeXMath inp = case readTeXMath' inp of
44+ Nothing -> [Str ("$" ++ inp ++ "$")]
45+ Just res -> res
46+
47+-- | Like 'readTeXMath', but without the default.
48+readTeXMath' :: String -- ^ String to parse (assumes @'\n'@ line endings)
49+ -> Maybe [Inline]
50+readTeXMath' inp = case parse formula "formula" inp of
51+ Left _ -> Just [Str inp]
52+ Right exps -> expsToInlines exps
53+
54+expsToInlines :: [Exp] -> Maybe [Inline]
55+expsToInlines xs = do
56+ res <- mapM expToInlines xs
57+ return (concat res)
58+
59+expToInlines :: Exp -> Maybe [Inline]
60+expToInlines (ENumber s) = Just [Str s]
61+expToInlines (EIdentifier s) = Just [Emph [Str s]]
62+expToInlines (EMathOperator s) = Just [Str s]
63+expToInlines (ESymbol t s) = Just $ addSpace t (Str s)
64+ where addSpace Op x = [x, thinspace]
65+ addSpace Bin x = [medspace, x, medspace]
66+ addSpace Rel x = [widespace, x, widespace]
67+ addSpace Pun x = [x, thinspace]
68+ addSpace _ x = [x]
69+ thinspace = Str "\x2006"
70+ medspace = Str "\x2005"
71+ widespace = Str "\x2004"
72+expToInlines (EStretchy x) = expToInlines x
73+expToInlines (EGrouped xs) = expsToInlines xs
74+expToInlines (ESpace _) = Just [Str " "] -- variable widths not supported
75+expToInlines (EBinary _ _ _) = Nothing
76+expToInlines (ESub x y) = do
77+ x' <- expToInlines x
78+ y' <- expToInlines y
79+ return $ x' ++ [Subscript y']
80+expToInlines (ESuper x y) = do
81+ x' <- expToInlines x
82+ y' <- expToInlines y
83+ return $ x' ++ [Superscript y']
84+expToInlines (ESubsup x y z) = do
85+ x' <- expToInlines x
86+ y' <- expToInlines y
87+ z' <- expToInlines z
88+ return $ x' ++ [Subscript y'] ++ [Superscript z']
89+expToInlines (EText _ x) = Just [Emph [Str x]]
90+expToInlines _ = Nothing
23591