pandoc在haskell中包含文件过滤器

时间:2014-02-05 17:36:26

标签: haskell pandoc

我正在使用这个haskell pandoc包含文件过滤器

#!/usr/bin/env runhaskell
-- includes.hs
import Text.Pandoc.JSON

doInclude :: Block -> IO Block
doInclude cb@(CodeBlock (id, classes, namevals) contents) =
  case lookup "include" namevals of
       Just f     -> return . (CodeBlock (id, classes, namevals)) =<< readFile f
       Nothing    -> return cb
doInclude x = return x

main :: IO ()
main = toJSONFilter doInclude

在markdown中使用以下代码段

~~~~ {include="tasks/mdbook.js"}
~~~~

这实际上包含了文件到markdown但是我希望它也包含代码格式,例如

```js
file content here
```

如何更新上面的haskell代码来实现这个?像

这样的东西
~~~~ {code="tasks/mdbook.js", format="js"}
~~~~

3 个答案:

答案 0 :(得分:2)

由于include过滤器会保留所有classes代码块,因此您可以使用以下内容包含文件内容并应用代码格式:

~~~~ {.javascript include="tasks/mdbook.js"}
~~~~

答案 1 :(得分:1)

我假设你要解决的问题是有一个降价文档引用某段代码而你想避免将代码复制粘贴到文档中并且有一个同步的噩梦手工制作两个版本。所以你试图通过过滤器将源文件包含在降价文档中来解决问题。

我以不同的方式解决了同样的问题。我将所有(相关的)源代码保存在markdown文档中,并编写了一个提取所有源代码的工具。我的特殊用例是我正在为讲座编写幻灯片,每次编辑幻灯片时我都会提取代码并确保编译。为了方便学生,我还将所有代码捆绑到一个zip存档中。

我的工具可在此处找到: https://github.com/josefs/CodeExtract

您可以编写如下代码块:

~~~ {.haskell file="Hello.hs"}
main = putStrLn "Hello World!"
~~~

当通过我的小工具运行包含此类代码块的文档时,它将生成一个包含块中代码的文件Hello.hs

还有一个更高级的功能,支持几个代码片段,最终可以在同一个文档中。例如,您可以有两个这样的代码块:

~~~ {.haskell template="Hello.hs.tmpl" var="mainfkn"}
main = putStrLn str
~~~

~~~ {.haskell template="Hello.hs.tmpl" var="misc"}
str = "Hello World!"
~~~

然后是一个模板文件Hello.hs.tmpl,如下所示(它使用与pandoc相同的模板格式):

~~~
module Main where
$mainfkn$
$misc$
~~~

它将生成一个包含模板文件的文件Hello.hs,但变量将替换为markdown文件中的相应代码块。它非常方便。

我希望您发现我的工具很有用,但我发现它可能无法解决您的特定问题。

答案 2 :(得分:1)

您似乎想要的是更新代码块的属性。以下是您可以做的事情:

#!/usr/bin/env runhaskell
-- includes.hs
import Text.Pandoc.JSON

doInclude :: Block -> IO Block
doInclude cb@(CodeBlock (id, classes, namevals) contents) =
  case lookup "include" namevals of
       Just f     -> do
         let newAttrs = filter ((/= "include") . fst) namevals ++ [("code",f), ("format","js")]
         return . (CodeBlock (id, classes, newAttrs)) =<< readFile f
       Nothing    -> return cb
doInclude x = return x

main :: IO ()
main = toJSONFilter doInclude

根据需要更改newAttr的代码。