为 Pandoc 贡献
欢迎来到 Pandoc!自2006年诞生以来,Pandoc 一直受到用户、开发者和新手的共同影响、改进和修改。该项目因其活跃的社区而蓬勃发展。很高兴您能加入我们。
我能如何提供帮助?
您可以通过多种方式支持 Pandoc。以下是一些建议:
参与在线讨论。讨论论坛是进行此项活动的好地方。
帮助解答问题。社区回答的每个请求都能为编程贡献者腾出时间。这将加快新功能开发和问题修复的速度。请不要低估您的知识,请分享它!
提供帮助的好地方有:讨论论坛、StackOverflow 等问答网站、社区论坛(例如 RStudio、Zettlr),以及针对技术问题的 GitHub 问题追踪器。
撰写或改进文档。如果您遇到一个比预期花费更多时间解决的问题,请考虑让其他用户免于同样的经历。撰写文档的人往往缺乏外部视角,所以请帮助提供一个。好的文档既困难又极其重要。
官方文档并非唯一的文档来源。Pandoc 也有一个 Wiki。私人博客也可以像官方手册一样作为文档。
贡献代码。无论是格式模板中的小修复,还是大量的 Haskell 代码:都欢迎您的帮助。通常,尽早讨论计划是个好主意,这可以避免不必要的工作。更多信息请参阅下文。
最后但同样重要:考虑在财务上资助 Pandoc 的开发和维护。您可以在 Pandoc 网站和 GitHub 仓库上找到赞助按钮。
围绕 Pandoc 已经发展出了一个丰富的库、编辑器、过滤器和模板生态系统;反过来,Pandoc 的构建也依赖于大量的库。为这些项目中的任何一个做出贡献,是另一种确保稳定并不断拓展 Pandoc 可能性的方式。
有问题?
请在讨论论坛上提问。
发现错误?
欢迎提交错误报告!请将所有错误报告至 Pandoc 的 GitHub 问题追踪器。
在提交错误报告之前,请搜索开放问题 和 已关闭问题,以确保该问题之前没有出现过。此外,请查阅用户指南和常见问题,了解任何相关信息。
请确保您可以使用 最新发布的 Pandoc 版本(或者,更好的是,开发版本,因为自上次发布以来错误可能已被修复)重现该错误。夜间构建版本可用,因此您无需从源代码编译即可测试开发版本。(要获取夜间构建版本,请访问链接,点击表格中最顶部的“Nightly”,然后选择“Artifacts”下的平台。请注意,您必须登录 GitHub 账户。)
您的报告应提供详细、可重现的说明,包括:
- Pandoc 版本(使用
pandoc -v
检查) - 使用的确切命令行
- 使用的确切输入
- 收到的输出
- 您期望的输出
一个小的测试用例(仅几行)是理想的。如果您的输入很大,请尝试将其精简为最小工作示例。
超出范围?
不完美的转换并不一定意味着 Pandoc 存在错误。引用手册中的内容:
因为 Pandoc 的文档中间表示法不如其转换的许多格式那样富有表现力,所以不应期望每种格式之间都能进行完美的转换。Pandoc 试图保留文档的结构元素,但不会保留页边距大小等格式细节。某些文档元素(例如复杂的表格)可能不符合 Pandoc 简单的文档模型。虽然从 Pandoc 的 Markdown 到所有格式的转换都力求完美,但从比 Pandoc 的 Markdown 更有表现力的格式进行的转换可能会有信息丢失。
例如,docx
和 odt
格式都可以表示页边距大小,但由于 Pandoc 的内部文档模型不包含页边距大小的表示,因此从 docx 转换为 odt
时此信息将丢失。(但是,您可以使用 --reference-doc
自定义页边距大小。)
因此,在提交错误报告之前,请考虑它是否可能“超出范围”。如果它涉及 Pandoc 的 Markdown 中无法表示的文档特性,那么它很可能超出范围。(如有疑问,您随时可以在讨论论坛上提问。)
从问题追踪器修复错误
问题追踪器上的几乎所有错误都带有一个或多个相关标签。这些标签用于指示错误的复杂性和性质。目前还没有指示优先级的方式。可以在 GitHub 标签上找到最新的问题摘要。
- good first issue — 新贡献者的完美起点。该问题具有通用性,无需深入了解代码库即可解决。
- enhancement — 一个期望的特性。我们建议您在编写代码之前,在讨论论坛上讨论任何提议的增强功能。
- bug — 需要修复的问题。
- complexity:low — 修复应该只有几行代码。
- complexity:high — 修复可能需要结构性更改或深入了解代码库。
- new:reader — 请求添加新的输入格式。
- new:writer — 请求添加新的输出格式。
- docs — 文档中的不一致或模糊之处。
- status:in-progress — 有人正在积极处理或计划处理该问题。
- status:more-discussion-needed — 解决此问题的正确方法尚不清楚。在开始处理此类问题之前,建议在问题上发表评论。
- status:more-info-needed — 我们需要用户提供更多信息才能正确分类报告。
与特定格式相关的问题会相应地打上标签,例如,与 Markdown 相关的功能请求或错误报告会标记为 format:markdown。
有新功能的想法?
首先,搜索讨论论坛和问题追踪器(包括开放问题 和 已关闭问题),以确保该想法之前未被讨论过。
解释您请求的功能的理由。为什么这个功能会有用?同时考虑任何可能的缺点,包括向后兼容性、新的库依赖和性能问题。
功能很少是“实现即忘”,因为所有代码都必须维护。这对于大型或复杂的贡献尤为重要。理解这一事实并清晰地沟通未来的计划和可用性非常有帮助。
任何潜在的新功能最好在开立问题之前,先在讨论论坛上进行讨论。
补丁和拉取请求
欢迎补丁和拉取请求。在花费时间处理非平凡的补丁之前,最好在讨论论坛上进行讨论,特别是如果它是针对新功能(而不是修复错误)的话。
请遵循以下指南:
每个补丁(提交)应进行单一的逻辑更改(修复一个错误、添加一个功能、清理一些代码、添加文档)。所有与该更改相关的内容都应包含在内(包括测试和文档),而不应包含任何不相关的内容。
提交消息的第一行应该是整个提交的简短描述(理想情况下 <= 50 个字符)。然后应该有一个空行,后面是更详细的更改描述。
遵循现有 Pandoc 代码中的风格约定。使用空格而非制表符,并将代码限制在 80 列以内。顶级函数务必包含类型签名。考虑安装 EditorConfig,这将帮助您遵循 Pandoc 中流行的编码风格。
您的代码应在没有警告的情况下编译通过(
-Wall
清洁)。运行测试以确保您的代码不会引入新的错误。(参见下文 测试。)所有测试都应通过。
为正在修复的 bug 添加测试用例是个好主意。(参见下文 测试。)如果您正在添加新的写入器或读取器,则必须包含测试。
如果您正在添加新功能,请更新
MANUAL.txt
。所有代码必须在管理 Pandoc 的通用许可证 (GPL v2) 下发布。
最好不要引入新的依赖。应特别避免依赖外部 C 库。
我们的目标是与至少最近三个发布的 ghc 版本兼容,有时甚至更多。目前 Pandoc 可以在 ghc 8.6 及更高版本上编译。所有拉取请求和提交都会在 GitHub Actions 上自动测试。
测试
测试可以按以下方式运行:
cabal install --only-dependencies --enable-tests
cabal configure --enable-tests
cabal build
cabal test
或者,如果您使用 stack,
stack setup
stack test
测试程序是 test/test-pandoc.hs
。
要运行特定测试(按名称模式匹配),请使用 -p
选项
cabal install pandoc --enable-tests
cabal test --test-options='-p markdown'
或使用 stack
stack test --test-arguments='-p markdown'
通常,在测试参数中添加 -j4
(并行运行测试)和 --hide-successes
(不显示成功的输出)会很有帮助。将所有选项收集在项目根目录的 cabal.project.local
文件中可以帮助缩短 cabal
命令。例如:
flags: +embed_data_files
tests: True
test-show-details: direct
test-options: -j4 --hide-successes
如果您向 Pandoc 添加新功能,请务必也添加测试,遵循现有测试的模式。测试套件代码位于 test/test-pandoc.hs
。如果您正在添加新的读取器或写入器,最简单的方法可能是向 test
目录添加一些数据文件,并修改 test/Tests/Old.hs
。否则,最好修改 test/Tests
层次结构下与您正在更改的 Pandoc 模块对应的模块。或者,您可以按照 /test/command/
层次结构中测试的模式,在此处添加一个“命令测试”。这些测试文件应具有有意义的名称,其中可以包含问题编号和/或正在测试的功能。例如,5474-tables.md
指的是问题和功能。
您可以通过向测试脚本传递 --accept
来重建 tests/
中的黄金测试。(如果您使用 stack,stack test --test-arguments "--accept"
;或者 make TESTARGS=--accept
)。然后检查更改后的黄金文件是否准确,并提交更改。对于 docx 或 pptx 测试,请在 Word 或 Powerpoint 中打开文件,以确保它们没有损坏并产生预期结果,并在您的提交评论中提及 Word/Powerpoint 版本和操作系统。
代码风格
Pandoc 使用 hlint 来识别代码改进的机会,例如冗余括号或不必要的 Language
扩展。然而,有时在某些情况下,有充分的理由使用与 hlint 建议不同的代码。在这些情况下,应在 .hlint.yaml
文件中禁用相应的警告。
运行 hlint .
时不应有错误;这由持续集成 (CI) 设置检查。建议贡献者使用本地 hlint 安装检查他们的代码,但依赖 CI 也可以。
确保不引入新警告的一个好方法是使用 Git pre-commit hook,该钩子在创建提交之前对所有已更新的 Haskell 文件运行 hlint
#!/bin/sh
git diff --diff-filter=MA --cached --name-only | grep '\.hs$' | \
xargs hlint --hint .hlint.yaml
(如果您使用的是 GNU xargs
,请在 xargs
后立即添加 -r
选项。)
将其保存到 .git/hooks/pre-commit
并使脚本可执行,将防止意外引入潜在的问题代码。
基准测试
使用 cabal 运行基准测试
cabal configure --enable-benchmarks
cabal build
cabal bench
使用 stack
stack bench
使用 REPL
使用最新版本的 cabal,您可以运行 cabal repl
来获取 ghci REPL 以使用 Pandoc。使用 stack,请使用 stack ghci
。
我们建议使用以下 .ghci
文件(可放置在源代码目录中)
:set -fobject-code
:set -XTypeSynonymInstances
:set -XScopedTypeVariables
:set -XOverloadedStrings
性能分析
要诊断解析性能问题,首先尝试使用 --trace
选项。这将为您提供块解析器成功时的记录,以便您可以发现回溯问题。
使用 cabal 使用 GHC 分析器
cabal clean
cabal install --enable-library-profiling --enable-executable-profiling
pandoc +RTS -p -RTS [file]...
less pandoc.prof
使用 stack
stack clean
stack install --profile
pandoc +RTS -p -RTS [file]...
less pandoc.prof
代码
Pandoc 在 GitHub 上有一个公开可访问的 git 仓库:https://github.com/jgm/pandoc。要获取源代码的本地副本:
git clone https://github.com/jgm/pandoc.git
主 Pandoc 程序的源代码是 pandoc.hs
。Pandoc 库的源代码在 src/
中,测试的源代码在 test/
中,基准测试的源代码在 benchmark/
中。
模块 Text.Pandoc.Definition
、Text.Pandoc.Builder
和 Text.Pandoc.Generic
位于独立的库 pandoc-types
中。代码可在 https://github.com/jgm/pandoc-types 找到。
要构建 Pandoc,您需要安装一个可用的 Haskell 平台。
该库的结构如下:
Text.Pandoc
是一个顶层模块,导出了库大多数用户所需的一切。任何添加新读取器或写入器的补丁也需要在此处进行更改。Text.Pandoc.Definition
(在pandoc-types
中)定义了用于表示 Pandoc 文档的类型。Text.Pandoc.Builder
(在pandoc-types
中)提供了用于以编程方式构建 Pandoc 文档的函数。Text.Pandoc.Generics
(在pandoc-types
中)提供了一些函数,允许您将操作 Pandoc 文档部分的功能提升为操作整个 Pandoc 文档的功能,并自动遍历树。Text.Pandoc.Readers.*
是读取器,Text.Pandoc.Writers.*
是写入器。Text.Pandoc.Citeproc.*
包含引用处理的代码,包括与 citeproc 库的接口。- 当使用
embed_data_files
cabal 标志时,Text.Pandoc.Data
用于嵌入数据文件。 Text.Pandoc.Emoji
是 emojis 的一个轻量级封装。Text.Pandoc.Highlighting
包含与 skylighting 库的接口,该库用于代码语法高亮。Text.Pandoc.ImageSize
是一个实用模块,包含根据图像文件内容计算图像大小的函数。Text.Pandoc.MIME
包含将 MIME 类型与扩展名关联的函数。Text.Pandoc.Options
定义了读取器和写入器选项。Text.Pandoc.PDF
包含从 LaTeX 源生成 PDF 的函数。Text.Pandoc.Parsing
包含多个读取器中使用的解析函数,满足 Pandoc 的需求。Text.Pandoc.SelfContained
包含使 HTML 文件“自包含”的函数,通过导入远程链接的图像、CSS 和 JavaScript 并将其转换为data:
URL。Text.Pandoc.Shared
是一系列共享实用函数的集合。Text.Pandoc.Writers.Shared
包含仅在写入器中使用的实用工具。Text.Pandoc.Slides
包含根据 MANUAL 中描述的约定,将 Markdown 文档拆分为幻灯片的函数。Text.Pandoc.Templates
定义了 Pandoc 的模板系统。Text.Pandoc.UTF8
包含用于将文本转换为 UTF8 字节串(严格和惰性)以及从 UTF8 字节串转换文本的函数。Text.Pandoc.Asciify
包含用于派生使用重音字符的标识符的 ASCII 版本的函数。Text.Pandoc.UUID
包含用于生成 UUID 的函数。Text.Pandoc.XML
包含用于格式化 XML 的函数。
添加新的命令行选项
要添加新的命令行选项,您需要在以下几个地方进行更改:
MANUAL.txt
– 新选项的文档,包括选项列表和默认文件部分。Text.Pandoc.App.Opt
– Opt 的新构造函数和默认值Text.Pandoc.App.CommandLineOptions
– 选项解析器Text.Pandoc.App
或Text.Pandoc.App.OutputSettings
– 处理新选项- 可能在 pandoc-server 中:
Text.Pandoc.Server
– 处理新选项
如果您的更改需要 ReaderOptions 或 WriterOptions 的新字段,您还需要:
Text.Pandoc.Options
– 类型更改和默认值- 在 pandoc-lua-engine 中:Text.Pandoc.Lua.Marshal.WriterOptions 和/或 Text.Pandoc.Lua.Marshal.ReaderOptions
Lua 过滤器
如果您编写了一个有用的 Pandoc Lua 过滤器,您可能希望考虑向 lua-filters 仓库提交一个拉取请求。