请帮助乌克兰!
赞助商
Pandoc   一个通用文档转换器

为 Pandoc 贡献

欢迎来到 Pandoc!自2006年诞生以来,Pandoc 一直受到用户、开发者和新手的共同影响、改进和修改。该项目因其活跃的社区而蓬勃发展。很高兴您能加入我们。

我能如何提供帮助?

您可以通过多种方式支持 Pandoc。以下是一些建议:

  • 参与在线讨论。讨论论坛是进行此项活动的好地方。

  • 帮助解答问题。社区回答的每个请求都能为编程贡献者腾出时间。这将加快新功能开发和问题修复的速度。请不要低估您的知识,请分享它!

    提供帮助的好地方有:讨论论坛、StackOverflow 等问答网站、社区论坛(例如 RStudioZettlr),以及针对技术问题的 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 更有表现力的格式进行的转换可能会有信息丢失。

例如,docxodt 格式都可以表示页边距大小,但由于 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

有新功能的想法?

首先,搜索讨论论坛和问题追踪器(包括开放问题 已关闭问题),以确保该想法之前未被讨论过。

解释您请求的功能的理由。为什么这个功能会有用?同时考虑任何可能的缺点,包括向后兼容性、新的库依赖和性能问题。

功能很少是“实现即忘”,因为所有代码都必须维护。这对于大型或复杂的贡献尤为重要。理解这一事实并清晰地沟通未来的计划和可用性非常有帮助。

任何潜在的新功能最好在开立问题之前,先在讨论论坛上进行讨论。

补丁和拉取请求

欢迎补丁和拉取请求。在花费时间处理非平凡的补丁之前,最好在讨论论坛上进行讨论,特别是如果它是针对新功能(而不是修复错误)的话。

请遵循以下指南:

  1. 每个补丁(提交)应进行单一的逻辑更改(修复一个错误、添加一个功能、清理一些代码、添加文档)。所有与该更改相关的内容都应包含在内(包括测试和文档),而不应包含任何不相关的内容。

  2. 提交消息的第一行应该是整个提交的简短描述(理想情况下 <= 50 个字符)。然后应该有一个空行,后面是更详细的更改描述。

  3. 遵循现有 Pandoc 代码中的风格约定。使用空格而非制表符,并将代码限制在 80 列以内。顶级函数务必包含类型签名。考虑安装 EditorConfig,这将帮助您遵循 Pandoc 中流行的编码风格。

  4. 您的代码应在没有警告的情况下编译通过(-Wall 清洁)。

  5. 运行测试以确保您的代码不会引入新的错误。(参见下文 测试。)所有测试都应通过。

  6. 为正在修复的 bug 添加测试用例是个好主意。(参见下文 测试。)如果您正在添加新的写入器或读取器,则必须包含测试。

  7. 如果您正在添加新功能,请更新 MANUAL.txt

  8. 所有代码必须在管理 Pandoc 的通用许可证 (GPL v2) 下发布。

  9. 最好不要引入新的依赖。应特别避免依赖外部 C 库。

  10. 我们的目标是与至少最近三个发布的 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.DefinitionText.Pandoc.BuilderText.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.Emojiemojis 的一个轻量级封装。
  • 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.AppText.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 仓库提交一个拉取请求。