1 {section .foo .unnumbered key=“val“}
2026/9/21 15:23:47 网站建设 项目流程
  • 文档
  • 开发工具
  • CLI

【免费下载链接】pandoc

Universal markup converter

项目地址:https://gitcode.com/gh_mirrors/pa/pandoc
点击查看免费下载
pandoc 的 Markdown 读者会将其解析为完全相同的 `Attr`(解析逻辑位于 [src/Text/Pandoc/Readers/Markdown.hs](https://link.gitcode.com/i/108f370d091799d57a5ebf4e1a06b1b5) 的 `attribute` 解析器族,见下文第六节)。 ## 四、输出侧剖析:HTML5 中 Attr 的映射规则 ### 4.1 期望输出 ```html <h1 class="foo unnumbered">attrsToHtml opts (id',classes',keyvals) = do attrs <- toAttrs keyvals let classes'' = nubOrd $ filter (not . T.null) classes' return $ [prefixedId opts id' | not (T.null id')] ++ [A.class_ (toValue $ T.unwords classes'') | not (null classes'')] ++ attrs
  • prefixedId opts id'负责生成id(支持--id-prefix等选项注入前缀);
  • T.unwords classes''把类列表拼成空格分隔的class字符串,nubOrdfilter保证去重、去空;
  • 键值对由toAttrs处理。

toAttrs(src/Text/Pandoc/Writers/HTML.hs)是data-前缀规则的核心:当输出为 HTML5 时,若键属于html5Attributes/rdfaAttributes白名单、包含:命名空间(如epub:)、以data-aria-开头,则原样输出;否则自动改写为data-<key>"key"不在白名单中,因此key="val"最终呈现为data-key="val",与本测试的期望输出完全一致。

4.3 非 HTML5 输出的差异(推断)

toAttrs的代码分支可以推断:在非 HTML5 模式(如 HTML4)下,属性映射策略不同——未知键不会自动添加data-前缀,而是按白名单过滤;若同时面向 EPUB2 输出,不符合白名单的属性甚至会被直接丢弃。因此本测试的结果严格依赖-t html默认的 HTML5 输出模式。

五、unnumbered类的特殊语义:抑制节编号

["foo","unnumbered"]中的unnumbered并非普通样式类,它是 pandoc 内部识别的保留类,作用是标记"该标题不参与节编号(section numbering)"。

5.1 编号生成阶段的抑制

在 src/Text/Pandoc/Shared.hs 的makeSections(开启--number-sections时用于计算各级编号并包装<section>结构)中:

unless (null newnum || "unnumbered" `elem` classes) $ S.put newnum ... case lookup "number" kvs of Nothing | numbering , "unnumbered" `notElem` classes -> ("number", T.intercalate "." (map tshow newnum)) : kvs _ -> kvs

即:标题类列表中若存在unnumbered,则既不推进当前节编号计数器,也不注入number键值对

5.2 HTML 写出的编号抑制

在 src/Text/Pandoc/Writers/HTML.hs 的Header分支中:

let secnum = fromMaybe mempty $ lookup "number" kvs let contents' = if writerNumberSections opts && not (T.null secnum) && "unnumbered" `notElem` classes then (H.span ! A.class_ "header-section-number" $ toHtml secnum) >> toHtml ' ' >> contents else contents

即使开启了--number-sections,只要标题带unnumbered类,就不会渲染<span class="header-section-number">…</span>编号前缀。本例未开启编号选项,因此直接输出纯文本1,测试结果不受编号逻辑影响,但unnumbered类的存在恰好覆盖了"编号场景下须被忽略"的关键路径。

六、从 Markdown 语法到unnumbered:属性的来源

unnumbered类最常见的来源是 Markdown 标题的属性语法。在 src/Text/Pandoc/Readers/Markdown.hs 中,specialAttr解析器专门处理以-开头的特殊属性:

specialAttr = do char '-' return $ \(id',cs,kvs) -> (id',cs ++ ["unnumbered"],kvs)

因此以下写法是等价的:

# 前言 {.unnumbered} # 前言 {-#}

{-#}{.unnumbered}的简写,二者都会被解析为在类列表尾部追加"unnumbered"。用户可在 MANUAL.txt 的扩展说明中找到更多上下文;如需查看其与原生 AST 的对应关系,可运行:

pandoc -f markdown -t native

随后输入# 前言 {-#}并按^D,观察输出中 Header 的类列表是否出现"unnumbered"。这正是 6062 测试所用的"手工构造 native 输入"思路的交互式版本。

七、如何运行与扩展该测试

7.1 本地复现

在源码根目录构建后,可直接手动执行测试中的命令以观察实际输出:

printf '[Header 1 ("section",["foo","unnumbered"],[("key","val")]) [Str "1"]]\n' | pandoc -f native -t html

输出应与测试期望完全一致:

<h1 class="foo unnumbered">cabal test pandoc --test-options='-p command'
  • 文档
  • 开发工具
  • CLI

【免费下载链接】pandoc

Universal markup converter

项目地址:https://gitcode.com/gh_mirrors/pa/pandoc
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询