如何在Hakyll中使用Pandoc过滤器?

时间:2015-04-25 16:57:49

标签: haskell filter pandoc hakyll

很抱歉提出这样的问题。但我对Haskell真的很新。我在互联网上搜索了一整天,但没有找到任何例子。

我有一个用python(tikzcd.py)编写的pandoc过滤器。我想使用该过滤器来处理我的博客帖子。

我想我需要使用unixFilterpandocCompileWithTransform,但我对Haskell的了解实际上还不足以找到解决方案。

那么,有人可以给我一个例子吗?

-----------û - P - d - 甲 - T - ë - S ---------------

@Michael使用pandocCompileWithTransformMunixFilter提供解决方案。有用。但是有一个问题。

从命令行使用过滤器时,我要做的是

pandoc -t json -READEROPTIONS input.markdown | ./filter.py | pandoc -f JSON -WRITEROPTIONS -o output.html
  

或等效

pandoc --filter ./filter.py -READEROPTIONS -WRITEROPTIONS -o html
     

此命令较短但不显示过程。

但是对于pandocCompilerTransformM,它会执行类似

的操作
pandoc -t html -READEROPTIONS -WRITEROPTIONS input.mardown | pandoc -t JSON | ./filter.py | pandoc -f JSON -WRITEROPTIONS -o output.html

区别在于传递给filter.py的文本是不同的:一个是从markdown直接生成的内容,另一个是从markdown生成的HTML文本。如你所知,来回转换东西总会产生意想不到的问题。所以我认为可能有更好的解决方案。

PS。我盯着学习Haskell。我希望有一天我能自己解决这个问题。谢谢!

1 个答案:

答案 0 :(得分:4)

最后我想你会同时使用两者。使用此https://github.com/listx/listx_blog/blob/master/blog.hs作为模型,以下内容与transformer has in it具有相同的形状。 transformer上使用pandocCompilerWithTransformM - 这是(Pandoc -> Compiler Pandoc)的第三个参数,即defaultHakyllReaderOptions这里你需要添加python过滤器的绝对路径 - - 或者名称,如果它在$ PATH中 - 以及读者和作者选项(例如defaultHakyllWriterOptionsimport Text.Pandoc import Hakyll type Script = String transformer :: Script -- e.g. "/absolute/path/filter.py" -> ReaderOptions -- e.g. defaultHakyllReaderOptions -> WriterOptions -- e.g. defaultHakyllWriterOptions -> (Pandoc -> Compiler Pandoc) transformer script reader_opts writer_opts pandoc = do let input_json = writeJSON writer_opts pandoc output_json <- unixFilter script [] input_json return $ -- either (error.show) id $ -- this line needs to be uncommented atm. readJSON reader_opts output_json

(transformer "/usr/local/bin/myfilter.py" defaultHakyllReaderOptions defaultHakyllWriterOptions)

类似地,在lines 69-80 for 'posts'

的第125行使用(return . pandocTransform)时可能会使用unixFilter

对于调试,您可能会将所有内容外包给transform :: Script -> String -> Compiler String transform script md = do json0 <- unixFilter pandoc input_args md json1 <- unixFilter script [] json0 unixFilter pandoc output_args json1 where pandoc = "pandoc" input_args = words "-f markdown -t json" -- add others output_args = words "-f json -t html" -- add others

do

pandoc -t json | filter.py | pandoc -f json块的三行等同于pandocCompilerWithTransform(M)中unix管道的各个阶段,以及其他任何参数。

我想也许你是对的,这里有一层额外的pandoc来回。 unixCompile函数用于直接Pandoc-&gt; Pandoc功能 - 它将被应用到Pandoc hakyll中。我认为我们应该免除这一点并直接使用Pandoc库。使用transformXLVI :: Script -> ReaderOptions -> WriterOptions -> String -> Compiler Html transformXLVI script ropts wopts = fmap fromJSON . unixFilter script [] . toJSON where toJSON = writeJSON wopts -- . either (error . show) id -- for pandoc > 1.14 . readMarkdown ropts fromJSON = writeHtml wopts -- . either (error . show) id . readJSON ropts 可能是这样的。

transform

我希望这些变化能够摆脱这些原则!这应该与前面的pandoc几乎相同;我们使用pandoc库代替对Option Strict On Option Explicit On Option Infer Off Imports System.Net.Mail Public Class Form1 Function SendEmail(ByVal Recipients As List(Of String), _ ByVal FromAddress As String, _ ByVal Subject As String, _ ByVal Body As String, _ ByVal UserName As String, _ ByVal Password As String, _ Optional ByVal Server As String = "smtp.gmail.com", _ Optional ByVal Port As Integer = 587, _ Optional ByVal Attachments As List(Of String) = Nothing) As String Dim Email As New MailMessage() Try Dim SMTPServer As New SmtpClient For Each Attachment As String In Attachments Email.Attachments.Add(New Attachment(Attachment)) Next Email.From = New MailAddress(FromAddress) For Each Recipient As String In Recipients Email.To.Add(Recipient) Next Email.Subject = Subject Email.Body = Body '---------------------------------- Email.Priority = MailPriority.High '---------------------------------- SMTPServer.Host = Server SMTPServer.Port = Port SMTPServer.Credentials = New System.Net.NetworkCredential(UserName, Password) SMTPServer.EnableSsl = True SMTPServer.Send(Email) Email.Dispose() Return "Email to " & Recipients(0) & " from " & FromAddress & " was sent." Catch ex As SmtpException Email.Dispose() Return "Sending Email Failed. Smtp Error." Catch ex As ArgumentOutOfRangeException Email.Dispose() Return "Sending Email Failed. Check Port Number." Catch Ex As InvalidOperationException Email.Dispose() Return "Sending Email Failed. Check Port Number." End Try End Function Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim Recipients As New List(Of String) Recipients.Add("SomeEmailAddress") Dim FromEmailAddress As String = Recipients(0) Dim Subject As String = "Test From VB." Dim Body As String = "email body text, if you are reading this from your gmail account, the program worked." Dim UserName As String = "GMAIL USERNAME WITHOUT (@GMAIL>COM)" Dim Password As String = "Password" Dim Port As Integer = 587 Dim Server As String = "smtp.gmail.com" Dim Attachments As New List(Of String) MsgBox(SendEmail(Recipients, FromEmailAddress, Subject, Body, UserName, Password, Server, Port, Attachments)) End Sub End Class 可执行文件的调用。