Pandoc 3:获取并修改 Hakyll 4 中 Markdown 到 HTML 转换的默认上下文?

问题描述 投票:0回答:1

我目前正在与 Hakyll 和 Pandoc 一起玩。

我想从 Markdown 源代码创建一个静态 HTML 网站,包括 LaTeX 中的内联数学。使用 pandoc-katex 我可以使用以下命令进行转换:

$ pandoc -f markdown -t html --filter pandoc-katex --css "https://cdn.jsdelivr.net/npm/katex@$(pandoc-katex --katex-version)/dist/katex.min.css" --css "https://pandoc.org/demo/pandoc.css" --standalone -o output.html input.md

但是,我想在

Hakyll
中使用 pandoc-katex 过滤器并获得与上面命令(目前)相同的结果 exact,即我想使用 Pandoc 的标准 HTML 模板,使其加载两个 CSS文件并以与上述命令相同的方式处理
input.md
中的任何可用元数据是的。 我导出的标准 HTML 模板如下:

$ pandoc -D html > default-template.html

使用 
pandocCompilerWithTransformM

,我能够使用

pandoc-katex
过滤器:
katexCompiler = pandocCompilerWithTransformM defaultHakyllReaderOptions (defaultHakyllWriterOptions) katexFilter
  where katexFilter = recompilingUnsafeCompiler
      . runIOorExplode
      . applyFilters noEngine def [JSONFilter "pandoc-katex"] []

在 Hakyll 中使用这个编译器,我只能得到 HTML 文件的正文部分。我在网上搜索了此问题的解决方案,但我找到的所有信息似乎都涉及已弃用的 Pandoc 版本。显然在早期版本的 Pandoc 中有一个 
writerStandalone

选项,但它

不再存在
(尽管命令行工具 仍然有 opStandalone 并且上面使用的
--standalone
参数显然有效)。
我目前所做的是,我使用 

loadAndApplyTemplate "templates/default-template.html" myCtx

应用默认模板,然后尝试手动复制

myCtx
中的默认上下文。这显然不应该这样做。
这是我尝试的一个最小的例子(抱歉,它仍然有点长 - 这正是问题所在):

{-# LANGUAGE OverloadedStrings #-} import Text.Pandoc import Text.Pandoc.Filter import Text.Pandoc.Scripting import Hakyll css1Item = Item (fromFilePath "css/katex.min.css") "https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css" css2Item = Item (fromFilePath "css/pandoc.css") "https://pandoc.org/demo/pandoc.css" authorItem = Item (fromFilePath "general") "Jon Doe" stylesString = "/* 15 lines of CSS */" myCtx :: Context String myCtx = dateField "date" "%B %e, %Y" <> constField "pagetitle" "My Title" <> constField "styles.html" stylesString <> listCtx "author" [authorItem] <> listCtx "author-meta" [authorItem] <> listCtx "css" [css1Item, css2Item] <> listCtx "header-includes" [] <> listCtx "include-before" [] <> listCtx "include-after" [] <> defaultContext listCtx :: String -> [Item String] -> Context String listCtx name lst = listField name ctx (return $ lst) where ctx = field name (return . itemBody) katexCompiler = pandocCompilerWithTransformM defaultHakyllReaderOptions (defaultHakyllWriterOptions) katexFilter where katexFilter = recompilingUnsafeCompiler . runIOorExplode . applyFilters noEngine def [JSONFilter "pandoc-katex"] [] main :: IO () main = hakyll $ do match "templates/default-template.html" $ compile templateBodyCompiler match "input.md" $ do route $ setExtension ".html" compile $ katexCompiler >>= loadAndApplyTemplate "templates/default-template.html" myCtx

我有两个具体问题:

    Item
  • 数据类型将
    Identifier
    类型的键与值相关联。
    Identifier
    的构造函数建议
    Identifier
    应该是文件名,但对于我上下文中的某些
    Item
    (例如,对于
    author
    字段;请参阅变量
    authorItem
    ),有一个文件名称作为键没有意义。我想我误解了这种类型的目的。我该如何看待这些
    Item
    有没有办法获得命令行工具在进行转换时使用的
  • Context
  • ?默认的
    Context
    似乎比我的快速草稿涉及更多,例如它从 Markdown 文件的元数据中读取摘要,并将每个段落放在单独的
    <p> ... </p>
    HTML 标签之间。我知道有一个
    metadataField :: Context a
    ,但它似乎不是我想要的。
    
    
  • 除了这些具体问题外,一般问题是:

我这样做是否正确,或者是否有一种更简单的方法来完成我尝试做的事情(即使用 Hakyll 在 Haskell 中复制初始 pandoc shell 命令的输出)?
haskell pandoc katex hakyll
1个回答
0
投票
Pandoc 的

writerTemplate

 中使用 WriterOptions
 来传递默认模板,如 
compileDefaultTemplate
:
所示
main :: IO () main = do pandocTmpl <- runIoOrExplode $ compileDefaultTemplate "html" let katexOpts = defaultHakyllWriterOptions { writerTemplate = Just pandocTmpl , writerHTMLMathMethod = KaTeX defaultKaTeXURL -- And whatever else you need. } katexCompiler = pandocCompilerWith defaultHakyllReaderOptions katexOpts hakyll $ do -- etc. match "input.md" $ do route $ setExtension ".html" compile katexCompiler

另请参阅 
pandoc Issue #10209

,它指出了类似的方法。

附带问题:

我应该如何看待这些
Item


Item

确实主要用于绑定到站点树中的文件路径的内容。有时,使用假路径作为标识符是有意义的 - 例如,当使用

create
 规则合成某些内容时。然而,这通常不是人们为了设置上下文字段而想要做的事情,因为可能有更直接的方法来做到这一点。 (特别要注意的是,原则上您不必显式定义源文件的元数据标头中包含的字段,因为 Hakyll 的 
defaultContext
已经通过包含
metadataField
 涵盖了这一点。)

有没有办法获得命令行工具在进行转换时使用的
Context


虽然 Pandoc 提供了操作其自身元数据的方法(我自己从未使用过;

Text.Pandoc.Writers.Shared

 可能是一个开始浏览的好地方),但重要的是要强调 Pandoc 和 Hakyll 的模板系统看起来相似,但是不同,特别是 Hakyll 的 
Context 类型与其 Pandoc 对应类型不同。

最后一点,值得一提的是,如果您完全陷入尝试在 Hakyll 中重现 Pandoc 的输出的情况,最后的选择是使用

unixFilter

 设置一个编译器,该编译器可以运行到命令行潘多克。

© www.soinside.com 2019 - 2024. All rights reserved.