@@ -36,7 +36,7 @@ import Text.Pandoc.Walk
3636import Text.Pandoc.Writers.Shared
3737import Text.Pandoc.Options
3838import Text.Pandoc.Templates (renderTemplate')
39−import Text.Pandoc.Readers.TeXMath
39+import Text.Pandoc.Writers.Math
4040import Data.List ( stripPrefix, isPrefixOf, intercalate, isSuffixOf )
4141import Data.Char ( toLower )
4242import Data.Monoid ( Any(..) )
@@ -50,13 +50,13 @@ import Data.Generics (everywhere, mkT)
5050import Text.Pandoc.Class (PandocMonad)
5151
5252-- | Convert list of authors to a docbook <author> section
53−authorToDocbook :: WriterOptions -> [Inline] -> B.Inlines
54−authorToDocbook opts name' =
55− let name = render Nothing $ inlinesToDocbook opts name'
56− colwidth = if writerWrapText opts == WrapAuto
53+authorToDocbook :: PandocMonad m => WriterOptions -> [Inline] -> m B.Inlines
54+authorToDocbook opts name' = do
55+ name <- render Nothing <$> inlinesToDocbook opts name'
56+ let colwidth = if writerWrapText opts == WrapAuto
5757 then Just $ writerColumns opts
5858 else Nothing
59− in B.rawInline "docbook" $ render colwidth $
59+ return $ B.rawInline "docbook" $ render colwidth $
6060 if ',' `elem` name
6161 then -- last name first
6262 let (lastname, rest) = break (==',') name
@@ -75,44 +75,45 @@ authorToDocbook opts name' =
7575
7676-- | Convert Pandoc document to string in Docbook format.
7777writeDocbook :: PandocMonad m => WriterOptions -> Pandoc -> m String
78−writeDocbook opts (Pandoc meta blocks) = return $
78+writeDocbook opts (Pandoc meta blocks) = do
7979 let elements = hierarchicalize blocks
80− colwidth = if writerWrapText opts == WrapAuto
80+ let colwidth = if writerWrapText opts == WrapAuto
8181 then Just $ writerColumns opts
8282 else Nothing
83− render' = render colwidth
84− opts' = if (maybe False (("/book>" `isSuffixOf`) . trimr)
83+ let render' = render colwidth
84+ let opts' = if (maybe False (("/book>" `isSuffixOf`) . trimr)
8585 (writerTemplate opts) &&
8686 TopLevelDefault == writerTopLevelDivision opts)
8787 then opts{ writerTopLevelDivision = TopLevelChapter }
8888 else opts
89− -- The numbering here follows LaTeX's internal numbering
90− startLvl = case writerTopLevelDivision opts' of
89+ -- The numbering here follows LaTeX's internal numbering
90+ let startLvl = case writerTopLevelDivision opts' of
9191 TopLevelPart -> -1
9292 TopLevelChapter -> 0
9393 TopLevelSection -> 1
9494 TopLevelDefault -> 1
95− auths' = map (authorToDocbook opts) $ docAuthors meta
96− meta' = B.setMeta "author" auths' meta
97− Just metadata = metaToJSON opts
98− (Just . render colwidth . (vcat .
99− (map (elementToDocbook opts' startLvl)) . hierarchicalize))
100− (Just . render colwidth . inlinesToDocbook opts')
95+ auths' <- mapM (authorToDocbook opts) $ docAuthors meta
96+ let meta' = B.setMeta "author" auths' meta
97+ metadata <- metaToJSON opts
98+ (fmap (render colwidth . vcat) .
99+ (mapM (elementToDocbook opts' startLvl) .
100+ hierarchicalize))
101+ (fmap (render colwidth) . inlinesToDocbook opts')
101102 meta'
102− main = render' $ vcat (map (elementToDocbook opts' startLvl) elements)
103− context = defField "body" main
103+ main <- (render' . vcat) <$> mapM (elementToDocbook opts' startLvl) elements
104+ let context = defField "body" main
104105 $ defField "mathml" (case writerHTMLMathMethod opts of
105106 MathML _ -> True
106107 _ -> False)
107108 $ metadata
108− in case writerTemplate opts of
109+ return $ case writerTemplate opts of
109110 Nothing -> main
110111 Just tpl -> renderTemplate' tpl context
111112
112113-- | Convert an Element to Docbook.
113−elementToDocbook :: WriterOptions -> Int -> Element -> Doc
114+elementToDocbook :: PandocMonad m => WriterOptions -> Int -> Element -> m Doc
114115elementToDocbook opts _ (Blk block) = blockToDocbook opts block
115−elementToDocbook opts lvl (Sec _ _num (id',_,_) title elements) =
116+elementToDocbook opts lvl (Sec _ _num (id',_,_) title elements) = do
116117 -- Docbook doesn't allow sections with no content, so insert some if needed
117118 let elements' = if null elements
118119 then [Blk (Para [])]
@@ -131,13 +132,14 @@ elementToDocbook opts lvl (Sec _ _num (id',_,_) title elements) =
131132 nsAttr = if writerDocbook5 opts && lvl == 0 then [("xmlns", "http://docbook.org/ns/docbook"),("xmlns:xlink", "http://www.w3.org/1999/xlink")]
132133 else []
133134 attribs = nsAttr ++ idAttr
134− in inTags True tag attribs $
135− inTagsSimple "title" (inlinesToDocbook opts title) $$
136− vcat (map (elementToDocbook opts (lvl + 1)) elements')
135+ contents <- mapM (elementToDocbook opts (lvl + 1)) elements'
136+ title' <- inlinesToDocbook opts title
137+ return $ inTags True tag attribs $
138+ inTagsSimple "title" title' $$ vcat contents
137139
138140-- | Convert a list of Pandoc blocks to Docbook.
139−blocksToDocbook :: WriterOptions -> [Block] -> Doc
140−blocksToDocbook opts = vcat . map (blockToDocbook opts)
141+blocksToDocbook :: PandocMonad m => WriterOptions -> [Block] -> m Doc
142+blocksToDocbook opts = fmap vcat . mapM (blockToDocbook opts)
141143
142144-- | Auxiliary function to convert Plain block to Para.
143145plainToPara :: Block -> Block
@@ -146,26 +148,29 @@ plainToPara x = x
146148
147149-- | Convert a list of pairs of terms and definitions into a list of
148150-- Docbook varlistentrys.
149−deflistItemsToDocbook :: WriterOptions -> [([Inline],[[Block]])] -> Doc
151+deflistItemsToDocbook :: PandocMonad m
152+ => WriterOptions -> [([Inline],[[Block]])] -> m Doc
150153deflistItemsToDocbook opts items =
151− vcat $ map (\(term, defs) -> deflistItemToDocbook opts term defs) items
154+ vcat <$> mapM (\(term, defs) -> deflistItemToDocbook opts term defs) items
152155
153156-- | Convert a term and a list of blocks into a Docbook varlistentry.
154−deflistItemToDocbook :: WriterOptions -> [Inline] -> [[Block]] -> Doc
155−deflistItemToDocbook opts term defs =
156− let def' = concatMap (map plainToPara) defs
157− in inTagsIndented "varlistentry" $
158− inTagsIndented "term" (inlinesToDocbook opts term) $$
159− inTagsIndented "listitem" (blocksToDocbook opts def')
157+deflistItemToDocbook :: PandocMonad m
158+ => WriterOptions -> [Inline] -> [[Block]] -> m Doc
159+deflistItemToDocbook opts term defs = do
160+ term' <- inlinesToDocbook opts term
161+ def' <- blocksToDocbook opts $ concatMap (map plainToPara) defs
162+ return $ inTagsIndented "varlistentry" $
163+ inTagsIndented "term" term' $$
164+ inTagsIndented "listitem" def'
160165
161166-- | Convert a list of lists of blocks to a list of Docbook list items.
162−listItemsToDocbook :: WriterOptions -> [[Block]] -> Doc
163−listItemsToDocbook opts items = vcat $ map (listItemToDocbook opts) items
167+listItemsToDocbook :: PandocMonad m => WriterOptions -> [[Block]] -> m Doc
168+listItemsToDocbook opts items = vcat <$> mapM (listItemToDocbook opts) items
164169
165170-- | Convert a list of blocks into a Docbook list item.
166−listItemToDocbook :: WriterOptions -> [Block] -> Doc
171+listItemToDocbook :: PandocMonad m => WriterOptions -> [Block] -> m Doc
167172listItemToDocbook opts item =
168− inTagsIndented "listitem" $ blocksToDocbook opts $ map plainToPara item
173+ inTagsIndented "listitem" <$> blocksToDocbook opts (map plainToPara item)
169174
170175imageToDocbook :: WriterOptions -> Attr -> String -> Doc
171176imageToDocbook _ attr src = selfClosingTag "imagedata" $
@@ -177,43 +182,46 @@ imageToDocbook _ attr src = selfClosingTag "imagedata" $
177182 Nothing -> []
178183
179184-- | Convert a Pandoc block element to Docbook.
180−blockToDocbook :: WriterOptions -> Block -> Doc
181−blockToDocbook _ Null = empty
185+blockToDocbook :: PandocMonad m => WriterOptions -> Block -> m Doc
186+blockToDocbook _ Null = return empty
182187-- Add ids to paragraphs in divs with ids - this is needed for
183188-- pandoc-citeproc to get link anchors in bibliographies:
184189blockToDocbook opts (Div (ident,_,_) [Para lst]) =
185190 let attribs = [("id", ident) | not (null ident)] in
186191 if hasLineBreaks lst
187− then flush $ nowrap $ inTags False "literallayout" attribs
188− $ inlinesToDocbook opts lst
189− else inTags True "para" attribs $ inlinesToDocbook opts lst
190−blockToDocbook opts (Div (ident,_,_) bs) =
191− (if null ident
192− then mempty
193− else selfClosingTag "anchor" [("id", ident)]) $$
194− blocksToDocbook opts (map plainToPara bs)
195−blockToDocbook _ (Header _ _ _) = empty -- should not occur after hierarchicalize
192+ then (flush . nowrap . inTags False "literallayout" attribs)
193+ <$> inlinesToDocbook opts lst
194+ else inTags True "para" attribs <$> inlinesToDocbook opts lst
195+blockToDocbook opts (Div (ident,_,_) bs) = do
196+ contents <- blocksToDocbook opts (map plainToPara bs)
197+ return $
198+ (if null ident
199+ then mempty
200+ else selfClosingTag "anchor" [("id", ident)]) $$ contents
201+blockToDocbook _ (Header _ _ _) =
202+ return empty -- should not occur after hierarchicalize
196203blockToDocbook opts (Plain lst) = inlinesToDocbook opts lst
197204-- title beginning with fig: indicates that the image is a figure
198−blockToDocbook opts (Para [Image attr txt (src,'f':'i':'g':':':_)]) =
199− let alt = inlinesToDocbook opts txt
200− capt = if null txt
205+blockToDocbook opts (Para [Image attr txt (src,'f':'i':'g':':':_)]) = do
206+ alt <- inlinesToDocbook opts txt
207+ let capt = if null txt
201208 then empty
202209 else inTagsSimple "title" alt
203− in inTagsIndented "figure" $
210+ return $ inTagsIndented "figure" $
204211 capt $$
205212 (inTagsIndented "mediaobject" $
206213 (inTagsIndented "imageobject"
207214 (imageToDocbook opts attr src)) $$
208215 inTagsSimple "textobject" (inTagsSimple "phrase" alt))
209216blockToDocbook opts (Para lst)
210− | hasLineBreaks lst = flush $ nowrap $ inTagsSimple "literallayout" $ inlinesToDocbook opts lst
211− | otherwise = inTagsIndented "para" $ inlinesToDocbook opts lst
217+ | hasLineBreaks lst = (flush . nowrap . inTagsSimple "literallayout")
218+ <$> inlinesToDocbook opts lst
219+ | otherwise = inTagsIndented "para" <$> inlinesToDocbook opts lst
212220blockToDocbook opts (LineBlock lns) =
213221 blockToDocbook opts $ linesToPara lns
214222blockToDocbook opts (BlockQuote blocks) =
215− inTagsIndented "blockquote" $ blocksToDocbook opts blocks
216−blockToDocbook _ (CodeBlock (_,classes,_) str) =
223+ inTagsIndented "blockquote" <$> blocksToDocbook opts blocks
224+blockToDocbook _ (CodeBlock (_,classes,_) str) = return $
217225 text ("<programlisting" ++ lang ++ ">") <> cr <>
218226 flush (text (escapeStringForXML str) <> cr <> text "</programlisting>")
219227 where lang = if null langs
@@ -225,11 +233,11 @@ blockToDocbook _ (CodeBlock (_,classes,_) str) =
225233 then [s]
226234 else languagesByExtension . map toLower $ s
227235 langs = concatMap langsFrom classes
228−blockToDocbook opts (BulletList lst) =
236+blockToDocbook opts (BulletList lst) = do
229237 let attribs = [("spacing", "compact") | isTightList lst]
230− in inTags True "itemizedlist" attribs $ listItemsToDocbook opts lst
231−blockToDocbook _ (OrderedList _ []) = empty
232−blockToDocbook opts (OrderedList (start, numstyle, _) (first:rest)) =
238+ inTags True "itemizedlist" attribs <$> listItemsToDocbook opts lst
239+blockToDocbook _ (OrderedList _ []) = return empty
240+blockToDocbook opts (OrderedList (start, numstyle, _) (first:rest)) = do
233241 let numeration = case numstyle of
234242 DefaultStyle -> []
235243 Decimal -> [("numeration", "arabic")]
@@ -240,39 +248,41 @@ blockToDocbook opts (OrderedList (start, numstyle, _) (first:rest)) =
240248 LowerRoman -> [("numeration", "lowerroman")]
241249 spacing = [("spacing", "compact") | isTightList (first:rest)]
242250 attribs = numeration ++ spacing
243− items = if start == 1
244− then listItemsToDocbook opts (first:rest)
245− else (inTags True "listitem" [("override",show start)]
246− (blocksToDocbook opts $ map plainToPara first)) $$
247− listItemsToDocbook opts rest
248− in inTags True "orderedlist" attribs items
249−blockToDocbook opts (DefinitionList lst) =
251+ items <- if start == 1
252+ then listItemsToDocbook opts (first:rest)
253+ else do
254+ first' <- blocksToDocbook opts (map plainToPara first)
255+ rest' <- listItemsToDocbook opts rest
256+ return $
257+ (inTags True "listitem" [("override",show start)] first') $$
258+ rest'
259+ return $ inTags True "orderedlist" attribs items
260+blockToDocbook opts (DefinitionList lst) = do
250261 let attribs = [("spacing", "compact") | isTightList $ concatMap snd lst]
251− in inTags True "variablelist" attribs $ deflistItemsToDocbook opts lst
262+ inTags True "variablelist" attribs <$> deflistItemsToDocbook opts lst
252263blockToDocbook opts (RawBlock f str)
253− | f == "docbook" = text str -- raw XML block
264+ | f == "docbook" = return $ text str -- raw XML block
254265 | f == "html" = if writerDocbook5 opts
255− then empty -- No html in Docbook5
256− else text str -- allow html for backwards compatibility
257− | otherwise = empty
258−blockToDocbook _ HorizontalRule = empty -- not semantic
259−blockToDocbook opts (Table caption aligns widths headers rows) =
260− let captionDoc = if null caption
261− then empty
262− else inTagsIndented "title"
263− (inlinesToDocbook opts caption)
264− tableType = if isEmpty captionDoc then "informaltable" else "table"
266+ then return empty -- No html in Docbook5
267+ else return $ text str -- allow html for backwards compatibility
268+ | otherwise = return empty
269+blockToDocbook _ HorizontalRule = return empty -- not semantic
270+blockToDocbook opts (Table caption aligns widths headers rows) = do
271+ captionDoc <- if null caption
272+ then return empty
273+ else inTagsIndented "title" <$>
274+ inlinesToDocbook opts caption
275+ let tableType = if isEmpty captionDoc then "informaltable" else "table"
265276 percent w = show (truncate (100*w) :: Integer) ++ "*"
266277 coltags = vcat $ zipWith (\w al -> selfClosingTag "colspec"
267278 ([("colwidth", percent w) | w > 0] ++
268279 [("align", alignmentToString al)])) widths aligns
269− head' = if all null headers
270− then empty
271− else inTagsIndented "thead" $
272− tableRowToDocbook opts headers
273− body' = inTagsIndented "tbody" $
274− vcat $ map (tableRowToDocbook opts) rows
275− in inTagsIndented tableType $ captionDoc $$
280+ head' <- if all null headers
281+ then return empty
282+ else inTagsIndented "thead" <$> tableRowToDocbook opts headers
283+ body' <- (inTagsIndented "tbody" . vcat) <$>
284+ mapM (tableRowToDocbook opts) rows
285+ return $ inTagsIndented tableType $ captionDoc $$
276286 (inTags True "tgroup" [("cols", show (length headers))] $
277287 coltags $$ head' $$ body')
278288
@@ -293,92 +303,97 @@ alignmentToString alignment = case alignment of
293303 AlignCenter -> "center"
294304 AlignDefault -> "left"
295305
296−tableRowToDocbook :: WriterOptions
306+tableRowToDocbook :: PandocMonad m
307+ => WriterOptions
297308 -> [[Block]]
298− -> Doc
309+ -> m Doc
299310tableRowToDocbook opts cols =
300− inTagsIndented "row" $ vcat $ map (tableItemToDocbook opts) cols
311+ (inTagsIndented "row" . vcat) <$> mapM (tableItemToDocbook opts) cols
301312
302−tableItemToDocbook :: WriterOptions
313+tableItemToDocbook :: PandocMonad m
314+ => WriterOptions
303315 -> [Block]
304− -> Doc
316+ -> m Doc
305317tableItemToDocbook opts item =
306− inTags True "entry" [] $ vcat $ map (blockToDocbook opts) item
318+ (inTags True "entry" [] . vcat) <$> mapM (blockToDocbook opts) item
307319
308320-- | Convert a list of inline elements to Docbook.
309−inlinesToDocbook :: WriterOptions -> [Inline] -> Doc
310−inlinesToDocbook opts lst = hcat $ map (inlineToDocbook opts) lst
321+inlinesToDocbook :: PandocMonad m => WriterOptions -> [Inline] -> m Doc
322+inlinesToDocbook opts lst = hcat <$> mapM (inlineToDocbook opts) lst
311323
312324-- | Convert an inline element to Docbook.
313−inlineToDocbook :: WriterOptions -> Inline -> Doc
314−inlineToDocbook _ (Str str) = text $ escapeStringForXML str
325+inlineToDocbook :: PandocMonad m => WriterOptions -> Inline -> m Doc
326+inlineToDocbook _ (Str str) = return $ text $ escapeStringForXML str
315327inlineToDocbook opts (Emph lst) =
316− inTagsSimple "emphasis" $ inlinesToDocbook opts lst
328+ inTagsSimple "emphasis" <$> inlinesToDocbook opts lst
317329inlineToDocbook opts (Strong lst) =
318− inTags False "emphasis" [("role", "strong")] $ inlinesToDocbook opts lst
330+ inTags False "emphasis" [("role", "strong")] <$> inlinesToDocbook opts lst
319331inlineToDocbook opts (Strikeout lst) =
320− inTags False "emphasis" [("role", "strikethrough")] $
332+ inTags False "emphasis" [("role", "strikethrough")] <$>
321333 inlinesToDocbook opts lst
322334inlineToDocbook opts (Superscript lst) =
323− inTagsSimple "superscript" $ inlinesToDocbook opts lst
335+ inTagsSimple "superscript" <$> inlinesToDocbook opts lst
324336inlineToDocbook opts (Subscript lst) =
325− inTagsSimple "subscript" $ inlinesToDocbook opts lst
337+ inTagsSimple "subscript" <$> inlinesToDocbook opts lst
326338inlineToDocbook opts (SmallCaps lst) =
327− inTags False "emphasis" [("role", "smallcaps")] $
339+ inTags False "emphasis" [("role", "smallcaps")] <$>
328340 inlinesToDocbook opts lst
329341inlineToDocbook opts (Quoted _ lst) =
330− inTagsSimple "quote" $ inlinesToDocbook opts lst
342+ inTagsSimple "quote" <$> inlinesToDocbook opts lst
331343inlineToDocbook opts (Cite _ lst) =
332344 inlinesToDocbook opts lst
333345inlineToDocbook opts (Span (ident,_,_) ils) =
334− (if null ident
335− then mempty
336− else selfClosingTag "anchor" [("id", ident)]) <>
346+ ((if null ident
347+ then mempty
348+ else selfClosingTag "anchor" [("id", ident)]) <>) <$>
337349 inlinesToDocbook opts ils
338350inlineToDocbook _ (Code _ str) =
339− inTagsSimple "literal" $ text (escapeStringForXML str)
351+ return $ inTagsSimple "literal" $ text (escapeStringForXML str)
340352inlineToDocbook opts (Math t str)
341− | isMathML (writerHTMLMathMethod opts) =
342− case writeMathML dt <$> readTeX str of
343− Right r -> inTagsSimple tagtype
344− $ text $ Xml.ppcElement conf
345− $ fixNS
346− $ removeAttr r
347− Left _ -> inlinesToDocbook opts
348− $ texMathToInlines t str
349− | otherwise = inlinesToDocbook opts $ texMathToInlines t str
350− where (dt, tagtype) = case t of
351− InlineMath -> (DisplayInline,"inlineequation")
352− DisplayMath -> (DisplayBlock,"informalequation")
353+ | isMathML (writerHTMLMathMethod opts) = do
354+ res <- convertMath writeMathML t str
355+ case res of
356+ Right r -> return $ inTagsSimple tagtype
357+ $ text $ Xml.ppcElement conf
358+ $ fixNS
359+ $ removeAttr r
360+ Left il -> inlineToDocbook opts il
361+ | otherwise =
362+ texMathToInlines t str >>= inlinesToDocbook opts
363+ where tagtype = case t of
364+ InlineMath -> "inlineequation"
365+ DisplayMath -> "informalequation"
353366 conf = Xml.useShortEmptyTags (const False) Xml.defaultConfigPP
354367 removeAttr e = e{ Xml.elAttribs = [] }
355368 fixNS' qname = qname{ Xml.qPrefix = Just "mml" }
356369 fixNS = everywhere (mkT fixNS')
357−inlineToDocbook _ (RawInline f x) | f == "html" || f == "docbook" = text x
358− | otherwise = empty
359−inlineToDocbook _ LineBreak = text "\n"
370+inlineToDocbook _ (RawInline f x)
371+ | f == "html" || f == "docbook" = return $ text x
372+ | otherwise = return empty
373+inlineToDocbook _ LineBreak = return $ text "\n"
360374-- currently ignore, would require the option to add custom
361375-- styles to the document
362−inlineToDocbook _ PageBreak = empty
363−inlineToDocbook _ Space = space
376+inlineToDocbook _ PageBreak = return empty
377+inlineToDocbook _ Space = return space
364378-- because we use \n for LineBreak, we can't do soft breaks:
365−inlineToDocbook _ SoftBreak = space
379+inlineToDocbook _ SoftBreak = return space
366380inlineToDocbook opts (Link attr txt (src, _))
367381 | Just email <- stripPrefix "mailto:" src =
368382 let emailLink = inTagsSimple "email" $ text $
369383 escapeStringForXML $ email
370384 in case txt of
371− [Str s] | escapeURI s == email -> emailLink
372− _ -> inlinesToDocbook opts txt <+>
373− char '(' <> emailLink <> char ')'
385+ [Str s] | escapeURI s == email -> return emailLink
386+ _ -> do contents <- inlinesToDocbook opts txt
387+ return $ contents <+>
388+ char '(' <> emailLink <> char ')'
374389 | otherwise =
375390 (if isPrefixOf "#" src
376391 then inTags False "link" $ ("linkend", drop 1 src) : idAndRole attr
377392 else if writerDocbook5 opts
378393 then inTags False "link" $ ("xlink:href", src) : idAndRole attr
379− else inTags False "ulink" $ ("url", src) : idAndRole attr ) $
380− inlinesToDocbook opts txt
381−inlineToDocbook opts (Image attr _ (src, tit)) =
394+ else inTags False "ulink" $ ("url", src) : idAndRole attr )
395+ <$> inlinesToDocbook opts txt
396+inlineToDocbook opts (Image attr _ (src, tit)) = return $
382397 let titleDoc = if null tit
383398 then empty
384399 else inTagsIndented "objectinfo" $
@@ -386,7 +401,7 @@ inlineToDocbook opts (Image attr _ (src, tit)) =
386401 in inTagsIndented "inlinemediaobject" $ inTagsIndented "imageobject" $
387402 titleDoc $$ imageToDocbook opts attr src
388403inlineToDocbook opts (Note contents) =
389− inTagsIndented "footnote" $ blocksToDocbook opts contents
404+ inTagsIndented "footnote" <$> blocksToDocbook opts contents
390405
391406isMathML :: HTMLMathMethod -> Bool
392407isMathML (MathML _) = True