
Pandoc--strip-comments实战彻底清除 Markdown/Textile 源文件中的 HTML 注释【免费下载链接】pandocUniversal markup converter项目地址: https://gitcode.com/gh_mirrors/pa/pandoc导读--strip-comments是 Pandoc 提供的一个布尔型选项用于在读取 Markdown 或 Textile 源文件时剥离其中的 HTML 注释!-- ... --而不是像默认行为那样把它们当作 raw HTML 透传到输出文档中。本文以 test/command/2552.md 中的官方命令测试为骨架完整讲解该选项的语法、默认行为、生效范围、源码实现原理与边界场景并给出可直接复制的实战示例。读完本文你将能够准确判断何时该用--strip-comments以及它在不同输入格式Markdown / CommonMark / HTML / Textile和不同扩展组合下的实际表现。一、命令测试一条最能说明问题的基线用例Pandoc 仓库中的test/command/2552.md是一个典型的 golden test命令测试它描述了一次完整的命令行执行过程及期望输出由测试框架读取后运行并比对结果。其内容如下% pandoc --strip-comments Foo bar !-- comment -- baz!-- bim --boop ^D pFoo/p pbar/p pbazboop/p测试文件的核心信息命令行仅带--strip-comments不指定输入输出格式因此按 Pandoc 惯例自动选择 markdown 输入、HTML 输出输入文本包含三种注释形态独立成段的块级注释!-- comment --内联注释!-- bim --它把一行文本baz!-- bim --boop从中间切开期望输出中注释被完全删除块级注释连同其所在段落一起消失bar前后两个段落仍然各自独立内联注释被移除后baz与boop合并成同一个段落pbazboop/p中间没有残留空格或其他字符。注意baz!-- bim --boop的合并行为注释被剥离后两段文本直接拼接为bazboop这与注释相当于占位文本、替换为空字符串的实现一致。仓库中另有一个用例 test/command/7521.md 验证了列表场景% pandoc --strip-comments - one !-- with comm -- - two ^D ul lione/li litwo/li /ul它说明位于列表项之间的块级注释同样会被剥除且不会在li之间留下空项输出列表保持干净。二、选项语法与默认行为2.1 命令行写法--strip-comments是一个带可选布尔参数的选项完整的语法为--strip-comments[true|false]直接写--strip-comments等价于--strip-commentstrue显式传false可关闭--strip-commentsfalse若想覆盖配置文件中的设置可传入--strip-commentstrue显式开启。2.2 官方手册中的权威定义MANUAL.txtPandoc 官方手册对该选项的定义如下Strip out HTML comments in the Markdown or Textile source, rather than passing them on to Markdown, Textile or HTML output as raw HTML. This does not apply to HTML comments inside raw HTML blocks when themarkdown_in_html_blocksextension is not set.翻译并拆解为三点关键约束适用输入格式Markdown 或 Textile 源文件默认行为不开启时HTML 注释会被当作 raw HTML 原样透传到 Markdown、Textile 或 HTML 输出中边界条件当markdown_in_html_blocks扩展未启用时位于raw HTML 块内部的 HTML 注释不受本选项影响。2.3 默认值与配置映射在 Pandoc 的读取器选项中readerStripComments的默认值为False见 src/Text/Pandoc/Options.hs 与 src/Text/Pandoc/Options.hs即默认保留注释。该选项同样暴露在 YAML 元数据与 Lua 读取器参数中YAML 前端数据standalone模式字段名为strip-comments见 MANUAL.txt 的选项—变量对照表Lua APIReaderOptions.strip_comments见 pandoc-lua-engine/src/Text/Pandoc/Lua/Marshal/ReaderOptions.hs。也就是说在文档头部写入strip-comments: true或在 Lua 过滤器里修改读取器选项可以达到与命令行相同的目的。三、命令行参数解析源码命令行选项在 src/Text/Pandoc/App/CommandLineOptions.hs 中定义, option [strip-comments] (OptArg (\arg opt - do boolValue - readBoolFromOptArg --strip-comments arg return opt { optStripComments boolValue }) true|false) OptFlag (T.pack Strip HTML comments)实现要点使用OptArg声明参数为可选参数类型参数取值true|false这正是带参数可写可不写语法--strip-comments[true|false]的来源通过readBoolFromOptArg解析布尔值未提供参数时视为true解析结果存入optStripComments字段src/Text/Pandoc/App/Opt.hs随后在组装ReaderOptions时映射为readerStripComments。因此从源码可以确认这是一个纯粹的读取端reader选项只影响输入解析阶段与输出格式无关。四、源码级实现注释在哪里、如何被剥除readerStripComments的消费点主要有两处分别对应 Markdown/CommonMark 读取器和 HTML 读取器。4.1 CommonMark/Markdown 读取器解析后遍历剥离在 src/Text/Pandoc/Readers/CommonMark.hs 中readCommonMarkBody在解析完成后对 AST 做一次遍历(if readerStripComments opts then walk stripBlockComments . walk stripInlineComments else id) $对应的剥离函数src/Text/Pandoc/Readers/CommonMark.hsstripBlockComments :: Block - Block stripBlockComments (RawBlock (B.Format html) s) RawBlock (B.Format html) (removeComments s) stripBlockComments x x stripInlineComments :: Inline - Inline stripInlineComments (RawInline (B.Format html) s) RawInline (B.Format html) (removeComments s) stripInlineComments x x原理拆解Markdown 解析器本身会把 HTML 注释识别为RawBlock (Format html)块级或RawInline (Format html)行内AST 节点开启选项后解析完成后用walk遍历整棵 AST只对这两类 raw HTML 节点调用removeCommentsremoveCommentssrc/Text/Pandoc/Readers/CommonMark.hs使用 Attoparsec 解析并删除其中的!-- ... --片段解析失败则原样返回剥离后的空字符串节点在后续写出阶段自然消失。这解释了 2552 测试中的行为baz!-- bim --boop中的注释被解析为 raw inline HTML剥除后剩bazboop!-- comment --被解析为 raw block剥除后该块为空bar两侧的段落边界保持不变。4.2 HTML 读取器解析期就地替换在 src/Text/Pandoc/Readers/HTML.hs 中HTML 读取器在词法扫描阶段处理TagCommentTagComment s | !-- T.isPrefixOf inp - do string !-- count (T.length s) anyChar string -- stripComments - getOption readerStripComments if stripComments then return (next, ) else return (next, !-- s --)也就是说HTML 读取器在识别注释 token 的当下即决定保留还是替换为空字符串属于解析期就地处理与 CommonMark 读取器的解析后遍历是两条不同实现路径但对外行为一致。五、可复制的实战示例5.1 独立段落注释对应 2552 测试printf Foo\n\nbar\n\n!-- comment --\n\nbaz\n | pandoc --strip-comments输出pFoo/p pbar/p pbaz/p5.2 行内注释合并文本printf baz!-- bim --boop\n | pandoc --strip-comments输出pbazboop/p5.3 列表项之间的注释printf -- - one\n !-- with comm --\n- two\n | pandoc --strip-comments输出ul lione/li litwo/li /ul5.4 对比不开启选项时注释被透传printf baz!-- bim --boop\n | pandoc输出Markdown 读取器将注释作为 raw HTML 透传pbaz!-- bim --boop/p这正是--strip-comments要改变的默认行为。需要说明的是HTML 读取器在解析 HTML 输入时同样受该选项控制开启后在 token 解析期直接丢弃注释而不开启时注释会保留在输出中。5.5 通过 YAML 元数据开启在standalone文档头部写入字段名与命令行对应见 MANUAL.txt 的对照表--- strip-comments: true ---六、边界与注意事项markdown_in_html_blocks扩展当该扩展未启用、且注释位于 raw HTML 块内部时--strip-comments不生效见 MANUAL.txt 的说明。这是官方文档明确划出的边界涉及多格式组合时应特别留意。仅影响读取端选项写入ReaderOptionsreaderStripComments默认False见 src/Text/Pandoc/Options.hs因此无论输出为 HTML、LaTeX 还是其他格式只要输入是受支持的格式剥除行为都发生在解析阶段。只针对 HTML 注释该选项只处理!-- ... --形式的 HTML 注释不影响 Lua 注释、其他语言的注释语法也不涉及按行注释剥离。多格式输入差异Markdown/CommonMark 走AST 遍历剥离HTML 走token 解析期替换二者实现位置不同分别为 src/Text/Pandoc/Readers/CommonMark.hs 与 src/Text/Pandoc/Readers/HTML.hs但对外行为一致。验证手段仓库中 test/command/2552.md 与 test/command/7521.md 是官方回归测试修改相关代码后运行这些测试即可验证行为是否被破坏。七、小结--strip-comments是一个实现简洁、边界清晰的读取端选项它通过修改ReaderOptions.readerStripComments在 Markdown/CommonMark 读取器中以 AST 遍历的方式、在 HTML 读取器中以 token 替换的方式将!-- ... --注释安全地剥离避免其以 raw HTML 形式泄漏到最终文档。无论是清理导出文档中的敏感批注、去除模板注释还是在批量转换流程中统一净化源文件都可以把pandoc --strip-comments作为标准前置处理步骤。【免费下载链接】pandocUniversal markup converter项目地址: https://gitcode.com/gh_mirrors/pa/pandoc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考