尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Pandoc 全解析:通用标记转换器的格式矩阵、Reader/Writer 模块化架构与源码级实现

Pandoc 全解析:通用标记转换器的格式矩阵、Reader/Writer 模块化架构与源码级实现 Pandoc 全解析通用标记转换器的格式矩阵、Reader/Writer 模块化架构与源码级实现【免费下载链接】pandocUniversal markup converter项目地址: https://gitcode.com/gh_mirrors/pa/pandocPandoc 是一个用 Haskell 实现的通用标记转换器universal markup converter既能把 40 余种输入格式解析为统一的文档 AST抽象语法树又能把 AST 渲染为 60 余种输出格式。本文以仓库 README.md 为主线完整梳理其输入/输出格式矩阵、PDF 生成路线与“有损转换”设计边界并深入 src/Text/Pandoc/Readers.hs、src/Text/Pandoc/Writers.hs 等源码揭示 CLI 入口到格式分发的完整调用链帮助读者建立从“会用命令”到“理解实现”的整体认知。一、定位Haskell 库 命令行工具的双重形态README 开篇即给出 Pandoc 的标准定义Pandoc is a Haskell library for converting from one markup format to another, and a command-line tool that uses this library. Pandoc 是一个用于在标记格式之间进行转换的 Haskell 库同时也是一个使用该库的命令行工具。这一定义对应仓库的实际工程结构——pandoc.cabal声明的核心库包源码位于 src/Text/Pandoc.hs 及其子目录与独立的 CLI 包 pandoc-cli/pandoc-cli.cabal 解耦。命令行入口在 pandoc-cli/src/pandoc.hs 的main函数中约 L46-L67其处理逻辑值得注意main E.handle (handleError . Left) $ do prg - getProgName rawArgs - getArgs ... case prg of pandoc-server.cgi - versionOr runCGI pandoc-server - versionOr $ runServer rawArgs pandoc-lua - runLuaInterpreter prg rawArgs _ - ... convertWithOpts engine opts从源码结构看同一个二进制文件依据可执行文件名或子命令切换三种运行形态普通转换convertWithOpts、HTTP 服务器模式pandoc-server或pandoc server、以及 Lua 解释器模式pandoc lua。versionInfoCLI还会通过getFeatures在pandoc -v输出中报告构建时启用的lua/server特性开关由 cabal flag 控制。此外仓库还包含 pandoc-lua-engine/Lua 过滤器运行时与 pandoc-server/服务器模式等配套子包共同构成完整的产品形态。命令行参数的解析与转换调用集中在Text.Pandoc.App模块options、parseOptionsFromArgs、convertWithOpts用户指南中的--from/--to、-o、-s等选项均在此定义完整参数说明见 MANUAL.txt约 8200 行的 pandoc 风格 Markdown 用户手册。二、输入格式矩阵48 种可读格式README 的input-formats部分列出了 Pandoc 全部支持的输入格式此处完整继承并分类整理如下Wiki/通用标记语言格式名说明markdownPandoc 增强版 Markdown含表格、定义列表、元数据、脚注、引文、数学等扩展markdown_strict原始未扩展的 Markdownmarkdown_mmdMultiMarkdownmarkdown_phpextraPHP Markdown ExtragfmGitHub-Flavored Markdowncommonmark/commonmark_xCommonMark后者启用扩展asciidocAsciiDoc 标记djotDjot 标记orgEmacs Org moderstreStructuredTextcreoleCreole 1.0dokuwiki/mediawiki/tikiwiki/twiki/vimwiki/xwiki*各类 Wiki 标记xwiki 仅输出textileTextilemuseMuse 标记t2ttxt2tagshaddockHaskell Haddock 标记podPerl POD 文档HTML/XML 系html、docbook、epub、jatsJATS XMLbits为其别名、opml、latex、context*context 仅输出、typst、man/mdocroff 手册页。Office/二进制文档以字节流方式读取docxWord、pptxPowerPoint、xlsxExcel 表格、odtOpenDocument 文本、fb2FictionBook2 电子书、ipynbJupyter Notebook、rtf富文本。表格数据csv、tsv。文献/引用数据bibtex、biblatex、csljson、ris、endnotexml。原生/调试格式nativeHaskell 原生 AST 文本表示、jsonAST 的 JSON 序列化、xmlAST 的 XML 序列化。自定义最后一条不是格式名而是任意 Lua 自定义 reader 的文件路径对应 README 指向的 Custom readers and writers 文档——即输入格式可以无限扩展这正是模块化设计的直接红利。源码印证readers 关联列表与“文本/二进制”双通道上述格式清单并非文档空谈src/Text/Pandoc/Readers.hs 中Reader数据类型与readers关联列表给出了精确实现data Reader m TextReader (forall a . ToSources a ReaderOptions - a - m Pandoc) | ByteStringReader (ReaderOptions - BL.ByteString - m Pandoc)每个格式名映射到两种构造函数之一纯文本格式走TextReader输入为 UTF-8 文本而docx/pptx/xlsx/odt/epub五个 ZIP 容器格式走ByteStringReader输入为ByteString字节流。这与data/目录下内置的 docx/odt/pptx 模板资源data/docx/、data/odt/、data/pptx/相印证——这些模板正是二进制格式读写时用于构造/解析 OOXML 的骨架。值得注意的实现细节gfmGitHub-Flavored Markdown在列表中映射到readCommonMark而非readMarkdown(gfm , TextReader readCommonMark)即 GFM 解析基于 CommonMark 解析器实现这正是 README 中“markdown_github已被弃用且准确性较低仅在需要 GFM 不支持的扩展时才使用它”这一建议的底层原因。格式分发由getReaderL192-L198完成按格式名查表未知名抛出PandocUnknownReaderError命中后通过Format.applyExtensionsDiff应用format扩展开关的差异例如markdownraw_html这类带扩展修饰的格式说明符。三、输出格式矩阵60 余种可写格式README 的output-formats部分同样完整继承如下纯文本/终端ansi带 ANSI 转义码供终端查看、plain纯文本。Markdown 族markdown、markdown_strict、markdown_phpextra、markdown_mmd、commonmark、commonmark_x、gfm。HTML 族html/html5HTML/XHTML polyglot、html4XHTML 1.0 Transitional、chunkedhtml多个链接 HTML 文件的 zip 归档。幻灯片beamerLaTeX beamer、s5、slidy、slideous、dzslides、revealjs后五种均为 HTML JavaScript 方案对应 data/templates/default.revealjs 等模板文件。LaTeX 系与排版latex、contextConTeXt、texinfoGNU Texinfo、msroff ms、manroff man、typst、texinfo。Office/电子书docx、odt、opendocumentOpenDocument XML、pptx、epub/epub3、epub2、fb2、icmlInDesign、rtf。学术/出版 XMLdocbook默认即 DocBook 5另有docbook4/docbook5显式区分、jats_archiving/jats_articleauthoring/jats_publishingJATS 三种 Tag Setjats为 archiving 的别名、teiTEI Simple、biblatex/bibtex/csljson文献格式。Wiki 族mediawiki、dokuwiki、jira、xwiki、zimwiki、vimdocVim 帮助文档、textile、t2t、muse、haddock、asciidoc/asciidoc_legacyasciidoctor为asciidoc的弃用同义词、markua、djot。BBCode 变体bbcode及bbcode_fluxbb、bbcode_phpbb、bbcode_steam、bbcode_hubzilla、bbcode_xenforo六个社区定制方言。其他ipynbJupyter Notebook、opml、native、json、xmlAST 的三种原生序列化以及最后一条——任意 Lua 自定义 writer 的文件路径。源码印证writers 列表与模板化输出src/Text/Pandoc/Writers.hs 的Writer类型与writers关联列表是上表的实现真相结构镜像 ReaderTextWriter输出Text与ByteStringWriter输出ByteString用于docx/odt/pptx/epub/chunkedhtml等二进制容器。几个可直接验证的实现细节docbook , TextWriter writeDocBook5——默认 docbook 输出即 DocBook 5docbook4单独映射到writeDocBook4五个 BBCode 方言共用 src/Text/Pandoc/Writers/BBCode.hs 中的同一核心仅导出不同方言函数writeBBCodeSteam、writeBBCodeFluxBB等每个文本 writer 的行为由 data/templates/ 下的同名模板驱动如 default.latex、default.html5、default.org用户可通过--template覆盖模板系统与 MANUAL.txt 中 Templates 一节对应。多语言支持方面data/translations/ 目录含约 130 个语言的.yaml翻译文件en.yaml、de.yaml、zh-Hans.yaml等用于 HTML/LaTeX 等输出中界面文本如“目录”“图”“表”的本地化对应--translate选项。四、PDF 生成一条输出三条中间路线README 明确指出Pandoc can also produce PDF output via LaTeX, Groff ms, or HTML.MANUAL.txt 的 “Creating a PDF” 一节给出了完整操作语义输出文件扩展名为.pdf即触发 PDF 管线默认经由 LaTeX 引擎如pdflatex/xelatex/lualatex也可改用 ConTeXt-t context、roff ms-t ms或 HTML配合wkhtmltopdf/prince等工具。生成工具统一由--pdf-engine指定。相关实现在 src/Text/Pandoc/PDF.hsPDF 引擎调用与模板处理与 src/Text/Pandoc/Process.hs外部进程调度。调试技巧同样来自手册把-o test.pdf换成-s -o test.tex即可导出中间 LaTeX再手工pdflatex test.tex定位问题。使用 LaTeX 路线时需要若干必备宏包amsmath、unicode-math、fancyvrb、longtable、graphicx等清单完整列于 MANUAL.txt 的 Creating a PDF 小节INSTALL.md 则按 Windows/macOS/Linux 分别给出 MiKTeX、BasicTeX/TinyTeX、TeX Live 的安装建议。五、模块化架构Reader → AST → Filter → WriterREADME 用一段话概括了 Pandoc 的核心设计Pandoc has a modular design: it consists of a set of readers, which parse text in a given format and produce a native representation of the document (an abstract syntax tree or AST), and a set of writers, which convert this native representation into a target format.结合源码完整数据流可表述为解析getReader按格式名查表得到Reader调用后产出Pandoc文档值AST 定义在 src/Text/Pandoc/Definition.hsReaders.hs顶部即import Text.Pandoc.Definition变换用户可通过--filter挂接外部过滤程序或直接用内置的Lua filters修改 AST文档见 doc/filters.md 与 doc/lua-filters.mdLua 运行时实现在 pandoc-lua-engine/含约 40 个 Haskell 侧模块与完整 Lua 测试集 pandoc-lua-engine/test/lua/data/init.lua 是自定义 reader/writer 的内置引导脚本渲染getWriter按目标格式查表Writers.hsL238-L244逻辑与getReader对称未知名抛PandocUnknownWriterError配合WriterOptions与模板生成最终文本或字节流。“增加一种输入/输出格式只需增加一个 reader 或 writer”这句设计宣言直接体现在readers/writers两个纯数据表上——新格式的实现只需新增一个模块并在表中登记一行。仓库中 test/ 目录按 Reader/Writer 维度组织测试test/Tests/Readers/ 34 个模块、test/Tests/Writers/ 23 个模块并为每个格式准备了.native期望输出快照如 test/markdown-reader-more.native构成对格式矩阵的回归保障。六、转换的边界为什么有些转换必然“有损”README 中一段极易被忽视但对正确使用 Pandoc 至关重要的段落Pandoc attempts to preserve the structural elements of a document, but not formatting details such as margin size. And some document elements, such as complex tables, may not fit into pandocs simple document model. While conversions from pandocs Markdown to all formats aspire to be perfect, conversions from formats more expressive than pandocs Markdown can be expected to be lossy.其含义可以归纳为三条规则Pandoc 保留结构标题层级、列表、表格、代码块、引用、脚注、公式、链接不保留版面格式细节页边距、字号、列宽等从 Pandoc Markdown向外的转换追求无损从表达力强于Pandoc Markdown 的格式如完整 docx 样式、复杂 Word 表格向内再向外的转换预期会有损失有些文档元素如跨越多行的复杂表格根本装不进简单文档模型。CONTRIBUTING.md 的 “Out of scope?” 一节给了一个标准例子docx与odt都能表示页边距但 Pandoc 的内部文档模型没有“页边距”这一概念因此 docx→odt 时该信息必然丢失不过可以借助--reference-doc在输出侧重新定制页边距。理解这一边界能避免把“设计如此”误报为 bug。七、安装与运行README 将安装细节链接到 INSTALL.md核心要点如下以仓库文档为准二进制包推荐各平台提供安装包/zip官方 Linux amd64 可执行文件为静态链接、无动态依赖与外部数据文件。注意 INSTALL.md 的明确警告静态二进制无法运行依赖 C 编写 Lua 模块的 Lua 过滤器需要此类能力时应改用源码/包管理器安装。包管理器Windows 的 Chocolateychoco install pandoc、wingetmacOS 的 Homebrewbrew install pandoc、MacPortsLinux 各发行版Debian/Ubuntu/Fedora/Arch/NixOS 等均有收录以及 Conda Forgeconda install -c conda-forge pandoc同样为静态链接。Docker官方pandoc/core仅 pandoc与pandoc/latex含最小 LaTeX镜像示例命令docker run --rm --volume pwd:/data --user id -u:id -g pandoc/latex README.md -o README.pdf源码编译stack 路线stack setup stack install pandoc-clicabal 路线cabal update cabal install pandoc-cli。cabal flag 控制可选特性pandoc包的embed_data_files把数据文件嵌入二进制得到可重定位的自包含可执行文件stack 对应--flag pandoc:embed_data_filespandoc-cli包的luaLua 过滤器支持与serverHTTP 服务器模式。测试运行cabal test/stack test可用-p markdown按名称过滤、-j4并行基准测试位于 benchmark/benchmark-pandoc.hs用cabal bench运行。日常使用的基本命令行形态来自 MANUAL.txt “Using pandoc” 与 “Specifying formats”pandoc -o output.html input.txt # 未指定格式时按扩展名推断 pandoc -s -o output.html input.txt # -s/--standalone 生成完整 HTML 文档 pandoc -f markdown -t latex hello.txt # 显式指定输入/输出格式 pandoc --list-input-formats # 列出全部输入格式 pandoc --list-output-formats # 列出全部输出格式未指定输入时读 stdin、输出默认走 stdout多输入文件会先拼接再解析--file-scope可改为逐文件解析。字符编码统一为 UTF-8非 UTF-8 环境应经iconv转码。八、文档体系、贡献与许可完整用户手册仓库内 MANUAL.txt 即网站 Users Guide 的源文件pandoc 风格 Markdown8000 行涵盖全部命令行选项、Pandocs Markdown 语法、模板系统、引用渲染等功能专题文档位于 doc/ 目录doc/filters.md、doc/lua-filters.md、doc/custom-readers.md、doc/custom-writers.md、doc/epub.md、doc/nix.md 等。贡献流程CONTRIBUTING.md 欢迎 pull request、bug 报告与功能提议报告 bug 前应使用pandoc -v核对版本、准备最小可复现用例并先判断问题是否属于上述“转换边界”范畴。test/Tests/Helpers.hs 与 test/test-pandoc.hs 是测试框架入口新增 reader/writer 的测试约定在 INSTALL.md “Running tests” 一节有说明。许可与作者README 与 COPYRIGHT 一致——© 2006-2024 John MacFarlane以 GPL 第 2 版或更高版本发布不提供任何担保。CITATION.cff 提供了学术引用规范主要作者 John MacFarlane、Albert Krewinkel、Jesse Rosenthal。README 自身即“文档工程”产物文件头部注释声明它由 README.template 与 MANUAL.txt 经pandoc --lua-filter tools/update-readme.lua自动生成过滤器脚本见 tools/update-readme.lua因此其中的格式清单与代码表始终保持同步。九、仓库导读关键路径速查路径内容README.md格式矩阵与设计宣言本文主线MANUAL.txt完整用户手册源文件INSTALL.md分平台安装指南CONTRIBUTING.md贡献规范与 bug 报告准则src/Text/Pandoc/Readers.hs全部 reader 注册表与分发逻辑src/Text/Pandoc/Writers.hs全部 writer 注册表与分发逻辑src/Text/Pandoc/Definition.hs文档 AST 定义src/Text/Pandoc/核心库全部模块格式解析、模板、PDF、翻译等pandoc-cli/src/pandoc.hsCLI 入口含 server/lua 形态切换pandoc-lua-engine/Lua 过滤器运行时与测试data/templates/各输出格式的默认模板data/translations/界面文本多语言翻译test/按 Reader/Writer 组织的回归测试与.native快照benchmark/benchmark-pandoc.hs性能基准适用前提提示本文所述格式清单、flag 与命令行为以当前仓库快照为准pandoc -v输出的lua/server特性标记与--list-input-formats/--list-output-formats的输出是核对具体构建能力的最可靠方式。【免费下载链接】pandocUniversal markup converter项目地址: https://gitcode.com/gh_mirrors/pa/pandoc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表