首页
/ free-programming-books 全解析:多语种免费编程学习资源库的资源分类体系、站点构建与贡献工作流

free-programming-books 全解析:多语种免费编程学习资源库的资源分类体系、站点构建与贡献工作流

2026-09-06 10:01:31作者:蔡怀权

本文基于仓库入口文档 README.md 展开,系统讲解 free-programming-books 项目的目录结构与六大资源列表分类体系、Jekyll 静态站点发布机制,以及由格式规范、fpb-lint 与 RTL/LTR 双向文本检查器构成的贡献自动化工作流。读完后你将能够独立导航该仓库中的数千条免费编程资源、理解每个列表文件的组织规则,并按规范提交格式正确的列表条目。

1. 项目概述:起源、治理与许可

README.md 的 "Intro" 章节交代了项目的三段历史:

  1. 该列表最初是 StackOverflow 上 "List of Freely Available Programming Books" 问答的克隆,内容来自 Karan Bhangui 和 George Stocker 的贡献(见 README.md);
  2. 随后由 Victor Felder 迁移到 GitHub 以支持协作式更新与维护,并成长为 GitHub 上最流行的仓库之一;
  3. 目前仓库由 Free Ebook Foundation(一个非营利组织)管理,该组织致力于推动免费电子书的创作、分发、存档与可持续性。

许可方面,README.md 明确指出:"Each file included in this repository is licensed under the CC BY License"。仓库根目录的 LICENSE 文件即为完整的 Creative Commons Attribution 4.0 International (CC BY 4.0) 全文(共 395 行)。这意味着:仓库中每一个文件都以 CC BY 4.0 单独授权,允许自由分享与改编,前提是给予署名。

2. 仓库目录结构总览

从仓库根目录的实际文件布局看,项目由"资源列表数据 + 站点构建配置 + 治理文档 + 校验脚本"四部分组成:

路径 内容 说明
books/ 48 个 .md 列表文件 英文书(按语言/按主题)+ 43 种其他语种书籍列表
courses/ 44 个 .md 列表文件 各语种免费在线课程列表
casts/ 22 个 .md 列表文件 各语种播客与屏幕录像(Podcast/Screencast)列表
more/ 9 个 .md 列表文件 速查表(Cheatsheets)、交互式教程、在线编程练习场(Playgrounds)、竞赛题集
docs/ 治理文档 CONTRIBUTING.mdHOWTO.mdCODE_OF_CONDUCT.md 及约 40 种语言的译文
scripts/ 校验工具 rtl_ltr_linter.py 及其配置 rtl_ltr_linter_config.yml
_config.yml Jekyll 配置 静态站点的主题与插件设置
_includes/head-custom.html HTML 头部片段 站点 favicon 注入

3. 资源列表的分类体系:六种列表类型

README.md 的 "Resources" 章节是理解整个仓库内容的骨架。项目按体裁(genres)把资源分为六类,其权威定义来自 docs/CONTRIBUTING.md

列表类型 定义(据 CONTRIBUTING) 仓库对应位置
Books PDF、HTML、ePub、基于 gitbook.io 的站点、Git 仓库等书籍 books/
Courses 不是书的教材(如 MIT OCW 课程页),通常含讲义、习题、测验等教学辅助 courses/
Interactive Tutorials 允许用户输入代码/命令并即时求值的交互式网站(如 Try Haskell、Try Git) more/free-programming-interactive-tutorials-en.md 等 5 个语种
Playgrounds 可在浏览器内编写、编译、运行代码的在线环境 more/free-programming-playgrounds.md 等 3 个语种
Podcasts & Screencasts 播客与屏幕录像 casts/
Problem Sets & Competitive Programming 通过解题(可选代码评审、排行榜)评估编程能力的网站或软件 more/problem-sets-competitive-programming.md

3.1 英文书籍:按编程语言与按主题的双轨组织

英文书籍被拆成两个大文件,这一拆分有明确的历史原因。books/free-programming-books-langs.md 开头写道:原列表曾有一个 "Language Agnostic" 章节,因体积膨胀过大而拆分为独立的 "BY SUBJECT" 文件;通用编程书籍归入主题 "Programming",专题书籍归入各自小节。

  • 按编程语言组织books/free-programming-books-langs.md(约 2773 行)。文件头部是一个覆盖全部章节的 Index,从 ABAP、Ada、Agda 一路排到 Go、GraphQL、Haskell 等数百种语言/技术,支持二级小节(如 Elixir 下的 Ecto、Phoenix;Groovy 下的 Gradle、Grails;HTML and CSS 下的 Bootstrap、Tailwindcss)。
  • 按主题组织books/free-programming-books-subjects.md(约 1086 行)。收录语言无关的编程主题书籍,Index 覆盖 Algorithms & Data Structures、Artificial Intelligence、Machine Learning、Compiler Design、Operating Systems、Quantum Computing、Prompt Engineering、Web Performance 等 40 多个主题。

两个文件的组织规则一致:文件以 Index 开头,章节使用三级标题(###),小节使用四级标题(####),条目按字母序排列——这套格式规范由贡献指南强制,详见第 5.2 节。

3.2 多语种资源覆盖

README.md 的 "Other Languages" 及各资源小节给出了完整的多语种矩阵(路径均指向仓库根目录):

4. 静态站点发布机制(Jekyll)

README 本身是一篇可直接被 Jekyll 渲染的 Markdown,仓库根目录的 _config.yml 定义了完整的站点构建行为:

remote_theme: pages-themes/minimal@v0.2.0

# [Conversion]
markdown: kramdown

# [Used rubygem plugins]
plugins:
  - jekyll-remote-theme
  - jemoji
  - jekyll-relative-links

relative_links:
  enabled: true
  collections: true

include:
  - CONTRIBUTING.md
  - LICENSE.md
  - CODE_OF_CONDUCT.md

从这份配置可以看出几个关键事实:

  • 主题:使用 jekyll-remote-theme 插件拉取远程主题 pages-themes/minimal@v0.2.0,即 GitHub Pages 的 minimal 主题;Markdown 转换引擎为 kramdown
  • 插件链jemoji 支持在列表条目中内嵌 emoji(例如 "in process" 标注使用的 🚧、"archived" 标注使用的 🗃,见 docs/CONTRIBUTING.md);jekyll-relative-links 配合 relative_links.enabled: truecollections: true,让 README 中形如 books/free-programming-books-langs.md纯文件名相对链接在被渲染成网页后依然可以正确解析跳转——这正是 README 能以"文件名相对路径"书写 100+ 条列表链接而不 404 的原因。
  • favicon 注入_includes/head-custom.html 是 minimal 主题提供的头部扩展点,仓库在其中通过 Jekyll 过滤器注入根目录的 favicon:<link rel="shortcut icon" type="image/x-icon" href="{{ '/favicon.ico' | relative_url }}">
  • 搜索表单README.md 内嵌了一段原生 HTML <form>action 指向项目的动态搜索站点,输入框 name="search"、占位符 "Search Book or Author"。README 同时说明项目提供了一个"易读版"静态站点。

5. 贡献工作流:从格式规范到自动化校验

README.md 的 "How To Contribute" 章节把贡献入口收敛为三份治理文档:docs/CONTRIBUTING.md(贡献指南)、docs/HOWTO.md(GitHub 新手入门,含 Fork 与 PR 教程链接)、docs/CODE_OF_CONDUCT.md(改编自 Contributor Covenant 1.3 的行为准则)。README 还通过徽章指向 Issue 中的 good first issuehelp wanted 标签作为上手路径。docs/HOWTO.md 特别强调:PR 提交后 GitHub Actions 会运行 linter,常因间距或字母序等小问题而失败,需在失败检查的 "Details" 中查看原因并向分支追加修复 commit。

5.1 内容准入规则("In a nutshell")

docs/CONTRIBUTING.md 的核心条款:

  1. 必须确认资源真正免费:不接受"要求填写有效邮箱才能获取书籍"的页面,但欢迎标注"email address requested, not required"的条目;
  2. 不需要会 Git:发现仓库中没有的资源,可直接开 Issue 提交链接提议;会 Git 则 Fork 后发 PR;
  3. 选对列表类型:六类列表(见第 3 节表格),选错文件会导致 linter/审查失败;
  4. 遵循下方 Guidelines 与 Markdown 格式规则
  5. GitHub Actions 会自动测试字母序与格式规则,提交前务必自查。

具体链接选择准则(docs/CONTRIBUTING.md):

  • 拒绝 Google Drive、Dropbox、Mega、Scribd、Issuu 等文件托管平台链接;
  • 同域下 https 优先于 http;根域名去掉尾部斜杠(example.com 优于 example.com/);
  • 永远选最短链接(/dir/ 优于 /dir/index.html),禁止 URL 短链;
  • 同一资源优先选"current"链接而非版本号链接;
  • 证书失效/自签名的链接:能换成 http 对应地址则替换,仍可访问则保留,否则删除;
  • 一个资源多种格式时,各格式单列链接并注明格式;
  • 老书在标题括号内标注出版年份;未完成的在进程书籍加 in process 标注;通过 Wayback Machine 恢复的加 archived 标注;
  • 尽量使用原子化 commit(一次增/删/改一个 commit)。

5.2 Markdown 格式规范(可复制的实操细节)

docs/CONTRIBUTING.md 的 "Formatting" 小节给出了被 linter 强制执行的空白行规则与条目语法,以下是完整继承的规范与示例:

空白行规则

  • 上一条链接与新章节标题之间:2 个空行;
  • 章节标题与该章节第一条链接之间:1 个空行;
  • 两条链接之间:0 个空行;
  • 每个 .md 文件末尾:1 个空行。
[...]
* [An Awesome Book](http://example.com/example.html)
                                (blank line)
                                (blank line)
### Example
                                (blank line)
* [Another Awesome Book](http://example.com/book.html)
* [Some Other Book](http://example.com/other.html)

链接语法]( 之间不留空格:

BAD : * [Another Awesome Book] (http://example.com/book.html)
GOOD: * [Another Awesome Book](http://example.com/book.html)

字段顺序:作者名(如有)紧跟链接,作者与格式标注之间、链接与格式之间用单个空格分隔,且作者必须在格式之前

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)

多格式:优先单链接;确需多链接时用括号嵌套第二个链接:

GOOD: * [Another Awesome Book](http://example.com/) - John Doe (HTML) [(PDF, EPUB)](https://downloads.example.org/book.html)

年份、状态与许可标注

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

GOOD: * [Will Be An Awesome Book Soon](http://example.com/book2.html) - John Doe (HTML) *( :construction: in process)*

GOOD: * [A Way-backed Interesting Book](https://web.archive.org/web/20211016123456/http://example.com/) - John Doe (HTML) *( :card_file_box: archived)*

自由许可证标注:对 CC/GFDL 等自由许可资源,在格式标注之后加许可短码(不带版本号),受支持的短码为 CC BYCC BY-NCCC BY-SACC BY-NC-SACC BY-NDCC BY-NC-NDGFDL

GOOD: * [A Very Awesome Book](https://example.org/book.pdf) - Jane Roe (PDF) (CC BY-SA)

docs/CONTRIBUTING.md 还给出了添加许可标注的五步流程:在资源页脚/About/Legal 区确认许可 → 归一化为短码 → 放在格式标注之后、其他注释之前 → 不同版本许可不同时拆分为独立条目 → 不确定时在 PR 中说明依据。

字母序规则docs/CONTRIBUTING.md):同前缀按次字母排序(aa 先于 ab),空格参与排序(one two 先于 onetwo)。条目放错位置时,按 linter 报错信息交换对应行即可。

5.3 CI 自动化:fpb-lint 与 awesome_bot

docs/CONTRIBUTING.md 的 "Automation" 小节描述了仓库的自动化链路:

  • 格式规则由 GitHub Actions 中的 fpb-lint 工作流强制(工作流文件路径 ../.github/workflows/fpb-lint.yml 在该小节被引用;当前仓库快照的可见文件中未包含 .github/ 目录,故此处仅陈述文档记载,不对该文件做进一步断言);
  • URL 有效性校验使用 awesome_bot触发方式是提交一个 commit message 中包含 check_urls=file_to_check 的 commit,例如:
check_urls=free-programming-books.md free-programming-books-en.md

多个文件用单个空格分隔。文档同时提醒:指定多个文件时构建结果以最后一个文件的结果为准,可能出现"假绿",需在 PR 的 "Show all checks" -> "Details" 中逐一核对构建日志。

5.4 RTL/LTR 双向文本 Linter(scripts 目录)

对阿拉伯语、希伯来语、波斯语、乌尔都语等从右向左(RTL)语种的列表文件,仓库自带一个 Python 检查器 scripts/rtl_ltr_linter.py。从其文件头 docstring(scripts/rtl_ltr_linter.py)可见其能力:

  • 逐行解析 Markdown 列表项,检测 HTML dir 属性以切换文本方向上下文,并处理 <span> 标签内的嵌套 dir 上下文;
  • 借助 python-bidi 库做 BIDI(双向算法)视觉分析,判断"显示顺序"与"逻辑顺序"是否一致(bidi_mismatch);
  • 解析书籍条目的 title/author/meta 元数据,专门检查"RTL 作者名后紧跟 LTR 元数据"这类易错场景;
  • 过滤代码块、行内代码与括号内文本,避免误报。

其配置位于 scripts/rtl_ltr_linter_config.yml,脚本 load_config() 函数(scripts/rtl_ltr_linter.py)在配置缺失或解析失败时会回退到内置默认值,保证 linter 永不因配置问题中断。配置要点:

配置项 作用 示例
ltr_keywords RTL 语境中需要 &rlm; 的 LTR 技术词 HTMLJavaScriptPythonDockerKubernetesVS Code 等 90+ 词
ltr_symbols RTL 语境中需要 &lrm; 的 LTR 符号 C#C++F#.NETNode.jsCI/CD
pure_ltr_pattern 识别纯 LTR 片段的正则 ^[\u0000-\u007F]+$(ASCII 基本拉丁字符)
rtl_chars_pattern 识别 RTL 字符的正则 [\u0590-\u08FF](希伯来文/阿拉伯文/叙利亚文范围)
rlm_entities / lrm_entities 可识别的方向标记实体 &rlm;/&#x200F;/&#8207;&lrm;/&#x200E;/&#8206;
severity 各类问题的严重级别 bidi_mismatch: errorkeyword: warningsymbol: warningpure_ltr: noticeauthor_meta: notice

docs/CONTRIBUTING.md 给出了修复 RTL/LTR 报错的标准手法与三组 BAD/GOOD 对照:LTR 技术词后紧跟 &rlm;,LTR 符号后紧跟 &lrm;

<!-- BAD -->
* كتاب الأمثلة في R - John Doe (PDF)
<!-- GOOD -->
* كتاب الأمثلة في R&rlm; - John Doe&rlm; (PDF)
<!-- BAD -->
* أساسيات C#
<!-- GOOD -->
* أساسيات C#&lrm;

6. 文档国际化:Translations 清单

README.md 的 "Translations" 章节说明志愿者已把 Contributing、How-to、Code of Conduct 三类治理文档翻译成列表所覆盖的多种语言,完整映射表维护在 docs/README.md(#translations 锚点):每个语种下列出已完成的文档链接,例如中文有 docs/CODE_OF_CONDUCT-zh.md(贡献者行为准则)、docs/CONTRIBUTING-zh.mddocs/HOWTO-zh.md;法语、日语、俄语、越南语等语种各有两到三份译文。README 同时把"这里还有缺失的译文"转化为贡献入口——欢迎通过 docs/CONTRIBUTING.md 的 "Help out by contributing a translation" 一节补全翻译。

7. 使用与复用要点

结合以上各节,使用该仓库时的三条实用结论:

  1. 按目标定位文件:找某语言的免费书去 books/ 对应 free-programming-books-<locale>.md;找课程去 courses/;找可交互练习去 more/ 的 interactive-tutorials/playgrounds 文件。每个文件头部的 Index 是快速跳转的锚点。
  2. 贡献前先自查:确认资源免费、选对六大列表类型之一、按 docs/CONTRIBUTING.md 的空白行规则与字段顺序书写条目、保持字母序;RTL 语种文件还要跑一遍 &rlm;/&lrm; 标注自查(规则与严重级别见 scripts/rtl_ltr_linter_config.yml)。
  3. 引用时遵守许可:仓库每个文件均为 CC BY 4.0(LICENSE),转引其中的书目清单时按 CC BY 要求署名即可;项目本身由 Free Ebook Foundation 治理,README 中的社交分享按钮(Facebook/LinkedIn/Mastodon/Telegram/X)也表明分享是被鼓励的(见 README.md)。

本文所有结论均以当前仓库快照为准;README 提及的动态搜索站点与静态站点属于项目配套服务,仓库内仅保留 README 中的表单与说明,其可用性以实际访问为准。

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