设置Ext_yaml_metadata_block后,Pandoc Haskell代码为何不输出YAML元数据块?
问题
我尝试用Markdown写入器还原读取的Markdown文件,测试发现命令行指令pandoc -s -t markdown input.md -o output.md可以生成带有YAML头的文件。查看源码后得知需要启用Ext_yaml_metadata_block扩展,但在我的Haskell代码中,尽管读写环节都设置了该扩展,写入器却只输出内容,不生成YAML头。请问还需要额外配置什么,或者代码中存在哪些问题?
最小示例代码
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} module MarkdownYAMLquestion where import qualified Text.Pandoc as Pandoc import Text.Pandoc.Definition as Pandoc(Pandoc(..)) import Uniform.PandocImports(unPandocM) import UniformBase(s2t,putIOwords, runErr, ErrIO, Text, showT) smallMD :: Text smallMD = s2t $ unlines ["---" , "keywords: somewords" , "showframe: False" , "---" , "" , "some content text" ] testyaml :: IO () -- a minimal example testyaml = do res <- runErr $ do pan1 <- readMarkdown3 smallMD putIOwords ["the pandoc", showT pan1] -- the YAML header is parsed! mdRes <- writeToMarkdown3 pan1 putIOwords ["\n\nthe file reproduced\n", mdRes] putIOwords ["testyaml end res", showT res] writeToMarkdown3 :: Pandoc -> ErrIO Text -- write with yaml header writeToMarkdown3 pan1= unPandocM $ Pandoc.writeMarkdown markdownWriterOptionsx pan1 markdownWriterOptionsx :: Pandoc.WriterOptions markdownWriterOptionsx = Pandoc.def {Pandoc.writerExtensions = exts} where exts = mconcat [ Pandoc.extensionsFromList [Pandoc.Ext_yaml_metadata_block] ] readMarkdown3 :: Text -> ErrIO Pandoc -- | reads the markdown text and produces a pandoc structure -- the filename is only used for the error message readMarkdown3 text1 = unPandocM $ Pandoc.readMarkdown markdownOptions text1 markdownOptions :: Pandoc.ReaderOptions markdownOptions = Pandoc.def { Pandoc.readerExtensions = exts } where exts = mconcat [ Pandoc.extensionsFromList [ Pandoc.Ext_yaml_metadata_block -- , Pandoc.Ext_fenced_code-block -- code blocks with ~ , Pandoc.Ext_backtick_code_blocks , Pandoc.Ext_fenced_code_attributes -- eg for haskell code snippets , Pandoc.Ext_auto_identifiers -- , Pandoc.Ext_raw_html -- three extension give markdown_strict , Pandoc.Ext_raw_tex --Allow raw TeX (other than math) , Pandoc.Ext_latex_macros -- allow tex for math , Pandoc.Ext_tex_math_dollars , Pandoc.Ext_shortcut_reference_links , Pandoc.Ext_spaced_reference_links , Pandoc.Ext_footnotes -- all footnotes , Pandoc.Ext_inline_notes , Pandoc.Ext_citations -- <-- this is the important extension for bibTex , Pandoc.Ext_implicit_figures -- a figure alone in a para will have a caption , Pandoc.Ext_header_attributes -- for {.unnumbered} , Pandoc.Ext_lists_without_preceding_blankline , Pandoc.Ext_superscript -- start and closing ^ , Pandoc.Ext_subscript -- start and closing ~ -- , Pandoc.Ext_short_subsuperscripts -- only start ^ and ~ , Pandoc.Ext_strikeout -- require ~~ two! before and after , Pandoc.Ext_smart -- Smart quotes, apostrophes, ellipses, dashes ] , Pandoc.githubMarkdownExtensions ]
解答
你的代码有两个关键问题导致YAML头无法输出:
- Writer扩展集合被错误替换:你直接用
Ext_yaml_metadata_block覆盖了默认的Markdown扩展集合,丢失了很多必要的基础扩展。正确的做法是在默认扩展基础上启用目标扩展,而不是完全替换。 - 未开启独立文档模式:命令行里的
-s参数对应Haskell API中的writerStandalone选项,只有开启这个选项,pandoc才会将元数据以YAML块的形式输出。
修改后的markdownWriterOptionsx应该如下:
markdownWriterOptionsx :: Pandoc.WriterOptions markdownWriterOptionsx = Pandoc.def { Pandoc.writerExtensions = Pandoc.enableExtension Pandoc.Ext_yaml_metadata_block Pandoc.def , Pandoc.writerStandalone = True }
另外,读取端的扩展集合同时混合了手动添加的扩展和githubMarkdownExtensions,可能存在潜在冲突,建议保持扩展集合的一致性,但这不是YAML头不输出的直接原因。
内容的提问来源于stack exchange,提问作者user855443
相关产品推荐
相关产品推荐

