ManimGL 社区贡献指南:如何选择仓库、提交 PR 并本地构建官方文档
本文基于 3b1b/manim(ManimGL)仓库中的 contributing.rst 编写,面向希望参与 ManimGL 开发的贡献者与研究者。读完本文,你将掌握三件事:一是如何在本仓库与 ManimCommunity/manim 之间正确选择贡献目标;二是源码、文档、Bug 报告与成果分享各自的提交渠道与流程;三是如何在本机复现官方文档的完整 Sphinx 构建流程,从克隆仓库到产出 docs/build/html/ 成品。
为什么必须先选对 Manim 仓库
Contributing 文档 的开篇就强调了一个容易踩坑的前提:这个仓库是 3Blue1Brown 使用的 ManimGL 版本,它聚焦于 OpenGL 渲染、交互式工作流,以及 3b1b/videos 视频制作的具体需求。仓库的 README.md 与 about.rst 也印证了这一点:
- 3b1b/manim(ManimGL,即本仓库):由 3Blue1Brown 的 Grant Sanderson 维护,使用 OpenGL 及其 GLSL 语言借助 GPU 渲染,效率更高、渲染更快,并支持实时渲染与交互。PR 在这里同样欢迎,但审查可能需要一段时间。
- ManimCommunity/manim:由 Manim Community 团队维护,采用多后端渲染,文档更好、贡献社区更开放、响应更快。
因此贡献策略应当是:如果你的改动是面向广泛社区的功能、打包变更或面向新手的文档,也可以考虑提交到 ManimCommunity/manim;如果改动特定于 ManimGL(例如 OpenGL 渲染管线、交互场景、WGSL shader),则应保留在本仓库。README 中的安装警告同样适用于贡献场景——两个版本的安装与开发方式互不兼容,不要混用两处的说明。
四类贡献路径及其渠道
contributing.rst 明确列出了四条贡献路径,逐一说明如下。
1. 贡献 Manim 源码
流程为:fork 到你的仓库 → 修改代码 → 提交 pull request → 按模板填写变更动机。文档特别提示 PR 会被逐条仔细审查,且“通常需要一段时间,请保持耐心”。README 的 Contributing 一节还补充了一个实操要求:请在 PR 中解释清楚某个变更的动机,以及该变更效果的具体示例。
结合本仓库的源码结构,可以推断出改动通常涉及的模块分布(供你在写 PR 时定位与描述变更范围参考):
| 模块 | 路径 | 典型贡献场景 |
|---|---|---|
| 动画系统 | manimlib/animation/ | 新增/修改动画类,如 creation.py、transform.py |
| Mobject 对象体系 | manimlib/mobject/ | 向量对象、坐标系统、数学函数曲线等 |
| 渲染器与 shader | manimlib/renderer/、manimlib/shaders/ | OpenGL 渲染管线、WGSL 着色器逻辑 |
| 场景与交互 | manimlib/scene/ | 交互场景 interactive_scene.py 的键盘事件处理 |
| 工具函数 | manimlib/utils/ | Bezier、颜色、速率函数、LaTeX 处理等 |
例如,若你改动了着色器,对应的 WGSL 源文件位于 manimlib/shaders/ 及其 inserts/ 子目录;若改动动画,manimlib/animation/animation.py 是基类所在。
2. 贡献文档
文档贡献同样走 PR 流程,且要在 PR 中写清主要变更点。本仓库的文档源码即 docs/source/ 目录,入口为 docs/source/index.rst,其中 Development 章节的 toctree 收录了 changelog、contributing 与 about 三篇。撰写新文档时需注意:
- 文档基于 Sphinx + reStructuredText(
source_suffix = '.rst',见 docs/source/conf.py); - 代码高亮与复制按钮依赖
sphinx_copybutton扩展; - 数学公式依赖
sphinx.ext.mathjax,其mathjax_path指向 jsDelivr 上的 MathJax 3; - 主题使用
furo,favicon 取自 docs/source/_static/icon.png。
3. 报告 Bug
发现代码 Bug 时,应开一个 issue 并按模板填写问题描述与你的运行环境。文档同时提醒:如果你判断这更可能是自身使用问题而非源码缺陷,建议先到讨论区的 Q&A 分类提问,而不是直接开 issue——这能帮维护者过滤低效工单。
4. 分享成果与想法
- 用 manim 制作的视频/内容,可发布到讨论区的 Show and Tell 分类;
- 建议与想法,可发布到讨论区的 Ideas 分类。
这两类不产生代码变更,但被 about.rst 与 contributing.rst 一致认定为社区交流的重要组成。
本地构建官方文档:完整流程与底层细节
contributing.rst 给出了构建文档的三步流程,下面完整继承并结合仓库文件逐项展开。
第一步:克隆仓库
git clone https://github.com/3b1b/manim.git
# 或克隆你自己的 fork
# git clone https://github.com/<your user name>/manim.git
cd manim
第二步:安装文档构建依赖
pip install -r docs/requirements.txt
依赖清单 docs/requirements.txt 非常短,但值得注意其刻意设置版本上限的设计意图,文件内注释原样说明了历史教训:
# Upper bounds are deliberate. This build previously pinned Sphinx to 3.0.3
# while leaving Jinja2 unbounded, so it broke the day Jinja2 3.1 dropped
# environmentfilter. Bump these on purpose rather than drifting.
Sphinx>=8,<10
furo>=2024.8
sphinx-copybutton>=0.5,<1
Jinja2>=3.1,<4
也就是说,此前构建曾把 Sphinx 钉在 3.0.3 却放任 Jinja2 无上限,结果 Jinja2 3.1 移除 environmentfilter 时构建直接崩溃。因此这里同时约束 Sphinx 与 Jinja2 区间——如果你要为文档 PR 调整依赖,注释明确要求“有意识地升级,而不是让版本漂移”。
第三步:执行构建
cd docs/
make html
产出位于 docs/build/html/。
从 docs/Makefile 的源码结构看,这个 make html 并非手写目标,而是一个极简的 Sphinx 通用入口:
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = build
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option.
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
关键点:
- 通配目标
%: Makefile会把任意目标(html、latexpdf、epub、clean等)统一转发给sphinx-build -M <目标> source build; - 直接运行
make(无参数)等价于make help,因为help被排在第一个; SPHINXOPTS与O两个变量允许你在命令行追加 Sphinx 参数,例如make html SPHINXOPTS="-E"可清空环境缓存后重建。
Windows 用户对应的入口是 docs/make.bat,逻辑相同(sphinx-build -M %1 source build),并且会在检测不到 sphinx-build 命令时给出明确的安装提示。
构建配置解读:conf.py 与示例指令扩展
docs/source/conf.py 是构建行为的核心配置,除了上文提到的主题与扩展外,还有两处对贡献文档的人尤其重要:
-
路径注入:文件开头将
docs/目录自身和仓库根目录都插入sys.path,这使得 Sphinx 扩展可以直接 import 到仓库顶层的manimlib相关对象,也是文档能够做 API 级展示的前提。 -
自定义扩展
manim_example_ext:这是本仓库文档的招牌能力,实现在 docs/source/manim_example_ext.py。它注册了一个 RST 指令manim-example,用法形如:.. manim-example:: SquareToCircle :media: media/SquareToCircle.mp4从 ManimExampleDirective 的源码可以读出其行为细节:
required_arguments = 1:必须传入场景名(scene name);option_spec支持两个选项:hide_code(bool,隐藏代码块)与media(str,媒体文件名);- 指令会先把你写在指令体里的 Python 代码重新拼回
.. code-block:: python,再用 Jinja2 模板渲染出<video ... controls loop autoplay>(mp4 等)或.. image::(png/jpg/gif)块——判断依据是媒体后缀是否为图片扩展名; - 最终输出包裹在
<div class="manim-example">中,配合 conf.py 里引入的 CDN 样式表实现视频与代码并排的排版。
配套示例场景见 docs/example.py,其中
SquareToCircle与SquareToCircleEmbed两个 Scene 演示了交互与嵌入两种写法。 -
文档入口结构:docs/source/index.rst 按 Getting Started / Documentation / Development 三个 toctree 组织页面,Development 分组下按顺序包含
changelog、contributing、about。新增文档页时,把它加入对应 toctree 后重新make html才会出现在成品目录中。
贡献工作流小结
- 先定仓库:ManimGL 专属改动 → 本仓库;通用/打包/新手向改动 → 可同时考虑 ManimCommunity/manim;
- 源码 PR:fork → 修改 → 按模板写动机与效果示例,耐心等审查;
- 文档 PR:修改
docs/source/*.rst(或新增页面并挂入 toctree),依赖遵循 docs/requirements.txt 的有界约束,本地用make html验证产物; - Bug:按模板开 issue;疑似自身问题先走 Q&A 讨论区;
- 成果与想法:分别发到 Show and Tell / Ideas 讨论区。
文档构建链路本身也很适合当作学习 Sphinx 定制的小样本:Makefile 只做转发(docs/Makefile)、配置集中在 docs/source/conf.py、而 manim-example 指令(docs/source/manim_example_ext.py)展示了如何用一个 RST 指令 + Jinja2 模板把“场景源码 + 渲染视频”合并成文档页面。掌握这条链路,你就能在提交任何文档 PR 前,在本地完整复现并验证最终 HTML 效果。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00