% \iffalse meta-comment
%
% File: ctex-kernel.dtx
% -----------------------------------------------------------------------
% Copyright (C) 2003--2026
% CTEX.ORG and any individual authors listed elsewhere in this file.
% -----------------------------------------------------------------------
% This work may be distributed and/or modified under the conditions *
% of the LaTeX Project Public License (LPPL), 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.3c or later is part of all distributions of LaTeX *
% version 2008 or later. *
% *
% This work has the LPPL maintenance status `maintained'. *
% -----------------------------------------------------------------------
% This work consists of the files ctex.dtx, *
% ctex-kernel.dtx, *
% ctex-engine.dtx, *
% ctex-scheme.dtx, *
% ctex-auxpkg.dtx, *
% ctex-fontset.dtx, *
% ctexpunct.spa, *
% ctxdoc.cls, *
% ctxdocstrip.tex, *
% ctex-zhconv.lua, *
% ctex-zhconv-index.lua, *
% ctex-zhconv-make.lua, *
% the derived files ctex.ins, *
% ctex.sty, *
% ctexsize.sty, *
% ctexheading.sty, *
% ctexart.cls, *
% ctexbook.cls, *
% ctexrep.cls, *
% ctexbeamer.cls, *
% ctexcap.sty, *
% ctexhook.sty, *
% ctexpatch.sty, *
% ctex-c5size.clo, *
% ctex-cs4size.clo, *
% ctex-heading-article.def, *
% ctex-heading-book.def, *
% ctex-heading-report.def, *
% ctex-heading-beamer.def, *
% ctexbackend.cfg, *
% ctex-engine-pdftex.def, *
% ctex-engine-xetex.def, *
% ctex-engine-luatex.def, *
% ctex-engine-aptex.def, *
% ctex-engine-uptex.def, *
% ctex-name-utf8.cfg, *
% ctex-name-gbk.cfg, *
% ctex.cfg, *
% ctexopts.cfg, *
% ctex-scheme-plain.def, *
% ctex-scheme-plain-article.def, *
% ctex-scheme-plain-book.def, *
% ctex-scheme-plain-report.def, *
% ctex-scheme-plain-beamer.def, *
% ctex-scheme-chinese.def, *
% ctex-scheme-chinese-article.def, *
% ctex-scheme-chinese-book.def, *
% ctex-scheme-chinese-report.def, *
% ctex-scheme-chinese-beamer.def, *
% ctex-fontset-adobe.def, *
% ctex-fontset-fandol.def, *
% ctex-fontset-founder.def, *
% ctex-fontset-hanyi.def, *
% ctex-fontset-mac.def, *
% ctex-fontset-macnew.def, *
% ctex-fontset-macold.def, *
% ctex-fontset-ubuntu.def, *
% ctex-fontset-windows.def, *
% c19rm.fd, *
% c19sf.fd, *
% c19tt.fd, *
% c70rm.fd, *
% c70sf.fd, *
% c70tt.fd, *
% jy2zhrm.fd, *
% jy2zhsf.fd, *
% jy2zhtt.fd, *
% jt2zhrm.fd, *
% jt2zhsf.fd, *
% jt2zhtt.fd, *
% ctexspa.def, *
% translator-theorem-dictionary-ChineseUTF8.dict, *
% translator-theorem-dictionary-ChineseGBK.dict, *
% ctex-spa-make.tex, *
% ctex-spa-macro.tex, *
% ctex-zhmap-adobe.tex, *
% ctex-zhmap-fandol.tex, *
% ctex-zhmap-founder.tex, *
% ctex-zhmap-hanyi.tex, *
% ctex-zhmap-mac.tex, *
% ctex-zhmap-ubuntu.tex, *
% ctex-zhmap-windows.tex, *
% the documentation files ctex.pdf, *
% and README.md. *
% -----------------------------------------------------------------------
% *
% Any modification of this file should ensure that the copyright and *
% license information is placed in the derived files. *
% *
% -----------------------------------------------------------------------
%
%<*!driver>
%\NeedsTeXFormat{LaTeX2e}[2026/06/01]
%\input{ctexbackend.cfg}
%\RequirePackage{expl3}
%<+!driver>\GetIdInfo $Id: ctex-kernel.dtx 2.6.2 2026-07-06 20:43:36 +0800 dbfd7c43 Mingyu Hsia $
% {Chinese adapter in LaTeX (CTEX)}
%\ProvidesExplPackage{ctex}
% {Chinese font size definition (CTEX)}
%\ProvidesExplPackage{ctexsize}
% {Heading style modification (CTEX)}
%\ProvidesExplPackage{ctexheading}
% {Chinese adapter for class article (CTEX)}
%\ProvidesExplClass{ctexart}
% {Chinese adapter for class book (CTEX)}
%\ProvidesExplClass{ctexbook}
% {Chinese adapter for class report (CTEX)}
%\ProvidesExplClass{ctexrep}
% {Chinese adapter for class beamer (CTEX)}
%\ProvidesExplClass{ctexbeamer}
% {c5size option (CTEX)}
%\ProvidesExplFile{ctex-c5size.clo}
% {cs4size option (CTEX)}
%\ProvidesExplFile{ctex-cs4size.clo}
% {Heading modification for article (CTEX)}
%\ProvidesExplFile{ctex-heading-article.def}
% {Heading modification for book (CTEX)}
%\ProvidesExplFile{ctex-heading-book.def}
% {Heading modification for report (CTEX)}
%\ProvidesExplFile{ctex-heading-report.def}
% {Heading modification for beamer (CTEX)}
%\ProvidesExplFile{ctex-heading-beamer.def}
% {\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
%!driver>
%
% \fi
%
% \begin{implementation}
%
% \paragraph*{\fbox{\file{\jobname-kernel.dtx}}}
%
% \begin{macrocode}
%<@@=ctex>
% \end{macrocode}
%
% \changes{v2.6.2}{2026/07/02}{订正 \file{ctex-heading-*.def} 中
% \cs{ProvidesExplFile} 使用与实际文件名不匹配的 \file{ctex-*.def}。}
% \changes{v2.5.9}{2022/05/27}{设置消息模块的名字和类型。}
% \changes{v2.5.10}{2022/06/10}{更新一些内部函数。}
% \changes{v2.5.10}{2022/07/08}{不直接依赖 \pkg{xparse} 和 \pkg{l3keys2e}。}
%
% \begin{macrocode}
%<*class|style>
\cs_if_exist:NF \NewDocumentCommand
{ \RequirePackage { xparse } }
%\prop_gput:Nnn \g_msg_module_type_prop { ctex } { Class }
%\prop_gput:Nnn \g_msg_module_name_prop { ctex } { ctexart }
%\prop_gput:Nnn \g_msg_module_name_prop { ctex } { ctexbook }
%\prop_gput:Nnn \g_msg_module_name_prop { ctex } { ctexrep }
%\prop_gput:Nnn \g_msg_module_name_prop { ctex } { ctexbeamer }
%\prop_gput:Nnn \g_msg_module_name_prop { ctex } { ctexsize }
%\prop_gput:Nnn \g_msg_module_name_prop { ctex } { ctexheading }
%
% \end{macrocode}
%
% \begin{macrocode}
%<*class|ctex>
% \end{macrocode}
%
% \changes{v2.3}{2015/12/20}{与 \LaTeXiii{} (2015/12/20) 同步。}
% \changes{v2.4.10}{2017/07/19}{常数 \cs{c_minus_one} 已过时。}
% \changes{v2.4.10}{2017/07/22}{使用 \texttt{lazy} 函数对 Boolean 表达式
% 进行最小化运算(\LaTeXiii{} 2017/07/19)。}
% \changes{v2.6.0}{2024/04/20}{提升 \LaTeXiii{} 版本至 2022/10/09。}
% \changes{v2.6.0}{2026/05/03}{提升 \LaTeXiii{} 最低版本要求至 2025/10/09。}
%
% 检查 \pkg{expl3} 的版本。
% \begin{macrocode}
\msg_new:nnnn { ctex } { l3-too-old }
{ Support~package~`#1'~too~old. }
{
Please~update~an~up-to-date~version~of~the~bundles\\\\
`l3kernel'~and~`l3packages'\\\\
using~your~TeX~package~manager~or~from~CTAN.
}
\@ifpackagelater { expl3 } { 2025/10/09 } { }
{ \msg_error:nnn { ctex } { l3-too-old } { expl3 } }
% \end{macrocode}
%
% \begin{variable}{\c_@@_engine_str,\c_@@_engine_file_str}
% 引擎检查。目前 \LaTeXiii{} 将 \ApTeX{} 识别为 \upTeX。
% \begin{macrocode}
\str_const:Ne \c_@@_engine_str
{ \cs_if_exist:NTF \ngostype { aptex } { \c_sys_engine_str } }
\msg_new:nnnn { ctex } { engine-not-supported }
{ Engine~`#1'~is~not~yet~supported,~ctex~will~abort! }
{ You~can~switch~to~xelatex,~lualatex,~pdflatex,~uplatex,~or~aplatex. }
\file_if_exist:nTF { ctex-engine- \c_@@_engine_str .def }
{
\str_const:Ne \c_@@_engine_file_str
{ ctex-engine- \c_@@_engine_str .def }
}
{ \msg_critical:nne { ctex } { engine-not-supported } { \c_@@_engine_str } }
% \end{macrocode}
% \end{variable}
%
% \begin{macrocode}
%
% \end{macrocode}
%
% \changes{v2.5}{2020/04/19}
% {处理 \cs{ctex_file_input:n} 在 \pkg{ctexsize} 中未定义的错误。}
% \changes{v2.5}{2020/04/21}{在 \pkg{ctexsize} 也载入 \pkg{fix-cm}。}
%
% \begin{macrocode}
%<*class|ctex|ctexheading|ctexsize>
% \end{macrocode}
%
% \pkg{ctexsize} 也要载入 \pkg{fix-cm} 包解决传统 cm 字体字号缺失的问题。
% \begin{macrocode}
%\RequirePackage { ctexhook , ctexpatch }
%\RequirePackage { fix-cm }
% \end{macrocode}
%
% 宏包载入检查。
% \begin{macrocode}
%<*class|ctex>
%<*class>
\ctex_disable_package:n { ctex }
\ctex_disable_package:n { ctexcap }
%
\ctex_disable_package:n { ctexsize }
\ctex_disable_package:n { ctexheading }
%
% \end{macrocode}
%
% \changes{v2.5.7}{2021/06/04}{兼容 \LaTeX \ 2021/06/01 的字体钩子。}
%
% \begin{variable}{\c_@@_everysel_loaded_bool}
% \LaTeX \ 2021-06-01 以后的版本内建了 \pkg{everysel} 包的功能。
% \begin{macrocode}
%<*!ctexsize>
%<*!ctexheading>
\ctex_if_format_at_least:nTF { 2021/06/01 }
{ \bool_const:Nn \c_@@_everysel_loaded_bool { \c_false_bool } }
{
\RequirePackage { everysel }
\bool_const:Nn \c_@@_everysel_loaded_bool { \c_true_bool }
}
%!ctexheading>
% \end{macrocode}
% \end{variable}
%
% \subsection{内部函数与变量}
%
% \begin{variable}{\l_@@_tmp_tl,\l_@@_tmp_int,\l_@@_tmp_box,\l_@@_tmp_dim}
% 临时变量。
% \begin{macrocode}
\tl_clear_new:N \l_@@_tmp_tl
\int_new:N \l_@@_tmp_int
\box_new:N \l_@@_tmp_box
%\dim_new:N \l_@@_tmp_dim
% \end{macrocode}
% \end{variable}
%
% \begin{macro}[int]{\ctex_define_option:n,
% \ctex_define:n,\ctex_set:n,\ctex_set:nn}
% 在宏包内部使用的键值选项定义、设置命令。
% \begin{macrocode}
%!ctexsize>
\cs_new_protected:Npn \ctex_define_option:n
{ \keys_define:nn { ctex / option } }
%<*!ctexsize>
\cs_new_protected:Npn \ctex_define:n
{ \keys_define:nn { ctex } }
\cs_new_protected:Npn \ctex_set:n
{ \keys_set:nn { ctex } }
\cs_new_protected:Npn \ctex_set:nn #1
{ \keys_set:nn { ctex / #1 } }
% \end{macrocode}
% \end{macro}
%
% \changes{v2.5.3}{2020/06/06}{正确关闭和恢复 \LaTeXiii 语法环境。}
% \changes{v2.5.4}{2020/08/02}{应用 \pkg{l3cctab}。}
% \changes{v2.5.5}{2020/10/17}{放弃应用 \pkg{l3cctab}。}
%
% \begin{macro}[int]{\ctex_scheme_input:n}
% 输入 \opt{scheme} 文件。先查找当前文档类下的 \meta{scheme},找不到再查找一般的文件。
% \begin{macrocode}
\cs_new_protected:Npn \ctex_scheme_input:n #1
{
\ctex_push_file:
\tl_if_exist:NTF \c_@@_class_tl
{
\file_if_exist_input:nF { ctex-scheme- #1 - \c_@@_class_tl .def }
{ \file_input:n { ctex-scheme- #1 .def } }
}
{ \file_input:n { ctex-scheme- #1 .def } }
\ctex_pop_file:
}
\cs_generate_variant:Nn \ctex_scheme_input:n { o }
% \end{macrocode}
% \end{macro}
%
% \begin{variable}{\g_@@_section_depth_int}
% 若大于 |3|,则 \tn{paragraph} 和 \tn{subparagraph} 标题单独占一行;若为 |3|,则
% \tn{paragraph} 单独占一行。
% \begin{macrocode}
%<*!beamer>
\int_new:N \g_@@_section_depth_int
\int_gset:Nn \g_@@_section_depth_int { 2 }
%!beamer>
% \end{macrocode}
% \end{variable}
%
% \begin{macrocode}
%!ctexsize>
%
%<*class|ctex>
% \end{macrocode}
%
% 对旧版本的宏包给出错误信息。
% \begin{macrocode}
\msg_new:nnnn { ctex } { package-too-old }
{ Support~package~`#1'~too~old. }
{
Please~update~an~up-to-date~version~of~the~package~`#1'\\
using~your~TeX~package~manager~or~from~CTAN.
}
% \end{macrocode}
%
% \changes{v2.1}{2015/05/25}{不依赖 \pkg{ifpdf} 宏包。}
%
% \begin{macro}[int]{\ifctexpdf}
% 在 \pkg{zhmetrics} 映射文件中使用。
% \begin{macrocode}
\sys_if_output_pdf:TF
{ \cs_new_eq:NN \ifctexpdf \if_true: }
{ \cs_new_eq:NN \ifctexpdf \if_false: }
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\ctex_if_preamble:TF}
% 测试是否在 \LaTeXe{} 的导言区。在宏包内部初始为真,文档最开始位置再设置为假。
% 注意,钩子 \cs{ctex_after_end_preamble:n} 在 \tn{AtBeginDocument} 之后执行,
% 可以与 \tn{@onlypreamble} 的行为一致。
% \begin{macrocode}
\cs_new_eq:NN \ctex_if_preamble:TF \use_i:nn
\ctex_after_end_preamble:n { \cs_set_eq:NN \ctex_if_preamble:TF \use_ii:nn }
% \end{macrocode}
% \end{macro}
%
% \changes{v2.3}{2015/09/17}{代码实现避免使用 \tn{lowercase} 技巧(Joseph Wright)。}
%
% \changes{v2.4.16}{2019/05/11}{允许设置 \texttt{autoindent} 为 $0$。}
%
% \begin{macro}[int]{\ctex_set_default_ccwd:Nn}
% 若参数 |#2| 带长度单位,则设置它为 |tl| 变量 |#1| 的值,否则以 \tn{ccwd} 为单位。
% \begin{macrocode}
\cs_new_protected:Npn \ctex_set_default_ccwd:Nn #1#2
{ \tl_set:Ne #1 { \@@_default_ccwd_aux:n {#2} } }
\cs_new:Npn \@@_default_ccwd_aux:n #1
{
\exp_not:n {#1}
\exp_after:wN \@@_default_ccwd_aux:w
\dim_use:N \tex_dimexpr:D #1 pt \scan_stop: \q_stop
}
\exp_last_unbraced:NNNNo
\cs_new:Npn \@@_default_ccwd_aux:w #1 { \tl_to_str:n { pt } } #2 \q_stop
{ \tl_if_empty:nT {#2} { \ccwd } }
% \end{macrocode}
% \end{macro}
%
% \begin{variable}{\g_@@_encoding_tl}
% 所有引擎下默认编码均设为 UTF-8,初始值为空,\tn{ProcessKeysOptions} 再判断。
% \begin{macrocode}
\tl_new:N \g_@@_encoding_tl
% \end{macrocode}
% \end{variable}
%
% \begin{variable}{\g_@@_zhmCJK_bool}
% 是否使用 \pkg{zhmCJK} 宏包。
% \begin{macrocode}
\bool_new:N \g_@@_zhmCJK_bool
% \end{macrocode}
% \end{variable}
%
% \begin{variable}{\l_@@_autoindent_tl}
% 保存 \opt{autoindent} 选项的值,空值表示不自动调整首行缩进。
% \begin{macrocode}
\tl_new:N \l_@@_autoindent_tl
% \end{macrocode}
% \end{variable}
%
% \begin{macro}[int]{\ctex_if_autoindent_touched:F}
% 检查 \opt{autoindent} 选项是否被用户设置。
% \begin{macrocode}
\cs_new_eq:NN \ctex_if_autoindent_touched:F \use:n
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\ctex_zhmap_case:nnn}
% 参数 |#1| 是 \pkg{zhmCJK} 的内容,|#2| 是 \pkg{zhmetrics}。
% \begin{macrocode}
\cs_new_eq:NN \ctex_zhmap_case:nnn \use_ii:nnn
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\ctex_at_end:n}
% 区分 \tn{AtEndOfClass} 和 \tn{AtEndOfPackage},虽然它们的意思都是一样的。
% \begin{macrocode}
%\cs_new_protected:Npn \ctex_at_end:n { \AtEndOfClass }
%\cs_new_protected:Npn \ctex_at_end:n { \AtEndOfPackage }
% \end{macrocode}
% \end{macro}
%
% \begin{variable}{\ctex_load_std_class:n,\g_@@_std_options_clist}
% 保存传递给标准文档类的选项。
% 使用 \tn{PassOptionsToClass} 是为了预防可能存在的选项冲突,选项列表展开后再传递。
% \begin{macrocode}
%<*class>
\cs_new_protected:Npn \ctex_load_std_class:n #1
{
\tl_const:Nn \c_@@_class_tl {#1}
\exp_args:No \PassOptionsToClass
{ \g_@@_std_options_clist }
{#1}
\LoadClass {#1}
}
\clist_new:N \g_@@_std_options_clist
%
% \end{macrocode}
% \end{variable}
%
% 对无效选项给出警告。
% \changes{v2.6.0}{2026/05/02}{使用 \cs{l_keys_key_str} 和
% \cs{l_keys_choice_str} 替代已废弃的 \texttt{\_tl} 版本(\#806)。}
% \begin{macrocode}
\msg_new:nnn { ctex } { invalid-option }
{ Option~`\l_keys_key_str'~is~invalid~in~current~mode. }
\msg_new:nnn { ctex } { invalid-value }
{ Value~`#1'~is~invalid~for~the~key~`\l_keys_key_str'. }
\msg_new:nnn { ctex } { CJKecglue-unsupported }
{ `experiment/CJKecglue'~is~not~supported~by~the~current~engine. }
% \end{macrocode}
%
% \begin{macro}[int]{\ctex_deprecated_option:nn,
% \ctex_set_deprecated_option:n,\ctex_deprecated_command:Nn}
% 对过时选项或命令给出警告。
% \begin{macrocode}
\cs_new_protected:Npn \ctex_deprecated_option:n
{ \msg_warning:nnn { ctex } { deprecated-option } }
\cs_new_protected:Npn \ctex_set_deprecated_option:n #1
{
\ctex_deprecated_option:n { Option~`#1'~is~set. }
\ctex_set:nn { option } {#1}
}
\cs_new_protected:Npn \ctex_deprecated_command:Nn #1#2
{
\msg_warning:nnee { ctex } { deprecated-command }
{ \token_to_str:N #1 } { \exp_not:n {#2} }
}
\msg_new:nnn { ctex } { deprecated-option }
{ Option~`\l_keys_key_str'~is~deprecated.\\ #1 }
\msg_new:nnn { ctex } { deprecated-command }
{ Command~`#1'~is~deprecated.\\ #2 }
% \end{macrocode}
% \end{macro}
%
% \begin{macrocode}
%
% \end{macrocode}
%
% \begin{variable}{\g_@@_font_size_int}
% |0| 表示修改默认字体大小为五号,|1| 为小四号,大于 1 则不作修改。初始值 |-1|
% 表示 \opt{zihao} 选项未初始化,会在将来根据文档类决定初值。
% \begin{macrocode}
%<*class|ctex|ctexsize>
\int_new:N \g_@@_font_size_int
\int_gset:Nn \g_@@_font_size_int { -1 }
%
% \end{macrocode}
% \end{variable}
%
% \subsection{宏包选项}
%
% \changes{v2.3}{2015/09/25}
% {\texttt{.value_required:} 和 \texttt{.value_forbidden:} 已过时。}
%
% \begin{macrocode}
%<*class|style>
\ctex_define_option:n
{
%
% \end{macrocode}
%
% \changes{v2.6.0}{2026/05/04}{新增实验性
% \opt{experiment/font-size-system} 选项(\#543)。}
% \changes{v2.6.0}{2026/05/04}{将 \opt{experiment/font-size-system}
% 的 \opt{traditional} 选项更名为 \opt{letterpress}(\#813)。}
% \changes{v2.6.0}{2026/06/23}{文档:在标准字体命令、中文字号表附近提示
% \opt{experiment/font-size-system} 的影响;说明
% \opt{letterpress} 只是金属活字排印字号体系之一(\#871)。}
%
% \begin{macro}{experiment/font-size-system}
% 选择字号系统。预设有 |word| 和 |letterpress| 两种字号系统,用户也可以自定义。
% \begin{macrocode}
%<*class|ctex|ctexsize>
experiment / font-size-system .tl_gset:N = \g_@@_font_size_system_tl ,
experiment / font-size-system .initial:n = { word } ,
experiment / font-size-system .value_required:n = true ,
%
% \end{macrocode}
% \end{macro}
%
% \changes{v2.0}{2015/05/06}{新增 \opt{zihao} 选项。}
% \changes{v2.0}{2015/05/06}{\opt{c5size}, \opt{cs4size} 是过时选项。}
%
% \begin{macro}{zihao}
% \changes{v2.4.1}{2016/05/13}{不允许无参 \opt{zihao} 选项。}
% \begin{macrocode}
%<*class|ctex|ctexsize>
zihao .choice: ,
zihao .value_required:n = true ,
zihao / 5 .code:n = { \int_gset:Nn \g_@@_font_size_int { 0 } } ,
zihao / -4 .code:n = { \int_gset:Nn \g_@@_font_size_int { 1 } } ,
zihao / false .code:n = { \int_gset:Nn \g_@@_font_size_int { 2 } } ,
% }
%
%<*class|ctex>
c5size .code:n = { \ctex_set_deprecated_option:n { zihao = 5 } } ,
cs4size .code:n = { \ctex_set_deprecated_option:n { zihao = -4 } } ,
c5size .value_forbidden:n = true ,
cs4size .value_forbidden:n = true ,
% \end{macrocode}
% \end{macro}
%
% \changes{v2.0}{2014/04/23}{新增 \opt{linespread} 选项。}
%
% \begin{macro}{linespread}
% 行距初始值为标志 \texttt{nan},用于检查用户是否设置了 \opt{linespread} 选项。
% \begin{macrocode}
linespread .fp_set:N = \l_@@_line_spread_fp ,
linespread .initial:n = { \c_nan_fp } ,
linespread .value_required:n = true ,
% \end{macrocode}
% \end{macro}
%
% \changes{v2.0}{2014/03/13}{新增 \opt{autoindent} 选项。}
%
% \begin{macro}{autoindent}
% 自动调整段落的首行缩进功能。
% \begin{macrocode}
autoindent .choice: ,
autoindent .default:n = { true } ,
autoindent / true .code:n =
{
\tl_set:Nn \l_@@_autoindent_tl { 2 \ccwd }
\cs_set_eq:NN \ctex_if_autoindent_touched:F \use_none:n
} ,
autoindent / false .code:n =
{
\tl_clear:N \l_@@_autoindent_tl
\cs_set_eq:NN \ctex_if_autoindent_touched:F \use_none:n
} ,
autoindent / unknown .code:n =
{
\ctex_set_default_ccwd:Nn \l_@@_autoindent_tl {#1}
\cs_set_eq:NN \ctex_if_autoindent_touched:F \use_none:n
} ,
% \end{macrocode}
% \end{macro}
%
% \changes{v2.0}{2015/03/21}{\opt{indent}, \opt{noindent} 是过时选项。}
% \begin{macro}{indent}
% 仅为兼容性保留,已过时。
% \begin{macrocode}
indent .code:n =
{
\ctex_deprecated_option:n
{
The~functionality~has~been~removed.\\
It's~better~to~set~the~heading~styles~via~`afterindent'~option.
}
} ,
indent .value_forbidden:n = true ,
noindent .code:n =
{
\ctex_deprecated_option:n
{
The~functionality~has~been~removed.\\
It's~better~to~set~the~heading~styles~via~`afterindent'~option.
}
} ,
noindent .value_forbidden:n = true ,
% \end{macrocode}
% \end{macro}
%
% \changes{v2.5}{2019/11/10}{所有引擎下默认编码均设为 UTF-8。}
%
% \begin{macro}{GBK,UTF8}
% 文档编码,默认为 UTF-8。
% \begin{macrocode}
GBK .code:n =
{
\sys_if_engine_pdftex:TF
{ \tl_gset:Nn \g_@@_encoding_tl { GBK } }
{
\msg_warning:nn { ctex } { invalid-option }
\tl_gset:Nn \g_@@_encoding_tl { UTF8 }
}
} ,
UTF8 .code:n = { \tl_gset:Nn \g_@@_encoding_tl { UTF8 } } ,
GBK .value_forbidden:n = true ,
UTF8 .value_forbidden:n = true ,
% \end{macrocode}
% \end{macro}
%
% \changes{v2.0}{2014/03/08}{新增 \opt{fontset} 选项。}
% \changes{v2.0}{2015/03/21}{\opt{nofonts}, \opt{adobefonts}, \opt{winfonts}
% 是过时选项。}
%
% \begin{macro}{fontset}
% 初始值为空。若用户未指定,则根据操作系统载入对应字体配置,可以区分 Windows、
% macOS 和其他。
% \begin{macrocode}
fontset .tl_gset:N = \g_@@_fontset_tl ,
nofonts .code:n = { \ctex_set_deprecated_option:n { fontset = none } } ,
adobefonts .code:n = { \ctex_set_deprecated_option:n { fontset = adobe } } ,
winfonts .code:n = { \ctex_set_deprecated_option:n { fontset = windows } } ,
nofonts .value_forbidden:n = true ,
winfonts .value_forbidden:n = true ,
adobefonts .value_forbidden:n = true ,
% \end{macrocode}
% \end{macro}
%
% \changes{v2.0}{2014/03/08}{新增 \opt{zhmCJK} 支持选项。}
% \changes{v2.0}{2015/03/22}{\opt{nozhmap} 是过时选项。}
%
% \begin{macro}{zhmap}
% \begin{macrocode}
zhmap .choice: ,
zhmap .default:n = { true } ,
zhmap / zhmCJK .code:n =
{
\bool_gset_true:N \g_@@_zhmCJK_bool
\cs_gset_eq:NN \ctex_zhmap_case:nnn \use_i:nnn
} ,
zhmap / true .code:n =
{
\bool_gset_false:N \g_@@_zhmCJK_bool
\cs_gset_eq:NN \ctex_zhmap_case:nnn \use_ii:nnn
} ,
zhmap / false .code:n =
{
\bool_gset_false:N \g_@@_zhmCJK_bool
\cs_gset_eq:NN \ctex_zhmap_case:nnn \use_iii:nnn
} ,
nozhmap .code:n =
{ \ctex_set_deprecated_option:n { zhmap = false } } ,
nozhmap .value_forbidden:n = true ,
% \end{macrocode}
% \end{macro}
%
% \changes{v2.0}{2014/04/11}{\opt{punct} 选项可以设置标点格式。}
% \changes{v2.0}{2015/03/21}{\opt{nopunct} 是过时选项。}
%
% \begin{macro}{punct}
% 设置标点符号输出格式。
% \begin{macrocode}
punct .tl_set:N = \l_@@_punct_tl ,
punct .default:n = { quanjiao } ,
punct .initial:n = { quanjiao } ,
nopunct .code:n = \ctex_set_deprecated_option:n { punct = plain } ,
nopunct .value_forbidden:n = true ,
% \end{macrocode}
% \end{macro}
%
% \changes{v2.0}{2015/03/22}{\opt{nospace} 是过时选项。}
% \begin{macro}{space}
% \begin{macrocode}
space .choices:nn =
{ true , auto , false }
{ \ctex_at_end:n { \ctex_set:n { space = #1 } } } ,
space .default:n = { true } ,
nospace .code:n = { \ctex_deprecated_option:nn { space = false } } ,
nospace .value_forbidden:n = true ,
% \end{macrocode}
% \end{macro}
%
% \changes{v2.0}{2014/03/08}{\pkg{ctex} 宏包新增 \opt{heading} 选项。}
%
% \begin{macro}{heading}
% \begin{macrocode}
heading .bool_set:N = \l_@@_heading_bool ,
% \end{macrocode}
% \end{macro}
%
% \begin{macrocode}
%
%<*class|ctex|ctexheading>
% \end{macrocode}
%
% \begin{macro}{sub3section,sub4section}
% \begin{macrocode}
%<*!beamer>
sub3section .code:n =
{ \int_gset:Nn \g_@@_section_depth_int { 3 } } ,
sub4section .code:n =
{ \int_gset:Nn \g_@@_section_depth_int { 4 } } ,
sub3section .value_forbidden:n = true ,
sub4section .value_forbidden:n = true ,
%!beamer>
% \end{macrocode}
% \end{macro}
%
% \changes{v2.0}{2015/04/15}{新增 \opt{scheme} 选项,并将 \opt{cap} 和 \opt{nocap}
% 列为过时选项。}
%
% \begin{macro}{scheme}
% \begin{macrocode}
scheme .tl_set:N = \l_@@_scheme_tl ,
%<*ctexheading>
scheme .default:n = { plain } ,
scheme .initial:n = { plain }
}
%
%<*!ctexheading>
scheme .default:n = { chinese } ,
scheme .initial:n = { chinese } ,
%!ctexheading>
% \end{macrocode}
% \end{macro}
%
% \begin{macrocode}
%
%<*class|ctex>
% \end{macrocode}
%
% \begin{macro}{cap,nocap}
% \opt{cap} 和 \opt{nocap} 是过时选项。
% \begin{macrocode}
cap .code:n = { \ctex_set_deprecated_option:n { scheme = chinese } } ,
nocap .code:n = { \ctex_set_deprecated_option:n { scheme = plain } } ,
cap .value_forbidden:n = true ,
nocap .value_forbidden:n = true ,
% \end{macrocode}
% \end{macro}
%
% \changes{v2.0}{2015/04/20}{\opt{hyperref} 成为过时选项,原选项功能总是打开。}
% \changes{v2.0}{2015/04/20}{\opt{fancyhdr} 成为过时选项,原选项功能总是打开。}
% \changes{v2.0}{2015/04/20}{\opt{fntef} 成为过时选项,原选项功能总是打开。}
%
% 以下三项都是过时的兼容选项,它们会载入有关宏包。
%
% \begin{macro}{fntef}
% \changes{v2.5}{2019/11/10}{仅在该选项启用时会载入 \pkg{CJKfntef} 或
% \pkg{xeCJKfntef} 宏包。}
% \begin{macrocode}
fntef .code:n =
{
\sys_if_engine_xetex:TF
{
\ctex_deprecated_option:n { `xeCJKfntef'~package~is~loaded. }
\ctex_at_end:n { \RequirePackage { xeCJKfntef } }
}
{
\sys_if_engine_pdftex:TF
{
\ctex_deprecated_option:n { `CJKfntef'~package~is~loaded. }
\ctex_at_end:n { \RequirePackage { CJKfntef } }
}
{
\ctex_deprecated_option:n
{ Furthermore,~option~`fntef'~is~invalid~in~current~mode. }
}
}
} ,
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{fancyhdr}
% \begin{macrocode}
fancyhdr .code:n =
{
\ctex_deprecated_option:n { `fancyhdr'~package~is~loaded. }
\ctex_at_end:n { \RequirePackage { fancyhdr } }
} ,
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{hyperref}
% \changes{v2.1}{2015/06/03}{补充定义 \tn{hypersetup}。}
% \begin{macrocode}
hyperref .code:n =
{
\ctex_deprecated_option:n { `hyperref'~package~will~be~loaded. }
\ctex_at_end:n
{
\cs_if_exist:NF \hypersetup
{ \cs_new_eq:NN \hypersetup \ctex_hypersetup:n }
}
\ctex_at_end_preamble:n { \RequirePackage { hyperref } }
} ,
}
% \end{macrocode}
% \end{macro}
%
% \begin{macrocode}
%
%<*class|ctex|ctexsize>
% \end{macrocode}
%
% \changes{v2.0}{2015/05/06}{兼容 \pkg{extsizes} 宏包、\cls{beamer}、\pkg{memoir}
% 等提供的更多字号选项。}
% \changes{v2.0.1}{2015/05/15}{修复 \opt{10pt}、\opt{11pt} 等选项无效的问题。}
% \begin{macro}{10pt,11pt,12pt}
% 使 \pkg{ctex} 和 \pkg{ctexsize} 可以接受文档类的全局选项,不修改默认字体大小。
% 在文档类下还将参数传给标准文档类。
% \begin{macrocode}
\tl_clear_new:N \l_@@_tmp_tl
\clist_map_inline:nn
{
10pt , 11pt , 12pt ,
8pt , 9pt , 14pt , 17pt , 20pt , 25pt , 30pt , 36pt , 48pt , 60pt
}
{
\tl_put_right:Nn \l_@@_tmp_tl
{
#1 .code:n =
%<*!class>
{ \int_gset:Nn \g_@@_font_size_int { 2 } } ,
%!class>
%<*class>
{
\int_gset:Nn \g_@@_font_size_int { 2 }
\clist_gput_right:Nn \g_@@_std_options_clist {#1}
} ,
%
#1 .value_forbidden:n = true ,
}
}
\exp_args:No \ctex_define_option:n { \l_@@_tmp_tl }
\tl_clear:N \l_@@_tmp_tl
% \end{macrocode}
% \end{macro}
%
% 将未知选项传给标准文档类。
% \begin{macrocode}
%<*class>
\ctex_define_option:n
{
unknown .code:n =
{ \clist_gput_right:No \g_@@_std_options_clist { \CurrentOption } }
}
%
% \end{macrocode}
%
% 载入选项配置文件。
% \begin{macrocode}
%\ctex_file_input:n { ctexopts.cfg }
%
% \end{macrocode}
%
% 处理宏包选项。
% \begin{macrocode}
%<*class|style>
\cs_if_exist:NTF \ProcessKeyOptions
{ \ProcessKeyOptions [ ctex / option ] }
{
\RequirePackage { l3keys2e }
\ProcessKeysOptions { ctex / option }
}
%
% \end{macrocode}
%
% \pdfLaTeX{} 下,如果没有显式指定编码为 |UTF8|,则给出警告信息。
% \begin{macrocode}
%<*class|ctex>
\msg_new:nnn { ctex } { pdftex-utf8 }
{ UTF8~will~be~used~as~the~default~encoding. }
\tl_if_empty:NT \g_@@_encoding_tl
{
\sys_if_engine_pdftex:T
{ \msg_warning:nn { ctex } { pdftex-utf8 } }
\tl_gset:Nn \g_@@_encoding_tl { UTF8 }
}
%
% \end{macrocode}
%
% \begin{macrocode}
%<*class>
% \end{macrocode}
%
% 五号字使用标准文档类的 |10pt| 字体大小设置,小四号字则使用 |12pt|。
% \begin{macrocode}
\int_case:nn { \g_@@_font_size_int }
{
{ 0 } { \clist_gput_right:Nn \g_@@_std_options_clist { 10pt } }
{ 1 } { \clist_gput_right:Nn \g_@@_std_options_clist { 12pt } }
}
% \end{macrocode}
%
% 载入标准文档类。
% \begin{macrocode}
%<*article>
\ctex_load_std_class:n { article }
%
%<*book>
\ctex_load_std_class:n { book }
%
%<*report>
\ctex_load_std_class:n { report }
%
%<*beamer>
\ctex_load_std_class:n { beamer }
%
% \end{macrocode}
%
% \begin{macrocode}
%
% \end{macrocode}
%
% \changes{v2.1}{2015/06/16}{不再设置 \pkg{hyperref} 宏包的 \opt{colorlinks} 选项。}
%
% 现在处理各个引擎下的 PDF 中文书签问题。根据编译引擎与文件编码的不
% 同,\pkg{ctex} 向 \pkg{hyperref} 传递适当的参数,完成中文书签的正确设置。用
% 户仍需要自己载入 \pkg{hyperref} 宏包。
%
% \begin{macro}[int]{\ctex_hypersetup:n}
% 如果已经载入 \pkg{hyperref} 宏包,则直接使用其定义设置选项;否则
% \cs{ctex_hypersetup:n} 的效果与 \tn{PassOptionsToPackage} 一致,只传递宏包参
% 数。如果用户不载入 \pkg{hyperref} 宏包,相关参数即被丢弃。
% \begin{macrocode}
%<*class|ctex>
\@ifpackageloaded { hyperref }
{
\cs_new_protected:Npn \ctex_hypersetup:n #1
{ \hypersetup {#1} }
}
{
\cs_new_protected:Npn \ctex_hypersetup:n #1
{ \PassOptionsToPackage {#1} { hyperref } }
}
% \end{macrocode}
% \end{macro}
%
% \subsubsection{载入引擎定义文件}
%
% 最后载入 \ref{subsubsec:hyperref}~中的各个编译引擎的定义文件。
% \begin{macrocode}
\ctex_file_input:n { \c_@@_engine_file_str }
%
% \end{macrocode}
%
% \subsection{用户设置接口}
%
% \changes{v2.0}{2014/03/18}{新增统一设置接口 \tn{ctexset}。}
% \changes{v2.4.12}{2018/01/14}
% {修正 \tn{ctexset} 在 \pkg{ctexheading} 包中无定义的错误(曾祥东)。 }
%
% \begin{macro}{\ctexset}
% \begin{macrocode}
%<*class|ctex|ctexheading>
\NewDocumentCommand \ctexset { } { \ctex_set:n }
%
% \end{macrocode}
% \end{macro}
%
% \changes{v2.0}{2015/03/21}{\tn{CTEXsetup}, \tn{CTEXoptions} 是过时命令。}
% \begin{macro}{\CTEXsetup,\CTEXoptions}
% 过时命令。
% \begin{macrocode}
%<*class|ctex>
\NewDocumentCommand \CTEXsetup { +O { } > { \TrimSpaces } m }
{
\tl_if_blank:nTF {#1}
{ \ctex_deprecated_command:Nn \CTEXsetup { } }
{
\ctex_deprecated_command:Nn \CTEXsetup
{ \ctexset {~#2~=~{~#1~}~}~is~set. }
\ctex_set:nn {#2} {#1}
}
}
\NewDocumentCommand \CTEXoptions { +O { } }
{
\tl_if_blank:nTF {#1}
{ \ctex_deprecated_command:Nn \CTEXoptions { } }
{
\ctex_deprecated_command:Nn \CTEXoptions
{ \ctexset {~#1~}~is~set. }
\ctex_set:n {#1}
}
}
% \end{macrocode}
% \end{macro}
%
% \subsection{字距与缩进}
%
% \begin{macro}{autoindent}
% \opt{autoindent} 也是可以用在正文中的选项,意义与宏包选项 |option/autoindent| 相同。
% \begin{macrocode}
\ctex_define:n
{
autoindent .choice: ,
autoindent .default:n = { true } ,
autoindent / true .code:n =
{
\tl_set:Nn \l_@@_autoindent_tl { 2 \ccwd }
\ctex_select_size:
} ,
autoindent / false .code:n =
{ \tl_clear:N \l_@@_autoindent_tl } ,
autoindent / unknown .code:n =
{
\ctex_set_default_ccwd:Nn \l_@@_autoindent_tl {#1}
\ctex_select_size:
}
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\CTEXsetfont}
% 无论字体大小是否变化都更新相关信息。
% \begin{macrocode}
\NewDocumentCommand \CTEXsetfont { } { \ctex_select_size: }
\cs_new_protected:Npn \ctex_select_size:
{ \cs_if_free:NTF \size@update { \ctex_update_size: } { \selectfont } }
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\ctex_update_size:}
% 在字号变化时更新 \tn{ccwd}、\tn{parindent} 和汉字间距。字距为零则恢复正常设置。
% \begin{macrocode}
\cs_new_protected:Npn \ctex_update_size:
{
\tl_if_eq:NNTF \l_@@_ziju_tl \c_@@_zero_tl
{
\ctex_update_stretch:
\ctex_update_parindent:
}
{ \ctex_update_ziju: }
}
\tl_const:Ne \c_@@_zero_tl { \fp_use:N \c_zero_fp }
\tl_new:N \l_@@_ziju_tl
\tl_set_eq:NN \l_@@_ziju_tl \c_@@_zero_tl
% \end{macrocode}
% 在 \tn{selectfont} 中,若 \tn{size@update} 为 \tn{relax},说明字体大小没有变化,
% 我们也就不用更新相关参数。
% \begin{macrocode}
\ctex_add_to_selectfont:n
{ \cs_if_free:NF \size@update { \ctex_update_size: } }
% \end{macrocode}
% \end{macro}
%
% \changes{v2.0}{2014/03/26}{新增 \opt{linestretch} 选项。}
%
% \begin{macro}{linestretch}
% 若行宽不是汉字宽度的整数倍,自然要求伸展它们之间的差。这里设置的是在此基础上的
% 额外伸展量。初始化为一个汉字的宽度。若设置为 \tn{maxdimen},则禁用此功能。
% 参数的默认单位是汉字的宽度 \tn{ccwd}。
% \begin{macrocode}
\ctex_define:n
{
linestretch .code:n =
{
\ctex_set_default_ccwd:Nn \l_@@_line_stretch_tl {#1}
\ctex_select_size:
} ,
linestretch .value_required:n = true
}
\tl_new:N \l_@@_line_stretch_tl
\tl_set:Nn \l_@@_line_stretch_tl { \ccwd }
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\ctex_update_stretch:}
% 首先计算一行上汉字的字数,\tn{CJKglue} 相当于将 \tn{linewidth} 与汉字总宽度之差
% 均匀地填充到汉字之间。\hologo{eTeX} 的除法是四舍五入,而我们这里应该用截断。由于
% 没有可展性的要求,直接用原语 \cs{tex_divide:D} 要比 \cs{int_div_truncate:nn}
% 快一些。下面的算法还兼顾到了 \tn{linewidth} 不为汉字字宽的整数倍的情况。
% 若用户禁用 \opt{linestretch} 并且修改过 \tn{CJKglue},则只更新
% \tn{ccwd},否则设置伸展量为 $0.08$ 倍 \tn{baselineskip}。注意 \pkg{everysel} 的
% 钩子位于 \tn{size@update} 之前,\tn{baselineskip} 还未更新,不能直接使用它。
% \begin{macrocode}
\cs_new_protected:Npn \ctex_update_stretch:
{
\ctex_update_em_unit:
\dim_set:Nn \l_@@_tmp_dim { \l_@@_line_stretch_tl }
\dim_compare:nNnTF \l_@@_tmp_dim = \c_max_dim
{ \@@_update_stretch_auxi: }
{ \@@_update_stretch_auxii: }
}
\cs_new_protected:Npn \@@_update_stretch_auxi:
{
\ctex_if_ccglue_touched:TF
{ \ctex_update_ccwd: }
{
\dim_set:Nn \l_@@_tmp_dim
{ \baselinestretch \tex_glueexpr:D \f@baselineskip \scan_stop: }
\skip_set:Nn \l_@@_ccglue_skip
{ \c_zero_dim plus .08 \l_@@_tmp_dim }
\ctex_update_ccglue:
}
}
\cs_new_protected:Npn \@@_update_stretch_auxii:
{ \@@_update_stretch_auxiii: }
\cs_new_protected:Npn \@@_update_stretch_auxiii:
{
\int_set:Nn \l_@@_tmp_int
{ \tex_dimexpr:D \linewidth - \ccwd - \l_@@_tmp_dim \scan_stop: }
\tex_divide:D \l_@@_tmp_int \ccwd
\int_compare:nNnTF \l_@@_tmp_int > \c_zero_int
{
\skip_set:Nn \l_@@_ccglue_skip
{
\c_zero_dim plus \dim_eval:n
{
( \linewidth - \ccwd - \l_@@_tmp_int \ccwd ) /
\l_@@_tmp_int
}
}
}
{ \skip_zero:N \l_@@_ccglue_skip }
\ctex_update_ccglue:
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\ctex_update_parindent:}
% 更新段落首行缩进。此函数在字号变化时调用。
% \begin{macrocode}
\cs_new_protected:Npn \ctex_update_parindent:
{
\tl_if_empty:NF \l_@@_autoindent_tl
{
\dim_compare:nNnF \parindent = \c_zero_dim
{ \dim_set:Nn \parindent { \l_@@_autoindent_tl } }
}
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ziju}
% 若参数为 $0$,则恢复正常间距。
% \begin{macrocode}
\NewDocumentCommand \ziju { m }
{ \exp_args:Ne \ctex_ziju:n {#1} \tex_ignorespaces:D }
\cs_new_protected:Npn \ctex_ziju:n #1
{
\tl_set:Ne \l_@@_ziju_tl { \fp_eval:n {#1} }
\ctex_select_size:
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\ctex_update_ziju:}
% 更新字距。若字距不大于 $-1$,即 \tn{ccwd} 为非正值,则不计算伸缩值。
% 否则,首先假定汉字的宽度为正常宽度加上字距,看一行上能正常放下多少个汉字。
% \begin{macrocode}
\cs_new_protected:Npn \ctex_update_ziju:
{
\ctex_update_em_unit:
\dim_set:Nn \l_@@_ziju_dim { \l_@@_ziju_tl \ccwd }
\dim_add:Nn \ccwd { \l_@@_ziju_dim }
\dim_compare:nNnTF \ccwd > \c_zero_dim
% \end{macrocode}
% 伸展量保证行内的剩余空白能够被均匀地填充到汉字之间,收缩的最大限度是让当前行
% 还能够再挤下一个汉字并且不会出现负间距。由 \TeX{} 决定伸展还是收缩。
% \begin{macrocode}
{
\dim_set:Nn \l_@@_tmp_dim
{ \linewidth - \ccwd + \l_@@_ziju_dim }
\int_set:Nn \l_@@_tmp_int { \l_@@_tmp_dim }
\tex_divide:D \l_@@_tmp_int \ccwd
\dim_sub:Nn \l_@@_tmp_dim { \l_@@_tmp_int \ccwd }
% \end{macrocode}
% 由于 \tn{parindent} 是一个固定值,并不参与伸缩,容易导致第一行出现坏盒子。
% 我们在这里将字数减去 $2$,以此放大伸缩值。
% \begin{macrocode}
\dim_compare:nNnF \parindent = \c_zero_dim
{
\int_compare:nNnF \l_@@_tmp_int < 3
{ \int_sub:Nn \l_@@_tmp_int { 2 } }
}
\skip_set:Nn \l_@@_ccglue_skip
{
\l_@@_ziju_dim
plus \dim_eval:n { \l_@@_tmp_dim / \l_@@_tmp_int }
minus \dim_min:nn { \dim_abs:n { \l_@@_ziju_dim } }
{ ( \ccwd - \l_@@_tmp_dim ) / ( \l_@@_tmp_int + 1 ) }
}
}
{ \skip_set:Nn \l_@@_ccglue_skip { \l_@@_ziju_dim } }
\ctex_update_ccglue:
% \end{macrocode}
% 字距设置得比较大时,为了尽量保证段首缩进能够与下一行对齐,应该需要相应地加上
% 或者减去伸缩值。但是这里并不清楚 \TeX{} 是伸展还是收缩,之前以“当前行是否还
% 放得下一个汉字”为标准加上或减去伸缩值的做法也未必与实际结果一致,所以只好还
% 是设置为 |2\ccwd|。
% \begin{macrocode}
\ctex_update_parindent:
}
\dim_new:N \l_@@_ziju_dim
% \end{macrocode}
% \end{macro}
%
% \changes{v2.0}{2015/03/21}{\tn{CTEXindent}, \tn{CTEXnoindent} 是过时命令。}
% \begin{macro}{\CTEXindent,\CTEXnoindent}
% 过时命令。
% \begin{macrocode}
\NewDocumentCommand \CTEXindent { }
{
\ctex_deprecated_command:Nn \CTEXindent
{ \parindent is~set~to~2\ccwd. }
\ctex_update_ccwd:
\dim_set:Nn \parindent { 2 \ccwd }
}
\NewDocumentCommand \CTEXnoindent { }
{
\ctex_deprecated_command:Nn \CTEXnoindent
{ \parindent is~set~to~0pt. }
\dim_zero:N \parindent
}
% \end{macrocode}
% \end{macro}
%
% \subsection{中文数字与日期}
%
% 需要注意的是,\pkg{ltkeys} 设置的选项列表是
% |\@raw@opt@|\meta{\textbackslash @currname}|.|\meta{\textbackslash @currext},
% 该列表不会将 \tn{PassOptionsToPackage} 传递的选项完全展开。
% \begin{macrocode}
\exp_args:Ne \PassOptionsToPackage
{ encoding = \g_@@_encoding_tl }
{ zhnumber }
\RequirePackage { zhnumber }
% \end{macrocode}
%
% \begin{macro}{\chinese}
% \changes{v2.4.1}{2016/05/01}{支持 \tn{pagenumbering}。}
% \begin{macrocode}
\cs_new:Npn \chinese { \zhnum_counter:n }
\cs_new_eq:NN \@chinese \@zhnum
\cs_new_eq:NN \Chinese \chinese
\cs_new_eq:NN \CTEXcounter \use_none:n
% \end{macrocode}
% \end{macro}
%
% \changes{v2.2}{2015/06/29}{给 \pkg{enumitem} 宏包注册 \tn{chinese} 和
% \tn{zhnum}。}
%
% 给 \pkg{enumitem} 宏包注册 \tn{chinese}、\tn{zhnum} 和 \tn{zhdig}。
% \begin{macrocode}
\ctex_at_end_package:nn { enumitem }
{
\cs_if_free:NF \AddEnumerateCounter
{
\AddEnumerateCounter * { \zhnum } { \@zhnum } { 1 }
\AddEnumerateCounter * { \zhdig } { \@zhdig } { 1 }
\AddEnumerateCounter * { \chinese } { \@chinese } { 1 }
}
}
% \end{macrocode}
%
% \begin{macro}{\CTEXnumber,\CTEXdigits}
% \begin{macrocode}
\NewDocumentCommand \CTEXnumber { m m }
{ \protected@edef #1 { \zhnumber {#2} } }
\NewDocumentCommand \CTEXdigits { m m }
{ \protected@edef #1 { \zhdigits {#2} } }
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{today}
% \begin{macrocode}
\cs_set_eq:NN \CTEX@todayold \today
\ctex_define:n
{
today .choice: ,
today / old .code:n =
{ \cs_set_eq:NN \today \CTEX@todayold } ,
today / small .code:n =
{
\cs_set_eq:NN \today \zhtoday
\zhnumsetup { time = Arabic }
} ,
today / big .code:n =
{
\cs_set_eq:NN \today \zhtoday
\zhnumsetup { time = Chinese }
} ,
today / unknown .code:n =
{ \msg_error:nne { ctex } { today-undef } {#1} }
}
\msg_new:nnnn { ctex } { today-undef }
{ Today~format~`#1'~is~undefined. }
{ Available~today~formats~are~`old',~`small',~and~`big'. }
% \end{macrocode}
% \end{macro}
%
% \subsection{其他中文标题定义}
%
% \changes{v2.0}{2014/03/08}{将标题汉化功能加入 \file{ctex.sty}。}
% \changes{v2.4.3}{2016/08/18}{确保 \tn{proofname} 非空。}
%
% \begin{macro}[int]{\proofname}
% \tn{proofname} 未在标准文档类中定义,需要确保它非空。
% \begin{macrocode}
\tl_if_exist:NF \proofname
{
\tl_new:N \proofname
\tl_set:Nn \proofname { Proof }
}
% \end{macrocode}
% \end{macro}
%
% \begin{macrocode}
\ctex_define:n
{
contentsname .tl_set:N = \contentsname ,
listfigurename .tl_set:N = \listfigurename ,
listtablename .tl_set:N = \listtablename ,
figurename .tl_set:N = \figurename ,
tablename .tl_set:N = \tablename ,
abstractname .tl_set:N = \abstractname ,
indexname .tl_set:N = \indexname ,
appendixname .tl_set:N = \appendixname ,
proofname .tl_set:N = \proofname ,
% bibname .tl_set:N = \refname
% bibname .tl_set:N = \bibname
%<*beamer>
algorithmname .tl_set:N = \algorithmname ,
bibname .tl_set:N = \bibname ,
refname .tl_set:N = \refname ,
continuation .tl_set:N = \insertcontinuationtext
%
}
% \end{macrocode}
%
% \begin{macrocode}
%<*ctex>
\msg_new:nnn { ctex } { ctexbibname }
{
Neither~`\token_to_str:N \bibname'~nor~`\token_to_str:N \refname'~can~be~found.\\
The~key~`bibname'~will~set~`\token_to_str:N \ctexbibname'~to~the~given~value.
}
\tl_if_exist:NTF \insertcontinuationtext
{
\ctex_define:n
{
algorithmname .tl_set:N = \algorithmname ,
bibname .tl_set:N = \bibname ,
refname .tl_set:N = \refname ,
continuation .tl_set:N = \insertcontinuationtext
}
}
{
\tl_if_exist:NTF \bibname
{ \ctex_define:n { bibname .tl_set:N = \bibname } }
{
\tl_if_exist:NTF \refname
{ \ctex_define:n { bibname .tl_set:N = \refname } }
{
\msg_warning:nn { ctex } { ctexbibname }
\ctex_define:n { bibname .tl_set:N = \ctexbibname }
}
}
}
%
% \end{macrocode}
%
% \begin{macrocode}
%
% \end{macrocode}
%
% \subsection{中文化的标题结构}
%
% 本节内容在 \CTeX{} 文档类或打开 \opt{heading} 选项下生效。
% \begin{macrocode}
%<*class|heading>
% \end{macrocode}
%
% \subsubsection{定义标题格式选项}
%
% \begin{variable}{\c_@@_section_headings_seq}
% 保存 \tn{section} 级以下标题名字。
% \begin{macrocode}
%<*article|book|report>
\seq_const_from_clist:Nn \c_@@_section_headings_seq
{ section , subsection , subsubsection , paragraph , subparagraph }
%
% \end{macrocode}
% \end{variable}
%
% \begin{variable}{\c_@@_headings_seq}
% 保存各级标题名字。
% \begin{macrocode}
%\seq_const_from_clist:Nn \c_@@_headings_seq
%<*article|book|report>
{
part ,
% chapter ,
section , subsection , subsubsection , paragraph , subparagraph
}
%
% { part , section , subsection }
% \end{macrocode}
% \end{variable}
%
% \changes{v2.1}{2015/06/19}{\opt{nameformat} 可以接受章节名字为参数。}
% \changes{v2.3}{2016/01/05}{修复 \opt{nameformat} 作用域问题。}
%
% \begin{macro}{\@@_initial_heading:n}
% \begin{macrocode}
\cs_new_protected:Npn \@@_initial_heading:n #1
{
\tl_new:c { CTEX@pre#1 }
\tl_new:c { CTEX@post#1 }
\tl_const:ce { CTEXthe#1 }
{
\exp_not:c { CTEX@pre#1 }
\exp_not:c { CTEX@the#1 }
\exp_not:c { CTEX@post#1 }
}
\tl_const:ce { CTEX@#1name }
{
\group_begin:
\exp_not:c { CTEX@#1@nameformat }
{
\exp_not:c { CTEX@pre#1 }
\exp_not:N \tl_if_empty:NTF
\exp_not:c { CTEX@#1@numberformat }
{ \exp_not:c { CTEX@the#1 } }
{
\group_begin:
\exp_not:c { CTEX@#1@numberformat }
\exp_not:c { CTEX@the#1 }
\group_end:
}
\exp_not:c { CTEX@post#1 }
}
\group_end:
}
}
% \end{macrocode}
% \end{macro}
%
% \changes{v2.1}{2015/05/22}{\opt{format+}, \opt{nameformat+} 等带加号的选项,
% 加号与前面的文字之间可以有可选的空格。}
% \changes{v2.1}{2015/06/19}{新的标题格式选项 \opt{aftertitle}。}
% \changes{v2.2}{2015/06/21}{新的标题格式选项 \opt{numbering}。}
% \changes{v2.2}{2015/06/27}{\opt{beforeskip} 和 \opt{afterskip} 选项的符号
% 不再有特殊意义。}
% \changes{v2.2}{2015/06/27}{新的标题格式选项 \opt{afterindent}。}
% \changes{v2.2}{2015/06/27}{新的标题格式选项 \opt{runin}。}
% \changes{v2.4.3}{2016/06/03}{新的标题格式选项 \opt{fixskip}。}
% \changes{v2.4.4}{2016/09/19}{新的标题格式选项 \opt{break}。}
% \changes{v2.4.5}{2016/10/22}{新的标题格式选项 \opt{hang}。}
% \changes{v2.4.5}{2016/10/25}{新的标题格式选项 \opt{tocline}。}
% \changes{v2.4.11}{2017/11/21}{因上游 \pkg{l3keys} 变化,重新定义
% \opt{format\textvisiblespace+} 等带空格加号的选项。}
%
% \begin{macro}{\@@_def_heading_keys:n}
% \begin{macrocode}
\cs_new_protected:Npn \@@_def_heading_keys:n #1
{
\exp_args:NNe \tl_put_right:Nn \l_@@_tmp_tl
{
#1 .meta:nn = { ctex / #1 } { ##1 } ,
#1 / name .code:n =
{ \ctex_assign_heading_name:nn {#1} { ##1 } } ,
#1 / number .tl_set:N = \exp_not:c { CTEX@the#1 } ,
#1 / beforeskip .tl_set:N = \exp_not:c { CTEX@#1@beforeskip } ,
#1 / afterskip .tl_set:N = \exp_not:c { CTEX@#1@afterskip} ,
#1 / indent .tl_set:N = \exp_not:c { CTEX@#1@indent } ,
#1 / numbering .bool_set:N = \exp_not:c { CTEX@#1@numbering } ,
#1 / numbering .initial:n = true ,
#1 / beforeskip .initial:n = \c_zero_skip ,
#1 / afterskip .initial:n = \c_zero_skip ,
#1 / indent .initial:n = \c_zero_dim ,
#1 / beforeskip .value_required:n = true ,
#1 / afterskip .value_required:n = true ,
#1 / indent .value_required:n = true ,
%<*article|book|report>
#1 / afterindent .bool_set:N = \exp_not:c { CTEX@#1@afterindent } ,
#1 / fixskip .bool_set:N = \exp_not:c { CTEX@#1@fixskip } ,
#1 / hang .bool_set:N = \exp_not:c { CTEX@#1@hang } ,
#1 / hang .initial:n = true ,
#1 / runin .bool_set:N = \exp_not:c { CTEX@#1@runin } ,
#1 / tocline .cs_set:Np = \exp_not:c { CTEX@#1@tocline } ##1##2 ,
\@@_plus_key_aux:nn {#1} { break } ,
%
\@@_plus_key_aux:nn {#1} { format } ,
\@@_plus_key_aux:nn {#1} { nameformat } ,
\@@_plus_key_aux:nn {#1} { numberformat } ,
\@@_plus_key_aux:nn {#1} { titleformat } ,
\@@_plus_key_aux:nn {#1} { aftername } ,
\@@_plus_key_aux:nn {#1} { aftertitle } ,
}
}
\cs_new:Npn \@@_plus_key_aux:nn #1#2
{
#1 / #2 .tl_set:N = \exp_not:c { CTEX@#1@#2 } ,
#1 / #2 + .code:n =
{ \tl_put_right:Nn \exp_not:c { CTEX@#1@#2 } { ##1 } } ,
#1 / #2 ~ + .code:n =
{ \tl_put_right:Nn \exp_not:c { CTEX@#1@#2 } { ##1 } }
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\ctex_assign_heading_name:nn}
% \begin{macro}{\@@_assign_heading_name:nnn}
% \opt{name} 的值是一个至多两个元素的逗号分隔列表。由于 \LaTeXiii{} 的
% \texttt{clist} 总是会自动忽略空元素,所以设置 |name={,章}| 后,第一个元素将会
% 是“章”,必须用空的分组保护空元素:|name={{},章}|,这在使用中有些许不便。我们
% 可以改用 \texttt{seq} 或者手写函数解析参数来加以改进。为实现的简单起见,这里用
% 了 \pkg{xparse} 的 \tn{SplitArgument},它带有参数的长度检查。
% \begin{macrocode}
\NewDocumentCommand \ctex_assign_heading_name:nn
{ m > { \SplitArgument { 1 } { , } } +m }
{ \@@_assign_heading_name:nnn {#1} #2 }
\cs_new_protected:Npn \@@_assign_heading_name:nnn #1#2#3
{
\tl_set:cn { CTEX@pre#1 } {#2}
\tl_if_novalue:nTF {#3}
{ \tl_clear:c { CTEX@post#1 } }
{ \tl_set:cn { CTEX@post#1 } {#3} }
}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \changes{v2.0}{2014/03/21}{标题设置新增 \opt{pagestyle} 选项。}
% \changes{v2.4.1}{2016/05/10}{新的标题格式选项 \opt{part/fixbeforeskip} 和
% \opt{chapter/fixbeforeskip}。}
% \changes{v2.4.3}{2016/06/03}{删除选项 \opt{part/fixbeforeskip} 和
% \opt{chapter/fixbeforeskip}。}
% \changes{v2.4.5}{2016/10/01}{新的标题格式选项 \opt{chapter/lofskip} 和
% \opt{chapter/lotskip}。}
%
% \begin{macro}{part/pagestyle,chapter/pagestyle,chapter/lofskip,chapter/lotskip}
% 只在 \cls{ctexbook} 和 \cls{ctexrep} 下有定义。
% \begin{macrocode}
\group_begin:
%<*book|report>
\tl_set:Nn \l_@@_tmp_tl
{
part / pagestyle .tl_set:N = \CTEX@part@pagestyle ,
chapter / pagestyle .tl_set:N = \CTEX@chapter@pagestyle ,
chapter / lofskip .tl_set:N = \CTEX@chapter@lofskip ,
chapter / lotskip .tl_set:N = \CTEX@chapter@lotskip ,
chapter / lofskip .initial:n = \c_zero_skip ,
chapter / lotskip .initial:n = \c_zero_skip ,
chapter / lofskip .value_required:n = true ,
chapter / lotskip .value_required:n = true ,
}
%
%<*article|beamer>
\tl_clear:N \l_@@_tmp_tl
%
% \end{macrocode}
% \end{macro}
%
% 定义标题键值选项。
% \begin{macrocode}
\seq_map_inline:Nn \c_@@_headings_seq
{
\@@_initial_heading:n {#1}
\@@_def_heading_keys:n {#1}
}
\exp_args:NNo \group_end: \ctex_define:n { \l_@@_tmp_tl }
% \end{macrocode}
%
% \changes{v2.5}{2020/04/23}{重构标题选项 \opt{indent} 和 \opt{hang}。}
%
% \begin{macro}[int]{\CTEX@heading@format@initial}
% 标题格式的一些初始设置,包括恢复默认字体,并禁用自动调整首行缩进,禁止在标题中分页。
% 同时用 \tn{noindent} 抑制首行缩进并进入水平模式。
% 统一在各级标题的 \opt{format} 选项之前使用。
% \begin{macrocode}
\cs_new_protected:Npn \CTEX@heading@format@initial
{
\normalfont
\tl_clear:N \l_@@_autoindent_tl
\int_set:Nn \tex_interlinepenalty:D { 10 000 }
\tex_noindent:D
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\ctex_indent_box:n}
% 设置 \tn{parindent},并插入用于产生缩进的盒子,如果缩进为 |0|,就不插入。
% \begin{macrocode}
\cs_new_protected:Npn \ctex_indent_box:n #1
{
\dim_set:Nn \tex_parindent:D {#1}
\@@_insert_indent:
}
\cs_new_protected:Npn \@@_insert_indent:
{
\dim_compare:nNnF \tex_parindent:D = \c_zero_dim
{ \tex_indent:D }
}
\cs_new_eq:NN \CTEX@indentbox \ctex_indent_box:n
% \end{macrocode}
% \end{macro}
%
% \subsubsection{标准标题命令的修改}
%
% \begin{macrocode}
%<*article|book|report>
% \end{macrocode}
%
% \begin{macro}[int]{\CTEX@fixtopskip}
% 修正 \cls{book} 和 \cls{report} 类的 \tn{part} 和 \tn{chapter} 标题之前的多余空行。
% \begin{macrocode}
%<*book|report>
\cs_new_protected:Npn \CTEX@fixtopskip
{
\CTEX@fixheadingskip
\dim_compare:nNnF \tex_pagegoal:D < \c_max_dim
{ \skip_sub:Nn \l_@@_heading_skip { \tex_topskip:D } }
}
%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\CTEX@fixheadingskip}
% 抑制行间粘连,修正标题前后的多余间距。事实上,减掉 \tn{parskip},有一定的风险。
% 如果接下来的内容不会进入水平模式(例如在 \opt{format} 选项中使用 \tn{hrule} 或者 \tn{hbox}),
% \TeX{} 就不会加上 \tn{parskip}。这时候就需要用户把 \tn{parskip} 加到 \opt{beforeskip}
% 或者 \opt{afterskip} 作为修正。
% \begin{macrocode}
\cs_new_protected:Npn \CTEX@fixheadingskip
{
\par
\dim_set:Nn \tex_prevdepth:D { -1000pt }
\skip_sub:Nn \l_@@_heading_skip { \tex_parskip:D }
}
\skip_new:N \l_@@_heading_skip
\cs_new_protected:Npn \CTEX@setheadingskip
{ \skip_set:Nn \l_@@_heading_skip }
\cs_new_eq:NN \CTEX@headingskip \l_@@_heading_skip
% \end{macrocode}
% \end{macro}
%
% \changes{v2.5.10}{2022/06/23}{展开传递 \opt{pagestyle} 的值。}
%
% \begin{macro}[int]{\CTEX@setthispagestyle}
% 将 \verb"\CTEX@(part|chapter)@pagestyle" 展开后再传给 \tn{thispagestyle}。
% \begin{macrocode}
%<*book|report>
\cs_new_protected:Npn \CTEX@setthispagestyle #1
{ \exp_args:Ne \thispagestyle { \use:c { CTEX@#1@pagestyle } } }
%
% \end{macrocode}
% \end{macro}
%
% \changes{v2.4.4}{2016/09/18}{提供 \tn{partmark}。}
% \begin{macro}[int]{\partmark}
% 提供 \tn{partmark}。
% \begin{macrocode}
\ProvideDocumentCommand \partmark { m }
{ \markboth { } { } }
% \end{macrocode}
% \end{macro}
%
% \changes{v2.4.4}{2016/09/19}{提供 \tn{CTEXifname}。}
% \changes{v2.4.6}{2016/10/31}{\tn{CTEXifname} 初始为假。}
% \begin{macro}{\CTEXifname}
% \begin{macro}[int]{\CTEX@ifnametrue,\CTEX@ifnamefalse}
% 用于判断当前标题是否有编号。
% \begin{macrocode}
\cs_new_eq:NN \CTEXifname \use_ii:nn
\cs_new_protected:Npn \CTEX@ifnametrue
{ \cs_set_eq:NN \CTEXifname \use_i:nn }
\cs_new_protected:Npn \CTEX@ifnamefalse
{ \cs_set_eq:NN \CTEXifname \use_ii:nn }
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}[int]{\CTEX@addloflotskip}
% 往插图和表格目录中加入额外间距。如果间距为零,则不加入。
% \begin{macrocode}
%<*book|report>
\cs_new_protected:Npn \CTEX@addloflotskip #1
{
\skip_set:Nn \l_@@_heading_skip { \use:c { CTEX@#1@lofskip } }
\skip_if_eq:nnF { \l_@@_heading_skip } { \c_zero_skip }
{
\addtocontents { lof }
{ \protect \addvspace { \skip_use:N \l_@@_heading_skip } }
}
\skip_set:Nn \l_@@_heading_skip { \use:c { CTEX@#1@lotskip } }
\skip_if_eq:nnF { \l_@@_heading_skip } { \c_zero_skip }
{
\addtocontents { lot }
{ \protect \addvspace { \skip_use:N \l_@@_heading_skip } }
}
}
%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\CTEX@addtocline}
% \begin{macrocode}
\cs_new_protected:Npn \CTEX@addtocline #1#2
{ \addcontentsline { toc } {#1} { \use:c { CTEX@#1@tocline } {#1} {#2} } }
% \end{macrocode}
% \end{macro}
%
% \changes{v2.2}{2015/06/27}{\opt{beforeskip}、\opt{afterskip} 和 \opt{indent}
% 选项支持表达式。}
% \changes{v2.4.15}{2019/03/31}{修正 \opt{part/indent} 和 \opt{chapter/indent} 的实现方法。}
% \changes{v2.4.15}{2019/03/31}{定义 \opt{part/hang} 和 \opt{chapter/hang}。}
% \changes{v2.4.16}{2019/05/11}{修正 \opt{part/indent} 和 \opt{chapter/indent}
% 的实现方法,在其标题内部禁用 \opt{autoindent}。}
%
% \changes{v2.5}{2020/04/22}{标题选项 \opt{format} 也可以接受参数。}
%
% \paragraph{part 的标题}
%
% \changes{v2.2}{2015/06/27}{非 \cls{ctexart} 类的 \opt{part/beforeskip} 和
% \opt{part/afterskip} 选项有意义。}
%
% \begin{macro}[int]{\part}
% \begin{macrocode}
%<*article>
\renewcommand\part{%
\if@noskipsec \leavevmode \fi
\par
\CTEX@part@break
% \addvspace{4ex}%
\CTEX@setheadingskip \CTEX@part@beforeskip
\ifodd \CTEX@part@fixskip \CTEX@fixheadingskip \fi
\addvspace \CTEX@headingskip
\ifodd \CTEX@part@afterindent
\@afterindenttrue
\else
\@afterindentfalse
\fi
\secdef\@part\@spart}
%
%<*book|report>
\renewcommand\part{%
% \if@openright
% \cleardoublepage
% \else
% \clearpage
% \fi
\CTEX@part@break
% \thispagestyle{plain}%
\CTEX@setthispagestyle{part}%
\if@twocolumn
\onecolumn
\@tempswatrue
\else
\@tempswafalse
\fi
% \null\vfil
\CTEX@setheadingskip \CTEX@part@beforeskip
\ifodd \CTEX@part@fixskip \CTEX@fixtopskip \fi
\vspace*{\CTEX@headingskip}%
\secdef\@part\@spart}
%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\@part}
% \begin{macrocode}
%<*article>
\def\@part[#1]#2{%
\ifnum \c@secnumdepth >\m@ne
\ifodd \CTEX@part@numbering
\CTEX@ifnametrue
\refstepcounter{part}%
% \addcontentsline{toc}{part}{\thepart\hspace{1em}#1}%
\else
\CTEX@ifnamefalse
\CTEX@makeanchor{part*}%
% \addcontentsline{toc}{part}{#1}%
\fi
\else
\CTEX@ifnamefalse
\CTEX@makeanchor{part*}%
% \addcontentsline{toc}{part}{#1}%
\fi
\CTEX@gettitle{#1}%
\CTEX@addtocline{part}{#1}%
\partmark{#1}%
\begingroup
% \parindent \z@ \raggedright \interlinepenalty \@M \normalfont
\CTEX@heading@format@initial
\CTEX@part@format{%
% \ifnum \c@secnumdepth >\m@ne
% \Large\bfseries\partname\nobreakspace\thepart\par\nobreak
% \fi
\CTEX@headinghang{part}%
{\CTEXifname{\CTEX@partname\CTEX@part@aftername}{}}%
% \huge\bfseries #2%
\CTEX@part@titleformat{#2}%
% \markboth{}{}\par
\CTEX@part@aftertitle}\par
\endgroup
\nobreak
% \vskip 3ex
\CTEX@setheadingskip \CTEX@part@afterskip
\ifodd \CTEX@part@fixskip \CTEX@fixheadingskip \fi
\vskip \CTEX@headingskip
\@afterheading}
%
%<*book|report>
\def\@part[#1]#2{%
\ifnum \c@secnumdepth >-2\relax
\ifodd \CTEX@part@numbering
\CTEX@ifnametrue
\refstepcounter{part}%
% \addcontentsline{toc}{part}{\thepart\hspace{1em}#1}%
\else
\CTEX@ifnamefalse
\CTEX@makeanchor{part*}%
% \addcontentsline{toc}{part}{#1}%
\fi
\else
\CTEX@ifnamefalse
\CTEX@makeanchor{part*}%
% \addcontentsline{toc}{part}{#1}%
\fi
\CTEX@gettitle{#1}%
\CTEX@addtocline{part}{#1}%
% \markboth{}{}%
\partmark{#1}%
\begingroup
% \centering \interlinepenalty \@M \normalfont
\CTEX@heading@format@initial
\CTEX@part@format{%
% \ifnum \c@secnumdepth >-2\relax
% \huge\bfseries\partname\nobreakspace\thepart\par\vskip 20\p@
% \fi
\CTEX@headinghang{part}%
{\CTEXifname{\CTEX@partname\CTEX@part@aftername}{}}%
% \Huge\bfseries #2\par
\CTEX@part@titleformat{#2}%
\CTEX@part@aftertitle}\par
\endgroup
\@endpart}
%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\@spart}
% \begin{macrocode}
%<*article>
\def\@spart#1{%
\CTEX@ifnamefalse
\CTEX@makeanchor@spart{part*}%
\CTEX@gettitle{#1}%
\begingroup
% \parindent \z@ \raggedright \interlinepenalty \@M \normalfont
\CTEX@heading@format@initial
\CTEX@part@format{%
\CTEX@headinghang{part}{}%
% \huge \bfseries #1\par
\CTEX@part@titleformat{#1}%
\CTEX@part@aftertitle}\par
\endgroup
\nobreak
% \vskip 3ex
\CTEX@setheadingskip \CTEX@part@afterskip
\ifodd \CTEX@part@fixskip \CTEX@fixheadingskip \fi
\vskip \CTEX@headingskip
\@afterheading}
%
%<*book|report>
\def\@spart#1{%
\CTEX@ifnamefalse
\CTEX@makeanchor@spart{part*}%
\CTEX@gettitle{#1}%
\begingroup
% \centering \interlinepenalty \@M \normalfont
\CTEX@heading@format@initial
\CTEX@part@format{%
\CTEX@headinghang{part}{}%
% \Huge \bfseries #1\par%
\CTEX@part@titleformat{#1}%
\CTEX@part@aftertitle}\par
\endgroup
\@endpart}
%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\@endpart}
% \begin{macrocode}
%<*book|report>
\def\@endpart{%
% \vfil
\CTEX@setheadingskip \CTEX@part@afterskip
\ifodd \CTEX@part@fixskip \CTEX@fixheadingskip \fi
\vskip \CTEX@headingskip
\newpage
\if@twoside
\if@openright
\null
\thispagestyle{empty}%
\newpage
\fi
\fi
\if@tempswa
\twocolumn
\fi}
%
% \end{macrocode}
% \end{macro}
%
% \paragraph{chapter 的标题}
%
% \begin{macrocode}
%<*book|report>
% \end{macrocode}
%
% \begin{macro}[int]{\chapter}
% \begin{macrocode}
\renewcommand\chapter{%
% \if@openright\cleardoublepage\else\clearpage\fi
% \thispagestyle{plain}%
\CTEX@chapter@break
\CTEX@setthispagestyle{chapter}%
\global\@topnum\z@
% \@afterindentfalse
\ifodd \CTEX@chapter@afterindent
\@afterindenttrue
\else
\@afterindentfalse
\fi
\secdef\@chapter\@schapter}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\@chapter}
% \begin{macrocode}
\def\@chapter[#1]#2{%
\ifnum \c@secnumdepth >\m@ne
%<*book>
\if@mainmatter
%
\ifodd \CTEX@chapter@numbering
\CTEX@ifnametrue
\refstepcounter{chapter}%
% \typeout{\@chapapp\space\thechapter.}%
\typeout{\CTEXthechapter}%
% \addcontentsline{toc}{chapter}
% {\protect\numberline{\thechapter}#1}%
\else
\CTEX@ifnamefalse
\CTEX@makeanchor{\Hy@chapapp*}%
% \addcontentsline{toc}{chapter}{#1}%
\fi
%<*book>
\else
\CTEX@ifnamefalse
\CTEX@makeanchor@chapter{\Hy@chapapp*}%
% \addcontentsline{toc}{chapter}{#1}%
\fi
%
\else
\CTEX@ifnamefalse
\CTEX@makeanchor@chapter{\Hy@chapapp*}%
% \addcontentsline{toc}{chapter}{#1}%
\fi
\CTEX@gettitle{#1}%
\CTEX@addtocline{chapter}{#1}%
\chaptermark{#1}%
% \addtocontents{lof}{\protect\addvspace{10\p@}}%
% \addtocontents{lot}{\protect\addvspace{10\p@}}%
\CTEX@addloflotskip{chapter}%
\if@twocolumn
\@topnewpage[\@makechapterhead{#2}]%
\else
\@makechapterhead{#2}%
\@afterheading
\fi}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\@schapter}
% \begin{macrocode}
\def\@schapter#1{%
\CTEX@ifnamefalse
\CTEX@makeanchor@schapter{\Hy@chapapp*}%
\CTEX@gettitle{#1}%
\if@twocolumn
\@topnewpage[\@makeschapterhead{#1}]%
\else
\@makeschapterhead{#1}%
\@afterheading
\fi}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\@makechapterhead}
% \begin{macrocode}
\def\@makechapterhead#1{%
% \vspace*{50\p@}%
\CTEX@setheadingskip \CTEX@chapter@beforeskip
\ifodd \CTEX@chapter@fixskip \CTEX@fixtopskip \fi
\vspace*{\CTEX@headingskip}%
\begingroup
% \parindent \z@ \raggedright \normalfont
\CTEX@heading@format@initial
\CTEX@chapter@format{%
% \ifnum \c@secnumdepth >\m@ne
% \if@mainmatter
% \huge\bfseries\@chapapp\space\thechapter\par\nobreak\vskip 20\p@
% \fi
% \fi
\CTEX@headinghang{chapter}%
{\CTEXifname{\CTEX@chaptername\CTEX@chapter@aftername}{}}%
% \Huge \bfseries #1\par\nobreak
\CTEX@chapter@titleformat{#1}%
\CTEX@chapter@aftertitle}\par
\endgroup
\nobreak
% \vskip 40\p@
\CTEX@setheadingskip \CTEX@chapter@afterskip
\ifodd \CTEX@chapter@fixskip \CTEX@fixheadingskip \fi
\vskip \CTEX@headingskip}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\@makeschapterhead}
% \begin{macrocode}
\def\@makeschapterhead#1{%
% \vspace*{50\p@}%
\CTEX@setheadingskip \CTEX@chapter@beforeskip
\ifodd \CTEX@chapter@fixskip \CTEX@fixtopskip \fi
\vspace*{\CTEX@headingskip}%
\begingroup
% \parindent \z@ \raggedright \normalfont \interlinepenalty\@M
\CTEX@heading@format@initial
\CTEX@chapter@format{%
\CTEX@headinghang{chapter}{}%
% \Huge \bfseries #1\par\nobreak
\CTEX@chapter@titleformat{#1}%
\CTEX@chapter@aftertitle}\par
\endgroup
\nobreak
% \vskip 40\p@
\CTEX@setheadingskip \CTEX@chapter@afterskip
\ifodd \CTEX@chapter@fixskip \CTEX@fixheadingskip \fi
\vskip \CTEX@headingskip}
% \end{macrocode}
% \end{macro}
%
% \begin{macrocode}
%
% \end{macrocode}
%
% \paragraph{section 类的标题}
%
% \begin{macro}[int]{\@startsection}
% \LaTeX 的标准参数是:
% \begin{quote}\small
% \Arg{name}\Arg{level}\Arg{indent}\Arg{beforeskip}\Arg{afterskip}^^A
% \Arg{style}|*|\oarg{altheading}\Arg{heading}
% \end{quote}
% \begin{macrocode}
\def\@startsection#1#2#3#4#5#6{%
\if@noskipsec \leavevmode \fi
\par
% \@tempskipa #4\relax
% \@afterindenttrue
% \ifdim \@tempskipa <\z@
% \@tempskipa -\@tempskipa \@afterindentfalse
% \fi
\CTEX@update@sectionformat@n{#1}%
\ifodd \CTEX@afterindent
\@afterindenttrue
\else
\@afterindentfalse
\fi
\if@nobreak
\everypar{}%
\else
% \addpenalty\@secpenalty\addvspace\@tempskipa
\csname CTEX@#1@break\endcsname
\CTEX@setheadingskip{#4}%
\ifodd \CTEX@fixskip \CTEX@fixheadingskip \fi
\addvspace \CTEX@headingskip
\fi
\@ifstar
{\CTEX@makeanchor@ssect{#1*}\@ssect{#3}{#4}{#5}{#6}}%
{\@dblarg{\@sect{#1}{#2}{#3}{#4}{#5}{#6}}}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\@seccntformat}
% \begin{macrocode}
\def\@seccntformat#1{%
% \csname the#1\endcsname\quad}%
\csname CTEX@#1name\endcsname
\csname CTEX@#1@aftername\endcsname}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\@sect}
% \begin{macrocode}
\def\@sect#1#2#3#4#5#6[#7]#8{%
\ifnum #2>\c@secnumdepth
\CTEX@ifnamefalse
\CTEX@makeanchor@sect{#1*}%
\let\@svsec\@empty
\else
\ifodd \csname CTEX@#1@numbering\endcsname
\CTEX@ifnametrue
\refstepcounter{#1}%
\protected@edef\@svsec{\@seccntformat{#1}\relax}%
\else
\CTEX@ifnamefalse
\CTEX@makeanchor{#1*}%
\let\@svsec\@empty
\fi
\fi
\CTEX@gettitle{#7}%
% \@tempskipa #5\relax
% \ifdim \@tempskipa>\z@
\unless \ifodd \CTEX@runin
\begingroup
\CTEX@heading@format@initial
#6{%
% \@hangfrom{\hskip #3\relax\@svsec}%
% \interlinepenalty \@M #8\@@@@par
\CTEX@sectionhang{#3}{\@svsec}%
\csname CTEX@#1@titleformat\endcsname{#8}%
\csname CTEX@#1@aftertitle\endcsname}\par
\endgroup
\csname #1mark\endcsname{#7}%
% \addcontentsline{toc}{#1}{%
% \ifnum #2>\c@secnumdepth \else
% \protect\numberline{\csname the#1\endcsname}%
% \fi
% #7}%
\CTEX@addtocline{#1}{#7}%
\else
\def\@svsechd{%
#6{%
% \hskip #3\relax \@svsec #8
{\CTEX@indentbox{#3}}\@svsec
\csname CTEX@#1@titleformat\endcsname{#8}%
\csname CTEX@#1@aftertitle\endcsname}%
\csname #1mark\endcsname{#7}%
% \addcontentsline{toc}{#1}{%
% \ifnum #2>\c@secnumdepth \else
% \protect\numberline{\csname the#1\endcsname}%
% \fi
% #7}%
\CTEX@addtocline{#1}{#7}}%
\fi
\@xsect{#5}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\@ssect}
% \begin{macrocode}
\def\@ssect#1#2#3#4#5{%
\CTEX@ifnamefalse
\CTEX@gettitle{#5}%
% \@tempskipa #3\relax
% \ifdim \@tempskipa>\z@
\unless \ifodd \CTEX@runin
\begingroup
\CTEX@heading@format@initial
#4{%
% \@hangfrom{\hskip #1}%
% \interlinepenalty \@M #5\@@par
\CTEX@sectionhang{#1}{}%
\CTEX@titleformat@n{#5}%
\CTEX@aftertitle}\par
\endgroup
\else
% \def\@svsechd{#4{\hskip #1\relax #5}}%
\def\@svsechd{#4{{\CTEX@indentbox{#1}}%
\CTEX@titleformat@n{#5}\CTEX@aftertitle}}%
\fi
\@xsect{#3}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\@xsect}
% \begin{macrocode}
\def\@xsect#1{%
% \@tempskipa #1\relax
% \ifdim \@tempskipa>\z@
\unless \ifodd \CTEX@runin
\par \nobreak
% \vskip \@tempskipa
\CTEX@setheadingskip{#1}%
\ifodd \CTEX@fixskip \CTEX@fixheadingskip \fi
\vskip \CTEX@headingskip
\@afterheading
\else
\@nobreakfalse
\global\@noskipsectrue
\everypar{%
\if@noskipsec
\global\@noskipsecfalse
{\setbox\z@\lastbox}%
\clubpenalty\@M
\begingroup \@svsechd \endgroup
\unskip
% \@tempskipa #1\relax
% \hskip -\@tempskipa
\CTEX@heading@glue{#1}%
\else
\clubpenalty \@clubpenalty
\everypar{}%
\fi}%
\fi
\ignorespaces}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\CTEX@headinghang,\CTEX@sectionhang}
% 分别用于用于实现 \tn{part}/\tn{chapter} 和 \tn{section} 类标题的
% \opt{indent} 和 \opt{hang} 选项。
% \begin{macrocode}
\cs_new_protected:Npn \CTEX@headinghang #1
{
\ctex_heading_hang:cnn
{ CTEX@#1@hang }
{ \use:c { CTEX@#1@indent } }
}
\cs_new_protected:Npn \CTEX@sectionhang
{ \ctex_heading_hang:Nnn \CTEX@hang }
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\ctex_heading_hang:Nnn,\ctex_hang_from:n}
% \opt{hang} 选项控制是否采用悬挂缩进,同时设置 \tn{parindent}。
% \begin{macrocode}
\cs_new_protected:Npn \ctex_heading_hang:Nnn #1#2#3
{
\dim_set:Nn \tex_parindent:D {#2}
\bool_if:NTF #1
{ \ctex_hang_from:n }
{ \use:n }
{ \@@_insert_indent: #3 }
}
\cs_new_protected:Npn \ctex_hang_from:n #1
{
\tex_noindent:D
\hbox_set:Nn \l_@@_tmp_box {#1}
\tex_hangindent:D = \box_wd:N \l_@@_tmp_box
\box_use_drop:N \l_@@_tmp_box
}
\cs_generate_variant:Nn \ctex_heading_hang:Nnn { c }
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\ctex_heading_glue:n,\CTEX@heading@glue}
% 如果缩进 |#1| 长度为零,就不插入水平间距。
% \begin{macrocode}
\cs_new_protected:Npn \ctex_heading_glue:n #1
{
\group_begin:
\skip_set:Nn \l_@@_heading_skip {#1}
\dim_compare:nNnF \l_@@_heading_skip = \c_zero_dim
{ \skip_horizontal:N \l_@@_heading_skip }
\group_end:
}
\cs_new_eq:NN \CTEX@heading@glue \ctex_heading_glue:n
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\CTEX@update@sectionformat@n}
% 在 \tn{@startsection} 中设置 \tn{CTEX@titleformat@n} 等为相应函数。
% \begin{macrocode}
\cs_new_protected:Npn \CTEX@update@sectionformat@n #1
{
\cs_set_eq:Nc \CTEX@titleformat@n { CTEX@#1@titleformat }
\cs_set_eq:Nc \CTEX@aftertitle { CTEX@#1@aftertitle }
\cs_set_eq:Nc \CTEX@afterindent { CTEX@#1@afterindent }
\cs_set_eq:Nc \CTEX@fixskip { CTEX@#1@fixskip }
\cs_set_eq:Nc \CTEX@hang { CTEX@#1@hang }
\cs_set_eq:Nc \CTEX@runin { CTEX@#1@runin }
}
\cs_new_eq:NN \CTEX@titleformat@n \use:n
\cs_new_eq:NN \CTEX@aftertitle \prg_do_nothing:
\cs_new_eq:NN \CTEX@afterindent \c_true_bool
\cs_new_eq:NN \CTEX@fixskip \c_false_bool
\cs_new_eq:NN \CTEX@hang \c_true_bool
\cs_new_eq:NN \CTEX@runin \c_false_bool
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\CTEX@part@tocline, \CTEX@chapter@tocline}
% \begin{macrocode}
\cs_new:Npn \CTEX@part@tocline #1#2
{
\CTEXifname
{ \CTEXthepart \hspace { 1em } }
{ }
#2
}
%<*book|report>
\cs_new:Npn \CTEX@chapter@tocline #1#2
{
\CTEXifname
{ \protect \numberline { \CTEXthechapter \hspace { .3em } } }
{ }
#2
}
%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\CTEXnumberline}
% \begin{macrocode}
\cs_new:Npn \CTEXnumberline #1
{
\CTEXifname
{ \protect \numberline { \use:c { CTEXthe #1 } } }
{ }
}
% \end{macrocode}
% \end{macro}
%
% \begin{macrocode}
\int_zero:N \l_@@_tmp_int
\seq_map_inline:Nn \c_@@_section_headings_seq
{
\int_incr:N \l_@@_tmp_int
\cs_gset_protected:cpx {#1}
{
\exp_not:N \@startsection {#1}
{ \int_use:N \l_@@_tmp_int }
{ \exp_not:c { CTEX@#1@indent } }
{ \exp_not:c { CTEX@#1@beforeskip } }
{ \exp_not:c { CTEX@#1@afterskip } }
{ \exp_not:N \normalfont \exp_not:c { CTEX@#1@format } }
}
\cs_new:cpn { CTEX@#1@tocline } ##1##2
{ \CTEXnumberline { ##1 } ##2 }
}
% \end{macrocode}
%
% \paragraph{附录标题}
%
% \begin{macro}[int]{appendix/name,appendix/number,appendix/numbering}
% \begin{macrocode}
\ctex_define:n
{
appendix .meta:nn = { ctex / appendix } {#1} ,
appendix / name .code:n =
{ \ctex_assign_heading_name:nn { appendix } {#1} } ,
appendix / number .tl_set:N = \CTEX@appendix@number ,
appendix / numbering .bool_set:N = \CTEX@appendix@numbering ,
appendix / numbering .initial:n = true
}
\tl_new:N \CTEX@preappendix
\tl_new:N \CTEX@postappendix
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\appendix}
% \begin{macrocode}
\cs_new_eq:NN \CTEX@save@appendix \appendix
\cs_gset_protected:Npn \appendix
{
\CTEX@save@appendix
%<*article>
\gdef \CTEX@presection { \CTEX@preappendix }
\gdef \CTEX@thesection { \CTEX@appendix@number }
\gdef \CTEX@postsection { \CTEX@postappendix }
\gdef \CTEX@section@numbering { \CTEX@appendix@numbering }
%
%<*book|report>
\gdef \CTEX@prechapter { \CTEX@preappendix }
\gdef \CTEX@thechapter { \CTEX@appendix@number }
\gdef \CTEX@postchapter { \CTEX@postappendix }
\gdef \CTEX@chapter@numbering { \CTEX@appendix@numbering }
%
}
% \end{macrocode}
% \end{macro}
%
% \paragraph{设置 \pkg{hyperref} 宏包的标题锚点}
%
% \changes{v2.4.4}{2016/09/12}{改进 \pkg{hyperref} 宏包的标题锚点设置。}
%
% \begin{macro}[int]{\CTEX@makeanchor}
% 设置超链接跳转锚点,在 \pkg{hyperref} 载入后才有意义。
% \begin{macrocode}
\cs_new_protected:Npn \CTEX@makeanchor #1
{ }
% \end{macrocode}
% \end{macro}
%
% \begin{variable}{\c_@@_headings_cs_seq}
% 保存内部标题命令的 \CTeX{} 定义,用于随后比较。
% \begin{macrocode}
\seq_const_from_clist:Nn \c_@@_headings_cs_seq
% { part , spart , sect , ssect }
% { part , spart , chapter , schapter , sect , ssect }
\seq_map_inline:Nn \c_@@_headings_cs_seq
{
\cs_new_eq:cc { CTEX@ #1 } { @ #1 }
\cs_new_eq:cN { CTEX@makeanchor@ #1 } \CTEX@makeanchor
}
% \end{macrocode}
% \end{variable}
%
% \begin{macro}[int]{\CTEX@hyperheadinghook}
% \pkg{hyperref} 会重定义内部标题命令,目的在于为没有编号的标题设置锚点(这一功能受他的
% \opt{implicit} 选项的控制)。我们在上面对标题命令的修改已经包含这一功能,如果这些标题命令在
% \pkg{hyperref} 载入之前没有被修改过,则恢复 \CTeX{} 的定义。
% \begin{macrocode}
\cs_new_protected:Npn \CTEX@hyperheadinghook
{
\group_begin:
\legacy_if:nTF { Hy@implicit }
{
\cs_set_eq:NN \H@old@chapter \Hy@org@chapter
\seq_map_inline:Nn \c_@@_headings_cs_seq
{
\cs_if_eq:ccT { H@old@ ##1 } { CTEX@ ##1 }
{
\cs_gset_eq:cc { @ ##1 } { CTEX@ ##1 }
\cs_gset_eq:cN { CTEX@makeanchor@ ##1 } \CTEX@makeanchor
}
}
}
{
\seq_map_inline:Nn \c_@@_headings_cs_seq
{ \cs_gset_eq:cN { CTEX@makeanchor@ ##1 } \CTEX@makeanchor }
}
\group_end:
}
% \end{macrocode}
% \end{macro}
%
% \begin{macrocode}
\ctex_at_end_package:nn { hyperref }
{
\cs_gset_protected:Npn \CTEX@makeanchor #1
{
\Hy@MakeCurrentHrefAuto {#1}
\Hy@raisedlink
{
\hyper@anchorstart { \@currentHref }
\hyper@anchorend
}
}
\CTEX@hyperheadinghook
}
% \end{macrocode}
%
% \paragraph{兼容 \pkg{nameref} 宏包}
%
% \changes{v2.4.16}{2019/05/29}{更好地兼容 \pkg{nameref} 宏包。}
%
% \begin{macro}[int]{\CTEX@gettitle}
% 在 \pkg{nameref} 载入后才有意义,与上述 \pkg{hyperref} 的处理类似。
% \begin{macrocode}
\cs_new_protected:Npn \CTEX@gettitle #1
{ }
\ctex_at_end_package:nn { nameref }
{
\cs_gset_protected:Npn \CTEX@gettitle { \NR@gettitle }
\seq_map_inline:Nn \c_@@_headings_cs_seq
{
\cs_if_eq:ccT { NR@ #1 } { CTEX@ #1 }
{ \cs_gset_eq:cc { @ #1 } { CTEX@ #1 } }
}
}
% \end{macrocode}
% \end{macro}
%
% \paragraph{兼容 \pkg{titlesec} 宏包}
%
% 我们修改了 \tn{@startsection} 的定义,它的第四个(\meta{beforeskip})和
% 第五个(\meta{afterskip})参数的符号不再有特殊意义,改由相应的选项
% \opt{afterindent} 和 \opt{runin} 来控制。
%
% 引入 \pkg{titlesec} 宏包,并且未设置它的 \opt{loadonly} 选项时,\pkg{titlesec}
% 会展开 section 类标题获取它们的参数,进行初始设置。我们需要进行一些调整。
%
% \begin{macro}[int]{\ctex_titlesec_hook:}
% \tn{titleformat} 的设置保存在名为 |\ttlf@|\meta{section} 的宏中备用,它的内容是
% \begin{quote}\small
% |\ttlh@|\meta{shape}\Arg{format}\Arg{label}\Arg{sep}\Arg{before}\Arg{after}
% \end{quote}
% 我们这里的 \meta{shape} 为 |hang| 或者 |runin|。\tn{titlespacing} 的设置保存在
% |\ttls@|\meta{section} 之中,它的内容是
% \begin{quote}\small
% \Arg{left}\Arg{right}\Arg{before}\Arg{after}\Arg{afterindent}
% \end{quote}
% 其中 \meta{afterindent} 为 |1| 或 |0|,分别对应是否保留段首缩进。
% 我们需要根据 \CTeX{} 的 \opt{runin} 和 \opt{afterindent} 选项调整
% |\ttlh@|\meta{shape} 和 \meta{afterindent}。注意,由 \tn{ttl@extract} 得的
% \meta{before} 和 \meta{after} 的值总是非负的,而 \CTeX{} 的 \opt{beforeskip}
% 和 \opt{afterskip} 是可以取负值的,但我们不打算调整它们了。
% 如果使用了 \pkg{titlesec} 的 \opt{indentafter} 等选项,也不需要调整
% |\ttls@|\meta{section}。
% \begin{macrocode}
\cs_new_protected:Npn \ctex_titlesec_hook:
{
\@ifpackagewith { titlesec } { explicit }
{
\cs_set_eq:NN \@@_titlesec_format:Nn
\@@_titlesec_format_explicit:Nn
}
{ }
\clist_map_inline:nn
{ indentafter , noindentafter , indentfirst , nonindentfirst }
{
\@ifpackagewith { titlesec } { ##1 }
{
\clist_map_break:n
{ \cs_set_eq:NN \@@_titlesec_hook:n \@@_titlesec_format:n }
}
{ }
}
\seq_map_function:NN \c_@@_section_headings_seq \@@_titlesec_hook:n
}
\cs_new_protected:Npn \@@_titlesec_hook:n #1
{
\@@_titlesec_format:n {#1}
\exp_args:Nc \@@_titlesec_spacing:Nn { ttls@#1 } {#1}
}
\cs_new_protected:Npn \@@_titlesec_format:n #1
{
\cs_if_free:cF { ttlf@#1 }
{ \exp_args:Nc \@@_titlesec_format:Nn { ttlf@#1 } {#1} }
}
\cs_new_protected:Npn \@@_titlesec_format:Nn #1#2
{
\tl_set:Ne #1
{
\bool_if:cTF { CTEX@#2@runin }
{ \exp_not:N \ttlh@runin }
{ \exp_not:N \ttlh@hang }
\tl_tail:N #1
}
}
\cs_new_protected:Npn \@@_titlesec_format_explicit:Nn #1#2
{
\cs_set_nopar:Npx #1 ##1
{
\bool_if:cTF { CTEX@#2@runin }
{ \exp_not:N \ttlh@runin }
{ \exp_not:N \ttlh@hang }
\exp_args:No \tl_tail:n { #1 { } }
}
}
\cs_new_protected:Npn \@@_titlesec_spacing:Nn #1#2
{ \tl_set:Ne #1 { \exp_after:wN \@@_titlesec_spacing:nnnnnn #1 {#2} } }
\cs_new:Npn \@@_titlesec_spacing:nnnnnn #1#2#3#4#5#6
{
\exp_not:n { {#1} {#2} {#3} {#4} }
{ \bool_if:cTF { CTEX@#6@afterindent } { \@ne } { \z@ } }
}
% \end{macrocode}
% \end{macro}
%
% \begin{macrocode}
\@ifpackageloaded { titlesec }
{ }
{
\ctex_at_end_package:nn { titlesec }
{
\@ifpackagewith { titlesec } { loadonly }
{ }
{ \ctex_titlesec_hook: }
}
}
% \end{macrocode}
%
% \changes{v2.4.4}{2016/09/13}{使用 \pkg{titlesec} 时,章节目录也使用 \CTeX{} 的编号。}
% 让编译时终端显示 \tn{CTEXthechapter},目录使用 |\CTEXtheXXX| 编号。
% \begin{macrocode}
\ctex_at_end_package:nn { titlesec }
{
%<*book|report>
\tl_set:Nn \ttl@chapterout { \typeout { \CTEXthechapter } }
%
\cs_if_free:NF \ttl@tocpart
{
\cs_set_protected:Npn \ttl@tocpart
{ \tl_set:Nn \ttl@a { \CTEXthepart \hspace { 1em } } }
}
\seq_map_inline:Nn \c_@@_headings_seq
{
\cs_if_exist:cF { ttl@toc #1 }
{
\cs_new_protected:cpx { ttl@toc #1 }
{
\tl_set:Nn \exp_not:N \ttl@a
{
\exp_not:N \protect
\exp_not:N \numberline { \exp_not:c { CTEXthe #1 } }
}
}
}
}
}
% \end{macrocode}
%
% \changes{v2.5.8}{2021/12/04}{兼容 \pkg{titlesec} 包和 \tn{CTEXifname}。}
% 在 \pkg{titlesec} 包定义的标题中更新 \tn{CTEXifname}。
% \begin{macrocode}
\ctex_at_end_package:nn { titlesec }
{
\ctex_patch_cmd:Nnn \ttl@labelling
{ \let \ifttl@toclabel \ifttl@label }
{
\let \ifttl@toclabel \ifttl@label
\CTEX@updatettlifname
}
\cs_new_protected:Npn \CTEX@updatettlifname
{ \legacy_if:nTF { ttl@label } { \CTEX@ifnametrue } { \CTEX@ifnamefalse } }
}
% \end{macrocode}
%
% \paragraph{兼容 \pkg{titleps} 宏包}
%
% \changes{v2.3}{2015/12/25}{兼容 \pkg{titleps} 宏包。}
%
% 按照 \pkg{titleps} 宏包的实现机制,|\CTEXtheXXX| 等宏直到页眉排版时才会被展开,
% 这可能会造成问题\footnote{\url{https://github.com/CTeX-org/ctex-kit/issues/217}}。
%
% \begin{macro}[int]{\ctex_titleps_hook:}
% 我们修改 \pkg{titleps} 包的内部命令 \tn{ttl@settopmark} 和 \tn{ttl@setsubmark},
% 将 |\CTEXtheXXX| 等加入更新队列中。
% \begin{macrocode}
\group_begin:
\char_set_catcode_other:N \#
\cs_new_protected:Npn \ctex_titleps_hook:
{
\ctex_patch_cmd:Nnn \ttl@settopmark
{ \protect \@namedef { the#1 } { \@nameuse { the#1 } } }
{
\protect \@namedef { the#1 } { \@nameuse { the#1 } }
\CTEX@titlepslabel@set {#1}
}
\ctex_patch_cmd:Nnn \ttl@setsubmark
{ \protect \@namedef { the#1 } { } }
{
\protect \@namedef { the#1 } { }
\CTEX@titlepslabel@clear {#1}
}
\ctex_patch_cmd:Nnn \ttl@setsubmark
{ \protect \@namedef { the#2 } { \@nameuse { the#2 } } }
{
\protect \@namedef { the#2 } { \@nameuse { the#2 } }
\CTEX@titlepslabel@set {#2}
}
}
\group_end:
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\CTEX@titlepslabel@set,\CTEX@titlepslabel@clear}
% 这两个函数要在随后被 \tn{xdef} 展开来获得 |\CTEXtheXXX| 的内容,不应该用
% \tn{protected} 来定义。
% \begin{macrocode}
\cs_new:Npn \CTEX@titlepslabel@set #1
{
\cs_if_free:cF { CTEXthe#1 }
{ \protect \@namedef { CTEXthe#1 } { \@nameuse { CTEXthe#1 } } }
}
\cs_new:Npn \CTEX@titlepslabel@clear #1
{
\cs_if_free:cF { CTEXthe#1 }
{ \protect \@namedef { CTEXthe#1 } { } }
}
% \end{macrocode}
% \end{macro}
%
% \pkg{titleps} 宏包的功能可以由 \pkg{titlesec} 的选项 \opt{pagestyles} 引入。
% \begin{macrocode}
\ctex_at_end_package:nn { titlesec }
{ \cs_if_free:NF \ttl@settopmark { \ctex_titleps_hook: } }
\ctex_at_end_package:nn { titleps } { \ctex_titleps_hook: }
% \end{macrocode}
%
% 除此之外,也可以使用 \pkg{titleps} 提供的命令 \tn{newtitlemark} 来完成:
% \begin{verbatim}
% \newtitlemark { \CTEXthechapter }
% \newtitlemark { \CTEXthesection }
% \end{verbatim}
% 但 \tn{newtitlemark} 不包含章节间的层次信息,功能上不及修改内部命令完整。
%
% \changes{v2.4.6}{2016/10/31}{重新初始化 \tn{ifthechapter} 等。}
% \begin{macro}[int]{\ttl@setifthe}
% 使 |\iftheXXX| 等命令在页眉设置中可用。
% \begin{macrocode}
\ctex_at_end_package:nn { titleps }
{
\cs_set_protected:Npn \ttl@setifthe #1
{
\exp_args:Nco \cs_set:Npn { ifthe #1 }
{
\CTEXifname
{ \protect \@firstoftwo }
{ \protect \@secondoftwo }
}
}
\seq_map_function:NN \c_@@_headings_seq \ttl@setifthe
}
% \end{macrocode}
% \end{macro}
%
% \subsubsection{目录标签的宽度}
%
% \begin{macro}{\CTEX@toc@width@n}
% \begin{macrocode}
\cs_new_protected:Npn \CTEX@toc@width@n #1
{
\hbox_set:Nn \l_@@_tmp_box {#1}
\dim_set:Nn \@tempdima
{
\dim_max:nn { \@tempdima }
{ \box_wd:N \l_@@_tmp_box + \f@size \p@ / 2 }
}
}
% \end{macrocode}
% \end{macro}
%
% \changes{v2.5}{2020/01/11}{兼容 \pkg{titletoc} 宏包。}
%
% \begin{macro}{\numberline,\@@_patch_toc_width:n}
% 为 \tn{numberline} 命令打补丁,并兼容 \pkg{tocloft} 和 \pkg{titletoc} 宏包。
%
% 这里需要替换 |#| 本身,因此需要先切换为 other 类。表示参数的 |#| 用
% \cs{c_parameter_token} 代替。
% \begin{macrocode}
\group_begin:
\char_set_catcode_other:N \#
\use:n
{
\group_end:
\ctex_preto_cmd:NnnTF \numberline { \ExplSyntaxOff }
{ \CTEX@toc@width@n {#1} }
{ }
{ \ctex_patch_failure:N \numberline }
\cs_new_protected:Npn \@@_patch_toc_width:n \c_parameter_token 1
{
\@ifpackageloaded { \c_parameter_token 1 }
{ }
{
\ctex_at_end_package:nn { \c_parameter_token 1 }
{
\ctex_preto_cmd:NnnTF \numberline
{ \char_set_catcode_letter:n { 64 } }
{ \CTEX@toc@width@n {#1} }
{ }
{ \ctex_patch_failure:N \numberline }
}
}
}
}
\@@_patch_toc_width:n { tocloft }
\@@_patch_toc_width:n { titletoc }
% \end{macrocode}
% \end{macro}
%
% \subsubsection{页眉信息的修改}
%
% \begin{macro}[int]{\ps@headings}
% \changes{v2.4.5}{2016/10/01}{修复补丁失败。}
% \changes{v2.4.7}{2016/12/23}{修复 \cls{ctexrep} 类的 \tn{chaptermark} 汉化错误。}
% \changes{v2.4.11}{2017/09/13}{补充页眉空格。}
% \begin{macrocode}
%<*article>
\legacy_if:nTF { @twoside }
{
\ctex_patch_cmd:Nnn \ps@headings
{ \ifnum \c@secnumdepth > \z@ \thesection \quad \fi }
{ \CTEXifname { \CTEXthesection \quad } { } }
\ctex_patch_cmd:Nnn \ps@headings
{ \ifnum \c@secnumdepth > \@ne \thesubsection \quad \fi }
{ \CTEXifname { \CTEXthesubsection \quad } { } }
}
% \end{macrocode}
% 不知为何,标准文档类此处对 \texttt{secnumdepth} 的判断为 $0$,与 \tn{section} 的层次 $1$ 不符。
% \begin{macrocode}
{
\ctex_patch_cmd:Nnn \ps@headings
{ \ifnum \c@secnumdepth > \m@ne \thesection \quad \fi }
{ \CTEXifname { \CTEXthesection \quad } { } }
}
%
%<*book|report>
\ctex_patch_cmd:Nnn \ps@headings
{
% \ifnum \c@secnumdepth > \m@ne \if@mainmatter
% \ifnum \c@secnumdepth > \m@ne
\@chapapp \ \thechapter . ~ \ %
% \fi
% \fi \fi
}
{ \CTEXifname { \CTEXthechapter \quad } { } }
\legacy_if:nT { @twoside }
{
\ctex_patch_cmd:Nnn \ps@headings
{ \ifnum \c@secnumdepth > \z@ \thesection . ~ \ \fi }
{ \CTEXifname { \CTEXthesection \quad } { } }
}
%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\f@nch@initialise}
% 这里对 \pkg{fancyhdr} 宏包打补丁。原来 \pkg{fancyhdr} 宏包中使用
% \tn{thesection} 等宏表示页眉中的章节编号,这里改用 \pkg{ctex} 包所用的
% \tn{CTEXthesection} 系列宏。
% \changes{v2.5.6}{2021/01/11}{更新 \pkg{fancyhdr} 宏包的补丁。}
% \begin{macrocode}
\ctex_at_end_package:nn { fancyhdr }
{
\ctex_patch_cmd:Nnn \f@nch@initialise
{ \ifnum \c@secnumdepth > \z@ \thesection \hskip 1em \relax \fi }
{ \CTEXifname { \CTEXthesection \quad } { } }
\ctex_patch_cmd:Nnn \f@nch@initialise
{ \ifnum \c@secnumdepth > \@ne \thesubsection \hskip 1em \relax \fi }
{ \CTEXifname { \CTEXthesubsection \quad } { } }
\ctex_patch_cmd:Nnn \f@nch@initialise
{ \ifnum \c@secnumdepth > \m@ne \@chapapp\ \thechapter . ~ \ \fi }
{ \CTEXifname { \CTEXthechapter \quad } { } }
\ctex_patch_cmd:Nnn \f@nch@initialise
{ \ifnum \c@secnumdepth > \z@ \thesection . ~ \ \fi }
{ \CTEXifname { \CTEXthesection \quad } { } }
\f@nch@initialise
% \end{macrocode}
% \pkg{fancyhdr} 的 \opt{headings} 选项会重定义 \tn{ps@headings},
% 这里也要打补丁。
% \begin{macrocode}
\@ifpackagewith { fancyhdr } { headings }
{
%<*article>
\legacy_if:nTF { @twoside }
{
\ctex_patch_cmd:Nnn \ps@headings
{ \ifnum \c@secnumdepth > \z@ \thesection \quad \fi }
{ \CTEXifname { \CTEXthesection \quad } { } }
\ctex_patch_cmd:Nnn \ps@headings
{ \ifnum \c@secnumdepth > \@ne \thesubsection \quad \fi }
{ \CTEXifname { \CTEXthesubsection \quad } { } }
}
{
\ctex_patch_cmd:Nnn \ps@headings
{ \ifnum \c@secnumdepth > \z@ \thesection \quad \fi }
{ \CTEXifname { \CTEXthesection \quad } { } }
}
%
%<*book|report>
\ctex_patch_cmd:Nnn \ps@headings
{
% \ifnum \c@secnumdepth > \m@ne \if@mainmatter
% \ifnum \c@secnumdepth > \m@ne
\@chapapp \ \thechapter . ~ \ %
% \fi
% \fi \fi
}
{ \CTEXifname { \CTEXthechapter \quad } { } }
\legacy_if:nT { @twoside }
{
\ctex_patch_cmd:Nnn \ps@headings
{ \ifnum \c@secnumdepth > \z@ \thesection . ~ \ \fi }
{ \CTEXifname { \CTEXthesection \quad } { } }
}
%
}
{ }
}
% \end{macrocode}
% \end{macro}
%
% \begin{macrocode}
%
% \end{macrocode}
%
% \subsubsection{\cls{beamer} 标题页模板的修改}
%
% \begin{macrocode}
%<*beamer>
% \end{macrocode}
%
% \begin{macrocode}
\ExplSyntaxOff
% \end{macrocode}
%
% \changes{v2.4.15}{2019/01/29}{局部指定 \opt{autoindent} 为 \opt{false},并交换
% \tn{CTEX@XXX@indent} 与 \tn{CTEX@XXX@format} 的顺序。}
%
% 对应 \tn{partpage}。
% \begin{macrocode}
\defbeamertemplate*{part page}{CTEX}[1][]{%
\begingroup
% \centering
% {\usebeamerfont{part name}%
% \usebeamercolor[fg]{part name}\partname~\insertromanpartnumber}
% \vskip1em\par
\par \addvspace{\glueexpr\CTEX@part@beforeskip\relax}%
\CTEX@heading@format@initial
\CTEX@part@format{%
\CTEX@indentbox{\CTEX@part@indent}%
\ifodd \CTEX@part@numbering
\CTEX@partname \CTEX@part@aftername
\fi
\begin{beamercolorbox}[sep=16pt,center,#1]{part title}
% \usebeamerfont{part title}\insertpart\par
\CTEX@part@titleformat \insertpart \CTEX@part@aftertitle
\end{beamercolorbox}}%
\par \addvspace{\glueexpr\CTEX@part@afterskip\relax}%
\endgroup}
% \end{macrocode}
%
% 对应 \tn{sectionpage}。
% \begin{macrocode}
\defbeamertemplate*{section page}{CTEX}[1][]{%
\begingroup
% \centering
% {\usebeamerfont{section name}%
% \usebeamercolor[fg]{section name}\sectionname~\insertsectionnumber}
% \vskip1em\par
\par \addvspace{\glueexpr\CTEX@section@beforeskip\relax}%
\CTEX@heading@format@initial
\CTEX@section@format{%
\CTEX@indentbox{\CTEX@section@indent}%
\ifodd \CTEX@section@numbering
\CTEX@sectionname \CTEX@section@aftername
\fi
\begin{beamercolorbox}[sep=12pt,center,#1]{part title}
% \usebeamerfont{section title}\insertsection\par
\CTEX@section@titleformat \insertsection \CTEX@section@aftertitle
\end{beamercolorbox}}%
\par \addvspace{\glueexpr\CTEX@section@afterskip\relax}%
\endgroup}
% \end{macrocode}
%
% 对应 \tn{subsectionpage}。
% \begin{macrocode}
\defbeamertemplate*{subsection page}{CTEX}[1][]{%
\begingroup
% \centering
% {\usebeamerfont{subsection name}%
% \usebeamercolor[fg]{subsection name}\subsectionname~\insertsubsectionnumber}
% \vskip1em\par
\par \addvspace{\glueexpr\CTEX@subsection@beforeskip\relax}%
\CTEX@heading@format@initial
\CTEX@subsection@format{%
\CTEX@indentbox{\CTEX@subsection@indent}%
\ifodd \CTEX@subsection@numbering
\CTEX@subsectionname \CTEX@subsection@aftername
\fi
\begin{beamercolorbox}[sep=8pt,center,#1]{part title}
% \usebeamerfont{subsection title}\insertsubsection\par
\CTEX@subsection@titleformat \insertsubsection \CTEX@subsection@aftertitle
\end{beamercolorbox}}%
\par \addvspace{\glueexpr\CTEX@subsection@afterskip\relax}%
\endgroup}
% \end{macrocode}
%
% 将 \cls{beamer} 的默认模板重定向为 \texttt{CTEX} 模板。
% \begin{macrocode}
\defbeamertemplatealias{part page}{default}{CTEX}
\defbeamertemplatealias{section page}{default}{CTEX}
\defbeamertemplatealias{subsection page}{default}{CTEX}
% \end{macrocode}
%
% \begin{macrocode}
\ExplSyntaxOn
% \end{macrocode}
%
% \begin{macrocode}
%
% \end{macrocode}
%
% \subsubsection{标题编号和目录的层次设置}
%
% \changes{v2.5.2}{2020/05/06}{新增标题选项 \opt{secnumdepth} 和 \opt{tocdepth}。}
%
% \begin{macro}{secnumdepth, tocdepth}
% \opt{secnumdepth} 在 \cls{beamer} 下无意义。
% \begin{macrocode}
\ctex_define:n
{
%<*!beamer>
secnumdepth .code:n = \ctex_heading_depth:ne { secnumdepth } {#1} ,
secnumdepth .value_required:n = true ,
%!beamer>
tocdepth .code:n = \ctex_heading_depth:ne { tocdepth } {#1} ,
tocdepth .value_required:n = true
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\ctex_heading_depth:nn}
% 注意此处 \tn{setcounter} 的赋值是全局的。
% \begin{macrocode}
\cs_new_protected:Npn \ctex_heading_depth:nn #1#2
{
\prop_get:NnNTF \c_@@_heading_level_prop {#2} \l_@@_tmp_tl
{ \setcounter {#1} { \l_@@_tmp_tl } }
{ \setcounter {#1} { \int_eval:n {#2} } }
}
\cs_generate_variant:Nn \ctex_heading_depth:nn { ne }
% \end{macrocode}
% \end{macro}
%
% \begin{variable}[int]{\c_@@_heading_level_prop}
% 章节层次与名称的对应表。
% \begin{macrocode}
\prop_const_from_keyval:Nn \c_@@_heading_level_prop
{
%<*article|beamer>
part = 0 ,
%
%<*book|report>
part = -1 ,
chapter = 0 ,
%
section = 1 ,
subsection = 2 ,
subsubsection = 3 ,
paragraph = 4 ,
subparagraph = 5
}
% \end{macrocode}
% \end{variable}
%
% \subsubsection{标签引用数字的汉化}
%
% \begin{macro}[int]{\refstepcounter}
% 对标题进行引用时,设置标签为通过 \opt{number} 选项设置的形式。
% \begin{macrocode}
\cs_new_protected:Npn \CTEX@setcurrentlabel@n #1
{
\protected@edef \@currentlabel
{
\cs_if_exist:cTF { CTEX@the#1 }
{ \exp_args:cc { p@#1 } { CTEX@the#1 } }
{ \exp_not:o { \@currentlabel } }
}
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\ctex_varioref_hook:}
% 关于标签引用的宏包可能会修改 \tn{refstepcounter}。其中 \pkg{cleveref} 和
% \pkg{hyperref} 宏包都会保存之前的定义,并且它们都要求尽可能晚的被载入,所以
% 对我们上述的修改影响不大。需要注意的是 \pkg{varioref} 宏包,如果它在
% \CTeX{} 之后被载入,我们之前的修改将会被覆盖。
% 较新版 \LaTeX \ 内核已经包含 \tn{labelformat},可以直接使用。
% \begin{macrocode}
\cs_new_protected:Npn \ctex_varioref_hook:
{
\seq_map_inline:Nn \c_@@_headings_seq
{ \ctex_fix_varioref_label:n { ##1 } }
\ctex_at_end_package:nn { cleveref } { \ctex_cleveref_hook: }
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ctex_fix_varioref_label:n}
% \pkg{varioref} 宏包的 \tn{labelformat} 实际上是定义一个以 |\the<#1>| 为参数的宏
% |\p@<#1>|。\LaTeX{} 在定义计数器 |<#1>| 时,都会将 |\p@<#1>| 初始化为 \tn{@empty}。
% 如果这个宏非空,说明用户自定义了标签格式,我们就不再修改。这里不能使用
% \cs{exp_args:Nnc},因为 \texttt{c} 这种展开格式不会将参数放在花括号内。而
% \tn{labelformat} 的定义是
% \begin{verbatim}
% \def\labelformat#1{\expandafter\def\csname p@#1\endcsname##1}
% \end{verbatim}
% 它的第二个参数必须放在花括号内,否则将会被作为宏的定界符号。
% \begin{macrocode}
\cs_new_protected:Npn \ctex_fix_varioref_label:n #1
{
\tl_if_empty:cT { p@#1 }
{ \exp_args:Nne \labelformat {#1} { \exp_not:c { CTEX@the#1 } } }
}
% \end{macrocode}
% \end{macro}
%
% \changes{v2.5.3}{2020/06/04}{兼容 \pkg{cleveref}。}
% \changes{v2.5.4}{2020/06/17}{同时兼容 \pkg{cleveref} 和 \pkg{hyperref}。}
% \changes{v2.5.7}{2021/06/04}{同时兼容 \pkg{cleveref} 和 \cls{beamer}。}
%
% \begin{macro}{patch/cleveref}
% \pkg{cleveref} 宏包长期未维护,与较新的 \LaTeX{} 内核和 \pkg{hyperref}
% 存在兼容问题。\CTeX{} 提供了对 \pkg{cleveref} 的补丁,但用户也可以选择
% 关闭它。
%
% 当同时使用 \pkg{hyperref} 和 \pkg{cleveref} 时,|\appendix| 之后的交叉引用
% 类型可能不正确(例如,\texttt{appendix} 退化为 \texttt{chapter})。
% 这是上游 \LaTeX{} 内核 \texttt{firstaid} 对 \pkg{cleveref} 补丁不完整所致,
% 与 \CTeX{} 无关。可以使用以下方法规避:
% \begin{verbatim}
% \AddToHook{cmd/appendix/before}{%
% \crefalias{chapter}{appendix}%
% \crefalias{section}{subappendix}%
% \crefalias{subsection}{subsubappendix}%
% \crefalias{subsubsection}{subsubsubappendix}%
% }
% \end{verbatim}
% \begin{macrocode}
\ctex_define:n
{
patch / cleveref .bool_set:N = \l_@@_patch_cleveref_bool ,
patch / cleveref .initial:n = true
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ctex_cleveref_hook:,\@@_cleveref_hook_aux:N}
% 需要将\pkg{cleveref} 包对应命令中 |\p@|\meta{counter} 的参数及时展开,以兼容 \tn{labelformat}。
% \begin{macrocode}
\cs_new_protected:Npn \ctex_cleveref_hook:
{
\bool_if:NT \l_@@_patch_cleveref_bool
{
\@ifpackageloaded { hyperref }
{
\@ifpackagewith { hyperref } { implicit = false }
{ }
{ \@@_cleveref_hook_aux:N \H@refstepcounter }
}
{
\@@_cleveref_hook_aux:N \refstepcounter@noarg
\@@_cleveref_hook_aux:N \refstepcounter@optarg
}
\@@_cleveref_hook_aux:N \appendix
}
}
\cs_new_protected:Npn \@@_cleveref_hook_aux:N #1
{
\ctex_patch_cmd_all:NnnnTF #1
{
\ExplSyntaxOff
\char_set_catcode_letter:n { 64 }
}
{ \endcsname \csname the }
{ \expandafter \endcsname \csname the }
{ }
{ \ctex_patch_failure:N #1 }
}
% \end{macrocode}
% \end{macro}
%
% \changes{v2.5}{2020/04/19}{应用新内核中的 \tn{labelformat}。}
%
% 如果 \pkg{varioref} 已经被载入,则使用它来设置。
% \begin{macrocode}
\cs_if_exist:NTF \labelformat
{ \ctex_varioref_hook: }
{
\cs_new_eq:NN \CTEX@save@refstepcounter \refstepcounter
\RenewDocumentCommand \refstepcounter { m }
{
\CTEX@save@refstepcounter {#1}
\CTEX@setcurrentlabel@n {#1}
}
\ctex_at_end_package:nn { varioref } { \ctex_varioref_hook: }
}
% \end{macrocode}
%
% \subsubsection{载入 \meta{scheme} 文件}
%
% \begin{macrocode}
\ctex_scheme_input:o { \l_@@_scheme_tl }
% \end{macrocode}
%
% \begin{macrocode}
%
% \end{macrocode}
%
% \subsubsection{\texttt{ctex.sty} 的 \opt{heading} 选项}
%
% \begin{macrocode}
%<*ctex|ctexheading>
% \end{macrocode}
%
% \begin{variable}{\c_@@_std_class_tl}
% 用于记录被引入的标准文档类。
% \begin{macrocode}
\clist_map_inline:nn { article , book , report , beamer }
{
\@ifclassloaded {#1}
{ \clist_map_break:n { \tl_const:Nn \c_@@_std_class_tl {#1} } }
{ }
}
% \end{macrocode}
% \end{variable}
%
% 若标准文档类被引入,则载入对应的标题定义文件。否则视 \tn{chapter} 是否有定义来
% 引入 \cls{book} 或者 \cls{article}。
% \begin{macrocode}
\msg_new:nnn { ctex } { not-standard-class }
{
None~of~the~standard~document~classes~was~loaded.\\
Heading~`#1'~is~selected.\\
ctex~may~not~work~as~expected.
}
%\bool_if:NTF \l_@@_heading_bool
%\use:n
{
\tl_if_exist:NTF \c_@@_std_class_tl
{ \cs_new_eq:NN \c_@@_class_tl \c_@@_std_class_tl }
{
\cs_if_exist:NTF \chapter
{
\cs_if_exist:NF \if@mainmatter
{ \cs_new_eq:NN \if@mainmatter \tex_iftrue:D }
\tl_const:Nn \c_@@_class_tl { book }
}
{ \tl_const:Nn \c_@@_class_tl { article } }
\msg_warning:nne { ctex } { not-standard-class } { \c_@@_class_tl }
}
\ctex_file_input:n { ctex-heading- \c_@@_class_tl .def }
}
% { \ctex_scheme_input:o { \l_@@_scheme_tl } }
% \end{macrocode}
%
% \begin{macrocode}
%
% \end{macrocode}
%
% \subsection{中文字号}
%
% \begin{macrocode}
%<*class|ctex|ctexsize>
% \end{macrocode}
%
% \changes{v2.0}{2014/03/08}{将中文字号功能提取到可以独立使用的 \pkg{ctexsize}。}
%
% \begin{macro}{\zihao}
% \begin{macrocode}
\NewDocumentCommand \zihao { m }
{ \exp_args:Ne \ctex_zihao:n {#1} \tex_ignorespaces:D }
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\ctex_zihao:n}
% \begin{macrocode}
\cs_new_protected:Npn \ctex_zihao:n #1
{
\prop_get:NnNTF \c_@@_font_size_prop {#1} \l_@@_font_size_tl
{ \exp_after:wN \fontsize \l_@@_font_size_tl \selectfont }
{ \msg_error:nnn { ctex } { fontsize } {#1} }
}
\msg_new:nnnn { ctex } { fontsize }
{ Undefined~Chinese~font~size~`#1'~in~command~\token_to_str:N \zihao.}
{
The~old~font~size~is~used~if~you~continue.\\
The~available~font~sizes~are~listed~as~follow.\\
\seq_use:Nnnn \c_@@_font_size_seq { ~and~ } { ,~ } { ,~and~ }.
}
% \end{macrocode}
% \end{macro}
%
% \subsubsection{定义中文字号}
%
% \changes{v2.0}{2014/03/08}{中文字号不再采用近似值。}
%
% \begin{variable}{\c_@@_font_size_prop}
% \begin{macro}{\@@_save_font_size:nn}
% \begin{macro}[int]{\ctex_save_font_size:nn}
% 基础行距是字号的 $1.2$ 倍,采用 \hologo{eTeX} 的 scaling 运算得到的结果
% 要比简单的 |1.2\dimexpr| 精确^^A
% \footnote{\url{http://thread.gmane.org/gmane.comp.tex.latex.latex3/3190}}。
% \begin{macrocode}
\prop_new:N \l_@@_font_size_temp_prop
\seq_new:N \l_@@_font_size_temp_seq
\cs_new_protected:Npn \@@_save_font_size:nn #1#2
{
\prop_put:Nne \l_@@_font_size_temp_prop {#1}
{
{ \dim_to_decimal:n {#2} }
{ \dim_to_decimal:n { (#2) * 6 / 5 } }
}
\seq_put_right:Nn \l_@@_font_size_temp_seq {#1}
}
\cs_new_eq:NN \ctex_save_font_size:nn \@@_save_font_size:nn
\group_begin:
\prop_clear:N \l_@@_font_size_temp_prop
\seq_clear:N \l_@@_font_size_temp_seq
\str_case:onF { \g_@@_font_size_system_tl }
{
{ word }
{
\clist_map_inline:nn
{
{ 8 } { 5 bp } ,
{ 7 } { 5.5 bp } ,
{ -6 } { 6.5 bp } ,
{ 6 } { 7.5 bp } ,
{ -5 } { 9 bp } ,
{ 5 } { 10.5 bp } ,
{ -4 } { 12 bp } ,
{ 4 } { 14 bp } ,
{ -3 } { 15 bp } ,
{ 3 } { 16 bp } ,
{ -2 } { 18 bp } ,
{ 2 } { 22 bp } ,
{ -1 } { 24 bp } ,
{ 1 } { 26 bp } ,
{ -0 } { 36 bp } ,
{ 0 } { 42 bp }
}
{ \@@_save_font_size:nn #1 }
}
{ letterpress }
{
\clist_map_inline:nn
{
{ 8 } { 4 bp } ,
{ 7 } { 5.25 bp } ,
{ -6 } { 7.5 bp } ,
{ 6 } { 8 bp } ,
{ -5 } { 9 bp } ,
{ 5 } { 10.5 bp } ,
{ -4 } { 12 bp } ,
{ 4 } { 14 bp } ,
{ -3 } { 15 bp } ,
{ 3 } { 16 bp } ,
{ -2 } { 18 bp } ,
{ 2 } { 21 bp } ,
{ -1 } { 24 bp } ,
{ 1 } { 28 bp } ,
{ -0 } { 36 bp } ,
{ 0 } { 42 bp }
}
{ \@@_save_font_size:nn #1 }
}
}
{
\file_if_exist:nTF { ctex-fontsize- \g_@@_font_size_system_tl .def }
{
\ctex_file_input:n
{ ctex-fontsize- \g_@@_font_size_system_tl .def }
}
{
\msg_error:nne { ctex } { fontsize-system-not-found }
{ \g_@@_font_size_system_tl }
\clist_map_inline:nn
{
{ 8 } { 5 bp } ,
{ 7 } { 5.5 bp } ,
{ -6 } { 6.5 bp } ,
{ 6 } { 7.5 bp } ,
{ -5 } { 9 bp } ,
{ 5 } { 10.5 bp } ,
{ -4 } { 12 bp } ,
{ 4 } { 14 bp } ,
{ -3 } { 15 bp } ,
{ 3 } { 16 bp } ,
{ -2 } { 18 bp } ,
{ 2 } { 22 bp } ,
{ -1 } { 24 bp } ,
{ 1 } { 26 bp } ,
{ -0 } { 36 bp } ,
{ 0 } { 42 bp }
}
{ \@@_save_font_size:nn #1 }
}
}
\exp_args:NNe \prop_const_from_keyval:Nn \c_@@_font_size_prop
{ \prop_to_keyval:N \l_@@_font_size_temp_prop }
\exp_args:NNe \seq_const_from_clist:Nn \c_@@_font_size_seq
{ \seq_use:Nn \l_@@_font_size_temp_seq { , } }
\group_end:
\msg_new:nnnn { ctex } { fontsize-system-not-found }
{
CTeX~font~size~system~`#1'~could~not~be~found.
\\ The~`word'~system~will~be~used~instead.
}
{ You~may~need~to~create~`ctex-fontsize-#1.def'. }
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{variable}
%
% \begin{macro}[int]{\ctex_declare_math_sizes:nnnn}
% \begin{macrocode}
\cs_new_protected:Npn \ctex_declare_math_sizes:nnnn #1#2#3#4
{
\@@_get_font_sizes:Nn \l_@@_font_size_tl { {#1} {#2} {#3} {#4} }
\exp_after:wN \DeclareMathSizes \l_@@_font_size_tl
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_get_font_sizes:Nn}
% \begin{macrocode}
\cs_new_protected:Npn \@@_get_font_sizes:Nn #1#2
{
\tl_clear:N #1
\tl_map_inline:nn {#2}
{
\prop_get:NnNTF \c_@@_font_size_prop {##1} \l_@@_tmp_tl
{ \tl_put_right:Ne #1 { { \tl_head:N \l_@@_tmp_tl } } }
{ \tl_put_right:Ne #1 { { \dim_to_decimal:n { ##1 } } } }
}
}
% \end{macrocode}
% \end{macro}
%
% \begin{macrocode}
\clist_map_inline:nn
{
{ 8 }{ 8 }{ 5pt }{ 5pt } ,
{ 7 }{ 7 }{ 5pt }{ 5pt } ,
{ -6 }{ -6 }{ 5pt }{ 5pt } ,
{ 6 }{ 6 }{ 5pt }{ 5pt } ,
{ -5 }{ -5 }{ 6pt }{ 5pt } ,
{ 5 }{ 5 }{ 7pt }{ 5pt } ,
{ -4 }{ -4 }{ 8pt }{ 6pt } ,
{ 4 }{ 4 }{ 5 }{ 6 } ,
{ -3 }{ -3 }{ -4 }{ -5 } ,
{ 3 }{ 3 }{ 4 }{ 5 } ,
{ -2 }{ -2 }{ -3 }{ -4 } ,
{ 2 }{ 2 }{ 3 }{ 4 } ,
{ -1 }{ -1 }{ -2 }{ -3 } ,
{ 1 }{ 1 }{ 2 }{ 3 } ,
{ -0 }{ -0 }{ -1 }{ -2 } ,
{ 0 }{ 0 }{ 1 }{ 2 }
}
{ \ctex_declare_math_sizes:nnnn #1 }
% \end{macrocode}
%
% \subsubsection{修改默认字号大小}
%
% \begin{macro}[int]{\ctex_set_font_size:Nnn}
% \begin{macrocode}
\cs_new_protected:Npn \ctex_set_font_size:Nnn #1#2#3
{
\prop_get:NnNTF \c_@@_font_size_prop {#2} \l_@@_font_size_tl
{ \exp_after:wN \@@_set_font_size:nnNn \l_@@_font_size_tl #1 {#3} }
{ \msg_error:nnn { ctex } { fontsize } {#2} }
}
\cs_new_protected:Npn \@@_set_font_size:nnNn #1#2#3#4
{ \cs_set_protected:Npn #3 { \@setfontsize #3 {#1} {#2} #4 } }
% \end{macrocode}
% \end{macro}
%
% \begin{macrocode}
\int_case:nn { \g_@@_font_size_int }
{
{ 0 } { \file_input:n { ctex-c5size.clo } }
{ 1 } { \file_input:n { ctex-cs4size.clo } }
}
% \end{macrocode}
%
% \begin{macrocode}
%
% \end{macrocode}
%
% \begin{macrocode}
%<*c5size>
\ctex_set_font_size:Nnn \normalsize { 5 }
{
\abovedisplayskip 10\p@ \@plus2\p@ \@minus5\p@
\abovedisplayshortskip \z@ \@plus3\p@
\belowdisplayshortskip 6\p@ \@plus3\p@ \@minus3\p@
\belowdisplayskip \abovedisplayskip
\let\@listi\@listI
}
\ctex_set_font_size:Nnn \small { -5 }
{
\abovedisplayskip 8.5\p@ \@plus3\p@ \@minus4\p@
\abovedisplayshortskip \z@ \@plus2\p@
\belowdisplayshortskip 4\p@ \@plus2\p@ \@minus2\p@
\def\@listi{\leftmargin\leftmargini
\topsep 4\p@ \@plus2\p@ \@minus2\p@
\parsep 2\p@ \@plus\p@ \@minus\p@
\itemsep \parsep}
\belowdisplayskip \abovedisplayskip
}
\ctex_set_font_size:Nnn \footnotesize { 6 }
{
\abovedisplayskip 6\p@ \@plus2\p@ \@minus4\p@
\abovedisplayshortskip \z@ \@plus\p@
\belowdisplayshortskip 3\p@ \@plus\p@ \@minus2\p@
\def\@listi{\leftmargin\leftmargini
\topsep 3\p@ \@plus\p@ \@minus\p@
\parsep 2\p@ \@plus\p@ \@minus\p@
\itemsep \parsep}
\belowdisplayskip \abovedisplayskip
}
\ctex_set_font_size:Nnn \scriptsize { -6 } { }
\ctex_set_font_size:Nnn \tiny { 7 } { }
\ctex_set_font_size:Nnn \large { -4 } { }
\ctex_set_font_size:Nnn \Large { -3 } { }
\ctex_set_font_size:Nnn \LARGE { -2 } { }
\ctex_set_font_size:Nnn \huge { 2 } { }
\ctex_set_font_size:Nnn \Huge { 1 } { }
%
%<*cs4size>
\ctex_set_font_size:Nnn \normalsize { -4 }
{
\abovedisplayskip 12\p@ \@plus3\p@ \@minus7\p@
\abovedisplayshortskip \z@ \@plus3\p@
\belowdisplayshortskip 6.5\p@ \@plus3.5\p@ \@minus3\p@
\belowdisplayskip \abovedisplayskip
\let\@listi\@listI
}
\ctex_set_font_size:Nnn \small { 5 }
{
\abovedisplayskip 11\p@ \@plus3\p@ \@minus6\p@
\abovedisplayshortskip \z@ \@plus3\p@
\belowdisplayshortskip 6.5\p@ \@plus3.5\p@ \@minus3\p@
\def\@listi{\leftmargin\leftmargini
\topsep 9\p@ \@plus3\p@ \@minus5\p@
\parsep 4.5\p@ \@plus2\p@ \@minus\p@
\itemsep \parsep}
\belowdisplayskip \abovedisplayskip
}
\ctex_set_font_size:Nnn \footnotesize { -5 }
{
\abovedisplayskip 10\p@ \@plus2\p@ \@minus5\p@
\abovedisplayshortskip \z@ \@plus3\p@
\belowdisplayshortskip 6\p@ \@plus3\p@ \@minus3\p@
\def\@listi{\leftmargin\leftmargini
\topsep 6\p@ \@plus2\p@ \@minus2\p@
\parsep 3\p@ \@plus2\p@ \@minus\p@
\itemsep \parsep}
\belowdisplayskip \abovedisplayskip
}
\ctex_set_font_size:Nnn \scriptsize { 6 } { }
\ctex_set_font_size:Nnn \tiny { -6 } { }
\ctex_set_font_size:Nnn \large { -3 } { }
\ctex_set_font_size:Nnn \Large { -2 } { }
\ctex_set_font_size:Nnn \LARGE { 2 } { }
\ctex_set_font_size:Nnn \huge { -1 } { }
\ctex_set_font_size:Nnn \Huge { 1 } { }
%
% \end{macrocode}
%
% \begin{macrocode}
%\normalsize
% \end{macrocode}
%
% \begin{macrocode}
%<*class|ctex>
% \end{macrocode}
%
% \subsection{更新行距}
%
% \cs{l_@@_line_spread_fp} 被设置了才有必要更新行距和 \tn{footnotesep}。
% \begin{macrocode}
\fp_if_nan:nF { \l_@@_line_spread_fp }
{
\exp_args:Ne \linespread { \fp_use:N \l_@@_line_spread_fp }
% \end{macrocode}
%
% \changes{v2.0}{2014/04/23}{调整 \tn{footnotesep} 的大小,以适合行距的变化。}
%
% \begin{variable}[int]{\footnotesep}
% 我们调整了行距,可能导致脚注的间距与行距不协调,需要调整 \tn{footnotesep}。标准
% 文档类对 \tn{footnotesep} 的设置是,字体大小为 \tn{footnotesize} 时 \tn{strutbox}
% 的高度(默认值是 |.7\baselineskip|)。我们沿用这个设置方法,只需要更新具体的大小。
% \begin{macrocode}
\group_begin: \footnotesize \exp_args:NNNo \group_end:
\dim_set:Nn \footnotesep { \dim_use:N \box_ht:N \strutbox }
}
% \end{macrocode}
% \end{variable}
%
% 激活默认字体大小,更新行距、\tn{parindent} 和 \tn{CJKglue}。
% \begin{macrocode}
\normalsize
% \end{macrocode}
%
% \subsection{其他功能}
%
% \begin{macro}{\CTeX}
% \changes{v2.4.12}{2017/12/05}{不依赖 \tn{ifincsname}。}
% \file{ctex-faq.sty} 中的定义是
% \begin{verbatim}
% \DeclareRobustCommand\CTeX{$\mathbb{C}$\kern-.05em\TeX}
% \end{verbatim}
% 然而 \tn{mathbb} 未必有定义,这里就不采用它了,只定义最简单的形式。
% \CTeX{} 可以直接用在 PDF 书签中。
% \begin{macrocode}
\NewDocumentCommand \CTeX { }
{ C \TeX }
\ctex_at_end_package:nn { hyperref }
{ \pdfstringdefDisableCommands { \tl_set:Nn \CTeX { CTeX } } }
% \end{macrocode}
% \end{macro}
%
% \changes{v2.0}{2014/03/28}{\opt{captiondelimiter} 是过时选项。}
% \begin{macro}{captiondelimiter}
% 过时选项。
% \begin{macrocode}
\ctex_define:n
{
captiondelimiter .code:n =
{
\ctex_deprecated_option:n
{ You~can~load~the~package~`caption'~to~get~its~functionality. }
}
}
% \end{macrocode}
% \end{macro}
%
% \changes{v2.0}{2014/03/09}
% {解决 \pkg{etoolbox} 与 \pkg{breqn} 关于 \tn{end} 的冲突。}
% \changes{v2.2}{2015/06/23}{删去 \pkg{etoolbox} 与 \pkg{breqn} 的兼容补丁。}
%
% \subsection{载入中文字库}
%
% \begin{macro}[int]{\ctex_fontset_error:n}
% 字库不可用时给出紧急错误信息,停止读取定义文件。
% \begin{macrocode}
\cs_new_protected:Npn \ctex_fontset_error:n #1
{ \msg_critical:nnn { ctex } { fontset-unavailable } {#1} }
\msg_new:nnn { ctex } { fontset-unavailable }
{ CTeX~fontset~`#1'~is~unavailable~in~current~mode. }
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\ctex_fontset_case:nnn}
% $3$ 个参数依次为 \pdfTeX、\upTeX\ 和 \XeTeX/\LuaTeX。
% \begin{macrocode}
\cs_new:Npx \ctex_fontset_case:nnn #1#2#3
{
\sys_if_engine_pdftex:TF
{#1}
{ \sys_if_engine_uptex:TF {#2} {#3} }
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\ctex_fontset_case:nnnn}
% $4$ 个参数依次为 \pdfTeX(生成 PDF)、\pdfTeX(生成 DVI)、\upTeX 和
% \XeTeX/\LuaTeX。
% \begin{macrocode}
\cs_new:Npx \ctex_fontset_case:nnnn #1#2#3#4
{
\sys_if_engine_pdftex:TF
{ \sys_if_output_pdf:TF {#1} {#2} }
{ \sys_if_engine_uptex:TF {#3} {#4} }
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\ctex_detect_platform:}
% 根据操作系统判断默认字体配置。
% \begin{macrocode}
\cs_new_protected:Npn \ctex_detect_platform:
{
\sys_if_platform_windows:TF
{ \tl_gset:Nn \g_@@_fontset_tl { windows } }
{
\ctex_if_platform_macos:TF
{ \tl_gset:Nn \g_@@_fontset_tl { mac } }
{ \tl_gset:Nn \g_@@_fontset_tl { fandol } }
}
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\ctex_if_platform_macos:TF}
% \changes{v2.1}{2015/06/17}{改用 \file{/Library/Fonts/Songti.ttc} 为特征文件。}
% \changes{v2.5}{2019/10/25}{改用 \file{/System/Library/Fonts/Menlo.ttc}
% 为特征文件。}
% 以特定字体判断 macOS 系统。
% \begin{macrocode}
\cs_new_protected:Npn \ctex_if_platform_macos:TF
{ \file_if_exist:nTF { /System/Library/Fonts/Menlo.ttc } }
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\ctex_load_fontset:}
% 如果用户没有指定字体,则探测操作系统,载入相应的字体配置。
% \begin{macrocode}
\cs_new_protected:Npn \ctex_load_fontset:
{
\tl_if_empty:NTF \g_@@_fontset_tl
{ \ctex_detect_platform: }
{
\bool_lazy_or:nnTF
{ \str_if_eq_p:on { \g_@@_fontset_tl } { windowsnew } }
{ \str_if_eq_p:on { \g_@@_fontset_tl } { windowsold } }
{
\msg_warning:nnee { ctex } { deprecated-fontset }
{ \g_@@_fontset_tl } { windows }
\tl_gset:Nn \g_@@_fontset_tl { windows }
}
{
\file_if_exist:nF { ctex-fontset- \g_@@_fontset_tl .def }
{
\use:e
{
\ctex_detect_platform:
\msg_error:nnee { ctex } { fontset-not-found }
{ \g_@@_fontset_tl } { \exp_not:N \g_@@_fontset_tl }
}
}
}
}
\ctex_file_input:n { ctex-fontset- \g_@@_fontset_tl .def }
}
\msg_new:nnn { ctex } { deprecated-fontset }
{ CTeX~fontset~`#1'~is~deprecated.\\ Fontset~`#2'~will~be~used~instead. }
\msg_new:nnnn { ctex } { fontset-not-found }
{ CTeX~fontset~`#1'~could~not~be~found.\\ Fontset~`#2'~will~be~used~instead. }
{ You~may~run~`mktexlsr'~firstly. }
\@onlypreamble \ctex_load_fontset:
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{fontset}
% 在导言区通过 \tn{ctexset} 载入中文字库的选项。
% \begin{macrocode}
\ctex_define:n
{
fontset .code:n =
{
\ctex_if_preamble:TF
{
\str_if_eq:eeTF {#1} { none }
{ \msg_warning:nnn { ctex } { invalid-value } {#1} }
{
\str_if_eq:onTF { \g_@@_fontset_tl } { none }
{
\tl_gset:Ne \g_@@_fontset_tl {#1}
\ctex_load_fontset:
}
{
\msg_error:nnee { ctex } { fontset-loaded }
{ \g_@@_fontset_tl } {#1}
}
}
}
{ \msg_error:nn { ctex } { fontset-only-preamble } }
}
}
\msg_new:nnnn { ctex } { fontset-loaded }
{
CTeX~fontset~`#1'~has~been~loaded.
\str_if_eq:nnF {#1} {#2} { \\ Fontset~`#2'~will~be~ignored. }
}
{ Only~one~fontset~can~be~loaded~in~the~preamble. }
\msg_new:nnn { ctex } { fontset-only-preamble }
{ The~`fontset'~option~can~be~used~only~in~preamble. }
% \end{macrocode}
% \end{macro}
%
% 载入中文字库。
% \begin{macrocode}
\str_if_eq:onF { \g_@@_fontset_tl } { none }
{ \ctex_load_fontset: }
% \end{macrocode}
%
% \subsection{宏包配置文件}
%
% \subsubsection{\texttt{ctex.cfg}}
%
% \begin{macrocode}
\ctex_at_end:n { \ctex_file_input:n { ctex.cfg } }
% \end{macrocode}
%
% \begin{macrocode}
%
% \end{macrocode}
%
% \begin{macrocode}
%<@@=>
% \end{macrocode}
%
% \end{implementation}