2014-02-05 48 views
4

我用这哈斯克尔pandoc包括文件过滤pandoc包含在Haskell文件过滤器

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

doInclude :: Block -> IO Block 
doInclude [email protected](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 

用下面的代码片段在降价

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

但这实际上包含文件到降价然而,我想它也包括代码格式,例如

```js 
file content here 
``` 

我该怎么做约会上面的haskell代码来实现这个?喜欢的东西

~~~~ {code="tasks/mdbook.js", format="js"} 
~~~~ 

回答

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包含模板文件,但变量被替换为降格文件中的相应代码块。这非常方便。

我希望你找到我的工具有用,但我意识到它可能无法解决你的特定问题。

+0

嗨svenningsson,感谢,但我需要它去其他方式。我不想让源代码保存在markdown文件中,因为我会失去所有IDE功能。有没有办法在haskell的IO块的开头添加字符? –

+0

够公平的。看到我的新答案。 – svenningsson

1

你似乎想要更新代码块的属性。这里是你可以做什么:

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

doInclude :: Block -> IO Block 
doInclude [email protected](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的代码,你认为合适。

+0

这似乎没有编译。此代码是否会更新代码块?它看起来会添加代码,并将值格式化为属性数组,这不是我想要实现的。在.md文件中,我想指定代码,格式并让过滤器在返回的代码块的开头添加必要的字符,如'''js('此处的读取代码')''' –

+0

第一个错误是词法错误在字符'/ n'字符串/字符文字我认为这是由于缺少“之后”包括修复后,它现在不会编译与输入下面的错误分析错误'返回' –

+0

我不想让它对你来说太简单了:-)我已经更新了代码,以便它检测。所做的改变是:“你注意到了”的缺失,然后是'Just f - >'模式下的'do' 我还没有测试过代码 – svenningsson

2

由于include过滤器可保留代码块的所有classes,您可以包括文件内容和应用代码格式化它只是这一点:为响应

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