Skip to content
Snippets Groups Projects
njuthesis.dtx 220 KiB
Newer Older
% 在开启某些选项时,本模板也会调用以下宏包:
% \begin{itemize}
%   \item \pkg{fandol}、\pkg{tex-gyre} 和 \pkg{tex-gyre-math},提供自由字体。
%   \item \pkg{emptypage},在双面模式下清空空白页的页眉、页脚和页码。
%   \item \pkg{njuvisual},用于绘制封面的校名校徽。
Yu Xiong's avatar
Yu Xiong committed
%   \item \pkg{tabularray},用于绘制研究生的出版授权书信息表格。
%   \item \pkg{xeCJKfntef} 或 \pkg{lua-ul},用于在对应引擎下绘制下划线。
% \end{itemize}
%
% 下列宏包会与本模板产生冲突,或者不能发挥预期作用:
% \begin{itemize}
%   \item \pkg{natbib} 和 \pkg{gbt7714} 等 \hologo{BibTeX} 相关的参考文献宏包。
%   \item \pkg{bm} 等使用传统数学字体配置方案的宏包。
%   \item \pkg{babel} 在直接使用时会覆盖默认的中文名称设置。
%   \item \pkg{microtype} 在 \hologo{XeTeX} 和 \hologo{LuaTeX} 下支持有限。
Yu Xiong's avatar
Yu Xiong committed
% \begin{thebibliography}{99}
%
% \newcommand\urlprefix{\newline\hspace*{\fill}}
% \let\OldUrl=\url
% \renewcommand\url[2][]{{\small\textit{#1}~\OldUrl{#2}}}
% \newcommand\CTANurl[2][]{{^^A
%   \small\textit{#1}~\href{http://mirror.ctan.org/#2}{\texttt{CTAN://#2}}}}
%
% \subsection*{书籍}
Yu Xiong's avatar
Yu Xiong committed
%
% \bibitem{lshort}
% \textsc{Oetiker T}, \textsc{Partl H}, \textsc{Hyna I}, et al.
% \newblock \textit{The Not So Short Introduction to \hologo{LaTeXe}: Or \hologo{LaTeXe} in 139 minutes} [EB/OL].
% \newblock version 6.4,
% \newblock (2021-03-09)
% \urlprefix\url{https://ctan.org/pkg/lshort-english}
% \urlprefix\CTANurl[文档:]{info/lshort/english/lshort.pdf}
%
% \bibitem{lshort-zh-cn}
% \textsc{Oetiker T}, \textsc{Partl H}, \textsc{Hyna I}, et al.
% \newblock \textit{一份(不太)简短的 \hologo{LaTeXe} 介绍: 或 111 分钟了解 \hologo{LaTeXe}} [EB/OL].
% \newblock \CTeX{} 开发小组, 译.
% \newblock 原版版本 version 6.4, 中文版本 version 6.03,
% \newblock (2021-11-21)
% \urlprefix\url{https://ctan.org/pkg/lshort-zh-cn}
% \urlprefix\CTANurl[文档:]{info/lshort/chinese/lshort-zh-cn.pdf}
%
Yu Xiong's avatar
Yu Xiong committed
% \bibitem{install-latex-guide-zh-cn}
% 王然.
% \newblock \textit{一份简短的关于 \hologo{LaTeX} 安装的介绍} [EB/OL].
% \newblock version 2021.12.1,
% \newblock (2021-12-01)
% \urlprefix\url{https://ctan.org/pkg/install-latex-guide-zh-cn}
% \urlprefix\CTANurl[文档:]{info/install-latex-guide-zh-cn/install-latex-guide-zh-cn.pdf}
%
% \bibitem{刘海洋2013latex入门}
% 刘海洋.
% \newblock \textit{\hologo{LaTeX} 入门} [M].
% \newblock 北京: 电子工业出版社, 2013
%
Yu Xiong's avatar
Yu Xiong committed
%
% \subsection*{标准、规范}
Yu Xiong's avatar
Yu Xiong committed
% \bibitem{gb-t-7408-2005}
% 全国信息与文献标准化技术委员会.
% \newblock \textit{数据元和交换格式\quad 信息交换~ 日期和时间表示法: GB/T 7408--2005} [S].
% \newblock 北京: 中国标准出版社, 2005
%
% \bibitem{gb-t-7713.1-2006}
% 全国信息与文献标准化技术委员会.
% \newblock \textit{学位论文编写规则: GB/T 7713.1--2006} [S].
% \newblock 北京: 中国标准出版社, 2006
%
% \bibitem{gb-t-7714-2015}
% 全国信息与文献标准化技术委员会.
% \newblock \textit{信息与文献\quad 参考文献著录规则: GB/T 7714--2015} [S].
% \newblock 北京: 中国标准出版社, 2015
%
% \bibitem{nju2021}
% 南京大学本科生院.
% \newblock \textit{关于启动南京大学2022届本科毕业论文(设计)工作的通知} [EB/OL].
% \newblock (2021-12-14)
% \urlprefix\url{https://jw.nju.edu.cn/7c/86/c26263a556166/page.htm}
%
%
% \subsection*{宏包}
Yu Xiong's avatar
Yu Xiong committed
%
Yu Xiong's avatar
Yu Xiong committed
% \bibitem{biblatex}
% \textsc{Lehman P}, \textsc{Wright J}, \textsc{Boruvka A}, \textsc{Kime P}.
% \newblock \textit{Sophisticated Bibliographies in \hologo{LaTeX}} [EB/OL].
% \newblock version 3.17,
% \newblock (2022-02-02)
% \urlprefix\url{https://ctan.org/pkg/biblatex}
% \urlprefix\CTANurl[文档:]{macros/latex/contrib/biblatex/doc/biblatex.pdf}
%
% \bibitem{biblatex-gb7714-2015}
% 胡振震.
% \newblock \textit{符合 GB/T 7714-2015 标准的 biblatex 参考文献样式} [EB/OL].
% \newblock version 1.1b,
% \newblock (2021-12-11)
% \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}
%
Yu Xiong's avatar
Yu Xiong committed
% \bibitem{latexmk}
% \textsc{Collins J}.
% \newblock \textit{Fully automated \hologo{LaTeX} document generation} [EB/OL].
% \newblock version 4.76,
% \newblock (2021-11-20)
% \urlprefix\url{https://www.ctan.org/pkg/latexmk}
% \urlprefix\CTANurl[文档:]{support/latexmk/latexmk.pdf}
%
% \bibitem{listings}
% \textsc{Heinz C}, \textsc{Moses B}, \textsc{Hoffmann J}.
% \newblock \textit{Typeset source code listings using \hologo{LaTeX}} [EB/OL].
% \newblock version 1.8d,
% \newblock (2020-03-24)
% \urlprefix\url{https://www.ctan.org/pkg/listings}
% \urlprefix\CTANurl[文档:]{macros/latex/contrib/listings/listings.pdf}
%
Yu Xiong's avatar
Yu Xiong committed
% \bibitem{njuvisual}
% \textsc{Yu Xiong}.
% \newblock \textit{Display logos related to Nanjing University} [EB/OL].
% \newblock version 0.2.1,
% \newblock (2022-01-09)
% \urlprefix\url{https://ctan.org/pkg/njuvisual}
% \urlprefix\CTANurl[文档:]{macros/latex/contrib/njuvisual/njuvisual.pdf}
Yu Xiong's avatar
Yu Xiong committed
% \bibitem{tabularray}
% \textsc{Jianrui Lyu}.
% \newblock \textit{Typeset tabulars and arrays with \hologo{LaTeX3}} [EB/OL].
% \newblock version 2021Q,
% \newblock (2021-12-01)
% \urlprefix\url{https://ctan.org/pkg/tabularray}
% \urlprefix\CTANurl[文档:]{macros/latex/contrib/tabularray/tabularray.pdf}
%
%
% \subsection*{模板}
%
% \bibitem{fduthesis}
% 曾祥东.
% \newblock \textit{fduthesis: 复旦大学论文模板} [EB/OL].
% \newblock version 0.7e,
% \newblock (2020-08-30)
% \urlprefix\url{https://ctan.org/pkg/fduthesis}
% \urlprefix\CTANurl[文档及源代码:]{macros/latex/contrib/fduthesis/fduthesis.pdf}
%
% \bibitem{thuthesis}
% 清华大学 TUNA 协会.
% \newblock \textit{\textsc{ThuThesis}:清华大学学位论文模板} [EB/OL].
% \newblock version 7.2.3,
% \newblock (2021-05-31)
% \urlprefix\url{https://ctan.org/pkg/thuthesis}
% \urlprefix\CTANurl[文档及源代码:]{macros/latex/contrib/thuthesis/thuthesis.pdf}
%
%
% \emph{以下模版现已停止更新。}
%
% \bibitem{wenboyang2013}
% 杨文博.
% \newblock \textit{南京大学学位论文 \hologo{LaTeX} 模板} [EB/OL].
% \newblock (2018-06-23)
% \urlprefix\url{https://github.com/solrex/njuthesis}
%
% \bibitem{fireblue2013}
% \textsc{fireblue}.
% \newblock \textit{南京大学学位论文 \hologo{LaTeX} 模板} [EB/OL].
% \newblock (2013-04-13)
% \urlprefix\url{https://github.com/fireblue/NJUThesis}
%
% \bibitem{wenhai-zheng2013}
% \textsc{wenhai-zheng}.
% \newblock \textit{南京大学本科毕业论文 \hologo{LaTeX} 模板} [EB/OL].
% \newblock (2013-08-12)
% \urlprefix\url{https://github.com/wenhai-zheng/NJUThesis}
%
% \bibitem{zenglecao2013}
% 曹增乐.
% \newblock \textit{南京大学本科毕业论文(设计) \hologo{LaTeX} 模板} [EB/OL].
% \newblock (2019-06-26)
% \urlprefix\url{https://github.com/ZLCao/NJUBachelor}
%
% \bibitem{haixinghu2013}
% 胡海星.
% \newblock \textit{南京大学学位论文 \hologo{XeLaTeX} 模板} [EB/OL].
% \newblock (2018-08-08)
% \urlprefix\url{https://github.com/Haixing-Hu/nju-thesis}
%
% \bibitem{chuhengzhang2016}
% 张楚珩.
% \newblock \textit{南京大学本科生毕业论文 \hologo{LaTeX} 模板} [EB/OL].
% \newblock (2016-06-01)
% \urlprefix\url{https://github.com/zhangchuheng123/NJUThesis}
%
% \bibitem{yanyanjiang2017}
% 蒋炎岩.
% \newblock \textit{南京大学山寨 \hologo{LyX} 研究生毕业论文模板} [EB/OL].
% \newblock (2019-01-16)
% \urlprefix\url{https://github.com/jiangyy/njuthesis}
%
% \bibitem{njuHan2018}
% \textsc{njuHan}.
% \newblock \textit{南京大学学位论文(本科/硕士/博士),毕业论文 \hologo{LaTeX} 模板} [EB/OL].
% \newblock (2021-06-15)
% \urlprefix\url{https://github.com/njuHan/njuthesis-nju-thesis-template}
%
% \bibitem{anyirao2018}
% 饶安逸.
% \newblock \textit{南京大学本科生毕业论文 \hologo{LaTeX} 模板 2018 新版} [EB/OL].
% \newblock (2018-06-24)
% \urlprefix\url{https://github.com/AnyiRao/NJUThesis2018}
%
% \bibitem{yichenzhao2021}
% 赵懿晨.
% \newblock \textit{南京大学本科生毕业论文 \hologo{LaTeX} 模板(2021版)} [EB/OL].
% \newblock (2021-09-23)
% \urlprefix\url{https://github.com/FengChendian/NJUThesis2021}
%
%
Yu Xiong's avatar
Yu Xiong committed
% \end{thebibliography}
%
%
Yu Xiong's avatar
Yu Xiong committed
% \section{代码实现}
Yu Xiong's avatar
Yu Xiong committed
% \changes{v0.10}{2021/09/26}{对代码实现部分进行了整理。}
%
% 本模板使用 \hologo{LaTeX3} 语法编写,依赖 \pkg{expl3} 环境,
% 并需调用 \pkg{l3packages} 中的相关宏包。
%
% 以下代码中有一些形如 \agrd{*class} 的标记,
% 这是 \pkg{DocStrip} 中的“guard”,用来选择性地提取文件。
% “|*|”和“|/|”分别表示该部分的开始和结束。不含
% “|*|”和“|/|”的 guard 出现在行号右侧,它们用来确定
% 单独一行代码的归属。这些 guard 的颜色深浅不一,用以明确嵌套关系。
%
% 另有若干包含 \bgrd{@@} 的 guard,用以表示名空间(模块)。
Yu Xiong's avatar
Yu Xiong committed
% 在删除注释生成格式文件时,源代码变量名称中的 |@@| 会被等号后的字段替换,
% 譬如在本模板主体部分中 \bgrd{〈@@=nju〉}。
% \subsection{准备}
%    \begin{macrocode}
Yu Xiong's avatar
Yu Xiong committed
%<*class>
Yu Xiong's avatar
Yu Xiong committed
%<@@=nju>
Yu Xiong's avatar
Yu Xiong committed
%    \end{macrocode}
%
Yu Xiong's avatar
Yu Xiong committed
% \changes{v0.11}{2021/10/23}{添加了若干环境检查与警告信息。}
% \changes{v0.12}{2021/12/03}{放宽对于 \pkg{l3packages} 的版本要求。}
% 检查 \hologo{LaTeX3} 编程环境。
%    \begin{macrocode}
\RequirePackage { xtemplate, l3keys2e }
\msg_new:nnn { njuthesis } { l3-too-old }
  {
Yu Xiong's avatar
Yu Xiong committed
    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.
\clist_map_inline:nn { xtemplate, l3keys2e }
    \@ifpackagelater {#1} { 2020/10/01 }
      { } { \msg_error:nnn { njuthesis } { l3-too-old } {#1} }
  }
%    \end{macrocode}
%
Yu Xiong's avatar
Yu Xiong committed
% 目前 \cls{njuthesis} 仅支持 \hologo{XeTeX} 和 \hologo{LuaTeX}。
%    \begin{macrocode}
\msg_new:nnn { njuthesis } { unsupported-engine }
  {
    The~ njuthesis~ class~ requires~ either~
Yu Xiong's avatar
Yu Xiong committed
    XeTeX~ or~ LuaTeX. \\
    "#1"~ is~ not~ supported~ at~ present.~
    You~ must~ change~ your~ typesetting~ engine~
Yu Xiong's avatar
Yu Xiong committed
    to~ "xelatex"~ or~ "lualatex".
\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}
%
% \subsection{定义变量}
%
% 在变量名称中,|l| 代表局部变量,|g| 代表全局变量,|c| 代表常量,最后一个下划线后的内容指示其类型。
% \begin{variable}{\l_@@_tmp_box,\l_@@_tmp_clist,
%   \l_@@_tmpa_dim,\l_@@_tmpb_dim,\l_@@_tmp_int,
%   \l_@@_tmp_seq,\l_@@_tmpa_tl,\l_@@_tmpb_tl}
% 临时变量。
%    \begin{macrocode}
Yu Xiong's avatar
Yu Xiong committed
\box_new:N   \l_@@_tmp_box
\clist_new:N \l_@@_tmp_clist
\dim_new:N   \l_@@_tmpa_dim
\dim_new:N   \l_@@_tmpb_dim
Yu Xiong's avatar
Yu Xiong committed
\int_new:N   \l_@@_tmp_int
\seq_new:N   \l_@@_tmp_seq
\tl_new:N    \l_@@_tmpa_tl
\tl_new:N    \l_@@_tmpb_tl
% \end{variable}
Yu Xiong's avatar
Yu Xiong committed
% \begin{variable}{\g_@@_info_degree_int,
%   \g_@@_info_diploma_int,\g_@@_info_type_int}
% 用于存储学位类型的变量。
Yu Xiong's avatar
Yu Xiong committed
\int_new:N \g_@@_info_degree_int
\int_new:N \g_@@_info_diploma_int
Yu Xiong's avatar
Yu Xiong committed
\int_new:N \g_@@_info_type_int
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\g_@@_info_degree_tl,\g_@@_info_diploma_tl,
%   \g_@@_info_type_tl,\g_@@_info_type_en_tl}
% 用于存储学位名称的变量。
%    \begin{macrocode}
\tl_new:N  \g_@@_info_degree_tl
\tl_new:N  \g_@@_info_diploma_tl
\tl_new:N  \g_@@_info_type_tl
\tl_new:N  \g_@@_info_type_en_tl
% \end{variable}
% \begin{variable}{\g_@@_twoside_bool}
% 定义用于判断是否使用双面模式的变量,初始值为使用双面模式。
%    \begin{macrocode}
\bool_new:N \g_@@_twoside_bool
\bool_set_true:N \g_@@_twoside_bool
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\l_@@_second_supv_bool}
% 定义用于判断是否有第二导师的变量。
%    \begin{macrocode}
\bool_new:N \l_@@_second_supv_bool
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\g_@@_info_supvfull_tl,\g_@@_info_supvfull_en_tl}
% 用于存储导师姓名加职称的变量。
\tl_new:N \g_@@_info_supvfull_tl
\tl_new:N \g_@@_info_supvfull_en_tl
% \end{variable}
% \begin{variable}{\g_@@_latin_font_tl,\g_@@_cjk_font_tl}
% 用于存储所使用字体名称的全局变量。
%    \begin{macrocode}
\tl_new:N \g_@@_latin_font_tl
\tl_new:N \g_@@_cjk_font_tl
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\g_@@_config_tl}
% 保存配置文件名称。默认为空。
%    \begin{macrocode}
\tl_new:N \g_@@_config_tl
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\g_@@_theorem_type_clist}
% 定理类型。
%    \begin{macrocode}
\clist_new:N \g_@@_theorem_type_clist
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\g_@@_info_submitdate_tl,\g_@@_info_submitdate_en_tl,
% \g_@@_info_defenddate_tl}
% 用于存储格式化后的论文提交日期和答辩日期的变量。
%    \begin{macrocode}
\tl_new:N \g_@@_info_submitdate_tl
\tl_new:N \g_@@_info_submitdate_en_tl
\tl_new:N \g_@@_info_defenddate_tl
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\c_@@_today_tl}
% 编译当天日期,格式为 |yyyy-mm-dd|。
%    \begin{macrocode}
\tl_const:Nx \c_@@_today_tl
  {
    \int_to_arabic:n { \c_sys_year_int  } -
    \int_to_arabic:n { \c_sys_month_int } -
    \int_to_arabic:n { \c_sys_day_int   }
  }
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\g_@@_name_type_clist,\g_@@_name_type_en_clist,
%   \g_@@_name_degree_clist,\g_@@_name_degree_en_clist}
Yu Xiong's avatar
Yu Xiong committed
% 论文类型与学位类型。
%    \begin{macrocode}
\clist_const:Nn \g_@@_name_type_clist
Yu Xiong's avatar
Yu Xiong committed
  { 毕业论文, 毕业设计 }
\clist_const:Nn \g_@@_name_type_en_clist
Yu Xiong's avatar
Yu Xiong committed
  { THESIS, DESIGN }
\clist_const:Nn \g_@@_name_degree_clist
Yu Xiong's avatar
Yu Xiong committed
  { 学士, 硕士, 硕士专业, 博士 }
\clist_const:Nn \g_@@_name_degree_en_clist
Yu Xiong's avatar
Yu Xiong committed
  { Bachelor, Master, Master, Doctor~of~Philosophy }
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\c_@@_month_en_clist}
% 英文月份名称。
%    \begin{macrocode}
\clist_const:Nn \c_@@_month_en_clist
  {
    January, February, March, April, May, June,
    July, August, September, October, November, December
  }
%    \end{macrocode}
% \end{variable}
%
% \subsection{内部函数}
% \begin{macro}{\@@_quad:,\@@_qquad:}
% 等价于 \LaTeXe{} 中的 \tn{quad} 和 \tn{qquad}。
Yu Xiong's avatar
Yu Xiong committed
%    \begin{macrocode}
\cs_new:Nn \@@_quad:  { \skip_horizontal:n { 1 em } }
\cs_new:Nn \@@_qquad: { \skip_horizontal:n { 2 em } }
Yu Xiong's avatar
Yu Xiong committed
%    \end{macrocode}
Yu Xiong's avatar
Yu Xiong committed
%
% \begin{macro}{\@@_vskip:,\@@_hskip:}
% 生成一个较小的 skip。
Yu Xiong's avatar
Yu Xiong committed
%    \begin{macrocode}
\cs_new:Nn \@@_vskip: { \skip_vertical:N   \g_@@_smallvskip_dim }
\cs_new:Nn \@@_hskip: { \skip_horizontal:N \g_@@_smallhskip_dim }
Yu Xiong's avatar
Yu Xiong committed
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\@@_vskip:N}
% 类似于 \hologo{LaTeX2e} 中的 \tn{vspace*},
% 从上一个页面元素底部开始生成 |skip|。
%    \begin{macrocode}
\cs_new_protected:Npn \@@_vskip:N #1
  {
    \hrule height \c_zero_dim
    \nobreak
    \skip_vertical:n { - \baselineskip - \lineskip }
    \skip_vertical:N #1
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_define_name:nn,\@@_define_name:nnn}
% 用来定义默认名称的辅助函数。
%    \begin{macrocode}
\cs_new_protected:Npn \@@_define_name:nn #1#2
  {
    \tl_new:c   { g_@@_name_ #1    _tl }
    \tl_gset:cn { g_@@_name_ #1    _tl } { #2 }
  }
\cs_new_protected:Npn \@@_define_name:nnn #1#2#3
  {
    \tl_new:c   { g_@@_name_ #1    _tl }
    \tl_gset:cn { g_@@_name_ #1    _tl } { #2 }
    \tl_new:c   { g_@@_name_ #1 _en_tl }
    \tl_gset:cn { g_@@_name_ #1 _en_tl } { #3 }
% \begin{macro}{\@@_define_fmt:nn}
% 用来定义默认样式的辅助函数。
%    \begin{macrocode}
\cs_new_protected:Npn \@@_define_fmt:nn #1#2
  {
    \tl_new:c   { g_@@_fmt_ #1 _tl }
    \tl_gset:cn { g_@@_fmt_ #1 _tl } { #2 }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_define_dim:nn,\@@_define_skip:nn}
% 用来定义默认间距的辅助函数。
%    \begin{macrocode}
\cs_new_protected:Npn \@@_define_dim:nn #1#2
  {
    \dim_new:c   { g_@@_ #1 _dim }
    \dim_gset:cn { g_@@_ #1 _dim } { #2 }
  }
\cs_new_protected:Npn \@@_define_skip:nn #1#2
  {
    \skip_new:c   { g_@@_ #1 _skip }
    \skip_gset:cn { g_@@_ #1 _skip } { #2 }
  }
%    \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}
Yu Xiong's avatar
Yu Xiong committed
% 根据变量名调用名称和内容信息。
\cs_new:Npn \@@_name:n #1 { \tl_use:c { g_@@_name_ #1 _tl } }
\cs_new:Npn \@@_info:n #1 { \tl_use:c { g_@@_info_ #1 _tl } }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_ulined_center_box:nn}
% 带有下划线的水平盒子。
% \begin{arguments}
%   \item 宽度,|dim| 型变量
%   \item 内容,可带有格式
% \end{arguments}
%    \begin{macrocode}
\cs_new_protected:Npn \@@_ulined_center_box:nn #1#2
    \mode_leave_vertical:
    \rule [ -0.55 ex ] { #1 } { 0.4 pt }
    \skip_horizontal:n { -#1 }
    \hbox_to_wd:nn { #1 } { \hfil #2 \hfil }
%    \end{macrocode}
% \end{macro}
%
Yu Xiong's avatar
Yu Xiong committed
% \begin{macro}{\@@_spread_box:nnn,\@@_spread_box:nnV,\@@_spread_box:nnx}
% 分散对齐的水平盒子。
% \begin{arguments}
%   \item 宽度,|dim| 型变量
%   \item 格式
%   \item 内容,不可带有格式
% \end{arguments}
%    \begin{macrocode}
\cs_new_protected:Npn \@@_spread_box:nnn #1#2#3
    \mode_leave_vertical:
    \hbox_to_wd:nn { #1 }
Yu Xiong's avatar
Yu Xiong committed
      { #2 \tl_map_inline:nn { #3 } { ##1 \hfil } \unskip }
Yu Xiong's avatar
Yu Xiong committed
\cs_generate_variant:Nn \@@_spread_box:nnn { nnV }
\cs_generate_variant:Nn \@@_spread_box:nnn { nnx }
% \end{macro}
% \begin{macro}{\@@_multiline_box:nnnn}
% 多行固定长度的下划线内容,用于国家图书馆封面。
% \begin{arguments}
%   \item 用于循环的 |int| 型变量
%   \item 内容,|clist| 型变量
%   \item 行数
%   \item 宽度,|dim| 型变量
% \end{arguments}
%    \begin{macrocode}
\cs_new_protected:Npn \@@_multiline_box:nnnn #1#2#3#4
    \int_set:Nn #1 { 1 }
    \int_do_until:nn { #1 > #3 }
      {
        \@@_ulined_center_box:nn { #4 }
          { \clist_item:Nn #2 { #1 } } \\
        \int_incr:N #1
      }
  }
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\@@_put_inempty_seg:nnn}
% 将固定长度的非空字符串插入 |clist|。
% \begin{arguments}
%   \item 原始字符串
%   \item 起始位置
%   \item 长度
% \end{arguments}
%    \begin{macrocode}
\cs_new_protected:Npn \@@_put_inempty_seg:nnn #1#2#3
  {
    \tl_set:Nx \l_@@_tmpa_tl
      { \tl_range:Nnn { #1 } { #2 } { #2 + #3 - 1 } }
    \tl_if_empty:NF \l_@@_tmpa_tl
      { \clist_put_right:NV \l_@@_tmp_clist { \l_@@_tmpa_tl } }
  }
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\@@_uline:n}
% 指定宽度的下划线。
% \begin{arguments}
%   \item 宽度,|dim| 型变量
% \end{arguments}
%    \begin{macrocode}
\cs_new_protected:Npn \@@_uline:n #1
  {
    \mode_leave_vertical:
    \rule [ -0.55 ex ] { #1 } { 0.4 pt }
    \skip_horizontal:n { -#1 }
  }
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\@@_uuline:n}
% 指定宽度的双层下划线。
% \begin{arguments}
%   \item 宽度,|dim| 型变量
% \end{arguments}
Yu Xiong's avatar
Yu Xiong committed
%    \begin{macrocode}
\cs_new_protected:Npn \@@_uuline:n #1
  {
    \mode_leave_vertical:
    \rule [ -0.5 ex ] { #1 } { 0.4 pt }
    \skip_horizontal:n { -#1 }
    \rule [ -0.6 ex ] { #1 } { 0.4 pt }
    \skip_horizontal:n { -#1 }
  }
Yu Xiong's avatar
Yu Xiong committed
%    \end{macrocode}
% \end{macro}
Yu Xiong's avatar
Yu Xiong committed
%
% \begin{macro}{\@@_get_text_width:Nn,\@@_get_text_width:NV}
% 获取文本宽度。
% \begin{arguments}
%   \item 存储宽度的 |dim| 型变量
%   \item 文本
% \end{arguments}
% 将内容放入 \tn{hbox} 后读取其宽度,存入 |dim| 型变量。
Yu Xiong's avatar
Yu Xiong committed
%    \begin{macrocode}
\cs_new:Npn \@@_get_text_width:Nn #1#2
  {
Yu Xiong's avatar
Yu Xiong committed
    \hbox_set:Nn \l_@@_tmp_box {#2}
    \dim_set:Nn #1 { \box_wd:N \l_@@_tmp_box }
  }
\cs_generate_variant:Nn \@@_get_text_width:Nn { NV }
Yu Xiong's avatar
Yu Xiong committed
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_full_uline:Nn,\@@_full_uline:NV}
% 横跨整页的下划线。
% \begin{arguments}
%   \item 宽度,|dim| 型变量
%   \item 文本
% \end{arguments}
% 先使用 \cs{@@_get_text_width:Nn} 获取文本内容宽度,该宽度存储在调用的 |dim| 型变量中。随后输出文本内容。
%    \begin{macrocode}
\cs_new_protected:Npn \@@_full_uline:Nn #1#2
  {
    \@@_get_text_width:Nn #1 { #2 }
    \dim_set:Nn #1 { \textwidth - #1 } #2
  }
\cs_generate_variant:Nn \@@_full_uline:Nn { NV }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_uline_entry:Nnnn}
% 生成占整页宽度的下划线条目。
% \begin{arguments}
%   \item 宽度,|dim| 型变量
%   \item 文本
%   \item 文本
%   \item 分隔符
% \end{arguments}
%    \begin{macrocode}
\cs_new_protected:Npn \@@_uline_entry:Nnnn #1#2#3#4
  {
    \@@_full_uline:NV #1 { \@@_name:n { #2 } #4 }
    \@@_ulined_center_box:nn { #1 } { \@@_info:n { #3 } }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_uline_bientry:Nnnn}
% 生成占半页宽度的下划线条目。
% \begin{arguments}
%   \item 宽度,|dim| 型变量
%   \item 文本
%   \item 文本
%   \item 分隔符
% \end{arguments}
%    \begin{macrocode}
\cs_new_protected:Npn \@@_uline_bientry:Nnnn #1#2#3#4
  {
    \@@_full_uline:NV #1 { \@@_name:n { #2 } #4 }
    \dim_sub:Nn #1 { \textwidth / 2 }
    \@@_ulined_center_box:nn { #1 } { \@@_info:n { #3 } }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_date:www,\@@_date_en:www}
% 将形如 |yyyy-mm-dd| 的 ISO 日期格式字符串转化为日期表示。该格式符合国际标准 ISO 8601 以及国内标准 GB/T 7408--2005《数据元和交换格式 信息交换 日期和时间表示法》。
% \begin{arguments}
%   \item 年份
%   \item 月份
%   \item 日期
% \end{arguments}
% 中文日期表示通过封装 \pkg{zhnumber} 的内部函数实现;英文日期表示通过用于研究生英文封面。其中,变量类型 |w| 表明参数符合特定语法格式。
%    \begin{macrocode}
\cs_new:Npn \@@_date:www #1-#2-#3 \q_stop
  { \__zhnum_date_aux:nnn { #1 } { #2 } { #3 } }
\cs_new:Npn \@@_date_en:www #1-#2-#3 \q_stop
  { \clist_item:Nn \c_@@_month_en_clist { #2 } ~#3 , ~#1  }
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{封面相关}
% \changes{v0.16}{2022/03/10}{将封面和摘要内部函数定义移动到前部。}
%
% 定义关于标题的报错信息。
%    \begin{macrocode}
\msg_new:nnn { njuthesis } { missing-title }
  {
    The~ title~ should~ not~ be~ left~ blank.\\
    Please~ check~ whether~ you~ have~ fill~ in~
    both~ Chinese~ and~ English~ titles.
  }
%    \end{macrocode}
%
% \begin{macro}{\@@_uline_title:}
% \changes{v0.17}{2022/04/09}{优化封面标题的断行方式。}
% 多行带下划线标题。使用 \hologo{TeX} 原生断行算法实现。
%    \begin{macrocode}
\cs_new_protected:Npn \@@_uline_title:
    \setbox0 = \vbox{
        \leftskip=0.5em plus 1 fill
        \rightskip=\leftskip \parskip=1cm
        \parindent=\z@ \g_@@_info_title_tl \par
        \global\setbox2=\hbox{}
        \loop
          \setbox1=\lastbox \unskip\unpenalty
        \unless\ifvoid1
          \global\setbox2=\hbox{\@@_uline_box:\penalty0\unhbox2}
        \repeat
      { \noindent \unhbox2 \par }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_cover_entry_title:nnn}
% 生成普通封面页的标题条目,包括标签和标题本身。
% \begin{arguments}
%   \item 内容格式
%   \item 名称盒子宽度,|dim| 型变量
%   \item 内容盒子宽度,|dim| 型变量
% \end{arguments}
%    \begin{macrocode}
\cs_new_protected:Npn \@@_cover_entry_title:nnn #1#2#3
    \tl_if_empty:NT \g_@@_info_title_tl
      { \msg_error:nn { njuthesis } { missing-title } }
    \@@_spread_box:nnV { #2 } { \kaishu } \g_@@_name_title_tl
    \mode_leave_vertical: \@@_hskip:
%    \end{macrocode}
% 这里需要存储 \tn{baselineskip} 的值,以使 \tn{parbox} 后行距正确。
% \footnote{\url{https://tex.stackexchange.com/questions/34971/how-to-keep-a-constant-baselineskip-when-using-minipages-or-parboxes}}
%    \begin{macrocode}
    \parbox [ t ] { #3 }
      {
        \dim_set_eq:NN \baselineskip \g_@@_coverlineskip_dim
        #1 \@@_uline_title:
        \dim_set_eq:NN \l_@@_tmpa_dim \prevdepth
      }
    \par \prevdepth \l_@@_tmpa_dim
  }
%    \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 } }
  }
%    \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 } }
    \@@_spread_box:nnx { #3 } { \kaishu } { \@@_name:n { #2 } }
    \@@_hskip:
    \@@_ulined_center_box:nn { #4 }       { \@@_info:n { #2 } }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_cover_entry_supv:nnn}
% 生成两项导师信息条目,仅用于本科生封面。
% \begin{arguments}
%   \item 条目名称
%   \item 长内容盒子宽度,|dim| 型变量
%   \item 短内容盒子宽度,|dim| 型变量
% \end{arguments}
%    \begin{macrocode}
\cs_new_protected:Npn \@@_cover_entry_supv:nnn #1#2#3
  {
    \@@_spread_box:nnx { #2 } { \kaishu } { \@@_name:n { #1 } }
    \@@_hskip:
    \@@_ulined_center_box:nn { #3 }
      { \clist_item:cn { g_@@_info_ #1 _clist } { 1 } }
    \@@_spread_box:nnV { #2 } { \kaishu } \g_@@_name_supv_ttl_tl
    \@@_hskip:
    \@@_ulined_center_box:nn { #3 }
      { \clist_item:cn { g_@@_info_ #1 _clist } { 2 } }
  }
%    \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_@@_tmpa_dim {#1}
    \@@_uuline:n { \l_@@_tmpa_dim } #1
  }
\cs_generate_variant:Nn \@@_abs_title:n { V }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_uline_box:}
% 用于摘要标题的下划线盒子。
%    \begin{macrocode}
\cs_new_protected:Npn \@@_uline_box:
  { \vtop{\box1\kern-\prevdepth\kern0.5ex\hrule} }
%    \end{macrocode}
% \end{macro}
%
% 定义关于标题的报错信息。
%    \begin{macrocode}
\msg_new:nnn { njuthesis } { abs-title-too-long }
  {
    Your~ title~ is~ too~ long~ to~ fit~ in~ two~ lines.\\
    I~ have~ drawn~ additional~ lines~ to~ contain~ it,~
    which~ will~ probably~ make~ your~ abstract~ page~
    look~ slightly~ different~ from~ the~ standard.\\
    You~ can~ use~ the~ "style/abstract-title"~ key~
    to~ disable~ this~ message.
  }
%    \end{macrocode}
%
% \begin{macro}{\@@_uline_list:nnn,\@@_uline_list:xnn}
% \changes{v0.16}{2022/03/25}{使用原生断行算法处理摘要页标题。}
% 用于研究生摘要页面的多行标题。
% \begin{arguments}
%   \item 标签名
%   \item 内容
%   \item 左边距
% \end{arguments}
% 这里使用了 Primitive \TeX{} 语法以利用原生的断行算法\footnote{\url{https://tex.stackexchange.com/questions/637861/underline-list-item-to-page-width}}。
% 对其语法的简要介绍可以参考 \href{http://petr.olsak.net/ftp/olsak/optex/tex-nutshell.pdf}{\file{tex-nutshell.pdf}}。
%    \begin{macrocode}
\cs_new_protected:Npn \@@_uline_list:nnn #1#2#3
  {
    \hbox_set:Nn \l_@@_tmp_box {#1}
    \setbox0 = \vbox{\hangindent=\wd\l_@@_tmp_box \hangafter=-1
        \leftskip=#3 \rightskip=\leftskip \parindent=\z@ #2\par
        \global\setbox2=\hbox{}
        \int_gzero:N \l_@@_tmp_int
        \loop
          \setbox1=\lastbox \unskip\unpenalty
        \unless\ifvoid1
          \global\setbox2=\hbox{\@@_uline_box:\penalty0\unhbox2}
          \int_gincr:N \l_@@_tmp_int
        \repeat
      }
      {
        \noindent\copy\l_@@_tmp_box\unhbox2
%    \end{macrocode}
% 在使用自然断行算法后,研究生的摘要标题可选择 \opt{strict}
% 或者 \opt{natural} 模式。前者会为少于两行的标题补齐下划线,
% 并对多于三行的标题生成警告信息。这里通过行数处理边界条件,
% 包括标题未填写、标题只有一行,以及标题过长的情况。
%    \begin{macrocode}
        \bool_if:NT \g_@@_strict_abs_title_bool
          {
            \int_case:nnF { \l_@@_tmp_int }
              {
                { 0 } { \msg_error:nn { njuthesis } { missing-title } }
                { 1 } { \@@_uline:n { \textwidth } }
                { 2 } { \prg_do_nothing: }
              }
              { \msg_warning:nn { njuthesis } { abs-title-too-long } }
            \par
          }
      }
  }
\cs_generate_variant:Nn \@@_uline_list:nnn { xnn }
%    \end{macrocode}
% \end{macro}
%
% \subsection{页面对象}
% \changes{v0.15}{2022/01/24}{使用 \pkg{xtemplate} 重构封面。}
%
% 本模板使用 \pkg{xtemplate} 提供的面向对象方法简化封面和摘要的绘制过程。
%
Yu Xiong's avatar
Yu Xiong committed
% 以下分别从页面元素(element)和页面整体(page)的层次进行了抽象。
% 当我们把页面部件考虑为一个对象时,它天然地只具备有限数量的属性:
% 内容、格式、边距、对齐方式等。而具体的页面是这些对象的实例的集合,
% 附加边距、行距等属性,创建页面只需传入一个列表调用各个 Instance
% 即可。通过 \pkg{xtemplate} 提供的功能,我们可以根据这些属性创建模板
% (template),进而能大量构建具有\emph{相似行为}的实例(instance)。
% 这种做法能充分分离内容和样式,极大优化代码的可读性。
%
% 声明对象类型。此类对象不需要参数。
%    \begin{macrocode}
\DeclareObjectType { nju } { \c_zero_int }
%    \end{macrocode}
%
% 定义元素模板。
%    \begin{macrocode}
%<@@=njuelem>
%    \end{macrocode}
%
% 声明页面元素模板接口。
Yu Xiong's avatar
Yu Xiong committed
% 元素是一个页面的基本组成单位,包括文段、图片等等。
% 一个抽象的元素应当具备以下属性:
% \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 =