首页
/ free-programming-books 波斯语版免费编程书籍列表:完整资源盘点与 RTL 双向排版校验机制解析

free-programming-books 波斯语版免费编程书籍列表:完整资源盘点与 RTL 双向排版校验机制解析

2026-09-06 12:17:01作者:管翌锬

本文以 free-programming-books-fa_IR.md 这份波斯语(伊朗区)免费编程书籍清单为主体,完整梳理其按语言/主题组织的 20 余个免费资源条目,并结合仓库根 README.md 的多语言列表组织方式、CONTRIBUTING.md 的条目书写规范,以及 rtl_ltr_linter.py 双向文本(Bidi)检查器源码,说明这类 RTL 语言 Markdown 列表"为什么长这样"、贡献者应当"如何维护它"。

一、文件定位:fa_IR 书籍列表在仓库中的位置

本仓库是一个多语言免费编程学习资源索引,按资源类型分为四个目录:

目录 内容 波斯语对应文件
books/ 免费书籍列表 books/free-programming-books-fa_IR.md
courses/ 免费在线课程 courses/free-courses-fa_IR.md
casts/ 播客/屏幕录制 casts/free-podcasts-screencasts-fa_IR.md
more/ 速查表、交互教程等 无区分会话的通用文件

根目录 README.md 在 "Other Languages" 小节中通过 books/free-programming-books-fa_IR.md 链接索引该文件(README 中写作 "Persian / Farsi (Iran) / فارسى")。文件名采用 -fa_IR 后缀(语言码_区域码)以区分通用波斯语,仓库内波斯语资源统一遵循这一命名约定。

从源码结构看,这一命名并非随意约定:RTL 检查器 rtl_ltr_linter.py 中的 is_rtl_filename() 函数通过文件后缀(-ar.md-he.md-fa.md-ur.md 等)判断一个文件的基础文字方向。值得注意的是,该后缀集合中并不包含 -fa_IR.md,因此 fa_IR 文件的基础方向会落入 LTR 分支——文件真正的 RTL 上下文由下文第二节说明的 <div dir="rtl"> 包裹标记提供。两套机制(文件名判定 + div 方向栈)互为补充,是这类混合方向文档能稳定渲染和校验的前提。

二、文档主体结构:目录、章节与 RTL 包裹标记

books/free-programming-books-fa_IR.md 全文共 99 行,结构上由三部分组成:

  1. RTL 包裹层:第 1 行 <div dir="rtl" markdown="1"> 与第 99 行 </div> 将全部正文声明为从右向左排版,中间内容可继续按 Markdown 语法书写。
  2. 目录(فهرست):以纯锚点链接列出各章节——رایانش ابری(云计算)、مهندسی نرم‌افزار(软件工程)、HTML and CSS、Java、JavaScript、LaTeX、Linux、PHP(含子目录 Symfony)、Python(含子目录 Django)、R;其中 PHP 与 Python 使用嵌套 <ul dir="rtl"> 列表展开二级锚点。
  3. 正文条目区:按 ### 章节 分节,每个章节为 Markdown 无序列表,条目格式统一为 标题 - 作者 (格式)

一个可以在文档中直接观察到的细节:正文比目录多出一个 ### شبکه(网络)章节(第 28 行),目录锚点列表中并未收录该章节。这说明目录区是手工维护的,新增章节时需要同步更新 فهرست,属于该文档当前存在的一处不一致。

条目中的 &rlm;&lrm; 并非普通文字,而是 Unicode 双向文本控制符(Right/Left-to-Run Mark)的 HTML 实体。例如第 42 行的 یادگیری پیکربندی با CSS&rlm; 在 CSS 之后加了 RLM,第 37 行的 Robert C. Martin, et al.&lrm; 在 LTR 作者名之后加了 LRM。它们的作用是阻止浏览器 Bidi 算法在波斯文与英文术语混排时错误重排词序——这正是第三节 linter 校验规则针对的对象。

三、完整资源清单(逐条继承原文档)

以下表格按原文章节顺序完整收录全部条目,格式标注与归档标注均保持原文。

3.1 رایانش ابری(云计算)

资源标题(波斯语原文) 格式 链接
رایانش ابری(云计算) PDF http://docs.occc.ir/books/Main%20Book-20110110_2.pdf

3.2 شبکه(网络)

资源标题 作者/来源 链接
علم شبکه(网络科学) 阿尔伯特-拉斯洛·巴拉巴西(Albert-László Barabási) http://networksciencebook.com

3.3 مهندسی نرم‌افزار(软件工程)

资源标题 作者/来源 格式/备注 链接
الگوهای طراحی(设计模式) Hossein Badrnezhad 需要注册(نیاز به ثبت نام دارد) https://holosen.net/what-is-design-pattern/
الگوهای طراحی در برنامه‌نویسی شیء‌گرا(面向对象编程中的设计模式) 自由作品 https://github.com/khajavi/Practical-Design-Patterns
ترجمه آزاد کتاب کد تمیز(《代码整洁之道》自由翻译) Robert C. Martin 等 https://codetamiz.vercel.app

3.4 HTML and CSS

资源标题 格式 链接
یادگیری پیکربندی با CSS(用 CSS 学习布局) http://fa.learnlayout.com

3.5 Java

资源标题 格式/备注 链接
آموزش اسپرينگ(Spring 教程) 幻灯片 https://github.com/raaminz/training/tree/master/slides/spring
آموزش جاوا از صفر(从零学 Java) 在线课程 https://toplearn.com/courses/85/آموزش-جاوا-از-صفر
آموزش هايبرنيت(Hibernate 教程) 幻灯片 https://github.com/raaminz/training/tree/master/slides/hibernate

3.6 JavaScript

资源标题 作者 格式 链接
جاوااسکریپت شیوا(《流畅的 JavaScript》,波斯译名) Marijn Haverbeke、Moein Ofoati 译 HTML http://eloquentjs.ir
ریکت جی اس(React 波斯语版文档) https://github.com/reactjs/fa.reactjs.org
یادگیری اصولی جاوااسکریپت(系统学习 JavaScript) https://github.com/Mariotek/BetterUnderstandingOfJavascript

3.7 LaTeX

资源标题 链接
مقدمه‌ای نه چندان کوتاه بر LaTeX(《LaTeX 不短简介》,波斯语版) http://www.ctan.org/tex-archive/info/lshort/persian

3.8 Linux

资源标题 格式 链接
تائوی برنامه نویسان(《程序员道》/ 程序员的 Tao) PDF https://aidinhut.com/fa/books/the_tao_of_programming.pdf
فقط برای تفریح؛ داستان یک انقلابی اتفاقی(《仅仅出于爱好:一次意外革命的传奇》) https://linuxstory.ir
لینوکس و زندگی؛ درس‌هایی برای گیک های جوان(《Linux 与生活:写给年轻极客的课》) https://linuxbook.ir

3.9 PHP

Symfony

资源标题 备注 链接
سیمفونی ۵: سریع‌ترین مسیر(Symfony 5:快速上手) :card_file_box: archived(已归档,经 Internet Archive 存档) https://web.archive.org/web/20210122133755/https://symfony.com/doc/current/the-fast-track/fa/index.html

3.10 Python

资源标题 作者 格式 链接
پایتون به پارسی(《波斯语 Python》) Saeed Darvish HTML https://python.coderz.ir
ترجمه آزاد کتاب Asyncio in Python(《Asyncio in Python》自由翻译) https://github.com/ftg-iran/aip-persian
ترجمه آزاد کتاب ThinkPython(《ThinkPython》自由翻译) 译者群体 https://github.com/ThinkPythonPersian/thinkbook

Django

资源标题 链接
ترجمه آزاد کتاب Django Design Patterns and Best Practices(《Django 设计模式与最佳实践》自由翻译) https://github.com/ftg-iran/ddpabp-persian
کتاب جنگو برای حرفه‌ای‌ها(《专业 Django 指南》) https://github.com/mthri/dfp-persian
کتاب جنگو برای API(《面向 API 的 Django 指南》) https://github.com/ftg-iran/dfa-persian

3.11 R

资源标题 格式 链接
تحلیل شبکه‌های اجتماعی در R(R 中的社会网络分析) PDF http://cran.r-project.org/doc/contrib/Raeesi-SNA_in_R_in_Farsi.pdf
راهنمای زبان R(R 语言指南) PDF http://cran.r-project.org/doc/contrib/Mousavi-R-lang_in_Farsi.pdf
مباحث ویژه در R(R 语言专题) PDF http://cran.r-project.org/doc/contrib/Mousavi-R_topics_in_Farsi.pdf

四、条目书写规范:格式标注、归档标注与许可证标注

上表中的 (PDF)(HTML) 括号标注与 *( :card_file_box: archived)* 归档标注并非作者随意为之,而是 docs/CONTRIBUTING.md 规定的通用条目格式。规范要点如下:

标准条目格式(标题 + 链接 + 可选作者 + 可选格式 + 可选许可证 + 可选附加说明):

* [书名](https://example.org/book.pdf) - 作者 (PDF) (CC BY)

归档链接规则CONTRIBUTING.md "Archived link" 小节):当原始资源已下线、必须借助 Internet Archive(Wayback Machine)等存档访问时,链接应指向存档快照,并在条目末尾附加归档标注:

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

fa_IR 文档第 75 行的 Symfony 5 条目正是该规范的实例:链接指向 web.archive.org 的 2021-01-22 快照,并携带 archived 标注。

许可证标注规则CONTRIBUTING.md):仅对自由/开放许可资源添加标注,且需归一化为支持列表中的短码(CC BYCC BY-SAGFDL 等,不带版本号);多格式资源可在同一括号中列出,如 (HTML, PDF);不确定许可时应改在 PR 中说明理由。fa_IR 文档当前未对任何条目附加许可证标注,属于规范允许的状态(该节资源未逐一确认为开放许可)。

排序规则CONTRIBUTING.md "Alphabetical order"):同一章节内多个条目按标题字母序排列,首字母相同时依次比较后续字符(aaab 之前,one twoonetwo 之前)。

五、源码纵深:RTL/LTR Linter 如何校验这份文档

books/free-programming-books-fa_IR.md 这类"RTL 正文 + 大量 LTR 术语"的混合方向文档,在仓库中由 scripts/rtl_ltr_linter.py 在 CI 中做自动化校验。读懂校验逻辑,也就读懂了这份文档中 &rlm;/&lrm; 标记存在的必要性。

5.1 校验范围与文件方向判定

main() 接受待扫描的文件/目录路径列表,逐文件调用 lint_file()rtl_ltr_linter.py#L518-L589)。lint_file() 的判定流程:

  1. 基础方向is_rtl_filename() 按文件后缀(-ar.md-he.md-fa.md-ur.md 等)把文件基础方向定为 RTL 或 LTR(rtl_ltr_linter.py#L77-L88)。如前所述,-fa_IR.md 不在后缀列表中,基础方向为 LTR;
  2. div 方向栈:逐行扫描 <div dir="rtl|ltr" ... markdown="1"></div>,用栈维护块级方向上下文(rtl_ltr_linter.py#L250-L266)。fa_IR 文件首行的 <div dir="rtl" markdown="1"> 因此会把整个正文推入 RTL 上下文,末行 </div> 弹出;文件结尾若发现栈未清空,会报 unclosed <div dir='...'> 错误(rtl_ltr_linter.py#L394-L399);
  3. 逐条目解析:仅处理 Markdown 列表项(* / - / + 开头),并用 BOOK_ITEM_RE 把条目拆成 标题 / 作者 / 元数据 三段(rtl_ltr_linter.py#L90-L99),这正是文档条目统一写作 标题 - 作者 (格式) 的原因——只有符合该结构的行才能被正确分段检查。

5.2 五类问题与严重级别

检查器对每段文本做以下检查,严重级别由 scripts/rtl_ltr_linter_config.yml#L125-L131 配置:

检查项 严重级别 触发条件(结合源码)
bidi_mismatch error 同一段落同时含 RTL 字符与 [A-Za-z0-9],且 python-bidi 计算的视觉序与逻辑序不一致(rtl_ltr_linter.py#L357-L364
keyword warning RTL 上下文中出现 LTR 关键词(如 HTMLCSSSymfonyDjango,完整词表见 rtl_ltr_linter_config.yml#L2-L97)且缺少 &rlm; 标记
symbol warning 出现 LTR 符号(如 C++Node.jsCI/CD,见 rtl_ltr_linter_config.yml#L99-L113)且缺少 &lrm; 标记
pure_ltr notice 非标题段为纯 ASCII 文本且长度 ≥ min_ltr_length(默认 3),建议补尾部 &rlm;
author_meta notice RTL 作者名后紧跟纯 LTR 元数据(如 作者 (HTML))且作者未以 RLM 结尾

识别为"已带标记"的实体集合为 &rlm;/&#x200F;/&#8207;&lrm;/&#x200E;/&#8206;rtl_ltr_linter_config.yml#L121-L123),代码中同时兼容这些控制字符的原始 Unicode 形式(rtl_ltr_linter.py#L226-L232)。此外,(PDF)(EPUB)(HTML) 等格式标注在脚本内置的 ignore_meta 名单中,不会被当作待修复文本。

对照 fa_IR 文档可以看到这些规则的实际落点:

  • 第 42 行 با CSS&rlm;、第 61 行 بر LaTeX&rlm;——标题内的 LTR 关键词 CSS/LaTeX 后补 RLM,避免 keyword 告警;
  • 第 37 行 Robert C. Martin, et al.&lrm;——LTR 作者名以 LRM 结尾,避免与后续分隔符错位;
  • 第 35 行 Badrnezhad&rlm;——RTL 作者名尾部 RLM,对应 author_meta 检查中 author.strip().endswith(rlm_marker) 的放行条件(rtl_ltr_linter.py#L300-L307)。

5.3 运行方式与一个值得注意的配置细节

检查器可在仓库中直接运行(只扫描、不改文件,日志可重定向到仓库外):

python3 scripts/rtl_ltr_linter.py books/free-programming-books-fa_IR.md --log-file /tmp/rtl-linter-output.log

参数说明(rtl_ltr_linter.py#L461-L486):位置参数为待扫描的文件或目录列表(目录会递归取 *.md);--changed-files 传入 PR 变更文件列表后,仅当问题落在 git diff origin/main... 的变更行上才输出 GitHub Actions 注解(::error/::warning/::notice 格式),并以变更行上的 error 数量决定退出码(rtl_ltr_linter.py#L404-L442rtl_ltr_linter.py#L601-L602);--log-file 默认为 rtl-linter-output.log

从源码看有一处值得留意的细节:main() 加载的配置文件名硬编码为 rtl_linter_config.ymlrtl_ltr_linter.py#L491-L495),而仓库内实际存在的配置文件名是 scripts/rtl_ltr_linter_config.yml,两者不一致。由于 load_config() 在文件不存在时会静默回退到脚本内置默认配置(rtl_ltr_linter.py#L29-L74),按当前仓库内容推断,实际生效的是内置默认值(ltr_keywords/ltr_symbols 为空列表、ignore_metaseverity 等与 YAML 内容相同),而非 YAML 中维护的那份较长关键词表。阅读或运行该检查器时,应把这一点作为适用前提。

六、延伸:fa_IR 资源族与文档一致性维护要点

波斯语(fa_IR)在本仓库中形成一组平行的资源文件,维护书籍列表时可交叉参考:

对维护者而言,围绕这份文档的一致性检查点可归纳为:

  1. 目录同步:新增/删减章节时同步更新文首 فهرست 锚点列表(当前正文的 شبکه 章节未列入目录,是既有的不一致点);
  2. 条目格式:遵循 docs/CONTRIBUTING.md标题 - 作者 (格式) (许可) *( 附加标注 )* 结构与章节内字母序,保证 BOOK_ITEM_RE 能正确分段;
  3. 双向标记:在 LTR 术语后补 &rlm;/&lrm;,使 bidi_mismatchkeywordsymbol 类检查通过;
  4. 归档资源:链接失效时替换为 Internet Archive 快照并加 archived 标注,而非直接删除。

七、小结

books/free-programming-books-fa_IR.md 覆盖了云计算、网络、软件工程、HTML/CSS、Java、JavaScript、LaTeX、Linux、PHP(Symfony)、Python(Django)与 R 共 11 个主题、26 个免费资源条目,其中 Django 与 Python 条目主要由 ftg-iran、ThinkPythonPersian 等开源翻译项目支撑,Symfony 条目是仓库内 archived 标注规范的标准实例。文档表面的波斯语排版之下,是一套可被 scripts/rtl_ltr_linter.py 逐行校验的 Bidi 标记体系:<div dir="rtl"> 方向栈、&rlm;/&lrm; 运行标记与五类分级检查共同保证了 RTL 语言列表在浏览器渲染与 CI 校验两条路径下的一致表现。理解这套机制后,无论是检索本列表中的波斯语学习资源,还是为同类多语言资源文档补条目,都有明确的格式依据与验证手段可依。

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