texlive[62813] Master/texmf-dist: njuthesis (18mar22)

commits+karl at tug.org commits+karl at tug.org
Sat Mar 19 21:03:43 CET 2022


Revision: 62813
          http://tug.org/svn/texlive?view=revision&revision=62813
Author:   karl
Date:     2022-03-19 21:03:43 +0100 (Sat, 19 Mar 2022)
Log Message:
-----------
njuthesis (18mar22)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/njuthesis/README.md
    trunk/Master/texmf-dist/doc/latex/njuthesis/njuthesis.pdf
    trunk/Master/texmf-dist/source/latex/njuthesis/njuthesis.dtx
    trunk/Master/texmf-dist/source/latex/njuthesis/njuthesis.ins
    trunk/Master/texmf-dist/tex/latex/njuthesis/njuthesis.cls

Added Paths:
-----------
    trunk/Master/texmf-dist/tex/latex/njuthesis/njuthesis-graduate.def
    trunk/Master/texmf-dist/tex/latex/njuthesis/njuthesis-undergraduate.def

Modified: trunk/Master/texmf-dist/doc/latex/njuthesis/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/njuthesis/README.md	2022-03-19 20:03:25 UTC (rev 62812)
+++ trunk/Master/texmf-dist/doc/latex/njuthesis/README.md	2022-03-19 20:03:43 UTC (rev 62813)
@@ -11,7 +11,7 @@
 
 A minimal example of this document class should look like
 
-```
+```LaTeX
 \documentclass{njuthesis}
 \njusetup{}
 \begin{document}

Modified: trunk/Master/texmf-dist/doc/latex/njuthesis/njuthesis.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/source/latex/njuthesis/njuthesis.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/njuthesis/njuthesis.dtx	2022-03-19 20:03:25 UTC (rev 62812)
+++ trunk/Master/texmf-dist/source/latex/njuthesis/njuthesis.dtx	2022-03-19 20:03:43 UTC (rev 62813)
@@ -20,6 +20,8 @@
 % This work consists of the files njuthesis.dtx,
 %           and the derived files njuthesis.ins,
 %                                 njuthesis.cls,
+%                                 njuthesis-undergraduate.def,
+%                                 njuthesis-graduate.def,
 %                                 njuthesis.pdf,
 %                             and README.md.
 %
@@ -71,10 +73,12 @@
 
 \generate{
   \usedir{tex/latex/njuthesis}
-    \file{\jobname.cls}        {\from{\jobname.dtx}{class}}
+    \file{\jobname.cls}               {\from{\jobname.dtx}{class}}
+    \file{\jobname-undergraduate.def} {\from{\jobname.dtx}{definition-ug}}
+    \file{\jobname-graduate.def}      {\from{\jobname.dtx}{definition-g}}
 %<*internal>
   \usedir{source/latex/njuthesis}
-    \file{\jobname.ins}        {\from{\jobname.dtx}{install}}
+    \file{\jobname.ins}               {\from{\jobname.dtx}{install}}
 %</internal>
 }
 
@@ -87,6 +91,8 @@
 \Msg{* The recommended directory is TDS:tex/latex/njuthesis      *}
 \Msg{*                                                           *}
 \Msg{*     njuthesis.cls                                         *}
+\Msg{*     njuthesis-graduate.def                                *}
+\Msg{*     njuthesis-undergraduate.def                           *}
 \Msg{*     njuthesis.ins                                         *}
 \Msg{*                                                           *}
 \Msg{* To produce the documentation, run the file njuthesis.dtx  *}
@@ -104,22 +110,30 @@
 %</internal>
 %
 %<class>\NeedsTeXFormat{LaTeX2e}
-%<class>\RequirePackage{expl3}
-%<class>\GetIdInfo $Id: njuthesis.dtx 0.15.0 2022-02-20 10:30:00 +0800 NJU LUG <git+nju-lug-email-3104-issue- at yaoge123.cn>$
+%<*!(driver|install)>
+%<+!driver>\GetIdInfo $Id: njuthesis.dtx 0.16.0 2022-03-19 12:00:00 +0800 NJU LUG <git+nju-lug-email-3104-issue- at yaoge123.cn>$
 %<class>  {Thesis template for Nanjing University}
 %<class>\ProvidesExplClass{njuthesis}
-%<class>  {\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+%<definition-ug>  {Undergraduate definition file for njuthesis}
+%<definition-ug>\ProvidesExplFile{njuthesis-undergraduate.def}
+%<definition-g>  {Graduate definition file for njuthesis}
+%<definition-g>\ProvidesExplFile{njuthesis-graduate.def}
+%<!driver>  {\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+%</!(driver|install)>
 %
 %<*driver>
 \ProvidesFile{njuthesis.dtx}
-\documentclass{ctxdoc}
+\documentclass[fontset=fandol]{ctxdoc}
 \usepackage{listings,njuvisual,tabularray}
 \usepackage[firstpage=true]{background}
 \backgroundsetup{contents={\njuemblem[white!85!gray]{22cm}{!}},scale=1,angle=0,hshift=-4cm}
 \colorlet{at at guard}{njuviolet}
 \definecolor{olgreen}{HTML}{138a07}
+\definecolor{agrd}{HTML}{2E3191}
 \newcommand\olbutton[1]{\textcolor{olgreen}{\bfseries #1}}
-\newcommand\grd[1]{\textcolor{at at guard}{\sffamily #1}}
+\newcommand\agrd[1]{\textcolor{agrd}{\sffamily 〈#1〉}}
+\newcommand\bgrd[1]{\textcolor{at at guard}{\sffamily #1}}
+\newcommand\tikzlogo{Ti\emph{k}Z}
 \hypersetup{%
   pdftitle  = {The njuthesis class - LaTeX thesis template for Nanjing University},
   citecolor = njublue,
@@ -183,7 +197,7 @@
 % 南京大学 Linux 用户组
 % \thanks{E-mail: \href{mailto:git+nju-lug-email-3104-issue- at yaoge123.cn}{git+nju-lug-email-3104-issue- at yaoge123.cn}}}
 %
-% \date{v0.15.0 \quad 2022-02-20}
+% \date{v0.16.0 \quad 2022-03-19}
 %
 % \changes{v0.1}{2021/09/04}{开始开发。}
 % \changes{v0.2}{2021/09/07}{初步搭建了可用的模板。}
@@ -206,6 +220,7 @@
 % \changes{v0.13}{2021/12/12}{优化了编译速度。}
 % \changes{v0.13}{2021/12/15}{适配2022届本科生毕业毕业论文(设计)规范。}
 % \changes{v0.14}{2022/01/13}{将本模板内嵌入南大 \hologo{TeX} 网站。}
+% \changes{v0.16}{2022/03/01}{分离本科生和研究生模板配置。}
 %
 %
 % \maketitle
@@ -327,7 +342,7 @@
 % \end{itemize}
 %
 %
-% \subsection{君 \hologo{LaTeX} 本当上手}
+% \subsection{快速上手}
 %
 % \hologo{LaTeX} 并不是一种零门槛的语言,亦不是南京大学学生的必备技能。有同学听
 % 到“\emph{给毕业论文交差也得写代码}”这种事情就头疼,实在是我们不愿意见到而必须
@@ -413,29 +428,33 @@
 %
 % \subsubsection{文件构成}
 %
-% 本模板由数量众多的文件组成,\emph{所有可能遇到的}文件如表 \ref{tab:njuthesisfiles} 所示。
-% 其中标注为黄色的内容仅供开发使用,并不会在发行版中出现。
+% 本模板由数量众多的文件组成,\emph{所有可能遇到的}文件如表 \ref{tab:njuthesis-files} 所示。
 %
 % \begin{table}[ht]
-%   \caption{\cls{njuthesis}文件构成}
-%   \label{tab:njuthesisfiles}
 %   \centering
-%   \begin{tabular}{lp{18em}}
+%   \begin{talltblr}[
+%     caption = {\cls{njuthesis}文件构成},
+%     label = {tab:njuthesis-files},
+%     note{a} = {仅供开发使用,并不会在发布版本中出现。}
+%   ] {ll}
 %     \toprule
-%     名称                                  & 说明                             \\
+%     名称                               & 说明                             \\
 %     \midrule
-%     \file{.vscode}                        & Visual Studio Code 配置文件      \\
-%     \file{latexmkrc}                      & latexmk 配置文件                 \\
-%     \file{LICENSE}                        & 许可证                           \\
-%     \file{njuthesis.cls}                  & 模板文档类                       \\
-%     \color{njuyellow}\file{njuthesis.dtx} & 文档类源代码                     \\
-%     \color{njuyellow}\file{njuthesis.ins} & 文档类安装脚本                   \\
-%     \file{njuthesis.pdf}                  & 用户手册(本文档)               \\
-%     \file{njuthesis-sample.bib}           & 示例参考文献列表                 \\
-%     \file{njuthesis-sample.tex}           & 示例文档,不妨以此为基础撰写论文 \\
-%     \file{README.md}                      & 自述文件                         \\
+%     \file{.vscode}                     & Visual Studio Code 配置文件      \\
+%     \file{CHANGELOG.md}                & 修订记录                         \\
+%     \file{latexmkrc}                   & \pkg{latexmk} 配置文件           \\
+%     \file{LICENSE}                     & 许可证                           \\
+%     \file{njuthesis.cls}               & 模板文档类                       \\
+%     \file{njuthesis.dtx}\TblrNote{a}   & 文档类源代码                     \\
+%     \file{njuthesis.ins}\TblrNote{a}   & 文档类安装脚本                   \\
+%     \file{njuthesis.pdf}               & 用户手册(本文档)               \\
+%     \file{njuthesis-sample.bib}        & 示例参考文献列表                 \\
+%     \file{njuthesis-sample.tex}        & 示例文档,不妨以此为基础撰写论文 \\
+%     \file{njuthesis-graduate.def}      & 研究生参数配置文件               \\
+%     \file{njuthesis-undergraduate.def} & 本科生参数配置文件               \\
+%     \file{README.md}                   & 自述文件                         \\
 %     \bottomrule
-%   \end{tabular}
+%   \end{talltblr}
 % \end{table}
 %
 %
@@ -505,7 +524,7 @@
 %     \hologo{TeX}        & Windows   & macOS     & Linux     \\
 %     \midrule
 %     \hologo{TeX}\,Live  & $\bullet$ &           & $\bullet$ \\
-%     mac\hologo{TeX}     &           & $\bullet$ &           \\
+%     Mac\hologo{TeX}     &           & $\bullet$ &           \\
 %     \hologo{MiKTeX}     & $\bullet$ & $\bullet$ & $\bullet$ \\
 %     \bottomrule
 %   \end{tabular}
@@ -555,14 +574,15 @@
 % 下命令顺序进行编译,以生成内容正确的 \file{njuthesis-sample.pdf}。输出的 PDF
 % 文档位于同一目录下。该目录下同时会生成若干中间文件。
 %
-% 编译命令具体为引擎名称加主文件名,在编译 \file{.tex} 文件时,文件扩展名可以省略
-% 不写。现阶段 \cls{njuthesis} 仅支持 \hologo{XeLaTeX} 与 \hologo{LuaLaTeX}。请
-% 注意,几种命令的输出文件基本相同,可以任取一种;但如果您不清楚这两种编译引擎的
+% 编译命令具体为引擎名称加主文件名,在编译 \file{.tex} 文件时,
+% 文件扩展名可以省略不写。现阶段 \cls{njuthesis} 仅支持 \hologo{XeTeX}
+% 与 \hologo{LuaTeX} 引擎,以及 \hologo{biber} 文献工具。请注意,
+% 几种命令的输出文件基本相同,可以任取一种;但如果您不清楚这两种编译引擎的
 % 区别,或者对多步编译感到困惑,我们建议优先使用 |latexmk -xelatex|。
 %
 %
 % \subparagraph{使用 \hologo{XeLaTeX}}
-% 标准的 \hologo{XeLaTeX} 引擎四步编译方法。
+% 标准的 \hologo{XeTeX} 引擎四步编译方法。
 %
 % \begin{shellexample}[morekeywords={xelatex,biber}]
 %   xelatex njuthesis-sample
@@ -573,7 +593,7 @@
 %
 %
 % \subparagraph{使用 \hologo{LuaLaTeX}}
-% 标准的 \hologo{LuaLaTeX} 引擎四步编译方法。
+% 标准的 \hologo{LuaTeX} 引擎四步编译方法。
 %
 % \begin{shellexample}[morekeywords={lualatex,biber}]
 %   lualatex njuthesis-sample
@@ -594,7 +614,9 @@
 % \begin{shellexample}[morekeywords={latexmk}]
 %   latexmk njuthesis-sample
 % \end{shellexample}
-% 直接运行会调用 \hologo{pdfLaTeX} 引擎导致报错。如需指定编译引擎,可以加入 |-xelatex| 或 |-lualatex| 参数,例如指定 \hologo{XeLaTeX} 的命令为
+% 直接运行会调用 \hologo{pdfLaTeX} 引擎导致报错。
+% 如需指定编译引擎,可以加入 |-xelatex| 或 |-lualatex| 参数。
+% 例如,指定 \hologo{XeLaTeX} 的命令为
 % \begin{shellexample}[morekeywords={latexmk},emph={-xelatex}]
 %   latexmk -xelatex njuthesis-sample
 % \end{shellexample}
@@ -750,15 +772,29 @@
 % \end{itemize}
 % 草稿模式有助于提升编译速度以及检查格式问题,建议在定稿前始终开启。
 %
-% 启用这一选项也会改变特定宏包的行为,譬如在草稿模式下 \pkg{listings} 宏包的代码环境不会显示内容,具体效果需要参照各个宏包的说明文档。如需抵消草稿模式的影响,请使用 \opt{final} 选项载入相关宏包。
+% 启用这一选项也会改变特定宏包的行为,譬如在草稿模式下 \pkg{listings}
+% 宏包的代码环境不会显示内容,具体效果需要参照各个宏包的说明文档。
+% 如需抵消草稿模式的影响,请使用 \opt{final} 选项载入相关宏包。
 %
 %
+% \subsubsection{配置文件}
+%
+% \begin{function}[added=2022-02-23]{config}
+%   \begin{syntax}
+%     config = \Arg{文件}
+%   \end{syntax}
+% 配置文件路径。
+% \end{function}
+%
+% 本选项可用于载入额外的用户配置文件。该文件支持 \hologo{LaTeX3} 语法。
+%
+%
 % \subsubsection{指定字体}
 %
-% 学校论文格式要求使用的字体一般已经预装在各个操作系统,本模板针对不同平台进行了自动检测适配,可以开箱即用。
+% 学校论文格式要求使用的字体一般已经预装在各个操作系统,
+% 本模板针对不同平台进行了自动检测适配,可以开箱即用。
+% 如果希望更改本模板使用的字体,请填写以下两个选项以覆盖默认设置。
 %
-% 如果希望更改本模板使用的字体,请填写以下两个选项以覆盖操作系统检测得到的设置。
-%
 % \begin{function}[added=2021-09-07,updated=2021-12-18]{cjk-font,latin-font}
 %   \begin{syntax}
 %     cjk-font = <win|mac|fandol|founder|noto|source|none>
@@ -1049,8 +1085,6 @@
 %   \cs{mainmatter} 标志着正文的开始,使用阿拉伯数字重新进行页码编号,并设置页眉格式。
 % \end{function}
 %
-% 在页面布局方面,页面编号居中位于页脚,本科生无页眉,研究生页眉包括章名(奇数页)和节名(偶数页)。
-%
 % \begin{function}{\chapter,\section,\subsection,\subsubsection}
 %   \begin{syntax}
 %     \tn{chapter}\oarg{短描述}\marg{完整的章标题}
@@ -1058,12 +1092,68 @@
 %     \tn{subsection}\oarg{短描述}\marg{完整的节标题}
 %     \tn{subsection}\oarg{短描述}\marg{完整的节标题}
 %   \end{syntax}
-% \pkg{ctex} 宏集提供了其中用于处理长标题的可选参数。对于过长的标题,目录中会使用其短描述。
+% 对于过长的标题,目录和页眉中会使用其短描述。
 % \end{function}
 %
 %
+% \subsubsection{页面}
+%
+% 在本模板预定义的页面样式中:本科生使用 \opt{plain} 样式,无页眉,
+% 页面编号使用五号罗马体,居中位于页脚;研究生使用 \opt{headings} 样式,
+% 页眉使用五号楷体,包括章名(奇数页右侧)和节名(偶数页左侧),
+% 页面编号使用五号罗马体,居中位于页脚。在单面模式下,页眉会同时显示章节名。
+%
+% 考虑到各个院系对于页眉内容的规定并不一致,本模板提供了若干个自定义选项。
+%
+% \begin{function}{style/header/format,style/footer/format,
+%   style/header,style/header*,style/footer,style/footer*}
+%   \begin{syntax}
+%     header/format = \Arg{格式}
+%     footer/format = \Arg{格式}
+%     header  = \{\Arg{位置}\Arg{内容},\Arg{位置}\Arg{内容},...\}
+%     header* = \{\Arg{位置}\Arg{内容},\Arg{位置}\Arg{内容},...\}
+%     footer  = \{\Arg{位置}\Arg{内容},\Arg{位置}\Arg{内容},...\}
+%     footer* = \{\Arg{位置}\Arg{内容},\Arg{位置}\Arg{内容},...\}
+%   \end{syntax}
+% 页眉页脚的格式与内容设置。带有星号的设置项供单面模式下使用。
+% \end{function}
+%
+% 页眉页脚的内容设置是一个逗号分隔的列表,实际上是 \cs{fancyhead} 和
+% \cs{fancyfoot} 命令的选项。前一个花括号内为大写字母指定的位置选项,
+% 可使用左(\opt{L})、中(\opt{C})、右(\opt{R})。
+% 双面模式下可额外指定出现在奇数页(\opt{O})还是偶数页(\opt{E})。
+% 详细说明请参考 \pkg{fancyhdr} 的手册。
+%
+% 接下来展示了一个手动设置页眉内容的例子。这里我们清空了页脚,
+% 并将页眉格式设置成五号黑体,奇数页左侧为节名,右侧为页码,
+% 偶数页左侧为页码,右侧为章名。
+% \begin{latexexample}[moretexcs={\njusetup,\sffamily},emph={[2]style}]
+%   \njusetup {
+%       style = {
+%           header/format = \small \sffamily,
+%           header = {
+%               { OR } { \thepage }, { OL } { \rightmark },
+%               { EL } { \thepage }, { ER } { \leftmark  }
+%             },
+%           footer = {},
+%         }
+%     }
+% \end{latexexample}
+%
+%
 % \subsubsection{文字}
 %
+% \begin{function}{\songti,\heiti,\kaishu,\fangsong,\zihao}
+%   \begin{syntax}
+%     \tn{zihao}\Arg{字号}
+%   \end{syntax}
+% 字形与字号设置。
+% \end{function}
+%
+% 本模板继承 \pkg{ctex} 宏集提供的字形字号设置,以备不时之需。换句话说,
+% 除非你有十足的把握,认为某处字体产生了偏差\footnote{在此情况下也应当直接到
+% GitHub 反馈},否则无需动用这些命令处理样式问题。
+%
 % \begin{function}[added=2021-09-22]{\njuline}
 %   \begin{syntax}
 %     \tn{njuline}\Arg{文字}
@@ -1191,12 +1281,8 @@
 %
 % \subsubsection{数学}
 %
-% 符号表可以参考 \url{https://www.caam.rice.edu/~heinken/latex/symbols.pdf}。
+% 行内公式形如 |$\mathrm{e}^{(a+2b)x}$|。
 %
-% 单位请参考相关国家标准\footnote{GB 3100-1993, GB/T 3101-1993, GB/T 3102-1993},使用 \pkg{siunitx} 宏包。\pkg{siunitx} 是一个更新频繁的包,可能会引发兼容性问题。
-%
-% 行内公式形如|$\mathrm{e}^{(a+2b)x}$|。
-%
 % 带有编号的行间公式 \env{equation}。
 % \begin{latexexample}[emph={[1]equation}]
 %   \begin{equation}\label{eq:myeqlabel}
@@ -1204,9 +1290,22 @@
 %   \end{equation}
 % \end{latexexample}
 %
-% 如不需要编号,可以用 \env{equation*} 或者 |\[|\meta{公式}|\]|,请不要使用可能引发问题的 |$$|\meta{公式}|$$|\footnote{\url{https://tex.stackexchange.com/questions/503/why-is-preferable-to}}。
+% 如不需要编号,可以用 \env{equation*} 或者 |\[|\meta{公式}|\]|,
+% 请不要使用可能引发问题的 |$$|\meta{公式}|$$|\footnote{\url{https://tex.stackexchange.com/questions/503/why-is-preferable-to}}。
 %
 %
+% \paragraph{符号和单位}
+%
+% 模板使用 \pkg{unicode-math} 配置数学字体,可以替代传统方案下的 \pkg{bm}、
+% \pkg{mathrsfs} 等宏包\footnote{\url{https://tex.stackexchange.com/questions/528831/why-doesnt-the-bm-package-work-with-the-unicode-math-package}}。
+% 相应地,也需要使用新方案提供的命令。例如,加粗数学符号的命令可以使用
+% \tn{symbf}。更多细节请查阅 \pkg{unicode-math} 手册。
+%
+% 符号表可以参考 \url{https://www.caam.rice.edu/~heinken/latex/symbols.pdf}。
+%
+% 单位请参考相关国家标准\footnote{GB 3100-1993, GB/T 3101-1993, GB/T 3102-1993},使用 \pkg{siunitx} 宏包。\pkg{siunitx} 是一个更新频繁的包,可能会引发兼容性问题。
+%
+%
 % \paragraph{定理环境}
 %
 % 本模板也提供了一系列的数学定理环境。
@@ -1229,13 +1328,11 @@
 % \end{table}
 %
 % 使用示例如下。
-% \begin{latexexample}
+% \begin{latexexample}[emph={[1]proof,definition}]
 %   \begin{proof}
 %       证明我是我
 %   \end{proof}
-% \end{latexexample}
-% 普通环境。
-% \begin{latexexample}
+%
 %   \begin{definition}[他人]
 %       定义他人即地狱
 %   \end{definition}
@@ -1462,16 +1559,20 @@
 %
 % 参考文献数据源理应是通过文献管理软件导出的,而不是逐条手动填写的。
 %
-% \subparagraph{使用EndNote}
+% \subparagraph{使用 EndNote}
 %
 % 南京大学信息化建设管理服务中心已购买 \href{https://itsc.nju.edu.cn/EndNote/list.htm}{EndNote} 供全校师生免费使用,最新版为 EndNote 20。
 %
+% \subparagraph{使用 JabRef}
 %
-% \subparagraph{使用Zotero}
+% \href{https://www.jabref.org/}{jabRef} 是一款开源、跨平台的文献管理软件。
+% JabRef 提供了对 \hologo{BibTeX} 和 \pkg{biblatex} 的原生支持,
+% 能够直接管理 \file{.bib} 文件, 还可以向 TeXstudio 等外部软件推送引用命令。
 %
-% \href{https://www.zotero.org/}{Zotero}是一款免费的文献管理软件,支持所有桌面平台。
+% \subparagraph{使用 Zotero}
 %
-% 在保持 Zotero 程序运行的情况下,点击浏览器工具栏的 Zotero Connector 插件即可自动从网页抓取参考文件信息。Zotero 可以通过\href{https://github.com/l0o0/jasminum}{jasminum插件}支持中文参考文献的识别。在选中希望使用的文献后右键导出文献条目即可生成 \file{.bib} 文件。
+% \href{https://www.zotero.org/}{Zotero} 也是一款开源、跨平台的文献管理软件。
+% Zotero 更为通用,其功能可以通过 \href{https://github.com/l0o0/jasminum}{Jasminum}、\href{https://github.com/retorquere/zotero-better-bibtex}{Better BibTeX}、\href{https://github.com/bwiernik/zotero-shortdoi}{DOI Manager} 等第三方插件,以及 Zotero Connector 浏览器插件进行增强。
 %
 %
 % \subsection{特殊页面}
@@ -1492,23 +1593,18 @@
 %
 % \paragraph{封面图片}
 %
-% \begin{function}[added=2021-12-23]{style/emblem-img}
+% \begin{function}[added=2021-12-23,updated=2022-02-22]{
+%   style/emblem-img,style/name-img}
 %   \begin{syntax}
 %     emblem-img = \Arg{文件}
-%   \end{syntax}
-% 校徽图片文件。
-% \end{function}
-%
-% \begin{function}[added=2021-12-23]{style/name-img}
-%   \begin{syntax}
 %     name-img = \Arg{文件}
 %   \end{syntax}
-% 校名图片文件。
+% 校名、校徽图片文件路径。
 % \end{function}
 %
-% 通过以上两个选项可以使用外置的校徽和校名图片。本模板封面中校徽及校名的绘制
-% 默认依赖 \pkg{njuvisual} 宏包提供的 \pkg{tikz} 矢量曲线,耗时较长,
-% 在替换为外置图片后可节省约1秒的编译时长。
+% 通过以上选项可以使用外置的校徽和校名图片,两个选项\emph{任一留空}则不会生效。
+% 本模板封面中校徽及校名的绘制默认依赖 \pkg{njuvisual} 宏包提供的 \tikzlogo
+% 矢量曲线,耗时较长,在替换为外置图片后可节省约1秒的编译时长。
 %
 %
 % \subsubsection{摘要页}
@@ -1660,6 +1756,54 @@
 % 本宏包的详细使用方法请参考其使用手册。
 %
 %
+% \section{宏包依赖}
+%
+% 在任何情况下,本模板都会\emph{显式}调用以下宏包(或文档类):
+% \begin{itemize}
+%   \item \pkg{xtemplate} 和 \pkg{l3keys2e},用于扩展 \hologo{LaTeX3} 编程环境。
+%         它们属于 \pkg{l3packages} 宏集。
+%   \item \cls{ctexbook},提供中文排版的通用框架。属于 C\hologo{TeX}
+%         宏集 \cite{CTeX}。
+%   \item \pkg{mathtools},增强数学功能。
+%   \item \pkg{unicode-math},负责处理 Unicode 编码的 OpenType 数学字体。
+%   \item \pkg{geometry},用于调整页面尺寸。
+%   \item \pkg{setspace},调整行距。
+%   \item \pkg{fancyhdr},处理页眉页脚。
+%   \item \pkg{footmisc},处理脚注。
+%   \item \pkg{ntheorem},提供增强版的定理类环境。
+%   \item \pkg{enumitem},调整列表环境。
+%   \item \pkg{graphicx},提供图形插入的接口。
+%   \item \pkg{booktabs},绘制三线表。
+%   \item \pkg{caption},用于设置题注。
+%   \item \pkg{hyperref},提供交叉引用、超链接、电子书签等功能。
+%   \item \pkg{cleveref},用于自动生成引用标签。
+%   \item \pkg{biblatex},提供参考文献解决方案。
+% \end{itemize}
+%
+% 以下宏包可能被隐式载入:
+% \begin{itemize}
+%   \item \pkg{xcolor},提供色彩支持。
+%   \item \pkg{amsmath},对 \LaTeX{} 的数学排版功能进行了
+%         全面扩展。属于 \hologo{AmSLaTeX} 套件。
+%   \item \pkg{biblatex-gb7714-2015},用于生成国标下的参考文献样式。
+%   \item \pkg{xits},提供数学字体。
+% \end{itemize}
+%
+% 在开启某些选项时,本模板也会调用以下宏包:
+% \begin{itemize}
+%   \item \pkg{fandol}、\pkg{tex-gyre} 和 \pkg{tex-gyre-math},提供自由字体。
+%   \item \pkg{emptypage},在双面模式下清空空白页的页眉、页脚和页码。
+%   \item \pkg{njuvisual},用于绘制封面的校名校徽。
+%   \item \pkg{xeCJKfntef} 或 \pkg{lua-ul},用于在对应引擎下绘制下划线。
+% \end{itemize}
+%
+% 下列宏包会与本模板产生冲突,或者不能发挥预期作用:
+% \begin{itemize}
+%   \item \pkg{natbib} 和 \pkg{gbt7714} 等 \hologo{BibTeX} 相关的参考文献宏包。
+%   \item \pkg{bm} 等使用传统数学字体配置方案的宏包。
+% \end{itemize}
+%
+%
 % \begin{thebibliography}{99}
 %
 % \newcommand\urlprefix{\newline\hspace*{\fill}}
@@ -1743,6 +1887,14 @@
 % \urlprefix\url{https://ctan.org/pkg/biblatex-gb7714-2015}
 % \urlprefix\CTANurl[文档:]{biblatex-contrib/biblatex-gb7714-2015/biblatex-gb7714-2015.pdf}
 %
+% \bibitem{CTeX}
+% \textsc{CTEX.ORG}.
+% \newblock \textit{\CTeX{} 宏集手册} [EB/OL].
+% \newblock version 2.5.8,
+% \newblock (2021-12-12)
+% \urlprefix\url{https://ctan.org/pkg/ctex}
+% \urlprefix\CTANurl[文档及源代码:]{language/chinese/ctex/ctex.pdf}
+%
 % \bibitem{latexmk}
 % \textsc{Collins J}.
 % \newblock \textit{Fully automated \hologo{LaTeX} document generation} [EB/OL].
@@ -1872,15 +2024,15 @@
 % 本模板使用 \hologo{LaTeX3} 语法编写,依赖 \pkg{expl3} 环境,
 % 并需调用 \pkg{l3packages} 中的相关宏包。
 %
-% 以下代码中有一些形如 \textsf{\color{guard at series!!}〈*class〉}
-% 的标记,这是 \pkg{DocStrip} 中的“guard”,用来选择性地提取文件。
+% 以下代码中有一些形如 \agrd{*class} 的标记,
+% 这是 \pkg{DocStrip} 中的“guard”,用来选择性地提取文件。
 % “|*|”和“|/|”分别表示该部分的开始和结束。不含
 % “|*|”和“|/|”的 guard 出现在行号右侧,它们用来确定
 % 单独一行代码的归属。这些 guard 的颜色深浅不一,用以明确嵌套关系。
 %
-% 另有若干包含 \grd{@@} 的 guard,用以表示名空间(模块)。
+% 另有若干包含 \bgrd{@@} 的 guard,用以表示名空间(模块)。
 % 在删除注释生成格式文件时,源代码变量名称中的 |@@| 会被等号后的字段替换,
-% 譬如在本模板中 \grd{〈@@=nju〉}。
+% 譬如在本模板主体部分中 \bgrd{〈@@=nju〉}。
 %
 %
 % \subsection{准备}
@@ -1898,10 +2050,9 @@
 \msg_new:nnn { njuthesis } { l3-too-old }
   {
     Package~ "#1"~ is~ too~ old. \\
-    Please~ update~ an~ up-to-date~ version~ of~
-    the~ bundles "l3kernel"~ and~ "l3packages"~
-    using~ your~ TeX~ package~ manager~ or~ from~ \\
-    CTAN.
+    Please~ update~ an~ up-to-date~ version~ of~ the~
+    bundles~ "l3kernel"~ and~ "l3packages"~ using~
+    your~ TeX~ package~ manager~ or~ from~ CTAN.
   }
 \clist_map_inline:nn { xtemplate, l3keys2e }
   {
@@ -1908,7 +2059,6 @@
     \@ifpackagelater {#1} { 2020/10/01 }
       { } { \msg_error:nnn { njuthesis } { l3-too-old } {#1} }
   }
-
 %    \end{macrocode}
 %
 % 目前 \cls{njuthesis} 仅支持 \hologo{XeTeX} 和 \hologo{LuaTeX}。
@@ -1921,14 +2071,10 @@
     You~ must~ change~ your~ typesetting~ engine~
     to~ "xelatex"~ or~ "lualatex".
   }
-\sys_if_engine_xetex:F
-  {
-    \sys_if_engine_luatex:F
-      {
-        \msg_fatal:nnx { njuthesis } { unsupported-engine }
-          { \c_sys_engine_str }
-      }
-  }
+\bool_lazy_or:nnF
+  { \sys_if_engine_xetex_p:  }
+  { \sys_if_engine_luatex_p: }
+  { \msg_fatal:nnx { njuthesis } { unsupported-engine } { \c_sys_engine_str } }
 %    \end{macrocode}
 %
 %
@@ -1949,13 +2095,13 @@
 %    \end{macrocode}
 % \end{variable}
 %
-% \begin{variable}{\l_@@_info_degree_int,
-%   \l_@@_info_diploma_int,\l_@@_info_type_int}
+% \begin{variable}{\g_@@_info_degree_int,
+%   \l_@@_info_diploma_int,\g_@@_info_type_int}
 % 用于存储学位类型的变量。
 %    \begin{macrocode}
-\int_new:N \l_@@_info_degree_int
+\int_new:N \g_@@_info_degree_int
 \int_new:N \l_@@_info_diploma_int
-\int_new:N \l_@@_info_type_int
+\int_new:N \g_@@_info_type_int
 %    \end{macrocode}
 % \end{variable}
 %
@@ -1992,22 +2138,30 @@
 %    \end{macrocode}
 % \end{variable}
 %
-% \begin{variable}{\g_@@_load_sys_font_bool}
-% 定义用于判断是否需要载入系统预装字体的变量。
+% \begin{variable}{\g_@@_latin_font_tl,\g_@@_cjk_font_tl}
+% 用于存储所使用字体名称的全局变量。
 %    \begin{macrocode}
-\bool_new:N \g_@@_load_sys_font_bool
+\tl_new:N \g_@@_latin_font_tl
+\tl_new:N \g_@@_cjk_font_tl
 %    \end{macrocode}
 % \end{variable}
 %
-% \begin{variable}{\g_@@_latin_font_tl,\g_@@_cjk_font_tl}
-% 用于存储所使用字体名称的全局变量
+% \begin{variable}{\g_@@_config_tl}
+% 保存配置文件名称。默认为空。
 %    \begin{macrocode}
-\tl_new:N \g_@@_latin_font_tl
-\tl_new:N \g_@@_cjk_font_tl
+\tl_new:N \g_@@_config_tl
 %    \end{macrocode}
 % \end{variable}
 %
-% \begin{variable}{\l_@@_info_sm_date_tl,\l_@@_info_sm_date_en_tl,\l_@@_info_df_date_tl}
+% \begin{variable}{\g_@@_theorem_type_clist}
+% 定理类型。
+%    \begin{macrocode}
+\clist_new:N \g_@@_theorem_type_clist
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_info_sm_date_tl,\l_@@_info_sm_date_en_tl,
+% \l_@@_info_df_date_tl}
 % 用于存储格式化后的论文提交日期和答辩日期的变量。
 %    \begin{macrocode}
 \tl_new:N \l_@@_info_sm_date_tl
@@ -2074,7 +2228,8 @@
 % \end{macro}
 %
 % \begin{macro}{\@@_vskip:N}
-% 类似于 \hologo{LaTeX2e} 中的 \tn{vspace*},从上一个页面元素底部开始生成 |skip|。
+% 类似于 \hologo{LaTeX2e} 中的 \tn{vspace*},
+% 从上一个页面元素底部开始生成 |skip|。
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_vskip:N #1
   {
@@ -2099,6 +2254,17 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}{\@@_add_theorem_type:nnn}
+% 添加已知的定理环境类型。
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_add_theorem_type:nnn #1#2#3
+  {
+    \clist_gput_right:Nn \g_@@_theorem_type_clist { #1 }
+    \@@_define_name:nnn { #1 } { #2 } { #3 }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}{\@@_name:n,\@@_info:n}
 % 根据变量名调用名称和内容信息。
 %    \begin{macrocode}
@@ -2124,7 +2290,7 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_spread_box:nnn}
+% \begin{macro}{\@@_spread_box:nnn,\@@_spread_box:nnV,\@@_spread_box:nnx}
 % 分散对齐的水平盒子。
 % \begin{arguments}
 %   \item 宽度,|dim| 型变量
@@ -2132,13 +2298,14 @@
 %   \item 内容,不可带有格式
 % \end{arguments}
 %    \begin{macrocode}
-\cs_generate_variant:Nn \tl_map_inline:nn { xn }
 \cs_new_protected:Npn \@@_spread_box:nnn #1#2#3
   {
     \mode_leave_vertical:
     \hbox_to_wd:nn { #1 }
-      { #2 \tl_map_inline:xn { #3 } { ##1 \hfil } \unskip }
+      { #2 \tl_map_inline:nn { #3 } { ##1 \hfil } \unskip }
   }
+\cs_generate_variant:Nn \@@_spread_box:nnn { nnV }
+\cs_generate_variant:Nn \@@_spread_box:nnn { nnx }
 %    \end{macrocode}
 % \end{macro}
 %
@@ -2299,7 +2466,287 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \subsubsection{封面相关}
+% \changes{v0.16}{2022/03/10}{将封面和摘要内部函数定义移动到前部。}
 %
+% \begin{macro}{\@@_split_title:n,\@@_split_title:V}
+% 分割标题。
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_split_title:n #1
+  {
+    \tl_if_in:nnTF { #1 } { \\ }
+      {
+%    \end{macrocode}
+% 从 |\\| 进行分割,存入 |clist|。
+%    \begin{macrocode}
+        \seq_set_split:Nnn \l_@@_tmp_seq { \\ } { #1 }
+        \clist_set_from_seq:NN \l_@@_tmp_clist \l_@@_tmp_seq
+      }
+      {
+%    \end{macrocode}
+% 如果没找到换行符,则手动从固定宽度的位置进行分割。
+%    \begin{macrocode}
+        \@@_put_inempty_seg:nnn { #1 } { 1  } { 15 }
+        \@@_put_inempty_seg:nnn { #1 } { 16 } { 15 }
+        \@@_put_inempty_seg:nnn { #1 } { 31 } { 15 }
+      }
+  }
+\cs_generate_variant:Nn \@@_split_title:n { V }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_multiline_title:nnn}
+% 生成多行标题。
+% \begin{arguments}
+%   \item 内容格式
+%   \item 名称盒子宽度,|dim| 型变量
+%   \item 内容盒子宽度,|dim| 型变量
+% \end{arguments}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_multiline_title:nnn #1#2#3
+  {
+    \@@_split_title:V \l_@@_info_title_tl
+    \@@_spread_box:nnV { #2 } { \kaishu } \c_@@_name_title_tl
+    \@@_hskip:
+    \clist_map_inline:Nn \l_@@_tmp_clist
+      { \@@_ulined_center_box:nn { #3 } { #1 ##1 } \@@_vskip: }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_cover_entry:nnn}
+% 生成单项信息条目。
+% \begin{arguments}
+%   \item 条目名称
+%   \item 名称盒子宽度,|dim| 型变量
+%   \item 内容盒子宽度,|dim| 型变量
+% \end{arguments}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_cover_entry:nnn #1#2#3
+  {
+    \@@_spread_box:nnx { #2 } { \kaishu } { \@@_name:n { #1 } }
+    \@@_hskip:
+    \@@_ulined_center_box:nn { #3 }       { \@@_info:n { #1 } }
+    \@@_vskip:
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_cover_bientry:nnnn}
+% 生成两项信息条目,仅用于本科生封面。
+% \begin{arguments}
+%   \item 左侧条目名称
+%   \item 右侧条目名称
+%   \item 名称盒子宽度,|dim| 型变量
+%   \item 内容盒子宽度,|dim| 型变量
+% \end{arguments}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_cover_bientry:nnnn #1#2#3#4
+  {
+    \@@_spread_box:nnx { #3 } { \kaishu } { \@@_name:n { #1 } }
+    \@@_hskip:
+    \@@_ulined_center_box:nn { #4 }       { \@@_info:n { #1 } }
+    \skip_horizontal:n { 0.5 em }
+    \@@_spread_box:nnx { #3 } { \kaishu } { \@@_name:n { #2 } }
+    \@@_hskip:
+    \@@_ulined_center_box:nn { #4 }       { \@@_info:n { #2 } }
+    \@@_vskip:
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_cover_supv_entry:nnn}
+% 生成两项导师信息条目,仅用于本科生封面。
+% \begin{arguments}
+%   \item 条目名称
+%   \item 长内容盒子宽度,|dim| 型变量
+%   \item 短内容盒子宽度,|dim| 型变量
+% \end{arguments}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_cover_supv_entry:nnn #1#2#3
+  {
+    \@@_spread_box:nnx { #2 } { \kaishu } { \@@_name:n { #1 } }
+    \@@_hskip:
+    \@@_ulined_center_box:nn { #3 }
+      { \clist_item:cn { l_@@_info_ #1 _clist } { 1 } }
+    \skip_horizontal:n { 0.5 em }
+    \@@_spread_box:nnV { #2 } { \kaishu } \c_@@_name_supv_ttl_tl
+    \@@_hskip:
+    \@@_ulined_center_box:nn { #3 }
+      { \clist_item:cn { l_@@_info_ #1 _clist } { 2 } }
+    \@@_vskip:
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{摘要相关}
+%
+% \begin{macro}{\@@_abs_bookmark:nn,\@@_abs_bookmark:Vn}
+% \changes{v0.14}{2021/12/21}{将摘要插入目录。}
+% 生成摘要的目录条目。
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_abs_bookmark:nn #1#2
+  {
+    \phantomsection
+    \bool_if:NTF \g_@@_abs_in_toc_bool
+      { \@@_add_tocline:n { #1 } }
+      { \pdfbookmark [0] { #1 } { #2 } }
+    \@@_chapter_header:n { #1 }
+  }
+\cs_generate_variant:Nn \@@_abs_bookmark:nn { Vn }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_abs_title:n,\@@_abs_title:V}
+% 摘要标题双层下划线格式。
+% \begin{arguments}
+%   \item 宽度,|dim| 型变量
+% \end{arguments}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_abs_title:n #1
+  {
+    \@@_get_text_width:Nn \l_@@_tmp_dim {#1}
+    \@@_uuline:n { \l_@@_tmp_dim } #1
+  }
+\cs_generate_variant:Nn \@@_abs_title:n { V }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{页面对象}
+% \changes{v0.15}{2022/01/24}{使用 \pkg{xtemplate} 重构封面。}
+%
+% 本模板使用 \pkg{xtemplate} 提供的面向对象方法简化封面和摘要的绘制过程。
+%
+% 以下分别从页面元素(element)和页面整体(page)的层次进行了抽象。当我们把页面部件考虑为一个对象时,它天然地只具备有限数量的属性:内容、格式、边距、对齐方式等。而具体的页面是这些对象的实例的集合,附加边距、行距等属性,创建页面只需传入一个列表调用各个 Instance 即可。通过 \pkg{xtemplate} 提供的功能,我们可以根据这些属性创建模板(template),进而能大量构建具有\emph{相似行为}的实例(instance)。这种做法能充分分离内容和样式,极大优化代码的可读性。
+%
+% 声明对象类型。此类对象不需要参数。
+%    \begin{macrocode}
+\DeclareObjectType { nju } { \c_zero_int }
+%    \end{macrocode}
+%
+% 定义元素模板。
+%    \begin{macrocode}
+%<@@=njuelem>
+%    \end{macrocode}
+%
+% 声明页面元素模板接口。
+% 元素是一个页面的基本组成单位,包括文段、图片等等。一个抽象的元素应当具备以下属性:
+% \begin{description}
+%   \item[\opt{content}] 内容,即剥离样式的元素本身
+%   \item[\opt{format}] 格式,例如字号、字体
+%   \item[\opt{bottom-skip}] 下间距,即与下一个元素的距离
+%   \item[\opt{align}] 对齐方式,包括左对齐、右对齐、居中、正常段落
+% \end{description}
+%    \begin{macrocode}
+\DeclareTemplateInterface { nju } { element } { \c_zero_int }
+  {
+    content     : tokenlist = \c_empty_tl,
+    format      : tokenlist = \c_empty_tl,
+    bottom-skip : skip      = \c_zero_skip,
+    align       : choice { l, r, c, n } = c
+  }
+%    \end{macrocode}
+%
+% 声明页面元素模板代码。涉及的变量将被自动创建。
+%    \begin{macrocode}
+\DeclareTemplateCode { nju } { element } { \c_zero_int }
+  {
+    content     = \l_@@_content_tl,
+    format      = \l_@@_format_tl,
+    bottom-skip = \l_@@_bottom_skip,
+    align =
+      {
+        l =
+          { \tl_set_eq:NN \l_@@_begin_align_tl \flushleft
+            \tl_set_eq:NN \l_@@_end_align_tl   \endflushleft  },
+        r =
+          { \tl_set_eq:NN \l_@@_begin_align_tl \flushright
+            \tl_set_eq:NN \l_@@_end_align_tl   \endflushright },
+        c =
+          { \tl_set_eq:NN \l_@@_begin_align_tl \center
+            \tl_set_eq:NN \l_@@_end_align_tl   \endcenter     },
+        n =
+          { \tl_clear:N   \l_@@_begin_align_tl
+            \tl_clear:N   \l_@@_end_align_tl                  }
+      }
+  }
+  {
+    \AssignTemplateKeys
+    \group_begin:
+      \l_@@_begin_align_tl
+      \l_@@_format_tl
+      \l_@@_content_tl \par
+      \l_@@_end_align_tl
+    \group_end:
+    \__nju_vskip:N \l_@@_bottom_skip
+  }
+%    \end{macrocode}
+%
+% 定义页面模板。
+%    \begin{macrocode}
+%<@@=njupage>
+%    \end{macrocode}
+%
+% 声明页面模板接口。
+% 页面是元素的集合。一个抽象的页面应当具备以下属性:
+% \begin{description}
+%   \item[\opt{element}] 包含的元素,这里使用的是名称列表
+%   \item[\opt{prefix}] 元素名称前缀
+%   \item[\opt{format}] 格式,例如行距
+%   \item[\opt{top-skip}] 上间距,即与页面顶部的距离
+%   \item[\opt{bottom-skip}] 下间距,即与页面底部的距离
+% \end{description}
+%    \begin{macrocode}
+\DeclareTemplateInterface { nju } { page } { \c_zero_int }
+  {
+    element     : commalist = \c_empty_clist,
+    prefix      : tokenlist = \c_empty_tl,
+    format      : tokenlist = \c_empty_tl,
+    top-skip    : skip      = \c_zero_skip,
+    bottom-skip : skip      = \c_zero_skip
+  }
+%    \end{macrocode}
+%
+% 声明页面模板代码。
+%    \begin{macrocode}
+\DeclareTemplateCode { nju } { page } { \c_zero_int }
+  {
+    element     = \l_@@_element_clist,
+    prefix      = \l_@@_prefix_tl,
+    format      = \l_@@_format_tl,
+    top-skip    = \l_@@_top_skip,
+    bottom-skip = \l_@@_bottom_skip
+  }
+  {
+    \AssignTemplateKeys
+    \newpage
+    \__nju_vskip:N \l_@@_top_skip
+    \group_begin:
+      \l_@@_format_tl
+      \clist_map_inline:Nn \l_@@_element_clist
+        { \UseInstance { nju } { \l_@@_prefix_tl ##1 } }
+    \group_end:
+    \__nju_vskip:N \l_@@_bottom_skip
+  }
+%<@@=nju>
+%    \end{macrocode}
+%
+% \begin{macro}{\@@_declare_element:nn,\@@_declare_page:nn}
+% 封装 \pkg{xtemplate} 提供的函数,简化创建实例的过程。
+% \begin{arguments}
+%   \item 实例名称
+%   \item 参数列表
+% \end{arguments}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_declare_element:nn #1#2
+  { \DeclareInstance { nju } {#1} { element } {#2} }
+\cs_new_protected:Npn \@@_declare_page:nn    #1#2
+  { \DeclareInstance { nju } {#1} { page    } {#2} }
+%    \end{macrocode}
+% \end{macro}
+%
+%
 % \subsection{模板选项}
 % \changes{v0.11}{2021/11/15}{进行了效率优化。}
 %
@@ -2312,20 +2759,7 @@
 % 学位类型,默认为本科。
 %    \begin{macrocode}
     degree            .choices:nn = { ug, mg, mf, phd }
-      {
-        \int_set_eq:NN \l_@@_info_degree_int \l_keys_choice_int
-        \tl_set:Nn \l_@@_info_degree_tl
-          {
-            \clist_item:Nn \c_@@_name_degree_clist
-              { \l_@@_info_degree_int }
-          }
-%    \end{macrocode}
-% 进行学位的判断。
-%    \begin{macrocode}
-        \int_compare:nTF { \l_@@_info_degree_int == 1 }
-          { \tl_set:Nn \l_@@_info_diploma_tl { ug } }
-          { \tl_set:Nn \l_@@_info_diploma_tl { g  } }
-      },
+      { \int_gset_eq:NN \g_@@_info_degree_int \l_keys_choice_int },
     degree            .initial:n  = ug,
 %    \end{macrocode}
 % \end{macro}
@@ -2334,13 +2768,7 @@
 % 论文类型,默认为毕业论文。
 %    \begin{macrocode}
     type              .choices:nn = { thesis, design }
-      {
-        \int_set_eq:NN \l_@@_info_type_int \l_keys_choice_int
-        \tl_set:Nn \l_@@_info_type_tl
-          { \clist_item:Nn \c_@@_name_type_clist { \l_@@_info_type_int } }
-        \tl_put_left:Nn \l_@@_info_type_tl
-          { \tl_use:c { c_@@_name_ \l_@@_info_diploma_tl _tl } }
-      },
+      { \int_gset_eq:NN \g_@@_info_type_int   \l_keys_choice_int },
     type              .initial:n    = thesis,
 %    \end{macrocode}
 % \end{macro}
@@ -2386,7 +2814,7 @@
 %
 % \begin{macro}{latin-font,cjk-font}
 % \changes{v0.14}{2021/12/12}{简化字体选项名称。}
-% 定义字体选项。
+% 字体选项。
 %    \begin{macrocode}
     latin-font        .choices:nn =
       { gyre, mac, win, none }
@@ -2394,6 +2822,14 @@
     cjk-font          .choices:nn =
       { fandol, founder, mac, noto, source, win, none }
       { \tl_set_eq:NN \g_@@_cjk_font_tl   \l_keys_choice_tl },
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{config}
+% \changes{v0.16}{2022/02/23}{新增 \opt{config} 选项。}
+% 配置文件路径。
+%    \begin{macrocode}
+    config             .tl_set:N  = \g_@@_config_clist
   }
 %    \end{macrocode}
 % \end{macro}
@@ -2427,180 +2863,6 @@
 % \end{macro}
 %
 %
-% \subsection{配置常量}
-% TODO: 分离为单独文件
-% 通用默认名称。注意空格是忽略掉的。
-%    \begin{macrocode}
-\clist_map_inline:nn
-  {
-    { acknowledgement } { 致\hspace{2em}谢              },
-    { id              } { 学号                          },
-    { notation        } { 符号表                        },
-    { orig_date       } { 日期                          },
-    { paperlist       } { 发表文章目录                  },
-    { pdf_creator     } { LaTeX~ with~ njuthesis~ class },
-    { preface         } { 前\hspace{2em}言              },
-    { supv_ii         } { 第二导师                      },
-    { supv_ttl        } { 职称                          }
-  }
-  { \@@_define_name:nn #1 }
-%    \end{macrocode}
-%
-% 定义同时使用到中英文名称的常量。
-%    \begin{macrocode}
-\clist_map_inline:nn
-  {
-    { abstract  } { 摘要     } { ABSTRACT            },
-    { appendix  } { 附录     } { appendix            },
-    { dept      } { 院系     } { DEPARTMENT          },
-    { figure    } { 图       } { figure              },
-    { keywords  } { 关键词: } { Keywords:~          },
-    { lang      } { 中文     } { 英文                },
-    { nju       } { 南京大学 } { Nanjing~ University },
-    { table     } { 表       } { table               }
-  }
-  { \@@_define_name:nnn #1 }
-%    \end{macrocode}
-%
-% 针对学位的特定名称。需要放在 \cs{ProcessKeysOptions} 导入设置选项后,以使用学位信息。
-%    \begin{macrocode}
-\int_compare:nTF { \l_@@_info_degree_int == 1 }
-  {
-%    \end{macrocode}
-% 本科默认名称。
-%    \begin{macrocode}
-    \clist_map_inline:nn
-      {
-        { author_full } { 本科生姓名                      },
-        { grade       } { 年级                            },
-        { orig_decl   } { 本科毕业论文(设计)诚信承诺书  },
-        { orig_sign   } { 作者签名                        },
-        { sm_date     } { 提交日期                        },
-        { supv        } { 导师                            },
-        { title       } { 题目                            },
-        { type        } { 本科生毕业论文(设计、作品)    },
-        { ug          } { 本科                            }
-      }
-      { \@@_define_name:nn #1 }
-      \clist_map_inline:nn
-        {
-          { author    } { 学生姓名               } { UNDERGRADUATE  },
-          { major     } { 专业                   } { SPECIALIZATION },
-          { supv_full } { 指导教师(姓名、职称) } { MENTOR         }
-        }
-        { \@@_define_name:nnn #1 }
-%    \end{macrocode}
-%
-% \begin{variable}{\c_@@_orig_decl_text_tl}
-% 学位论文诚信承诺书。
-%    \begin{macrocode}
-      \tl_const:Nn \c_@@_orig_decl_text_tl
-        {
-          本人郑重承诺:所呈交的毕业论文(设计)(题目:)是在指导教师的指导下
-          严格按照学校和院系有关规定由本人独立完成的。本毕业论文(设计)中引用
-          他人观点及参考资源的内容均已标注引用,如出现侵犯他人知识产权的行为,
-          由本人承担相应法律责任。本人承诺不存在抄袭、伪造、篡改、代写、买卖毕
-          业论文(设计)等违纪行为。
-        }
-  }
-%    \end{macrocode}
-% \end{variable}
-%
-% 研究生默认名称。
-%    \begin{macrocode}
-  {
-    \clist_map_inline:nn
-      {
-        { abstract_r  } { 摘要首页用纸       },
-        { author_r    } { 生姓名             },
-        { chairman    } { 答辩委员会主席:   },
-        { clc         } { 分类号             },
-        { confer      } { 学位授予单位和日期 },
-        { df_date     } { 论文答辩日期       },
-        { degree      } { 申请学位级别       },
-        { apply       }
-        { (申请 \l_@@_info_degree_tl 学位) },
-        { field       } { 研究方向           },
-        { g           } { 研究生             },
-        { grade       } { 级                 },
-        { major_s     } { 专业               },
-        { major_nl    } { 专业名称           },
-        { orig_decl   } { 学位论文原创性声明 },
-        { orig_sign   } { 研究生签名         },
-        { reviewer    } { 评阅人:           },
-        { seclv       } { 密级               },
-        { sign        } { (签字)           },
-        { sm_date     } { 论文提交日期       },
-        { supv        } { 导师               },
-        { supv_r      } { (姓名、职称)     },
-        { supv_info   } { 指导教师姓名、职务、
-                  职称、学位、单位名称及地址 },
-        { title       } { 论文题目           },
-        { title_nl    } { (题名和副题名)   },
-        { title_s     } { 题目               },
-        { udc         } { U D C              }
-      }
-      { \@@_define_name:nn #1 }
-      \clist_map_inline:nn
-        {
-          { author    } { 作者姓名 } { POSTGRADUATE   },
-          { major     } { 专业方向 } { SPECIALIZATION },
-          { supv_full } { 指导教师 } { MENTOR         }
-        }
-        { \@@_define_name:nnn #1 }
-%    \end{macrocode}
-%
-% \begin{variable}{\c_@@_cover_en_text_tl}
-% 英文封面字样。
-%    \begin{macrocode}
-    \tl_const:Nn \c_@@_cover_en_text_tl
-      {
-        A~ dissertation~ submitted~ to \\
-        the~ graduate~ school~ of~ Nanjing~ University \\
-        in~ partial~ fulfilment~ of~ the~ requirements~ for~ the~ degree~ of
-      }
-%    \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\c_@@_orig_decl_text_tl}
-% 学位论文原创性声明。
-%    \begin{macrocode}
-    \tl_const:Nn \c_@@_orig_decl_text_tl
-      {
-        本人郑重声明,所提交的学位论文是本人在导师指导下独立进行科学研究工作
-        所取得的成果。除本论文中已经注明引用的内容外,本论文不包含其他个人或
-        集体已经发表或撰写过的研究成果,也不包含为获得南京大学或其他教育机构
-        的学位证书而使用过的材料。对本文的研究做出重要贡献的个人和集体,均已
-        在论文的致谢部分明确标明。本人郑重申明愿承担本声明的法律责任。
-      }
-  }
-%    \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\c_@@_theorem_type_clist}
-% 默认定理类型。
-%    \begin{macrocode}
-\clist_const:Nn \c_@@_theorem_type_clist
-  { axiom, corollary, definition, example, lemma, theorem }
-%    \end{macrocode}
-% \end{variable}
-%
-% 默认定理头名称。
-%    \begin{macrocode}
-\clist_map_inline:nn
-  {
-    { axiom      } { 公理 } { Axiom      },
-    { corollary  } { 推论 } { Corollary  },
-    { definition } { 定义 } { Definition },
-    { example    } { 例   } { Example    },
-    { lemma      } { 引理 } { Lemma      },
-    { proof      } { 证明 } { Proof      },
-    { theorem    } { 定理 } { Theorem    }
-  }
-  { \@@_define_name:nnn #1 }
-%    \end{macrocode}
-%
-%
 % \subsection{载入宏包}
 %
 % \changes{v0.12}{2021/12/07}{重新组织宏包载入顺序。}
@@ -2610,7 +2872,7 @@
   {
     a4paper,
     UTF8,
-    scheme=chinese,
+    scheme = chinese,
 %    \end{macrocode}
 % 传入单双面模式选项。
 %    \begin{macrocode}
@@ -2620,18 +2882,18 @@
 %    \begin{macrocode}
     \bool_if:NT \g_@@_draft_bool { draft, }
 %    \end{macrocode}
-% 关于行距,\hologo{LaTeX} 默认1.2行距,word 默认行距是1.3,要求1.5倍 word 行距,故
-% $1.5\times\frac{1.3}{1.2} = 1.625$
+% 关于行距,\hologo{LaTeX} 默认1.2行距,MS Word 默认行距是1.3,要求1.5倍
+% Word 行距,故 $1.5\times\frac{1.3}{1.2} = 1.625$
 %    \begin{macrocode}
-    linespread=1.625,
+    linespread = 1.625,
 %    \end{macrocode}
 % 默认不载入任何字体,供本模板自行设置。
 %    \begin{macrocode}
-    fontset=none,
+    fontset = none,
 %    \end{macrocode}
 % 正文字体设置为小四号。
 %    \begin{macrocode}
-    zihao=-4
+    zihao = -4
   }
   { ctexbook }
 %    \end{macrocode}
@@ -2667,21 +2929,20 @@
     fancyhdr,
     setspace,
 %    \end{macrocode}
-% 南京大学视觉形象化标准宏包 \pkg{njuvisual} 用于绘制学校 logo。
+% \changes{v0.13}{2021/12/13}{使用 \pkg{ntheorem} 创建定理环境,删除
+%   \pkg{amsthm} 和 \pkg{thmtools}。}
+% \changes{v0.16}{2022/03/19}{不显式载入 \pkg{amsmath}。}
+% 数学相关的宏包。其中,\pkg{amsmath} 必须在 \pkg{unicode-math} 前加载。
+% \pkg{unicode-math} 指定了 \hologo{XeTeX} 和 \hologo{LuaTeX} 下所使用的
+% 数学字体。用于配置数学环境的 \pkg{mathtools} 会与 \pkg{unicode-math}
+% 发生冲突,需要手动消除其警告。
 %    \begin{macrocode}
-    njuvisual,
-%    \end{macrocode}
-% \changes{v0.13}{2021/12/13}{使用 \pkg{ntheorem} 创建定理环境,删除 \pkg{amsthm} 和 \pkg{thmtools}。}
-% 数学,\pkg{amsmath} 必须在 \pkg{unicode-math} 前加载。
-% \pkg{unicode-math} 指定了 \hologo{XeTeX} 和 \hologo{LuaTeX} 下所使用的数学字体。
-% 用于配置数学环境的 \pkg{mathtools} 会与 \pkg{unicode-math} 发生冲突,此处手动消除其警告。
-%    \begin{macrocode}
-    amsmath,
     mathtools,
     unicode-math,
     ntheorem,
 %    \end{macrocode}
-% \changes{v0.14}{2021/12/21}{移除内置的 \pkg{multirow}、\pkg{subcaption} 和 \pkg{wrapfig}。}
+% \changes{v0.14}{2021/12/21}{移除内置的 \pkg{multirow}、\pkg{subcaption}
+%   和 \pkg{wrapfig}。}
 % 图片与表格。
 %    \begin{macrocode}
     booktabs,
@@ -2731,7 +2992,7 @@
 %    \begin{macrocode}
 \msg_new:nnn { njuthesis } { package-too-old }
   {
-    Package~ "#1"~ is~ too~ old. \\
+    Package~ "#1"~ is~ too~ old.\\
     The~ njuthesis~ class~ only~ supports~ "#1"~ with~
     a~ version higher~ than~ v#2.\\
     Please~ update~ an~ up-to-date~ version~ of~ it~
@@ -2745,7 +3006,8 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% 检查绘制下划线所需的 \pkg{luatexja} 包版本。该宏包在2021-09-18的更新解决了下划线中断问题,然而在2021-10-24的更新才提供了正确的内嵌日期。
+% 检查绘制下划线所需的 \pkg{luatexja} 包版本。该宏包在 2021-09-18 的更新
+% 解决了下划线中断问题,然而在 2021-10-24 的更新才提供了正确的内嵌日期。
 %    \begin{macrocode}
 \sys_if_engine_luatex:T
   { \@@_check_package:nnn { luatexja } { 2021/10/24 } { 20211024.0 } }
@@ -2752,6 +3014,35 @@
 %    \end{macrocode}
 %
 %
+% \subsection{配置文件}
+%
+% \cls{njuthesis} 包含\emph{本科生}和\emph{研究生}两套区别较大的模板配置。
+% 出于定义的简洁起见,本模板将其拆分为两个单独的参数配置文件,
+% 编译过程中将会根据设置的学位信息,载入相应默认配置。
+% 注意,尽管在手册的实现细节部分封面、摘要、常量等位于靠后部分,
+% 拆分后实际上是在此处载入运行的,务必要注意逻辑顺序。
+%
+% 下文中,本科生模板配置对应 \agrd{definition-ug},用于生成
+% \file{njuthesis-undergraduate.def};研究生模板配置对应
+% \agrd{definition-g},用于生成 \file{njuthesis-graduate.def}。
+%    \begin{macrocode}
+\int_compare:nTF { \g_@@_info_degree_int == 1 }
+  { \file_input:n { njuthesis-undergraduate.def } }
+  { \file_input:n { njuthesis-     graduate.def } }
+%    \end{macrocode}
+%
+% 载入用户设置,可用于对模板做额外修改。
+%    \begin{macrocode}
+\msg_new:nnn { njuthesis } { load-config }
+  { I~ am~ loading~ config~ file~ "#1". }
+\clist_if_empty:NF \g_@@_config_clist
+  {
+    \msg_info:nnx { njuthesis } { load-config } { \g_@@_config_tl }
+    \clist_map_inline:Nn \g_@@_config_clist { \file_input:n { #1 } }
+  }
+%    \end{macrocode}
+%
+%
 % \subsection{个人信息}
 % \changes{v0.11}{2021/10/01}{将个人信息变量名改为小写字母加连字符的形式。}
 % \changes{v0.15}{2022/01/22}{将个人信息设置移到载入宏包后。}
@@ -2858,8 +3149,31 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \changes{v0.16}{2022/03/06}{正确处理学位和类型信息。}
+% 设置学位信息。该设置需要放在 \cs{ProcessKeysOptions}
+% 命令以及载入配置文件中的常量信息后进行。
+%    \begin{macrocode}
+\tl_set:Nx \l_@@_info_degree_tl
+  {
+    \clist_item:Nn \c_@@_name_degree_clist
+      { \g_@@_info_degree_int }
+  }
+\int_compare:nTF { \g_@@_info_degree_int == 1 }
+  { \tl_set:Nn \l_@@_info_diploma_tl { ug } }
+  { \tl_set:Nn \l_@@_info_diploma_tl { g  } }
+%    \end{macrocode}
+%
+% 设置类型信息。
+%    \begin{macrocode}
+\tl_set:Nx \l_@@_info_type_tl
+  { \clist_item:Nn \c_@@_name_type_clist { \g_@@_info_type_int } }
+\tl_put_left:Nx \l_@@_info_type_tl
+  { \tl_use:c { c_@@_name_ \l_@@_info_diploma_tl _tl } }
+%    \end{macrocode}
+%
 % \changes{v0.15}{2022/01/22}{正确处理双导师信息。}
-% 在导言区录入用户信息后进行变量设置。此处使用到了 \pkg{ctex} 提供的命令,应当位于载入文档类之后。
+% 在导言区录入用户信息后进行变量设置。此处使用到了 \pkg{ctex} 提供的命令,
+% 应当位于载入文档类之后。
 %    \begin{macrocode}
 \ctex_at_end_preamble:n
   {
@@ -2894,7 +3208,7 @@
 %    \end{macrocode}
 % 英文提交日期以及答辩日期仅用于研究生封面。
 %    \begin{macrocode}
-    \int_compare:nF { \l_@@_info_degree_int == 1 }
+    \int_compare:nF { \g_@@_info_degree_int == 1 }
       {
         \tl_set:Nn \l_@@_info_sm_date_en_tl
           {
@@ -2920,29 +3234,32 @@
 % 判断用户是否自定义了中英文字体。如果其中任意一种未被定义,
 % 则使用系统预装字体覆盖字体选项。
 %    \begin{macrocode}
-\tl_if_empty:NTF \g_@@_latin_font_tl
-  { \bool_gset_true:N \g_@@_load_sys_font_bool }
-  {
-    \tl_if_empty:NT \g_@@_cjk_font_tl
-      { \bool_gset_true:N \g_@@_load_sys_font_bool }
-  }
+\bool_lazy_or:nnT
+  { \tl_if_empty_p:N \g_@@_latin_font_tl }
+  { \tl_if_empty_p:N \g_@@_cjk_font_tl   }
 %    \end{macrocode}
-%
-% 进行系统检测。
+% 进行操作系统检测。
 % 检测 Windows 的命令由 \pkg{l3kernel} 提供,
 % 检测 macOS 的命令由 \pkg{ctex} 提供,
 % 这两种情况外的系统被判断为 Linux,一律使用自由字体。
 %    \begin{macrocode}
-\bool_if:NT \g_@@_load_sys_font_bool
   {
     \sys_if_platform_windows:TF
-      { \tl_set:Nn \g_@@_latin_font_tl   { win    }
-        \tl_set:Nn \g_@@_cjk_font_tl     { win    } }
-      { \ctex_if_platform_macos:TF
-        { \tl_set:Nn \g_@@_latin_font_tl { mac    }
-          \tl_set:Nn \g_@@_cjk_font_tl   { mac    } }
-        { \tl_set:Nn \g_@@_latin_font_tl { gyre   }
-          \tl_set:Nn \g_@@_cjk_font_tl   { fandol } } }
+      {
+        \tl_set:Nn \g_@@_latin_font_tl     { win    }
+        \tl_set:Nn \g_@@_cjk_font_tl       { win    }
+      }
+      {
+        \ctex_if_platform_macos:TF
+          {
+            \tl_set:Nn \g_@@_latin_font_tl { mac    }
+            \tl_set:Nn \g_@@_cjk_font_tl   { mac    }
+          }
+          {
+            \tl_set:Nn \g_@@_latin_font_tl { gyre   }
+            \tl_set:Nn \g_@@_cjk_font_tl   { fandol }
+          }
+      }
   }
 %    \end{macrocode}
 %
@@ -2956,9 +3273,10 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_load_latin_font_win:
   {
-    \setmainfont{Times~New~Roman}
-    \setsansfont{Arial}
-    \setmonofont{Courier~New}[Scale=MatchLowercase]
+    \setmainfont { Times~New~Roman }
+    \setsansfont { Arial           }
+    \setmonofont { Courier~New     }
+      [ Scale = MatchLowercase ]
   }
 %    \end{macrocode}
 % \end{macro}
@@ -2968,9 +3286,10 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_load_latin_font_mac:
   {
-    \setmainfont{Times~New~Roman}
-    \setsansfont{Arial}
-    \setmonofont{Menlo}[Scale=MatchLowercase]
+    \setmainfont { Times~New~Roman }
+    \setsansfont { Arial           }
+    \setmonofont { Menlo           }
+      [ Scale = MatchLowercase ]
   }
 %    \end{macrocode}
 % \end{macro}
@@ -2980,26 +3299,32 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_load_latin_font_gyre:
   {
-    \setmainfont{texgyretermes}[
-      Extension=.otf,
-      UprightFont=*-regular,
-      BoldFont=*-bold,
-      ItalicFont=*-italic,
-      BoldItalicFont=*-bolditalic]
-    \setsansfont{texgyreheros}[
-      Extension=.otf,
-      UprightFont=*-regular,
-      BoldFont=*-bold,
-      ItalicFont=*-italic,
-      BoldItalicFont=*-bolditalic]
-    \setmonofont{texgyrecursor}[
-      Extension=.otf,
-      UprightFont=*-regular,
-      BoldFont=*-bold,
-      ItalicFont=*-italic,
-      BoldItalicFont=*-bolditalic,
-      Scale=MatchLowercase,
-      Ligatures=CommonOff]
+    \setmainfont { texgyretermes }
+      [
+        Extension      = .otf,
+        UprightFont    = *-regular,
+        BoldFont       = *-bold,
+        ItalicFont     = *-italic,
+        BoldItalicFont = *-bolditalic
+      ]
+    \setsansfont { texgyreheros  }
+      [
+        Extension      = .otf,
+        UprightFont    = *-regular,
+        BoldFont       = *-bold,
+        ItalicFont     = *-italic,
+        BoldItalicFont = *-bolditalic
+      ]
+    \setmonofont { texgyrecursor }
+      [
+        Extension      = .otf,
+        UprightFont    = *-regular,
+        BoldFont       = *-bold,
+        ItalicFont     = *-italic,
+        BoldItalicFont = *-bolditalic,
+        Scale          = MatchLowercase,
+        Ligatures      = CommonOff
+      ]
   }
 %    \end{macrocode}
 % \end{macro}
@@ -3007,10 +3332,10 @@
 %
 % \subsubsection{定义中文字库}
 %
-% \begin{macro}{\@@_diable_no_script_msg:}
-% 移除 |does not contain script "CJK"| 警告。
+% \begin{macro}{\@@_hide_no_script_msg:}
+% 隐藏 |does not contain script "CJK"| 警告。
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_diable_no_script_msg:
+\cs_new_protected:Npn \@@_hide_no_script_msg:
   { \msg_redirect_name:nnn { fontspec } { no-script } { info } }
 %    \end{macrocode}
 % \end{macro}
@@ -3039,7 +3364,7 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_load_cjk_font_mac:
   {
-    \@@_diable_no_script_msg:
+    \@@_hide_no_script_msg:
     \setCJKmainfont{Songti~SC~Light}[
       BoldFont=Songti~SC~Bold,
       ItalicFont=Kaiti~SC,
@@ -3060,25 +3385,37 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_load_cjk_font_fandol:
   {
-    \@@_diable_no_script_msg:
-    \setCJKmainfont{FandolSong-Regular}[
-      Extension=.otf,
-      BoldFont=FandolSong-Bold,
-      ItalicFont=FandolKai-Regular]
-    \setCJKsansfont{FandolHei-Regular}[
-      Extension=.otf,
-      BoldFont=FandolHei-Bold]
-    \setCJKmonofont{FandolFang-Regular}[Extension=.otf]
-    \setCJKfamilyfont{zhsong}{FandolSong-Regular}[
-      Extension=.otf,
-      BoldFont=FandolSong-Bold]
-    \setCJKfamilyfont{zhhei}{FandolHei-Regular}[
-      Extension=.otf,
-      BoldFont=FandolHei-Bold]
-    \setCJKfamilyfont{zhfs}{FandolFang-Regular}[Extension=.otf]
-    \setCJKfamilyfont{zhkai}{FandolKai-Regular}[
-      Extension=.otf,
-      AutoFakeBold=2.17]
+    \@@_hide_no_script_msg:
+    \setCJKmainfont { FandolSong-Regular }
+      [
+        Extension    = .otf,
+        BoldFont     = FandolSong-Bold,
+        ItalicFont   = FandolKai-Regular
+      ]
+    \setCJKsansfont { FandolHei-Regular  }
+      [
+        Extension    = .otf,
+        BoldFont     = FandolHei-Bold
+      ]
+    \setCJKmonofont { FandolFang-Regular }
+      [ Extension    = .otf ]
+    \setCJKfamilyfont { zhsong } { FandolSong-Regular }
+      [
+        Extension    = .otf,
+        BoldFont     = FandolSong-Bold
+      ]
+    \setCJKfamilyfont { zhhei  } { FandolHei-Regular  }
+      [
+        Extension    = .otf,
+        BoldFont     = FandolHei-Bold
+      ]
+    \setCJKfamilyfont { zhfs   } { FandolFang-Regular }
+      [ Extension    = .otf ]
+    \setCJKfamilyfont { zhkai  } { FandolKai-Regular  }
+      [
+        Extension    = .otf,
+        AutoFakeBold = 2.17
+      ]
   }
 %    \end{macrocode}
 % \end{macro}
@@ -3103,9 +3440,9 @@
     \setCJKfamilyfont { zhsong } { FZShuSong-Z01  }
       [ BoldFont = FZXiaoBiaoSong-B05 ]
     \setCJKfamilyfont { zhhei  } { FZHei-B01      }
-      [AutoFakeBold=2.17]
+      [ AutoFakeBold = 2.17 ]
     \setCJKfamilyfont { zhkai  } { FZKai-Z03      }
-      [AutoFakeBold=2.17]
+      [ AutoFakeBold = 2.17 ]
     \setCJKfamilyfont { zhfs   } { FZFangSong-Z02 }
     \defaultCJKfontfeatures{}
   }
@@ -3212,7 +3549,7 @@
 %    \begin{macrocode}
     \@@_load_math_font:
 %    \end{macrocode}
-% 自行定义 C\hologo{TeX} 中的四类字体命令。
+% 自行定义 \pkg{ctex} 中的四类字体命令。
 %    \begin{macrocode}
     \NewDocumentCommand \songti   { } { \CJKfamily { zhsong } }
     \NewDocumentCommand \heiti    { } { \CJKfamily { zhhei  } }
@@ -3249,19 +3586,113 @@
 % 草稿模式下显示页面文字范围边界以及页眉、页脚线。
 %    \begin{macrocode}
 \bool_if:NT \g_@@_draft_bool { \geometry { showframe } }
+%</class>
 %    \end{macrocode}
 %
 %
 % \subsubsection{页眉页脚}
 %
-% \begin{macro}{\@@_fancy_head:nn}
-% 页眉样式,设置为小号字体、楷书。这里对 \pkg{fancyhdr} 的命令进行了包装。
+% \begin{variable}{\c_@@_pagestyle_tl}
+% 针对不同学位类型的默认页面样式设置。
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_fancy_head:nn #1#2
-  { \fancyhead [#1] { \small \kaishu \nouppercase {#2} } }
+%<definition-ug>\tl_const:Nn \c_@@_pagestyle_tl { plain    }
+%<definition-g>\tl_const:Nn \c_@@_pagestyle_tl { headings }
 %    \end{macrocode}
+% \end{variable}
+%
+% 提供设置页眉页脚的用户接口。在 \cs{fancyhead} 的可选参数中,
+% \opt{E} 和 \opt{O} 分别表示在偶数页(even)和奇数页(odd),
+% 而 \opt{L}、\opt{R} 和 \opt{C} 则分别表示左(left)、右
+% (right)和中间(center)。按照通常的排版规则,在双面模式下,
+% 偶数页的中间页眉文字在左,奇数页则在右。单面模式下,左右页眉都要显示。
+%    \begin{macrocode}
+%<*class>
+\keys_define:nn { nju / style }
+  {
+%    \end{macrocode}
+% \begin{macro}{style/header/format}
+% \changes{v0.16}{2022/03/18}{可手动指定页眉样式。}
+% 页眉格式。
+%    \begin{macrocode}
+    header/format .tl_gset:N = \g_@@_header_format_tl,
+    header/format .initial:n = \small \kaishu,
+%    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}{style/header,style/header*}
+% \changes{v0.16}{2022/03/18}{可手动指定页眉内容。}
+% 页眉内容,分别对应双面模式和单面模式。
+% 为了便于指定复杂的页眉样式,这里用 |clist| 存储位置和内容信息。
+%    \begin{macrocode}
+    header     .clist_gset:N = \g_@@_header_twoside_clist,
+    header*    .clist_gset:N = \g_@@_header_oneside_clist,
+    header        .initial:n =
+      {
+        { EL } { \leftmark  }, { OR } { \rightmark }
+      },
+    header*       .initial:n =
+      {
+        {  L } { \leftmark  }, {  R } { \rightmark }
+      },
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{style/footer/format}
+% \changes{v0.16}{2022/03/19}{可手动指定页脚样式。}
+% 页脚格式。
+%    \begin{macrocode}
+    footer/format .tl_gset:N = \g_@@_footer_format_tl,
+    footer/format .initial:n = \small \rmfamily,
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{style/footer,style/footer*}
+% \changes{v0.16}{2022/03/18}{可手动指定页脚内容。}
+% 页脚内容,同页眉。
+%    \begin{macrocode}
+    footer     .clist_gset:N = \g_@@_footer_twoside_clist,
+    footer*    .clist_gset:N = \g_@@_footer_oneside_clist,
+    footer        .initial:n = { { C } { \thepage } },
+    footer*       .initial:n = { { C } { \thepage } }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\g_@@_header_clist,\g_@@_footer_clist}
+% 设置页眉页脚。
+%    \begin{macrocode}
+\clist_new:N \g_@@_header_clist
+\clist_new:N \g_@@_footer_clist
+%    \end{macrocode}
+% \end{macro}
+%
+% 在导言区末尾确定页眉页脚内容。
+%    \begin{macrocode}
+\ctex_at_end_preamble:n
+  {
+    \bool_if:NTF \g_@@_twoside_bool
+      {
+        \clist_set_eq:NN \g_@@_header_clist \g_@@_header_twoside_clist
+        \clist_set_eq:NN \g_@@_footer_clist \g_@@_footer_twoside_clist
+      }
+      {
+        \clist_set_eq:NN \g_@@_header_clist \g_@@_header_oneside_clist
+        \clist_set_eq:NN \g_@@_footer_clist \g_@@_footer_oneside_clist
+      }
+  }
+%    \end{macrocode}
+%
+% \begin{macro}{\@@_header:nn,\@@_footer:nn}
+% 对 \pkg{fancyhdr} 的命令进行包装,便于设置页眉页脚。
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_header:nn #1#2
+  { \fancyhead [#1] { \g_@@_header_format_tl #2 } }
+\cs_new_protected:Npn \@@_footer:nn #1#2
+  { \fancyfoot [#1] { \g_@@_footer_format_tl #2 } }
+%    \end{macrocode}
+% \end{macro}
+%
 % 重定义 \pkg{fancyhdr} 的 \opt{plain} 样式,即本科生正文和部分特殊页面使用的的
 % 页眉页脚样式。页眉无内容;页脚为居中的页码,使用五号新罗马体数字。注意标记页眉
 % 页脚横线宽度的变量并不是 |dim| 类型的,但是采取了该类型的格式。
@@ -3269,45 +3700,40 @@
 \fancypagestyle { plain }
   {
     \fancyhf { }
-    \fancyfoot [ C ] { \zihao { 5 } \rmfamily \thepage }
+    \clist_map_inline:Nn \g_@@_footer_clist { \@@_footer:nn ##1 }
     \tl_set:Nn \headrulewidth { \c_zero_dim }
     \tl_set:Nn \footrulewidth { \c_zero_dim }
   }
 %    \end{macrocode}
 %
-% \begin{macro}{\@@_set_heading_g:}
 % \changes{v0.15}{2022/01/17}{修复单页模式的页眉问题。}
-% 以 \opt{plain} 样式为基础,单独设置研究生模板的页眉内容。在 \cs{fancyhead} 的
-% 可选参数中,\opt{E} 和 \opt{O} 分别表示在偶数页(even)和奇数页(odd), 而
-% \opt{L}、\opt{R} 和 \opt{C} 则分别表示左(left)、右(right)和中间(center)
-% 。按照通常的排版规则,在双面模式下,偶数页的中间页眉文字在左,奇数页则在右。
-% 单面模式下,左右页眉都要显示。
+% 以 \opt{plain} 样式为基础的 \opt{headings} 样式,用于研究生模板。
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_set_heading_g:
+\fancypagestyle { headings }
   {
-    \bool_if:NTF \g_@@_twoside_bool
+    \fancyhf { }
+    \clist_if_empty:NTF \g_@@_header_clist
       {
-        \@@_fancy_head:nn { EL } { \leftmark  }
-        \@@_fancy_head:nn { OR } { \rightmark }
+        \tl_set:Nn \headrulewidth { \c_zero_dim }
       }
       {
-        \@@_fancy_head:nn { L  } { \leftmark  }
-        \@@_fancy_head:nn { R  } { \rightmark }
+        \tl_set:Nn \headrulewidth { 0.4 pt }
+        \dim_set:Nn \headheight { 20 pt }
+        \clist_map_inline:Nn \g_@@_header_clist
+          { \@@_header:nn ##1 }
       }
-    \tl_set:Nn \headrulewidth { 0.4 pt }
-    \dim_set:Nn \headheight { 20 pt }
+    \clist_map_inline:Nn \g_@@_footer_clist { \@@_footer:nn ##1 }
+    \tl_set:Nn \footrulewidth { \c_zero_dim }
   }
 %    \end{macrocode}
-% \end{macro}
 %
 % \begin{macro}{\frontmatter}
-% 重定义 \cs{frontmatter},清空页眉页脚以及页码设置。
-% 此命令仅为解决原 \cls{book} 类中默认使用小写罗马字母序号的冲突,并不建议使用。
+% 重定义 \cs{frontmatter},设置前言区默认的页眉页脚以及页码样式。
 %    \begin{macrocode}
 \RenewDocumentCommand \frontmatter { }
   {
     \cleardoublepage
-    \pagestyle     { empty }
+    \exp_args:NV \pagestyle \c_@@_pagestyle_tl
     \pagenumbering { Roman }
   }
 %    \end{macrocode}
@@ -3316,15 +3742,13 @@
 % \begin{macro}{\mainmatter}
 % \changes{v0.12}{2021/12/03}{修复了摘要页字体格式泄漏到正文的问题。}
 % \changes{v0.12}{2021/12/03}{修复了页眉上长标题重叠的问题。}
-% 重定义 \cs{mainmatter},在论文主体部分载入页眉页脚设置,使用阿拉伯数字重新进行
-% 页码编号。
+% 重定义 \cs{mainmatter},在论文主体部分载入页面样式设置,
+% 使用阿拉伯数字重新进行页码编号。
 %    \begin{macrocode}
 \RenewDocumentCommand \mainmatter { }
   {
     \cleardoublepage
-    \pagestyle { plain }
-    \int_compare:nF { \l_@@_info_degree_int == 1 }
-      { \@@_set_heading_g: }
+    \exp_args:NV \pagestyle \c_@@_pagestyle_tl
     \pagenumbering { arabic }
     \normalfont \normalsize
   }
@@ -3331,7 +3755,17 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \changes{v0.16}{2022/03/18}{研究生模板的目录、摘要等页面也显示页眉。}
+% 在文档起始位置设置默认页面样式。
+%    \begin{macrocode}
+\AtBeginEnvironment { document }
+  {
+    \exp_args:NV \pagestyle \c_@@_pagestyle_tl
+    \pagenumbering { Roman }
+  }
+%    \end{macrocode}
 %
+%
 % \subsection{章节标题格式}
 %
 % \begin{macro}{\c_@@_sec_format_tl}
@@ -3379,7 +3813,7 @@
 % \begin{macro}{\njuchapter}
 % 封装无编号章环境,供用户在正文中使用。
 %    \begin{macrocode}
-\NewDocumentCommand \njuchapter { m } { \@@_chapter:V { #1 } }
+\NewDocumentCommand \njuchapter { m } { \@@_chapter:n { #1 } }
 %    \end{macrocode}
 % \end{macro}
 %
@@ -3587,7 +4021,7 @@
 % 如果需要在每章后附上一个参考文献表,即对 \pkg{biblatex} 传入了
 %  |refsection = chapter| 选项,则默认为 |section| 级别。
 %    \begin{macrocode}
-    \defbibheading { njubibintoc } [ \bibname ] { \@@_chapter:V { ##1 } }
+    \defbibheading { njubibintoc } [ \bibname ] { \@@_chapter:n { ##1 } }
     \tl_if_eq:NnTF \blx at refsecreset@level { 2 }
       { \DeclarePrintbibliographyDefaults { heading = subbibintoc } }
       { \DeclarePrintbibliographyDefaults { heading = njubibintoc } }
@@ -3641,7 +4075,7 @@
   }
 %    \end{macrocode}
 %
-% \begin{macro}{\@@_cref_name:n,}
+% \begin{macro}{\@@_cref_name:n,\@@_cref_name:V}
 % 用于修改 \pkg{cleverref} 的标签名称的辅助函数。
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_cref_name:n #1
@@ -3652,6 +4086,7 @@
           { \@@_name:n { ##1 } } { \@@_name:n { ##1 _en } }
       }
   }
+\cs_generate_variant:Nn \@@_cref_name:n { V }
 %    \end{macrocode}
 % \end{macro}
 %
@@ -3668,7 +4103,7 @@
 % 修改 \pkg{cleverref} 的标签名称。
 %    \begin{macrocode}
 \@@_cref_name:n { figure, table, appendix, proof }
-\exp_args:NV \@@_cref_name:n \c_@@_theorem_type_clist
+\@@_cref_name:V \g_@@_theorem_type_clist
 %    \end{macrocode}
 %
 %
@@ -3679,6 +4114,12 @@
 \DeclareGraphicsExtensions { .pdf, .eps, .jpg, .png }
 %    \end{macrocode}
 %
+% \changes{v0.16}{2022/03/11}{表格内字体设为五号。}
+% 表格默认居中,字号设置为五号。^^A  https://www.zhihu.com/question/366803177/answer/977853129
+%    \begin{macrocode}
+\BeforeBeginEnvironment { tabular } { \centering \zihao {5} }
+%    \end{macrocode}
+%
 % \changes{v0.12}{2021/12/06}{删除了可能导致冲突的 \pkg{floatrow}。}
 % 图表标题样式。文字设置为五号宋体,标签设置为粗体,间隔一个全角空格。
 %    \begin{macrocode}
@@ -3728,311 +4169,29 @@
 \newtheorem* { proof } { \c_@@_name_proof_tl }
 %    \end{macrocode}
 %
-% 定义普通定理环境。
+% 定义普通定理环境,需要排除 \env{proof}。
 %    \begin{macrocode}
-\@@_new_theorem:N \c_@@_theorem_type_clist
+\group_begin:
+  \clist_remove_all:Nn \g_@@_theorem_type_clist { proof }
+  \@@_new_theorem:N \g_@@_theorem_type_clist
+\group_end:
+%</class>
 %    \end{macrocode}
 %
 %
 % \subsection{封面}
 %
-% \subsubsection{内部命令}
 %
-% \begin{macro}{\@@_split_title:n}
-% 分割标题。
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_split_title:n #1
-  {
-    \tl_if_in:VnTF { #1 } { \\ }
-      {
-%    \end{macrocode}
-% 从 |\\| 进行分割,存入 |clist|。
-%    \begin{macrocode}
-        \seq_set_split:NnV \l_@@_tmp_seq { \\ } { #1 }
-        \clist_set_from_seq:NN \l_@@_tmp_clist \l_@@_tmp_seq
-      }
-      {
-%    \end{macrocode}
-% 如果没找到换行符,则手动从固定宽度的位置进行分割。
-%    \begin{macrocode}
-        \@@_put_inempty_seg:nnn { #1 } { 1  } { 15 }
-        \@@_put_inempty_seg:nnn { #1 } { 16 } { 15 }
-        \@@_put_inempty_seg:nnn { #1 } { 31 } { 15 }
-      }
-  }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_multiline_title:nnn}
-% 生成多行标题。
-% \begin{arguments}
-%   \item 内容格式
-%   \item 名称盒子宽度,|dim| 型变量
-%   \item 内容盒子宽度,|dim| 型变量
-% \end{arguments}
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_multiline_title:nnn #1#2#3
-  {
-    \@@_split_title:n { \l_@@_info_title_tl }
-    \@@_spread_box:nnn { #2 } { \kaishu } { \c_@@_name_title_tl }
-    \@@_hskip:
-    \clist_map_inline:Nn \l_@@_tmp_clist
-      { \@@_ulined_center_box:nn { #3 } { #1 ##1 } \@@_vskip: }
-  }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_cover_entry:nnn}
-% 生成单项信息条目。
-% \begin{arguments}
-%   \item 条目名称
-%   \item 名称盒子宽度,|dim| 型变量
-%   \item 内容盒子宽度,|dim| 型变量
-% \end{arguments}
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_cover_entry:nnn #1#2#3
-  {
-    \@@_spread_box:nnn { #2 } { \kaishu } { \@@_name:n { #1 } }
-    \@@_hskip:
-    \@@_ulined_center_box:nn { #3 }       { \@@_info:n { #1 } }
-    \@@_vskip:
-  }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_cover_bientry:nnnn}
-% 生成两项信息条目,仅用于本科生封面。
-% \begin{arguments}
-%   \item 左侧条目名称
-%   \item 右侧条目名称
-%   \item 名称盒子宽度,|dim| 型变量
-%   \item 内容盒子宽度,|dim| 型变量
-% \end{arguments}
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_cover_bientry:nnnn #1#2#3#4
-  {
-    \@@_spread_box:nnn { #3 } { \kaishu } { \@@_name:n { #1 } }
-    \@@_hskip:
-    \@@_ulined_center_box:nn { #4 }       { \@@_info:n { #1 } }
-    \skip_horizontal:n { 0.5 em }
-    \@@_spread_box:nnn { #3 } { \kaishu } { \@@_name:n { #2 } }
-    \@@_hskip:
-    \@@_ulined_center_box:nn { #4 }       { \@@_info:n { #2 } }
-    \@@_vskip:
-  }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_cover_supv_entry:nnn}
-% 生成两项导师信息条目,仅用于本科生封面。
-% \begin{arguments}
-%   \item 条目名称
-%   \item 长内容盒子宽度,|dim| 型变量
-%   \item 短内容盒子宽度,|dim| 型变量
-% \end{arguments}
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_cover_supv_entry:nnn #1#2#3
-  {
-    \@@_spread_box:nnn { #2 } { \kaishu } { \@@_name:n { #1 } }
-    \@@_hskip:
-    \@@_ulined_center_box:nn { #3 }
-      { \clist_item:cn { l_@@_info_ #1 _clist } { 1 } }
-    \skip_horizontal:n { 0.5 em }
-    \@@_spread_box:nnn { #2 } { \kaishu } { \c_@@_name_supv_ttl_tl }
-    \@@_hskip:
-    \@@_ulined_center_box:nn { #3 }
-      { \clist_item:cn { l_@@_info_ #1 _clist } { 2 } }
-    \@@_vskip:
-  }
-%    \end{macrocode}
-% \end{macro}
-%
-%
-% \subsubsection{定义对象}
-% \changes{v0.15}{2022/01/24}{使用 \pkg{xtemplate} 重构封面。}
-%
-% 本模板使用 \pkg{xtemplate} 提供的面向对象方法简化封面和摘要的绘制过程。
-%
-% 以下分别从页面元素(element)和页面整体(page)的层次进行了抽象。当我们把页面部件考虑为一个对象时,它天然地只具备有限数量的属性:内容、格式、边距、对齐方式等。而具体的页面是这些对象的实例的集合,附加边距、行距等属性,创建页面只需传入一个列表调用各个 Instance 即可。通过 \pkg{xtemplate} 提供的功能,我们可以根据这些属性创建模板(template),进而能大量构建具有\emph{相似行为}的实例(instance)。这种做法能充分分离内容和样式,极大优化代码的可读性。
-%
-% 声明对象类型。此类对象不需要参数。
-%    \begin{macrocode}
-\DeclareObjectType { nju } { \c_zero_int }
-%    \end{macrocode}
-%
-% 定义元素模板。
-%    \begin{macrocode}
-%<@@=njuelem>
-%    \end{macrocode}
-%
-% 声明页面元素模板接口。
-% 元素是一个页面的基本组成单位,包括文段、图片等等。一个抽象的元素应当具备以下属性:
-% \begin{description}
-%   \item[\opt{content}] 内容,即剥离样式的元素本身
-%   \item[\opt{format}] 格式,例如字号、字体
-%   \item[\opt{bottom-skip}] 下间距,即与下一个元素的距离
-%   \item[\opt{align}] 对齐方式,包括左对齐、右对齐、居中、正常段落
-% \end{description}
-%    \begin{macrocode}
-\DeclareTemplateInterface { nju } { element } { \c_zero_int }
-  {
-    content     : tokenlist = \c_empty_tl,
-    format      : tokenlist = \c_empty_tl,
-    bottom-skip : skip      = \c_zero_skip,
-    align       : choice { l, r, c, n } = c
-  }
-%    \end{macrocode}
-%
-% 声明页面元素模板代码。涉及的变量将被自动创建。
-%    \begin{macrocode}
-\DeclareTemplateCode { nju } { element } { \c_zero_int }
-  {
-    content     = \l_@@_content_tl,
-    format      = \l_@@_format_tl,
-    bottom-skip = \l_@@_bottom_skip,
-    align =
-      {
-        l =
-          { \tl_set_eq:NN \l_@@_begin_align_tl \flushleft
-            \tl_set_eq:NN \l_@@_end_align_tl   \endflushleft  },
-        r =
-          { \tl_set_eq:NN \l_@@_begin_align_tl \flushright
-            \tl_set_eq:NN \l_@@_end_align_tl   \endflushright },
-        c =
-          { \tl_set_eq:NN \l_@@_begin_align_tl \center
-            \tl_set_eq:NN \l_@@_end_align_tl   \endcenter     },
-        n =
-          { \tl_clear:N   \l_@@_begin_align_tl
-            \tl_clear:N   \l_@@_end_align_tl                  }
-      }
-  }
-  {
-    \AssignTemplateKeys
-    \group_begin:
-      \l_@@_begin_align_tl
-      \l_@@_format_tl
-      \l_@@_content_tl \par
-      \l_@@_end_align_tl
-    \group_end:
-    \__nju_vskip:N \l_@@_bottom_skip
-  }
-%    \end{macrocode}
-%
-% 定义页面模板。
-%    \begin{macrocode}
-%<@@=njupage>
-%    \end{macrocode}
-%
-% 声明页面模板接口。
-% 页面是元素的集合。一个抽象的页面应当具备以下属性:
-% \begin{description}
-%   \item[\opt{element}] 包含的元素,这里使用的是名称列表
-%   \item[\opt{prefix}] 元素名称前缀
-%   \item[\opt{format}] 格式,例如行距
-%   \item[\opt{top-skip}] 上间距,即与页面顶部的距离
-%   \item[\opt{bottom-skip}] 下间距,即与页面底部的距离
-% \end{description}
-%    \begin{macrocode}
-\DeclareTemplateInterface { nju } { page } { \c_zero_int }
-  {
-    element     : commalist = \c_empty_clist,
-    prefix      : tokenlist = \c_empty_tl,
-    format      : tokenlist = \c_empty_tl,
-    top-skip    : skip      = \c_zero_skip,
-    bottom-skip : skip      = \c_zero_skip
-  }
-%    \end{macrocode}
-%
-% 声明页面模板代码。
-%    \begin{macrocode}
-\DeclareTemplateCode { nju } { page } { \c_zero_int }
-  {
-    element     = \l_@@_element_clist,
-    prefix      = \l_@@_prefix_tl,
-    format      = \l_@@_format_tl,
-    top-skip    = \l_@@_top_skip,
-    bottom-skip = \l_@@_bottom_skip
-  }
-  {
-    \AssignTemplateKeys
-    \newpage
-    \__nju_vskip:N \l_@@_top_skip
-    \group_begin:
-      \l_@@_format_tl
-      \clist_map_inline:Nn \l_@@_element_clist
-        { \UseInstance { nju } { \l_@@_prefix_tl ##1 } }
-    \group_end:
-    \__nju_vskip:N \l_@@_bottom_skip
-  }
-%<@@=nju>
-%    \end{macrocode}
-%
-% \begin{macro}{\@@_declare_element:nn,\@@_declare_page:nn}
-% 封装 \pkg{xtemplate} 提供的函数,简化创建实例的过程。
-% \begin{arguments}
-%   \item 实例名称
-%   \item 参数列表
-% \end{arguments}
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_declare_element:nn #1#2
-  { \DeclareInstance { nju } {#1} { element } {#2} }
-\cs_new_protected:Npn \@@_declare_page:nn    #1#2
-  { \DeclareInstance { nju } {#1} { page    } {#2} }
-%    \end{macrocode}
-% \end{macro}
-%
-%
 % \subsubsection{绘制部件}
 %
-%    \begin{macrocode}
-\keys_define:nn { nju / style }
-  {
-%    \end{macrocode}
-% \begin{macro}{style/emblem-img}
-% \changes{v0.14}{2021/12/23}{提供选择外置校徽图片的接口。}
-% 校徽图片路径。
-%    \begin{macrocode}
-    emblem-img .tl_set:N = \l_@@_emblem_img_tl,
-%    \end{macrocode}
-% \end{macro}
-% \begin{macro}{style/name-img}
-% \changes{v0.14}{2021/12/23}{提供选择外置校名图片的接口。}
-% 校名图片路径。
-%    \begin{macrocode}
-    name-img   .tl_set:N = \l_@@_name_img_tl
-  }
-%    \end{macrocode}
-% \end{macro}
+% \changes{v0.16}{2022/03/01}{将封面部件分离到 \file{.def} 文件。}
 %
-% 根据导言区载入的用户设置进行一些处理。
-%    \begin{macrocode}
-\ctex_at_end_preamble:n
-  {
-%    \end{macrocode}
-% \begin{macro}{\njuemblem,\njuname}
-% 如果用户在定义了图片的路径,则覆盖 \pkg{njuvisual} 提供的绘制命令。
-%    \begin{macrocode}
-    \tl_if_empty:NF \l_@@_emblem_img_tl
-      {
-        \RenewDocumentCommand \njuemblem { o m m }
-          { \includegraphics [ width = #2, height = #3 ]
-              { \l_@@_emblem_img_tl } }
-      }
-    \tl_if_empty:NF \l_@@_name_img_tl
-      {
-        \RenewDocumentCommand \njuname { o m m }
-          { \includegraphics [ width = #2, height = #3 ]
-              { \l_@@_name_img_tl } }
-      }
-  }
-%    \end{macrocode}
-% \end{macro}
-%
 % \paragraph{本科生}
 %
 % \begin{macro}{cover/ug/emblem-img}
 % 本科生封面校徽图片实例。
 %    \begin{macrocode}
+%<*definition-ug>
 \@@_declare_element:nn { cover / ug / emblem-img }
   {
     content = \njuemblem [ black ] { ! } { 3.35 cm },
@@ -4059,7 +4218,7 @@
 \@@_declare_element:nn { cover / ug / title }
   {
     content  =
-      \@@_spread_box:nnn { 9 em } { \bf } { \l_@@_info_type_tl },
+      \@@_spread_box:nnV { 9 em } { \bf } \l_@@_info_type_tl,
     format   = \zihao { -1 },
     bottom-skip = 0 pt plus 1.5 fill
   }
@@ -4101,6 +4260,7 @@
       \@@_cover_entry:nnn { sm_date  } { #1 } { #2 }
     \end{minipage}
   }
+%</definition-ug>
 %    \end{macrocode}
 % \end{macro}
 %
@@ -4111,6 +4271,7 @@
 % \begin{macro}{cover/g/emblem-img}
 % 研究生封面校徽图片实例。
 %    \begin{macrocode}
+%<*definition-g>
 \@@_declare_element:nn { cover / g / emblem-img }
   {
     content     = \njuemblem [ black ] { ! } { 1.9 cm },
@@ -4124,7 +4285,7 @@
 %    \begin{macrocode}
 \@@_declare_element:nn { cover / g / name-img }
   {
-    content = \njuname [ black ] { 4.4 cm } { ! },
+    content     = \njuname [ black ] { 4.4 cm } { ! },
     bottom-skip = 2 cm
   }
 %    \end{macrocode}
@@ -4136,7 +4297,7 @@
 \@@_declare_element:nn { cover / g / type }
   {
     content     =
-      \@@_spread_box:nnn { 9 em } { } { \l_@@_info_type_tl },
+      \@@_spread_box:nnV { 9 em } { } \l_@@_info_type_tl,
     format      = \zihao { -1 } \bfseries,
     bottom-skip = 1 cm
   }
@@ -4211,13 +4372,13 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_cover_back_g:
   {
-    \@@_spread_box:nnn { 6.2 em } { \kaishu } { \c_@@_name_id_tl }
+    \@@_spread_box:nnV { 6.2 em } { \kaishu } \c_@@_name_id_tl
     { : \@@_quad: } \l_@@_info_id_tl
     \@@_vskip:
-    \@@_spread_box:nnn { 6.2 em } { \kaishu } { \c_@@_name_df_date_tl }
+    \@@_spread_box:nnV { 6.2 em } { \kaishu } \c_@@_name_df_date_tl
     { : \@@_quad: } \l_@@_info_df_date_tl
     \@@_vskip:
-    \@@_spread_box:nnn { 6.2 em } { \kaishu } { \c_@@_name_supv_full_tl }
+    \@@_spread_box:nnV { 6.2 em } { \kaishu } \c_@@_name_supv_full_tl
     { : \@@_quad: } \skip_horizontal:n { 8 em } \c_@@_name_sign_tl
   }
 %    \end{macrocode}
@@ -4264,7 +4425,7 @@
     content     =
       \c_@@_cover_en_text_tl \@@_vskip:
       \textsc { \clist_item:Nn \c_@@_name_degree_en_clist
-                  { \l_@@_info_degree_int } }
+                  { \g_@@_info_degree_int } }
       \@@_vskip: { in } \@@_vskip:
       \l_@@_info_major_en_tl,
     bottom-skip = 2 cm
@@ -4315,7 +4476,7 @@
 \@@_declare_element:nn { cover / nl / name }
   {
     content     =
-      \@@_spread_box:nnn { 6 em } { } { \c_@@_name_title_tl },
+      \@@_spread_box:nnV { 6 em } { } \c_@@_name_title_tl,
     format      = \zihao { -0 },
     bottom-skip = 0 pt plus 1.2 fil
   }
@@ -4374,11 +4535,11 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_cover_top_nl:
   {
-    \@@_spread_box:nnn { 3.2 em } { } { \c_@@_name_clc_tl   } \@@_hskip:
+    \@@_spread_box:nnV { 3.2 em } { } \c_@@_name_clc_tl   \@@_hskip:
     \@@_ulined_center_box:nn { 9 em } { \l_@@_info_clc_tl   } \hfill
-    \@@_spread_box:nnn { 3.2 em } { } { \c_@@_name_seclv_tl } \@@_hskip:
+    \@@_spread_box:nnV { 3.2 em } { } \c_@@_name_seclv_tl \@@_hskip:
     \@@_ulined_center_box:nn { 9 em } { \l_@@_info_seclv_tl } \\
-    \@@_spread_box:nnn { 3.2 em } { } { \c_@@_name_udc_tl   } \@@_hskip:
+    V { 3.2 em } { } { \c_@@_name_udc_tl   } \@@_hskip:
     \@@_ulined_center_box:nn { 9 em } { \l_@@_info_udc_tl   } \hfill \null
   }
 %    \end{macrocode}
@@ -4389,10 +4550,10 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_cover_title_nl:
   {
-    \@@_split_title:n { \l_@@_info_title_tl }
+    \@@_split_title:V \l_@@_info_title_tl
     \@@_multiline_box:nnnn { \l_@@_tmp_int } \l_@@_tmp_clist { 3 } { 15 em }
     \skip_vertical:n { - 0.5 cm }
-    { \zihao { 4 } \c_@@_name_title_nl_tl }
+    { \zihao { 4 } \c_@@_name_title_b_tl }
     \skip_vertical:N \c_zero_skip
     \@@_ulined_center_box:nn { 4.5 em } { \l__nju_info_author_tl }
     \skip_vertical:n { - 0.5 cm }
@@ -4414,7 +4575,7 @@
     \@@_ulined_center_box:nn { \textwidth } { \@@_info:n { supv_ttl }
     \@@_quad: \@@_info:n  { supv_cont } }                             \\
     \@@_uline_bientry:Nnnn \l_@@_tmp_dim { degree   } { degree  } { }
-    \@@_uline_bientry:Nnnn \l_@@_tmp_dim { major_nl } { major   } { } \\
+    \@@_uline_bientry:Nnnn \l_@@_tmp_dim { major_b  } { major   } { } \\
     \@@_uline_bientry:Nnnn \l_@@_tmp_dim { sm_date  } { sm_date } { }
     \@@_uline_bientry:Nnnn \l_@@_tmp_dim { df_date  } { df_date } { } \\
     \@@_full_uline:Nn \l_@@_tmp_dim { \c_@@_name_confer_tl }
@@ -4434,6 +4595,7 @@
     \@@_multiline_box:nnnn { \l_@@_tmp_int }
       { \l_@@_info_reviewer_clist } { 4 } { 9 em }
   }
+%</definition-g>
 %    \end{macrocode}
 % \end{macro}
 %
@@ -4449,6 +4611,7 @@
 % \begin{macro}{cover-ug-default}
 % 默认本科生封面实例。
 %    \begin{macrocode}
+%<*definition-ug>
 \@@_declare_page:nn { cover-ug-default }
   {
     element     = { emblem-img, name-img, title, info },
@@ -4455,6 +4618,7 @@
     prefix      = cover / ug /,
     bottom-skip = 0.5 cm plus 1.5 fill
   }
+%</definition-ug>
 %    \end{macrocode}
 % \end{macro}
 %
@@ -4461,6 +4625,7 @@
 % \begin{macro}{cover-g-front-default}
 % 默认研究生普通封面正面实例。
 %    \begin{macrocode}
+%<*definition-g>
 \@@_declare_page:nn { cover-g-front-default }
   {
     element  = { emblem-img, name-img, type, degree, info, date },
@@ -4505,24 +4670,19 @@
     prefix  = cover / nl /,
     format  = \kaishu
   }
+%</definition-g>
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_make_cover_ug:}
-% 生成本科生封面。
+% \begin{macro}{\@@_make_cover:}
+% 生成本科生或研究生的普通封面。
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_make_cover_ug:
-  { \UseInstance { nju } { cover-ug-default } }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_make_cover_g:}
-% 生成研究生的普通封面。
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_make_cover_g:
+%<*(definition-ug|definition-g)>
+\cs_new_protected:Npn \@@_make_cover:
   {
-    \clist_map_inline:nn { front, back, en }
-      { \UseInstance { nju } { cover-g- ##1 -default } }
+%<definition-ug>    \UseInstance { nju } { cover-ug-default }
+%<definition-g>    \clist_map_inline:nn { front, back, en }
+%<definition-g>      { \UseInstance { nju } { cover-g- ##1 -default } }
   }
 %    \end{macrocode}
 % \end{macro}
@@ -4530,8 +4690,8 @@
 % \begin{macro}{\@@_make_cover_nl:}
 % 生成研究生的国家图书馆封面。
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_make_cover_nl:
-  { \UseInstance { nju } { cover-nl-default } }
+%<definition-g>\cs_new_protected:Npn \@@_make_cover_nl:
+%<definition-g>  { \UseInstance { nju } { cover-nl-default } }
 %    \end{macrocode}
 % \end{macro}
 %
@@ -4541,19 +4701,18 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_make_orig_decl:
   {
-    \chapter* { \c_@@_name_nju_tl \c_@@_name_orig_decl_tl }
+    \chapter* { \c_@@_name_orig_decl_tl }
     \thispagestyle { empty }
     \c_@@_orig_decl_text_tl
     \vfil
     \begin{flushright}
-      \clist_set:Nn \l_@@_tmp_clist { orig_sign, id, orig_date }
-      \int_compare:nF { \l_@@_info_degree_int == 1 }
-        { \clist_remove_all:Nn \l_@@_tmp_clist { id } }
-      \clist_map_inline:Nn \l_@@_tmp_clist
+%<definition-ug>      \clist_map_inline:nn { orig_sign, id, orig_date }
+%<definition-g>      \clist_map_inline:nn { orig_sign,     orig_date }
         { \@@_vskip: \@@_name:n { ##1 } : \@@_uline:n { 7 em } }
     \end{flushright}
     \vfil
   }
+%</(definition-ug|definition-g)>
 %    \end{macrocode}
 % \end{macro}
 %
@@ -4560,6 +4719,71 @@
 %
 % \subsubsection{用户接口}
 %
+% \begin{macro}{\@@_new_img_cmd:nn,\@@_new_img_cmd:nV}
+% 用于定义插入图片命令的辅助函数。
+%    \begin{macrocode}
+%<*class>
+\cs_new_protected:Npn \@@_new_img_cmd:nn #1#2
+  {
+    \exp_args:Nc \NewDocumentCommand { #1 } { o m m }
+      { \includegraphics [ width = ##2, height = ##3 ] { #2 } }
+  }
+\cs_generate_variant:Nn \@@_new_img_cmd:nn { nV }
+%    \end{macrocode}
+% \end{macro}
+%
+%    \begin{macrocode}
+\keys_define:nn { nju / style }
+  {
+%    \end{macrocode}
+% \begin{macro}{style/emblem-img,\njuemblem}
+% \changes{v0.14}{2021/12/23}{提供选择外置校徽图片的接口。}
+% 校徽图片路径。
+%    \begin{macrocode}
+    emblem-img .code:n =
+      { \@@_new_img_cmd:nV { njuemblem } \l_keys_value_tl },
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{style/name-img,\njuname}
+% \changes{v0.14}{2021/12/23}{提供选择外置校名图片的接口。}
+% 校名图片路径。
+%    \begin{macrocode}
+    name-img   .code:n =
+      { \@@_new_img_cmd:nV { njuname   } \l_keys_value_tl }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \changes{v0.16}{2022/02/22}{不再默认载入 \pkg{njuvisual}。}
+% 检查 \cs{njuemblem} 和 \cs{njuname} 命令是否有定义。
+%    \begin{macrocode}
+\msg_new:nnn { njuthesis } { missing-image }
+  {
+    Local~ images~ not~ designated.\\
+    It~ seems~ that~ you~ haven't~ fill~ in~ both~
+    "style/emblem-img"~ and~ "style/name-img",~
+    therefore~ I~ am~ using~ package~ "njuvisual"~
+    instead,~ which~ may~ slow~ down~ the~ compilation.
+  }
+\ctex_at_end_preamble:n
+  {
+%    \end{macrocode}
+% 如果校名、校徽图片其中之一的路径未被定义,
+% 则全盘使用 \pkg{njuvisual} 提供的绘制命令。
+%    \begin{macrocode}
+    \bool_lazy_and:nnF
+      { \cs_if_exist_p:N \njuemblem }
+      { \cs_if_exist_p:N \njuname   }
+      {
+        \cs_undefine:N \njuemblem
+        \cs_undefine:N \njuname
+        \msg_warning:nn { njuthesis } { missing-image }
+        \RequirePackage { njuvisual }
+      }
+  }
+%    \end{macrocode}
+%
 % \begin{macro}{\maketitle}
 % \changes{v0.12}{2021/12/01}{仅会生成国家图书馆封面或者普通封面之一。}
 % \changes{v0.13}{2021/12/12}{重新绘制封面。}
@@ -4579,7 +4803,7 @@
 %    \begin{macrocode}
         \bool_if:NTF \g_@@_nlcover_bool
           { \@@_make_cover_nl: }
-          { \use:c { @@_make_cover_ \l_@@_info_diploma_tl : } }
+          { \@@_make_cover:    }
 %    \end{macrocode}
 % 如果在选择了 \opt{decl-page},就生成本科生的诚信承诺书或研究生的原创性声明。
 %    \begin{macrocode}
@@ -4593,10 +4817,10 @@
 % 在标题页后使用大写罗马字母页码,恢复正常字体设置。
 %    \begin{macrocode}
     \cleardoublepage
-    \pagestyle     { plain }
+    \exp_args:NV \pagestyle \c_@@_pagestyle_tl
     \pagenumbering { Roman }
-    \normalfont \normalsize
   }
+%</class>
 %    \end{macrocode}
 % \end{macro}
 %
@@ -4603,80 +4827,69 @@
 %
 % \subsection{摘要页}
 %
-% \subsubsection{内部命令}
+% \subsubsection{绘制部件}
+% \changes{v0.16}{2022/03/02}{将摘要部件分离到 \file{.def} 文件。}
+% \changes{v0.16}{2022/03/02}{使用 \pkg{xtemplate} 重构摘要。}
 %
+% \begin{macro}{abstract/title}
+% 中文摘要标题实例。
 %    \begin{macrocode}
-\keys_define:nn { nju / style }
+%<*(definition-ug|definition-g)>
+\@@_declare_element:nn { abstract / title }
   {
-%    \end{macrocode}
-% \begin{macro}{style/abstract-in-toc}
-% \changes{v0.15}{2022/02/04}{可选择摘要是否出现在目录中。}
-% 是否将摘要添加到目录。
-%    \begin{macrocode}
-    abstract-in-toc .bool_gset:N = \g_@@_abs_in_toc_bool,
-    abstract-in-toc   .initial:n = true
+    content     = \@@_abs_title:V \c_@@_name_abstract_title_tl,
+    format      = \bfseries \kaishu \zihao { -2 },
+    bottom-skip = 1.2 cm
   }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_abs_bookmark:nn}
-% \changes{v0.14}{2021/12/21}{将摘要插入目录。}
-% 生成摘要的目录条目。
+% \begin{macro}{abstract/info}
+% 中文摘要信息栏实例。
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_abs_bookmark:nn #1#2
+\@@_declare_element:nn { abstract / info }
   {
-    \phantomsection
-    \bool_if:NTF \g_@@_abs_in_toc_bool
-      { \@@_add_tocline:n { #1 } }
-      { \pdfbookmark [0] { #1 } { #2 } }
+%<definition-ug>    content     = \@@_abs_info_ug:nn { } { : },
+%<definition-g>    content     = \@@_abs_info_g:n       { : },
+%<definition-ug>    format      = \zihao { -4 } \kaishu,
+%<definition-g>    format      = \zihao {  4 } \kaishu,
+    align       = l,
+    bottom-skip = 1 cm
   }
-\cs_generate_variant:Nn \@@_abs_bookmark:nn { Vn }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_abs_title_uuline:n}
-% 摘要标题双层下划线格式。
-% \begin{arguments}
-%   \item 宽度,|dim| 型变量
-% \end{arguments}
+% \begin{macro}{abstract/en/title}
+% 英文摘要标题实例。
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_abs_title_uuline:n #1
-  { \bf \kaishu \zihao { -2 } \@@_uuline:n { #1 } }
+\@@_declare_element:nn { abstract / en / title }
+  {
+    content     = \@@_abs_title:V \c_@@_name_abstract_title_en_tl,
+    format      = \bfseries \kaishu \zihao { -2 },
+    bottom-skip = 1.2 cm
+  }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_abs_info_style:n,\@@_abs_info_style_en:n}
-% 摘要信息栏通用格式,设置为无缩进、四号或者小四号、楷书。
-% \begin{arguments}
-%   \item 字号
-% \end{arguments}
+% \begin{macro}{abstract/en/info}
+% 英文摘要信息栏实例。
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_abs_info_style:n #1
-  { \noindent \zihao{ #1 } \kaishu }
-\cs_new_protected:Npn \@@_abs_info_style_en: #1
-  { \zihao{ #1 } }
+\@@_declare_element:nn { abstract / en / info }
+  {
+%<definition-ug>    content     = \@@_abs_info_ug:nn { _en } { :~ },
+%<definition-g>    content     = \@@_abs_info_en_g:n        { :~ },
+%<definition-ug>    format      = \zihao { -4 },
+%<definition-g>    format      = \zihao {  4 },
+    align       = l,
+    bottom-skip = 1 cm
+  }
+%</(definition-ug|definition-g)>
 %    \end{macrocode}
 % \end{macro}
 %
-%
-% \subsubsection{绘制部件}
-%
 % \paragraph{本科生}
+% \changes{v0.13}{2021/12/12}{使用 \hologo{LaTeX3} 语法重构本科生摘要。}
 %
-% \begin{macro}{\@@_abs_title_ug:n}
-% 绘制本科生摘要标题。
-% \begin{arguments}
-%   \item 语言,空置为中文,|_en| 为英文
-% \end{arguments}
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_abs_title_ug:n #1
-  {
-    \clist_map_inline:nn { nju, type, lang #1, abstract }
-      { \@@_name:n { ##1 } }
-  }
-%    \end{macrocode}
-% \end{macro}
-%
 % \begin{macro}{\@@_abs_info_ug:nn}
 % 绘制本科生摘要信息栏。
 % \begin{arguments}
@@ -4685,6 +4898,7 @@
 % \end{arguments}
 % 本科生摘要页面不含下划线,因而不用确定文本宽度,绘制命令较为简单。
 %    \begin{macrocode}
+%<*definition-ug>
 \cs_new_protected:Npn \@@_abs_info_ug:nn #1#2
   {
 %    \end{macrocode}
@@ -4692,12 +4906,12 @@
 %    \begin{macrocode}
     \tl_if_blank:eTF { #1 }
       { \c_@@_name_title_tl }
-      { \clist_item:Nn \c_@@_name_type_en_clist { \l_@@_info_type_int } }
+      { \clist_item:Nn \c_@@_name_type_en_clist { \g_@@_info_type_int } }
     #2 \tl_use:c { l_@@_info_title #1 _tl } \\
 %    \end{macrocode}
 % 由于作者姓名使用的字样发生了变动,这里进行替换以便嵌入循环。
 %    \begin{macrocode}
-    \tl_set_eq:NN \c_@@_name_author_tl \c_@@_name_author_full_tl
+    \tl_set_eq:NN \c_@@_name_author_tl \c_@@_name_author_a_tl
 %    \end{macrocode}
 % 使用循环输出院系、专业、作者、导师信息。
 %    \begin{macrocode}
@@ -4705,91 +4919,82 @@
       { \@@_name:n { ##1 #1 } #2 \@@_info:n { ##1 #1 } \\ }
     \@@_name:n { abstract #1 } #2
   }
+%</definition-ug>
 %    \end{macrocode}
 % \end{macro}
 %
 % \paragraph{研究生}
+% \changes{v0.13}{2021/12/12}{使用 \hologo{LaTeX3} 语法重构研究生摘要。}
 %
-% \begin{macro}{\@@_abs_title_g:n}
-% 绘制研究生摘要标题。
+% \begin{macro}{\@@_abs_info_g:n}
+% 绘制研究生中文摘要信息栏。
 % \begin{arguments}
-%   \item 语言,空置为中文,|_en| 为英文
-% \end{arguments}
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_abs_title_g:n #1
-  {
-    \@@_name:n { nju     } \@@_info:n { type       }
-    \@@_name:n { lang #1 } \@@_name:n { abstract_r }
-  }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_abs_info_g:nn}
-% 绘制研究生摘要信息栏。
-% \begin{arguments}
-%   \item 语言,空置为中文,|_en| 为英文
 %   \item 分隔符
-% 研究生摘要页包括下划线以及若干特殊的对齐方式,实现方式较为繁琐。
 % \end{arguments}
+% 研究生中文摘要页包括下划线以及若干特殊的对齐方式,实现方式较为繁琐。使用 \cs{@@_full_uline:NV} 确定内容宽度后,调用 \cs{@@_uline:n} 或 \cs{@@_ulined_center_box:nn} 命令以绘制横穿页面的下划线。前两行为标题。
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_abs_info_g:nn #1#2
+%<*definition-g>
+\cs_new_protected:Npn \@@_abs_info_g:n #1
   {
-    \tl_if_blank:eTF { #1 }
+    \@@_full_uline:NV \l_@@_tmp_dim
       {
+        \clist_item:Nn \c_@@_name_type_clist { \g_@@_info_type_int }
+        \c_@@_name_title_a_tl #1
+      }
+    \@@_ulined_center_box:nn { \l_@@_tmp_dim }
+      { \tl_range:Nnn \l_@@_info_title_tl { 1 } { 20 } } \\
+    \@@_uline:n { \textwidth } \@@_qquad:
+    \tl_range:Nnn \l_@@_info_title_tl { 21 } { -1 } \\
 %    \end{macrocode}
-% 中文摘要环境,使用 \cs{@@_full_uline:NV} 确定内容宽度后,调用 \cs{@@_uline:n} 或 \cs{@@_ulined_center_box:nn} 命令以绘制横穿页面的下划线。前两行为标题。
-%    \begin{macrocode}
-        \@@_full_uline:NV \l_@@_tmp_dim
-          {
-            \clist_item:Nn \c_@@_name_type_clist { \l_@@_info_type_int }
-            \c_@@_name_title_s_tl #2
-          }
-        \@@_ulined_center_box:nn { \l_@@_tmp_dim }
-          { \tl_range:Nnn \l_@@_info_title_tl { 1 } { 20 } } \\
-        \@@_uline:n { \textwidth } \@@_qquad:
-        \tl_range:Nnn \l_@@_info_title_tl { 21 } { -1 } \\
-%    \end{macrocode}
 % 专业、年级、姓名。
 %    \begin{macrocode}
-        \@@_full_uline:NV \l_@@_tmp_dim
-          {
-            \@@_ulined_center_box:nn { 11 em } { \l_@@_info_major_tl }
-            \c_@@_name_major_s_tl
-            \@@_ulined_center_box:nn { 4 em } { \l_@@_info_grade_tl }
-            \c_@@_name_grade_tl
-            \tl_item:nn { \l_@@_info_degree_tl } { 1 }
-            \c_@@_name_author_r_tl #2
-          }
-        \@@_ulined_center_box:nn { \l_@@_tmp_dim }
-          { \l_@@_info_author_tl } \\
+    \@@_full_uline:NV \l_@@_tmp_dim
+      {
+        \@@_ulined_center_box:nn { 11 em } { \l_@@_info_major_tl }
+        \c_@@_name_major_a_tl
+        \@@_ulined_center_box:nn { 4  em } { \l_@@_info_grade_tl }
+        \c_@@_name_grade_tl \c_@@_name_author_a_tl #1
+      }
+    \@@_ulined_center_box:nn { \l_@@_tmp_dim }
+      { \l_@@_info_author_tl } \\
 %    \end{macrocode}
 % 导师姓名、职称。
 %    \begin{macrocode}
-        \@@_full_uline:NV \l_@@_tmp_dim
-          { \c_@@_name_supv_full_tl \c_@@_name_supv_r_tl #2 }
-        \@@_ulined_center_box:nn { \l_@@_tmp_dim }
-          { \l_@@_info_supv_full_tl }
-      }
+    \@@_full_uline:NV \l_@@_tmp_dim
+      { \c_@@_name_supv_a_tl #1 }
+    \@@_ulined_center_box:nn { \l_@@_tmp_dim }
+      { \l_@@_info_supv_full_tl }
+  }
 %    \end{macrocode}
-% 英文摘要环境。前两行为标题。
+% \end{macro}
+%
+% \begin{macro}{\@@_abs_info_en_g:n}
+% 绘制研究生英文摘要信息栏。
+% \begin{arguments}
+%   \item 分隔符
+% \end{arguments}
+% 前两行为标题。
 %    \begin{macrocode}
-      {
-        \@@_full_uline:NV \l_@@_tmp_dim
-          { \clist_item:cn { c_@@_name_type #1 _clist }
-              { \l_@@_info_type_int } # 2 }
-        \@@_ulined_center_box:nn { \l_@@_tmp_dim }
-          { \tl_range:Nnn \l_@@_info_title_en_tl { 1 } { 40 } } \\
-        \@@_uline:n { \textwidth } \@@_qquad:
-        \tl_range:Nnn \l_@@_info_title_en_tl { 41 } { -1 }
+\cs_new_protected:Npn \@@_abs_info_en_g:n #1
+  {
+    \@@_full_uline:NV \l_@@_tmp_dim
+      { \clist_item:Nn \c_@@_name_type_en_clist
+          { \g_@@_info_type_int } #1 }
+    \@@_ulined_center_box:nn { \l_@@_tmp_dim }
+      { \tl_range:Nnn \l_@@_info_title_en_tl { 1 } { 40 } } \\
+    \@@_uline:n { \textwidth } \@@_qquad:
+    \tl_range:Nnn \l_@@_info_title_en_tl { 41 } { -1 }
 %    \end{macrocode}
-% 使用循环输出专业、姓名、导师。注意这里将 |\\| 放置在前部,以避免末尾生成多余的换行符产生 |Underfull \vbox| 信息。
+% 使用循环输出专业、姓名、导师。注意这里将 |\\| 放置在前部,
+% 以避免末尾生成多余的换行符产生 |Underfull \vbox| 信息。
 %    \begin{macrocode}
-        \clist_map_inline:nn { major, author, supv_full }
-          { \\
-            \@@_uline_entry:Nnnn \l_@@_tmp_dim { ##1 _en } { ##1 _en } { #2 }
-          }
+    \clist_map_inline:nn { major, author, supv_full }
+      { \\
+        \@@_uline_entry:Nnnn \l_@@_tmp_dim
+          { ##1 _en } { ##1 _en } { #1 }
       }
   }
+%</definition-g>
 %    \end{macrocode}
 % \end{macro}
 %
@@ -4803,11 +5008,11 @@
 %   \item 关键词分隔符
 % \end{arguments}
 %    \begin{macrocode}
+%<*class>
 \cs_new_protected:Npn \@@_print_keywords:nn #1#2
   {
-    \exp_args:NNc
-      \tl_set_eq:NN \l_@@_tmp_tl { c_@@_name_keywords #1 _tl }
-    \@@_get_text_width:Nn \l_@@_tmp_dim { \l_@@_tmp_tl }
+    \tl_set:Nv \l_@@_tmp_tl { c_@@_name_keywords #1 _tl }
+    \@@_get_text_width:NV \l_@@_tmp_dim \l_@@_tmp_tl
 %    \end{macrocode}
 % 关键词列表的悬挂缩进样式由 \tn{list} 环境产生。
 %    \begin{macrocode}
@@ -4827,6 +5032,7 @@
       \clist_use:cn { l_@@_info_keywords #1 _clist } { #2 }
     \endlist
   }
+%</class>
 %    \end{macrocode}
 % \end{macro}
 %
@@ -4833,53 +5039,42 @@
 %
 % \subsubsection{绘制摘要}
 %
-% \begin{macro}{\@@_make_abs_ug:nn}
-% \changes{v0.13}{2021/12/12}{使用 \hologo{LaTeX3} 语法重构本科生摘要。}
-% \begin{arguments}
-%   \item 语言,空置为中文,|_en| 为英文
-%   \item 关键词分隔符
-% \end{arguments}
-% 生成本科生摘要。
+% \begin{macro}{\@@_make_abstract:,\@@_make_abstract_en:}
+% 绘制摘要页面。
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_make_abs_ug:nn #1#2
+%<*(definition-ug|definition-g)>
+\cs_new_protected:Npn \@@_make_abstract:
   {
-    \begin{center}
-      \@@_abs_title_uuline:n { 22 em }
-      \@@_abs_title_ug:n { #1 }
-    \end{center}
-    \group_begin:
-      \@@_abs_info_style:n { -4 }
-      \@@_abs_info_ug:nn { #1 } { #2 }
-    \group_end: \@@_vskip:
+    \UseInstance { nju } { abstract / title }
+    \UseInstance { nju } { abstract / info  }
   }
+\cs_new_protected:Npn \@@_make_abstract_en:
+  {
+    \UseInstance { nju } { abstract / en / title }
+    \UseInstance { nju } { abstract / en / info  }
+  }
+%</(definition-ug|definition-g)>
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_make_abs_g:nn}
-% \changes{v0.13}{2021/12/12}{使用 \hologo{LaTeX3} 语法重构研究生摘要。}
-% \begin{arguments}
-%   \item 语言,空置为中文,|_en| 为英文
-%   \item 关键词分隔符
-% \end{arguments}
-% 生成研究生摘要。
+%
+% \subsubsection{用户接口}
+%
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_make_abs_g:nn #1#2
+%<*class>
+\keys_define:nn { nju / style }
   {
-    \begin{center}
-      \@@_abs_title_uuline:n { 19 em }
-      \@@_abs_title_g:n { #1 }
-    \end{center}
-    \group_begin:
-      \@@_abs_info_style:n { 4 }
-      \@@_abs_info_g:nn { #1 } { #2 }
-    \group_end: \@@_vskip:
+%    \end{macrocode}
+% \begin{macro}{style/abstract-in-toc}
+% \changes{v0.15}{2022/02/04}{可选择摘要是否出现在目录中。}
+% 是否将摘要添加到目录。
+%    \begin{macrocode}
+    abstract-in-toc .bool_gset:N = \g_@@_abs_in_toc_bool,
+    abstract-in-toc   .initial:n = true
   }
 %    \end{macrocode}
 % \end{macro}
 %
-%
-% \subsubsection{用户接口}
-%
 % \begin{environment}{abstract}
 % \changes{v0.13}{2021/12/12}{重新绘制摘要。}
 % 中文摘要环境。
@@ -4888,9 +5083,8 @@
   {
     \cleardoublepage
     \thispagestyle { plain }
-    \@@_abs_bookmark:Vn
-      { \c_@@_name_lang_tl \c_@@_name_abstract_tl } { abstract }
-    \use:c { @@_make_abs_ \l_@@_info_diploma_tl :nn } { } { : }
+    \@@_abs_bookmark:Vn \c_@@_name_abstract_a_tl { abstract }
+    \@@_make_abstract:
     \group_begin: \kaishu \zihao { -4 } #1
   }
   { \@@_print_keywords:nn { } { ; } \group_end: }
@@ -4904,9 +5098,9 @@
   {
     \cleardoublepage
     \thispagestyle { plain }
-    \@@_abs_bookmark:Vn { \c_@@_name_abstract_en_tl } { abstract-en }
-    \use:c { @@_make_abs_ \l_@@_info_diploma_tl :nn } { _en } { :~ }
-    \group_begin: \zihao{ -4 } #1
+    \@@_abs_bookmark:Vn \c_@@_name_abstract_a_en_tl { abstract-en }
+    \@@_make_abstract_en:
+    \group_begin: \zihao { -4 } #1
   }
   { \@@_print_keywords:nn { _en } { ;~ } \group_end: }
 %    \end{macrocode}
@@ -4920,9 +5114,9 @@
 % 单独制作的前言致谢页。
 %    \begin{macrocode}
 \NewDocumentEnvironment { preface         } { +b }
-  { \@@_chapter:V { \c_@@_name_preface_tl         } #1 } { }
+  { \@@_chapter:V \c_@@_name_preface_tl         #1 } { }
 \NewDocumentEnvironment { acknowledgement } { +b }
-  { \@@_chapter:V { \c_@@_name_acknowledgement_tl } #1 } { }
+  { \@@_chapter:V \c_@@_name_acknowledgement_tl #1 } { }
 %    \end{macrocode}
 % \end{environment}
 % \end{environment}
@@ -5014,7 +5208,7 @@
 %    \begin{macrocode}
 \NewDocumentEnvironment { notation } { O { 10 em } O { 5 em } }
   {
-    \@@_chapter:V { \c_@@_name_notation_tl }
+    \@@_chapter:V \c_@@_name_notation_tl
     \@@_make_notation:nn { #1 } { #2 }
   }
   { \endlist }
@@ -5034,5 +5228,201 @@
 %    \end{macrocode}
 % \end{environment}
 %
+%
+% \subsection{配置常量}
+% \changes{v0.16}{2022/02/23}{将名称常量分离到 \file{.def} 文件。}
+%
+% 本节内容用于生成名称常量的默认定义,分为本科生和研究生模板两种。
+%
+% 由于同一名称在不同位置具有不同变体,本模板使用字母后缀名进行了区分,
+% 并在易混淆处添加了注释。
+%
+% 通用默认名称。注意空格是忽略掉的。
+%    \begin{macrocode}
+%<*(definition-ug|definition-g)>
+\clist_map_inline:nn
+  {
+    { acknowledgement } { 致\hspace{2em}谢              },
+    { id              } { 学号                          },
+    { notation        } { 符号表                        },
+    { orig_date       } { 日期                          },
+    { paperlist       } { 发表文章目录                  },
+    { pdf_creator     } { LaTeX~ with~ njuthesis~ class },
+    { preface         } { 前\hspace{2em}言              },
+    { supv_ii         } { 第二导师                      },
+    { supv_ttl        } { 职称                          }
+  }
+  { \@@_define_name:nn #1 }
+%    \end{macrocode}
+%
+% 定义同时使用到中英文名称的常量。
+%    \begin{macrocode}
+\clist_map_inline:nn
+  {
+    { abstract   } { 摘要       } { ABSTRACT            },
+    % 用于书签的摘要名称字样
+    { abstract_a } { 中文摘要   } { ABSTRACT            },
+    { appendix   } { 附录       } { appendix            },
+    { dept       } { 院系       } { DEPARTMENT          },
+    { figure     } { 图         } { figure              },
+    { keywords   } { 关键词:   } { Keywords:~          },
+    { lang       } { 中文       } { 英文                },
+    { nju        } { 南京大学   } { Nanjing~ University },
+    { table      } { 表         } { table               }
+  }
+  { \@@_define_name:nnn #1 }
+%</(definition-ug|definition-g)>
+%    \end{macrocode}
+%
+% 本科生模板默认名称。
+%    \begin{macrocode}
+%<*definition-ug>
+\clist_map_inline:nn
+  {
+    % 用于摘要的作者名称字样
+    { author_a    } { 本科生姓名                         },
+    { grade       } { 年级                               },
+    { orig_decl   }
+      { \c_@@_name_nju_tl 本科毕业论文(设计)诚信承诺书 },
+    { orig_sign   } { 作者签名                           },
+    { sm_date     } { 提交日期                           },
+    { supv        } { 导师                               },
+    { title       } { 题目                               },
+    { type        } { 本科生毕业论文(设计、作品)       },
+    { ug          } { 本科生                             }
+  }
+  { \@@_define_name:nn #1 }
+\clist_map_inline:nn
+  {
+    { abstract_title }
+      {
+        \c_@@_name_nju_tl  \c_@@_name_type_tl
+        \c_@@_name_lang_tl \c_@@_name_abstract_tl
+      }
+      {
+        \c_@@_name_nju_tl     \c_@@_name_type_tl
+        \c_@@_name_lang_en_tl \c_@@_name_abstract_tl
+      },
+    { author    } { 学生姓名               } { UNDERGRADUATE  },
+    { major     } { 专业                   } { SPECIALIZATION },
+    { supv_full } { 指导教师(姓名、职称) } { MENTOR         }
+  }
+  { \@@_define_name:nnn #1 }
+%    \end{macrocode}
+%
+% \begin{variable}{\c_@@_orig_decl_text_tl}
+% 学位论文诚信承诺书。
+%    \begin{macrocode}
+\tl_const:Nn \c_@@_orig_decl_text_tl
+  {
+    本人郑重承诺:所呈交的毕业论文(设计)(题目:)是在指导教师的指导下
+    严格按照学校和院系有关规定由本人独立完成的。本毕业论文(设计)中引用
+    他人观点及参考资源的内容均已标注引用,如出现侵犯他人知识产权的行为,
+    由本人承担相应法律责任。本人承诺不存在抄袭、伪造、篡改、代写、买卖毕
+    业论文(设计)等违纪行为。
+  }
+%</definition-ug>
+%    \end{macrocode}
+% \end{variable}
+%
+% 研究生模板默认名称。
+%    \begin{macrocode}
+%<*definition-g>
+\clist_map_inline:nn
+  {
+    % 用于摘要的作者名称字样
+    { author_a     }
+      { \tl_item:Nn \l_@@_info_degree_tl { 1 } 士生姓名 },
+    { chairman     } { 答辩委员会主席:                 },
+    { clc          } { 分类号                           },
+    { confer       } { 学位授予单位和日期               },
+    { df_date      } { 论文答辩日期                     },
+    { degree       } { 申请学位级别                     },
+    { apply        }
+      { (申请 \l_@@_info_degree_tl 学位)              },
+    { field        } { 研究方向                         },
+    { g            } { 研究生                           },
+    { grade        } { 级                               },
+    % 用于摘要的专业名称字样
+    { major_a      } { 专业                             },
+    % 用于国家图书馆封面的专业名称字样
+    { major_b      } { 专业名称                         },
+    { orig_decl    }
+      { \c_@@_name_nju_tl 学位论文原创性声明            },
+    { orig_sign    } { 研究生签名                       },
+    { reviewer     } { 评阅人:                         },
+    { seclv        } { 密级                             },
+    { sign         } { (签字)                         },
+    { sm_date      } { 论文提交日期                     },
+    { supv         } { 导师                             },
+    % 用于摘要的导师名称字样
+    { supv_a       } { 指导教师(姓名、职称)           },
+    { supv_info    }
+      { 指导教师姓名、职务、职称、学位、单位名称及地址  },
+    % 用于普通封面的标题名称字样
+    { title        } { 论文题目                         },
+    % 用于摘要的标题名称字样
+    { title_a      } { 题目                             },
+    % 用于国家图书馆封面的标题名称字样
+    { title_b      } { (题名和副题名)                },
+    { udc          } { U D C                           }
+  }
+  { \@@_define_name:nn #1 }
+\clist_map_inline:nn
+  {
+    { abstract_title }
+      { 南京大学 \l_@@_info_type_tl 中文摘要首页用纸 }
+      { 南京大学 \l_@@_info_type_tl 英文摘要首页用纸 },
+    { author    } { 作者姓名 } { POSTGRADUATE        },
+    { major     } { 专业方向 } { SPECIALIZATION      },
+    { supv_full } { 指导教师 } { MENTOR              }
+  }
+  { \@@_define_name:nnn #1 }
+%    \end{macrocode}
+%
+% \begin{variable}{\c_@@_cover_en_text_tl}
+% 英文封面字样。
+%    \begin{macrocode}
+\tl_const:Nn \c_@@_cover_en_text_tl
+  {
+    A~ dissertation~ submitted~ to \\
+    the~ graduate~ school~ of~ Nanjing~ University \\
+    in~ partial~ fulfilment~ of~ the~ requirements~ for~ the~ degree~ of
+  }
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_@@_orig_decl_text_tl}
+% 学位论文原创性声明。
+%    \begin{macrocode}
+\tl_const:Nn \c_@@_orig_decl_text_tl
+  {
+    本人郑重声明,所提交的学位论文是本人在导师指导下独立进行科学研究工作
+    所取得的成果。除本论文中已经注明引用的内容外,本论文不包含其他个人或
+    集体已经发表或撰写过的研究成果,也不包含为获得南京大学或其他教育机构
+    的学位证书而使用过的材料。对本文的研究做出重要贡献的个人和集体,均已
+    在论文的致谢部分明确标明。本人郑重申明愿承担本声明的法律责任。
+  }
+%</definition-g>
+%    \end{macrocode}
+% \end{variable}
+%
+% 默认定理类型和头名称。
+%    \begin{macrocode}
+%<*(definition-ug|definition-g)>
+\clist_map_inline:nn
+  {
+    { axiom      } { 公理 } { Axiom      },
+    { corollary  } { 推论 } { Corollary  },
+    { definition } { 定义 } { Definition },
+    { example    } { 例   } { Example    },
+    { lemma      } { 引理 } { Lemma      },
+    { proof      } { 证明 } { Proof      },
+    { theorem    } { 定理 } { Theorem    }
+  }
+  { \@@_add_theorem_type:nnn #1 }
+%</(definition-ug|definition-g)>
+%    \end{macrocode}
+%
 % \end{implementation}
 %

Modified: trunk/Master/texmf-dist/source/latex/njuthesis/njuthesis.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/njuthesis/njuthesis.ins	2022-03-19 20:03:25 UTC (rev 62812)
+++ trunk/Master/texmf-dist/source/latex/njuthesis/njuthesis.ins	2022-03-19 20:03:43 UTC (rev 62813)
@@ -50,7 +50,9 @@
 
 \generate{
   \usedir{tex/latex/njuthesis}
-    \file{\jobname.cls}        {\from{\jobname.dtx}{class}}
+    \file{\jobname.cls}               {\from{\jobname.dtx}{class}}
+    \file{\jobname-undergraduate.def} {\from{\jobname.dtx}{definition-ug}}
+    \file{\jobname-graduate.def}      {\from{\jobname.dtx}{definition-g}}
 }
 
 \obeyspaces
@@ -62,6 +64,8 @@
 \Msg{* The recommended directory is TDS:tex/latex/njuthesis      *}
 \Msg{*                                                           *}
 \Msg{*     njuthesis.cls                                         *}
+\Msg{*     njuthesis-graduate.def                                *}
+\Msg{*     njuthesis-undergraduate.def                           *}
 \Msg{*     njuthesis.ins                                         *}
 \Msg{*                                                           *}
 \Msg{* To produce the documentation, run the file njuthesis.dtx  *}

Added: trunk/Master/texmf-dist/tex/latex/njuthesis/njuthesis-graduate.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/njuthesis/njuthesis-graduate.def	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/njuthesis/njuthesis-graduate.def	2022-03-19 20:03:43 UTC (rev 62813)
@@ -0,0 +1,431 @@
+%%
+%% This is file `njuthesis-graduate.def',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% njuthesis.dtx  (with options: `definition-g')
+%% 
+%% Copyright (C) 2021 - 2022
+%% by Nanjing University Linux User Group
+%% <git+nju-lug-email-3104-issue- at yaoge123.cn>
+%% 
+%% This file may be distributed and/or modified under the conditions of
+%% the LaTeX Project Public License, either version 1.3c of this license
+%% or (at your option) any later version.  The latest version of this
+%% license is in:
+%% 
+%%    http://www.latex-project.org/lppl.txt
+%% 
+%% and version 1.3 or later is part of all distributions of LaTeX version
+%% 2005/12/01 or later.
+%% 
+%% To produce the documentation run the original source files ending with
+%% `.dtx' through XeTeX.
+%% 
+\GetIdInfo $Id: njuthesis.dtx 0.16.0 2022-03-19 12:00:00 +0800 NJU LUG <git+nju-lug-email-3104-issue- at yaoge123.cn>$
+  {Graduate definition file for njuthesis}
+\ProvidesExplFile{njuthesis-graduate.def}
+  {\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\tl_const:Nn \c__nju_pagestyle_tl { headings }
+\__nju_declare_element:nn { cover / g / emblem-img }
+  {
+    content     = \njuemblem [ black ] { ! } { 1.9 cm },
+    bottom-skip = 1 cm
+  }
+\__nju_declare_element:nn { cover / g / name-img }
+  {
+    content     = \njuname [ black ] { 4.4 cm } { ! },
+    bottom-skip = 2 cm
+  }
+\__nju_declare_element:nn { cover / g / type }
+  {
+    content     =
+      \__nju_spread_box:nnV { 9 em } { } \l__nju_info_type_tl,
+    format      = \zihao { -1 } \bfseries,
+    bottom-skip = 1 cm
+  }
+\__nju_declare_element:nn { cover / g / degree }
+  {
+    content     = \c__nju_name_apply_tl,
+    format      = \zihao { -1 } \bfseries,
+    bottom-skip = 1 cm plus 1.5 fil
+  }
+\__nju_declare_element:nn { cover / g / info }
+  {
+    content     = \__nju_cover_info_g:nn { 6.2 em } { 18 em },
+    bottom-skip = 0 pt plus 1.5 fil
+  }
+\__nju_declare_element:nn { cover / g / date }
+  { content = \l__nju_info_sm_date_tl }
+\cs_new_protected:Npn \__nju_cover_info_g:nn #1#2
+  {
+    \begin{minipage} { #1 + #2 + 0.3 em }
+      \raggedleft
+      \__nju_multiline_title:nnn { } { #1 } { #2 }
+      \clist_map_inline:nn { author, major, field, supv_full }
+        { \__nju_cover_entry:nnn { ##1 } { #1 } { #2 } }
+    \end{minipage}
+  }
+\__nju_declare_element:nn { cover / g / back }
+  {
+    content = \__nju_cover_back_g:,
+    align   = l
+  }
+\cs_new_protected:Npn \__nju_cover_back_g:
+  {
+    \__nju_spread_box:nnV { 6.2 em } { \kaishu } \c__nju_name_id_tl
+    { : \__nju_quad: } \l__nju_info_id_tl
+    \__nju_vskip:
+    \__nju_spread_box:nnV { 6.2 em } { \kaishu } \c__nju_name_df_date_tl
+    { : \__nju_quad: } \l__nju_info_df_date_tl
+    \__nju_vskip:
+    \__nju_spread_box:nnV { 6.2 em } { \kaishu } \c__nju_name_supv_full_tl
+    { : \__nju_quad: } \skip_horizontal:n { 8 em } \c__nju_name_sign_tl
+  }
+\__nju_declare_element:nn { cover / g / en / title }
+  {
+    content     = \l__nju_info_title_en_tl,
+    format      = \bf \sffamily \zihao { 2 },
+    bottom-skip = 2 cm
+  }
+\__nju_declare_element:nn { cover / g / en / top }
+  {
+    content      =
+      { by }
+      \skip_vertical:N \c_zero_skip
+      \textbf { \sffamily \l__nju_info_author_en_tl }
+      \skip_vertical:n { .5 cm }
+      { Supervised~ by }
+      \skip_vertical:N \c_zero_skip
+      \textsf { \l__nju_info_supv_full_en_tl },
+    format      = \zihao { 4 },
+    bottom-skip = 0 pt plus 1.2 fil
+  }
+\__nju_declare_element:nn { cover / g / en / middle }
+  {
+    content     =
+      \c__nju_cover_en_text_tl \__nju_vskip:
+      \textsc { \clist_item:Nn \c__nju_name_degree_en_clist
+                  { \g__nju_info_degree_int } }
+      \__nju_vskip: { in } \__nju_vskip:
+      \l__nju_info_major_en_tl,
+    bottom-skip = 2 cm
+  }
+\__nju_declare_element:nn { cover / g / en / emblem-img }
+  {
+    content     = \njuemblem [ black ] { ! } { 2.5 cm },
+    bottom-skip = 1.5 cm
+  }
+\__nju_declare_element:nn { cover / g / en / bottom }
+  {
+    content =
+      \l__nju_info_dept_en_tl \skip_vertical:N \c_zero_skip
+      \c__nju_name_nju_en_tl  \skip_vertical:n { 1 cm }
+      \l__nju_info_sm_date_en_tl
+  }
+\__nju_declare_element:nn { cover / nl / top }
+  {
+    content     = \__nju_cover_top_nl:,
+    bottom-skip = 2 cm
+  }
+\__nju_declare_element:nn { cover / nl / name }
+  {
+    content     =
+      \__nju_spread_box:nnV { 6 em } { } \c__nju_name_title_tl,
+    format      = \zihao { -0 },
+    bottom-skip = 0 pt plus 1.2 fil
+  }
+\__nju_declare_element:nn { cover / nl / title }
+  {
+    content     = \__nju_cover_title_nl:,
+    format      = \zihao { 1 },
+    bottom-skip = 1 cm
+  }
+\__nju_declare_element:nn { cover / nl / middle }
+  {
+    content     = \__nju_cover_info_nl:,
+    format      = \zihao { 4 },
+    bottom-skip = 0 pt plus 1.2 fil
+  }
+\__nju_declare_element:nn { cover / nl / bottom }
+  {
+    content     = \__nju_cover_bottom_nl:,
+    bottom-skip = 1 cm,
+    align       = r
+  }
+\__nju_declare_element:nn { cover / nl / date }
+  {
+    content = \__nju_qquad: 年 \__nju_quad: 月 \__nju_quad: 日,
+    format  = \kaishu \zihao { 3 }
+  }
+\cs_new_protected:Npn \__nju_cover_top_nl:
+  {
+    \__nju_spread_box:nnV { 3.2 em } { } \c__nju_name_clc_tl   \__nju_hskip:
+    \__nju_ulined_center_box:nn { 9 em } { \l__nju_info_clc_tl   } \hfill
+    \__nju_spread_box:nnV { 3.2 em } { } \c__nju_name_seclv_tl \__nju_hskip:
+    \__nju_ulined_center_box:nn { 9 em } { \l__nju_info_seclv_tl } \\
+    V { 3.2 em } { } { \c__nju_name_udc_tl   } \__nju_hskip:
+    \__nju_ulined_center_box:nn { 9 em } { \l__nju_info_udc_tl   } \hfill \null
+  }
+\cs_new_protected:Npn \__nju_cover_title_nl:
+  {
+    \__nju_split_title:V \l__nju_info_title_tl
+    \__nju_multiline_box:nnnn { \l__nju_tmp_int } \l__nju_tmp_clist { 3 } { 15 em }
+    \skip_vertical:n { - 0.5 cm }
+    { \zihao { 4 } \c__nju_name_title_b_tl }
+    \skip_vertical:N \c_zero_skip
+    \__nju_ulined_center_box:nn { 4.5 em } { \l__nju_info_author_tl }
+    \skip_vertical:n { - 0.5 cm }
+    { \zihao { 4 } { ( } \c__nju_name_author_tl { ) } }
+  }
+\cs_new_protected:Npn \__nju_cover_info_nl:
+  {
+    \tl_set:Nn \l__nju_info_supv_tl
+      { \clist_item:Nn \l__nju_info_supv_clist { 1 } }
+    \tl_set:Nn \l__nju_info_supv_ttl_tl
+      { \clist_item:Nn \l__nju_info_supv_clist { 2 } }
+    \__nju_uline_entry:Nnnn   \l__nju_tmp_dim { supv_info } { supv   } { } \\
+    \__nju_ulined_center_box:nn { \textwidth } { \__nju_info:n { supv_ttl }
+    \__nju_quad: \__nju_info:n  { supv_cont } }                             \\
+    \__nju_uline_bientry:Nnnn \l__nju_tmp_dim { degree   } { degree  } { }
+    \__nju_uline_bientry:Nnnn \l__nju_tmp_dim { major_b  } { major   } { } \\
+    \__nju_uline_bientry:Nnnn \l__nju_tmp_dim { sm_date  } { sm_date } { }
+    \__nju_uline_bientry:Nnnn \l__nju_tmp_dim { df_date  } { df_date } { } \\
+    \__nju_full_uline:Nn \l__nju_tmp_dim { \c__nju_name_confer_tl }
+    \__nju_uline:n { \l__nju_tmp_dim }
+  }
+\cs_new_protected:Npn \__nju_cover_bottom_nl:
+  {
+    \__nju_name:n { chairman } \__nju_hskip:
+    \__nju_ulined_center_box:nn { 9 em } { \__nju_info:n { chairman } } \\
+    \__nju_name:n { reviewer } \__nju_hskip:
+    \__nju_multiline_box:nnnn { \l__nju_tmp_int }
+      { \l__nju_info_reviewer_clist } { 4 } { 9 em }
+  }
+\__nju_declare_page:nn { cover-g-front-default }
+  {
+    element  = { emblem-img, name-img, type, degree, info, date },
+    prefix   = cover / g /,
+    format   = \zihao { 3 } \kaishu,
+    top-skip = 1.5 cm
+  }
+\__nju_declare_page:nn { cover-g-back-default }
+  {
+    element  = { back },
+    prefix   = cover / g /,
+    format   = \zihao { 3 } \kaishu,
+    top-skip = 20 cm
+  }
+\__nju_declare_page:nn { cover-g-en-default }
+  {
+    element  = { title, top, middle, emblem-img, bottom },
+    prefix   = cover / g / en /,
+    top-skip = 0 pt plus 1.2 fil
+  }
+\__nju_declare_page:nn { cover-nl-default }
+  {
+    element = { top, name, title, middle, bottom, date },
+    prefix  = cover / nl /,
+    format  = \kaishu
+  }
+\cs_new_protected:Npn \__nju_make_cover:
+  {
+    \clist_map_inline:nn { front, back, en }
+      { \UseInstance { nju } { cover-g- ##1 -default } }
+  }
+\cs_new_protected:Npn \__nju_make_cover_nl:
+  { \UseInstance { nju } { cover-nl-default } }
+\cs_new_protected:Npn \__nju_make_orig_decl:
+  {
+    \chapter* { \c__nju_name_orig_decl_tl }
+    \thispagestyle { empty }
+    \c__nju_orig_decl_text_tl
+    \vfil
+    \begin{flushright}
+      \clist_map_inline:nn { orig_sign,     orig_date }
+        { \__nju_vskip: \__nju_name:n { ##1 } : \__nju_uline:n { 7 em } }
+    \end{flushright}
+    \vfil
+  }
+\__nju_declare_element:nn { abstract / title }
+  {
+    content     = \__nju_abs_title:V \c__nju_name_abstract_title_tl,
+    format      = \bfseries \kaishu \zihao { -2 },
+    bottom-skip = 1.2 cm
+  }
+\__nju_declare_element:nn { abstract / info }
+  {
+    content     = \__nju_abs_info_g:n       { : },
+    format      = \zihao {  4 } \kaishu,
+    align       = l,
+    bottom-skip = 1 cm
+  }
+\__nju_declare_element:nn { abstract / en / title }
+  {
+    content     = \__nju_abs_title:V \c__nju_name_abstract_title_en_tl,
+    format      = \bfseries \kaishu \zihao { -2 },
+    bottom-skip = 1.2 cm
+  }
+\__nju_declare_element:nn { abstract / en / info }
+  {
+    content     = \__nju_abs_info_en_g:n        { :~ },
+    format      = \zihao {  4 },
+    align       = l,
+    bottom-skip = 1 cm
+  }
+\cs_new_protected:Npn \__nju_abs_info_g:n #1
+  {
+    \__nju_full_uline:NV \l__nju_tmp_dim
+      {
+        \clist_item:Nn \c__nju_name_type_clist { \g__nju_info_type_int }
+        \c__nju_name_title_a_tl #1
+      }
+    \__nju_ulined_center_box:nn { \l__nju_tmp_dim }
+      { \tl_range:Nnn \l__nju_info_title_tl { 1 } { 20 } } \\
+    \__nju_uline:n { \textwidth } \__nju_qquad:
+    \tl_range:Nnn \l__nju_info_title_tl { 21 } { -1 } \\
+    \__nju_full_uline:NV \l__nju_tmp_dim
+      {
+        \__nju_ulined_center_box:nn { 11 em } { \l__nju_info_major_tl }
+        \c__nju_name_major_a_tl
+        \__nju_ulined_center_box:nn { 4  em } { \l__nju_info_grade_tl }
+        \c__nju_name_grade_tl \c__nju_name_author_a_tl #1
+      }
+    \__nju_ulined_center_box:nn { \l__nju_tmp_dim }
+      { \l__nju_info_author_tl } \\
+    \__nju_full_uline:NV \l__nju_tmp_dim
+      { \c__nju_name_supv_a_tl #1 }
+    \__nju_ulined_center_box:nn { \l__nju_tmp_dim }
+      { \l__nju_info_supv_full_tl }
+  }
+\cs_new_protected:Npn \__nju_abs_info_en_g:n #1
+  {
+    \__nju_full_uline:NV \l__nju_tmp_dim
+      { \clist_item:Nn \c__nju_name_type_en_clist
+          { \g__nju_info_type_int } #1 }
+    \__nju_ulined_center_box:nn { \l__nju_tmp_dim }
+      { \tl_range:Nnn \l__nju_info_title_en_tl { 1 } { 40 } } \\
+    \__nju_uline:n { \textwidth } \__nju_qquad:
+    \tl_range:Nnn \l__nju_info_title_en_tl { 41 } { -1 }
+    \clist_map_inline:nn { major, author, supv_full }
+      { \\
+        \__nju_uline_entry:Nnnn \l__nju_tmp_dim
+          { ##1 _en } { ##1 _en } { #1 }
+      }
+  }
+\cs_new_protected:Npn \__nju_make_abstract:
+  {
+    \UseInstance { nju } { abstract / title }
+    \UseInstance { nju } { abstract / info  }
+  }
+\cs_new_protected:Npn \__nju_make_abstract_en:
+  {
+    \UseInstance { nju } { abstract / en / title }
+    \UseInstance { nju } { abstract / en / info  }
+  }
+\clist_map_inline:nn
+  {
+    { acknowledgement } { 致\hspace{2em}谢              },
+    { id              } { 学号                          },
+    { notation        } { 符号表                        },
+    { orig_date       } { 日期                          },
+    { paperlist       } { 发表文章目录                  },
+    { pdf_creator     } { LaTeX~ with~ njuthesis~ class },
+    { preface         } { 前\hspace{2em}言              },
+    { supv_ii         } { 第二导师                      },
+    { supv_ttl        } { 职称                          }
+  }
+  { \__nju_define_name:nn #1 }
+\clist_map_inline:nn
+  {
+    { abstract   } { 摘要       } { ABSTRACT            },
+    % 用于书签的摘要名称字样
+    { abstract_a } { 中文摘要   } { ABSTRACT            },
+    { appendix   } { 附录       } { appendix            },
+    { dept       } { 院系       } { DEPARTMENT          },
+    { figure     } { 图         } { figure              },
+    { keywords   } { 关键词:   } { Keywords:~          },
+    { lang       } { 中文       } { 英文                },
+    { nju        } { 南京大学   } { Nanjing~ University },
+    { table      } { 表         } { table               }
+  }
+  { \__nju_define_name:nnn #1 }
+\clist_map_inline:nn
+  {
+    % 用于摘要的作者名称字样
+    { author_a     }
+      { \tl_item:Nn \l__nju_info_degree_tl { 1 } 士生姓名 },
+    { chairman     } { 答辩委员会主席:                 },
+    { clc          } { 分类号                           },
+    { confer       } { 学位授予单位和日期               },
+    { df_date      } { 论文答辩日期                     },
+    { degree       } { 申请学位级别                     },
+    { apply        }
+      { (申请 \l__nju_info_degree_tl 学位)              },
+    { field        } { 研究方向                         },
+    { g            } { 研究生                           },
+    { grade        } { 级                               },
+    % 用于摘要的专业名称字样
+    { major_a      } { 专业                             },
+    % 用于国家图书馆封面的专业名称字样
+    { major_b      } { 专业名称                         },
+    { orig_decl    }
+      { \c__nju_name_nju_tl 学位论文原创性声明            },
+    { orig_sign    } { 研究生签名                       },
+    { reviewer     } { 评阅人:                         },
+    { seclv        } { 密级                             },
+    { sign         } { (签字)                         },
+    { sm_date      } { 论文提交日期                     },
+    { supv         } { 导师                             },
+    % 用于摘要的导师名称字样
+    { supv_a       } { 指导教师(姓名、职称)           },
+    { supv_info    }
+      { 指导教师姓名、职务、职称、学位、单位名称及地址  },
+    % 用于普通封面的标题名称字样
+    { title        } { 论文题目                         },
+    % 用于摘要的标题名称字样
+    { title_a      } { 题目                             },
+    % 用于国家图书馆封面的标题名称字样
+    { title_b      } { (题名和副题名)                },
+    { udc          } { U D C                           }
+  }
+  { \__nju_define_name:nn #1 }
+\clist_map_inline:nn
+  {
+    { abstract_title }
+      { 南京大学 \l__nju_info_type_tl 中文摘要首页用纸 }
+      { 南京大学 \l__nju_info_type_tl 英文摘要首页用纸 },
+    { author    } { 作者姓名 } { POSTGRADUATE        },
+    { major     } { 专业方向 } { SPECIALIZATION      },
+    { supv_full } { 指导教师 } { MENTOR              }
+  }
+  { \__nju_define_name:nnn #1 }
+\tl_const:Nn \c__nju_cover_en_text_tl
+  {
+    A~ dissertation~ submitted~ to \\
+    the~ graduate~ school~ of~ Nanjing~ University \\
+    in~ partial~ fulfilment~ of~ the~ requirements~ for~ the~ degree~ of
+  }
+\tl_const:Nn \c__nju_orig_decl_text_tl
+  {
+    本人郑重声明,所提交的学位论文是本人在导师指导下独立进行科学研究工作
+    所取得的成果。除本论文中已经注明引用的内容外,本论文不包含其他个人或
+    集体已经发表或撰写过的研究成果,也不包含为获得南京大学或其他教育机构
+    的学位证书而使用过的材料。对本文的研究做出重要贡献的个人和集体,均已
+    在论文的致谢部分明确标明。本人郑重申明愿承担本声明的法律责任。
+  }
+\clist_map_inline:nn
+  {
+    { axiom      } { 公理 } { Axiom      },
+    { corollary  } { 推论 } { Corollary  },
+    { definition } { 定义 } { Definition },
+    { example    } { 例   } { Example    },
+    { lemma      } { 引理 } { Lemma      },
+    { proof      } { 证明 } { Proof      },
+    { theorem    } { 定理 } { Theorem    }
+  }
+  { \__nju_add_theorem_type:nnn #1 }
+\endinput
+%%
+%% End of file `njuthesis-graduate.def'.


Property changes on: trunk/Master/texmf-dist/tex/latex/njuthesis/njuthesis-graduate.def
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/latex/njuthesis/njuthesis-undergraduate.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/njuthesis/njuthesis-undergraduate.def	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/njuthesis/njuthesis-undergraduate.def	2022-03-19 20:03:43 UTC (rev 62813)
@@ -0,0 +1,218 @@
+%%
+%% This is file `njuthesis-undergraduate.def',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% njuthesis.dtx  (with options: `definition-ug')
+%% 
+%% Copyright (C) 2021 - 2022
+%% by Nanjing University Linux User Group
+%% <git+nju-lug-email-3104-issue- at yaoge123.cn>
+%% 
+%% This file may be distributed and/or modified under the conditions of
+%% the LaTeX Project Public License, either version 1.3c of this license
+%% or (at your option) any later version.  The latest version of this
+%% license is in:
+%% 
+%%    http://www.latex-project.org/lppl.txt
+%% 
+%% and version 1.3 or later is part of all distributions of LaTeX version
+%% 2005/12/01 or later.
+%% 
+%% To produce the documentation run the original source files ending with
+%% `.dtx' through XeTeX.
+%% 
+\GetIdInfo $Id: njuthesis.dtx 0.16.0 2022-03-19 12:00:00 +0800 NJU LUG <git+nju-lug-email-3104-issue- at yaoge123.cn>$
+  {Undergraduate definition file for njuthesis}
+\ProvidesExplFile{njuthesis-undergraduate.def}
+  {\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\tl_const:Nn \c__nju_pagestyle_tl { plain    }
+\__nju_declare_element:nn { cover / ug / emblem-img }
+  {
+    content = \njuemblem [ black ] { ! } { 3.35 cm },
+    bottom-skip = 1 cm,
+    align   = l
+  }
+\__nju_declare_element:nn { cover / ug / name-img }
+  {
+    content     = \njuname [ black ] { ! } { 3 cm },
+    bottom-skip = 1 cm
+  }
+\__nju_declare_element:nn { cover / ug / title }
+  {
+    content  =
+      \__nju_spread_box:nnV { 9 em } { \bf } \l__nju_info_type_tl,
+    format   = \zihao { -1 },
+    bottom-skip = 0 pt plus 1.5 fill
+  }
+\__nju_declare_element:nn { cover / ug / info }
+  {
+    content  =
+      \__nju_cover_info_ug:nnn { 4.2 em } { 16 em } { 5.5 em },
+    format   = \zihao { 3 }
+  }
+\cs_new_protected:Npn \__nju_cover_info_ug:nnn #1#2#3
+  {
+    \begin{minipage} { #1 + #2 + 0.3 em }
+      \raggedleft
+      \__nju_cover_entry:nnn { dept     } { #1 } { #2 }
+      \__nju_cover_entry:nnn { major    } { #1 } { #2 }
+      \__nju_multiline_title:nnn  { \bf } { #1 } { #2 }
+      \__nju_cover_bientry:nnnn { grade } { id } { #1 } { #3 }
+      \__nju_cover_entry:nnn { author   } { #1 } { #2 }
+      \__nju_cover_supv_entry:nnn { supv } { #1 } { #3 }
+      \bool_if:NT \l__nju_second_supv_bool
+        { \__nju_cover_supv_entry:nnn { supv_ii } { #1 } { #3 } }
+      \__nju_cover_entry:nnn { sm_date  } { #1 } { #2 }
+    \end{minipage}
+  }
+\__nju_declare_page:nn { cover-ug-default }
+  {
+    element     = { emblem-img, name-img, title, info },
+    prefix      = cover / ug /,
+    bottom-skip = 0.5 cm plus 1.5 fill
+  }
+\cs_new_protected:Npn \__nju_make_cover:
+  {
+    \UseInstance { nju } { cover-ug-default }
+  }
+\cs_new_protected:Npn \__nju_make_orig_decl:
+  {
+    \chapter* { \c__nju_name_orig_decl_tl }
+    \thispagestyle { empty }
+    \c__nju_orig_decl_text_tl
+    \vfil
+    \begin{flushright}
+      \clist_map_inline:nn { orig_sign, id, orig_date }
+        { \__nju_vskip: \__nju_name:n { ##1 } : \__nju_uline:n { 7 em } }
+    \end{flushright}
+    \vfil
+  }
+\__nju_declare_element:nn { abstract / title }
+  {
+    content     = \__nju_abs_title:V \c__nju_name_abstract_title_tl,
+    format      = \bfseries \kaishu \zihao { -2 },
+    bottom-skip = 1.2 cm
+  }
+\__nju_declare_element:nn { abstract / info }
+  {
+    content     = \__nju_abs_info_ug:nn { } { : },
+    format      = \zihao { -4 } \kaishu,
+    align       = l,
+    bottom-skip = 1 cm
+  }
+\__nju_declare_element:nn { abstract / en / title }
+  {
+    content     = \__nju_abs_title:V \c__nju_name_abstract_title_en_tl,
+    format      = \bfseries \kaishu \zihao { -2 },
+    bottom-skip = 1.2 cm
+  }
+\__nju_declare_element:nn { abstract / en / info }
+  {
+    content     = \__nju_abs_info_ug:nn { _en } { :~ },
+    format      = \zihao { -4 },
+    align       = l,
+    bottom-skip = 1 cm
+  }
+\cs_new_protected:Npn \__nju_abs_info_ug:nn #1#2
+  {
+    \tl_if_blank:eTF { #1 }
+      { \c__nju_name_title_tl }
+      { \clist_item:Nn \c__nju_name_type_en_clist { \g__nju_info_type_int } }
+    #2 \tl_use:c { l__nju_info_title #1 _tl } \\
+    \tl_set_eq:NN \c__nju_name_author_tl \c__nju_name_author_a_tl
+    \clist_map_inline:nn { dept, major, author, supv_full }
+      { \__nju_name:n { ##1 #1 } #2 \__nju_info:n { ##1 #1 } \\ }
+    \__nju_name:n { abstract #1 } #2
+  }
+\cs_new_protected:Npn \__nju_make_abstract:
+  {
+    \UseInstance { nju } { abstract / title }
+    \UseInstance { nju } { abstract / info  }
+  }
+\cs_new_protected:Npn \__nju_make_abstract_en:
+  {
+    \UseInstance { nju } { abstract / en / title }
+    \UseInstance { nju } { abstract / en / info  }
+  }
+\clist_map_inline:nn
+  {
+    { acknowledgement } { 致\hspace{2em}谢              },
+    { id              } { 学号                          },
+    { notation        } { 符号表                        },
+    { orig_date       } { 日期                          },
+    { paperlist       } { 发表文章目录                  },
+    { pdf_creator     } { LaTeX~ with~ njuthesis~ class },
+    { preface         } { 前\hspace{2em}言              },
+    { supv_ii         } { 第二导师                      },
+    { supv_ttl        } { 职称                          }
+  }
+  { \__nju_define_name:nn #1 }
+\clist_map_inline:nn
+  {
+    { abstract   } { 摘要       } { ABSTRACT            },
+    % 用于书签的摘要名称字样
+    { abstract_a } { 中文摘要   } { ABSTRACT            },
+    { appendix   } { 附录       } { appendix            },
+    { dept       } { 院系       } { DEPARTMENT          },
+    { figure     } { 图         } { figure              },
+    { keywords   } { 关键词:   } { Keywords:~          },
+    { lang       } { 中文       } { 英文                },
+    { nju        } { 南京大学   } { Nanjing~ University },
+    { table      } { 表         } { table               }
+  }
+  { \__nju_define_name:nnn #1 }
+\clist_map_inline:nn
+  {
+    % 用于摘要的作者名称字样
+    { author_a    } { 本科生姓名                         },
+    { grade       } { 年级                               },
+    { orig_decl   }
+      { \c__nju_name_nju_tl 本科毕业论文(设计)诚信承诺书 },
+    { orig_sign   } { 作者签名                           },
+    { sm_date     } { 提交日期                           },
+    { supv        } { 导师                               },
+    { title       } { 题目                               },
+    { type        } { 本科生毕业论文(设计、作品)       },
+    { ug          } { 本科生                             }
+  }
+  { \__nju_define_name:nn #1 }
+\clist_map_inline:nn
+  {
+    { abstract_title }
+      {
+        \c__nju_name_nju_tl  \c__nju_name_type_tl
+        \c__nju_name_lang_tl \c__nju_name_abstract_tl
+      }
+      {
+        \c__nju_name_nju_tl     \c__nju_name_type_tl
+        \c__nju_name_lang_en_tl \c__nju_name_abstract_tl
+      },
+    { author    } { 学生姓名               } { UNDERGRADUATE  },
+    { major     } { 专业                   } { SPECIALIZATION },
+    { supv_full } { 指导教师(姓名、职称) } { MENTOR         }
+  }
+  { \__nju_define_name:nnn #1 }
+\tl_const:Nn \c__nju_orig_decl_text_tl
+  {
+    本人郑重承诺:所呈交的毕业论文(设计)(题目:)是在指导教师的指导下
+    严格按照学校和院系有关规定由本人独立完成的。本毕业论文(设计)中引用
+    他人观点及参考资源的内容均已标注引用,如出现侵犯他人知识产权的行为,
+    由本人承担相应法律责任。本人承诺不存在抄袭、伪造、篡改、代写、买卖毕
+    业论文(设计)等违纪行为。
+  }
+\clist_map_inline:nn
+  {
+    { axiom      } { 公理 } { Axiom      },
+    { corollary  } { 推论 } { Corollary  },
+    { definition } { 定义 } { Definition },
+    { example    } { 例   } { Example    },
+    { lemma      } { 引理 } { Lemma      },
+    { proof      } { 证明 } { Proof      },
+    { theorem    } { 定理 } { Theorem    }
+  }
+  { \__nju_add_theorem_type:nnn #1 }
+\endinput
+%%
+%% End of file `njuthesis-undergraduate.def'.


Property changes on: trunk/Master/texmf-dist/tex/latex/njuthesis/njuthesis-undergraduate.def
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/tex/latex/njuthesis/njuthesis.cls
===================================================================
--- trunk/Master/texmf-dist/tex/latex/njuthesis/njuthesis.cls	2022-03-19 20:03:25 UTC (rev 62812)
+++ trunk/Master/texmf-dist/tex/latex/njuthesis/njuthesis.cls	2022-03-19 20:03:43 UTC (rev 62813)
@@ -24,8 +24,7 @@
 %% `.dtx' through XeTeX.
 %% 
 \NeedsTeXFormat{LaTeX2e}
-\RequirePackage{expl3}
-\GetIdInfo $Id: njuthesis.dtx 0.15.0 2022-02-20 10:30:00 +0800 NJU LUG <git+nju-lug-email-3104-issue- at yaoge123.cn>$
+\GetIdInfo $Id: njuthesis.dtx 0.16.0 2022-03-19 12:00:00 +0800 NJU LUG <git+nju-lug-email-3104-issue- at yaoge123.cn>$
   {Thesis template for Nanjing University}
 \ProvidesExplClass{njuthesis}
   {\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
@@ -33,10 +32,9 @@
 \msg_new:nnn { njuthesis } { l3-too-old }
   {
     Package~ "#1"~ is~ too~ old. \\
-    Please~ update~ an~ up-to-date~ version~ of~
-    the~ bundles "l3kernel"~ and~ "l3packages"~
-    using~ your~ TeX~ package~ manager~ or~ from~ \\
-    CTAN.
+    Please~ update~ an~ up-to-date~ version~ of~ the~
+    bundles~ "l3kernel"~ and~ "l3packages"~ using~
+    your~ TeX~ package~ manager~ or~ from~ CTAN.
   }
 \clist_map_inline:nn { xtemplate, l3keys2e }
   {
@@ -43,7 +41,6 @@
     \@ifpackagelater {#1} { 2020/10/01 }
       { } { \msg_error:nnn { njuthesis } { l3-too-old } {#1} }
   }
-
 \msg_new:nnn { njuthesis } { unsupported-engine }
   {
     The~ njuthesis~ class~ requires~ either~
@@ -52,14 +49,10 @@
     You~ must~ change~ your~ typesetting~ engine~
     to~ "xelatex"~ or~ "lualatex".
   }
-\sys_if_engine_xetex:F
-  {
-    \sys_if_engine_luatex:F
-      {
-        \msg_fatal:nnx { njuthesis } { unsupported-engine }
-          { \c_sys_engine_str }
-      }
-  }
+\bool_lazy_or:nnF
+  { \sys_if_engine_xetex_p:  }
+  { \sys_if_engine_luatex_p: }
+  { \msg_fatal:nnx { njuthesis } { unsupported-engine } { \c_sys_engine_str } }
 \box_new:N   \l__nju_tmp_box
 \clist_new:N \l__nju_tmp_clist
 \dim_new:N   \l__nju_tmp_dim
@@ -66,9 +59,9 @@
 \int_new:N   \l__nju_tmp_int
 \seq_new:N   \l__nju_tmp_seq
 \tl_new:N    \l__nju_tmp_tl
-\int_new:N \l__nju_info_degree_int
+\int_new:N \g__nju_info_degree_int
 \int_new:N \l__nju_info_diploma_int
-\int_new:N \l__nju_info_type_int
+\int_new:N \g__nju_info_type_int
 \tl_new:N  \l__nju_info_degree_tl
 \tl_new:N  \l__nju_info_diploma_tl
 \tl_new:N  \l__nju_info_type_tl
@@ -77,9 +70,10 @@
 \bool_new:N \l__nju_second_supv_bool
 \tl_new:N \l__nju_info_supv_full_tl
 \tl_new:N \l__nju_info_supv_full_en_tl
-\bool_new:N \g__nju_load_sys_font_bool
 \tl_new:N \g__nju_latin_font_tl
 \tl_new:N \g__nju_cjk_font_tl
+\tl_new:N \g__nju_config_tl
+\clist_new:N \g__nju_theorem_type_clist
 \tl_new:N \l__nju_info_sm_date_tl
 \tl_new:N \l__nju_info_sm_date_en_tl
 \tl_new:N \l__nju_info_df_date_tl
@@ -120,6 +114,11 @@
     \tl_const:cn { c__nju_name_ #1    _tl } { #2 }
     \tl_const:cn { c__nju_name_ #1 _en_tl } { #3 }
   }
+\cs_new_protected:Npn \__nju_add_theorem_type:nnn #1#2#3
+  {
+    \clist_gput_right:Nn \g__nju_theorem_type_clist { #1 }
+    \__nju_define_name:nnn { #1 } { #2 } { #3 }
+  }
 \cs_new:Npn \__nju_name:n #1 { \tl_use:c { c__nju_name_ #1 _tl } }
 \cs_new:Npn \__nju_info:n #1 { \tl_use:c { l__nju_info_ #1 _tl } }
 \cs_new_protected:Npn \__nju_ulined_center_box:nn #1#2
@@ -129,13 +128,14 @@
     \skip_horizontal:n { -#1 }
     \hbox_to_wd:nn { #1 } { \hfil #2 \hfil }
   }
-\cs_generate_variant:Nn \tl_map_inline:nn { xn }
 \cs_new_protected:Npn \__nju_spread_box:nnn #1#2#3
   {
     \mode_leave_vertical:
     \hbox_to_wd:nn { #1 }
-      { #2 \tl_map_inline:xn { #3 } { ##1 \hfil } \unskip }
+      { #2 \tl_map_inline:nn { #3 } { ##1 \hfil } \unskip }
   }
+\cs_generate_variant:Nn \__nju_spread_box:nnn { nnV }
+\cs_generate_variant:Nn \__nju_spread_box:nnn { nnx }
 \cs_new_protected:Npn \__nju_multiline_box:nnnn #1#2#3#4
   {
     \int_set:Nn #1 { 1 }
@@ -194,29 +194,151 @@
   { \__zhnum_date_aux:nnn { #1 } { #2 } { #3 } }
 \cs_new:Npn \__nju_date_en:www #1-#2-#3 \q_stop
   { \clist_item:Nn \c__nju_month_en_clist { #2 } ~#3 , ~#1  }
+\cs_new_protected:Npn \__nju_split_title:n #1
+  {
+    \tl_if_in:nnTF { #1 } { \\ }
+      {
+        \seq_set_split:Nnn \l__nju_tmp_seq { \\ } { #1 }
+        \clist_set_from_seq:NN \l__nju_tmp_clist \l__nju_tmp_seq
+      }
+      {
+        \__nju_put_inempty_seg:nnn { #1 } { 1  } { 15 }
+        \__nju_put_inempty_seg:nnn { #1 } { 16 } { 15 }
+        \__nju_put_inempty_seg:nnn { #1 } { 31 } { 15 }
+      }
+  }
+\cs_generate_variant:Nn \__nju_split_title:n { V }
+\cs_new_protected:Npn \__nju_multiline_title:nnn #1#2#3
+  {
+    \__nju_split_title:V \l__nju_info_title_tl
+    \__nju_spread_box:nnV { #2 } { \kaishu } \c__nju_name_title_tl
+    \__nju_hskip:
+    \clist_map_inline:Nn \l__nju_tmp_clist
+      { \__nju_ulined_center_box:nn { #3 } { #1 ##1 } \__nju_vskip: }
+  }
+\cs_new_protected:Npn \__nju_cover_entry:nnn #1#2#3
+  {
+    \__nju_spread_box:nnx { #2 } { \kaishu } { \__nju_name:n { #1 } }
+    \__nju_hskip:
+    \__nju_ulined_center_box:nn { #3 }       { \__nju_info:n { #1 } }
+    \__nju_vskip:
+  }
+\cs_new_protected:Npn \__nju_cover_bientry:nnnn #1#2#3#4
+  {
+    \__nju_spread_box:nnx { #3 } { \kaishu } { \__nju_name:n { #1 } }
+    \__nju_hskip:
+    \__nju_ulined_center_box:nn { #4 }       { \__nju_info:n { #1 } }
+    \skip_horizontal:n { 0.5 em }
+    \__nju_spread_box:nnx { #3 } { \kaishu } { \__nju_name:n { #2 } }
+    \__nju_hskip:
+    \__nju_ulined_center_box:nn { #4 }       { \__nju_info:n { #2 } }
+    \__nju_vskip:
+  }
+\cs_new_protected:Npn \__nju_cover_supv_entry:nnn #1#2#3
+  {
+    \__nju_spread_box:nnx { #2 } { \kaishu } { \__nju_name:n { #1 } }
+    \__nju_hskip:
+    \__nju_ulined_center_box:nn { #3 }
+      { \clist_item:cn { l__nju_info_ #1 _clist } { 1 } }
+    \skip_horizontal:n { 0.5 em }
+    \__nju_spread_box:nnV { #2 } { \kaishu } \c__nju_name_supv_ttl_tl
+    \__nju_hskip:
+    \__nju_ulined_center_box:nn { #3 }
+      { \clist_item:cn { l__nju_info_ #1 _clist } { 2 } }
+    \__nju_vskip:
+  }
+\cs_new_protected:Npn \__nju_abs_bookmark:nn #1#2
+  {
+    \phantomsection
+    \bool_if:NTF \g__nju_abs_in_toc_bool
+      { \__nju_add_tocline:n { #1 } }
+      { \pdfbookmark [0] { #1 } { #2 } }
+    \__nju_chapter_header:n { #1 }
+  }
+\cs_generate_variant:Nn \__nju_abs_bookmark:nn { Vn }
+\cs_new_protected:Npn \__nju_abs_title:n #1
+  {
+    \__nju_get_text_width:Nn \l__nju_tmp_dim {#1}
+    \__nju_uuline:n { \l__nju_tmp_dim } #1
+  }
+\cs_generate_variant:Nn \__nju_abs_title:n { V }
+\DeclareObjectType { nju } { \c_zero_int }
+\DeclareTemplateInterface { nju } { element } { \c_zero_int }
+  {
+    content     : tokenlist = \c_empty_tl,
+    format      : tokenlist = \c_empty_tl,
+    bottom-skip : skip      = \c_zero_skip,
+    align       : choice { l, r, c, n } = c
+  }
+\DeclareTemplateCode { nju } { element } { \c_zero_int }
+  {
+    content     = \l__njuelem_content_tl,
+    format      = \l__njuelem_format_tl,
+    bottom-skip = \l__njuelem_bottom_skip,
+    align =
+      {
+        l =
+          { \tl_set_eq:NN \l__njuelem_begin_align_tl \flushleft
+            \tl_set_eq:NN \l__njuelem_end_align_tl   \endflushleft  },
+        r =
+          { \tl_set_eq:NN \l__njuelem_begin_align_tl \flushright
+            \tl_set_eq:NN \l__njuelem_end_align_tl   \endflushright },
+        c =
+          { \tl_set_eq:NN \l__njuelem_begin_align_tl \center
+            \tl_set_eq:NN \l__njuelem_end_align_tl   \endcenter     },
+        n =
+          { \tl_clear:N   \l__njuelem_begin_align_tl
+            \tl_clear:N   \l__njuelem_end_align_tl                  }
+      }
+  }
+  {
+    \AssignTemplateKeys
+    \group_begin:
+      \l__njuelem_begin_align_tl
+      \l__njuelem_format_tl
+      \l__njuelem_content_tl \par
+      \l__njuelem_end_align_tl
+    \group_end:
+    \__nju_vskip:N \l__njuelem_bottom_skip
+  }
+\DeclareTemplateInterface { nju } { page } { \c_zero_int }
+  {
+    element     : commalist = \c_empty_clist,
+    prefix      : tokenlist = \c_empty_tl,
+    format      : tokenlist = \c_empty_tl,
+    top-skip    : skip      = \c_zero_skip,
+    bottom-skip : skip      = \c_zero_skip
+  }
+\DeclareTemplateCode { nju } { page } { \c_zero_int }
+  {
+    element     = \l__njupage_element_clist,
+    prefix      = \l__njupage_prefix_tl,
+    format      = \l__njupage_format_tl,
+    top-skip    = \l__njupage_top_skip,
+    bottom-skip = \l__njupage_bottom_skip
+  }
+  {
+    \AssignTemplateKeys
+    \newpage
+    \__nju_vskip:N \l__njupage_top_skip
+    \group_begin:
+      \l__njupage_format_tl
+      \clist_map_inline:Nn \l__njupage_element_clist
+        { \UseInstance { nju } { \l__njupage_prefix_tl ##1 } }
+    \group_end:
+    \__nju_vskip:N \l__njupage_bottom_skip
+  }
+\cs_new_protected:Npn \__nju_declare_element:nn #1#2
+  { \DeclareInstance { nju } {#1} { element } {#2} }
+\cs_new_protected:Npn \__nju_declare_page:nn    #1#2
+  { \DeclareInstance { nju } {#1} { page    } {#2} }
 \keys_define:nn { nju }
   {
     degree            .choices:nn = { ug, mg, mf, phd }
-      {
-        \int_set_eq:NN \l__nju_info_degree_int \l_keys_choice_int
-        \tl_set:Nn \l__nju_info_degree_tl
-          {
-            \clist_item:Nn \c__nju_name_degree_clist
-              { \l__nju_info_degree_int }
-          }
-        \int_compare:nTF { \l__nju_info_degree_int == 1 }
-          { \tl_set:Nn \l__nju_info_diploma_tl { ug } }
-          { \tl_set:Nn \l__nju_info_diploma_tl { g  } }
-      },
+      { \int_gset_eq:NN \g__nju_info_degree_int \l_keys_choice_int },
     degree            .initial:n  = ug,
     type              .choices:nn = { thesis, design }
-      {
-        \int_set_eq:NN \l__nju_info_type_int \l_keys_choice_int
-        \tl_set:Nn \l__nju_info_type_tl
-          { \clist_item:Nn \c__nju_name_type_clist { \l__nju_info_type_int } }
-        \tl_put_left:Nn \l__nju_info_type_tl
-          { \tl_use:c { c__nju_name_ \l__nju_info_diploma_tl _tl } }
-      },
+      { \int_gset_eq:NN \g__nju_info_type_int   \l_keys_choice_int },
     type              .initial:n    = thesis,
     nlcover          .bool_set:N  = \g__nju_nlcover_bool,
     nlcover           .initial:n  = false,
@@ -233,6 +355,7 @@
     cjk-font          .choices:nn =
       { fandol, founder, mac, noto, source, win, none }
       { \tl_set_eq:NN \g__nju_cjk_font_tl   \l_keys_choice_tl },
+    config             .tl_set:N  = \g__nju_config_clist
   }
 \ProcessKeysOptions { nju }
 \keys_define:nn { nju }
@@ -242,140 +365,16 @@
     style .meta:nn = { nju / style } { #1 }
   }
 \NewDocumentCommand \njusetup { m } { \keys_set:nn { nju } { #1 } }
-\clist_map_inline:nn
-  {
-    { acknowledgement } { 致\hspace{2em}谢              },
-    { id              } { 学号                          },
-    { notation        } { 符号表                        },
-    { orig_date       } { 日期                          },
-    { paperlist       } { 发表文章目录                  },
-    { pdf_creator     } { LaTeX~ with~ njuthesis~ class },
-    { preface         } { 前\hspace{2em}言              },
-    { supv_ii         } { 第二导师                      },
-    { supv_ttl        } { 职称                          }
-  }
-  { \__nju_define_name:nn #1 }
-\clist_map_inline:nn
-  {
-    { abstract  } { 摘要     } { ABSTRACT            },
-    { appendix  } { 附录     } { appendix            },
-    { dept      } { 院系     } { DEPARTMENT          },
-    { figure    } { 图       } { figure              },
-    { keywords  } { 关键词: } { Keywords:~          },
-    { lang      } { 中文     } { 英文                },
-    { nju       } { 南京大学 } { Nanjing~ University },
-    { table     } { 表       } { table               }
-  }
-  { \__nju_define_name:nnn #1 }
-\int_compare:nTF { \l__nju_info_degree_int == 1 }
-  {
-    \clist_map_inline:nn
-      {
-        { author_full } { 本科生姓名                      },
-        { grade       } { 年级                            },
-        { orig_decl   } { 本科毕业论文(设计)诚信承诺书  },
-        { orig_sign   } { 作者签名                        },
-        { sm_date     } { 提交日期                        },
-        { supv        } { 导师                            },
-        { title       } { 题目                            },
-        { type        } { 本科生毕业论文(设计、作品)    },
-        { ug          } { 本科                            }
-      }
-      { \__nju_define_name:nn #1 }
-      \clist_map_inline:nn
-        {
-          { author    } { 学生姓名               } { UNDERGRADUATE  },
-          { major     } { 专业                   } { SPECIALIZATION },
-          { supv_full } { 指导教师(姓名、职称) } { MENTOR         }
-        }
-        { \__nju_define_name:nnn #1 }
-      \tl_const:Nn \c__nju_orig_decl_text_tl
-        {
-          本人郑重承诺:所呈交的毕业论文(设计)(题目:)是在指导教师的指导下
-          严格按照学校和院系有关规定由本人独立完成的。本毕业论文(设计)中引用
-          他人观点及参考资源的内容均已标注引用,如出现侵犯他人知识产权的行为,
-          由本人承担相应法律责任。本人承诺不存在抄袭、伪造、篡改、代写、买卖毕
-          业论文(设计)等违纪行为。
-        }
-  }
-  {
-    \clist_map_inline:nn
-      {
-        { abstract_r  } { 摘要首页用纸       },
-        { author_r    } { 生姓名             },
-        { chairman    } { 答辩委员会主席:   },
-        { clc         } { 分类号             },
-        { confer      } { 学位授予单位和日期 },
-        { df_date     } { 论文答辩日期       },
-        { degree      } { 申请学位级别       },
-        { apply       }
-        { (申请 \l__nju_info_degree_tl 学位) },
-        { field       } { 研究方向           },
-        { g           } { 研究生             },
-        { grade       } { 级                 },
-        { major_s     } { 专业               },
-        { major_nl    } { 专业名称           },
-        { orig_decl   } { 学位论文原创性声明 },
-        { orig_sign   } { 研究生签名         },
-        { reviewer    } { 评阅人:           },
-        { seclv       } { 密级               },
-        { sign        } { (签字)           },
-        { sm_date     } { 论文提交日期       },
-        { supv        } { 导师               },
-        { supv_r      } { (姓名、职称)     },
-        { supv_info   } { 指导教师姓名、职务、
-                  职称、学位、单位名称及地址 },
-        { title       } { 论文题目           },
-        { title_nl    } { (题名和副题名)   },
-        { title_s     } { 题目               },
-        { udc         } { U D C              }
-      }
-      { \__nju_define_name:nn #1 }
-      \clist_map_inline:nn
-        {
-          { author    } { 作者姓名 } { POSTGRADUATE   },
-          { major     } { 专业方向 } { SPECIALIZATION },
-          { supv_full } { 指导教师 } { MENTOR         }
-        }
-        { \__nju_define_name:nnn #1 }
-    \tl_const:Nn \c__nju_cover_en_text_tl
-      {
-        A~ dissertation~ submitted~ to \\
-        the~ graduate~ school~ of~ Nanjing~ University \\
-        in~ partial~ fulfilment~ of~ the~ requirements~ for~ the~ degree~ of
-      }
-    \tl_const:Nn \c__nju_orig_decl_text_tl
-      {
-        本人郑重声明,所提交的学位论文是本人在导师指导下独立进行科学研究工作
-        所取得的成果。除本论文中已经注明引用的内容外,本论文不包含其他个人或
-        集体已经发表或撰写过的研究成果,也不包含为获得南京大学或其他教育机构
-        的学位证书而使用过的材料。对本文的研究做出重要贡献的个人和集体,均已
-        在论文的致谢部分明确标明。本人郑重申明愿承担本声明的法律责任。
-      }
-  }
-\clist_const:Nn \c__nju_theorem_type_clist
-  { axiom, corollary, definition, example, lemma, theorem }
-\clist_map_inline:nn
-  {
-    { axiom      } { 公理 } { Axiom      },
-    { corollary  } { 推论 } { Corollary  },
-    { definition } { 定义 } { Definition },
-    { example    } { 例   } { Example    },
-    { lemma      } { 引理 } { Lemma      },
-    { proof      } { 证明 } { Proof      },
-    { theorem    } { 定理 } { Theorem    }
-  }
-  { \__nju_define_name:nnn #1 }
 \PassOptionsToClass
   {
     a4paper,
     UTF8,
-    scheme=chinese,
+    scheme = chinese,
     \bool_if:NTF \g__nju_twoside_bool { twoside, } { oneside, }
     \bool_if:NT \g__nju_draft_bool { draft, }
-    linespread=1.625,
-    fontset=none,
-    zihao=-4
+    linespread = 1.625,
+    fontset = none,
+    zihao = -4
   }
   { ctexbook }
 \clist_map_inline:nn
@@ -396,8 +395,6 @@
     geometry,
     fancyhdr,
     setspace,
-    njuvisual,
-    amsmath,
     mathtools,
     unicode-math,
     ntheorem,
@@ -421,7 +418,7 @@
   }
 \msg_new:nnn { njuthesis } { package-too-old }
   {
-    Package~ "#1"~ is~ too~ old. \\
+    Package~ "#1"~ is~ too~ old.\\
     The~ njuthesis~ class~ only~ supports~ "#1"~ with~
     a~ version higher~ than~ v#2.\\
     Please~ update~ an~ up-to-date~ version~ of~ it~
@@ -434,6 +431,16 @@
   }
 \sys_if_engine_luatex:T
   { \__nju_check_package:nnn { luatexja } { 2021/10/24 } { 20211024.0 } }
+\int_compare:nTF { \g__nju_info_degree_int == 1 }
+  { \file_input:n { njuthesis-undergraduate.def } }
+  { \file_input:n { njuthesis-     graduate.def } }
+\msg_new:nnn { njuthesis } { load-config }
+  { I~ am~ loading~ config~ file~ "#1". }
+\clist_if_empty:NF \g__nju_config_clist
+  {
+    \msg_info:nnx { njuthesis } { load-config } { \g__nju_config_tl }
+    \clist_map_inline:Nn \g__nju_config_clist { \file_input:n { #1 } }
+  }
 \keys_define:nn { nju / info }
   {
     title               .tl_set:N = \l__nju_info_title_tl,
@@ -466,6 +473,18 @@
     udc                 .tl_set:N = \l__nju_info_udc_tl,
     supervisor-contact  .tl_set:N = \l__nju_info_supv_cont_tl,
   }
+\tl_set:Nx \l__nju_info_degree_tl
+  {
+    \clist_item:Nn \c__nju_name_degree_clist
+      { \g__nju_info_degree_int }
+  }
+\int_compare:nTF { \g__nju_info_degree_int == 1 }
+  { \tl_set:Nn \l__nju_info_diploma_tl { ug } }
+  { \tl_set:Nn \l__nju_info_diploma_tl { g  } }
+\tl_set:Nx \l__nju_info_type_tl
+  { \clist_item:Nn \c__nju_name_type_clist { \g__nju_info_type_int } }
+\tl_put_left:Nx \l__nju_info_type_tl
+  { \tl_use:c { c__nju_name_ \l__nju_info_diploma_tl _tl } }
 \ctex_at_end_preamble:n
   {
     \bool_set:Nn \l__nju_second_supv_bool
@@ -490,7 +509,7 @@
         \exp_last_unbraced:NV
           \__nju_date:www \l__nju_info_sm_date_raw_tl \q_stop
       }
-    \int_compare:nF { \l__nju_info_degree_int == 1 }
+    \int_compare:nF { \g__nju_info_degree_int == 1 }
       {
         \tl_set:Nn \l__nju_info_sm_date_en_tl
           {
@@ -504,59 +523,71 @@
           }
       }
   }
-\tl_if_empty:NTF \g__nju_latin_font_tl
-  { \bool_gset_true:N \g__nju_load_sys_font_bool }
+\bool_lazy_or:nnT
+  { \tl_if_empty_p:N \g__nju_latin_font_tl }
+  { \tl_if_empty_p:N \g__nju_cjk_font_tl   }
   {
-    \tl_if_empty:NT \g__nju_cjk_font_tl
-      { \bool_gset_true:N \g__nju_load_sys_font_bool }
-  }
-\bool_if:NT \g__nju_load_sys_font_bool
-  {
     \sys_if_platform_windows:TF
-      { \tl_set:Nn \g__nju_latin_font_tl   { win    }
-        \tl_set:Nn \g__nju_cjk_font_tl     { win    } }
-      { \ctex_if_platform_macos:TF
-        { \tl_set:Nn \g__nju_latin_font_tl { mac    }
-          \tl_set:Nn \g__nju_cjk_font_tl   { mac    } }
-        { \tl_set:Nn \g__nju_latin_font_tl { gyre   }
-          \tl_set:Nn \g__nju_cjk_font_tl   { fandol } } }
+      {
+        \tl_set:Nn \g__nju_latin_font_tl     { win    }
+        \tl_set:Nn \g__nju_cjk_font_tl       { win    }
+      }
+      {
+        \ctex_if_platform_macos:TF
+          {
+            \tl_set:Nn \g__nju_latin_font_tl { mac    }
+            \tl_set:Nn \g__nju_cjk_font_tl   { mac    }
+          }
+          {
+            \tl_set:Nn \g__nju_latin_font_tl { gyre   }
+            \tl_set:Nn \g__nju_cjk_font_tl   { fandol }
+          }
+      }
   }
 \cs_new_protected:Npn \__nju_load_latin_font_win:
   {
-    \setmainfont{Times~New~Roman}
-    \setsansfont{Arial}
-    \setmonofont{Courier~New}[Scale=MatchLowercase]
+    \setmainfont { Times~New~Roman }
+    \setsansfont { Arial           }
+    \setmonofont { Courier~New     }
+      [ Scale = MatchLowercase ]
   }
 \cs_new_protected:Npn \__nju_load_latin_font_mac:
   {
-    \setmainfont{Times~New~Roman}
-    \setsansfont{Arial}
-    \setmonofont{Menlo}[Scale=MatchLowercase]
+    \setmainfont { Times~New~Roman }
+    \setsansfont { Arial           }
+    \setmonofont { Menlo           }
+      [ Scale = MatchLowercase ]
   }
 \cs_new_protected:Npn \__nju_load_latin_font_gyre:
   {
-    \setmainfont{texgyretermes}[
-      Extension=.otf,
-      UprightFont=*-regular,
-      BoldFont=*-bold,
-      ItalicFont=*-italic,
-      BoldItalicFont=*-bolditalic]
-    \setsansfont{texgyreheros}[
-      Extension=.otf,
-      UprightFont=*-regular,
-      BoldFont=*-bold,
-      ItalicFont=*-italic,
-      BoldItalicFont=*-bolditalic]
-    \setmonofont{texgyrecursor}[
-      Extension=.otf,
-      UprightFont=*-regular,
-      BoldFont=*-bold,
-      ItalicFont=*-italic,
-      BoldItalicFont=*-bolditalic,
-      Scale=MatchLowercase,
-      Ligatures=CommonOff]
+    \setmainfont { texgyretermes }
+      [
+        Extension      = .otf,
+        UprightFont    = *-regular,
+        BoldFont       = *-bold,
+        ItalicFont     = *-italic,
+        BoldItalicFont = *-bolditalic
+      ]
+    \setsansfont { texgyreheros  }
+      [
+        Extension      = .otf,
+        UprightFont    = *-regular,
+        BoldFont       = *-bold,
+        ItalicFont     = *-italic,
+        BoldItalicFont = *-bolditalic
+      ]
+    \setmonofont { texgyrecursor }
+      [
+        Extension      = .otf,
+        UprightFont    = *-regular,
+        BoldFont       = *-bold,
+        ItalicFont     = *-italic,
+        BoldItalicFont = *-bolditalic,
+        Scale          = MatchLowercase,
+        Ligatures      = CommonOff
+      ]
   }
-\cs_new_protected:Npn \__nju_diable_no_script_msg:
+\cs_new_protected:Npn \__nju_hide_no_script_msg:
   { \msg_redirect_name:nnn { fontspec } { no-script } { info } }
 \cs_new_protected:Npn \__nju_load_cjk_font_win:
   {
@@ -571,7 +602,7 @@
   }
 \cs_new_protected:Npn \__nju_load_cjk_font_mac:
   {
-    \__nju_diable_no_script_msg:
+    \__nju_hide_no_script_msg:
     \setCJKmainfont{Songti~SC~Light}[
       BoldFont=Songti~SC~Bold,
       ItalicFont=Kaiti~SC,
@@ -586,25 +617,37 @@
   }
 \cs_new_protected:Npn \__nju_load_cjk_font_fandol:
   {
-    \__nju_diable_no_script_msg:
-    \setCJKmainfont{FandolSong-Regular}[
-      Extension=.otf,
-      BoldFont=FandolSong-Bold,
-      ItalicFont=FandolKai-Regular]
-    \setCJKsansfont{FandolHei-Regular}[
-      Extension=.otf,
-      BoldFont=FandolHei-Bold]
-    \setCJKmonofont{FandolFang-Regular}[Extension=.otf]
-    \setCJKfamilyfont{zhsong}{FandolSong-Regular}[
-      Extension=.otf,
-      BoldFont=FandolSong-Bold]
-    \setCJKfamilyfont{zhhei}{FandolHei-Regular}[
-      Extension=.otf,
-      BoldFont=FandolHei-Bold]
-    \setCJKfamilyfont{zhfs}{FandolFang-Regular}[Extension=.otf]
-    \setCJKfamilyfont{zhkai}{FandolKai-Regular}[
-      Extension=.otf,
-      AutoFakeBold=2.17]
+    \__nju_hide_no_script_msg:
+    \setCJKmainfont { FandolSong-Regular }
+      [
+        Extension    = .otf,
+        BoldFont     = FandolSong-Bold,
+        ItalicFont   = FandolKai-Regular
+      ]
+    \setCJKsansfont { FandolHei-Regular  }
+      [
+        Extension    = .otf,
+        BoldFont     = FandolHei-Bold
+      ]
+    \setCJKmonofont { FandolFang-Regular }
+      [ Extension    = .otf ]
+    \setCJKfamilyfont { zhsong } { FandolSong-Regular }
+      [
+        Extension    = .otf,
+        BoldFont     = FandolSong-Bold
+      ]
+    \setCJKfamilyfont { zhhei  } { FandolHei-Regular  }
+      [
+        Extension    = .otf,
+        BoldFont     = FandolHei-Bold
+      ]
+    \setCJKfamilyfont { zhfs   } { FandolFang-Regular }
+      [ Extension    = .otf ]
+    \setCJKfamilyfont { zhkai  } { FandolKai-Regular  }
+      [
+        Extension    = .otf,
+        AutoFakeBold = 2.17
+      ]
   }
 \cs_new_protected:Npn \__nju_load_cjk_font_founder:
   {
@@ -619,9 +662,9 @@
     \setCJKfamilyfont { zhsong } { FZShuSong-Z01  }
       [ BoldFont = FZXiaoBiaoSong-B05 ]
     \setCJKfamilyfont { zhhei  } { FZHei-B01      }
-      [AutoFakeBold=2.17]
+      [ AutoFakeBold = 2.17 ]
     \setCJKfamilyfont { zhkai  } { FZKai-Z03      }
-      [AutoFakeBold=2.17]
+      [ AutoFakeBold = 2.17 ]
     \setCJKfamilyfont { zhfs   } { FZFangSong-Z02 }
     \defaultCJKfontfeatures{}
   }
@@ -707,44 +750,86 @@
     headheight = 15 pt
   }
 \bool_if:NT \g__nju_draft_bool { \geometry { showframe } }
-\cs_new_protected:Npn \__nju_fancy_head:nn #1#2
-  { \fancyhead [#1] { \small \kaishu \nouppercase {#2} } }
+\keys_define:nn { nju / style }
+  {
+    header/format .tl_gset:N = \g__nju_header_format_tl,
+    header/format .initial:n = \small \kaishu,
+    header     .clist_gset:N = \g__nju_header_twoside_clist,
+    header*    .clist_gset:N = \g__nju_header_oneside_clist,
+    header        .initial:n =
+      {
+        { EL } { \leftmark  }, { OR } { \rightmark }
+      },
+    header*       .initial:n =
+      {
+        {  L } { \leftmark  }, {  R } { \rightmark }
+      },
+    footer/format .tl_gset:N = \g__nju_footer_format_tl,
+    footer/format .initial:n = \small \rmfamily,
+    footer     .clist_gset:N = \g__nju_footer_twoside_clist,
+    footer*    .clist_gset:N = \g__nju_footer_oneside_clist,
+    footer        .initial:n = { { C } { \thepage } },
+    footer*       .initial:n = { { C } { \thepage } }
+  }
+\clist_new:N \g__nju_header_clist
+\clist_new:N \g__nju_footer_clist
+\ctex_at_end_preamble:n
+  {
+    \bool_if:NTF \g__nju_twoside_bool
+      {
+        \clist_set_eq:NN \g__nju_header_clist \g__nju_header_twoside_clist
+        \clist_set_eq:NN \g__nju_footer_clist \g__nju_footer_twoside_clist
+      }
+      {
+        \clist_set_eq:NN \g__nju_header_clist \g__nju_header_oneside_clist
+        \clist_set_eq:NN \g__nju_footer_clist \g__nju_footer_oneside_clist
+      }
+  }
+\cs_new_protected:Npn \__nju_header:nn #1#2
+  { \fancyhead [#1] { \g__nju_header_format_tl #2 } }
+\cs_new_protected:Npn \__nju_footer:nn #1#2
+  { \fancyfoot [#1] { \g__nju_footer_format_tl #2 } }
 \fancypagestyle { plain }
   {
     \fancyhf { }
-    \fancyfoot [ C ] { \zihao { 5 } \rmfamily \thepage }
+    \clist_map_inline:Nn \g__nju_footer_clist { \__nju_footer:nn ##1 }
     \tl_set:Nn \headrulewidth { \c_zero_dim }
     \tl_set:Nn \footrulewidth { \c_zero_dim }
   }
-\cs_new_protected:Npn \__nju_set_heading_g:
+\fancypagestyle { headings }
   {
-    \bool_if:NTF \g__nju_twoside_bool
+    \fancyhf { }
+    \clist_if_empty:NTF \g__nju_header_clist
       {
-        \__nju_fancy_head:nn { EL } { \leftmark  }
-        \__nju_fancy_head:nn { OR } { \rightmark }
+        \tl_set:Nn \headrulewidth { \c_zero_dim }
       }
       {
-        \__nju_fancy_head:nn { L  } { \leftmark  }
-        \__nju_fancy_head:nn { R  } { \rightmark }
+        \tl_set:Nn \headrulewidth { 0.4 pt }
+        \dim_set:Nn \headheight { 20 pt }
+        \clist_map_inline:Nn \g__nju_header_clist
+          { \__nju_header:nn ##1 }
       }
-    \tl_set:Nn \headrulewidth { 0.4 pt }
-    \dim_set:Nn \headheight { 20 pt }
+    \clist_map_inline:Nn \g__nju_footer_clist { \__nju_footer:nn ##1 }
+    \tl_set:Nn \footrulewidth { \c_zero_dim }
   }
 \RenewDocumentCommand \frontmatter { }
   {
     \cleardoublepage
-    \pagestyle     { empty }
+    \exp_args:NV \pagestyle \c__nju_pagestyle_tl
     \pagenumbering { Roman }
   }
 \RenewDocumentCommand \mainmatter { }
   {
     \cleardoublepage
-    \pagestyle { plain }
-    \int_compare:nF { \l__nju_info_degree_int == 1 }
-      { \__nju_set_heading_g: }
+    \exp_args:NV \pagestyle \c__nju_pagestyle_tl
     \pagenumbering { arabic }
     \normalfont \normalsize
   }
+\AtBeginEnvironment { document }
+  {
+    \exp_args:NV \pagestyle \c__nju_pagestyle_tl
+    \pagenumbering { Roman }
+  }
 \tl_const:Nn \c__nju_sec_format_tl { \large \normalfont \sffamily }
 \cs_new_protected:Npn \__nju_add_tocline:n #1
   { \addcontentsline { toc } { chapter } { \c__nju_sec_format_tl #1 } }
@@ -762,7 +847,7 @@
       { \markboth { #1 } { #1 } }
       { \markboth { \hfill #1 \hfill } { } }
   }
-\NewDocumentCommand \njuchapter { m } { \__nju_chapter:V { #1 } }
+\NewDocumentCommand \njuchapter { m } { \__nju_chapter:n { #1 } }
 \keys_set:nn { ctex }
   {
     chapter        / beforeskip = 10 pt,
@@ -855,7 +940,7 @@
   }
 \cs_new_protected:Npn \__nju_biblatex_post_setup:
   {
-    \defbibheading { njubibintoc } [ \bibname ] { \__nju_chapter:V { ##1 } }
+    \defbibheading { njubibintoc } [ \bibname ] { \__nju_chapter:n { ##1 } }
     \tl_if_eq:NnTF \blx at refsecreset@level { 2 }
       { \DeclarePrintbibliographyDefaults { heading = subbibintoc } }
       { \DeclarePrintbibliographyDefaults { heading = njubibintoc } }
@@ -892,6 +977,7 @@
           { \__nju_name:n { ##1 } } { \__nju_name:n { ##1 _en } }
       }
   }
+\cs_generate_variant:Nn \__nju_cref_name:n { V }
 \crefdefaultlabelformat { #2#1#3\, }
 \crefformat { equation      } { 公式~#2#1#3~   }
 \crefformat { chapter       } { 第#2#1#3章     }
@@ -899,8 +985,9 @@
 \crefformat { subsection    } { 第~#2#1#3~小节 }
 \crefformat { subsubsection } { 第~#2#1#3~小节 }
 \__nju_cref_name:n { figure, table, appendix, proof }
-\exp_args:NV \__nju_cref_name:n \c__nju_theorem_type_clist
+\__nju_cref_name:V \g__nju_theorem_type_clist
 \DeclareGraphicsExtensions { .pdf, .eps, .jpg, .png }
+\BeforeBeginEnvironment { tabular } { \centering \zihao {5} }
 \DeclareCaptionStyle{njucap}
   {
     font          = small,
@@ -919,419 +1006,43 @@
   }
 \theoremsymbol { \ensuremath { \mdwhtsquare } }
 \newtheorem* { proof } { \c__nju_name_proof_tl }
-\__nju_new_theorem:N \c__nju_theorem_type_clist
-\cs_new_protected:Npn \__nju_split_title:n #1
+\group_begin:
+  \clist_remove_all:Nn \g__nju_theorem_type_clist { proof }
+  \__nju_new_theorem:N \g__nju_theorem_type_clist
+\group_end:
+\cs_new_protected:Npn \__nju_new_img_cmd:nn #1#2
   {
-    \tl_if_in:VnTF { #1 } { \\ }
-      {
-        \seq_set_split:NnV \l__nju_tmp_seq { \\ } { #1 }
-        \clist_set_from_seq:NN \l__nju_tmp_clist \l__nju_tmp_seq
-      }
-      {
-        \__nju_put_inempty_seg:nnn { #1 } { 1  } { 15 }
-        \__nju_put_inempty_seg:nnn { #1 } { 16 } { 15 }
-        \__nju_put_inempty_seg:nnn { #1 } { 31 } { 15 }
-      }
+    \exp_args:Nc \NewDocumentCommand { #1 } { o m m }
+      { \includegraphics [ width = ##2, height = ##3 ] { #2 } }
   }
-\cs_new_protected:Npn \__nju_multiline_title:nnn #1#2#3
+\cs_generate_variant:Nn \__nju_new_img_cmd:nn { nV }
+\keys_define:nn { nju / style }
   {
-    \__nju_split_title:n { \l__nju_info_title_tl }
-    \__nju_spread_box:nnn { #2 } { \kaishu } { \c__nju_name_title_tl }
-    \__nju_hskip:
-    \clist_map_inline:Nn \l__nju_tmp_clist
-      { \__nju_ulined_center_box:nn { #3 } { #1 ##1 } \__nju_vskip: }
+    emblem-img .code:n =
+      { \__nju_new_img_cmd:nV { njuemblem } \l_keys_value_tl },
+    name-img   .code:n =
+      { \__nju_new_img_cmd:nV { njuname   } \l_keys_value_tl }
   }
-\cs_new_protected:Npn \__nju_cover_entry:nnn #1#2#3
+\msg_new:nnn { njuthesis } { missing-image }
   {
-    \__nju_spread_box:nnn { #2 } { \kaishu } { \__nju_name:n { #1 } }
-    \__nju_hskip:
-    \__nju_ulined_center_box:nn { #3 }       { \__nju_info:n { #1 } }
-    \__nju_vskip:
+    Local~ images~ not~ designated.\\
+    It~ seems~ that~ you~ haven't~ fill~ in~ both~
+    "style/emblem-img"~ and~ "style/name-img",~
+    therefore~ I~ am~ using~ package~ "njuvisual"~
+    instead,~ which~ may~ slow~ down~ the~ compilation.
   }
-\cs_new_protected:Npn \__nju_cover_bientry:nnnn #1#2#3#4
-  {
-    \__nju_spread_box:nnn { #3 } { \kaishu } { \__nju_name:n { #1 } }
-    \__nju_hskip:
-    \__nju_ulined_center_box:nn { #4 }       { \__nju_info:n { #1 } }
-    \skip_horizontal:n { 0.5 em }
-    \__nju_spread_box:nnn { #3 } { \kaishu } { \__nju_name:n { #2 } }
-    \__nju_hskip:
-    \__nju_ulined_center_box:nn { #4 }       { \__nju_info:n { #2 } }
-    \__nju_vskip:
-  }
-\cs_new_protected:Npn \__nju_cover_supv_entry:nnn #1#2#3
-  {
-    \__nju_spread_box:nnn { #2 } { \kaishu } { \__nju_name:n { #1 } }
-    \__nju_hskip:
-    \__nju_ulined_center_box:nn { #3 }
-      { \clist_item:cn { l__nju_info_ #1 _clist } { 1 } }
-    \skip_horizontal:n { 0.5 em }
-    \__nju_spread_box:nnn { #2 } { \kaishu } { \c__nju_name_supv_ttl_tl }
-    \__nju_hskip:
-    \__nju_ulined_center_box:nn { #3 }
-      { \clist_item:cn { l__nju_info_ #1 _clist } { 2 } }
-    \__nju_vskip:
-  }
-\DeclareObjectType { nju } { \c_zero_int }
-\DeclareTemplateInterface { nju } { element } { \c_zero_int }
-  {
-    content     : tokenlist = \c_empty_tl,
-    format      : tokenlist = \c_empty_tl,
-    bottom-skip : skip      = \c_zero_skip,
-    align       : choice { l, r, c, n } = c
-  }
-\DeclareTemplateCode { nju } { element } { \c_zero_int }
-  {
-    content     = \l__njuelem_content_tl,
-    format      = \l__njuelem_format_tl,
-    bottom-skip = \l__njuelem_bottom_skip,
-    align =
-      {
-        l =
-          { \tl_set_eq:NN \l__njuelem_begin_align_tl \flushleft
-            \tl_set_eq:NN \l__njuelem_end_align_tl   \endflushleft  },
-        r =
-          { \tl_set_eq:NN \l__njuelem_begin_align_tl \flushright
-            \tl_set_eq:NN \l__njuelem_end_align_tl   \endflushright },
-        c =
-          { \tl_set_eq:NN \l__njuelem_begin_align_tl \center
-            \tl_set_eq:NN \l__njuelem_end_align_tl   \endcenter     },
-        n =
-          { \tl_clear:N   \l__njuelem_begin_align_tl
-            \tl_clear:N   \l__njuelem_end_align_tl                  }
-      }
-  }
-  {
-    \AssignTemplateKeys
-    \group_begin:
-      \l__njuelem_begin_align_tl
-      \l__njuelem_format_tl
-      \l__njuelem_content_tl \par
-      \l__njuelem_end_align_tl
-    \group_end:
-    \__nju_vskip:N \l__njuelem_bottom_skip
-  }
-\DeclareTemplateInterface { nju } { page } { \c_zero_int }
-  {
-    element     : commalist = \c_empty_clist,
-    prefix      : tokenlist = \c_empty_tl,
-    format      : tokenlist = \c_empty_tl,
-    top-skip    : skip      = \c_zero_skip,
-    bottom-skip : skip      = \c_zero_skip
-  }
-\DeclareTemplateCode { nju } { page } { \c_zero_int }
-  {
-    element     = \l__njupage_element_clist,
-    prefix      = \l__njupage_prefix_tl,
-    format      = \l__njupage_format_tl,
-    top-skip    = \l__njupage_top_skip,
-    bottom-skip = \l__njupage_bottom_skip
-  }
-  {
-    \AssignTemplateKeys
-    \newpage
-    \__nju_vskip:N \l__njupage_top_skip
-    \group_begin:
-      \l__njupage_format_tl
-      \clist_map_inline:Nn \l__njupage_element_clist
-        { \UseInstance { nju } { \l__njupage_prefix_tl ##1 } }
-    \group_end:
-    \__nju_vskip:N \l__njupage_bottom_skip
-  }
-\cs_new_protected:Npn \__nju_declare_element:nn #1#2
-  { \DeclareInstance { nju } {#1} { element } {#2} }
-\cs_new_protected:Npn \__nju_declare_page:nn    #1#2
-  { \DeclareInstance { nju } {#1} { page    } {#2} }
-\keys_define:nn { nju / style }
-  {
-    emblem-img .tl_set:N = \l__nju_emblem_img_tl,
-    name-img   .tl_set:N = \l__nju_name_img_tl
-  }
 \ctex_at_end_preamble:n
   {
-    \tl_if_empty:NF \l__nju_emblem_img_tl
+    \bool_lazy_and:nnF
+      { \cs_if_exist_p:N \njuemblem }
+      { \cs_if_exist_p:N \njuname   }
       {
-        \RenewDocumentCommand \njuemblem { o m m }
-          { \includegraphics [ width = #2, height = #3 ]
-              { \l__nju_emblem_img_tl } }
+        \cs_undefine:N \njuemblem
+        \cs_undefine:N \njuname
+        \msg_warning:nn { njuthesis } { missing-image }
+        \RequirePackage { njuvisual }
       }
-    \tl_if_empty:NF \l__nju_name_img_tl
-      {
-        \RenewDocumentCommand \njuname { o m m }
-          { \includegraphics [ width = #2, height = #3 ]
-              { \l__nju_name_img_tl } }
-      }
   }
-\__nju_declare_element:nn { cover / ug / emblem-img }
-  {
-    content = \njuemblem [ black ] { ! } { 3.35 cm },
-    bottom-skip = 1 cm,
-    align   = l
-  }
-\__nju_declare_element:nn { cover / ug / name-img }
-  {
-    content     = \njuname [ black ] { ! } { 3 cm },
-    bottom-skip = 1 cm
-  }
-\__nju_declare_element:nn { cover / ug / title }
-  {
-    content  =
-      \__nju_spread_box:nnn { 9 em } { \bf } { \l__nju_info_type_tl },
-    format   = \zihao { -1 },
-    bottom-skip = 0 pt plus 1.5 fill
-  }
-\__nju_declare_element:nn { cover / ug / info }
-  {
-    content  =
-      \__nju_cover_info_ug:nnn { 4.2 em } { 16 em } { 5.5 em },
-    format   = \zihao { 3 }
-  }
-\cs_new_protected:Npn \__nju_cover_info_ug:nnn #1#2#3
-  {
-    \begin{minipage} { #1 + #2 + 0.3 em }
-      \raggedleft
-      \__nju_cover_entry:nnn { dept     } { #1 } { #2 }
-      \__nju_cover_entry:nnn { major    } { #1 } { #2 }
-      \__nju_multiline_title:nnn  { \bf } { #1 } { #2 }
-      \__nju_cover_bientry:nnnn { grade } { id } { #1 } { #3 }
-      \__nju_cover_entry:nnn { author   } { #1 } { #2 }
-      \__nju_cover_supv_entry:nnn { supv } { #1 } { #3 }
-      \bool_if:NT \l__nju_second_supv_bool
-        { \__nju_cover_supv_entry:nnn { supv_ii } { #1 } { #3 } }
-      \__nju_cover_entry:nnn { sm_date  } { #1 } { #2 }
-    \end{minipage}
-  }
-\__nju_declare_element:nn { cover / g / emblem-img }
-  {
-    content     = \njuemblem [ black ] { ! } { 1.9 cm },
-    bottom-skip = 1 cm
-  }
-\__nju_declare_element:nn { cover / g / name-img }
-  {
-    content = \njuname [ black ] { 4.4 cm } { ! },
-    bottom-skip = 2 cm
-  }
-\__nju_declare_element:nn { cover / g / type }
-  {
-    content     =
-      \__nju_spread_box:nnn { 9 em } { } { \l__nju_info_type_tl },
-    format      = \zihao { -1 } \bfseries,
-    bottom-skip = 1 cm
-  }
-\__nju_declare_element:nn { cover / g / degree }
-  {
-    content     = \c__nju_name_apply_tl,
-    format      = \zihao { -1 } \bfseries,
-    bottom-skip = 1 cm plus 1.5 fil
-  }
-\__nju_declare_element:nn { cover / g / info }
-  {
-    content     = \__nju_cover_info_g:nn { 6.2 em } { 18 em },
-    bottom-skip = 0 pt plus 1.5 fil
-  }
-\__nju_declare_element:nn { cover / g / date }
-  { content = \l__nju_info_sm_date_tl }
-\cs_new_protected:Npn \__nju_cover_info_g:nn #1#2
-  {
-    \begin{minipage} { #1 + #2 + 0.3 em }
-      \raggedleft
-      \__nju_multiline_title:nnn { } { #1 } { #2 }
-      \clist_map_inline:nn { author, major, field, supv_full }
-        { \__nju_cover_entry:nnn { ##1 } { #1 } { #2 } }
-    \end{minipage}
-  }
-\__nju_declare_element:nn { cover / g / back }
-  {
-    content = \__nju_cover_back_g:,
-    align   = l
-  }
-\cs_new_protected:Npn \__nju_cover_back_g:
-  {
-    \__nju_spread_box:nnn { 6.2 em } { \kaishu } { \c__nju_name_id_tl }
-    { : \__nju_quad: } \l__nju_info_id_tl
-    \__nju_vskip:
-    \__nju_spread_box:nnn { 6.2 em } { \kaishu } { \c__nju_name_df_date_tl }
-    { : \__nju_quad: } \l__nju_info_df_date_tl
-    \__nju_vskip:
-    \__nju_spread_box:nnn { 6.2 em } { \kaishu } { \c__nju_name_supv_full_tl }
-    { : \__nju_quad: } \skip_horizontal:n { 8 em } \c__nju_name_sign_tl
-  }
-\__nju_declare_element:nn { cover / g / en / title }
-  {
-    content     = \l__nju_info_title_en_tl,
-    format      = \bf \sffamily \zihao { 2 },
-    bottom-skip = 2 cm
-  }
-\__nju_declare_element:nn { cover / g / en / top }
-  {
-    content      =
-      { by }
-      \skip_vertical:N \c_zero_skip
-      \textbf { \sffamily \l__nju_info_author_en_tl }
-      \skip_vertical:n { .5 cm }
-      { Supervised~ by }
-      \skip_vertical:N \c_zero_skip
-      \textsf { \l__nju_info_supv_full_en_tl },
-    format      = \zihao { 4 },
-    bottom-skip = 0 pt plus 1.2 fil
-  }
-\__nju_declare_element:nn { cover / g / en / middle }
-  {
-    content     =
-      \c__nju_cover_en_text_tl \__nju_vskip:
-      \textsc { \clist_item:Nn \c__nju_name_degree_en_clist
-                  { \l__nju_info_degree_int } }
-      \__nju_vskip: { in } \__nju_vskip:
-      \l__nju_info_major_en_tl,
-    bottom-skip = 2 cm
-  }
-\__nju_declare_element:nn { cover / g / en / emblem-img }
-  {
-    content     = \njuemblem [ black ] { ! } { 2.5 cm },
-    bottom-skip = 1.5 cm
-  }
-\__nju_declare_element:nn { cover / g / en / bottom }
-  {
-    content =
-      \l__nju_info_dept_en_tl \skip_vertical:N \c_zero_skip
-      \c__nju_name_nju_en_tl  \skip_vertical:n { 1 cm }
-      \l__nju_info_sm_date_en_tl
-  }
-\__nju_declare_element:nn { cover / nl / top }
-  {
-    content     = \__nju_cover_top_nl:,
-    bottom-skip = 2 cm
-  }
-\__nju_declare_element:nn { cover / nl / name }
-  {
-    content     =
-      \__nju_spread_box:nnn { 6 em } { } { \c__nju_name_title_tl },
-    format      = \zihao { -0 },
-    bottom-skip = 0 pt plus 1.2 fil
-  }
-\__nju_declare_element:nn { cover / nl / title }
-  {
-    content     = \__nju_cover_title_nl:,
-    format      = \zihao { 1 },
-    bottom-skip = 1 cm
-  }
-\__nju_declare_element:nn { cover / nl / middle }
-  {
-    content     = \__nju_cover_info_nl:,
-    format      = \zihao { 4 },
-    bottom-skip = 0 pt plus 1.2 fil
-  }
-\__nju_declare_element:nn { cover / nl / bottom }
-  {
-    content     = \__nju_cover_bottom_nl:,
-    bottom-skip = 1 cm,
-    align       = r
-  }
-\__nju_declare_element:nn { cover / nl / date }
-  {
-    content = \__nju_qquad: 年 \__nju_quad: 月 \__nju_quad: 日,
-    format  = \kaishu \zihao { 3 }
-  }
-\cs_new_protected:Npn \__nju_cover_top_nl:
-  {
-    \__nju_spread_box:nnn { 3.2 em } { } { \c__nju_name_clc_tl   } \__nju_hskip:
-    \__nju_ulined_center_box:nn { 9 em } { \l__nju_info_clc_tl   } \hfill
-    \__nju_spread_box:nnn { 3.2 em } { } { \c__nju_name_seclv_tl } \__nju_hskip:
-    \__nju_ulined_center_box:nn { 9 em } { \l__nju_info_seclv_tl } \\
-    \__nju_spread_box:nnn { 3.2 em } { } { \c__nju_name_udc_tl   } \__nju_hskip:
-    \__nju_ulined_center_box:nn { 9 em } { \l__nju_info_udc_tl   } \hfill \null
-  }
-\cs_new_protected:Npn \__nju_cover_title_nl:
-  {
-    \__nju_split_title:n { \l__nju_info_title_tl }
-    \__nju_multiline_box:nnnn { \l__nju_tmp_int } \l__nju_tmp_clist { 3 } { 15 em }
-    \skip_vertical:n { - 0.5 cm }
-    { \zihao { 4 } \c__nju_name_title_nl_tl }
-    \skip_vertical:N \c_zero_skip
-    \__nju_ulined_center_box:nn { 4.5 em } { \l__nju_info_author_tl }
-    \skip_vertical:n { - 0.5 cm }
-    { \zihao { 4 } { ( } \c__nju_name_author_tl { ) } }
-  }
-\cs_new_protected:Npn \__nju_cover_info_nl:
-  {
-    \tl_set:Nn \l__nju_info_supv_tl
-      { \clist_item:Nn \l__nju_info_supv_clist { 1 } }
-    \tl_set:Nn \l__nju_info_supv_ttl_tl
-      { \clist_item:Nn \l__nju_info_supv_clist { 2 } }
-    \__nju_uline_entry:Nnnn   \l__nju_tmp_dim { supv_info } { supv   } { } \\
-    \__nju_ulined_center_box:nn { \textwidth } { \__nju_info:n { supv_ttl }
-    \__nju_quad: \__nju_info:n  { supv_cont } }                             \\
-    \__nju_uline_bientry:Nnnn \l__nju_tmp_dim { degree   } { degree  } { }
-    \__nju_uline_bientry:Nnnn \l__nju_tmp_dim { major_nl } { major   } { } \\
-    \__nju_uline_bientry:Nnnn \l__nju_tmp_dim { sm_date  } { sm_date } { }
-    \__nju_uline_bientry:Nnnn \l__nju_tmp_dim { df_date  } { df_date } { } \\
-    \__nju_full_uline:Nn \l__nju_tmp_dim { \c__nju_name_confer_tl }
-    \__nju_uline:n { \l__nju_tmp_dim }
-  }
-\cs_new_protected:Npn \__nju_cover_bottom_nl:
-  {
-    \__nju_name:n { chairman } \__nju_hskip:
-    \__nju_ulined_center_box:nn { 9 em } { \__nju_info:n { chairman } } \\
-    \__nju_name:n { reviewer } \__nju_hskip:
-    \__nju_multiline_box:nnnn { \l__nju_tmp_int }
-      { \l__nju_info_reviewer_clist } { 4 } { 9 em }
-  }
-\__nju_declare_page:nn { cover-ug-default }
-  {
-    element     = { emblem-img, name-img, title, info },
-    prefix      = cover / ug /,
-    bottom-skip = 0.5 cm plus 1.5 fill
-  }
-\__nju_declare_page:nn { cover-g-front-default }
-  {
-    element  = { emblem-img, name-img, type, degree, info, date },
-    prefix   = cover / g /,
-    format   = \zihao { 3 } \kaishu,
-    top-skip = 1.5 cm
-  }
-\__nju_declare_page:nn { cover-g-back-default }
-  {
-    element  = { back },
-    prefix   = cover / g /,
-    format   = \zihao { 3 } \kaishu,
-    top-skip = 20 cm
-  }
-\__nju_declare_page:nn { cover-g-en-default }
-  {
-    element  = { title, top, middle, emblem-img, bottom },
-    prefix   = cover / g / en /,
-    top-skip = 0 pt plus 1.2 fil
-  }
-\__nju_declare_page:nn { cover-nl-default }
-  {
-    element = { top, name, title, middle, bottom, date },
-    prefix  = cover / nl /,
-    format  = \kaishu
-  }
-\cs_new_protected:Npn \__nju_make_cover_ug:
-  { \UseInstance { nju } { cover-ug-default } }
-\cs_new_protected:Npn \__nju_make_cover_g:
-  {
-    \clist_map_inline:nn { front, back, en }
-      { \UseInstance { nju } { cover-g- ##1 -default } }
-  }
-\cs_new_protected:Npn \__nju_make_cover_nl:
-  { \UseInstance { nju } { cover-nl-default } }
-\cs_new_protected:Npn \__nju_make_orig_decl:
-  {
-    \chapter* { \c__nju_name_nju_tl \c__nju_name_orig_decl_tl }
-    \thispagestyle { empty }
-    \c__nju_orig_decl_text_tl
-    \vfil
-    \begin{flushright}
-      \clist_set:Nn \l__nju_tmp_clist { orig_sign, id, orig_date }
-      \int_compare:nF { \l__nju_info_degree_int == 1 }
-        { \clist_remove_all:Nn \l__nju_tmp_clist { id } }
-      \clist_map_inline:Nn \l__nju_tmp_clist
-        { \__nju_vskip: \__nju_name:n { ##1 } : \__nju_uline:n { 7 em } }
-    \end{flushright}
-    \vfil
-  }
 \RenewDocumentCommand \maketitle { }
   {
     \bool_if:NF \g__nju_draft_bool
@@ -1340,103 +1051,18 @@
         \pagenumbering { gobble }
         \bool_if:NTF \g__nju_nlcover_bool
           { \__nju_make_cover_nl: }
-          { \use:c { __nju_make_cover_ \l__nju_info_diploma_tl : } }
+          { \__nju_make_cover:    }
         \bool_if:NT \g__nju_orig_decl_bool { \__nju_make_orig_decl: }
       }
     \tl_remove_all:Nn \l__nju_info_title_tl { \\ }
     \cleardoublepage
-    \pagestyle     { plain }
+    \exp_args:NV \pagestyle \c__nju_pagestyle_tl
     \pagenumbering { Roman }
-    \normalfont \normalsize
   }
-\keys_define:nn { nju / style }
-  {
-    abstract-in-toc .bool_gset:N = \g__nju_abs_in_toc_bool,
-    abstract-in-toc   .initial:n = true
-  }
-\cs_new_protected:Npn \__nju_abs_bookmark:nn #1#2
-  {
-    \phantomsection
-    \bool_if:NTF \g__nju_abs_in_toc_bool
-      { \__nju_add_tocline:n { #1 } }
-      { \pdfbookmark [0] { #1 } { #2 } }
-  }
-\cs_generate_variant:Nn \__nju_abs_bookmark:nn { Vn }
-\cs_new_protected:Npn \__nju_abs_title_uuline:n #1
-  { \bf \kaishu \zihao { -2 } \__nju_uuline:n { #1 } }
-\cs_new_protected:Npn \__nju_abs_info_style:n #1
-  { \noindent \zihao{ #1 } \kaishu }
-\cs_new_protected:Npn \__nju_abs_info_style_en: #1
-  { \zihao{ #1 } }
-\cs_new_protected:Npn \__nju_abs_title_ug:n #1
-  {
-    \clist_map_inline:nn { nju, type, lang #1, abstract }
-      { \__nju_name:n { ##1 } }
-  }
-\cs_new_protected:Npn \__nju_abs_info_ug:nn #1#2
-  {
-    \tl_if_blank:eTF { #1 }
-      { \c__nju_name_title_tl }
-      { \clist_item:Nn \c__nju_name_type_en_clist { \l__nju_info_type_int } }
-    #2 \tl_use:c { l__nju_info_title #1 _tl } \\
-    \tl_set_eq:NN \c__nju_name_author_tl \c__nju_name_author_full_tl
-    \clist_map_inline:nn { dept, major, author, supv_full }
-      { \__nju_name:n { ##1 #1 } #2 \__nju_info:n { ##1 #1 } \\ }
-    \__nju_name:n { abstract #1 } #2
-  }
-\cs_new_protected:Npn \__nju_abs_title_g:n #1
-  {
-    \__nju_name:n { nju     } \__nju_info:n { type       }
-    \__nju_name:n { lang #1 } \__nju_name:n { abstract_r }
-  }
-\cs_new_protected:Npn \__nju_abs_info_g:nn #1#2
-  {
-    \tl_if_blank:eTF { #1 }
-      {
-        \__nju_full_uline:NV \l__nju_tmp_dim
-          {
-            \clist_item:Nn \c__nju_name_type_clist { \l__nju_info_type_int }
-            \c__nju_name_title_s_tl #2
-          }
-        \__nju_ulined_center_box:nn { \l__nju_tmp_dim }
-          { \tl_range:Nnn \l__nju_info_title_tl { 1 } { 20 } } \\
-        \__nju_uline:n { \textwidth } \__nju_qquad:
-        \tl_range:Nnn \l__nju_info_title_tl { 21 } { -1 } \\
-        \__nju_full_uline:NV \l__nju_tmp_dim
-          {
-            \__nju_ulined_center_box:nn { 11 em } { \l__nju_info_major_tl }
-            \c__nju_name_major_s_tl
-            \__nju_ulined_center_box:nn { 4 em } { \l__nju_info_grade_tl }
-            \c__nju_name_grade_tl
-            \tl_item:nn { \l__nju_info_degree_tl } { 1 }
-            \c__nju_name_author_r_tl #2
-          }
-        \__nju_ulined_center_box:nn { \l__nju_tmp_dim }
-          { \l__nju_info_author_tl } \\
-        \__nju_full_uline:NV \l__nju_tmp_dim
-          { \c__nju_name_supv_full_tl \c__nju_name_supv_r_tl #2 }
-        \__nju_ulined_center_box:nn { \l__nju_tmp_dim }
-          { \l__nju_info_supv_full_tl }
-      }
-      {
-        \__nju_full_uline:NV \l__nju_tmp_dim
-          { \clist_item:cn { c__nju_name_type #1 _clist }
-              { \l__nju_info_type_int } # 2 }
-        \__nju_ulined_center_box:nn { \l__nju_tmp_dim }
-          { \tl_range:Nnn \l__nju_info_title_en_tl { 1 } { 40 } } \\
-        \__nju_uline:n { \textwidth } \__nju_qquad:
-        \tl_range:Nnn \l__nju_info_title_en_tl { 41 } { -1 }
-        \clist_map_inline:nn { major, author, supv_full }
-          { \\
-            \__nju_uline_entry:Nnnn \l__nju_tmp_dim { ##1 _en } { ##1 _en } { #2 }
-          }
-      }
-  }
 \cs_new_protected:Npn \__nju_print_keywords:nn #1#2
   {
-    \exp_args:NNc
-      \tl_set_eq:NN \l__nju_tmp_tl { c__nju_name_keywords #1 _tl }
-    \__nju_get_text_width:Nn \l__nju_tmp_dim { \l__nju_tmp_tl }
+    \tl_set:Nv \l__nju_tmp_tl { c__nju_name_keywords #1 _tl }
+    \__nju_get_text_width:NV \l__nju_tmp_dim \l__nju_tmp_tl
     \list { }
       {
         \labelwidth  \l__nju_tmp_dim
@@ -1450,35 +1076,17 @@
       \clist_use:cn { l__nju_info_keywords #1 _clist } { #2 }
     \endlist
   }
-\cs_new_protected:Npn \__nju_make_abs_ug:nn #1#2
+\keys_define:nn { nju / style }
   {
-    \begin{center}
-      \__nju_abs_title_uuline:n { 22 em }
-      \__nju_abs_title_ug:n { #1 }
-    \end{center}
-    \group_begin:
-      \__nju_abs_info_style:n { -4 }
-      \__nju_abs_info_ug:nn { #1 } { #2 }
-    \group_end: \__nju_vskip:
+    abstract-in-toc .bool_gset:N = \g__nju_abs_in_toc_bool,
+    abstract-in-toc   .initial:n = true
   }
-\cs_new_protected:Npn \__nju_make_abs_g:nn #1#2
-  {
-    \begin{center}
-      \__nju_abs_title_uuline:n { 19 em }
-      \__nju_abs_title_g:n { #1 }
-    \end{center}
-    \group_begin:
-      \__nju_abs_info_style:n { 4 }
-      \__nju_abs_info_g:nn { #1 } { #2 }
-    \group_end: \__nju_vskip:
-  }
 \NewDocumentEnvironment { abstract } { +b }
   {
     \cleardoublepage
     \thispagestyle { plain }
-    \__nju_abs_bookmark:Vn
-      { \c__nju_name_lang_tl \c__nju_name_abstract_tl } { abstract }
-    \use:c { __nju_make_abs_ \l__nju_info_diploma_tl :nn } { } { : }
+    \__nju_abs_bookmark:Vn \c__nju_name_abstract_a_tl { abstract }
+    \__nju_make_abstract:
     \group_begin: \kaishu \zihao { -4 } #1
   }
   { \__nju_print_keywords:nn { } { ; } \group_end: }
@@ -1486,15 +1094,15 @@
   {
     \cleardoublepage
     \thispagestyle { plain }
-    \__nju_abs_bookmark:Vn { \c__nju_name_abstract_en_tl } { abstract-en }
-    \use:c { __nju_make_abs_ \l__nju_info_diploma_tl :nn } { _en } { :~ }
-    \group_begin: \zihao{ -4 } #1
+    \__nju_abs_bookmark:Vn \c__nju_name_abstract_a_en_tl { abstract-en }
+    \__nju_make_abstract_en:
+    \group_begin: \zihao { -4 } #1
   }
   { \__nju_print_keywords:nn { _en } { ;~ } \group_end: }
 \NewDocumentEnvironment { preface         } { +b }
-  { \__nju_chapter:V { \c__nju_name_preface_tl         } #1 } { }
+  { \__nju_chapter:V \c__nju_name_preface_tl         #1 } { }
 \NewDocumentEnvironment { acknowledgement } { +b }
-  { \__nju_chapter:V { \c__nju_name_acknowledgement_tl } #1 } { }
+  { \__nju_chapter:V \c__nju_name_acknowledgement_tl #1 } { }
 \NewDocumentCommand \njupaperlist
   { O { \c__nju_name_paperlist_tl } m }
   {
@@ -1531,7 +1139,7 @@
   }
 \NewDocumentEnvironment { notation } { O { 10 em } O { 5 em } }
   {
-    \__nju_chapter:V { \c__nju_name_notation_tl }
+    \__nju_chapter:V \c__nju_name_notation_tl
     \__nju_make_notation:nn { #1 } { #2 }
   }
   { \endlist }



More information about the tex-live-commits mailing list.