【问题标题】:Pandoc filter mimicking default MathML conversionPandoc 过滤器模仿默认的 MathML 转换
【发布时间】:2016-12-13 10:59:26
【问题描述】:

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

第一个 SVG 位工作正常;应该模仿标准 pandoc 行为的 MathML 位给我带来了问题。

浏览 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 初学者。 非常欢迎任何有关代码改进的建议!

【问题讨论】:

  • “正是 MathML 位应该模仿标准 pandoc 行为,这给我带来了问题。” --> 为什么不让它保持原样,在你的过滤器运行后让 Pandoc 处理它?
  • @SergioCorreia 因为,我使用 --jsmath 而不是 --mathml 运行 pandoc 以使用 MathJax 生成 SVG。
  • @SergioCorreia 我仔细检查了一遍。事实上,pandoc 在暴露其ToJSONFilter 之前 执行其math conversion。据我所知,以下解决方案是到达那里的唯一方法。
  • 编辑: 一个全新的、更现代的 Lua 过滤器解决方案可以解决这个问题,HERE

标签: haskell latex pandoc mathml


【解决方案1】:

诚然,我不熟悉 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),如果成功则使用showElement 函数将Element 转换为其 XML 字符串表示形式。

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

tex2mml :: String -> String
tex2mml latex = case texMathToMathML DisplayInline latex of
  Left err -> err
  Right xml -> showElement xml

由于计算是纯的,因此不需要嵌入 IO monad,结果可以直接传递给Math 构造函数。

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

【讨论】:

  • 精妙的答案,很好的解释!我从中学到了很多。
猜你喜欢
  • 2013-02-02
  • 2021-03-19
  • 2019-10-16
  • 2011-01-19
  • 2012-05-05
  • 2012-10-15
  • 2012-05-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多