2014-02-05 46 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"} 
~~~~