我目前正在玩 Hakyll 和 Pandoc。
我想从 Markdown 源(包括 LaTeX 中的内联数学)创建一个静态 HTML 网站。使用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
但是,我想使用Hakyllpandoc-katex
中的过滤器并获得与上述命令完全相同的结果(目前),即我想使用 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 的弃用版本。显然,writerStandalone
在早期版本的 Pandoc 中有一个选项,但它不再存在(尽管命令行工具仍然有 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
建议s 应该是文件名,但对于我上下文中的Identifier
某些s(例如对于字段;参见变量),将文件名作为键是没有意义的。我想我误解了这种类型的用途。我应该如何看待这些s?Item
author
authorItem
Item
- 有没有办法获取
Context
命令行工具在进行转换时使用的?默认设置Context
似乎比我的快速草稿复杂得多,例如,它从 Markdown 文件的元数据中读取摘要,并将每个段落放在单独的<p> ... </p>
HTML 标记之间。我知道有一个metadataField :: Context a
,但它似乎不是我想要的。
除了这些具体问题之外,一般问题是:
- 我这样做对吗?或者是否有一种更简单的方法来完成我尝试做的事情(即使用 Hakyll 复制 Haskell 中初始 pandoc shell 命令的输出)?