首页
/ free-programming-books 仓库贡献指南:免费编程书单的资源分类、Markdown 格式与自动化校验规则详解

free-programming-books 仓库贡献指南:免费编程书单的资源分类、Markdown 格式与自动化校验规则详解

2026-09-07 09:29:42作者:范垣楠Rhoda

本文基于 free-programming-books 仓库的日文版贡献文档 docs/CONTRIBUTING-ja.md(其英文原文为 docs/CONTRIBUTING.md,另有 docs/CONTRIBUTING-zh.md 等各语言翻译)整理而成。free-programming-books 并不是一个软件项目,而是一个以 books/courses/casts/more/ 四个目录组织、覆盖数十种语言的免费编程学习资源清单仓库,其"核心业务"就是维护一套规则严谨、格式统一的资源列表。因此,贡献指南中定义的资源分类口径、内容取舍标准、Markdown 排版契约与自动化校验机制,就是这个项目真正的"技术规范"。读完本文,你将掌握向该仓库提交 Issue / Pull Request 的完整流程,理解六类资源清单的划分边界,能够写出通过 fpb-lint 与 URL 校验的合规列表条目,并了解仓库在贡献流程之上叠加的 RTL/LTR 排版校验等自动化保障。

在投稿之前:两条必须接受的约束

向本仓库提交任何内容,首先意味着两重法律与社区层面的确认:

  1. 投稿者许可协议:通过提交内容,你即表示同意仓库根目录下 LICENSE 的许可条款。该仓库采用宽松许可,但贡献内容授权关系以 LICENSE 文本为准。
  2. 投稿者行为规范:通过贡献,你还同意遵守 docs/CODE_OF_CONDUCT-ja.md(日文版行为规范)所述要求,其翻译版本可在 README.md 的语言索引中找到。

这两条是进入后续所有实操规则的前提,无需额外签署任何协议,提交即视为同意。

一言以蔽之:贡献的五条总纲

日文版指南以"一言で言えば"(一句话概括)形式给出了贡献者必须牢记的五条总纲,后文所有细节均由它们展开:

  1. 免费性是第一原则:"能轻松下载本书的链接"不等于"指向免费图书的链接"。只提交确认为免费的内容,并尽量核实——仓库尤其不接受要求提供工作邮箱才能获取资源的页面链接,但欢迎那些"索取邮箱做登记"的列表式页面。
  2. 不懂 Git 也可以贡献:如果发现了仓库中还没有的有趣资源,直接带着链接建议去仓库的 Issues 区开一个 Issue 即可;熟悉 Git 的贡献者则可以把仓库 fork 后提交 Pull Request(PR)。
  3. 清单共有六类,必须对号入座:图书(书籍)、课程、交互式教程、Playground、播客与录屏、题目集与竞赛编程,详见下一节。
  4. 遵守下面的指南与格式契约:即 贡献指南Markdown 格式 两大部分。
  5. 必须通过自动化测试:仓库通过 GitHub Actions 运行测试,用于检查列表是否按字母顺序排列格式规则是否被遵守。提交 PR 前务必确认测试通过。

值得注意的是第五点在仓库的 .github/PULL_REQUEST_TEMPLATE.md 中也以强制 checklist 的形式固化了下来,例如要求贡献者先搜索是否重复、包含作者与平台、按字母顺序排列并保持正确间距、补充 PDF 等必要标注,并在 PR 描述中说明"为何这份资源确实免费"。

六类资源清单:先分清楚"这是哪一种"

仓库的所有资源被划分为六个互斥类别,对应仓库中不同目录与文件:

类别 定义 仓库落位
图书 PDF、HTML、ePub、基于 gitbook.io 的站点、Git 仓库等形式的完整书籍 books/ 下的各语言 .md 文件
课程 非书籍形态的系统化学习材料(有授课、练习、测验、讲义等) courses/
交互式教程 用户输入代码或命令、系统即时评测结果的交互网站 more/free-programming-interactive-tutorials-*.md
Playground 用于边写边编译/运行/分享代码片段的在线或桌面编程环境 more/free-programming-playgrounds*.md
播客与录屏 音频/视频形式的系列节目 casts/
题目集与竞赛编程 通过解题评估编程技能的网站或软件 more/problem-sets-competitive-programming.md

日文版指南对每一类都有精辟的判别口诀,贡献时应逐条对照:

  • 图书:PDF、HTML、ePub、gitbook.io 类站点、Git 仓库等都是书籍形态。
  • 课程:课程是"不是书的学习材料"。注意——单个讲座或单条视频不算课程,PowerPoint 幻灯片也不算课程
  • 交互式教程:核心判据是"能否打印出来却仍然保有其精髓(交互性)"——如果能,那它就不是交互式教程。tryhaskell.orglearngitbranching.js.org 这类"输入代码 → 系统评测结果"的站点才是典型例子。
  • Playground:写作、编译(或运行)、分享代码片段的地方,通常允许你 fork 一段代码上手摆弄。
  • 播客与录屏:即音频播客与录屏视频。
  • 问题集与竞赛编程:通过解决由简到难的问题来评测你编程技能水平的网站或软件。

这种"六类分治"直接决定了资源应该写进哪个目录、哪个文件,是最容易出现低级错误的环节。

通过 Issue 还是 PR 提交?

  • 不熟悉 Git:在仓库 Issues 区新建一个 Issue,贴上资源链接与推荐理由即可。这是门槛最低的路径,也方便维护者先讨论再入库。
  • 熟悉 Git:fork 仓库 → 按规则新增/修改列表 → 发起 PR。注意仓库在 .github/PULL_REQUEST_TEMPLATE.md 中明确要求:如果本次 PR 是对之前某个已提交 PR 的修订,应当回到原 PR 的分支上追加提交,而不是另开新 PR,以免让审阅变复杂。

贡献指南(Guidelines)——内容取舍与 URL 规范

免费性、托管平台与来源权威性

  • 确认免费:务必确认书籍确实是免费的,必要时二次核验。在 PR 中留言说明"为什么你认为它是免费的",会大幅方便维护者审阅。
  • 拒绝文件托管平台:不接受托管在 Google Drive、Dropbox、Mega、Scribd、Issuu 等类似文件上传平台上的文件。
  • 来源要"权威":优先选择最权威的来源——作者自己的网站优于编者网站、优于第三方网站;同理不要使用文件托管服务(如 Dropbox / Google Drive 链接)。
  • 同一资源多格式:当同一资源存在多个格式时,应分别添加带格式注记的链接(下文格式节有示例)。
  • 同一资源多处存续:若资源在互联网上有多个版本/出处,选择最权威的来源;当不同版本差异大到值得分别保留时,可以为每个版本单独添加链接并附注说明。

URL 书写规范

日文版指南对 URL 本身有非常细致的可操作规则:

  • HTTPS 优先:同一域名、提供相同内容时,https 链接永远优于 http 链接。
  • 去掉根域名尾斜杠:写 http://example.com,而不是 http://example.com/
  • 取最短链接http://example.com/dir/ 优于 http://example.com/dir/index.html禁止使用 URL 短链
  • "最新"优先于"版本号"http://example.com/dir/book/current/ 优于 http://example.com/dir/book/v1.0.0/index.html
  • 遇到 SSL 问题时按三步处理:① 可能的话先尝试改用 http(因为移动设备上接受证书例外很麻烦);② 若 http 版不可用但 https 版仍可访问,则保留该链接,让浏览器添加例外或忽略警告;③ 否则删除该链接。
  • 多格式分开列:资源有多种格式时,为每种格式各加一个链接并注明格式。
  • 不用短链服务,从 URL 中移除跟踪代码(tracking codes)。
  • 国际化 URL 需转义:浏览器地址栏通常会把它们渲染成 Unicode,但入库时应使用复制粘贴所得、正确转义后的形式。

提交粒度与资源元信息

  • 原子提交优先:一次提交只做一件事(一次新增 / 一次删除 / 一次修改),提交 PR 前不强制要求 squash 提交(这条只是维护者便利性约定,不会被强制执行)。
  • 旧书标注年份:书籍比较旧时,在标题旁标注出版年。
  • 作者署名:合适时写上作者名;作者列表可用"et al."缩写。
  • 未完成书籍:书籍尚未完成、仍在写作中的,加 in process 标记(格式见下)。
  • 归档资源:经 Internet Archive 的 Wayback Machine(或类似服务)恢复的失效资源,加 archived 标记,最好选用较近的完整快照。
  • 下载需登记:如果下载前必须配置邮箱或账号,应在括号内追加语言合适的注记,例如"邮箱地址并非必须"。

Markdown 格式规范

所有列表都是 .md 文件,使用标准 Markdown。日文版指南对排版给出了一套"空行契约",可直接对照 books/ 下各语言实际文件验证。

结构与标题层级

  • 每个列表文件以**索引(Index)**开头,索引中列出全部章节与子章节链接,并按字母顺序排列。
  • 章节用三级标题 ###,子章节用四级标题 ####。例如 books/free-programming-books-ja.md### Git### Go 是语言/主题章节,而 #### Gradle#### Grails#### Spock Framework### Groovy 下的子章节。

空行规则(极易被 lint 抓到的点)

  • 最后一个链接与新章节标题之间:2 个空行
  • 标题与该章节第一个链接之间:1 个空行
  • 两个相邻链接之间:0 个空行
  • 每个 .md 文件末尾:1 个空行

示意如下:

[...]
* 某本很棒的书(http://example.com/example.html)
                                (空行)
                                (空行)
### 示例
                                (空行)
* 另一本很棒的书(http://example.com/book.html)
* 还有一本书(http://example.com/other.html)

链接与作者字段的拼写细节

以下正误对照来自日文版指南,是最容易在 lint 中报错的"手滑"点:

  • ]( 之间不能有空格
BAD : * [Another Awesome Book] (http://example.com/book.html)
GOOD: * [Another Awesome Book](http://example.com/book.html)
  • 包含作者时使用 -(前后带空格的连字符)
BAD : * [Another Awesome Book](http://example.com/book.html)- John Doe
GOOD: * [Another Awesome Book](http://example.com/book.html) - John Doe
  • 链接与格式注记之间加半角空格
BAD : * [某本很棒的书](https://example.org/book.pdf)(PDF)
GOOD: * [某本很棒的书](https://example.org/book.pdf) (PDF)
  • 作者在格式注记之前
BAD : * [A Very Awesome Book](https://example.org/book.pdf)- (PDF) Jane Roe
GOOD: * [A Very Awesome Book](https://example.org/book.pdf) - Jane Roe (PDF)
  • 多格式资源的推荐写法——同一资源尽量只给一个主链接,不同格式以附加链接形式出现(每多一个链接就多一份维护负担,应尽量规避):
BAD : * [Another Awesome Book](http://example.com/)- John Doe (HTML)
BAD : * [Another Awesome Book](https://downloads.example.org/book.html)- John Doe (download site)
GOOD: * [Another Awesome Book](http://example.com/) - John Doe (HTML) [(PDF, EPUB)](https://downloads.example.org/book.html)

例如 books/free-programming-books-ja.mdPro Git 一条即是多格式链接的教科书式案例:* [Pro Git](http://git-scm.com/book/ja/) - Scott Chacon, trl.: 高木正弘 他 (PDF, EPUB, MOBI)

  • 旧书年份放进标题括号,而不是写在作者后面:
BAD : * [A Very Awesome Book](https://example.org/book.html) - Jane Roe - 1970
GOOD: * [A Very Awesome Book (1970)](https://example.org/book.html) - Jane Roe
  • in process(写作中)标记,使用 :construction: 图标:
GOOD: * [Will Be An Awesome Book Soon](http://example.com/book2.html) - John Doe (HTML) ( :construction: *in process*)
  • archived(已归档)标记,使用 :card_file_box: 图标并附 Wayback 快照地址:
GOOD: * [ウェイバックされた面白い本](https://web.archive.org/web/20211016123456/http://example.com/) - John Doe (HTML) *( :card_file_box: archived)*

字母顺序(アルファベット順)

  • 标题以同一字母开头的多个条目,从第二个字符起继续比较排序,如 aa 排在 ab 之前。
  • 含空格标题的排序规则是:one two 排在 onetwo 之前。
  • 若出现链接顺序错位,查看 linter 报错信息即可知道该交换哪几行。仓库中 books/free-programming-books-ja.md 等列表文件的目录顺序即为实测样例。

内容边界:什么绝不收录,什么是"书"

不收入清单的类型

为避免无限膨胀,以下类型一律不收录

  • 博客、博客文章、普通文章;
  • 网站(那些承载了大量上榜资源的平台除外);
  • 课程与录屏之外的视频;
  • 书的章节、书的预告样章;
  • IRC / Telegram 频道;
  • Slack 群与邮件列表。

竞赛编程列表对这些排除项相对宽松——仓库边界由社区共同决定,若想扩展或修改收录范围,请通过 Issue 提议。

判断"它是不是书"

指南对"书"的判定并不僵化,以下属性可以辅助判断:

  • 拥有 ISBN;
  • 有目录(目次);
  • 提供可下载版本,尤其有 ePub;
  • 有版本(edition);
  • 不依赖交互内容或视频;
  • 试图全面覆盖某个主题;
  • 自成一体(self-contained)。

榜单中很多条目并不具备全部属性,关键是与既有条目气质一致。

书 vs 课程

两者有时难以区分:课程往往附带教科书(教科书进图书榜),而课程本身包含授课、练习、测验、笔记与讲义等要素。单条讲座或视频不足以构成课程,PowerPoint 也不是课程。

交互式教程 vs 其他

判别唯一法则是:能打印出来却仍保有精髓的东西,不是交互式教程——交互性一旦脱离键盘输入与即时反馈就不复存在。

元数据与平台注意点(注意事項)

标题

  • 不要创作标题:尽量避免编造或采用编辑性标题;例外是"旧作"——当作品主要因历史意义被收录时,可在标题加括号年份,帮读者判断是否值得一看。
  • 不要全大写(ALLCAPS):一般遵循源出处的正常大小写,拿不准时照抄原文大小写。
  • 不要使用 emoji

URL(补充)

  • 不允许短链;删除 URL 中的跟踪代码;国际化 URL 使用转义形式;https 优先于 http我们不喜欢指向"并未承载所列资源"的落地页的 URL

创作者(クリエイター)

项目希望给创作者署名,包括译者

  • 译作的署名:原著者应获署名,其他创作者可用 MARC relators 编码标注。文档推荐用 trl.: 表示译者,示例:books/free-programming-books-ja.md 中既有 trl: 也有 trl.: 两种写法的真实条目,如 * [オープンソースソフトウェアの育て方](https://producingoss.com/ja/) - Fogel Karl, trl: 高木正弘, trl: Yoshinari Takaoka。MARC 编码本身建议参考 loc.gov 的 relator 词表。
  • 作者列表各项用英文逗号 , 分隔;可用 et al. 缩写。
  • 禁止给创作者附加外部链接
  • 汇编/混编作品的创作者需要描述性说明,例如 GoalKicker、RIP Tutorial 出品的书应标注"Compiled from StackOverflow documentation"。
  • 创作者姓名中不要包含 Prof.Dr. 等头衔。

限时课程与试用(期間限定のコースとトライアル)

  • 凡是"6 个月之内就会被移除"的内容不收录;
  • 报名期间/有效期受限的课程不收录;
  • 限时免费资源不收录。

平台与访问注记

  • 课程平台:课程清单中平台是资源描述的重要组成。图书通常不列需要注册才能阅读的,但许多课程平台没有账号就用不了(如 Coursera、edX、Udacity、Udemy 等)。课程依赖某平台时,平台名须写入括号
  • YouTube:以播放列表形式组织的课程很多;这时一般不把 YouTube 当平台名,而是标注 YouTube 创作者。
  • 单条 YouTube 视频:除非时长在 1 小时以上且按课程/教程结构组织,否则不收录;收录时务必在 PR 描述中说明。
  • 短链(如 youtu.be/xxxx)禁止
  • Leanpub:该平台混合了多种访问模式。无需注册即可读的收录;需要 Leanpub 账号才能免费读的,允许附加访问注记 *(Leanpubアカウントまたは有効な電子メールが必要です)*(需要 Leanpub 账号或有效邮箱)。

自动化校验:fpb-lint、awesome_bot 与 RTL/LTR 检查

日文版指南明确说明,格式规则的强制依靠 fpb-lint 与 GitHub Actions 完成:

  • 格式检查:由 fpb-lint(free-programming-books-lint)负责。该 workflow 在 PR 事件触发时全局安装 free-programming-books-lint,然后执行:
fpb-lint books casts courses more &> output.log

它会检查列表是否按字母顺序排列、格式规则(间距、空行、]/( 紧贴等)是否合规,并把清理后的错误日志上传为 workflow artifact 供作者查看。free-programming-books-lint 本身也独立发布,供本地预检使用。

awesome_bot "${{ matrix.file }}" --allow-redirect --allow-dupe --allow-ssl || true;

即允许跳转、允许重复、允许 SSL,并对每个改动文件生成结果 artifact 再汇总成报告。

  • 手动触发 URL 检查:向仓库推送一条提交消息中带 check_urls=文件路径 的提交即可触发校验,例如:
check_urls=free-programming-books.md free-programming-books-ja.md

可以同时指定多个文件。当指定多个文件时,构建结果以最后检查的那个文件为准——因此请在 PR 末尾点击 "Show all checks" → "Details" 查看构建日志,以免误判。

  • RTL/LTR 排版检查(仓库现有扩展):除贡献指南提到的两项外,仓库还内置了第三个质量门禁——.github/workflows/rtl-ltr-linter.yml 会在 PR 涉及阿拉伯语/希伯来语/波斯语/乌尔都语(ar、he、fa、ur)等 RTL 语言文件或带 RTL 标签时,运行 scripts/rtl_ltr_linter.py。该脚本逐行解析 Markdown 列表条目,检测 RTL 文本中嵌入的 LTR 关键词(如 HTML)、符号(如 C#)是否需要 ‏/‎ 等 Unicode 控制符,并结合 python-bidi 做双向文本视觉序分析;其严重级别(error/warning/notice)与忽略清单等均可在 scripts/rtl_ltr_linter_config.yml 中配置。这意味着面向 RTL 语言文件贡献时,除了格式与 URL,还要保证双向文本在 GitHub 上渲染不乱序。

给贡献者的最终自查清单

综合日文版贡献指南与仓库内的 .github/PULL_REQUEST_TEMPLATE.md,一次合格的贡献应当通过以下自查:

  1. 先检索确认没有重复条目(官方还提供免费的搜索界面用于查重)。
  2. 明确资源属于六类中的哪一类,写进正确的目录文件。
  3. 确认资源确实免费且不受"6 个月内下架 / 限时免费 / 需工作邮箱"等限制,不托管在网盘类平台。
  4. 选择了最权威来源、最短且无跟踪参数的 URL,https 优先。
  5. 格式合规:正确空行、- 分隔作者、格式注记用半角空格、标题不造词不带 emoji。
  6. 必要时补齐标注:旧书年份入标题、写作中加 :construction: in process、归档快照加 :card_file_box: archived、多格式附次级链接、译者用 trl.: 编码。
  7. 列表保持字母顺序,让 fpb-lint 与(涉 RTL 文件时的)rtl-ltr-linter 全部通过;URL 校验如需手动触发,用带 check_urls= 的提交消息推送,并在 PR 页面确认最终构建日志。

遵循上述规范提交的 PR,将能顺畅地通过自动化校验并大幅降低维护者的审阅成本——这正是 free-programming-books 能在十余年、数十种语言间保持列表一致性与高质量的原因。

登录后查看全文
热门项目推荐
相关项目推荐