
Pandoc Texinfo 输出中的链接文本转义从命令测试 11758 看uref与comma{}的底层实现【免费下载链接】pandocUniversal markup converter项目地址: https://gitcode.com/gh_mirrors/pa/pandoc导读本文围绕 Pandoc 仓库中的命令测试 test/command/11758.md 展开剖析 Markdown 文档转换为 Texinfo-t texinfo时链接文本中的特殊字符重点是英文句点.与逗号,是如何被安全转义的。读完本文你将理解 Pandoc Texinfo 写入器src/Text/Pandoc/Writers/Texinfo.hs中三种转义上下文Normal / Node / Argument的设计差异、uref/url/ref三种链接形态的判定逻辑以及如何通过命令测试框架验证转换结果。一、测试用例速览一行命令两个关键断言test/command/11758.md全文是一个标准 Pandoc 命令测试块% pandoc -t texinfo a.b a,b ^D node Top top Top uref{url,a.b} uref{url,acomma{}b}这个测试块遵循 test/Tests/Command.hs 中定义的命令测试格式首行以%开头后面是要执行的命令这里为pandoc -t texinfo%之后、^D之前的内容作为标准输入stdin传给该命令即两段 Markdown 链接^D之后的内容是期望在 stdout 上得到的输出测试运行器execTest会以test-pandoc --emulate方式实际执行命令并将实际输出与期望输出做逐行对比compareValues不一致即判定测试失败。该用例验证了两个事实句点无需特殊处理链接文本a.b原样进入uref的第二个参数输出为uref{url,a.b}逗号必须转义链接文本a,b中的逗号被替换为comma{}输出为uref{url,acomma{}b}。两者的差异并非偶然而是由 Texinfo 语法本身决定的uref{url,displayed-text}以逗号分隔命令参数如果链接文本中直接出现裸逗号会让 Texinfo 解析器把文本误判为第三个参数产生语法错误。因此写入器必须在“命令参数”这一上下文中将逗号转义为comma{}。二、转义的三个上下文Normal / Node / Argument在 src/Text/Pandoc/Writers/Texinfo.hs 中定义了写入器的上下文状态data Context NormalContext | NodeContext | ArgumentContext deriving (Eq, Show) withContext :: PandocMonad m Context - TI m a - TI m aNormalContext普通正文文本NodeContext用于生成 Texinfo 节点node名称节点名对.,:(),等字符有限制ArgumentContext用于生成 Texinfo 命令的参数如uref{url,文本}中逗号之后的显示文本。withContext通过修改写入器状态stContext并在执行完毕后恢复旧值保证不同上下文下的转义规则互不串扰。链接文本正是通过withContext ArgumentContext $ inlineListToTexinfo txt渲染的见inlineToTexinfo的Link分支因此链接中的逗号会命中 Argument 上下文规则。三、stringToTexinfo字符级转义的核心实现所有文本最终都会经过 stringToTexinfo 做逐字符转义其完整规则如下表字符转义结果生效上下文{{全部}}全部全部U00A0不间断空格全部U2014em dash---全部U2013en dash--全部U2026省略号dots{}全部U2019右单引号全部,删除NodeContext,comma{}ArgumentContext:.()删除NodeContext其他字符原样保留全部对应源码中的关键分支escChar , | context NodeContext escChar , | context ArgumentContext comma{} escChar : | context NodeContext escChar . | context NodeContext escChar ( | context NodeContext escChar ) | context NodeContext escChar c T.singleton c由此可以清晰解释 11758 测试的两个输出a.b句点.不在 ArgumentContext 的转义名单中所以a.b原样输出为uref{url,a.b}a,b逗号,在 ArgumentContext 中被替换为comma{}所以输出为uref{url,acomma{}b}。注意逗号在 NodeContext 中反而会被删除不是转义这是因为 Texinfo 节点名不允许包含逗号参见disallowedInNode[.,:,,,(,)]节点名中若含这些字符会导致node指令无法解析。同一个字符在不同上下文中有着完全不同的命运这正是该写入器设计最精妙之处。四、Link的完整渲染逻辑ref/url/uref转义只是Link渲染的一环。inlineToTexinfo 的 Link 分支 根据目标地址形态选择三种 Texinfo 指令内部链接#ident→ref目标是文档内部的节标识符。写入器会先在stHeadings映射中查找该标识符对应的节点名节点名由addNodeText在标题处理阶段生成并登记找到则直接引用节点名未找到则对原始目标做去除非法字符处理显示文本通过ArgumentContext渲染若与节点名相同则省略第二参数。自动链接autolink→url当链接文本恰为单个Str且其escapeURI结果与目标地址完全一致时输出不带显示文本的url{...}例如test/writer.texinfo中的url{http://example.com/}。普通链接 →uref{url,文本}其余情况统一走uref目标地址先经stringToTexinfo转义所以mailto:nobodynowhere.net会输出为mailto:nobodynowhere.net显示文本在 ArgumentContext 下渲染。11758 测试覆盖的正是这一最常见分支。在仓库的 texinfo 写入器综合测试 test/writer.texinfo 中可以找到大量uref形态的佐证例如Just a uref{/url/,URL}. uref{mailto:nobodynowhere.net,Email link} uref{,Empty}.其中uref{,Empty}.表示空地址、空显示文本的边界情况也能被正常生成。五、转义规则的完整配套标题节点与段落文本转义机制不仅作用于链接还贯穿整个写入流程标题节点生成addNodeTextTexinfo.hs#L87-L101在 NodeContext 下渲染 14 级标题文本作为node名重复的节点名会被自动追加序号如name 2避免 Texinfo 节点重名冲突5 级及以上标题Header 5则降级为普通段落输出。菜单条目makeMenuLineTexinfo.hs#L417-L426同样以 NodeContext 渲染菜单项文本保证menu中引用的节点名与实际node完全一致。普通段落与行内文本Str、Code等内容经stringToTexinfo处理Code额外套上code{...}带variable类的代码则输出code{var{...}}。脚注与引用Note输出为footnote{...}内部同样经过完整转义流程。六、如何运行与验证在 Pandoc 开发环境中命令测试由测试入口 test/test-pandoc.hs 驱动测试套件通过 test/Tests/Command.hs 扫描test/command/目录下所有.md文件并逐个执行其中的命令块。本地验证方式cabal test pandoc-tests或单独跑 texinfo 相关用例cabal test pandoc-tests --test-options--pattern Command:11758也可以不依赖测试框架直接用构建出的 pandoc 复现该测试printf a.b\n\na,b\n | pandoc -t texinfo预期输出与test/command/11758.md中^D之后的内容一致node Top top Top uref{url,a.b} uref{url,acomma{}b}node Top/top Top是写入器通过wrapTopTexinfo.hs#L83-L85自动添加的文档外壳——Texinfo 格式要求每个文档必须有一个 Top 节点这一行为在所有 texinfo 输出中都恒定存在因此也出现在本测试的期望输出中。七、小结test/command/11758.md用最短的篇幅精确锁定了 Pandoc Texinfo 写入器的一条关键行为链接文本Texinfo 命令参数中的逗号必须转义为comma{}而句点可以原样保留。这一行为由 src/Text/Pandoc/Writers/Texinfo.hs 中基于上下文的逐字符转义函数stringToTexinfo保证并且与节点名中逗号被直接删除的规则形成鲜明对照。理解这套上下文转义模型也就掌握了 Pandoc 输出合法、可被makeinfo正常编译的 Texinfo 文档的核心原理。如果你需要为 texinfo 输出配置元数据可参考 MANUAL.txt 的 Texinfo 变量章节version、filename等做进一步定制。【免费下载链接】pandocUniversal markup converter项目地址: https://gitcode.com/gh_mirrors/pa/pandoc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考