Pandoc过滤器模仿默认的MathML转换

时间:2016-12-13 10:59:26

标签: haskell latex pandoc mathml

我在Haskell中编写一个Pandoc JSON filter,它应该使用外部应用程序将显示LaTeX数学转换为SVG,而内联LaTeX数学应该在内部由pandoc转换为MathML。

第一个SVG位工作正常;它是MathML位,应该模仿标准pandoc行为,这会给我带来问题。

浏览Hackage,我找到the texMathToMathML code example(见下文)。此函数返回Either String Element

但是,我需要的是一个函数tex2mml(见下文),返回IO String需要在tex2mml的定义中添加哪些内容才能实现此目标?

tex2mml latex = texMathToMathML DisplayInline latex

我在(X)Ubuntu LTS 16.04上安装了以下pandoc 1.16.0.2软件包:

$ sudo apt install pandoc libghc-pandoc-prof

以下是我到目前为止的摘录:

#!/usr/bin/env runhaskell

import Text.Pandoc.JSON
import Control.Applicative ((<$>))
import Text.TeXMath (writeMathML, readTeX, DisplayType( DisplayInline ) )
import Text.XML.Light (Element)


texMathToMathML :: DisplayType -> String -> Either String Element
texMathToMathML dt s = writeMathML dt <$> readTeX s


tex2mml :: String -> IO String
tex2mml latex = texMathToMathML DisplayInline latex


main :: IO ()
main = toJSONFilter tex2math
  where tex2math (Math (DisplayMath) latex) = do
          svg <- tex2svg latex
          return (Math (DisplayMath) (svg))

        tex2math (Math (InlineMath) latex) = do
          mml <- tex2mml latex
          return (Math (InlineMath) (mml))

        tex2math other = return other

请跟我一起,因为我是一个绝对的Haskell初学者。 任何有关代码改进的建议都非常受欢迎!

1 个答案:

答案 0 :(得分:2)

不可否认,我不熟悉Pandoc和问题域,但如果正确理解tex2mml功能的目的,那么我相信这应该达到你想要的目的:

import Control.Applicative ((<$>))
import Text.Pandoc.JSON
import Text.TeXMath
       (writeMathML, readTeX, DisplayType(DisplayInline))
import Text.XML.Light (Element,showElement)

texMathToMathML :: DisplayType -> String -> Either String Element
texMathToMathML dt s = writeMathML dt <$> readTeX s

tex2mml :: String -> String
tex2mml latex = either id showElement (texMathToMathML DisplayInline latex)

-- actual definition of tex2svg goes here
tex2svg = undefined

main :: IO ()
main = toJSONFilter tex2math
  where
    tex2math :: Inline -> IO Inline
    tex2math (Math DisplayMath latex) = do
      svg <- tex2svg latex
      return (Math DisplayMath svg)
    tex2math (Math InlineMath latex) = return (Math InlineMath (tex2mml latex))
    tex2math other = return other

我正在使用either函数仔细检查转换函数texMathToMathML的结果 - 如果失败,错误将按原样返回(id),以防成功{ {1}}函数用于将showElement转换为其XML字符串表示形式。

如果您发现更清楚的话,也可以使用模式匹配重写:

Element

由于计算是纯粹的,因此不需要嵌入IO monad中,结果可以直接传递给tex2mml :: String -> String tex2mml latex = case texMathToMathML DisplayInline latex of Left err -> err Right xml -> showElement xml 构造函数。

如果您希望打印XML字符串或希望在输出中包含XML文档标题,Text.XML.Light.Output模块中还有其他函数。