南京大学毕业论文 LaTeX 模板 NJUThesis:dtx 单源文件与 l3build 开发工作流完整指南
【免费下载链接】NJUThesis南京大学学位论文模板项目地址: https://gitcode.com/gh_mirrors/nj/NJUThesis
如果你打开 NJUThesis 仓库,最引人注目的事实是:整个南京大学学位论文 LaTeX 模板,连同它的用户手册,全部写在一个约 9500 行的 dtx 单源文件里。为什么代码和文档能"合体"?docstrip 和 l3build 在其中各扮演什么角色?本文用最小代码量讲清楚这条开发工作流,帮你彻底看懂 NJUThesis 的构建机制。
一分钟认识 NJUThesis
NJUThesis 是制作南京大学本科毕业论文、硕士/博士学位论文、博士后出站报告的 LaTeX 文档类。它基于本科生院论文撰写规范,用 LaTeX3 语法实现了清晰的实现逻辑与友好的用户接口(键值配置命令\njusetup)。
普通用户和开发者的路径完全不同:
| 角色 | 你需要的东西 | 入口 |
|---|---|---|
| 📝 写论文的学生 | 用户包 zip / 南大在线 TeX 平台 | template/njuthesis-sample.tex |
| 🔧 模板维护者 | 源码仓库 + TeX Live 开发环境 | source/njuthesis.dtx |
仓库目录分工一目了然:
source/— 模板的 dtx 源码、用户手册源码和校徽校名 PDF 资源,仅开发者使用;template/— 官方空白模板与示例参考文献;test/— 回归测试与编译测试;scripts/— 依赖分析、打包辅助脚本。
⚠️ 新手最容易踩的坑:仓库里没有
njuthesis.cls这个文件。它是由 dtx 生成的产物,不是手写的。
dtx 单源文件之谜:代码与手册如何"合体"
所谓dtx 单源(Documentation/TeX eXtension),是一个把"程序实现"和"用户文档"写进同一份文件的体系。打开 source/njuthesis.dtx,你会看到它身兼两职:
- 对 XeLaTeX 来说:它是用户手册的源文件,直接编译得到 PDF 文档;
- 对 docstrip 来说:它是一部"带标签的零件库",按 guard 标签提取出真正的类代码。
dtx 文件开头的docstrip配置块(位于%<*install>区段)就是谜题的答案——它声明了哪些文件从哪些标签提取:
\generate{ \usedir{tex/latex/njuthesis} \file{\jobname.cls} {\from{\jobname.dtx}{class}} \file{\jobname-undergraduate.def} {\from{\jobname.dtx}{def-u}} \file{\jobname-graduate.def} {\from{\jobname.dtx}{def-g}} ... }也就是说,njuthesis.cls(主文档类)、njuthesis-undergraduate.def(本科版式)、njuthesis-graduate.def(研究生版式)、njuthesis-postdoctoral.def(博士后版式)以及手册文档类njuthesis-doc.cls,全部从同一个 dtx 文件的不同 guard 标签中切出来。
这种设计的好处对新手很直观:
- 文档与实现永不失同步——解释某段代码的文字就贴在代码旁边;
- 改行为只需改一处——项目规范明确要求"修改行为必须从 dtx 入手,不得直接编辑生成文件"(见 llmdoc/reference/coding-conventions.md);
- 一个版本对应一套文件——类代码、三个论文类型的 def 定义文件、手册,天然保持一致。
代价是编辑门槛较高:dtx 里的代码块被\begin{macrocode}...\end{macrocode}和环境标签包裹,误删标签就会破坏提取。项目在编码约定中甚至专门总结了"编辑 guard 前先定位完整范围、优先整块替换"的纪律(见 llmdoc/guides/common-development-tasks.md)。
开发工作流:l3build 如何驱动 dtx
单源文件的"拆分"和"装配"由l3build(LaTeX3 官方的构建工具)自动完成。仓库根目录的 build.lua 是整套流程的配置中枢,关键几行值得新手理解:
module = "njuthesis" sourcefiles = {"*.dtx", table.unpack(njulogofiles)} installfiles = {"*.cls", "*.def", table.unpack(njulogofiles)} typesetfiles = {"njuthesis.dtx"} unpackexe = "xetex"它告诉 l3build:源码是source/njuthesis.dtx加四枚校徽校名 PDF;安装产物是生成的 cls 和三个 def 文件;手册用 XeLaTeX 排版。围绕这份配置,开发者的日常命令只有三条:
| 命令 | 作用 | 什么时候用 |
|---|---|---|
l3build install | 从 dtx 提取生成 cls/def,安装到本地 TeX 树 | 改完 dtx 之后,测试之前必跑 |
l3build check | 编译 dtx 手册 + 跑test/下全部回归测试 | 本地验证改动 |
l3build ctan | 打 CTAN 发布包(内部还会先跑一遍 check) | 发布阶段 |
工作流串起来就是下面这条单向流水线:
编辑 source/njuthesis.dtx │ ▼ l3build install ──→ 生成 njuthesis.cls / *.def │ ▼ 编译 test/ 下最接近的变体(本科 / 研究生 / LuaLaTeX) │ ▼ CI 从规范源打包,产出用户 zip 与 CTAN 包两个值得注意的细节:
- 回归测试用的是 lvt 对照文件。
test/下的.lvt是预期输出快照,编译结果有差异会立即暴露行为回归;biblatex 相关行为还有独立的test/config-biblatex.lua配置和.tlg对照输出。 - CI 是两阶段流水线:先回归测试、后编译文档,任何一环失败都不会发布。失败时会自动上传构建产物便于诊断。
新手上手清单:从克隆到跑通测试
想完整体验这套工作流,只需准备一个现代 TeX 发行版(TeX Live 2023+ 自带 l3build):
git clone https://gitcode.com/gh_mirrors/nj/NJUThesis cd NJUThesis l3build install l3build check- 第一条克隆仓库;
l3build install会触发 docstrip 解包,把 dtx 里%<*install>标签中的生成规则执行一遍,产出 cls 与 def 文件;l3build check编译手册并逐项比对测试输出。
全部通过后,你就拥有了从"单源文件"到"可发布的模板包"的完整心智模型。
关键文件速查表
| 文件 | 一句话说明 |
|---|---|
| source/njuthesis.dtx | 规范源文件:实现代码 + 用户手册,一切修改的起点 |
| build.lua | l3build 构建配置:解包、安装、测试、CTAN 打包 |
| source/latexmkrc | 手册编译的 latexmk 配置 |
| template/njuthesis-sample.tex | 官方空白模板(用户入口) |
| test/test-xetex-undergraduate.tex | 本科变体回归测试 |
| test/test-xetex-graduate.tex | 研究生变体回归测试 |
| llmdoc/reference/file-map.md | 仓库全部文件的信任层级清单 |
| llmdoc/overview/project-overview.md | 项目概览与技术栈 |
总结:单源文件不是炫技,而是同步机制
回到开头的"之谜":NJUThesis 选择 dtx 单源 + l3build,本质上是把文档同步问题转换成了工程约定——代码旁即文档,生成文件永不手改,l3build 一条命令完成提取、安装、测试、打包。对写论文的同学,你只需用户 zip 和一条latexmk -xelatex;而对维护者,这套工作流保证了"改一处、处处生效"。理解了 docstrip 的标签提取和 l3build 的命令分工,你就看懂了本项目最核心的架构决策。
祝编译顺利!Happy TeXing ✨
【免费下载链接】NJUThesis南京大学学位论文模板项目地址: https://gitcode.com/gh_mirrors/nj/NJUThesis
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考