Newer
Older
% \newblock version 1.8d,
% \newblock (2020-03-24)
% \urlprefix\url{https://www.ctan.org/pkg/listings}
% \urlprefix\CTANurl[文档:]{macros/latex/contrib/listings/listings.pdf}
%
% \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}
% \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{以下模版现已停止更新。}
%
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
% \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}
%
%
% 本模板使用 \hologo{LaTeX3} 语法编写,依赖 \pkg{expl3} 环境,
% 并需调用 \pkg{l3packages} 中的相关宏包。
%
% 以下代码中有一些形如 \agrd{*class} 的标记,
% 这是 \pkg{DocStrip} 中的“guard”,用来选择性地提取文件。
% “|*|”和“|/|”分别表示该部分的开始和结束。不含
% “|*|”和“|/|”的 guard 出现在行号右侧,它们用来确定
% 单独一行代码的归属。这些 guard 的颜色深浅不一,用以明确嵌套关系。
%
% \changes{v0.12}{2021/12/03}{放宽对于 \pkg{l3packages} 的版本要求。}
Please~ update~ an~ up-to-date~ version~ of~ the~
bundles~ "l3kernel"~ and~ "l3packages"~ using~
your~ TeX~ package~ manager~ or~ from~ CTAN.
{ } { \msg_error:nnn { njuthesis } { l3-too-old } {#1} }
}
% \end{macrocode}
%
% \begin{macrocode}
\msg_new:nnn { njuthesis } { unsupported-engine }
{
\bool_lazy_or:nnF
{ \sys_if_engine_xetex_p: }
{ \sys_if_engine_luatex_p: }
{ \msg_fatal:nnx { njuthesis } { unsupported-engine } { \c_sys_engine_str } }
% \begin{variable}{\g_@@_info_degree_int,
% \l_@@_info_diploma_int,\g_@@_info_type_int}
% \end{macrocode}
% \end{variable}
%
% \begin{variable}{\l_@@_info_degree_tl,\l_@@_info_diploma_tl,
% \l_@@_info_type_tl,\l_@@_info_type_en_tl}
% 用于存储学位名称的变量。
% \begin{macrocode}
\tl_new:N \l_@@_info_degree_tl
\tl_new:N \l_@@_info_diploma_tl
% \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}{\l_@@_info_supv_full_tl,\l_@@_info_supv_full_en_tl}
% 用于存储导师姓名加职称的变量。
\tl_new:N \l_@@_info_supv_full_tl
\tl_new:N \l_@@_info_supv_full_en_tl
% \begin{variable}{\g_@@_latin_font_tl,\g_@@_cjk_font_tl}
\tl_new:N \g_@@_latin_font_tl
\tl_new:N \g_@@_cjk_font_tl
% \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}{\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
\tl_new:N \l_@@_info_sm_date_en_tl
\tl_new:N \l_@@_info_df_date_tl
% \end{macrocode}
% \end{variable}
%
% \begin{variable}{\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}{\c_@@_name_type_clist,\c_@@_name_type_en_clist,
% \c_@@_name_degree_clist,\c_@@_name_degree_en_clist}
% 论文类型与学位类型。
% \begin{macrocode}
\clist_const:Nn \c_@@_name_type_clist
{ 毕业论文, 毕业设计 }
\clist_const:Nn \c_@@_name_type_en_clist
{ THESIS, DESIGN }
\clist_const:Nn \c_@@_name_degree_clist
{ 学士, 硕士, 硕士专业, 博士 }
\clist_const:Nn \c_@@_name_degree_en_clist
{ 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}
%
% \begin{macro}{\@@_quad:,\@@_qquad:}
% 等价于 \LaTeXe{} 中的 \tn{quad} 和 \tn{qquad}。
\cs_new:Nn \@@_quad: { \skip_horizontal:n { 1 em } }
\cs_new:Nn \@@_qquad: { \skip_horizontal:n { 2 em } }
% \begin{macro}{\@@_vskip:,\@@_hskip:}
% 生成一个较小的 skip。
\cs_new:Nn \@@_vskip: { \skip_vertical:n { 1 ex } }
\cs_new:Nn \@@_hskip: { \skip_horizontal:n { 0.3 em } }
% 类似于 \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
\cs_new_protected:Npn \@@_define_name:nnn #1#2#3
{
\tl_const:cn { c_@@_name_ #1 _tl } { #2 }
\tl_const:cn { c_@@_name_ #1 _en_tl } { #3 }
}
% \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}
%
\cs_new:Npn \@@_name:n #1 { \tl_use:c { c_@@_name_ #1 _tl } }
\cs_new:Npn \@@_info:n #1 { \tl_use:c { l_@@_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
% \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
\cs_generate_variant:Nn \@@_spread_box:nnn { nnV }
\cs_generate_variant:Nn \@@_spread_box:nnn { nnx }
% \begin{arguments}
% \item 用于循环的 |int| 型变量
% \item 内容,|clist| 型变量
% \item 行数
% \item 宽度,|dim| 型变量
% \end{arguments}
{ \clist_item:Nn #2 { #1 } } \\
\int_incr:N #1
}
% \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_if_empty:NF \l_@@_tmp_tl
{ \clist_put_right:NV \l_@@_tmp_clist { \l_@@_tmp_tl } }
% \begin{macro}{\@@_uline:n}
% 指定宽度的下划线。
% \begin{arguments}
% \item 宽度,|dim| 型变量
% \end{arguments}
% \begin{macrocode}
\cs_new_protected:Npn \@@_uline:n #1
{
\mode_leave_vertical:
\skip_horizontal:n { -#1 }
}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\@@_uuline:n}
% 指定宽度的双层下划线。
% \begin{arguments}
% \item 宽度,|dim| 型变量
% \end{arguments}
\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 }
}
% \begin{macro}{\@@_get_text_width:Nn,\@@_get_text_width:NV}
% 获取文本宽度。
% \begin{arguments}
% \item 存储宽度的 |dim| 型变量
% \item 文本
% \end{arguments}
% 将内容放入 \tn{hbox} 后读取其宽度,存入 |dim| 型变量。
\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 }
% \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 }
}
\cs_generate_variant:Nn \@@_full_uline:Nn { NV }
% \end{macrocode}
% \end{macro}
%
% 生成占整页宽度的下划线条目。
% \begin{arguments}
% \item 宽度,|dim| 型变量
% \item 文本
% \item 文本
% \item 分隔符
% \end{arguments}
% \begin{macrocode}
{
\@@_full_uline:NV #1 { \@@_name:n { #2 } #4 }
\@@_ulined_center_box:nn { #1 } { \@@_info:n { #3 } }
}
% \end{macrocode}
% \end{macro}
%
% 生成占半页宽度的下划线条目。
% \begin{arguments}
% \item 宽度,|dim| 型变量
% \item 文本
% \item 文本
% \item 分隔符
% \end{arguments}
% \begin{macrocode}
{
\@@_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| 表明参数符合特定语法格式。
\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}
%
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
% \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
{
\tl_if_empty:NT \l_@@_info_title_tl
{ \msg_error:nn { njuthesis } { missing-title } }
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
\@@_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 } }
}
\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}
%
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
% \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}
%
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
% \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}{进行了效率优化。}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{type}
nlcover .bool_set:N = \g_@@_nlcover_bool,
nlcover .initial:n = false,
% \footnote{原创性声明的英文翻译为 Declaration of Originality,为了使选项表义更清晰同时缩减名称长度,将其修改为“声明页”这一名称。}
decl-page .bool_set:N = \g_@@_orig_decl_bool,
decl-page .initial:n = false,
% \begin{macro}{draft}
% \changes{v0.13}{2021/12/15}{新增草稿模式选项。}
% 是否开启草稿模式(默认关闭)。
% \begin{macrocode}
draft .bool_gset:N = \g_@@_draft_bool,
draft .initial:n = false,
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{oneside,twoside}
% \changes{v0.14}{2022/01/14}{新增单双面模式选项。}
% 单双面模式(默认为双面)。
% \begin{macrocode}
oneside .value_forbidden:n = true,
twoside .value_forbidden:n = true,
{ gyre, mac, win, none }
{ \tl_set_eq:NN \g_@@_latin_font_tl \l_keys_choice_tl },
{ fandol, founder, mac, noto, source, win, none }
{ \tl_set_eq:NN \g_@@_cjk_font_tl \l_keys_choice_tl },