Pandoc 隐式图片(implicit figure)与列表内图片解析:从 command 测试 5368 解读 native 输出结构
文档开发工具CLI【免费下载链接】pandocUniversal markup converter项目地址https://gitcode.com/gh_mirrors/pa/pandoc点击查看免费下载导读本篇以 pandoc 仓库中的命令行回归测试 test/command/5368.md 为切入点完整解析 Markdown 输入中有序列表内的图片段落如何被读取为 Pandoc 内部Figure块并通过-t native输出为可读的 AST 文本。读完本文你将掌握implicit_figures扩展的触发条件、Figure/Caption/Image三类节点的字段结构、列表嵌套块的解析行为以及如何在本仓库中运行该测试验证结果。一、测试用例 5368 是什么test/command/目录存放 pandoc 的命令行回归测试每个.md文件的第一行是一个 pandoc 命令随后是标准输入以^D结束再之后是期望的标准输出。测试由 test/Tests/Command.hs 统一驱动执行。test/command/5368.md 的内容极为精炼它验证的是有序列表中的图片段落这一输入形态。% pandoc -t native 1. foo bar 2. foo2 bar2 3. foo3 foo3 Quux. ^D输入是一个三项有序列表1./2./3.分隔符为句点Decimal/Period每个列表项都包含两段内容一段普通文本foo、foo2、foo3以及一段缩进 4 空格的独立图片段落bar等。列表结束后还有一个普通段落Quux.。这个测试回归的场景是列表项内部、以缩进块形式出现的图片必须被识别为带标题的Figure而不是普通的Image段落。这正是 pandoc 隐式图片implicit figures机制在嵌套块语境下的表现。二、期望输出native 格式下的完整 AST测试期望输出即pandoc -t native的真实结果如下[ OrderedList ( 1 , Decimal , Period ) [ [ Para [ Str foo ] , Figure ( , [] , [] ) (Caption Nothing [ Plain [ Str bar ] ]) [ Plain [ Image ( , [] , [] ) [ Str bar ] ( bar.png , ) ] ] ] , [ Para [ Str foo2 ] , Figure ( , [] , [] ) (Caption Nothing [ Plain [ Str bar2 ] ]) [ Plain [ Image ( , [] , [] ) [ Str bar2 ] ( bar2.png , ) ] ] ] , [ Para [ Str foo3 ] , Figure ( , [] , [] ) (Caption Nothing [ Plain [ Str foo3 ] ]) [ Plain [ Image ( , [] , [] ) [ Str foo3 ] ( foo3.png , ) ] ] ] ] , Para [ Str Quux. ] ]逐层拆解这段 AST可以看到几个关键结构顶层是一个[Block]列表包含一个OrderedList块和一个Para块。OrderedList的元组( 1 , Decimal , Period )依次表示起始编号1、编号样式Decimal十进制数字、编号分隔符Period句点对应源码中ListAttributes的三个字段。每个列表项本身又是一个[Block]列表这里恰为两项Para [Str foo]与Figure ...。列表项内的两个块是并列兄弟关系图片块是列表项内容的一部分而不是脱离列表的顶层块。图片被表示为Figure块其三个参数分别是属性( , [] , [] )空标识符、空 class 列表、空键值对标题(Caption Nothing [ Plain [ Str bar ] ])Caption的第一个参数是可选短标题Nothing表示无第二个参数是长标题块列表图体[ Plain [ Image ... ] ]一个Plain段落包裹着对应的Image内联元素。Image ( , [] , [] ) [ Str bar ] ( bar.png , )的三个参数为属性、替代文本alt text内联列表、以及(URL, title)二元组。这里 title 为空字符串。需要注意图体中的Image替代文本[Str bar]与标题内容一致——这正是implicit_figures机制的结果图片的 alt 文本被同时用作Figure的标题。三、源码级原理implicit_figures扩展如何把图片段落变成 Figurenative 输出中Figure块并非凭空产生它源自 Markdown 读取器在解析段落时的隐式图形判定。相关实现位于 src/Text/Pandoc/Readers/Markdown.hs 的para与implicitFigure函数。para解析函数的核心逻辑约 L1055-L1062是先解析一段内联内容然后检查该段落是否恰好由一个Image内联元素构成let figureOr constr inlns case B.toList inlns of [Image attr figCaption (src, tit)] | extensionEnabled Ext_implicit_figures exts , not (null figCaption) - do implicitFigure attr (B.fromList figCaption) src tit _ - constr inlns从这段代码可以确认隐式图形的两个必要条件扩展启用必须启用implicit_figures扩展源码中的Ext_implicit_figures。这是 Markdown 变体markdown、gfm、commonmark等的默认行为之一如果通过-f markdown-implicit_figures显式关闭则图片段落会退化为普通段落。段落恰好只有一个图片且 alt 文本非空figCaption即图片的替代文本not (null figCaption)保证空 alt 的图片不会变成图。满足条件后调用implicitFigureMarkdown.hs L1093-L1106它完成Figure的组装implicitFigure :: Attr - Inlines - Text - Text - Blocks implicitFigure (ident, classes, attribs) capt url title let alt case alt lookup attribs of Just alt - B.text alt _ - capt attribs filter ((/ latex-placement) . fst) (filter ((/ alt) . fst) attribs) figattribs case lookup latex-placement attribs of Just p - [(latex-placement, p)] _ - mempty figattr (ident, mempty, figattribs) caption B.simpleCaption $ B.plain capt figbody B.plain $ B.imageWith (, classes, attribs) url title alt in B.figureWith figattr caption figbodyimplicitFigure的行为细节与测试 5368 的输出一一对应caption B.simpleCaption $ B.plain capt标题由 alt 文本构成simpleCaption构造Caption Nothing [...]无短标题所以 native 中显示为Caption Nothing [ Plain [ Str bar ] ]。figbody B.plain $ B.imageWith ... alt图体是把图片包进Plain段落替代文本用 alt 属性或标题兜底。figattr (ident, mempty, figattribs)Figure 自身属性只保留标识符和latex-placement键值对原 class 列表移到图内Image上故输出中Figure ( , [] , [] )与Image ( , [] , [] )均为空属性。而列表项中的图片段落之所以也能命中此逻辑是因为para同样用于解析列表项内的缩进块——在列表上下文中缩进的图片段落依然走段落解析最终被识别为Figure与列表外的独立图片行为一致。测试 5368 正是用三个列表项验证了这条路径的稳定性。四、Figure块在 native 写出端的呈现pandoc -t native本身就是一个写出器writer它将内部 AST 渲染为 Haskell 风格的文本表示。Figure块的序列化逻辑位于 src/Text/Pandoc/Writers/Native.hs#L185Figure attr cap bs - con Figure [attrV attr, captionV cap, blocksV bs]对应地Caption的序列化在同文件 L188-L190captionV :: Caption - V captionV (Caption mshort bs) con Caption [maybeV inlinesV mshort, blocksV bs]这正是测试输出中Figure ( , [] , [] ) (Caption Nothing [ Plain [ Str bar ] ]) [ Plain [ Image ... ] ]的来源attrV渲染属性三元组captionV渲染Caption Nothing [Plain [...]]maybeV负责Nothing的呈现blocksV渲染图体块列表。Image内联元素则渲染为Image ( , [] , [] ) [ Str bar ] ( bar.png , )其中第三项是(URL, title)元组。native格式不依赖任何外部模板它直接打印 AST因此是观察读取器内部结构、编写过滤器或调试解析行为最直接的窗口——这也是该格式在回归测试中大量使用的原因。五、Figure在其他写出器中的落地Figure是跨格式的语义化结构不同写出器各有对应的渲染方式理解这些有助于判断implicit_figures的实际影响面HTML5在 src/Text/Pandoc/Writers/HTML.hs#L1086 中Figure块渲染为figure元素标题块渲染为figcaption若标题与图体 alt 文本一致还会在figcaption上附加aria-hiddentrue避免屏幕阅读器重复朗读。Markdown 写出器在 src/Text/Pandoc/Writers/Markdown.hs#L790 的figureToMarkdown中若启用了raw_html扩展则输出 HTML5figure否则退化为带figureclass 的Div正文加标题从而保证往返 Markdown 不丢失语义。不支持图形的格式Figure可被降级为通用Div。仓库在 src/Text/Pandoc/Shared.hs#L514 提供figureDiv工具函数将其转换为带figureclass 的Div标题放在captionclass 的Div中并以short-caption属性携带短标题——这解释了从源码结构看Figure在多种文本格式中都能保持可读性的原因。六、更多隐式图形的验证路径如果你想在仓库中复现或扩展该测试有两种方式直接运行命令行测试在test/command/下执行% pandoc -t native一行的命令把^D之前的内容作为输入对比输出与文件期望。也可借助 tools/diff-golden-tests.sh 这类脚本做 golden 文件差异比对。阅读同一机制的其它测试隐式图形并非 Markdown 专属其他读取器也构造Figure块。例如 test/Tests/Readers/Org/Block/Figure.hs 验证 Org 语法#caption:加#name:的图片如何成为figureWith构造的Figure其中还覆盖了空标题标签图等边界其实现位于 src/Text/Pandoc/Readers/Org/Blocks.hs#L518-L543 的figure函数——Org 读取器要求必须显式给出 caption 属性才判定为图。对照这些用例可以看到隐式alt 文本即标题与显式caption 属性驱动两种图形识别策略的差异。七、小结test/command/5368.md 虽然只有一份输入输出却完整覆盖了 pandoc 内部 AST 中Figure块的生成链路Markdown 读取器通过implicit_figures扩展将独立图片段落提升为Figuresrc/Text/Pandoc/Readers/Markdown.hsFigure携带属性、Caption与图体三部分信息native写出器将其原样打印src/Text/Pandoc/Writers/Native.hs#L185。对于列表项内的缩进图片该机制同样生效这正是测试 5368 所守护的回归场景。掌握这份 AST 结构无论是调试 Markdown 输入、编写自定义过滤器还是为写出器适配图形语义都能事半功倍。赞分享文档开发工具CLI【免费下载链接】pandocUniversal markup converter项目地址https://gitcode.com/gh_mirrors/pa/pandoc点击查看免费下载相关推荐pandoc 隐式图片implicit figures转换实战从 {width500px} 到 HTML5 figure 的完整链路解析pandoc 隐式图片implicit figures转换实战从 {width500px} 到 HTML5 figure 的完整链路解析 导读 本文以文档开发工具CLIPandoc 的 ConTeXt 图片输出解析从 HTML figure 到 \startplacefigure 的转换原理与黄金测试剖析Pandoc 的 ConTeXt 图片输出解析从 HTML figure 到 \startplacefigure 的转换原理与黄金测试剖析 导读 本文以 p文档开发工具CLIPandoc RST 简单表格列合并Col Span解析与输出command 测试 10127 深度解读Pandoc RST 简单表格列合并Col Span解析与输出command 测试 10127 深度解读 本指南以 Pandoc 仓库中的命令测试 tes文档开发工具CLI创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考