Pandoc MediaWiki 表格解析实战:HTML 注释处理与 `-f mediawiki` 读取器原理剖析 📅 发布时间:2026/9/21 1:32:31 👁 浏览次数: Pandoc MediaWiki 表格解析实战HTML 注释处理与-f mediawiki读取器原理剖析【免费下载链接】pandocUniversal markup converter项目地址: https://gitcode.com/gh_mirrors/pa/pandoc本篇技术指南围绕 Pandoc 中 MediaWiki 读取器的表格解析能力展开以 test/command/8110.md 这一官方回归测试为锚点完整讲解 MediaWiki 表格语法的转换流程重点剖析“行首后紧跟 HTML 注释”这一曾被修复的边缘场景对应 GitHub issue #8110并给出可复制、可运行的命令行验证方法。读者学完后将能熟练使用pandoc -f mediawiki将维基表格转换为标准 HTML 表格理解读取器底层状态机行分隔符、单元格分隔符、列头判定的解析顺序并掌握如何通过test/command目录中的回归测试用例来验证 Pandoc 读取器的行为。一、测试用例速览一段带注释的 MediaWiki 表格test/command/8110.md是一个典型的 Pandoc 命令回归测试golden test它完整记录了输入、命令行与期望输出% pandoc -f mediawiki {| classwikitable ! Header text ! Header text ! Header text | |- | Example | Example | Example | |- !-- This is a comment -- | Example | Example | Example |} ^D table thead tr thHeader text/th thHeader text/th thHeader text/th /tr /thead tbody tr tdExample/td tdExample/td tdExample/td /tr tr tdExample/td tdExample/td tdExample/td /tr /tbody /table1.1 测试文件的结构约定Pandoc 仓库中test/command/目录下的*.md文件是可自动执行的命令行回归测试文件以% pandoc ...开头声明要运行的命令随后是标准输入内容以^D表示 EOF^D之后则是期望的标准输出。test-pandoc.hs 驱动的测试框架会逐字节比对实际输出与期望输出任何不一致都会导致测试失败。因此8110.md本身既是文档也是一份可验证的契约。1.2 用例覆盖的核心场景该用例同时验证了 MediaWiki 表格解析的多个要点{|/|}包裹的完整表格结构!前缀的表头行thead/th|-行分隔符classwikitable表格属性被正确解析第二段表体行前紧跟 HTML 注释!-- This is a comment --注释被忽略且行仍被正确解析为新的tr——这正是本测试的回归对象issue #8110。二、从 MediaWiki 表格到 HTML解析流程全解2.1 命令入口与格式识别在 MANUAL.txt 中mediawiki被列为 Pandoc 默认支持的输入格式之一。运行时通过-f mediawiki指定输入格式-t html或省略时的默认输出指定输出格式。整个读取过程由 src/Text/Pandoc/Readers/MediaWiki.hs 中的readMediaWiki函数完成它接收ReaderOptions与输入文本调用parseMediaWiki解析器最终产出 Pandoc 内部文档表示Pandoc类型随后由 HTML 写入器渲染为table。2.2 表格块级解析器block解析器MediaWiki.hs按优先级依次尝试空行、table、标题、水平线、有序/无序/定义列表、HTML 注释、预格式化块、块级标签、模板与段落。tableMediaWiki.hs是其中专用于表格的分支其完整工作流如下表格起始tableStartMediaWiki.hs要求{|位于列首guardColumnOne并允许前导空白属性解析parseAttrsMediaWiki.hs解析classwikitable这类keyvalue或keyvalue形式的属性其中width属性还会经parseWidthMediaWiki.hs换算为相对列宽表头判定通过lookAhead (skipSpaces * char !)前瞻探测首行是否以!开头决定该行进入thead还是作为普通表体行行与单元格解析tableRowMediaWiki.hs逐行调用tableCellMediaWiki.hs后者经cellsepMediaWiki.hs识别|/!单元格分隔符并处理align、colspan、rowspan等单元格属性行分隔rowsepMediaWiki.hs匹配|-行分隔符表格结束tableEndMediaWiki.hs匹配列首的|}随后经compactifyTable压缩空单元格结构产出最终的 Pandoc 表格B.table并交由 HTML 写入器渲染。2.3 行分隔符中的注释处理#8110 修复点rowsep的完整定义是本次回归测试的关键实现rowsep try $ guardColumnOne * skipSpaces * sym |- * many (char -) * optional parseAttrs * skipSpaces * skipMany htmlComment * blanklines可以看到在匹配到|-之后解析器依次处理连续的-字符、可选的行属性、空白、任意数量的 HTML 注释skipMany htmlComment最后是空行。正是skipMany htmlComment这一行使得|- !-- This is a comment --这种“行分隔符后紧跟注释”的写法可以被正确识别。在 changelog.md 中记录了这一修复Allow HTML comment after row start (#8110)允许行首后出现 HTML 注释归属于 MediaWiki 读取器的小节。也就是说在修复之前|-后的 HTML 注释会导致行分隔符解析失败进而可能把后续内容误判为前一行的延续破坏整个表格结构修复后注释被静默跳过丢弃表格行照常切分。2.4 HTML 注释在解析器中的一般处理HTML 注释在 MediaWiki 读取器中并不特殊htmlCommentMediaWiki.hs复用Text.Pandoc.Readers.HTML的isCommentTag来匹配!-- ... --结构。除了rowsep中用于容忍行分隔符后的注释外block解析器MediaWiki.hs允许注释单独成块时被整体忽略mempty $ try (spaces * htmlComment)tableRowMediaWiki.hs在解析行首时也执行skipMany htmlComment因此即使注释出现在新行行的最前面也不会干扰行解析whitespaceMediaWiki.hs将行内注释视为空白处理。2.5 输出侧表格如何变成tableMediaWiki 读取器产出的是 Pandoc 统一的内部表格表示Table块含TableHead、TableBody、TableFoot。HTML 写入器负责将其渲染为语义化结构表头行输出为theadtrth…/th/tr/thead表体行输出为tbodytrtd…/td/tr/tbody表格属性如classwikitable则写入table标签的属性中。这也解释了 8110 用例期望输出中thHeader text/th与tdExample/td的对应关系。三、动手验证复现 8110 测试3.1 使用命令行直接验证如果本机已安装 Pandoc可完全复现该测试。将用例输入保存为table.wiki{| classwikitable ! Header text ! Header text ! Header text | |- | Example | Example | Example | |- !-- This is a comment -- | Example | Example | Example |}然后执行pandoc -f mediawiki -t html table.wiki输出应与 8110 用例的期望输出完全一致两行表体tr注释被丢弃且不产生任何残留节点。这说明读取器在“注释夹在行分隔符与新行之间”时依然能正确切分表格行。3.2 交叉验证其他格式转换为 Pandoc 原生格式观察内部表示pandoc -f mediawiki -t native table.wiki可看到Table块、TableHead、TableBody与ColWidth列宽信息有助于理解内部结构。转换为 Markdown / GFMGitHub 风格pandoc -f mediawiki -t gfm table.wiki输出为 GFM 管道表格可用于验证表格属性与列宽在不同目标格式下的降级表现。仓库中其他 MediaWiki 读取器回归测试同样可以参考例如 test/command/10390.md、test/command/2606.md含多个-f mediawiki -t html5用例、test/command/3585.mdmediawikismart扩展组合以及 test/command/11299.md输出 native 格式它们共同覆盖了表格、列表、链接、数学等更广泛的 MediaWiki 语法。3.3 运行仓库测试套件若需要从源码运行测试可参考 test/Tests/Old.hs其中将mediawiki读取器与写入器纳入writerTests/extWriterTests/reader测试组输入为 test/mediawiki-reader.wiki期望输出为 test/mediawiki-reader.native。命令回归测试含 8110则通过 test/test-pandoc.hs 执行例如cabal test pandoc-tests --test-options-p command四、边界与局限从源码结构可以推断当前 MediaWiki 读取器仍存在若干已知边界文件头部的 TODO 注释亦有提及见 MediaWiki.hs嵌套表格TODO 中明确写有 correctly handle tables within tables单元格内嵌套表格的解析属于已知未完全覆盖场景模板与魔术字template解析器MediaWiki.hs仅将{{...}}模板整体保留为rawBlock mediawiki原始内容不做模板展开行为开关类魔术字如__NOTOC__则经behaviorSwitchMediaWiki.hs写入文档元数据注释位置8110 修复针对的是行分隔符|-之后的注释从tableRow的实现看行首第一个单元格前的注释也会被跳过但注释出现在单元格内容中间时按whitespace规则会退化为空格处理。五、小结test/command/8110.md表面上只是一个 41 行的回归测试但它精确锚定了 Pandoc MediaWiki 读取器在表格行切分上的一个真实缺陷与修复方案。通过该用例我们梳理了从-f mediawiki命令入口、readMediaWiki状态机、table/rowsep/tableCell解析器链到 HTML 写入器输出table的完整链路并给出了可复现的验证命令。对于需要批量迁移维基站点内容、或为 Pandoc 贡献读取器修复的开发者这份用例与 src/Text/Pandoc/Readers/MediaWiki.hs 源码配合阅读是最直接的入手路径。【免费下载链接】pandocUniversal markup converter项目地址: https://gitcode.com/gh_mirrors/pa/pandoc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考