summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2022-07-28 20:11:42 +0000
committerKarl Berry <karl@freefriends.org>2022-07-28 20:11:42 +0000
commitb237c781052da2153e8e120f0e69909e54dad584 (patch)
treecb85963094b12969a2caeb82cc4688abc9028405 /Master/texmf-dist/tex/latex
parentc617f3c41b0840c82ed1f943d62a60cdadb9b2e5 (diff)
exam-zh (28jul22)
git-svn-id: svn://tug.org/texlive/trunk@63995 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex')
-rw-r--r--Master/texmf-dist/tex/latex/exam-zh/exam-zh-chinese-english.sty665
-rw-r--r--Master/texmf-dist/tex/latex/exam-zh/exam-zh-choices.sty555
-rw-r--r--Master/texmf-dist/tex/latex/exam-zh/exam-zh-font.sty580
-rw-r--r--Master/texmf-dist/tex/latex/exam-zh/exam-zh-question.sty1260
-rw-r--r--Master/texmf-dist/tex/latex/exam-zh/exam-zh-symbols.sty1198
-rw-r--r--Master/texmf-dist/tex/latex/exam-zh/exam-zh.cls2214
6 files changed, 6472 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/exam-zh/exam-zh-chinese-english.sty b/Master/texmf-dist/tex/latex/exam-zh/exam-zh-chinese-english.sty
new file mode 100644
index 00000000000..b27dfab271e
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/exam-zh/exam-zh-chinese-english.sty
@@ -0,0 +1,665 @@
+%
+% Copyright (c) 2022 Kangwei Xia, Lijun Guo
+% Released under the LaTeX Project Public License v1.3c License.
+% Repository: https://gitee.com/zepinglee/exam-zh
+%
+
+\NeedsTeXFormat{LaTeX2e}
+
+\RequirePackage{expl3}
+
+\ProvidesExplPackage {exam-zh-chinese-english} {2022-07-28} {v0.1.13}
+ {exam-zh chinese and english module}
+
+\PassOptionsToPackage { tcolorbox } { most }
+\RequirePackage { tcolorbox }
+\RequirePackage { varwidth }
+
+\keys_define:nn { exam-zh }
+ { select .meta:nn = { exam-zh / select } {#1} }
+
+
+% 选择环境 select
+\str_new:N \l__examzh_select_mark_position_str % mark 的方位
+
+\keys_define:nn { exam-zh / select }
+ {
+ mark-symbol .tl_set:N = \l__examzh_select_mark_symbol_tl,
+ mark-position .code:n =
+ {
+ \str_set:Nn \l__examzh_select_mark_position_str {#1}
+ },
+ mark-xshift .dim_set:N = \l__examzh_select_mark_xshift_dim,
+ mark-yshift .dim_set:N = \l__examzh_select_mark_yshift_dim,
+ separator .tl_set:N = \l__examzh_select_separator_tl,
+ pre-content .tl_set:N = \l__examzh_select_pre_content_tl,
+ post-content .tl_set:N = \l__examzh_select_post_content_tl,
+ show-mark .bool_set:N = \l__examzh_select_show_mark_bool
+ }
+\keys_set:nn { exam-zh / select }
+ {
+ mark-symbol = $\checkmark$,
+ mark-position = right,
+ mark-xshift = 0pt,
+ mark-yshift = 0pt,
+ separator = \hspace{1em},
+ pre-content = (,
+ post-content = ),
+ show-mark = false
+ }
+
+\seq_new:N \l__examzh_select_seq % 储存输入的内容
+
+\NewDocumentEnvironment { select } { O{ } +b }
+ {
+ % 可选参数
+ \keys_set:nn { exam-zh / select } {#1}
+ }
+ {
+ % 检测 mark-position 的输入
+ \__examzh_chinese_select_coffin_position_test:
+ % 对输入用 \item 进行分割
+ \seq_set_split:Nnn \l__examzh_select_seq { \sitem } {#2}
+ \seq_if_empty:NF \l__examzh_select_seq
+ { \seq_pop_left:NN \l__examzh_select_seq \l_tmpa_tl }
+ % 将内容和 mark 符号存入 coffin 并拼接输出
+ \__examzh_chinese_select_coffin_set_print:N
+ \l__examzh_select_seq
+ }
+\cs_new:Npn \__examzh_chinese_select_coffin_set_print:N #1
+% #1:\l__examzh_select_seq
+ {
+ % 前置内容
+ \l__examzh_select_pre_content_tl
+ % 主体部分
+ \seq_map_indexed_inline:Nn #1
+ % ##1: index
+ % ##2: content
+ {
+ % coffin 的声明
+ \__examzh_chinese_select_coffin_new:n {##1}
+ % 看 seq 的项是否开头是 *,是的话去掉 * 和空格存到 content coffin 并且在 mark coffin 里加入 mark,不是的话就只存到 content coffin
+ \__examzh_chinese_select_coffin_set:nn {##1} {##2}
+ \bool_if:NT \l__examzh_select_show_mark_bool
+ {
+ % 拼接 content coffin 和 mark coffin
+ \__examzh_chinese_select_coffin_join:n {##1}
+ }
+ % 输出 content coffin
+ \__examzh_chinese_select_coffin_typeset:n {##1}
+ }
+ % 后置内容
+ \l__examzh_select_post_content_tl
+ }
+\cs_new:Npn \__examzh_chinese_select_coffin_new:n #1
+ {
+ % 检测是否存在,没有的话就 new 一个
+ \coffin_if_exist:cF { l__examzh_select_content_ \int_to_roman:n {#1} _ coffin }
+ { \coffin_new:c { l__examzh_select_content_ \int_to_roman:n {#1} _ coffin } }
+ \coffin_if_exist:cF { l__examzh_select_mark_ \int_to_roman:n {#1} _ coffin }
+ { \coffin_new:c { l__examzh_select_mark_ \int_to_roman:n {#1} _ coffin } }
+ }
+\cs_new:Npn \__examzh_chinese_select_coffin_set:nn #1#2
+% #1: index
+% #2: content
+ {
+ \tl_if_head_eq_meaning:nNTF {#2} *
+ {
+ % 将去掉 * 号后的内容保存进 \l_tmpa_tl
+ \tl_set:Nx \l_tmpa_tl { \tl_tail:n {#2} }
+ % 去掉 * 和内容之间的空格
+ \tl_trim_spaces:N \l_tmpa_tl
+ % 将处理后的内容存到 content coffin 里
+ \hcoffin_set:cn { l__examzh_select_content_ \int_to_roman:n {#1} _ coffin }
+ { \l_tmpa_tl }
+ % 将 marksymbol 存到对应的第 #1 个 mark coffin 里
+ \hcoffin_set:cn { l__examzh_select_mark_ \int_to_roman:n {#1} _ coffin }
+ { \l__examzh_select_mark_symbol_tl }
+ }
+ {
+ % 不带 * 的直接存 coffin
+ \hcoffin_set:cn { l__examzh_select_content_ \int_to_roman:n {#1} _ coffin }
+ {#2}
+ }
+ }
+\msg_new:nnn { exam-zh / chinese } { select-no-mark-position }
+ {
+ There~is~no~position~named~#1 .\\
+ Please~read~the~manual~carefully.
+ }
+\cs_new:Npn \__examzh_chinese_select_coffin_position_test:
+ {
+ \str_case:VnF \l__examzh_select_mark_position_str
+ {
+ { top } { }
+ { above } { }
+ { bottom } { }
+ { below } { }
+ { left } { }
+ { right } { }
+ }
+ {
+ \msg_error:nnx { exam-zh / chinese } { select-no-mark-position } { \l__examzh_select_mark_position_str }
+ }
+ }
+\cs_new:Npn \__examzh_chinese_select_coffin_join:n #1
+% #1: index
+ {
+ \use:c { __examzh_chinese_select_coffin_join_ \l__examzh_select_mark_position_str :n } {#1}
+ }
+\cs_new:Npn \__examzh_chinese_select_coffin_join_top:n #1
+ {
+ \coffin_join:cnncnnnn
+ { l__examzh_select_content_ \int_to_roman:n {#1} _ coffin }
+ { hc } { t }
+ { l__examzh_select_mark_ \int_to_roman:n {#1} _ coffin }
+ { hc } { b }
+ { \l__examzh_select_mark_xshift_dim }
+ { \l__examzh_select_mark_yshift_dim + 2pt }
+ }
+\cs_set_eq:NN
+ \__examzh_chinese_select_coffin_join_above:n
+ \__examzh_chinese_select_coffin_join_top:n
+\cs_new:Npn \__examzh_chinese_select_coffin_join_bottom:n #1
+ {
+ \coffin_join:cnncnnnn
+ { l__examzh_select_content_ \int_to_roman:n {#1} _ coffin }
+ { hc } { H }
+ { l__examzh_select_mark_ \int_to_roman:n {#1} _ coffin }
+ { hc } { t }
+ { \l__examzh_select_mark_xshift_dim }
+ { \l__examzh_select_mark_yshift_dim - 2pt }
+ }
+\cs_set_eq:NN
+ \__examzh_chinese_select_coffin_join_below:n
+ \__examzh_chinese_select_coffin_join_bottom:n
+\cs_new:Npn \__examzh_chinese_select_coffin_join_left:n #1
+ {
+ \coffin_join:cnncnnnn
+ { l__examzh_select_content_ \int_to_roman:n {#1} _ coffin }
+ { l } { H }
+ { l__examzh_select_mark_ \int_to_roman:n {#1} _ coffin }
+ { r } { H }
+ { \l__examzh_select_mark_xshift_dim }
+ { \l__examzh_select_mark_yshift_dim }
+ }
+\cs_new:Npn \__examzh_chinese_select_coffin_join_right:n #1
+ {
+ \coffin_join:cnncnnnn
+ { l__examzh_select_content_ \int_to_roman:n {#1} _ coffin }
+ { r } { H }
+ { l__examzh_select_mark_ \int_to_roman:n {#1} _ coffin }
+ { l } { H }
+ { \l__examzh_select_mark_xshift_dim }
+ { \l__examzh_select_mark_yshift_dim }
+ }
+\cs_new:Npn \__examzh_chinese_select_coffin_typeset:n #1
+ {
+ \int_compare:nNnTF {#1} = {1}
+ {
+ \coffin_typeset:cnnnn
+ { l__examzh_select_content_ \int_to_roman:n {#1} _ coffin }
+ {l} {H} {0pt} {0pt}
+ }
+ {
+ \l__examzh_select_separator_tl
+ \coffin_typeset:cnnnn
+ { l__examzh_select_content_ \int_to_roman:n {#1} _ coffin }
+ {l} {H} {0pt} {0pt}
+ }
+ }
+
+
+% 连线题 lineto
+\clist_clear_new:N \l__examzh_lineto_list_set_clist
+\int_zero_new:N \l__examzh_lineto_node_index_int
+
+\keys_define:nn { exam-zh }
+ { lineto .meta:nn = { exam-zh / lineto } {#1} }
+
+\keys_define:nn { exam-zh / lineto }
+ {
+ xsep .dim_set:N = \l__examzh_lineto_node_xsep_dim,
+ ysep .dim_set:N = \l__examzh_lineto_node_ysep_dim,
+ name .tl_set:N = \l__examzh_lineto_name_tl,
+ list-style .tl_set:N = \l__examzh_lineto_list_style_tl
+ }
+\keys_set:nn { exam-zh / lineto }
+ {
+ xsep = .25\linewidth,
+ ysep = 1cm,
+ name = \int_to_roman:n { \l__examzh_lineto_node_index_int }
+ }
+
+
+\NewDocumentEnvironment { lineto } { O{ } }
+ {
+ \begin{center}
+ \begin{tikzpicture}[#1]
+ }
+ {
+ \end{tikzpicture}
+ \end{center}
+ }
+
+
+\NewDocumentCommand { \linelistset } { O{} m }
+ {
+ \int_incr:N \l__examzh_lineto_node_index_int
+ \group_begin:
+ \keys_set:nn { exam-zh / lineto } {#1}
+ \clist_set:Nn \l__examzh_lineto_list_set_clist {#2}
+ \int_step_inline:nnn {1}
+ { \clist_count:N \l__examzh_lineto_list_set_clist }
+ {
+ \use:x
+ {
+ \exp_not:N \node
+ [
+ name = \l__examzh_lineto_name_tl - ##1,
+ \l__examzh_lineto_list_style_tl
+ ]
+ at
+ (
+ \l__examzh_lineto_node_index_int * \l__examzh_lineto_node_xsep_dim,
+ - \int_eval:n { ##1 - 1 } * \l__examzh_lineto_node_ysep_dim
+ )
+ { \clist_item:Nn \l__examzh_lineto_list_set_clist {##1} };
+ }
+ }
+ \group_end:
+ }
+
+\NewDocumentCommand { \lineconnect }{ O{} +m }
+ {
+ \clist_set:Nn \l_tmpa_clist {#2}
+ \int_step_inline:nn { \clist_count:N \l_tmpa_clist - 1 }
+ {
+ \use:x
+ {
+ \exp_not:N \draw
+ [line~cap = round, #1]
+ ( \clist_item:Nn \l_tmpa_clist {##1} .east )
+ --
+ ( \clist_item:Nn \l_tmpa_clist { ##1 + 1 } .west );
+ }
+ }
+ }
+
+
+% 语文的文章 材料
+\keys_define:nn { exam-zh / material }
+ {
+ title .tl_set:N = \l__examzh_material_title_content_tl,
+ title-format .tl_set:N = \l__examzh_material_title_format_tl,
+ title-material-sep .skip_set:N = \l__examzh_material_title_material_sep_skip,
+ format .tl_set:N = \l__examzh_material_format_tl,
+ top-sep .skip_set:N = \l__examzh_material_top_sep_skip,
+ bottom-sep .skip_set:N = \l__examzh_material_bottom_sep_skip,
+ author .tl_set:N = \l__examzh_material_author_content_tl,
+ author-format .tl_set:N = \l__examzh_material_author_format_tl,
+ title-author-sep .skip_set:N = \l__examzh_material_title_author_sep_skip,
+ source .tl_set:N = \l__examzh_material_source_content_tl,
+ source-format .tl_set:N = \l__examzh_material_source_format_tl,
+ }
+
+\keys_set:nn { exam-zh / material }
+ {
+ title-format = \zihao{4},
+ author-format = \small,
+ format = \kaishu,
+ title-author-sep = 2em,
+ top-sep = 0pt,
+ bottom-sep = 0pt,
+ title-material-sep = 0pt,
+ }
+
+\NewDocumentEnvironment { material } { O{ } +b }
+ {
+ \par
+ \keys_set:nn { exam-zh / material } {#1}
+ \addvspace { \l__examzh_material_top_sep_skip }
+ \__examzh_material_title_author_type:
+ \group_begin:
+ \l__examzh_material_format_tl
+ #2
+ \group_end:
+ }
+ {
+ \tl_if_empty:NF \l__examzh_material_source_content_tl
+ {
+ \par
+ \group_begin:
+ \hfill
+ \begin{varwidth}{\textwidth}
+ \raggedleft
+ \l__examzh_material_source_format_tl
+ \l__examzh_material_source_content_tl
+ \end{varwidth}
+ \group_end:
+ }
+ \par
+ \addvspace { \l__examzh_material_bottom_sep_skip }
+ \par
+ }
+
+\cs_new:Npn \__examzh_material_title_author_type:
+ {
+ \tl_if_empty:NF \l__examzh_material_title_content_tl
+ {
+ \noindent \hfill
+ \group_begin:
+ \l__examzh_material_title_format_tl
+ \l__examzh_material_title_content_tl
+ \group_end:
+ \tl_if_empty:NF \l__examzh_material_author_content_tl
+ {
+ \hspace { \l__examzh_material_title_author_sep_skip }
+ \group_begin:
+ \l__examzh_material_author_format_tl
+ \l__examzh_material_author_content_tl
+ \group_end:
+ }
+ \hfill \null
+ \par
+ \addvspace { \l__examzh_material_title_material_sep_skip }
+ }
+ }
+
+
+% 古诗
+\bool_new:N \l__examzh_poem_type_minipage_bool
+\bool_set_true:N \l__examzh_poem_type_minipage_bool
+\int_new:N \l__examzh_poem_zhu_index_int
+\seq_new:N \g__examzh_poem_zhu_store_seq
+\str_new:N \l__examzh_poem_zhu_circlednumber_base_str
+
+\keys_define:nn { exam-zh / poem }
+ {
+ title .tl_set:N = \l__examzh_poem_title_content_tl,
+ title-format .tl_set:N = \l__examzh_poem_title_format_tl,
+ title-poem-sep .skip_set:N = \l__examzh_poem_title_poem_sep_skip,
+ format .tl_set:N = \l__examzh_poem_format_tl,
+ top-sep .skip_set:N = \l__examzh_poem_top_sep_skip,
+ bottom-sep .skip_set:N = \l__examzh_poem_bottom_sep_skip,
+ author .tl_set:N = \l__examzh_poem_author_content_tl,
+ author-format .tl_set:N = \l__examzh_poem_author_format_tl,
+ title-author-sep .skip_set:N = \l__examzh_poem_title_author_sep_skip,
+ type .choice:,
+ type / minipage .code:n = { \bool_set_true:N \l__examzh_poem_type_minipage_bool },
+ type / chinese .code:n = { \bool_set_false:N \l__examzh_poem_type_minipage_bool },
+ align .choices:nn =
+ { l , c , r }
+ { \tl_set:Nx \l__examzh_poem_align_tl { \l_keys_choice_tl } },
+ zhu-circlednumber-base .choices:nn =
+ { tikz, font }
+ { \str_set:Nx \l__examzh_poem_zhu_circlednumber_base_str { \l_keys_choice_tl } }
+ }
+
+\keys_set:nn { exam-zh / poem }
+ {
+ title-format = \zihao{5},
+ author-format = \small,
+ format = \kaishu,
+ title-author-sep = 2em,
+ top-sep = 0pt,
+ bottom-sep = 0pt,
+ title-poem-sep = 0.25\baselineskip,
+ type = chinese,
+ align = l,
+ zhu-circlednumber-base = font
+ }
+
+\NewDocumentEnvironment { poem } { O{ } +b }
+ {
+ \par
+ \keys_set:nn { exam-zh / poem } {#1}
+ \addvspace { \l__examzh_poem_top_sep_skip }
+ \__examzh_poem_begin:
+ \__examzh_poem_title_author_type:
+ \group_begin:
+ \l__examzh_poem_format_tl
+ \use:x
+ {
+ \exp_not:N \tabular
+ { \l__examzh_poem_align_tl }
+ }
+ #2
+ \endtabular
+ \group_end:
+ }
+ {
+ \__examzh_poem_end:
+ \par
+ \addvspace { \l__examzh_poem_bottom_sep_skip }
+ \par
+ }
+\cs_new:Npn \__examzh_poem_title_author_type:
+ {
+ \tl_if_empty:NF \l__examzh_poem_title_content_tl
+ {
+ % \noindent \hfill
+ \group_begin:
+ \l__examzh_poem_title_format_tl
+ \l__examzh_poem_title_content_tl
+ \group_end:
+ \tl_if_empty:NF \l__examzh_poem_author_content_tl
+ {
+ \hspace { \l__examzh_poem_title_author_sep_skip }
+ \group_begin:
+ \l__examzh_poem_author_format_tl
+ \l__examzh_poem_author_content_tl
+ \group_end:
+ }
+ % \hfill \null
+ \par
+ \addvspace { \l__examzh_poem_title_poem_sep_skip }
+ }
+ }
+\cs_new:Npn \__examzh_poem_begin:
+ {
+ \bool_if:NTF \l__examzh_poem_type_minipage_bool
+ {
+ \noindent
+ \minipage { \linewidth }
+ \cs_set:Npn \thempfootnote { \examzh_footnote_number:N \c@mpfootnote}
+ \center
+ }
+ {
+ \int_zero:N \l__examzh_poem_zhu_index_int
+ \seq_clear:N \g__examzh_poem_zhu_store_seq
+ \center
+ }
+ }
+\cs_new:Npn \__examzh_poem_end:
+ {
+ \bool_if:NTF \l__examzh_poem_type_minipage_bool
+ {
+ \endcenter
+ \endminipage
+ }
+ {
+ \endcenter
+ \vspace*{-0.7em}
+ \small
+ \begin{description}[leftmargin = 2em]
+ \item[{[注]}]
+ \seq_map_indexed_inline:Nn \g__examzh_poem_zhu_store_seq
+ % ##1: index
+ % ##2: content
+ {
+ \__examzh_chinese_circled_number:n {##1} ~ ##2
+ }
+ \end{description}
+ }
+ }
+
+
+\NewDocumentCommand { \zhu } { o m }
+ {
+ \bool_if:NTF \l__examzh_poem_type_minipage_bool
+ {
+ \footnote {#2}
+ }
+ {
+ \IfNoValueF {#1}
+ {
+ \int_gset:Nn \l__examzh_poem_zhu_index_int {#1 - 1}
+ }
+ \__examzh_poem_type_chinese_zhu:n {#2}
+ }
+ }
+
+\cs_new:Npn \__examzh_poem_type_chinese_zhu:n #1
+ {
+ \int_gincr:N \l__examzh_poem_zhu_index_int
+ \int_set_eq:NN \l_tmpa_int \l__examzh_poem_zhu_index_int
+ \unskip
+ % 输出符号
+ \textsuperscript
+ { \__examzh_chinese_circled_number:n { \l__examzh_poem_zhu_index_int } }
+ % 将参数存起来
+ \seq_gput_right:Nx \g__examzh_poem_zhu_store_seq
+ { #1 }
+ }
+
+\cs_new:Npn \__examzh_chinese_circled_number:n #1
+ {
+ \str_case:Vn \l__examzh_poem_zhu_circlednumber_base_str
+ {
+ { tikz } { \__examzh_chinese_tikz_circled_number:n {#1} }
+ { font } { \__examzh_chinese_tikz_circled_number:n {#1} }
+ }
+ }
+% 基于字体的带圈数字
+\cs_new:Npn \__examzh_chinese_font_circled_number:n #1
+ {
+ \int_set:Nn \l_tmpa_int {#1}
+ \int_compare:nNnTF { \l_tmpa_int } = { 0 }
+ { \int_set:Nn \l_tmpa_int { "24EA } }
+ {
+ \int_compare:nNnTF { \l_tmpa_int } < { 21 }
+ { \int_add:Nn \l_tmpa_int { "245F } }
+ {
+ \int_compare:nNnTF { \l_tmpa_int } < { 36 }
+ { \int_add:Nn \l_tmpa_int { "3250 } }
+ {
+ \int_compare:nNnTF { \l_tmpa_int } < { 51 }
+ { \int_add:Nn \l_tmpa_int { "32B0 } }
+ {
+ \msg_error:nnn { exam-zh / poem }
+ { invalid-circled-number } { \int_use:N \l_tmpa_int }
+ }
+ }
+ }
+ }
+ \group_begin:
+ \CJKfamily+ { }
+ \symbol { \l_tmpa_int }
+ \group_end:
+ }
+
+\msg_new:nnn { exam-zh / poem } { invalid-circled-number }
+ { Invalid~ circled~ number~ #1. }
+
+% tikz 绘制带圈数字
+\fp_new:N \l__examzh_chinese_tikz_circled_number_xscale_fp % 水平压缩系数
+\fp_new:N \l__examzh_chinese_tikz_circled_number_yscale_fp % 垂直压缩系数
+\dim_new:N \l__examzh_chinese_tikz_circled_number_total_hegiht_dim % 数字的总高度
+\dim_new:N \l__examzh_chinese_tikz_circled_number_radius_dim % 半径
+
+\cs_new:Npn \__examzh_chinese_tikz_circled_number_aux:n #1
+ {
+ % 根据数字大小设置压缩系数
+ \fp_set:Nn \l__examzh_chinese_tikz_circled_number_xscale_fp
+ {
+ \int_compare:nNnTF {#1} < { 10 }
+ { 0.9 }
+ {
+ \int_compare:nNnTF {#1} < { 100 }
+ { 0.7 }
+ { 0.5 }
+ }
+ }
+ \fp_set:Nn \l__examzh_chinese_tikz_circled_number_yscale_fp
+ {
+ \int_compare:nNnTF {#1} < { 10 }
+ { 0.9 }
+ {
+ \int_compare:nNnTF {#1} < { 100 }
+ { 0.8 }
+ { 0.6 }
+ }
+ }
+ % 获取数字的高度
+ \hbox_set:Nn \l_tmpa_box {#1}
+ \dim_set:Nn \l__examzh_chinese_tikz_circled_number_total_hegiht_dim
+ { \box_ht:N \l_tmpa_box + \box_dp:N \l_tmpa_box }
+ % 设置圆的半径
+ \dim_set:Nn \l__examzh_chinese_tikz_circled_number_radius_dim
+ { \dim_eval:n { \l__examzh_chinese_tikz_circled_number_total_hegiht_dim / 2 + 0.34 ex } }
+ % 绘制
+ \tikz [ baseline ]
+ {
+ \node
+ [ inner~sep = 0pt, outer~sep = 0pt ]
+ at (0, \dim_use:N \l__examzh_chinese_tikz_circled_number_total_hegiht_dim / 2 )
+ {
+ \hbox_set:Nn \l_tmpa_box
+ {
+ \int_compare:nNnTF {#1} > {9}
+ { \textbf {#1} }
+ {#1}
+ }
+ \makebox[0.35em][c]
+ {
+ % \scalebox { \fp_use:N \l__examzh_chinese_tikz_circled_number_xscale_fp }
+ % [ \fp_use:N \l__examzh_chinese_tikz_circled_number_yscale_fp ]
+ \box_scale:Nnn \l_tmpa_box
+ { \fp_use:N \l__examzh_chinese_tikz_circled_number_xscale_fp }
+ { \fp_use:N \l__examzh_chinese_tikz_circled_number_yscale_fp }
+ \box_use_drop:N \l_tmpa_box
+ }
+ };
+ \draw (0, \l__examzh_chinese_tikz_circled_number_total_hegiht_dim / 2 )
+ circle ( \l__examzh_chinese_tikz_circled_number_radius_dim );
+ }
+ }
+\cs_new:Npn \__examzh_chinese_tikz_circled_number:n #1
+ {
+ \__examzh_chinese_tikz_circled_number_aux:n { \int_eval:n {#1} }
+ }
+
+
+% 作文框
+\NewDocumentEnvironment { writingbox } { O{ } +b }
+ {
+ \begin{tcolorbox}
+ [
+ % 直角
+ sharp~corners = all,
+ % 颜色
+ colback = white,
+ colbacktitle = white,
+ % colframe = white,
+ coltitle = black,
+ % 边框粗细
+ boxrule = 1pt,
+ titlerule = 0pt,
+ % 间距
+ toptitle = 4pt,
+ % 字体
+ fonttitle = \centering,
+ % 首行缩进
+ parbox = false,
+ before~upper = \indent,
+ % 跨页
+ breakable,
+ enhanced~jigsaw,
+ #1
+ ]
+ #2
+ }
+ {
+ \end{tcolorbox}
+ } \ No newline at end of file
diff --git a/Master/texmf-dist/tex/latex/exam-zh/exam-zh-choices.sty b/Master/texmf-dist/tex/latex/exam-zh/exam-zh-choices.sty
new file mode 100644
index 00000000000..6eccb24867a
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/exam-zh/exam-zh-choices.sty
@@ -0,0 +1,555 @@
+%
+% Copyright (c) 2022 Zeping Lee
+% Released under the LaTeX Project Public License v1.3c License.
+% Repository: https://gitee.com/zepinglee/exam-zh
+%
+
+\NeedsTeXFormat{LaTeX2e}
+
+\RequirePackage{expl3}
+\RequirePackage{xparse}
+
+\ProvidesExplPackage {exam-zh-choices} {2022-07-28} {v0.1.13}
+ {exam-zh choices module}
+
+\dim_new:N \l__examzh_choices_column_sep_dim
+\int_new:N \l__examzh_choices_columns_int
+\tl_new:N \l__examzh_choices_label_tl
+\tl_new:N \l__examzh_choices_label_pos_tl
+\tl_new:N \l__examzh_choices_label_align_tl
+\dim_new:N \l__examzh_choices_label_sep_dim
+\dim_new:N \l__examzh_choices_label_width_dim
+\int_new:N \l__examzh_choices_max_columns_int
+
+\keys_define:nn { exam-zh }
+ { choices .meta:nn = { exam-zh / choices } {#1} }
+
+\keys_define:nn { exam-zh / choices }
+ {
+ column-sep .dim_set:N = \l__examzh_choices_column_sep_dim ,
+ columns .int_set:N = \l__examzh_choices_columns_int ,
+ label .tl_set:N = \l__examzh_choices_label_tl ,
+ label-pos .choices:nn =
+ { auto , top-left , left , bottom }
+ { \tl_set_eq:NN \l__examzh_choices_label_pos_tl \l_keys_choice_tl } ,
+ label-align .tl_set:N = \l__examzh_choices_label_align_tl ,
+ label-sep .dim_set:N = \l__examzh_choices_label_sep_dim ,
+ label-width .dim_set:N = \l__examzh_choices_label_width_dim ,
+ max-columns .int_set:N = \l__examzh_choices_max_columns_int ,
+ index .int_set:N = \l__examzh_choices_item_index_int
+ }
+
+\keys_set:nn { exam-zh / choices }
+ {
+ column-sep = 1em ,
+ columns = 0 ,
+ label = \Alph*. ,
+ label-pos = auto ,
+ label-align = right ,
+ label-sep = .5em ,
+ label-width = 0pt ,
+ max-columns = 4 ,
+ index = 1,
+ }
+
+\NewDocumentCommand \setchoices { m }
+ { \keys_set:nn { exam-zh / choices } {#1} }
+
+
+\tl_new:N \l__examzh_choices_counters_tl
+
+\NewDocumentCommand \AddChoicesCounter { m m }
+ % #1: \Alph(用户接口)
+ % #2: \@Alph(具体实现的命令或函数(开发层))
+ {
+ % TODO 这一步的作用是什么,为什么要把函数放在 tl 变量里而不是直接在某处使用?
+ % 猜测:put_right 而不是 set,是为了保证操作 label 的输入值前
+ % 几个函数都被 set
+ \tl_put_right:Nn \l__examzh_choices_counters_tl
+ { \__examzh_choices_process_counter:NN #1 #2 }
+ \cs_set_eq:cN { __examzh_choices_save_ \cs_to_str:N #1 : } #2
+ \cs_set_eq:cN { __examzh_choices_save_ \cs_to_str:N #2 : } #2
+ }
+
+\AddChoicesCounter \arabic \@arabic
+\AddChoicesCounter \alph \@alph
+\AddChoicesCounter \Alph \@Alph
+\AddChoicesCounter \roman \@roman
+\AddChoicesCounter \Roman \@Roman
+
+
+\dim_new:N \l__examzh_choices_total_width_dim
+\seq_new:N \l__examzh_choices_seq
+
+\NewDocumentEnvironment { choices } { O { } +b }
+ {
+ \par \nopagebreak
+ % 严格禁止孤行和寡行
+ \int_set:Nn \clubpenalty { 10000 }
+ \int_set:Nn \widowpenalty { 10000 }
+ % 尽量避免在选项中间换行
+ \int_set:Nn \interlinepenalty { 301 }
+ \noindent
+ \dim_set_eq:NN \l__examzh_choices_total_width_dim \linewidth
+ \int_zero:N \l__examzh_choices_columns_int
+ \dim_zero:N \l__examzh_choices_label_width_dim
+ \keys_set:nn { exam-zh / choices } {#1}
+ }
+ {
+ % 用 \item 分割选项
+ \seq_set_split:Nnn \l__examzh_choices_seq { \item } {#2}
+ % 把第一个空项去掉
+ \seq_if_empty:NF \l__examzh_choices_seq
+ { \seq_pop_left:NN \l__examzh_choices_seq \l_tmpa_tl }
+ % 收集正确的选项
+ \__examzh_choices_collect_correct_choices:N
+ \l__examzh_choices_seq
+ % 计算标签和选项内容的最大自然宽度
+ \__examzh_choices_calc_max_width:N \l__examzh_choices_seq
+ % label-pos = auto 时自动选择标签位置
+ \__examzh_choices_set_auto_label_pos:
+ % 如果用户没有声明列数,计算合适的列数
+ % 「学习点」从默认值是否被改变来测试用户是否输入
+ % 用户没有输入的话就采用自动计算列数
+ \int_compare:nNnT { \l__examzh_choices_columns_int } < {1}
+ { \__examzh_choices_calc_columns: }
+ % 计算每个选项内容的宽度 \l__examzh_choices_item_width_dim
+ \__examzh_choices_calc_item_width:
+ % 输出选项
+ \__examzh_print_choices:N \l__examzh_choices_seq
+ % 输出正确选项
+ \__examzh_print_correctchoice:
+ }
+
+% 用来存正确选项的序号(entry)
+\seq_new:N \l__examzh_choices_correct_choices_label_seq
+% 用来存正确选项的内容
+\seq_new:N \l__examzh_choices_correct_choices_item_seq
+
+% 收集正确的选项,保存在 \l__examzh_choices_correct_choices_seq
+\cs_new:Npn \__examzh_choices_collect_correct_choices:N #1
+ % #1: \l__examzh_choices_seq
+ {
+ \seq_clear:N \l__examzh_choices_correct_choices_label_seq
+ \seq_clear:N \l__examzh_choices_correct_choices_item_seq
+ \seq_clear:N \l_tmpa_seq
+ \seq_map_indexed_inline:Nn #1
+ {
+ % ##1: 选项序号
+ % ##2: 选项内容
+ % 如果分割后,第一个字符是 * 的,表明这是一个正确选项
+ %(即用 \item* 来标记正确答案)
+ \tl_if_head_eq_meaning:nNTF {##2} *
+ {
+ \seq_put_right:Nn \l__examzh_choices_correct_choices_label_seq
+ { \__examzh_choices_correct_choices_label_transfrom:n {##1} }
+ % 将去掉 * 号后的内容保存进 \l_tmpa_tl
+ \tl_set:Nx \l_tmpa_tl { \tl_tail:n {##2} }
+ % 去掉 * 和内容之间的空格
+ \tl_trim_spaces:N \l_tmpa_tl
+ \seq_put_right:NV \l__examzh_choices_correct_choices_item_seq
+ \l_tmpa_tl
+ \seq_put_right:NV \l_tmpa_seq \l_tmpa_tl
+ }
+ {
+ \seq_put_right:Nn \l_tmpa_seq { ##2 }
+ }
+ }
+ \seq_set_eq:NN #1 \l_tmpa_seq
+ }
+
+% 根据 label 的样式 \l__examzh_choices_label_tl 转化正确选项的样式
+\cs_new:Npn \__examzh_choices_correct_choices_label_transfrom:n #1
+ {
+ \group_begin:
+ \int_set:Nn \l__examzh_choices_index_int {#1}
+ % 定义计数器转换函数(如 \Alph 等)
+ \l__examzh_choices_counters_tl
+ % 输出
+ \l__examzh_choices_label_tl
+ \group_end:
+ }
+% 输出正确的选项
+\cs_new:Nn \__examzh_print_correctchoice:
+ {
+ \seq_if_empty:NF \l__examzh_choices_correct_choices_item_seq
+ {
+ \par
+ 参考答案:
+ \seq_use:Nn \l__examzh_choices_correct_choices_label_seq {,~}
+ }
+ }
+
+
+\dim_new:N \l__examzh_choices_item_width_dim
+\dim_new:N \l__examzh_choices_item_min_height_dim
+
+% 计算标签和选项内容的最大宽度,
+% 分别保存到 \l__examzh_choices_label_width_dim 和 \l__examzh_choices_item_width_dim
+% #1: \l__examzh_choices_seq
+\cs_new:Npn \__examzh_choices_calc_max_width:N #1
+ {
+ % 下面这两个的想法是 xchoices 项目可以优化学习的地方
+ % 因为 xchoices 是把变量先设置为第一项的参数,然后让后面的和前面的比
+ % 这里相当于把“设置为第一项的参数”这一步,用默认的“端点量”来代替
+ % 比如取最大的,就和 0 比,这样的话其实也会产生变量会变成第一项的参数的结果
+ % 但是两者性质不同,此处处理让 第一项 「没有特殊性」
+ % 后面的计算最小高度的也是如此
+ \dim_zero:N \l__examzh_choices_item_width_dim
+ \dim_set_eq:NN \l__examzh_choices_item_min_height_dim \c_max_dim
+ \seq_map_indexed_inline:Nn #1
+ {
+ % -- 标签 --
+ % 把标签整体放进 \l_tmpa_box
+ \hbox_set:Nn \l_tmpa_box { \__examzh_choices_the_label:n {##1} }
+ % 测量宽度
+ \dim_set:Nn \l_tmpa_dim { \box_wd:N \l_tmpa_box }
+ % 与当前最大值比较,最后效果是 \l__examzh_choices_label_width_dim 储存了所有标签中宽度最大的标签的宽度值
+ \dim_compare:nNnT
+ { \l_tmpa_dim } > { \l__examzh_choices_label_width_dim }
+ { \dim_set_eq:NN \l__examzh_choices_label_width_dim \l_tmpa_dim }
+ % -- 选项内容 --
+ % 把内容放进 \l_tmpa_box 中
+ \hbox_set:Nn \l_tmpa_box {##2}
+ % 测量宽度
+ \dim_set:Nn \l_tmpa_dim { \box_wd:N \l_tmpa_box }
+ % 与当前最大值比较,最后效果是 \l__examzh_choices_item_width_dim 储存了所有选项内容中宽度最大的内容的宽度值
+ \dim_compare:nNnT
+ { \l_tmpa_dim } > { \l__examzh_choices_item_width_dim }
+ {
+ \dim_set_eq:NN \l__examzh_choices_item_width_dim
+ \l_tmpa_dim
+ }
+ % -- 找到最小高度 --
+ % 把内容高度储存到 \l_tmpb_dim
+ \dim_set:Nn \l_tmpb_dim { \box_ht:N \l_tmpa_box }
+ % 与当前最小值比较,最后效果是 \l__examzh_choices_item_min_height_dim 储存了所有内容中高度最小的内容的高度值
+ \dim_compare:nNnT
+ { \l_tmpb_dim } < { \l__examzh_choices_item_min_height_dim }
+ { \dim_set_eq:NN \l__examzh_choices_item_min_height_dim \l_tmpb_dim }
+ \box_clear:N \l_tmpa_box
+ }
+ }
+
+% TODO 没看懂怎么实现的
+\int_new:N \l__examzh_choices_index_int
+
+% \Alph* 形式生成正确的标签
+\cs_new:Npn \__examzh_choices_the_label:n #1
+ {
+ \group_begin:
+ \int_set:Nn \l__examzh_choices_index_int
+ {
+ \int_eval:n
+ {
+ \l__examzh_choices_item_index_int + #1 - 1
+ }
+ }
+ \l__examzh_choices_counters_tl
+ \l__examzh_choices_label_tl
+ \group_end:
+ }
+
+\cs_new:Npn \__examzh_choices_process_counter:NN #1#2
+ % #1: \Alph
+ % #2: \@Alph
+ {
+ % 用户可以同时使用 #1 和 #2 两个函数(命令)作为 label 的操作函数
+ % #1 的内核原理函数是 #2
+ \cs_set:Npn #1 { \__examzh_choices_process_counter_aux:Nn #2 }
+ \cs_set:Npn #2 { \__examzh_choices_process_counter_aux:Nn #2 }
+ }
+
+\cs_new:Npn \__examzh_choices_process_counter_aux:Nn #1#2
+ % #1: \@Alph
+ {
+ \tl_if_eq:nnTF {#2} { * }
+ {
+ % 如果是 \alph* 类型的,效果为 \alph{ \l__examzh_choices_index_int }
+ \use:c { __examzh_choices_save_ \cs_to_str:N #1 : }
+ { \l__examzh_choices_index_int }
+ }
+ {
+ % 否则就是 \alph{...} 效果
+ \use:c { __examzh_choices_save_ \cs_to_str:N #1 : } {#2}
+ }
+ }
+
+
+% 超过这一高度阈值的选项视为插图模式
+% 注意使用 tl
+% TODO 为何要使用 tl 而不用 dim ?
+\tl_new:N \l__examzh_choices_figure_mode_threshold_tl
+\tl_set:Nn \l__examzh_choices_figure_mode_threshold_tl { 2 \baselineskip }
+
+\cs_new:Npn \__examzh_choices_set_auto_label_pos:
+ {
+ \tl_if_eq:NnT \l__examzh_choices_label_pos_tl { auto }
+ {
+ % 若最小高度超过阈值,推测其中包含插图,将标签位置改为左居中
+ \dim_compare:nNnTF
+ { \l__examzh_choices_item_min_height_dim } >
+ { \l__examzh_choices_figure_mode_threshold_tl }
+ { \tl_set:Nn \l__examzh_choices_label_pos_tl { left } }
+ { \tl_set:Nn \l__examzh_choices_label_pos_tl { top-left } }
+ }
+ }
+
+
+\int_new:N \l__examzh_tmp_int
+
+% 计算选项的合适列数,存到 \l__examzh_choices_columns_int
+\cs_new:Npn \__examzh_choices_calc_columns:
+ {
+ % 若标签不在底部,将 label-width 和 label-sep 加到 \l__examzh_choices_item_width_dim 里面
+ \tl_if_eq:NnF \l__examzh_choices_label_pos_tl { bottom }
+ {
+ \dim_add:Nn \l__examzh_choices_item_width_dim
+ { \l__examzh_choices_label_width_dim + \l__examzh_choices_label_sep_dim }
+ }
+ % [总宽度 / 最大的选项宽度] = 列数
+ % 这个计算出来是作为「算出来的、可以排的最大列数」
+ % 将要和下面的手动(或者默认的)最大列数进行比较,来确定最后排多少列
+ \int_set:Nn \l__examzh_choices_columns_int
+ {
+ \int_div_truncate:nn
+ { \l__examzh_choices_total_width_dim + \l__examzh_choices_column_sep_dim }
+ { \l__examzh_choices_item_width_dim + \l__examzh_choices_column_sep_dim }
+ }
+ % 如果上面的计算算出来是 0 的话,就设置为 1
+ \int_compare:nNnTF { \l__examzh_choices_columns_int } = {0}
+ { \int_set:Nn \l__examzh_choices_columns_int {1} }
+ % 从允许的最大列数开始,每次除以 2,直到行宽允许排下
+ % 比如设置了最大列数是 4 , 但是算出来可以排 5
+ % 那么就会将 [4 / 2] = 2 < 5 作为列数
+ \int_set_eq:NN \l__examzh_tmp_int \l__examzh_choices_max_columns_int
+ \int_while_do:nNnn
+ { \l__examzh_tmp_int } > { \l__examzh_choices_columns_int }
+ {
+ \int_set:Nn \l__examzh_tmp_int
+ { \int_div_truncate:nn { \l__examzh_tmp_int } {2} }
+ }
+ \int_set_eq:NN \l__examzh_choices_columns_int \l__examzh_tmp_int
+ }
+
+
+% 计算选项的最终宽度,保存到 \l__examzh_choices_item_width_dim
+\cs_new:Npn \__examzh_choices_calc_item_width:
+ {
+ \dim_set:Nn \l__examzh_choices_item_width_dim
+ {
+ % TODO 不是很理解这里的算法
+ ( \l__examzh_choices_total_width_dim
+ - \l__examzh_choices_columns_int \l__examzh_choices_column_sep_dim
+ + \l__examzh_choices_column_sep_dim
+ ) / \l__examzh_choices_columns_int
+ }
+ % 若标签不在底部,将 label-width 和 label-sep 算进来
+ % TODO 算进来?那怎么还是 sub?
+ \tl_if_eq:NnF \l__examzh_choices_label_pos_tl { bottom }
+ {
+ \dim_sub:Nn \l__examzh_choices_item_width_dim
+ { \l__examzh_choices_label_width_dim + \l__examzh_choices_label_sep_dim }
+ }
+ }
+
+
+\int_new:N \l__examzh_choices_current_col_int
+
+% #1: \l__examzh_choices_seq
+\cs_new:Npn \__examzh_print_choices:N #1
+ {
+ \int_zero:N \l__examzh_choices_current_col_int
+ \seq_map_indexed_inline:Nn \l__examzh_choices_seq
+ {
+ \int_incr:N \l__examzh_choices_current_col_int
+ % 当前列号重置为 1
+ \int_compare:nNnT
+ { \l__examzh_choices_current_col_int } > { \l__examzh_choices_columns_int }
+ {
+ % \par \noindent
+ \newline
+ \int_set:Nn \l__examzh_choices_current_col_int {1}
+ }
+ % TODO 为什么 > 1 才加呢? 这样的话第 1 列和第 2 列之间就没有这个间距?
+ \int_compare:nNnT { \l__examzh_choices_current_col_int } > {1}
+ {
+ \skip_horizontal:N \l__examzh_choices_column_sep_dim
+ % 增加一点弹性
+ \skip_horizontal:n {0pt plus 1pt minus 1pt}
+ }
+ \__examzh_print_single_choice:nn {##1} {##2}
+ }
+ \par
+ }
+
+
+\coffin_new:N \l__examzh_choices_item_coffin
+\coffin_new:N \l__examzh_choices_label_coffin
+
+\cs_new:Npn \__examzh_print_single_choice:nn #1#2
+ {
+ % 选项标签
+ \__examzh_choices_make_label_coffin:n {#1}
+ % 选项内容
+ \__examzh_choices_make_item_coffin:n {#2}
+ % 合并选项的标签和内容
+ \str_case:Vn \l__examzh_choices_label_pos_tl
+ {
+ { top-left }
+ {
+ \coffin_join:NnnNnnnn
+ \l__examzh_choices_item_coffin {l} {H}
+ \l__examzh_choices_label_coffin {r} {H}
+ { - \l__examzh_choices_label_sep_dim }
+ { 0pt }
+ }
+ { left }
+ {
+ \coffin_join:NnnNnnnn
+ \l__examzh_choices_item_coffin {l} {vc}
+ \l__examzh_choices_label_coffin {r} {vc}
+ { - \l__examzh_choices_label_sep_dim }
+ { 0pt }
+ }
+ { bottom }
+ {
+ \coffin_join:NnnNnnnn
+ \l__examzh_choices_item_coffin {hc} {b}
+ \l__examzh_choices_label_coffin {hc} {t}
+ { 0pt }
+ % { - \l__examzh_choices_label_sep_dim }
+ { 0pt }
+ }
+ }
+ % 输出合并后
+ \coffin_typeset:Nnnnn \l__examzh_choices_item_coffin {l} {H} {0pt} {0pt}
+ \coffin_clear:N \l__examzh_choices_item_coffin
+ \coffin_clear:N \l__examzh_choices_label_coffin
+ }
+
+% 将标签内容存入 coffin
+\cs_new:Npn \__examzh_choices_make_label_coffin:n #1
+ {
+ \hcoffin_set:Nn \l__examzh_choices_label_coffin
+ {
+ \hbox_to_wd:nn { \l__examzh_choices_label_width_dim }
+ { \__examzh_choices_make_label:n {#1} \strut }
+ }
+ }
+
+\cs_new:Npn \__examzh_choices_make_label:n #1
+ {
+ \str_case:Vn \l__examzh_choices_label_align_tl
+ {
+ { left } { \rlap { \__examzh_choices_the_label:n {#1} } \hss }
+ { center } { \hss \clap { \__examzh_choices_the_label:n {#1} } \hss }
+ { right } { \hss \llap { \__examzh_choices_the_label:n {#1} } }
+ }
+ }
+
+\bool_new:N \l__examzh_choices_figure_mode_bool
+
+% 将选项内容存入 coffin
+\cs_new:Npn \__examzh_choices_make_item_coffin:n #1
+ {
+ \hcoffin_set:Nn \l__examzh_choices_item_coffin
+ {
+ % 优先尝试使用 hbox,这是因为在 \vcoffin_set 外部能保留原来的 \linewidth 和
+ % \textwidth,方便用户在 \includegraphics 中使用
+ \hbox_set:Nn \l_tmpa_box {#1}
+ % 若盒子的自然高度大于 2 行,且深度为 0pt,设置为插图模式
+ \bool_lazy_and:nnT
+ {
+ \dim_compare_p:nNn { \box_ht:N \l_tmpa_box } >
+ { \l__examzh_choices_figure_mode_threshold_tl }
+ }
+ { \dim_compare_p:nNn { \box_dp:N \l_tmpa_box } < { 1pt } }
+ { \bool_set_true:N \l__examzh_choices_figure_mode_bool }
+ \vcoffin_set:Nnn \l_tmpa_coffin
+ { \l__examzh_choices_item_width_dim }
+ {
+ \dim_set_eq:NN \parskip \c_zero_dim
+ \dim_set_eq:NN \parindent \listparindent
+ \noindent
+ % \strut
+ % 若标签在底部,将图片居中对齐。
+ \tl_if_eq:NnT \l__examzh_choices_label_pos_tl { bottom }
+ { \centering }
+ \dim_compare:nNnTF
+ { \box_wd:N \l_tmpa_box } > { \l__examzh_choices_item_width_dim }
+ { #1 }
+ { \box_use_drop:N \l_tmpa_box }
+ % 使用 \strut 将行距撑开,防止跟下一行选项的间距过小
+ \mode_if_horizontal:T { \strut }
+ }
+ \dim_set:Nn \l_tmpa_dim { \coffin_ht:N \l_tmpa_coffin }
+ \bool_if:NT \l__examzh_choices_figure_mode_bool
+ {
+ \coffin_set_horizontal_pole:Nnn \l_tmpa_coffin {T}
+ { \l_tmpa_dim - 0.7 \baselineskip }
+ }
+ \coffin_typeset:Nnnnn \l_tmpa_coffin {l} {T} {0pt} {0pt}
+ \coffin_clear:N \l_tmpa_coffin
+ }
+ }
+
+
+% 使用中文字体直接输出 unicode 带圈数字
+% \circlednumber 的参数既可以接受 LaTeX2e 的 <counter>,也可以直接接受 <intexpr>。
+% \NewDocumentCommand \circlednumber { m }
+% {
+% \int_if_exist:cTF { c@ #1 }
+% { \int_set_eq:Nc \l_tmpa_int { c@#1 } }
+% { \int_set:Nn \l_tmpa_int { #1 } }
+% \exp_args:Nx \__examzh_choices_circled_number:n { \int_use:N \l_tmpa_int }
+% }
+
+\cs_new:Npn \__examzh_choices_circled_number:n #1
+ {
+ \int_set:Nn \l_tmpa_int {#1}
+ \int_compare:nNnTF { \l_tmpa_int } = { 0 }
+ { \int_set:Nn \l_tmpa_int { "24EA } }
+ {
+ \int_compare:nNnTF { \l_tmpa_int } < { 21 }
+ { \int_add:Nn \l_tmpa_int { "245F } }
+ {
+ \int_compare:nNnTF { \l_tmpa_int } < { 36 }
+ { \int_add:Nn \l_tmpa_int { "3250 } }
+ {
+ \int_compare:nNnTF { \l_tmpa_int } < { 51 }
+ { \int_add:Nn \l_tmpa_int { "32B0 } }
+ {
+ \msg_error:nnn { exam-zh / choices }
+ { invalid-circled-number } { \int_use:N \l_tmpa_int }
+ }
+ }
+ }
+ }
+ \group_begin:
+ % TODO 为何要用 \CJKfamily+ { }
+ % xeCJK 宏包文档:当 \CJKfamily+ 参数为空时,则使用当前的 CJK 字体族。
+ \CJKfamily+ { }
+ \symbol { \l_tmpa_int }
+ \group_end:
+ }
+
+\msg_new:nnn { exam-zh / choices } { invalid-circled-number }
+ { Invalid~ circled~ number~ #1. }
+
+\AddChoicesCounter \circlednumber \__examzh_choices_circled_number:n
+
+
+% TODO 答案控制
+
+% 选择题答案控制
+% - 直接在后面显示
+% - 在括号内显示
+% - 手动输入
+% - 能否通过写中途文件方式使得答案可以出现在前面的括号内
+% - 统一移动到最后
+% - 也是 choices 的形式
+% - 表格形式
+
+% 答案确定
+% 通过 \item 是否带 * 判断,有的话则标记为正确答案 \ No newline at end of file
diff --git a/Master/texmf-dist/tex/latex/exam-zh/exam-zh-font.sty b/Master/texmf-dist/tex/latex/exam-zh/exam-zh-font.sty
new file mode 100644
index 00000000000..15b173c9ef7
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/exam-zh/exam-zh-font.sty
@@ -0,0 +1,580 @@
+%
+% Copyright (c) 2022 Zeping Lee
+% Released under the LaTeX Project Public License v1.3c License.
+% Repository: https://gitee.com/zepinglee/exam-zh
+%
+
+\NeedsTeXFormat{LaTeX2e}
+
+\RequirePackage{expl3}
+\RequirePackage{xparse}
+
+\ProvidesExplPackage {exam-zh-font} {2022-07-28} {v0.1.13}
+ {exam-zh font module}
+
+\RequirePackage { unicode-math }
+\RequirePackage { filehook }
+
+\tl_new:N \g__examzh_font_font_tl
+\tl_new:N \g__examzh_font_math_font_tl
+
+\keys_define:nn { exam-zh }
+ {
+ font .choices:nn =
+ {
+ newcm ,
+ lm ,
+ times ,
+ termes ,
+ stix,
+ xits ,
+ libertinus ,
+ % newtx ,
+ none
+ }
+ {
+ \tl_gset_eq:NN \g__examzh_font_font_tl \l_keys_choice_tl
+ \use:c { examzh_font_set_font_ \g__examzh_font_font_tl : }
+ } ,
+ math-font .choices:nn =
+ {
+ newcm ,
+ lm ,
+ termes ,
+ stix,
+ xits ,
+ libertinus ,
+ cambria ,
+ % newtx ,
+ none
+ }
+ {
+ \tl_gset_eq:NN \g__examzh_font_math_font_tl \l_keys_choice_tl
+ \use:c { examzh_font_set_math_font_ \g__examzh_font_math_font_tl : }
+ } ,
+ }
+
+
+% New Computer Modern
+\cs_new:Npn \examzh_font_set_font_newcm:
+ {
+ \setmainfont { NewCM10 }
+ [
+ Extension = .otf ,
+ UprightFont = *-Book ,
+ BoldFont = *-Bold ,
+ ItalicFont = *-BookItalic ,
+ BoldItalicFont = *-BoldItalic ,
+ ]
+ \setsansfont { NewCMSans10 }
+ [
+ Extension = .otf ,
+ UprightFont = *-Book ,
+ BoldFont = *-Bold ,
+ ItalicFont = *-BookOblique ,
+ BoldItalicFont = *-BoldOblique ,
+ ]
+ \setmonofont { NewCMMono10 }
+ [
+ Extension = .otf ,
+ UprightFont = *-Book ,
+ ItalicFont = *-BookItalic ,
+ BoldFont = *-Bold ,
+ BoldItalicFont = *-BoldOblique ,
+ ]
+ }
+
+
+% Latin Modern
+\cs_new:Npn \examzh_font_set_font_lm:
+ {
+ \setmainfont { lmroman10 }
+ [
+ Extension = .otf ,
+ UprightFont = *-regular ,
+ BoldFont = *-bold ,
+ ItalicFont = *-italic ,
+ BoldItalicFont = *-bolditalic ,
+ ]
+ \setsansfont { lmsans10 }
+ [
+ Extension = .otf ,
+ UprightFont = *-regular ,
+ BoldFont = *-bold ,
+ ItalicFont = *-oblique ,
+ BoldItalicFont = *-boldoblique ,
+ ]
+ \setmonofont { lmmonolt10 }
+ [
+ Extension = .otf ,
+ UprightFont = *-regular ,
+ BoldFont = *-bold ,
+ ItalicFont = *-oblique ,
+ BoldItalicFont = *-boldoblique ,
+ ]
+ }
+
+
+% Times New Roman + Arial
+\cs_new:Npn \examzh_font_set_font_times:
+ {
+ \setmainfont { Times~ New~ Roman }
+ \setsansfont { Arial } [ Scale = MatchLowercase ]
+ \setmonofont { Courier~ New } [ Scale = MatchLowercase ]
+ }
+
+
+% TeX Gyre Termes
+\cs_new:Npn \examzh_font_set_font_termes:
+ {
+ \setmainfont { texgyretermes }
+ [
+ Extension = .otf ,
+ UprightFont = *-regular ,
+ BoldFont = *-bold ,
+ ItalicFont = *-italic ,
+ BoldItalicFont = *-bolditalic ,
+ ]
+ \examzh_font_set_tex_gyre_sans_mono:
+ }
+
+\cs_new:Npn \examzh_font_set_tex_gyre_sans_mono:
+ {
+ \setsansfont { texgyreheros }
+ [
+ Extension = .otf ,
+ UprightFont = *-regular ,
+ BoldFont = *-bold ,
+ ItalicFont = *-italic ,
+ BoldItalicFont = *-bolditalic ,
+ Scale = MatchLowercase ,
+ ]
+ \setmonofont { texgyrecursor }
+ [
+ Extension = .otf ,
+ UprightFont = *-regular ,
+ BoldFont = *-bold ,
+ ItalicFont = *-italic ,
+ BoldItalicFont = *-bolditalic ,
+ Scale = MatchLowercase ,
+ Ligatures = CommonOff ,
+ ]
+ }
+
+
+% STIX Two 字体。
+% STIX 文件名在 v2.10 2020-12-19 从
+% \file{STIX2Text-Regular.otf}、\file{STIX2Math.otf} 分别改为
+% \file{STIXTwoText-Regular.otf}、\file{STIXTwoMath-Regular.otf}。
+\tl_new:N \g__examzh_font_font_family_stix_tl
+\tl_new:N \g__examzh_font_font_name_stix_math_tl
+\cs_new:Npn \examzh_font_set_stix_names:
+ {
+ \tl_if_empty:NT \g__examzh_font_font_family_stix_tl
+ {
+ \fontspec_font_if_exist:nTF { STIXTwoText-Regular.otf }
+ {
+ \tl_gset:Nn \g__examzh_font_font_family_stix_tl { STIXTwoText }
+ \tl_gset:Nn \g__examzh_font_font_name_stix_math_tl { STIXTwoMath-Regular }
+ }
+ {
+ \tl_gset:Nn \g__examzh_font_font_family_stix_tl { STIX2Text }
+ \tl_gset:Nn \g__examzh_font_font_name_stix_math_tl { STIX2Math }
+ }
+ }
+ }
+
+\cs_new:Npn \examzh_font_set_font_stix:
+ {
+ \examzh_font_set_stix_names:
+ \setmainfont { \g__examzh_font_font_family_stix_tl }
+ [
+ Extension = .otf ,
+ UprightFont = *-Regular ,
+ BoldFont = *-Bold ,
+ ItalicFont = *-Italic ,
+ BoldItalicFont = *-BoldItalic ,
+ ]
+ \examzh_font_set_tex_gyre_sans_mono:
+ }
+
+
+% XITS 字体。
+% XITS 的文件名在 v1.109 2018-09-30
+% 从 \file{xits-regular.otf}、\file{xits-math.otf} 分别改为
+% \file{XITS-Regular.otf}、\file{XITSMath-Regular.otf}。
+\tl_new:N \g__examzh_font_font_family_xits_tl
+\tl_new:N \g__examzh_font_font_style_xits_rm_tl
+\tl_new:N \g__examzh_font_font_style_xits_bf_tl
+\tl_new:N \g__examzh_font_font_style_xits_it_tl
+\tl_new:N \g__examzh_font_font_style_xits_bfit_tl
+\tl_new:N \g__examzh_font_font_name_xits_math_tl
+
+\cs_new:Npn \examzh_font_set_xits_names:
+ {
+ \tl_if_empty:NT \g__examzh_font_font_family_xits_tl
+ {
+ \fontspec_font_if_exist:nTF { XITSMath-Regular.otf }
+ {
+ \tl_gset:Nn \g__examzh_font_font_family_xits_tl { XITS }
+ \tl_gset:Nn \g__examzh_font_font_style_xits_rm_tl { Regular }
+ \tl_gset:Nn \g__examzh_font_font_style_xits_bf_tl { Bold }
+ \tl_gset:Nn \g__examzh_font_font_style_xits_it_tl { Italic }
+ \tl_gset:Nn \g__examzh_font_font_style_xits_bfit_tl { BoldItalic }
+ \tl_gset:Nn \g__examzh_font_font_name_xits_math_tl { XITSMath-Regular }
+ }
+ {
+ \tl_gset:Nn \g__examzh_font_font_family_xits_tl { xits }
+ \tl_gset:Nn \g__examzh_font_font_style_xits_rm_tl { regular }
+ \tl_gset:Nn \g__examzh_font_font_style_xits_bf_tl { bold }
+ \tl_gset:Nn \g__examzh_font_font_style_xits_it_tl { italic }
+ \tl_gset:Nn \g__examzh_font_font_style_xits_bfit_tl { bolditalic }
+ \tl_gset:Nn \g__examzh_font_font_name_xits_math_tl { xits-math }
+ }
+ }
+ }
+
+\cs_new:Npn \examzh_font_set_font_xits:
+ {
+ \examzh_font_set_xits_names:
+ \setmainfont { \g__examzh_font_font_family_xits_tl }
+ [
+ Extension = .otf ,
+ UprightFont = *-\g__examzh_font_font_style_xits_rm_tl ,
+ BoldFont = *-\g__examzh_font_font_style_xits_bf_tl ,
+ ItalicFont = *-\g__examzh_font_font_style_xits_it_tl ,
+ BoldItalicFont = *-\g__examzh_font_font_style_xits_bfit_tl ,
+ ]
+ \examzh_font_set_tex_gyre_sans_mono:
+ }
+
+
+% Libertinus 的文件名在 v6.7 2019-04-03 从小写改为驼峰式,
+% 在大小写敏感的平台上需要进行判断。
+\tl_new:N \g__examzh_font_font_family_libertinus_serif_tl
+\tl_new:N \g__examzh_font_font_family_libertinus_sans_tl
+\tl_new:N \g__examzh_font_font_style_libertinus_rm_tl
+\tl_new:N \g__examzh_font_font_style_libertinus_bf_tl
+\tl_new:N \g__examzh_font_font_style_libertinus_it_tl
+\tl_new:N \g__examzh_font_font_style_libertinus_bfit_tl
+\tl_new:N \g__examzh_font_font_name_libertinus_math_tl
+
+\cs_new:Npn \examzh_font_set_libertinus_names:
+ {
+ \tl_if_empty:NT \g__examzh_font_font_family_libertinus_serif_tl
+ {
+ \fontspec_font_if_exist:nTF { LibertinusSerif-Regular.otf }
+ {
+ \tl_gset:Nn \g__examzh_font_font_family_libertinus_serif_tl { LibertinusSerif }
+ \tl_gset:Nn \g__examzh_font_font_family_libertinus_sans_tl { LibertinusSans }
+ \tl_gset:Nn \g__examzh_font_font_style_libertinus_rm_tl { Regular }
+ \tl_gset:Nn \g__examzh_font_font_style_libertinus_bf_tl { Bold }
+ \tl_gset:Nn \g__examzh_font_font_style_libertinus_it_tl { Italic }
+ \tl_gset:Nn \g__examzh_font_font_style_libertinus_bfit_tl { BoldItalic }
+ \tl_gset:Nn \g__examzh_font_font_name_libertinus_math_tl { LibertinusMath-Regular }
+ }
+ {
+ \tl_gset:Nn \g__examzh_font_font_family_libertinus_serif_tl { libertinusserif }
+ \tl_gset:Nn \g__examzh_font_font_family_libertinus_sans_tl { libertinussans }
+ \tl_gset:Nn \g__examzh_font_font_style_libertinus_rm_tl { regular }
+ \tl_gset:Nn \g__examzh_font_font_style_libertinus_bf_tl { bold }
+ \tl_gset:Nn \g__examzh_font_font_style_libertinus_it_tl { italic }
+ \tl_gset:Nn \g__examzh_font_font_style_libertinus_bfit_tl { bolditalic }
+ \tl_gset:Nn \g__examzh_font_font_name_libertinus_math_tl { libertinusmath-regular }
+ }
+ }
+ }
+
+\cs_new:Npn \examzh_font_set_font_libertinus:
+ {
+ \examzh_font_set_libertinus_names:
+ \setmainfont { \g__examzh_font_font_family_libertinus_serif_tl }
+ [
+ Extension = .otf ,
+ UprightFont = *-\g__examzh_font_font_style_libertinus_rm_tl ,
+ BoldFont = *-\g__examzh_font_font_style_libertinus_bf_tl ,
+ ItalicFont = *-\g__examzh_font_font_style_libertinus_it_tl ,
+ BoldItalicFont = *-\g__examzh_font_font_style_libertinus_bfit_tl ,
+ ]
+ \setsansfont { \g__examzh_font_font_family_libertinus_sans_tl }
+ [
+ Extension = .otf ,
+ UprightFont = *-\g__examzh_font_font_style_libertinus_rm_tl ,
+ BoldFont = *-\g__examzh_font_font_style_libertinus_bf_tl ,
+ ItalicFont = *-\g__examzh_font_font_style_libertinus_it_tl ,
+ ]
+ \setmonofont { lmmonolt10 }
+ [
+ Extension = .otf ,
+ UprightFont = *-regular ,
+ BoldFont = *-bold ,
+ ItalicFont = *-oblique ,
+ BoldItalicFont = *-boldoblique ,
+ ]
+ }
+
+
+% 数学字体
+
+% 按照国标样式配置 unicode-math
+
+\tl_new:N \l__examzh_save_leq_tl
+\tl_new:N \l__examzh_save_geq_tl
+
+\AtEndOfPackageFile* { unicode-math }
+ {
+ \unimathsetup
+ {
+ math-style = ISO ,
+ bold-style = ISO ,
+ partial = upright ,
+ }
+ \AtBeginDocument
+ {
+ \tl_set_eq:NN \leq \l__examzh_save_leq_tl
+ \tl_set_eq:NN \geq \l__examzh_save_geq_tl
+ \tl_set_eq:NN \leq \leqslant
+ \tl_set_eq:NN \geq \geqslant
+ }
+ \cs_set_protected:Npn \mathellipsis { \mathinner { \unicodecdots } }
+ }
+
+
+% 数学符号样式
+
+% \tl_new:N \l__examzh_font_uppercase_greek_tl
+% \tl_new:N \l__examzh_font_leq_style_tl
+\tl_new:N \l__examzh_font_integral_style_tl
+% \bool_new:N \l__examzh_font_integral_limits_bool
+% \tl_new:N \l__examzh_font_partial_style_tl
+% \tl_new:N \l__examzh_font_math_ellipsis_tl
+% \tl_new:N \l__examzh_font_real_part_tl
+
+\tl_set:Nn \l__examzh_font_integral_style_tl { upright }
+
+% \keys_define:nn { exam-zh }
+% {
+% math-style .choices:nn =
+% { GB , ISO , TeX }
+% { \exp_args:NV \examzh_font_set_math_style:n \l_keys_choice_tl } ,
+% uppercase-greek .choices:nn =
+% { italic , upright }
+% { \tl_set_eq:NN \l__examzh_font_uppercase_greek_tl \l_keys_choice_tl } ,
+% less-than-or-equal .choices:nn =
+% { slanted , horizontal }
+% { \tl_set_eq:NN \l__examzh_font_leq_style_tl \l_keys_choice_tl } ,
+% integral .choices:nn =
+% { upright , slanted }
+% { \tl_set_eq:NN \l__examzh_font_integral_style_tl \l_keys_choice_tl } ,
+% integral-limits .bool_set:N = \l__examzh_font_integral_limits_bool ,
+% partial .choices:nn =
+% { upright , slanted }
+% { \tl_set_eq:NN \l__examzh_font_partial_style_tl \l_keys_choice_tl } ,
+% math-ellipsis .choices:nn =
+% { centered , lower , AMS }
+% { \tl_set_eq:NN \l__examzh_font_math_ellipsis_tl \l_keys_choice_tl } ,
+% real-part .choices:nn =
+% { roman , fraktur }
+% { \tl_set_eq:NN \l__examzh_font_real_part_tl \l_keys_choice_tl } ,
+% }
+
+
+
+% New Computer Modern Math
+
+\tl_new:N \l__examzh_font_stylistic_set_tl
+
+\cs_new:Npn \examzh_font_set_math_font_newcm:
+ {
+ % \examzh_font_load_unimath:
+ % \examzh_font_set_unimath_style:
+ \tl_if_eq:NnTF \l__examzh_font_integral_style_tl { upright }
+ { \tl_set:Nn \l__examzh_font_stylistic_set_tl { 2 } }
+ { \tl_clear:N \l__examzh_font_stylistic_set_tl }
+ \setmathfont { NewCMMath-Book }
+ [
+ Extension = .otf,
+ StylisticSet = \l__examzh_font_stylistic_set_tl ,
+ ]
+ \setmathfont { NewCMMath-Book }
+ [
+ Extension = .otf,
+ StylisticSet = 1,
+ range = { scr , bfscr } ,
+ ]
+ \examzh_font_set_stix_names:
+ \setmathfont { \g__examzh_font_font_name_stix_math_tl }
+ [
+ Extension = .otf,
+ range = { \complement } ,
+ ]
+ \setmathrm { NewCM10 }
+ [
+ Extension = .otf,
+ UprightFont = *-Book,
+ BoldFont = *-Bold,
+ ItalicFont = *-BookItalic,
+ BoldItalicFont = *-BoldItalic,
+ ]
+ \setmathsf { NewCMSans10 }
+ [
+ Extension = .otf,
+ UprightFont = *-Book,
+ BoldFont = *-Bold,
+ ItalicFont = *-BookOblique,
+ BoldItalicFont = *-BoldOblique,
+ ]
+ \setmathtt { NewCMMono10 }
+ [
+ Extension = .otf,
+ UprightFont = *-Book,
+ ItalicFont = *-BookItalic,
+ BoldFont = *-Bold,
+ BoldItalicFont = *-BoldOblique,
+ ]
+ }
+
+
+% Latin Modern Math
+\cs_new:Npn \examzh_font_set_math_font_lm:
+ {
+ % \examzh_font_load_unimath:
+ % \examzh_font_set_unimath_style:
+ \setmathfont { latinmodern-math } [ Extension = .otf ]
+ \examzh_font_set_stix_names:
+ \setmathfont { \g__examzh_font_font_name_stix_math_tl }
+ [
+ Extension = .otf,
+ range = { \complement } ,
+ ]
+ \setmathrm { lmroman10 }
+ [
+ Extension = .otf,
+ UprightFont = *-regular,
+ BoldFont = *-bold,
+ ItalicFont = *-italic,
+ BoldItalicFont = *-bolditalic,
+ ]
+ \setmathsf { lmsans10 }
+ [
+ Extension = .otf,
+ UprightFont = *-regular,
+ BoldFont = *-bold,
+ ItalicFont = *-oblique,
+ BoldItalicFont = *-boldoblique,
+ ]
+ \setmathtt { lmmonolt10 }
+ [
+ Extension = .otf,
+ UprightFont = *-regular,
+ BoldFont = *-bold,
+ ItalicFont = *-oblique,
+ BoldItalicFont = *-boldoblique,
+ ]
+ }
+
+
+% STIX Two Math
+\cs_new:Npn \examzh_font_set_math_font_stix:
+ {
+ % \examzh_font_load_unimath:
+ % \examzh_font_set_unimath_style:
+ \examzh_font_set_stix_names:
+ \tl_if_eq:NnTF \l__examzh_font_integral_style_tl { upright }
+ { \tl_set:Nn \l__examzh_font_stylistic_set_tl { 8 } }
+ { \tl_clear:N \l__examzh_font_stylistic_set_tl }
+ \setmathfont { \g__examzh_font_font_name_stix_math_tl }
+ [
+ Extension = .otf,
+ StylisticSet = \l__examzh_font_stylistic_set_tl,
+ ]
+ \setmathfont { \g__examzh_font_font_name_stix_math_tl }
+ [
+ Extension = .otf,
+ StylisticSet = 1,
+ range = { scr , bfscr },
+ ]
+ }
+
+
+% XITS Math
+\cs_new:Npn \examzh_font_set_math_font_xits:
+ {
+ % \examzh_font_load_unimath:
+ % \examzh_font_set_unimath_style:
+ \examzh_font_set_xits_names:
+ \tl_if_eq:NnTF \l__examzh_font_integral_style_tl { upright }
+ { \tl_set:Nn \l__examzh_font_stylistic_set_tl { 8 } }
+ { \tl_clear:N \l__examzh_font_stylistic_set_tl }
+ \setmathfont { \g__examzh_font_font_name_xits_math_tl }
+ [
+ Extension = .otf ,
+ StylisticSet = \l__examzh_font_stylistic_set_tl ,
+ ]
+ \setmathfont { \g__examzh_font_font_name_xits_math_tl }
+ [
+ Extension = .otf ,
+ StylisticSet = 1 ,
+ range = { cal , bfcal } ,
+ ]
+ }
+
+% Libertinus Math
+\cs_new:Npn \examzh_font_set_math_font_libertinus: {
+ % \examzh_font_load_unimath:
+ % \examzh_font_set_unimath_style:
+ \examzh_font_set_libertinus_names:
+ \tl_if_eq:NnTF \l__examzh_font_integral_style_tl { slanted }
+ { \tl_set:Nn \l__examzh_font_stylistic_set_tl { 8 } }
+ { \tl_clear:N \l__examzh_font_stylistic_set_tl }
+ \setmathfont { \g__examzh_font_font_name_libertinus_math_tl }
+ [
+ Extension = .otf,
+ StylisticSet = \l__examzh_font_stylistic_set_tl,
+ ]
+ \examzh_font_set_stix_names:
+ \setmathfont { \g__examzh_font_font_name_stix_math_tl }
+ [
+ Extension = .otf,
+ range = { \complement } ,
+ ]
+}
+
+
+% Cambria Math
+\cs_new:Npn \examzh_font_set_math_font_cambria: {
+ % \examzh_font_load_unimath:
+ % \examzh_font_set_unimath_style:
+ \setmathfont { Cambria~ Math }
+ \examzh_font_set_stix_names:
+ \setmathfont { \g__examzh_font_font_name_stix_math_tl }
+ [
+ Extension = .otf,
+ range = { \complement } ,
+ ]
+}
+
+
+
+\AtEndPreamble
+ {
+ \tl_if_empty:NT \g__examzh_font_font_tl
+ { \keys_set:nn { exam-zh } { font = newcm } }
+ \tl_if_empty:NT \g__examzh_font_math_font_tl
+ { \keys_set:nn { exam-zh } { math-font = newcm } }
+ }
+
+
+% unicode-math 的配置
+
+% 兼容旧的粗体命令:\pkg{bm} 的 \cs{bm} 和 \pkg{amsmath} 的 \cs{boldsymbol}。
+\AtEndOfPackageFile* { unicode-math }
+ {
+ \NewDocumentCommand \bm { m } { { \symbfit { ##1 } } }
+ \RenewDocumentCommand \boldsymbol { m } { { \symbfit { ##1 } } }
+ % 兼容 \pkg{amsfonts} 和 \pkg{amssymb} 中的一些命令。
+ \NewDocumentCommand \square { } { \mdlgwhtsquare }
+ \NewDocumentCommand \blacksquare { } { \mdlgblksquare }
+ \AtBeginDocument
+ { \RenewDocumentCommand \checkmark { } { \ensuremath{ ✓ } } }
+ }
diff --git a/Master/texmf-dist/tex/latex/exam-zh/exam-zh-question.sty b/Master/texmf-dist/tex/latex/exam-zh/exam-zh-question.sty
new file mode 100644
index 00000000000..825a6ad991b
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/exam-zh/exam-zh-question.sty
@@ -0,0 +1,1260 @@
+%
+% Copyright (c) 2022 Zeping Lee
+% Released under the LaTeX Project Public License v1.3c License.
+% Repository: https://gitee.com/zepinglee/exam-zh
+%
+
+\NeedsTeXFormat{LaTeX2e}
+
+\RequirePackage{expl3}
+\RequirePackage{xparse}
+
+\ProvidesExplPackage {exam-zh-question} {2022-07-28} {v0.1.13}
+ {exam-zh question module}
+
+\RequirePackage { amsthm }
+\@ifpackageloaded { tcolorbox }
+ { \tcbuselibrary { breakable } }
+ { \RequirePackage [ most ] { tcolorbox } }
+\RequirePackage { zref-savepos }
+\RequirePackage { ulem }
+
+\ExplSyntaxOff
+\usetikzlibrary{shapes.misc}
+\ExplSyntaxOn
+
+
+
+\NewDocumentCommand \questionsetup { m }
+ { \keys_set:nn { exam-zh / question } { #1 } }
+\NewDocumentCommand \fillinsetup { m }
+ { \keys_set:nn { exam-zh / fillin } { #1 } }
+
+% ulem 宏包重定义了 \emph,使用 \normalem 恢复
+\normalem
+
+
+% question 环境相关变量
+
+% 计数器
+\int_new:N \g__examzh_question_index_int
+% 答案颜色
+\tl_new:N \l__examzh_question_answer_color_tl
+% 题目分数
+\int_new:N \l__examzh_question_points_int
+% 是否显示题目分数
+\bool_new:N \l__examzh_question_show_points_bool
+\bool_new:N \l__examzh_question_show_points_auto_bool
+% 题目分数是否单独成段,解答题需要单独成段
+\bool_new:N \l__examzh_question_points_separate_par_bool
+% 是否显示括号
+\bool_new:N \l__examzh_question_show_paren_bool
+% 是否显示答案
+\bool_new:N \l__examzh_question_show_answer_bool
+\bool_new:N \l__examzh_question_show_fillin_answer_bool
+\bool_new:N \l__examzh_question_show_paren_answer_bool
+% 上下的间距
+\skip_new:N \l__examzh_question_top_sep_skip
+\skip_new:N \l__examzh_question_bottom_sep_skip
+% label 的对齐
+\tl_new:N \l__examzh_question_label_align_tl
+
+
+\keys_define:nn { exam-zh }
+ { question .meta:nn = { exam-zh / question } {#1} }
+
+
+\keys_define:nn { exam-zh / question }
+ {
+ % 手动调整 question 环境的计数器
+ index .int_gset:N = \g__examzh_question_index_int ,
+ % 分数
+ points .int_set:N = \l__examzh_question_points_int ,
+ % 分数显示控制
+ show-points .choice: ,
+ show-points / auto .code:n =
+ { \bool_set_true:N \l__examzh_question_show_points_auto_bool } ,
+ show-points / true .code:n =
+ {
+ \bool_set_true:N \l__examzh_question_show_points_bool
+ \bool_set_false:N \l__examzh_question_show_points_auto_bool
+ } ,
+ show-points / false .code:n =
+ {
+ \bool_set_false:N \l__examzh_question_show_points_bool
+ \bool_set_false:N \l__examzh_question_show_points_auto_bool
+ } ,
+ % 分数是否单独成段
+ points-separate-par .bool_set:N = \l__examzh_question_points_separate_par_bool ,
+ % 是否显示答案
+ % show-answer .bool_set:N = \l__examzh_question_show_answer_bool ,
+ show-answer .choice: ,
+ show-answer / true .code:n =
+ {
+ \bool_set_true:N \l__examzh_question_show_fillin_answer_bool
+ \bool_set_true:N \l__examzh_question_show_paren_answer_bool
+ },
+ show-answer / false .code:n =
+ {
+ \bool_set_false:N \l__examzh_question_show_fillin_answer_bool
+ \bool_set_false:N \l__examzh_question_show_paren_answer_bool
+ },
+ % 上方间距
+ top-sep .skip_set:N = \l__examzh_question_top_sep_skip ,
+ % 下方间距
+ bottom-sep .skip_set:N = \l__examzh_question_bottom_sep_skip ,
+ label .tl_set:N = \l__examzh_question_label_tl,
+ combine-fillin .bool_set:N = \l__examzh_question_combine_fillin_bool,
+ combine-fillin-args .tl_set:N = \l__examzh_question_combine_fillin_args_tl,
+ label-align .choices:nn =
+ { left, center, right }
+ { \tl_set_eq:NN \l__examzh_question_label_align_tl \l_keys_choice_tl }
+ }
+
+\keys_set:nn { exam-zh / question }
+ {
+ index = 1,
+ points = 0 ,
+ show-points = auto ,
+ points-separate-par = false ,
+ show-answer = false ,
+ top-sep = .25em plus .25em minus .1em ,
+ bottom-sep = .25em plus .25em minus .1em ,
+ label = \arabic*.,
+ combine-fillin = false,
+ label-align = right
+ }
+
+
+
+% 是否按照解答题的格式排版
+\bool_new:N \l__examzh_question_problem_style_bool
+
+
+% 选择题和填空题的题干
+\NewDocumentEnvironment { question } { O { } +b }
+ {
+ \bool_set_false:N \l__examzh_question_problem_style_bool
+ \__examzh_question_begin:nn {#1}{#2}
+ }
+ { \__examzh_question_end:nn {#1}{#2} }
+
+% 解答题
+\NewDocumentEnvironment { problem } { O { } +b }
+ {
+ \bool_set_true:N \l__examzh_question_problem_style_bool
+ \__examzh_question_begin:nn {#1}{#2}
+ }
+ { \__examzh_question_end:nn {#1}{#2} }
+
+\prg_generate_conditional_variant:Nnn \int_compare:nNn { xNn } { T }
+\cs_new:Npn \__examzh_question_begin:nn #1#2
+ {
+ \par
+ % 根据是否按解答题方式排版来设置是否分数要分段
+ \bool_if:NTF \l__examzh_question_problem_style_bool
+ { \keys_set:nn { exam-zh / question } { points-separate-par = true } }
+ { \keys_set:nn { exam-zh / question } { points-separate-par = false } }
+ % \bool_if:NTF \l__examzh_question_combine_fillin_bool
+ % { \keys_set:nn { exam-zh / question } { label-align = left } }
+ % { \keys_set:nn { exam-zh / question } { label-align = right } }
+ % 设置键值
+ \keys_set:nn { exam-zh / question } { #1 }
+ % 题干计数器的值加一
+ \int_gincr:N \g__examzh_question_index_int
+ % 设置上方间距
+ % \addvspace { \l__examzh_question_top_sep_skip }
+ \vspace { \l__examzh_question_top_sep_skip }
+ % 严格禁止孤行和寡行
+ \int_set:Nn \clubpenalty { 10000 }
+ \int_set:Nn \widowpenalty { 10000 }
+ % 尽量避免在题目中间换行
+ \int_set:Nn \interlinepenalty { 301 }
+ % 这部分是仿照 source2e 中 enumerate 的定义写的
+ % \@enumdepth 主要控制 enumerate 不同层级的编号
+ % 这样设置后,在 question 中使用 enumerate 会调用 level 2 的编号
+ % 也就是 question 中的 enumerate 环境直接从第二层开始
+ \int_incr:N \@enumdepth
+ % 如果 show-points = auto 那么解答题显示分数,选择题和填空题不显示分数
+ % 这样设置考虑到选择题和填空题都是每道题一样的分数,在最开始的地方说明即可
+ % 而解答题不太一样
+ \bool_if:NT \l__examzh_question_show_points_auto_bool
+ {
+ \bool_if:NTF \l__examzh_question_problem_style_bool
+ { \bool_set_true:N \l__examzh_question_show_points_bool }
+ { \bool_set_false:N \l__examzh_question_show_points_bool }
+ }
+ % 使用列表环境输出
+ \list
+ {
+ % \int_use:N \g__examzh_question_index_int .
+ \__examzh_question_make_label:n
+ {
+ \bool_if:NT \l__examzh_question_combine_fillin_bool
+ {
+ \tl_if_blank:VTF \l__examzh_question_combine_fillin_args_tl
+ { \fillin }
+ {
+ \use:x
+ {
+ \exp_not:N \fillin \l__examzh_question_combine_fillin_args_tl
+ }
+ }
+ }
+ \int_compare:xNnT { \g__examzh_question_index_int } < { 11 }
+ { \phantom {1} }
+ \__examzh_question_the_label:
+ }
+ }
+ {
+ % 用 group 是为了防止 combine-fillin 的 type 影响了环境里面的 fillin 的type
+ \group_begin:
+ \dim_gset:Nn \topsep { 0pt }
+ \dim_gset:Nn \partopsep { 0pt }
+ \dim_gset:Nn \itemsep { 0pt }
+ \dim_gset:Nn \parsep { 0pt }
+ % \group_begin:
+ % 上面 \fillin 里面的设置是局部的,这样的问题是 question 的可选参数改 type 的时候不会影响 \l__examzh_fillin_type_str 的值
+ % 所以要把 \l__examzh_question_combine_fillin_args_tl 里关于 type 的选取出来
+ \__examzh_question_begin_fillin_type_set:
+ \__examzh_question_begin_labelsep_labelwidth_set:
+ % \group_end:
+ \bool_if:NTF \l__examzh_question_problem_style_bool
+ {
+ % 解答题是正文 + 缩进 2em 的效果
+ \bool_if:NTF \l__examzh_question_combine_fillin_bool
+ {
+ % 如果 combine 的话就和 question 一样的缩进
+ \dim_gset:Nn \leftmargin { 6em }
+ \dim_gset:Nn \itemindent { 0pt }
+ }
+ {
+ \dim_gset:Nn \leftmargin { 0pt }
+ \dim_gset:Nn \itemindent { 2em }
+ }
+ }
+ {
+ % 选择和填空题是悬挂效果
+ \bool_if:NTF \l__examzh_question_combine_fillin_bool
+ % {
+ % \str_case:VnF \l__examzh_question_label_align_tl
+ % {
+ % { left } { \dim_set:Nn \leftmargin { 8em } }
+ % }
+ { \dim_gset:Nn \leftmargin { 6em } }
+ % }
+ { \dim_gset:Nn \leftmargin { 2em } }
+ \dim_set:Nn \itemindent { 0pt }
+ }
+ \dim_gset_eq:NN \listparindent \itemindent
+ \group_end:
+ }
+ \item \relax
+ % 输出题目分数
+ \bool_if:NT \l__examzh_question_show_points_bool
+ {
+ % 如果设置了分数且 show-points 的 bool 是 true 的话就显示
+ \int_compare:nNnT { \l__examzh_question_points_int } > { 0 }
+ { ( \int_use:N \l__examzh_question_points_int ~ 分 ) }
+ % 是否分段(解答题需要分段)
+ \bool_if:NT \l__examzh_question_points_separate_par_bool
+ % \par 分段之后使用 \nopagebreak 避免分页导致序号和分数出现在页面最后一行
+ { \par \nopagebreak }
+ }
+ }
+\int_new:N \l__examzh_question_begin_fillin_args_bracket_num_int
+\cs_generate_variant:Nn \regex_count:nnN { nVN }
+\prg_generate_conditional_variant:Nnn \regex_extract_once:nnN { nxN } { F }
+\cs_new:Npn \__examzh_question_begin_fillin_type_set:
+ {
+ \regex_count:nVN { \[ } %]
+ \l__examzh_question_combine_fillin_args_tl
+ \l__examzh_question_begin_fillin_args_bracket_num_int
+ % \int_use:N \l__examzh_question_begin_fillin_args_bracket_num_int
+ \int_compare:nNnT { \l__examzh_question_begin_fillin_args_bracket_num_int } = {2}
+ {
+ \regex_extract_once:nxNF { \[ (.*?) \] } { \l__examzh_question_combine_fillin_args_tl } \l_tmpa_seq { \fail }
+ \seq_pop_left:NN \l_tmpa_seq \l_tmpa_tl
+ % \seq_use:Nn \l_tmpa_seq {,}
+ \keys_set:nx { exam-zh / fillin } { \seq_use:Nn \l_tmpa_seq {,} }
+ }
+ }
+\cs_new:Npn \__examzh_question_begin_labelsep_labelwidth_set:
+ {
+ \bool_if:NTF \l__examzh_question_combine_fillin_bool
+ {
+ \str_case:Vn \l__examzh_question_label_align_tl
+ {
+ { left }
+ {
+ \str_case:VnF \l__examzh_fillin_type_str
+ {
+ { paren }
+ {
+ % combin-left-paren
+ \dim_gset:Nn \labelsep { 2.8em }
+ \dim_gset:Nn \labelwidth { 4.2em }
+ }
+ { line }
+ {
+ % combin-left-line
+ \dim_gset:Nn \labelsep { 2.4em }
+ \dim_gset:Nn \labelwidth { 3.8em }
+ }
+ }
+ {
+ % combin-left-paren/line 外的
+ \dim_gset:Nn \labelsep { 2.8em }
+ \dim_gset:Nn \labelwidth { 1.3em }
+ }
+ }
+ { center }
+ {
+ \str_case:VnF \l__examzh_fillin_type_str
+ {
+ { paren }
+ {
+ % combin-center-paren
+ \dim_gset:Nn \labelsep { 2em }
+ \dim_gset:Nn \labelwidth { 5em }
+ }
+ { line }
+ {
+ % combin-center-line
+ \dim_gset:Nn \labelsep { 2.8em }
+ \dim_gset:Nn \labelwidth { 4em }
+ }
+ }
+ {
+ % combin-center-paren/line 外的
+ \dim_gset:Nn \labelsep { 2em }
+ \dim_gset:Nn \labelwidth { 1.3em }
+ }
+ }
+ { right }
+ {
+ \dim_gset:Nn \labelsep { .7em }
+ \dim_gset:Nn \labelwidth { 1.3em }
+ }
+ }
+ }
+ {
+ \str_case:Vn \l__examzh_question_label_align_tl
+ {
+ { left }
+ {
+ \dim_gset:Nn \labelsep { .7em }
+ \dim_gset:Nn \labelwidth { 1.8em }
+ }
+ { center }
+ {
+ \dim_gset:Nn \labelsep { .7em }
+ \dim_gset:Nn \labelwidth { 1.3em }
+ }
+ { right }
+ {
+ \dim_gset:Nn \labelsep { .7em }
+ \dim_gset:Nn \labelwidth { 1.3em }
+ }
+ }
+
+ }
+ }
+
+\cs_new:Npn \__examzh_question_end:nn #1#2
+ {
+ #2
+ % 结束列表环境
+ \endlist
+ % 增加下方间距
+ % \addvspace { \l__examzh_question_bottom_sep_skip }
+ \vspace { \l__examzh_question_bottom_sep_skip }
+ }
+
+% 处理 question / problem 的 label
+\tl_new:N \l__examzh_question_counters_commands_set_tl
+
+\cs_new:Npn \__examzh_question_the_label:
+ {
+ \group_begin:
+ % 定义计数器相关的命令函数
+ \l__examzh_question_counters_commands_set_tl
+ % 输出处理后的 label
+ \l__examzh_question_label_tl
+ \group_end:
+ }
+\cs_new:Npn \__examzh_question_make_label:n #1
+ {
+ \str_case:Vn \l__examzh_question_label_align_tl
+ {
+ { left } { \rlap { #1 } \hss }
+ { center } { \hss \clap { #1 } \hss }
+ { right } { \hss \llap { #1 } }
+ }
+ }
+\NewDocumentCommand \AddQuestionCounter { m m }
+ {
+ % 生成用户层命令
+ \tl_put_right:Nn \l__examzh_question_counters_commands_set_tl
+ { \__examzh_process_counter:NNn #1 #2 { question } }
+ % 把核心函数存起来
+ \cs_set_eq:cN { __examzh_question_save_ \cs_to_str:N #1 : } #2
+ \cs_set_eq:cN { __examzh_question_save_ \cs_to_str:N #2 : } #2
+ }
+
+\AddQuestionCounter \arabic \@arabic
+\AddQuestionCounter \alph \@alph
+\AddQuestionCounter \Alph \@Alph
+\AddQuestionCounter \roman \@roman
+\AddQuestionCounter \Roman \@Roman
+
+\cs_new:Npn \__examzh_process_counter:NNn #1#2#3
+ % #1: \Alph
+ % #2: \@Alph
+ % #3: question / fillin
+ {
+ \cs_set:Npn #1 { \use:c { __examzh_ #3 _process_counter_aux:Nn } #2 }
+ \cs_set:Npn #2 { \use:c { __examzh_ #3 _process_counter_aux:Nn } #2 }
+ }
+
+\cs_new:Npn \__examzh_question_process_counter_aux:Nn #1#2
+ {
+ \tl_if_eq:nnTF {#2} { * }
+ {
+ % \Alph*
+ \use:c { __examzh_question_save_ \cs_to_str:N #1 : }
+ { \int_eval:n { \g__examzh_question_index_int - 1 } }
+ }
+ {
+ % \Alph{...}
+ \use:c { __examzh_question_save_ \cs_to_str:N #1 : }
+ {#2}
+ }
+ }
+
+
+% 处理 fillin/no-answer-type = counter 的 label
+\tl_new:N \l__examzh_fillin_counters_commands_set_tl
+
+
+\cs_new:Npn \__examzh_fillin_the_label:
+ {
+ \group_begin:
+ % 定义计数器相关的命令函数
+ \l__examzh_fillin_counters_commands_set_tl
+ % 输出处理后的 label
+ \l__examzh_fillin_label_tl
+ \group_end:
+ }
+
+\NewDocumentCommand \AddFillinCounter { m m }
+ {
+ % 生成用户层命令
+ \tl_put_right:Nn \l__examzh_fillin_counters_commands_set_tl
+ { \__examzh_process_counter:NNn #1 #2 { fillin } }
+ % 把核心函数存起来
+ \cs_set_eq:cN { __examzh_fillin_save_ \cs_to_str:N #1 : } #2
+ \cs_set_eq:cN { __examzh_fillin_save_ \cs_to_str:N #2 : } #2
+ }
+
+\AddFillinCounter \arabic \@arabic
+\AddFillinCounter \alph \@alph
+\AddFillinCounter \Alph \@Alph
+\AddFillinCounter \roman \@roman
+\AddFillinCounter \Roman \@Roman
+
+\cs_new:Npn \__examzh_fillin_process_counter_aux:Nn #1#2
+ {
+ \tl_if_eq:nnTF {#2} { * }
+ {
+ % \Alph*
+ \use:c { __examzh_fillin_save_ \cs_to_str:N #1 : }
+ { \int_eval:n { \g__examzh_fillin_no_answer_counter_int - 1 } }
+ }
+ {
+ % \Alph{...}
+ \use:c { __examzh_fillin_save_ \cs_to_str:N #1 : }
+ {#2}
+ }
+ }
+
+% 使用中文字体直接输出 unicode 带圈数字
+% \circlednumber 的参数既可以接受 LaTeX2e 的 <counter>,也可以直接接受 <intexpr>。
+\NewDocumentCommand \circlednumber { s m }
+ {
+ \int_if_exist:cTF { c@ #2 }
+ { \int_set_eq:Nc \l_tmpa_int { c@#2 } }
+ { \int_set:Nn \l_tmpa_int { #2 } }
+ \IfBooleanTF {#1}
+ {
+ \exp_args:Nx \__examzh_tikz_circled_number:n { \int_use:N \l_tmpa_int }
+ }
+ {
+ \exp_args:Nx \__examzh_question_circled_number:n { \int_use:N \l_tmpa_int }
+ }
+ }
+
+\cs_new:Npn \__examzh_circled_number:nn #1#2
+ {
+ \int_set:Nn \l_tmpa_int {#1}
+ \int_compare:nNnTF { \l_tmpa_int } = { 0 }
+ { \int_set:Nn \l_tmpa_int { "24EA } }
+ {
+ \int_compare:nNnTF { \l_tmpa_int } < { 21 }
+ { \int_add:Nn \l_tmpa_int { "245F } }
+ {
+ \int_compare:nNnTF { \l_tmpa_int } < { 36 }
+ { \int_add:Nn \l_tmpa_int { "3250 } }
+ {
+ \int_compare:nNnTF { \l_tmpa_int } < { 51 }
+ { \int_add:Nn \l_tmpa_int { "32B0 } }
+ {
+ \msg_error:nnn { exam-zh / #2 }
+ { invalid-circled-number } { \int_use:N \l_tmpa_int }
+ }
+ }
+ }
+ }
+ \group_begin:
+ \CJKfamily+ { }
+ \symbol { \l_tmpa_int }
+ \group_end:
+ }
+
+\msg_new:nnn { exam-zh / question } { invalid-circled-number }
+{ Invalid~ circled~ number~ #1. }
+
+\msg_new:nnn { exam-zh / fillin } { invalid-circled-number }
+{ Invalid~ circled~ number~ #1. }
+
+\cs_new:Npn \__examzh_question_circled_number:n #1
+ { \__examzh_circled_number:nn {#1} { question } }
+\cs_new:Npn \__examzh_fillin_circled_number:n #1
+ { \__examzh_circled_number:nn {#1} { fillin } }
+
+\AddQuestionCounter \circlednumber \__examzh_question_circled_number:n
+\AddFillinCounter \circlednumber \__examzh_fillin_circled_number:n
+
+% tikz 绘制带圈数字
+\fp_new:N \l__examzh_tikz_circled_number_xscale_fp % 水平压缩系数
+\fp_new:N \l__examzh_tikz_circled_number_yscale_fp % 垂直压缩系数
+\dim_new:N \l__examzh_tikz_circled_number_total_hegiht_dim % 数字的总高度
+\dim_new:N \l__examzh_tikz_circled_number_radius_dim % 半径
+
+\cs_new:Npn \__examzh_tikz_circled_number_aux:n #1
+ {
+ % 根据数字大小设置压缩系数
+ \fp_set:Nn \l__examzh_tikz_circled_number_xscale_fp
+ {
+ \int_compare:nNnTF {#1} < { 10 }
+ { 0.9 }
+ {
+ \int_compare:nNnTF {#1} < { 100 }
+ { 0.7 }
+ { 0.5 }
+ }
+ }
+ \fp_set:Nn \l__examzh_tikz_circled_number_yscale_fp
+ {
+ \int_compare:nNnTF {#1} < { 10 }
+ { 0.9 }
+ {
+ \int_compare:nNnTF {#1} < { 100 }
+ { 0.8 }
+ { 0.6 }
+ }
+ }
+ % 获取数字的高度
+ \hbox_set:Nn \l_tmpa_box {#1}
+ \dim_set:Nn \l__examzh_tikz_circled_number_total_hegiht_dim
+ { \box_ht:N \l_tmpa_box + \box_dp:N \l_tmpa_box }
+ % 设置圆的半径
+ \dim_set:Nn \l__examzh_tikz_circled_number_radius_dim
+ { \dim_eval:n { \l__examzh_tikz_circled_number_total_hegiht_dim / 2 + 0.34 ex } }
+ % 绘制
+ \tikz [ baseline ]
+ {
+ \node
+ [ inner~sep = 0pt, outer~sep = 0pt ]
+ at (0, \dim_use:N \l__examzh_tikz_circled_number_total_hegiht_dim / 2 )
+ {
+ \hbox_set:Nn \l_tmpa_box
+ {
+ \int_compare:nNnTF {#1} > {9}
+ { \textbf {#1} }
+ {#1}
+ }
+ \makebox[0.35em][c]
+ {
+ % \scalebox { \fp_use:N \l__examzh_tikz_circled_number_xscale_fp }
+ % [ \fp_use:N \l__examzh_tikz_circled_number_yscale_fp ]
+ \box_scale:Nnn \l_tmpa_box
+ { \fp_use:N \l__examzh_tikz_circled_number_xscale_fp }
+ { \fp_use:N \l__examzh_tikz_circled_number_yscale_fp }
+ \box_use_drop:N \l_tmpa_box
+ }
+ };
+ \draw (0, \l__examzh_tikz_circled_number_total_hegiht_dim / 2 )
+ circle ( \l__examzh_tikz_circled_number_radius_dim );
+ }
+ }
+\cs_new:Npn \__examzh_tikz_circled_number:n #1
+ {
+ \__examzh_tikz_circled_number_aux:n { \int_eval:n {#1} }
+ }
+\AddQuestionCounter \tikzcirclednumber \__examzh_tikz_circled_number:n
+\AddFillinCounter \tikzcirclednumber \__examzh_tikz_circled_number:n
+
+% 选择题括号
+% 控制括号是否右对齐
+\bool_new:N \l__examzh_paren_type_hfill_bool
+\keys_define:nn { exam-zh / paren }
+ {
+ show-answer .bool_set:N = \l__examzh_question_show_paren_answer_bool,
+ text-color .tl_set:N = \l__examzh_paren_text_color_tl ,
+ % 是否显示选择题的括号
+ show-paren .bool_set:N = \l__examzh_question_show_paren_bool ,
+ type .choice:,
+ type / hfill .code:n =
+ {
+ \bool_set_true:N \l__examzh_paren_type_hfill_bool
+ },
+ type / none .code:n =
+ {
+ \bool_set_false:N \l__examzh_paren_type_hfill_bool
+ },
+ }
+\keys_set:nn { exam-zh / paren }
+ {
+ show-answer = false,
+ text-color = black,
+ show-paren = false,
+ type = hfill
+ }
+\keys_define:nn { exam-zh }
+ { paren .meta:nn = { exam-zh / paren } {#1} }
+\NewDocumentCommand \paren { O { } }
+ {
+ % 如果开了 show answer 就默认 show paren
+ \bool_if:NT \l__examzh_question_show_paren_answer_bool
+ { \bool_set_true:N \l__examzh_question_show_paren_bool }
+ \bool_if:NT \l__examzh_question_show_paren_bool
+ {
+ % 使括号单独成行时居于右侧
+ % \null -> \hbox{}
+ % 𝖅𝖊𝖕𝖎𝖓𝖌 𝕷𝖊𝖊, [Mar 19, 2022 at 22:47:07]:
+ % 这个写法是为了处理这样的情况:假设括号需要 3em 宽度,但是如果题干末尾只剩下了 2em 的空白,括号就必要另起一行,并且用 \hill 把括号推到最右侧
+ % 所以中间用了两个 \hfill
+ % 至于 \nobreak 和 \allowbreak 大概是为了能够同时处理「括号不换行」和「括号换行」两种情况
+ % 这里参考 source2e 的 \@dottedtocline(目录的格式)
+ % 控制是否 hfill 到行尾
+ \bool_if:NT \l__examzh_paren_type_hfill_bool
+ {
+ \nobreak \hfill \allowbreak
+ \null \nobreak \hfill \nobreak
+ }
+ \hbox:n
+ {
+ (
+ \hbox_to_wd:nn { 3em }
+ {
+ \bool_if:NT \l__examzh_question_show_paren_answer_bool
+ { \hfill \__examzh_paren_print_answer:n {#1} \hfill }
+ }
+ ) \kern -.4em
+ }
+ }
+ }
+% “打印出”答案内容 因为 show 被用作“显示与否”的含义了,所以此处用 print
+\cs_new:Npn \__examzh_fillin_print_answer:n #1
+ {
+ % \group_begin:
+ \tl_if_eq:NnF \l__examzh_fillin_text_color_tl { black }
+ { \exp_args:NV \color \l__examzh_fillin_text_color_tl }
+ #1
+ % \group_end:
+ }
+\cs_new:Npn \__examzh_paren_print_answer:n #1
+ {
+ \group_begin:
+ \tl_if_eq:NnF \l__examzh_paren_text_color_tl { black }
+ { \exp_args:NV \color \l__examzh_paren_text_color_tl }
+ #1
+ \group_end:
+ }
+
+
+% fillin 的下划线样式控制
+\str_new:N \l__examzh_fillin_type_str
+
+% 不显示答案时显示的类型
+\str_new:N \l__examzh_fillin_no_answer_type_str
+
+% no-answer-type = counter 的计数器
+\int_new:N \g__examzh_fillin_no_answer_counter_int
+
+\keys_define:nn { exam-zh / fillin }
+ {
+ type .code:n =
+ {
+ \str_set:Nn \l__examzh_fillin_type_str {#1}
+ },
+ show-answer .bool_set:N = \l__examzh_question_show_fillin_answer_bool,
+ width .skip_set:N = \l__examzh_fillin_F_width_skip,
+ color .tl_set:N = \l__examzh_fillin_color_tl,
+ text-color .tl_set:N = \l__examzh_fillin_text_color_tl,
+ no-answer-type .choices:nn =
+ { blacktriangle, counter, none }
+ { \str_set:Nx \l__examzh_fillin_no_answer_type_str { \l_keys_choice_tl } },
+ no-answer-counter-index .int_gset:N = \g__examzh_fillin_no_answer_counter_int,
+ no-answer-counter-label .tl_set:N = \l__examzh_fillin_label_tl
+ }
+\keys_set:nn { exam-zh / fillin }
+ {
+ type = line,
+ show-answer = false,
+ width = 3em plus 1em minus 1em,
+ color = black,
+ text-color = black,
+ no-answer-type = blacktriangle,
+ no-answer-counter-index = 1,
+ no-answer-counter-label = \arabic*
+ }
+
+\keys_define:nn { exam-zh }
+ { fillin .meta:nn = { exam-zh / fillin } {#1} }
+
+
+\dim_new:N \l__examzh_question_answer_depth_dim
+
+% 填空命令
+% \fillin \fillin[] \fillin[][] 在 show-answer = false 的情况下
+% no-answer-type = blacktriangle 就显示黑色三角形
+% no-answer-type = counter :计数器(设计来源于完形填空)
+% no-answer-type = none :不显示
+\NewDocumentCommand \fillin { s O{} o }
+ {
+ \group_begin:
+ \IfNoValueTF {#3}
+ {
+ \bool_if:NTF \l__examzh_question_show_fillin_answer_bool
+ {
+ % 显示答案
+ \IfBooleanTF {#1}
+ {
+ % \fillin*[]
+ \__examzh_fillin_breakline:n {#2}
+ }
+ {
+ % \fillin[]
+ \__examzh_fillin:n {#2}
+ }
+ }
+ {
+ % 不显示答案
+ \__examzh_fillin_no_answer_typeset:
+ }
+ }
+ {
+ \keys_set:nn { exam-zh / fillin }
+ {#2}
+ \bool_if:NTF \l__examzh_question_show_fillin_answer_bool
+ {
+ % 显示答案
+ \IfBooleanTF {#1}
+ {
+ % \fillin*[][]
+ \__examzh_fillin_breakline:n {#3}
+ }
+ {
+ % \fillin[][]
+ \__examzh_fillin:n {#3}
+ }
+ }
+ {
+ % 不显示答案
+ \__examzh_fillin_no_answer_typeset:
+ }
+ }
+ \group_end:
+ \space \ignorespaces
+ }
+\msg_new:nnn { exam-zh / fillin } { no-such-noanswertype }
+ {
+ There~is~no~such~noanswertype~named~#1!\\
+ Please~read~the~manual~carefully!
+ }
+\cs_new:Npn \__examzh_fillin_no_answer_typeset:
+ {
+ \str_case:VnF \l__examzh_fillin_no_answer_type_str
+ {
+ { blacktriangle } { \__examzh_fillin_no_answer_typeset_blacktriangle: }
+ { counter } { \__examzh_fillin_no_answer_typeset_counter: }
+ { none } { \__examzh_fillin_no_answer_typeset_none: }
+ }
+ {
+ \msg_error:nnx { exam-zh / fillin } { no-such-noanswertype }
+ { \l__examzh_fillin_no_answer_type_str }
+ }
+ }
+\cs_new:Npn \__examzh_fillin_no_answer_typeset_blacktriangle:
+ {
+ \__examzh_fillin_without_judge:n { \__examzh_fillin_blacktriangle: }
+ }
+\cs_new:Npn \__examzh_fillin_no_answer_typeset_counter:
+ {
+ \int_gincr:N \g__examzh_fillin_no_answer_counter_int
+ \__examzh_fillin_without_judge:n
+ { \__examzh_fillin_the_label: }
+ % { \int_eval:n { \g__examzh_fillin_no_answer_counter_int - 1 } }
+ }
+\cs_new:Npn \__examzh_fillin_no_answer_typeset_none:
+ {
+ \__examzh_fillin_output_F:
+ }
+\cs_new:Npn \__examzh_fillin_without_judge:n #1
+ {
+ % \ULdepth 是 \uline 的下划线的深度
+ \dim_set:Nn \ULdepth { 0.3em }
+ % lazy 版本是指需要判断时才去获取当前用于判断的 bool 值
+ % 而不是类似于“提前展开”,和项子越在 LaTeX3 的 b站视频里讲到的 lazy evaluation 想法相同
+ \hbox_set:Nn \l_tmpa_box { \__examzh_fillin_print_answer:n {#1} }
+ \dim_set:Nn \l__examzh_question_answer_depth_dim
+ { \box_dp:N \l_tmpa_box }
+ \__examzh_fillin_output_T:
+ }
+\cs_new:Npn \__examzh_fillin:n #1
+ {
+ % \ULdepth 是 \uline 的下划线的深度
+ \dim_set:Nn \ULdepth { 0.3em }
+ % lazy 版本是指需要判断时才去获取当前用于判断的 bool 值
+ % 而不是类似于“提前展开”,和项子越在 LaTeX3 的 b站视频里讲到的 lazy evaluation 想法相同
+ \bool_lazy_and:nnTF
+ { \bool_if_p:N \l__examzh_question_show_fillin_answer_bool }
+ { \bool_not_p:n { \tl_if_empty_p:n {#1} } }
+ {
+ \hbox_set:Nn \l_tmpa_box { \__examzh_fillin_print_answer:n {#1} }
+ \dim_set:Nn \l__examzh_question_answer_depth_dim
+ { \box_dp:N \l_tmpa_box }
+ \__examzh_fillin_output_T:
+ }
+ {
+ \__examzh_fillin_output_F:
+ }
+ }
+\cs_new:Npn \__examzh_fillin_breakline:n #1
+ {
+ \bool_lazy_and:nnTF
+ { \bool_if_p:N \l__examzh_question_show_fillin_answer_bool }
+ { \bool_not_p:n { \tl_if_empty_p:n {#1} } }
+ {
+ \tl_set:Nn \l_tmpa_tl { \__examzh_fillin_print_answer:n {#1} }
+ \__examzh_fillin_output_breakline_T:
+ }
+ {
+ \__examzh_fillin_output_F:
+ }
+ }
+\msg_new:nnn { exam-zh } { no-fillin-type }
+ {
+ There~is~no~type~of~\fillin~named~#1!\\
+ Please~read~the~manual~for~more~details.
+ }
+\cs_new:Npn \__examzh_fillin_output_T:
+ {
+ \str_case:VnF \l__examzh_fillin_type_str
+ {
+ { line } { \__examzh_fillin_uline_T: }
+ { paren } { \__examzh_fillin_paren_T: }
+ { circle } { \__examzh_fillin_circle_T: }
+ { blank } { \__examzh_fillin_blank_T: }
+ { rectangle } { \__examzh_fillin_rectangle_T: }
+ }
+ {
+ \msg_error:nnx { exam-zh } { no-fillin-type }
+ { \l__examzh_fillin_type_str }
+ }
+ }
+\cs_new:Npn \__examzh_fillin_output_breakline_T:
+ {
+ \str_case:VnF \l__examzh_fillin_type_str
+ {
+ { line } { \__examzh_fillin_uline_breakline_T: }
+ { paren } { \__examzh_fillin_paren_breakline_T: }
+ { blank } { \__examzh_fillin_blank_breakline_T: }
+ }
+ {
+ \msg_error:nnx { exam-zh } { no-breakable-fillin-type }
+ { \l__examzh_fillin_type_str }
+ }
+ }
+\msg_new:nnn { exam-zh } { no-breakable-fillin-type }
+ {
+ The~type~:~#1~ cannot~be~used~in~breakable~fillin~cmd.
+ }
+\cs_new:Npn \__examzh_fillin_output_F:
+ {
+ \str_case:VnF \l__examzh_fillin_type_str
+ {
+ { line } { \__examzh_fillin_uline_F: }
+ { paren } { \__examzh_fillin_paren_F: }
+ { circle } { \__examzh_fillin_circle_F: }
+ { blank } { \__examzh_fillin_blank_F: }
+ { rectangle } { \__examzh_fillin_rectangle_F: }
+ }
+ {
+ \msg_error:nnx { exam-zh } { no-fillin-type }
+ { \l__examzh_fillin_type_str }
+ }
+ }
+\cs_new:Npn \__examzh_fillin_uline_T:
+ {
+ \uline
+ {
+ \hspace* { 0.5em plus .5em minus .5em }
+ \dim_compare:nNnTF { \l__examzh_question_answer_depth_dim } > { 0.2em }
+ {
+ \dim_sub:Nn \l__examzh_question_answer_depth_dim { 0.2em }
+ \raisebox { \l__examzh_question_answer_depth_dim }
+ { \box_use_drop:N \l_tmpa_box }
+ }
+ { \box_use_drop:N \l_tmpa_box }
+ \hspace* { 0.5em plus .5em minus .5em }
+ }
+ }
+\cs_new:Npn \__examzh_fillin_uline_F:
+ {
+ \uline { \hspace* { \l__examzh_fillin_F_width_skip } }
+ }
+\cs_new:Nn \__examzh_fillin_uline:
+ {
+ \bgroup
+ \color{ \l__examzh_fillin_text_color_tl }
+ \markoverwith{\textcolor{black}{\rule[-0.7ex]{2pt}{0.4pt}}}
+ \ULon
+ }
+\cs_new:Npn \__examzh_fillin_uline_breakline_T:
+ {
+ % \CJKunderline*
+ % \uline
+ \__examzh_fillin_uline:
+ {
+ \hspace* { 0.5em plus .5em minus .5em }
+ \l_tmpa_tl
+ % 答案很长时,不能完全显示,答案很长时,不能完全显示
+ \hspace* { 0.5em plus .5em minus .5em }
+ }
+ }
+\cs_new:Npn \__examzh_fillin_paren_T:
+ {
+ (
+ \hspace* { 0.5em plus .5em minus .5em }
+ \group_begin:
+ \box_use_drop:N \l_tmpa_box
+ \group_end:
+ \hspace* { 0.5em plus .5em minus .5em }
+ )
+ }
+\cs_new:Npn \__examzh_fillin_paren_breakline_T:
+ {
+ (
+ \hspace* { 0.5em plus .5em minus .5em }
+ \group_begin:
+ \l_tmpa_tl
+ \group_end:
+ \hspace* { 0.5em plus .5em minus .5em }
+ )
+ }
+\cs_new:Npn \__examzh_fillin_paren_F:
+ {
+ ( \hspace* { \l__examzh_fillin_F_width_skip} )
+ }
+\cs_new:Npn \__examzh_fillin_blank_T:
+ {
+ \hspace* { 0.5em plus .5em minus .5em }
+ \group_begin:
+ \box_use_drop:N \l_tmpa_box
+ \group_end:
+ \hspace* { 0.5em plus .5em minus .5em }
+ }
+\cs_new:Npn \__examzh_fillin_blank_breakline_T:
+ {
+ \hspace* { 0.5em plus .5em minus .5em }
+ \group_begin:
+ \l_tmpa_tl
+ \group_end:
+ \hspace* { 0.5em plus .5em minus .5em }
+ }
+\cs_new:Npn \__examzh_fillin_blank_F:
+ {
+ \hspace* { \l__examzh_fillin_F_width_skip }
+ }
+\tikzset
+ {
+ fillin-circle/.style =
+ {
+ rounded~rectangle~west~arc = convex,
+ draw, rounded~rectangle,
+ color = \l__examzh_fillin_color_tl, text = \l__examzh_fillin_text_color_tl
+ }
+ }
+\cs_new:Npn \__examzh_fillin_circle_T:
+ {
+ \hspace* { .5em minus .5em }
+ \tikz[baseline=-3pt]
+ {
+ \node [fillin-circle] at (0,0)
+ { \box_use_drop:N \l_tmpa_box };
+ }
+ \hspace* { .5em minus .5em }
+ }
+\cs_new:Npn \__examzh_fillin_circle_F:
+ {
+ \hspace* { 0.5em plus .5em minus .5em }
+ \tikz[baseline=-3pt]
+ {
+ \node [fillin-circle] at (0,0)
+ { \phantom{t} };
+ }
+ \hspace* { 0.5em plus .5em minus .5em }
+ }
+\cs_new:Npn \__examzh_fillin_rectangle_T:
+ {
+ \hspace* { .5em minus .5em }
+ \begin{tikzpicture}[baseline = -3pt]
+ \node[draw, color = \l__examzh_fillin_color_tl, text = \l__examzh_fillin_text_color_tl]
+ { \box_use_drop:N \l_tmpa_box };
+ \end{tikzpicture}
+ \hspace* { .5em minus .5em }
+ }
+\cs_new:Npn \__examzh_fillin_rectangle_F:
+ {
+ \hspace* { 0.5em plus .5em minus .5em }
+ \begin{tikzpicture}[baseline = -3pt]
+ \node[draw, color = \l__examzh_fillin_color_tl, text = \l__examzh_fillin_text_color_tl]
+ { \phantom{a} };
+ \end{tikzpicture}
+ \hspace* { 0.5em plus .5em minus .5em }
+ }
+
+
+\dim_new:N \l__examzh_blacktriangle_length_dim
+\dim_set:Nn \l__examzh_blacktriangle_length_dim { .7em }
+\cs_new:Npn \__examzh_fillin_blacktriangle:
+ {
+ \tikz[rounded~corners=0.5pt,baseline=0pt]
+ {
+ \fill[] (0,0) -- ++(60\c_colon_str \l__examzh_blacktriangle_length_dim) -- ++(-60\c_colon_str \l__examzh_blacktriangle_length_dim) -- cycle ;
+ }
+ }
+
+\str_new:N \l__examzh_solution_blank_type_str
+\keys_define:nn { exam-zh / solution }
+ {
+ show-solution .bool_set:N = \l__examzh_solution_show_bool,
+ show-qed .bool_set:N = \l__examzh_solution_show_qed_bool,
+ qedsymbol .tl_set:N = \l__examzh_solution_qedsymbol_tl,
+ label-content .tl_set:N = \l__examzh_solution_label_content_tl,
+ label-punct .tl_set:N = \l__examzh_solution_label_punct_tl,
+ score-showleader .bool_set:N = \l__examzh_score_show_leader_bool,
+ score-pre-content .tl_set:N = \l__examzh_score_pre_content_tl,
+ score-post-content .tl_set:N = \l__examzh_score_post_content_tl,
+ score-format .tl_set:N = \l__examzh_score_format_tl,
+ text-color .tl_set:N = \l__examzh_solution_text_color_tl,
+ blank-type .choices:nn =
+ { none, manual, hide }
+ {
+ \str_set:Nx \l__examzh_solution_blank_type_str { \l_keys_choice_tl }
+ },
+ blank-vsep .skip_set:N = \l__examzh_solution_blank_vsep_skip,
+ top-sep .skip_set:N = \l__examzh_solution_top_sep_skip,
+ bottom-sep .skip_set:N = \l__examzh_solution_bottom_sep_skip,
+ parbreak .bool_set:N = \l__examzh_solution_par_break_bool,
+ }
+\keys_set:nn { exam-zh / solution }
+ {
+ show-solution = false,
+ show-qed = true,
+ qedsymbol = $\square$,
+ label-content = {解答},
+ label-punct = {},
+ score-showleader = true,
+ score-pre-content = {},
+ score-post-content = 分,
+ score-format = \color{red},
+ text-color = black,
+ blank-type = none,
+ blank-vsep = 12ex plus 1ex minus 1ex,
+ top-sep = .25em plus .25em minus .1em,
+ bottom-sep = 0pt,
+ parbreak = false
+ }
+\keys_define:nn { exam-zh }
+ { solution .meta:nn = { exam-zh / solution } {#1} }
+% 解答题环境
+\NewDocumentEnvironment { solution } { O{ } +b }
+ {
+ % \addvspace { \l__examzh_solution_top_sep_skip }
+ \vspace { \l__examzh_solution_top_sep_skip }
+ \keys_set:nn { exam-zh / solution } {#1}
+ % 放在这是使得 \examsetup 设置 qedsymbol 可以放在正文区
+ \cs_set_eq:NN \qedsymbol \l__examzh_solution_qedsymbol_tl
+ \bool_if:NTF \l__examzh_solution_show_bool
+ {
+ \__examzh_solution_print_answer:n {#2}
+ }
+ {
+ \str_case:VnF \l__examzh_solution_blank_type_str
+ {
+ { none } { }
+ { manual } { \addvspace { \l__examzh_solution_blank_vsep_skip } }
+ { hide } { \__examzh_solution_simply_hide_solution:n {#2} }
+ }
+ {}
+ }
+ \par
+ % \mode_leave_vertical:
+ % \addvspace { \l__examzh_solution_bottom_sep_skip }
+ \vspace { \l__examzh_solution_bottom_sep_skip }
+ }
+ {}
+\cs_new:Npn \__examzh_solution_simply_hide_solution:n #1
+ {
+ \begin{tcolorbox}
+ [
+ invisible,
+ frame~hidden,
+ breakable,
+ opacityback = 0,
+ opacityframe = 0,
+ size = minimal,
+ width = \linewidth
+ ]
+ #1
+ \end{tcolorbox}
+ }
+\cs_new:Npn \__examzh_solution_print_answer:n #1
+ {
+ \par
+ \pushQED { \qed }
+ % \normalfont \topsep6 \p@ \@plus6 \p@ \relax
+ % \trivlist
+ % \item \relax
+ \group_begin:
+ % \hspace* { 2\ccwd }
+ \bfseries \l__examzh_solution_label_content_tl
+ \@addpunct { \l__examzh_solution_label_punct_tl }
+ \group_end:
+ \hspace{0.5em}
+ % \ignorespaces
+ % 是否要新起一段开始
+ \bool_if:NT \l__examzh_solution_par_break_bool { \par }
+ \group_begin:
+ \color { \l__examzh_solution_text_color_tl } #1
+ \group_end:
+ \bool_if:NT \l__examzh_solution_show_qed_bool
+ { \popQED }
+ % \endtrivlist
+ % \@endpefalse
+ }
+
+% https://github.com/CTeX-org/forum/issues/256#issuecomment-1172319787
+\zref@require@unique
+
+\NewDocumentCommand { \score } { O{} m }
+ {
+ \group_begin:
+ \mode_if_math:TF
+ {
+ \__examzh_score_math_version:n { #2 }
+ }
+ {
+ \__examzh_score_text_version:n { #2 }
+ }
+ \group_end:
+ }
+\cs_new:Npn \__examzh_score_math_version:n #1
+ {
+ \bool_if:NTF \l__examzh_score_show_leader_bool
+ {
+ \__examzh_math_cdotfill:n
+ {
+ \l__examzh_score_format_tl
+ \l__examzh_score_pre_content_tl
+ #1
+ \l__examzh_score_post_content_tl
+ }
+ }
+ {
+ \__examzh_math_nodotfill:n
+ {
+ {
+ \l__examzh_score_format_tl
+ \l__examzh_score_pre_content_tl
+ #1
+ \l__examzh_score_post_content_tl
+ }
+ }
+ }
+ }
+\cs_new:Npn \__examzh_score_text_version:n #1
+ {
+ \bool_if:NTF \l__examzh_score_show_leader_bool
+ {
+ \__examzh_cdotfill:
+ \l__examzh_score_format_tl
+ \l__examzh_score_pre_content_tl #1 \l__examzh_score_post_content_tl
+ }
+ {
+ \hfill
+ \l__examzh_score_format_tl
+ \l__examzh_score_pre_content_tl #1 \l__examzh_score_post_content_tl
+ }
+ \par \noindent \ignorespaces
+ }
+% 仿照 latex.ltx, line 651 的 \dotfill
+\cs_new:Npn \__examzh_cdotfill:
+ {
+ \mode_leave_vertical:
+ \cleaders
+ \hbox_to_wd:nn { .44em } { \hss $\cdot$ \hss }
+ \hfill \kern\z@
+ }
+\cs_new_protected:Npn \__examzh_math_nodotfill:n #1
+ {
+ \stepcounter { zref@unique }
+ \hbox_overlap_right:n
+ {
+ \zsaveposx { \thezref@unique L }
+ \zref@ifrefundefined { \thezref@unique R }
+ { }
+ {
+ \skip_horizontal:n
+ {
+ \zposx { \thezref@unique R } sp
+ - \zposx { \thezref@unique L } sp
+ }
+ }
+ }
+ \tag * { \zsaveposx { \thezref@unique R } #1 }
+ }
+\cs_new_protected:Npn \__examzh_math_cdotfill:n #1
+ {
+ \stepcounter { zref@unique }
+ \hbox_overlap_right:n
+ {
+ \zsaveposx { \thezref@unique L }
+ \zref@ifrefundefined { \thezref@unique R }
+ { }
+ {
+ \cleaders
+ \hbox_to_wd:nn { .44em } { \hss $\cdot$ \hss }
+ \skip_horizontal:n
+ {
+ \zposx { \thezref@unique R } sp
+ - \zposx { \thezref@unique L } sp
+ }
+ }
+ }
+ \tag * { \zsaveposx { \thezref@unique R } #1 }
+ } \ No newline at end of file
diff --git a/Master/texmf-dist/tex/latex/exam-zh/exam-zh-symbols.sty b/Master/texmf-dist/tex/latex/exam-zh/exam-zh-symbols.sty
new file mode 100644
index 00000000000..e0f147aab3c
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/exam-zh/exam-zh-symbols.sty
@@ -0,0 +1,1198 @@
+%
+% Copyright (c) 2022 Kangwei Xia
+% Released under the LaTeX Project Public License v1.3c License.
+% Repository: https://gitee.com/zepinglee/exam-zh
+%
+
+\NeedsTeXFormat{LaTeX2e}
+
+\RequirePackage{expl3}
+
+\ProvidesExplPackage {exam-zh-symbols} {2022-07-28} {v0.1.13}
+ {exam-zh symbols module}
+
+\RequirePackage { tikz }
+
+\keys_define:nn { exam-zh }
+ { symbols .meta:nn = { exam-zh / symbols } {#1} }
+
+
+% 分数 \frac \dfrac
+\int_new:N \l__examzh_symbols_frac_numerator_str_int % frac 分子字符数
+\int_new:N \l__examzh_symbols_frac_denominator_str_int % frac 分母字符数
+\int_new:N \l__examzh_symbols_dfrac_numerator_str_int % frac 分子字符数
+\int_new:N \l__examzh_symbols_dfrac_denominator_str_int % frac 分母字符数
+
+\keys_define:nn { exam-zh / symbols }
+ {
+ % 是否重定义 \frac
+ change-frac-style .bool_set:N = \l__examzh_symbols_change_frac_style_bool,
+ % 是否重定义 \dfrac
+ change-dfrac-style .bool_set:N = \l__examzh_symbols_change_dfrac_style_bool,
+ % \frac 分子分母增加的额外距离
+ frac-add .muskip_set:N = \l__examzh_symbols_frac_add_distance_muskip,
+ % \dfrac 分子分母增加的额外距离
+ dfrac-add .muskip_set:N = \l__examzh_symbols_dfrac_add_distance_muskip,
+ }
+\keys_set:nn { exam-zh / symbols }
+ {
+ change-frac-style = false,
+ change-dfrac-style = false,
+ frac-add = 5mu,
+ dfrac-add = 5mu,
+ }
+\NewCommandCopy { \examzhfrac } { \frac }
+\NewCommandCopy { \examzhdfrac } { \dfrac }
+\RenewDocumentCommand { \frac } { m m }
+ {
+ \group_begin:
+ \bool_if:NTF \l__examzh_symbols_change_frac_style_bool
+ {
+ % 计算分子分母的字符数
+ \__examzh_symbols_frac_calc_str_num:nn {#1} {#2}
+ % 根据字符数选择将额外的距离加在哪
+ \__examzh_symbols_frac_add_distance:NNNNnn
+ \examzhfrac
+ \l__examzh_symbols_frac_numerator_str_int
+ \l__examzh_symbols_frac_denominator_str_int
+ \l__examzh_symbols_frac_add_distance_muskip
+ {#1}{#2}
+ }
+ { \examzhfrac {#1} {#2} }
+ \group_end:
+ }
+\RenewDocumentCommand { \dfrac } { m m }
+ {
+ \group_begin:
+ \bool_if:NTF \l__examzh_symbols_change_dfrac_style_bool
+ {
+ % 计算分子分母的字符数
+ \__examzh_symbols_frac_calc_str_num:nn {#1} {#2}
+ % 根据字符数选择将额外的距离加在哪
+ \__examzh_symbols_frac_add_distance:NNNNnn
+ \examzhdfrac
+ \l__examzh_symbols_frac_numerator_str_int
+ \l__examzh_symbols_frac_denominator_str_int
+ \l__examzh_symbols_dfrac_add_distance_muskip
+ {#1}{#2}
+ }
+ { \examzhdfrac {#1} {#2} }
+ \group_end:
+ }
+\cs_new:Npn \__examzh_symbols_frac_calc_str_num:nn #1#2
+ {
+ \int_set:Nn \l__examzh_symbols_frac_numerator_str_int
+ { \str_count:n {#1} }
+ \int_set:Nn \l__examzh_symbols_frac_denominator_str_int
+ { \str_count:n {#2} }
+ }
+% \__examzh_symbols_frac_add_distance:NNNNnn
+ % <\oldfrac><numerator str num><denominator str num><add muskip><numerator><denominator>
+\cs_new:Npn \__examzh_symbols_frac_add_distance:NNNNnn #1#2#3#4#5#6
+ {
+ \int_compare:nNnTF {#2} = {1}
+ {
+ \int_compare:nNnTF {#3} = {1}
+ {
+ % 分子字符数=1,分母字符数=1
+ #1
+ {
+ \mskip #4
+ #5
+ \mskip #4
+ } {#6}
+ }
+ {
+ % 分子字符数=1,分母字符数>1
+ #1 {#5}
+ {
+ \mskip #4
+ #6
+ \mskip #4
+ }
+ }
+ }
+ {
+ \int_compare:nNnTF {#3} = {1}
+ {
+ % 分子字符数>1,分母字符数=1
+ #1
+ {
+ \mskip #4
+ #5
+ \mskip #4
+ } {#6}
+ }
+ {
+ % 分子字符数>1,分母字符数>1
+ #1
+ {
+ \mskip #4
+ #5
+ \mskip #4
+ } {#6}
+ }
+ }
+ }
+
+% 向量 vec
+\int_new:N \l__examzh_symbols_vec_input_count_int
+
+\AtBeginDocument
+ {
+ \RenewDocumentCommand { \vec } { m }
+ { \__examzh_symbols_vec:n {#1} }
+ }
+\cs_new:Npn \__examzh_symbols_vec:n #1
+ {
+ % 先检测 #1 有多少个字符
+ \__examzh_symbols_vec_detect_number_of_input_str:n {#1}
+ % 只有 1 个的:加粗,多于两个的加箭头
+ \int_compare:nNnTF { \l__examzh_symbols_vec_input_count_int } = {1}
+ { \symbfit {#1} }
+ { \overrightarrow {#1} }
+ }
+\cs_new:Npn \__examzh_symbols_vec_detect_number_of_input_str:n #1
+ {
+ \int_set:Nn \l__examzh_symbols_vec_input_count_int
+ { \str_count:n { #1 } }
+ }
+
+% 平行四边形 \parallelogram
+\keys_define:nn { exam-zh / symbols }
+ {
+ parallelogram-angle .fp_set:N = \l__examzh_symbols_parallelogram_angle_fp,
+ parallelogram-x .dim_set:N = \l__examzh_symbols_parallelogram_x_dim,
+ parallelogram-y .dim_set:N = \l__examzh_symbols_parallelogram_y_dim
+ }
+
+\cs_new:Npn \__examzh_symbols_parallelogram:
+ {
+ \begin{tikzpicture}[baseline]
+ \draw[line~join = round] (0,0) --++ (\l__examzh_symbols_parallelogram_x_dim,0) --++ (\fp_use:N \l__examzh_symbols_parallelogram_angle_fp \c_colon_str \l__examzh_symbols_parallelogram_y_dim) -- (\fp_use:N \l__examzh_symbols_parallelogram_angle_fp \c_colon_str \l__examzh_symbols_parallelogram_y_dim) -- cycle;
+ \end{tikzpicture}
+ }
+
+\AtBeginDocument
+ {
+ \RenewDocumentCommand { \parallelogram } { }
+ {
+ \group_begin:
+ \keys_set:nn { exam-zh / symbols }
+ {
+ parallelogram-angle = 67,
+ parallelogram-x = 0.9em,
+ parallelogram-y = 0.7em
+ }
+ \mathrel
+ {
+ \__examzh_symbols_symbol_four_size:n
+ { \__examzh_symbols_parallelogram: }
+ }
+ \group_end:
+ }
+ }
+
+% 平行 \parallel
+\bool_new:N \l__examzh_symbols_parallel_slant_bool
+\bool_new:N \l__examzh_symbols_nparallel_slant_bool
+
+\keys_define:nn { exam-zh / symbols }
+ {
+ parallel-angle .fp_set:N = \l__examzh_symbols_parallel_angle_fp,
+ parallel-twoline-distance .dim_set:N = \l__examzh_symbols_parallel_twoline_distance_dim,
+ parallel-length .dim_set:N = \l__examzh_symbols_parallel_length_dim,
+ parallel-baseline .dim_set:N = \l__examzh_symbols_parallel_baseline_dim,
+ nparallel-slant-angle .fp_set:N = \l__examzh_symbols_nparallel_slant_angle_fp,
+ nparallel-slant-length .dim_set:N = \l__examzh_symbols_nparallel_slant_length_dim,
+ parallel-type .choice:,
+ parallel-type / slant.code:n =
+ { \bool_set_true:N \l__examzh_symbols_parallel_slant_bool },
+ parallel-type / perpendicular .code:n =
+ { \bool_set_false:N \l__examzh_symbols_parallel_slant_bool },
+ nparallel-type .choice:,
+ nparallel-type / slant.code:n =
+ { \bool_set_true:N \l__examzh_symbols_nparallel_slant_bool },
+ nparallel-type / perpendicular .code:n =
+ { \bool_set_false:N \l__examzh_symbols_nparallel_slant_bool },
+ }
+\keys_set:nn { exam-zh / symbols }
+ {
+ parallel-type = slant,
+ nparallel-type = slant,
+ }
+
+\cs_new:Npn \__examzh_symbols_parallel:
+ {
+ \begin{tikzpicture}[baseline=\l__examzh_symbols_parallel_baseline_dim]
+ \draw[line~cap = round] (0, 0) --++ (\fp_use:N \l__examzh_symbols_parallel_angle_fp \c_colon_str \l__examzh_symbols_parallel_length_dim)
+ (\l__examzh_symbols_parallel_twoline_distance_dim, 0) --++ (\fp_use:N \l__examzh_symbols_parallel_angle_fp \c_colon_str \l__examzh_symbols_parallel_length_dim);
+ \end{tikzpicture}
+ }
+\cs_new:Npn \__examzh_symbols_nparallel:
+ {
+ \begin{tikzpicture}[line~cap = round, baseline=\l__examzh_symbols_parallel_baseline_dim]
+ \draw
+ (0, 0) --++ (\fp_use:N \l__examzh_symbols_parallel_angle_fp \c_colon_str \l__examzh_symbols_parallel_length_dim)
+ (\l__examzh_symbols_parallel_twoline_distance_dim, 0) --++ (\fp_use:N \l__examzh_symbols_parallel_angle_fp \c_colon_str \l__examzh_symbols_parallel_length_dim);
+ % n 线
+ \draw
+ (\l__examzh_symbols_parallel_twoline_distance_dim / 2, 0)++(\fp_use:N \l__examzh_symbols_parallel_angle_fp \c_colon_str \l__examzh_symbols_parallel_length_dim / 2) --++ (\fp_use:N \l__examzh_symbols_nparallel_slant_angle_fp \c_colon_str \l__examzh_symbols_nparallel_slant_length_dim / 2)
+ (\l__examzh_symbols_parallel_twoline_distance_dim / 2, 0)++(\fp_use:N \l__examzh_symbols_parallel_angle_fp \c_colon_str \l__examzh_symbols_parallel_length_dim / 2) --++ (\fp_eval:n { \l__examzh_symbols_nparallel_slant_angle_fp + 180 } \c_colon_str \l__examzh_symbols_nparallel_slant_length_dim / 2);
+ \end{tikzpicture}
+ }
+
+\AtBeginDocument
+ {
+ \cs_set_eq:NN \__examzh_symbols_old_parallel: \parallel
+ \cs_set_eq:NN \__examzh_symbols_old_nparallel: \nparallel
+ \RenewDocumentCommand { \parallel } { }
+ {
+ \group_begin:
+ \bool_if:NTF \l__examzh_symbols_parallel_slant_bool
+ {
+ \keys_set:nn { exam-zh / symbols }
+ {
+ parallel-angle = 60,
+ parallel-twoline-distance = 0.28em,
+ parallel-length = 0.98em,
+ parallel-baseline = 0.5pt
+ }
+ }
+ {
+ % 竖直
+ \keys_set:nn { exam-zh / symbols }
+ {
+ parallel-angle = 90,
+ parallel-twoline-distance = 0.2em,
+ parallel-length = 0.93em,
+ parallel-baseline = 1pt
+ }
+ }
+ \mathrel
+ {
+ \__examzh_symbols_symbol_four_size:n
+ { \__examzh_symbols_parallel: }
+ }
+ \group_end:
+ }
+ \RenewDocumentCommand { \nparallel } { }
+ {
+ \group_begin:
+
+ \bool_if:NTF \l__examzh_symbols_nparallel_slant_bool
+ {
+ \keys_set:nn { exam-zh / symbols }
+ {
+ parallel-angle = 60,
+ parallel-twoline-distance = 0.28em,
+ parallel-length = 0.98em,
+ parallel-baseline = 0.5pt,
+ nparallel-slant-angle = 120,
+ nparallel-slant-length = 0.65em
+ }
+ }
+ {
+ \keys_set:nn { exam-zh / symbols }
+ {
+ parallel-angle = 90,
+ parallel-twoline-distance = 0.2em,
+ parallel-length = 0.93em,
+ parallel-baseline = 1pt,
+ nparallel-slant-angle = 50,
+ nparallel-slant-length = 0.6em
+ }
+ % \tikz[baseline = {([yshift = 5pt]current~bounding~box.south)}]{ \node { $\__examzh_symbols_old_nparallel:$ }; }
+ }
+ \mathrel
+ {
+ \__examzh_symbols_symbol_four_size:n
+ { \__examzh_symbols_nparallel: }
+ }
+ \group_end:
+ }
+ }
+
+% 平行且相等 \paralleleq
+\bool_new:N \l__examzh_symbols_paralleleq_slant_bool
+
+\keys_define:nn { exam-zh / symbols }
+ {
+ % 上面部分的倾斜角
+ paralleleq-slant-angle .fp_set:N = \l__examzh_symbols_paralleleq_angle_fp,
+ % 线长度
+ paralleleq-upper-line-length .dim_set:N = \l__examzh_symbols_paralleleq_upper_line_length_dim,
+ paralleleq-lower-line-length .dim_set:N = \l__examzh_symbols_paralleleq_lower_line_length_dim,
+ % 线间距
+ paralleleq-upper-twoline-distance .dim_set:N = \l__examzh_symbols_paralleleq_upper_twoline_distance_dim,
+ paralleleq-lower-twoline-distance .dim_set:N = \l__examzh_symbols_paralleleq_lower_twoline_distance_dim,
+ % 下面部分的水平偏移量
+ paralleleq-lower-xshift .dim_set:N = \l__examzh_symbols_paralleleq_lower_xshift_dim,
+ paralleleq-type .choice:,
+ paralleleq-type / slant.code:n =
+ { \bool_set_true:N \l__examzh_symbols_paralleleq_slant_bool },
+ paralleleq-type / perpendicular .code:n =
+ { \bool_set_false:N \l__examzh_symbols_paralleleq_slant_bool },
+ }
+
+\keys_set:nn { exam-zh / symbols }
+ { paralleleq-type = slant }
+
+\cs_new:Npn \__examzh_symbols_paralleleq:
+ {
+ \begin{tikzpicture}[baseline = -1.7pt]
+ \draw[line~cap = round, name = parallel] (0, 0) --++ (\fp_use:N \l__examzh_symbols_paralleleq_angle_fp \c_colon_str \l__examzh_symbols_paralleleq_upper_line_length_dim)
+ (\l__examzh_symbols_paralleleq_upper_twoline_distance_dim, 0) --++ (\fp_use:N \l__examzh_symbols_paralleleq_angle_fp \c_colon_str \l__examzh_symbols_paralleleq_upper_line_length_dim);
+ \draw[anchor = parallel.south]
+ (\l__examzh_symbols_paralleleq_upper_twoline_distance_dim / 2 + \l__examzh_symbols_paralleleq_lower_xshift_dim,0) --++ (\l__examzh_symbols_paralleleq_lower_line_length_dim / 2,0)
+ (\l__examzh_symbols_paralleleq_upper_twoline_distance_dim / 2 + \l__examzh_symbols_paralleleq_lower_xshift_dim,0) --++ (-\l__examzh_symbols_paralleleq_lower_line_length_dim / 2,0)
+ (\l__examzh_symbols_paralleleq_upper_twoline_distance_dim / 2 + \l__examzh_symbols_paralleleq_lower_xshift_dim,-\l__examzh_symbols_paralleleq_lower_twoline_distance_dim) --++ (\l__examzh_symbols_paralleleq_lower_line_length_dim / 2 ,0)
+ (\l__examzh_symbols_paralleleq_upper_twoline_distance_dim / 2 + \l__examzh_symbols_paralleleq_lower_xshift_dim,-\l__examzh_symbols_paralleleq_lower_twoline_distance_dim) --++ (-\l__examzh_symbols_paralleleq_lower_line_length_dim / 2,0)
+ ;
+ \end{tikzpicture}
+ }
+
+\NewDocumentCommand { \paralleleq } { }
+ {
+ \group_begin:
+ \keys_set:nn { exam-zh / symbols }
+ {
+ paralleleq-upper-line-length = 0.65em,
+ paralleleq-lower-line-length = 0.8em,
+ paralleleq-upper-twoline-distance = 0.2em,
+ paralleleq-lower-twoline-distance = 0.18em,
+ }
+ \bool_if:NTF \l__examzh_symbols_paralleleq_slant_bool
+ {
+ % \paralleleq : 倾斜型
+ \keys_set:nn { exam-zh / symbols }
+ {
+ paralleleq-slant-angle = 70,
+ paralleleq-lower-xshift = 0.04em
+ }
+ }
+ {
+ % \paralleleq* : 垂直型
+ \keys_set:nn { exam-zh / symbols }
+ {
+ paralleleq-slant-angle = 90,
+ paralleleq-lower-xshift = 0em
+ }
+ }
+ \mathrel
+ {
+ \__examzh_symbols_symbol_four_size:n
+ { \__examzh_symbols_paralleleq: }
+ }
+ \group_end:
+ }
+
+
+% 子集 \subset 真子集 \subseteqq
+\keys_define:nn { exam-zh / symbols }
+ {
+ % 半圆的半径
+ subset-radius .dim_set:N = \l__examzh_symbols_subset_semicircle_radius_dim,
+ % 半圆右边横线的长度
+ subset-upper-linewidth .dim_set:N = \l__examzh_symbols_subset_semicircle_line_width_dim,
+ % 下面线的长度
+ subset-lower-linewidth .dim_set:N = \l__examzh_symbols_subset_lower_line_width_dim,
+ % 上面部分和下面部分的距离
+ subset-upper-lower-distance .dim_set:N = \l__examzh_symbols_subset_upper_lower_distance_dim,
+ % 下面部分 两条线的距离
+ subsetneqq-lower-twoline-distance .dim_set:N = \l__examzh_symbols_subsetneqq_lower_twoline_distance_dim,
+ % 下面斜线的长度
+ subsetneqq-lower-slant-length .dim_set:N = \l__examzh_symbols_subsetneqq_lower_slant_line_length_dim,
+ supsetneqq-lower-slant-length .dim_set:N = \l__examzh_symbols_supsetneqq_lower_slant_line_length_dim,
+ % 真子集下方斜线的倾斜角度
+ subsetneqq-lower-slant-angle .fp_set:N = \l__examzh_symbols_subsetneqq_lower_slant_line_angle_fp,
+ supsetneqq-lower-slant-angle .fp_set:N = \l__examzh_symbols_supsetneqq_lower_slant_line_angle_fp,
+ % nxxx 类的参数
+ % --角度--
+ nsubset-n-slant-angle .fp_set:N = \l__examzh_symbols_nsubset_slant_angle_fp,
+ nsubseteq-n-slant-angle .fp_set:N = \l__examzh_symbols_nsubseteq_slant_angle_fp,
+ nsubsetneqq-n-slant-angle .fp_set:N = \l__examzh_symbols_nsubsetneqq_slant_angle_fp,
+ % --长度--
+ nsubset-n-slant-length .dim_set:N = \l__examzh_symbols_nsubset_slant_length_dim,
+ nsubseteq-n-slant-length .dim_set:N = \l__examzh_symbols_nsubseteq_slant_length_dim,
+ nsubsetneqq-n-slant-length .dim_set:N = \l__examzh_symbols_nsubsetneqq_slant_length_dim,
+ }
+\keys_set:nn { exam-zh / symbols }
+ {
+ subset-radius = 0.2em,
+ subset-upper-linewidth = 0.6em,
+ subset-lower-linewidth =
+ {
+ \l__examzh_symbols_subset_semicircle_radius_dim + \l__examzh_symbols_subset_semicircle_line_width_dim
+ },
+ subset-upper-lower-distance = 0.12em,
+ subsetneqq-lower-twoline-distance = 0.14em,
+ subsetneqq-lower-slant-length = 0.42em,
+ supsetneqq-lower-slant-length = 0.4em,
+ subsetneqq-lower-slant-angle = 55,
+ supsetneqq-lower-slant-angle = 60,
+ nsubset-n-slant-angle = 65,
+ nsubseteq-n-slant-angle = 68,
+ nsubsetneqq-n-slant-angle = 70,
+ nsubset-n-slant-length = 1em,
+ nsubseteq-n-slant-length = 1em,
+ nsubsetneqq-n-slant-length = 1.2em,
+ }
+
+\cs_new:Npn \__examzh_symbols_subset:
+ {
+ \begin{tikzpicture}[line~cap=round,baseline = {([yshift = -1pt]current~bounding~box.south)}]
+ % 半圆 + 两条线
+ \draw[line~cap=round] (0,\l__examzh_symbols_subset_semicircle_radius_dim) arc (90 \c_colon_str 270 \c_colon_str \l__examzh_symbols_subset_semicircle_radius_dim)
+ (0,\l__examzh_symbols_subset_semicircle_radius_dim) --++ (\l__examzh_symbols_subset_semicircle_line_width_dim,0)
+ (0,-\l__examzh_symbols_subset_semicircle_radius_dim) --++ (\l__examzh_symbols_subset_semicircle_line_width_dim,0);
+ \end{tikzpicture}
+ }
+\cs_new:Npn \__examzh_symbols_nsubset:
+ {
+ \begin{tikzpicture}[line~cap=round,baseline = {([yshift = -1pt]current~bounding~box.south)}]
+ % 半圆 + 两条线
+ \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) arc (90 \c_colon_str 270 \c_colon_str \l__examzh_symbols_subset_semicircle_radius_dim)
+ (0,\l__examzh_symbols_subset_semicircle_radius_dim) --++ (\l__examzh_symbols_subset_semicircle_line_width_dim,0)
+ (0,-\l__examzh_symbols_subset_semicircle_radius_dim) --++ (\l__examzh_symbols_subset_semicircle_line_width_dim,0);
+ % 定位斜线的中心
+ \coordinate (n-center) at (\l__examzh_symbols_subset_semicircle_line_width_dim / 2 - \l__examzh_symbols_subset_semicircle_radius_dim / 2,0);
+ % 画斜线
+ \draw[overlay]
+ (n-center) --++ (\fp_use:N \l__examzh_symbols_nsubset_slant_angle_fp \c_colon_str \l__examzh_symbols_nsubset_slant_length_dim / 2)
+ (n-center) --++ (\fp_eval:n { \l__examzh_symbols_nsubset_slant_angle_fp + 180} \c_colon_str \l__examzh_symbols_nsubset_slant_length_dim / 2);
+ \end{tikzpicture}
+ }
+\cs_new:Npn \__examzh_symbols_subseteq:
+ {
+ \begin{tikzpicture}[line~cap=round,baseline = (current~bounding~box.south)]
+ % 半圆 + 两条线
+ \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) arc (90 \c_colon_str 270 \c_colon_str \l__examzh_symbols_subset_semicircle_radius_dim)
+ (0,\l__examzh_symbols_subset_semicircle_radius_dim) --++ (\l__examzh_symbols_subset_semicircle_line_width_dim,0)
+ (0,-\l__examzh_symbols_subset_semicircle_radius_dim) --++ (\l__examzh_symbols_subset_semicircle_line_width_dim,0);
+ % 下面的一条线
+ \draw (-\l__examzh_symbols_subset_semicircle_radius_dim, - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim) --++ (\l__examzh_symbols_subset_lower_line_width_dim, 0);
+ \end{tikzpicture}
+ }
+\cs_new:Npn \__examzh_symbols_nsubseteq:
+ {
+ \begin{tikzpicture}[line~cap=round,baseline = (current~bounding~box.south)]
+ % 半圆 + 两条线
+ \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) arc (90 \c_colon_str 270 \c_colon_str \l__examzh_symbols_subset_semicircle_radius_dim)
+ (0,\l__examzh_symbols_subset_semicircle_radius_dim) --++ (\l__examzh_symbols_subset_semicircle_line_width_dim,0)
+ (0,-\l__examzh_symbols_subset_semicircle_radius_dim) --++ (\l__examzh_symbols_subset_semicircle_line_width_dim,0);
+ % 下面的一条线
+ \draw (-\l__examzh_symbols_subset_semicircle_radius_dim, - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim) --++ (\l__examzh_symbols_subset_lower_line_width_dim, 0);
+ % 定位斜线的中心
+ \coordinate (n-center) at (\l__examzh_symbols_subset_semicircle_line_width_dim / 2 - \l__examzh_symbols_subset_semicircle_radius_dim / 2,0);
+ % 画斜线
+ \draw[overlay]
+ (n-center) --++ (\fp_use:N \l__examzh_symbols_nsubseteq_slant_angle_fp \c_colon_str \l__examzh_symbols_nsubseteq_slant_length_dim / 8 * 3.5)
+ (n-center) --++ (\fp_eval:n { \l__examzh_symbols_nsubseteq_slant_angle_fp + 180} \c_colon_str \l__examzh_symbols_nsubseteq_slant_length_dim / 8 * 4.5);
+ \end{tikzpicture}
+ }
+% 真子集
+\cs_new:Npn \__examzh_symbols_subsetneqq:
+ {
+ \begin{tikzpicture}[line~cap=round,baseline = (current~bounding~box.south)]
+ % 半圆 + 两条线
+ \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) arc (90 \c_colon_str 270 \c_colon_str \l__examzh_symbols_subset_semicircle_radius_dim)
+ (0,\l__examzh_symbols_subset_semicircle_radius_dim) --++ (\l__examzh_symbols_subset_semicircle_line_width_dim,0)
+ (0,-\l__examzh_symbols_subset_semicircle_radius_dim) --++ (\l__examzh_symbols_subset_semicircle_line_width_dim,0);
+ % 下面的两条线
+ \draw (-\l__examzh_symbols_subset_semicircle_radius_dim, - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim) --++ (\l__examzh_symbols_subset_lower_line_width_dim, 0)
+ (-\l__examzh_symbols_subset_semicircle_radius_dim, - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim - \l__examzh_symbols_subsetneqq_lower_twoline_distance_dim) --++ (\l__examzh_symbols_subset_lower_line_width_dim, 0);
+ % 定位斜线的中心点
+ \coordinate (lower-center) at
+ (\l__examzh_symbols_subset_semicircle_line_width_dim / 2 - \l__examzh_symbols_subset_semicircle_radius_dim / 2 , - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim - \l__examzh_symbols_subsetneqq_lower_twoline_distance_dim / 2 );
+ % 画斜线
+ \draw[overlay]
+ (lower-center) --++ (\fp_use:N \l__examzh_symbols_subsetneqq_lower_slant_line_angle_fp \c_colon_str \l__examzh_symbols_subsetneqq_lower_slant_line_length_dim / 2)
+ (lower-center) --++ (\fp_eval:n {\l__examzh_symbols_subsetneqq_lower_slant_line_angle_fp + 180} \c_colon_str \l__examzh_symbols_subsetneqq_lower_slant_line_length_dim / 2);
+ \end{tikzpicture}
+ }
+\cs_new:Npn \__examzh_symbols_nsubsetneqq:
+ {
+ \begin{tikzpicture}[line~cap=round,baseline = (current~bounding~box.south)]
+ % 半圆 + 两条线
+ \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) arc (90 \c_colon_str 270 \c_colon_str \l__examzh_symbols_subset_semicircle_radius_dim)
+ (0,\l__examzh_symbols_subset_semicircle_radius_dim) --++ (\l__examzh_symbols_subset_semicircle_line_width_dim,0)
+ (0,-\l__examzh_symbols_subset_semicircle_radius_dim) --++ (\l__examzh_symbols_subset_semicircle_line_width_dim,0);
+ % 下面的两条线
+ \draw (-\l__examzh_symbols_subset_semicircle_radius_dim, - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim) --++ (\l__examzh_symbols_subset_lower_line_width_dim, 0)
+ (-\l__examzh_symbols_subset_semicircle_radius_dim, - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim - \l__examzh_symbols_subsetneqq_lower_twoline_distance_dim) --++ (\l__examzh_symbols_subset_lower_line_width_dim, 0);
+ % 定位斜线的中心点
+ \coordinate (lower-center) at
+ (\l__examzh_symbols_subset_semicircle_line_width_dim / 2 - \l__examzh_symbols_subset_semicircle_radius_dim / 2 , - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim - \l__examzh_symbols_subsetneqq_lower_twoline_distance_dim / 2 );
+ % 画斜线
+ \draw[overlay]
+ (lower-center) --++ (\fp_use:N \l__examzh_symbols_subsetneqq_lower_slant_line_angle_fp \c_colon_str \l__examzh_symbols_subsetneqq_lower_slant_line_length_dim / 2)
+ (lower-center) --++ (\fp_eval:n {\l__examzh_symbols_subsetneqq_lower_slant_line_angle_fp + 180} \c_colon_str \l__examzh_symbols_subsetneqq_lower_slant_line_length_dim / 2);
+ % 定位斜线的中心
+ \coordinate (n-center) at (\l__examzh_symbols_subset_semicircle_line_width_dim / 2 - \l__examzh_symbols_subset_semicircle_radius_dim / 2,0);
+ % 画斜线
+ \draw[overlay]
+ (n-center) --++ (\fp_use:N \l__examzh_symbols_nsubsetneqq_slant_angle_fp \c_colon_str \l__examzh_symbols_nsubsetneqq_slant_length_dim / 8 * 3.2)
+ (n-center) --++ (\fp_eval:n { \l__examzh_symbols_nsubsetneqq_slant_angle_fp + 180} \c_colon_str \l__examzh_symbols_nsubsetneqq_slant_length_dim / 8 * 4.8);
+ \end{tikzpicture}
+ }
+\cs_new:Npn \__examzh_symbols_supset:
+ {
+ \begin{tikzpicture}[line~cap=round,baseline = {([yshift = -1pt]current~bounding~box.south)}]
+ \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) arc (90 \c_colon_str -90 \c_colon_str \l__examzh_symbols_subset_semicircle_radius_dim)
+ (0,\l__examzh_symbols_subset_semicircle_radius_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim,0)
+ (0,-\l__examzh_symbols_subset_semicircle_radius_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim,0);
+ \end{tikzpicture}
+ }
+\cs_new:Npn \__examzh_symbols_nsupset:
+ {
+ \begin{tikzpicture}[line~cap=round,baseline = {([yshift = -1pt]current~bounding~box.south)}]
+ \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) arc (90 \c_colon_str -90 \c_colon_str \l__examzh_symbols_subset_semicircle_radius_dim)
+ (0,\l__examzh_symbols_subset_semicircle_radius_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim,0)
+ (0,-\l__examzh_symbols_subset_semicircle_radius_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim,0);
+ % 定位斜线的中心
+ \coordinate (n-center) at (- \l__examzh_symbols_subset_semicircle_line_width_dim / 2 + \l__examzh_symbols_subset_semicircle_radius_dim / 2,0);
+ % 画斜线
+ \draw[overlay]
+ (n-center) --++ (\fp_use:N \l__examzh_symbols_nsubset_slant_angle_fp \c_colon_str \l__examzh_symbols_nsubset_slant_length_dim / 2)
+ (n-center) --++ (\fp_eval:n { \l__examzh_symbols_nsubset_slant_angle_fp + 180} \c_colon_str \l__examzh_symbols_nsubset_slant_length_dim / 2);
+ \end{tikzpicture}
+ }
+\cs_new:Npn \__examzh_symbols_supseteq:
+ {
+ \begin{tikzpicture}[line~cap=round,baseline = (current~bounding~box.south)]
+ \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) arc (90 \c_colon_str -90 \c_colon_str \l__examzh_symbols_subset_semicircle_radius_dim);
+ \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim,0);
+ \draw (0,-\l__examzh_symbols_subset_semicircle_radius_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim,0);
+ \draw
+ (\l__examzh_symbols_subset_semicircle_radius_dim, - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim - \l__examzh_symbols_subset_semicircle_radius_dim, 0);
+ \end{tikzpicture}
+ }
+\cs_new:Npn \__examzh_symbols_nsupseteq:
+ {
+ \begin{tikzpicture}[line~cap=round,baseline = (current~bounding~box.south)]
+ \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) arc (90 \c_colon_str -90 \c_colon_str \l__examzh_symbols_subset_semicircle_radius_dim)
+ (0,\l__examzh_symbols_subset_semicircle_radius_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim,0)
+ (0,-\l__examzh_symbols_subset_semicircle_radius_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim,0);
+ \draw
+ (\l__examzh_symbols_subset_semicircle_radius_dim, - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim - \l__examzh_symbols_subset_semicircle_radius_dim, 0);
+ \coordinate (n-center) at (-\l__examzh_symbols_subset_semicircle_line_width_dim / 2 + \l__examzh_symbols_subset_semicircle_radius_dim / 2,0);
+ % 画斜线
+ \draw[overlay]
+ (n-center) --++ (\fp_use:N \l__examzh_symbols_nsubseteq_slant_angle_fp \c_colon_str \l__examzh_symbols_nsubseteq_slant_length_dim / 8 * 3.5)
+ (n-center) --++ (\fp_eval:n { \l__examzh_symbols_nsubseteq_slant_angle_fp + 180} \c_colon_str \l__examzh_symbols_nsubseteq_slant_length_dim / 8 * 4.5);
+ \end{tikzpicture}
+ }
+% 反向真子集
+\cs_new:Npn \__examzh_symbols_supsetneqq:
+ {
+ \begin{tikzpicture}[line~cap=round,baseline = (current~bounding~box.south)]
+ \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) arc (90 \c_colon_str -90 \c_colon_str \l__examzh_symbols_subset_semicircle_radius_dim);
+ \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim,0);
+ \draw (0,-\l__examzh_symbols_subset_semicircle_radius_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim,0);
+ \draw
+ (\l__examzh_symbols_subset_semicircle_radius_dim, - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim - \l__examzh_symbols_subset_semicircle_radius_dim, 0)
+ (\l__examzh_symbols_subset_semicircle_radius_dim, - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim - \l__examzh_symbols_subsetneqq_lower_twoline_distance_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim - \l__examzh_symbols_subset_semicircle_radius_dim, 0);
+ % 定位斜线的中心点
+ \coordinate (center) at
+ (- \l__examzh_symbols_subset_semicircle_line_width_dim / 2 + \l__examzh_symbols_subset_semicircle_radius_dim / 2 , - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim - \l__examzh_symbols_subsetneqq_lower_twoline_distance_dim / 2 );
+ % 画斜线
+ \draw[overlay]
+ (center) --++ (\fp_use:N \l__examzh_symbols_supsetneqq_lower_slant_line_angle_fp \c_colon_str \l__examzh_symbols_supsetneqq_lower_slant_line_length_dim / 2)
+ (center) --++ (\fp_eval:n {\l__examzh_symbols_supsetneqq_lower_slant_line_angle_fp + 180} \c_colon_str \l__examzh_symbols_supsetneqq_lower_slant_line_length_dim / 2);
+ \end{tikzpicture}
+ }
+\cs_new:Npn \__examzh_symbols_nsupsetneqq:
+ {
+ \begin{tikzpicture}[line~cap=round,baseline = (current~bounding~box.south)]
+ \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) arc (90 \c_colon_str -90 \c_colon_str \l__examzh_symbols_subset_semicircle_radius_dim);
+ \draw (0,\l__examzh_symbols_subset_semicircle_radius_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim,0);
+ \draw (0,-\l__examzh_symbols_subset_semicircle_radius_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim,0);
+ \draw
+ (\l__examzh_symbols_subset_semicircle_radius_dim, - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim - \l__examzh_symbols_subset_semicircle_radius_dim, 0)
+ (\l__examzh_symbols_subset_semicircle_radius_dim, - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim - \l__examzh_symbols_subsetneqq_lower_twoline_distance_dim) --++ (-\l__examzh_symbols_subset_semicircle_line_width_dim - \l__examzh_symbols_subset_semicircle_radius_dim, 0);
+ % 定位斜线的中心点
+ \coordinate (center) at
+ (- \l__examzh_symbols_subset_semicircle_line_width_dim / 2 + \l__examzh_symbols_subset_semicircle_radius_dim / 2 , - \l__examzh_symbols_subset_semicircle_radius_dim - \l__examzh_symbols_subset_upper_lower_distance_dim - \l__examzh_symbols_subsetneqq_lower_twoline_distance_dim / 2 );
+ % 画斜线
+ \draw[overlay]
+ (center) --++ (\fp_use:N \l__examzh_symbols_supsetneqq_lower_slant_line_angle_fp \c_colon_str \l__examzh_symbols_supsetneqq_lower_slant_line_length_dim / 2)
+ (center) --++ (\fp_eval:n {\l__examzh_symbols_supsetneqq_lower_slant_line_angle_fp + 180} \c_colon_str \l__examzh_symbols_supsetneqq_lower_slant_line_length_dim / 2);
+ % 定位斜线的中心
+ \coordinate (n-center) at (-\l__examzh_symbols_subset_semicircle_line_width_dim / 2 + \l__examzh_symbols_subset_semicircle_radius_dim / 2,0);
+ % 画斜线
+ \draw[overlay]
+ (n-center) --++ (\fp_use:N \l__examzh_symbols_nsubsetneqq_slant_angle_fp \c_colon_str \l__examzh_symbols_nsubsetneqq_slant_length_dim / 8 * 3.2)
+ (n-center) --++ (\fp_eval:n { \l__examzh_symbols_nsubsetneqq_slant_angle_fp + 180} \c_colon_str \l__examzh_symbols_nsubsetneqq_slant_length_dim / 8 * 4.8);
+ \end{tikzpicture}
+ }
+\AtBeginDocument
+ {
+ \cs_set_eq:NN \__examzh_symbols_old_subset: \subset
+ \cs_set_eq:NN \__examzh_symbols_old_supset: \supset
+ \cs_set_eq:NN \__examzh_symbols_old_nsubset: \nsubset
+ \cs_set_eq:NN \__examzh_symbols_old_nsupset: \nsupset
+ \cs_set_eq:NN \__examzh_symbols_old_subseteq: \subseteq
+ \cs_set_eq:NN \__examzh_symbols_old_supseteq: \supseteq
+ \cs_set_eq:NN \__examzh_symbols_old_nsubseteq: \nsubseteq
+ \cs_set_eq:NN \__examzh_symbols_old_nsupseteq: \nsupseteq
+ \cs_set_eq:NN \__examzh_symbols_old_subsetneqq: \subsetneqq
+ \cs_set_eq:NN \__examzh_symbols_old_supsetneqq: \supsetneqq
+ % \cs_set_eq:NN \__examzh_symbols_old_nsubsetneqq: \nsubsetneqq
+ % \cs_set_eq:NN \__examzh_symbols_old_nsupsetneqq: \nsupsetneqq
+ \RenewDocumentCommand { \subset } { s }
+ {
+ \group_begin:
+ \keys_set:nn { exam-zh / symbols }
+ {
+ subset-radius = 0.2em,
+ subset-upper-linewidth = 0.6em
+ }
+ \IfBooleanTF {#1}
+ { \__examzh_symbols_old_subset: }
+ {
+ \mathrel
+ {
+ \__examzh_symbols_symbol_four_size:n
+ { \__examzh_symbols_subset: }
+ }
+ }
+ \group_end:
+ }
+ \RenewDocumentCommand { \nsubset } { s }
+ {
+ \group_begin:
+ \keys_set:nn { exam-zh / symbols }
+ {
+ subset-radius = 0.2em,
+ subset-upper-linewidth = 0.6em,
+ nsubset-n-slant-angle = 65,
+ nsubset-n-slant-length = 1em,
+ }
+ \IfBooleanTF {#1}
+ { \__examzh_symbols_old_nsubset: }
+ {
+ \mathrel
+ {
+ \__examzh_symbols_symbol_four_size:n
+ { \__examzh_symbols_nsubset: }
+ }
+ }
+ \group_end:
+ }
+ \RenewDocumentCommand { \subseteq } { s }
+ {
+ \group_begin:
+ \keys_set:nn { exam-zh / symbols }
+ {
+ subset-radius = 0.2em,
+ subset-upper-linewidth = 0.6em,
+ subset-upper-lower-distance = 0.12em,
+ subset-lower-linewidth =
+ {
+ \l__examzh_symbols_subset_semicircle_radius_dim + \l__examzh_symbols_subset_semicircle_line_width_dim
+ }
+ }
+ \IfBooleanTF {#1}
+ { \__examzh_symbols_old_subseteq: }
+ {
+ \mathrel
+ {
+ \__examzh_symbols_symbol_four_size:n
+ { \__examzh_symbols_subseteq: }
+ }
+ }
+ \group_end:
+ }
+ \RenewDocumentCommand { \nsubseteq } { s }
+ {
+ \group_begin:
+ \keys_set:nn { exam-zh / symbols }
+ {
+ subset-radius = 0.2em,
+ subset-upper-linewidth = 0.6em,
+ subset-lower-linewidth =
+ {
+ \l__examzh_symbols_subset_semicircle_radius_dim + \l__examzh_symbols_subset_semicircle_line_width_dim
+ },
+ subset-upper-lower-distance = 0.12em,
+ nsubseteq-n-slant-angle = 68,
+ nsubseteq-n-slant-length = 1em,
+ }
+ \IfBooleanTF {#1}
+ { \__examzh_symbols_old_nsubseteq: }
+ {
+ \mathrel
+ {
+ \__examzh_symbols_symbol_four_size:n
+ { \__examzh_symbols_nsubseteq: }
+ }
+ }
+ \group_end:
+ }
+ \RenewDocumentCommand { \subsetneqq } { s }
+ {
+ \group_begin:
+ \keys_set:nn { exam-zh / symbols }
+ {
+ subset-radius = 0.2em,
+ subset-upper-linewidth = 0.6em,
+ subset-lower-linewidth =
+ {
+ \l__examzh_symbols_subset_semicircle_radius_dim + \l__examzh_symbols_subset_semicircle_line_width_dim
+ },
+ subset-upper-lower-distance = 0.12em,
+ subsetneqq-lower-twoline-distance = 0.14em,
+ subsetneqq-lower-slant-length = 0.42em,
+ subsetneqq-lower-slant-angle = 55,
+ }
+ \IfBooleanTF {#1}
+ { \__examzh_symbols_old_subsetneqq: }
+ {
+ \mathrel
+ {
+ \__examzh_symbols_symbol_four_size:n
+ { \__examzh_symbols_subsetneqq: }
+ }
+ }
+ \group_end:
+ }
+ \NewDocumentCommand { \nsubsetneqq } { }
+ {
+ \group_begin:
+ \keys_set:nn { exam-zh / symbols }
+ {
+ subset-radius = 0.2em,
+ subset-upper-linewidth = 0.6em,
+ subset-lower-linewidth =
+ {
+ \l__examzh_symbols_subset_semicircle_radius_dim + \l__examzh_symbols_subset_semicircle_line_width_dim
+ },
+ subset-upper-lower-distance = 0.12em,
+ subsetneqq-lower-twoline-distance = 0.14em,
+ subsetneqq-lower-slant-length = 0.42em,
+ subsetneqq-lower-slant-angle = 55,
+ nsubsetneqq-n-slant-angle = 70,
+ nsubsetneqq-n-slant-length = 1.2em,
+ }
+ \mathrel
+ {
+ \__examzh_symbols_symbol_four_size:n
+ { \__examzh_symbols_nsubsetneqq: }
+ }
+ \group_end:
+ }
+ \RenewDocumentCommand { \supset } { s }
+ {
+ \group_begin:
+ \keys_set:nn { exam-zh / symbols }
+ {
+ subset-radius = 0.2em,
+ subset-upper-linewidth = 0.6em
+ }
+ \IfBooleanTF {#1}
+ { \__examzh_symbols_old_supset: }
+ {
+ \mathrel
+ {
+ \__examzh_symbols_symbol_four_size:n
+ { \__examzh_symbols_supset: }
+ }
+ }
+ \group_end:
+ }
+ \RenewDocumentCommand { \nsupset } { s }
+ {
+ \group_begin:
+ \keys_set:nn { exam-zh / symbols }
+ {
+ subset-radius = 0.2em,
+ subset-upper-linewidth = 0.6em,
+ nsubset-n-slant-angle = 65,
+ nsubset-n-slant-length = 1em,
+ }
+ \IfBooleanTF {#1}
+ { \__examzh_symbols_old_nsupset: }
+ {
+ \mathrel
+ {
+ \__examzh_symbols_symbol_four_size:n
+ { \__examzh_symbols_nsupset: }
+ }
+ }
+ \group_end:
+ }
+ \RenewDocumentCommand { \supseteq } { s }
+ {
+ \group_begin:
+ \keys_set:nn { exam-zh / symbols }
+ {
+ subset-radius = 0.2em,
+ subset-upper-linewidth = 0.6em,
+ subset-upper-lower-distance = 0.12em,
+ subset-lower-linewidth =
+ {
+ \l__examzh_symbols_subset_semicircle_radius_dim + \l__examzh_symbols_subset_semicircle_line_width_dim
+ }
+ }
+ \IfBooleanTF {#1}
+ { \__examzh_symbols_old_supseteq: }
+ {
+ \mathrel
+ {
+ \__examzh_symbols_symbol_four_size:n
+ { \__examzh_symbols_supseteq: }
+ }
+ }
+ \group_end:
+ }
+ \RenewDocumentCommand { \nsupseteq } { s }
+ {
+ \group_begin:
+ \keys_set:nn { exam-zh / symbols }
+ {
+ subset-radius = 0.2em,
+ subset-upper-linewidth = 0.6em,
+ subset-lower-linewidth =
+ {
+ \l__examzh_symbols_subset_semicircle_radius_dim + \l__examzh_symbols_subset_semicircle_line_width_dim
+ },
+ subset-upper-lower-distance = 0.12em,
+ nsubseteq-n-slant-angle = 68,
+ nsubseteq-n-slant-length = 1em,
+ }
+ \IfBooleanTF {#1}
+ { \__examzh_symbols_old_nsupseteq: }
+ {
+ \mathrel
+ {
+ \__examzh_symbols_symbol_four_size:n
+ { \__examzh_symbols_nsupseteq: }
+ }
+ }
+ \group_end:
+ }
+ \RenewDocumentCommand { \supsetneqq } { s }
+ {
+ \group_begin:
+ \keys_set:nn { exam-zh / symbols }
+ {
+ subset-radius = 0.2em,
+ subset-upper-linewidth = 0.6em,
+ subset-lower-linewidth =
+ {
+ \l__examzh_symbols_subset_semicircle_radius_dim + \l__examzh_symbols_subset_semicircle_line_width_dim
+ },
+ subset-upper-lower-distance = 0.12em,
+ subsetneqq-lower-twoline-distance = 0.14em,
+ supsetneqq-lower-slant-length = 0.4em,
+ supsetneqq-lower-slant-angle = 60,
+ }
+ \IfBooleanTF {#1}
+ { \__examzh_symbols_old_supsetneqq: }
+ {
+ \mathrel
+ {
+ \__examzh_symbols_symbol_four_size:n
+ { \__examzh_symbols_supsetneqq: }
+ }
+ }
+ \group_end:
+ }
+ \NewDocumentCommand { \nsupsetneqq } { }
+ {
+ \group_begin:
+ \keys_set:nn { exam-zh / symbols }
+ {
+ subset-radius = 0.2em,
+ subset-upper-linewidth = 0.6em,
+ subset-lower-linewidth =
+ {
+ \l__examzh_symbols_subset_semicircle_radius_dim + \l__examzh_symbols_subset_semicircle_line_width_dim
+ },
+ subset-upper-lower-distance = 0.12em,
+ subsetneqq-lower-twoline-distance = 0.14em,
+ supsetneqq-lower-slant-length = 0.4em,
+ supsetneqq-lower-slant-angle = 60,
+ nsubsetneqq-n-slant-angle = 70,
+ nsubsetneqq-n-slant-length = 1.2em,
+ }
+ \mathrel
+ {
+ \__examzh_symbols_symbol_four_size:n
+ { \__examzh_symbols_nsupsetneqq: }
+ }
+ \group_end:
+ }
+ % \RenewDocumentCommand { \subset } { s }
+ % {
+ % \group_begin:
+ % \keys_set:nn { exam-zh / symbols }
+ % {
+ % subset-radius = 0.2em,
+ % subset-upper-linewidth = 0.6em,
+ % subset-lower-linewidth =
+ % {
+ % \l__examzh_symbols_subset_semicircle_radius_dim + \l__examzh_symbols_subset_semicircle_line_width_dim
+ % },
+ % subset-upper-lower-distance = 0.12em,
+ % subsetneqq-lower-twoline-distance = 0.14em,
+ % subsetneqq-lower-slant-length = 0.42em,
+ % supsetneqq-lower-slant-length = 0.4em,
+ % subsetneqq-lower-slant-angle = 55,
+ % supsetneqq-lower-slant-angle = 60,
+ % nsubset-n-slant-angle = 65,
+ % nsubseteq-n-slant-angle = 68,
+ % nsubsetneqq-n-slant-angle = 70,
+ % nsubset-n-slant-length = 1em,
+ % nsubseteq-n-slant-length = 1em,
+ % nsubsetneqq-n-slant-length = 1.2em,
+ % }
+ % \IfBooleanTF {#1}
+ % { \__examzh_symbols_old_subset: }
+ % {
+ % \mathrel
+ % {
+ % \__examzh_symbols_symbol_four_size:n
+ % { \__examzh_symbols_subset: }
+ % }
+ % }
+ % \group_end:
+ % }
+ \RenewDocumentCommand { \subseteq } { s }
+ {
+ \group_begin:
+ \keys_set:nn { exam-zh / symbols }
+ {
+ subset-radius = 0.2em,
+ subset-upper-linewidth = 0.6em,
+ subset-lower-linewidth =
+ {
+ \l__examzh_symbols_subset_semicircle_radius_dim + \l__examzh_symbols_subset_semicircle_line_width_dim
+ },
+ subset-upper-lower-distance = 0.12em,
+ }
+ \IfBooleanTF {#1}
+ { \__examzh_symbols_old_subseteq: }
+ {
+ \mathrel
+ {
+ \__examzh_symbols_symbol_four_size:n
+ { \__examzh_symbols_subseteq: }
+ }
+ }
+ \group_end:
+ }
+
+ }
+
+
+
+% 并集 交集 cap cup
+
+% 直线长度
+\dim_new:N \l__examzh_symbols_cap_line_length_dim
+\dim_new:N \l__examzh_symbols_cup_line_length_dim
+% 半径大小
+\dim_new:N \l__examzh_symbols_cap_radius_dim
+\dim_new:N \l__examzh_symbols_cup_radius_dim
+
+\cs_new:Npn \__examzh_symbols_cap:
+ {
+ \begin{tikzpicture}[line~cap=round, line~width = 0.6pt,baseline = {([yshift = 1.2pt]current~bounding~box.south)}]
+ \draw (\l__examzh_symbols_cap_radius_dim,0) arc (0 \c_colon_str 180 \c_colon_str \l__examzh_symbols_cap_radius_dim);
+ \draw
+ (\l__examzh_symbols_cap_radius_dim,0) --++ (0,-\l__examzh_symbols_cap_line_length_dim)
+ (-\l__examzh_symbols_cap_radius_dim,0) --++ (0,-\l__examzh_symbols_cap_line_length_dim);
+ \end{tikzpicture}
+ }
+\cs_new:Npn \__examzh_symbols_cup:
+ {
+ \begin{tikzpicture}[line~cap=round, line~width = 0.6pt,baseline = {([yshift = 1.8pt]current~bounding~box.south)}]
+ \draw (-\l__examzh_symbols_cup_radius_dim,0) arc (180 \c_colon_str 360 \c_colon_str \l__examzh_symbols_cup_radius_dim);
+ \draw
+ (\l__examzh_symbols_cup_radius_dim,0) --++ (0,\l__examzh_symbols_cup_line_length_dim)
+ (-\l__examzh_symbols_cup_radius_dim,0) --++ (0,\l__examzh_symbols_cup_line_length_dim);
+ \end{tikzpicture}
+ }
+\AtBeginDocument
+ {
+ \cs_set_eq:NN \__examzh_symbols_old_cap: \cap
+ \cs_set_eq:NN \__examzh_symbols_old_cup: \cup
+ \RenewDocumentCommand { \cap } { s }
+ {
+ \group_begin:
+ \dim_set:Nn \l__examzh_symbols_cap_line_length_dim { 0.56em }
+ \dim_set:Nn \l__examzh_symbols_cap_radius_dim { 0.28em }
+ \IfBooleanTF {#1}
+ { \__examzh_symbols_old_cap: }
+ {
+ \mathrel
+ {
+ \__examzh_symbols_symbol_four_size:n
+ { \__examzh_symbols_cap: }
+ }
+ }
+ \group_end:
+ }
+ \RenewDocumentCommand { \cup } { s }
+ {
+ \group_begin:
+ \dim_set:Nn \l__examzh_symbols_cup_line_length_dim { 0.53em }
+ \dim_set:Nn \l__examzh_symbols_cup_radius_dim { 0.28em }
+ \IfBooleanTF {#1}
+ { \__examzh_symbols_old_cup: }
+ {
+ \mathrel
+ {
+ \__examzh_symbols_symbol_four_size:n
+ { \__examzh_symbols_cup: }
+ }
+ }
+ \group_end:
+ }
+ }
+% 相似
+\cs_new:Npn \__examzh_symbols_sim:
+ {
+ \begin{tikzpicture}[line~cap=round, line~width = 0.6pt,baseline = {([yshift = -1pt]current~bounding~box.south)}]
+ \draw
+ (-.25em,1.15ex)
+ .. controls (-.55em,1.15ex) and (-.51em,.23ex) .. (-.275em,.23ex)
+ .. controls (0,.23ex) and (0,1.15ex) .. (.275em,1.15ex)
+ .. controls (.51em,1.15ex) and (.55em,.23ex) .. (.25em,.23ex);
+ \end{tikzpicture}
+ }
+\cs_new:Npn \__examzh_symbols_nsim:
+ {
+ \begin{tikzpicture}[line~width = 0.6pt,line~cap=round, baseline = {([yshift = 1pt]current~bounding~box.south)}]
+ \draw
+ (-.25em,1.15ex)
+ .. controls (-.55em,1.15ex) and (-.51em,.23ex) .. (-.275em,.23ex)
+ .. controls (0,.23ex) and (0,1.15ex) .. (.275em,1.15ex)
+ .. controls (.51em,1.15ex) and (.55em,.23ex) .. (.25em,.23ex);
+ \draw (-0.15em,-0.2ex) --++ (70 \c_colon_str 0.8em);
+ \end{tikzpicture}
+ }
+\AtBeginDocument
+ {
+ \cs_set_eq:NN \__examzh_symbols_old_sim: \backsim
+ \RenewDocumentCommand { \sim } { s }
+ {
+ \IfBooleanTF {#1}
+ { \__examzh_symbols_old_sim: }
+ {
+ \mathrel { \__examzh_symbols_symbol_four_size:n { \__examzh_symbols_sim: } }
+ }
+ }
+ \RenewDocumentCommand { \nsim } { }
+ {
+ \mathrel { \__examzh_symbols_symbol_four_size:n { \__examzh_symbols_nsim: } }
+ }
+ }
+
+% 全等
+\cs_new:Npn \__examzh_symbols_cong:
+ {
+ \begin{tikzpicture}[line~cap=round, baseline]
+ \draw
+ (-.2em,1.35ex)
+ .. controls (-.46em,1.6ex) and (-.54em,.65ex) .. (-.25em,.65ex)
+ .. controls (-.06em,.65ex) and (.06em,1.35ex) .. (.25em,1.35ex)
+ .. controls (.54em,1.35ex) and (.46em,.4ex) .. (.2em,.65ex)
+ (-.46em,.4ex) -- (.46em,.4ex)
+ (-.46em,0ex) -- (.46em,0ex);
+ \end{tikzpicture}
+ }
+\cs_new:Npn \__examzh_symbols_ncong:
+ {
+ \begin{tikzpicture}[line~cap=round, baseline]
+ \draw
+ (-.2em,1.35ex)
+ .. controls (-.46em,1.6ex) and (-.54em,.65ex) .. (-.25em,.65ex)
+ .. controls (-.06em,.65ex) and (.06em,1.35ex) .. (.25em,1.35ex)
+ .. controls (.54em,1.35ex) and (.46em,.4ex) .. (.2em,.65ex)
+ (-.46em,.4ex) -- (.46em,.4ex)
+ (-.46em,0ex) -- (.46em,0ex);
+ \draw (-0.22em,-0.4ex) --++ (66 \c_colon_str 1em);
+ \end{tikzpicture}
+ }
+
+\AtBeginDocument
+ {
+ \cs_set_eq:NN \__examzh_symbols_old_cong: \backcong
+ \RenewDocumentCommand { \cong } { s }
+ {
+ \IfBooleanTF {#1}
+ { \__examzh_symbols_old_cong: }
+ {
+ \mathrel { \__examzh_symbols_symbol_four_size:n { \__examzh_symbols_cong: } }
+ }
+ }
+ \RenewDocumentCommand { \ncong } { }
+ {
+ \mathrel { \__examzh_symbols_symbol_four_size:n { \__examzh_symbols_ncong: } }
+ }
+ }
+
+% 处理符号的不同情况的大小
+\cs_set_eq:NN \NewDocumentCommand:Nnn \NewDocumentCommand
+\cs_set_eq:NN \RenewDocumentCommand:Nnn \RenewDocumentCommand
+\cs_generate_variant:Nn \NewDocumentCommand:Nnn { cnn }
+\cs_generate_variant:Nn \RenewDocumentCommand:Nnn { cnn }
+
+\cs_new:Npn \__examzh_symbols_new_command_without_star_or_old_version:n #1
+ {
+ \NewDocumentCommand:cnn { #1 } { }
+ {
+ \mathrel
+ {
+ \__examzh_symbols_symbol_four_size:n
+ { \use:c { __examzh_symbols_ #1 : } }
+ }
+ }
+ }
+
+\cs_new:Npn \__examzh_symbols_new_command_with_star_and_old_version:n #1
+ {
+ \RenewDocumentCommand:cnn { #1 } { s }
+ {
+ \IfBooleanTF {##1}
+ { \use:c { __examzh_symbols_old_ #1 : } }
+ {
+ \mathrel
+ {
+ \__examzh_symbols_symbol_four_size:n
+ { \use:c { __examzh_symbols_ #1 : } }
+ }
+ }
+ }
+ }
+\cs_new:Npn \__examzh_symbols_symbol_four_size:n #1
+ {
+ \mathchoice
+ {
+ \hbox:n
+ {
+ \fontsize{\tf@size}{\tf@size}\selectfont #1
+ }
+ }
+ {
+ \hbox:n
+ {
+ \fontsize{\tf@size}{\tf@size}\selectfont #1
+ }
+ }
+ {
+ \hbox:n
+ {
+ \fontsize{\sf@size}{\sf@size}\selectfont #1
+ }
+ }
+ {
+ \hbox:n
+ {
+ \fontsize{\ssf@size}{\ssf@size}\selectfont #1
+ }
+ }
+ } \ No newline at end of file
diff --git a/Master/texmf-dist/tex/latex/exam-zh/exam-zh.cls b/Master/texmf-dist/tex/latex/exam-zh/exam-zh.cls
new file mode 100644
index 00000000000..7deb619de63
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/exam-zh/exam-zh.cls
@@ -0,0 +1,2214 @@
+%
+% Copyright (c) 2022 Zeping Lee
+% Released under the LaTeX Project Public License v1.3c License.
+% Repository: https://gitee.com/zepinglee/exam-zh
+%
+
+\NeedsTeXFormat{LaTeX2e}[2017/04/15]
+\RequirePackage{expl3}
+\ProvidesExplClass {exam-zh} {2022-07-28} {v0.1.13} {LaTeX template for Chinese exam}
+
+% 检查 LaTeX2e kernel 版本
+\msg_new:nnn { exam-zh } { latex-too-old }
+ { TeX~ Live~ 2020~ or~ later~ version~ is~ required~ to~ compile~ this~ document. }
+\@ifl@t@r \fmtversion { 2020/02/02 }
+ { }
+ { \msg_fatal:nn { exam-zh } { latex-too-old } }
+
+% 检查编译引擎,要求使用 XeLaTeX。
+\msg_new:nnn { exam-zh } { incompatible-engine }
+ { XeLaTeX~ is~ required~ to~ compile~ this~ document. }
+
+\sys_if_engine_xetex:F
+ { \msg_fatal:nn { exam-zh } { incompatible-engine } }
+
+
+% 使用 l3keys 定义 \examsetup 配置命令
+\NewDocumentCommand \examsetup { m }
+ { \keys_set:nn { exam-zh } {#1} }
+
+
+
+
+% 加载文档类和宏包
+
+% 处理文档类选项
+\PassOptionsToClass { UTF8 , scheme = chinese, openany } { ctexbook }
+\DeclareOption* { \PassOptionsToClass { \CurrentOption } { ctexbook } }
+\ProcessOptions*
+
+\RequirePackage { filehook }
+\AtEndOfPackageFile* { fontspec }
+ { \msg_redirect_name:nnn { fontspec } { no-script } { none } }
+\AtEndOfPackageFile* { xeCJK }
+ {
+ \msg_redirect_name:nnn { xeCJK } { CJKfamily-redef } { none }
+ \defaultCJKfontfeatures
+ {
+ Script = CJK,
+ % Mapping = fullwidth-stop ,
+ }
+ }
+
+% 载入 \cls{ctexbook} 文档类。
+\LoadClass { ctexbook }
+
+% 要求 ctex v2.4.9 2017-04-01 或更高的版本。
+\msg_new:nnn { exam-zh } { require-package-version }
+ { The~ package~ "#1"~ is~ required. }
+
+\@ifclasslater { ctexbook } { 2017/04/01 }
+ { }
+ {
+ \msg_fatal:nnn { exam-zh } { require-package-version }
+ { ctex~ v2.4.9~ 2017-04-01 }
+ }
+
+% 建议在模板开始处载入全部宏包,不要轻易改变加载顺序。
+\RequirePackage { etoolbox }
+\RequirePackage { geometry }
+\RequirePackage { fontspec }
+\RequirePackage { xeCJK }
+\RequirePackage { xeCJKfntef }
+\RequirePackage { fancyhdr }
+\RequirePackage { lastpage }
+\RequirePackage { amsmath }
+\RequirePackage { enumitem }
+\RequirePackage { varwidth }
+
+\ExplSyntaxOff
+\RequirePackage { tikzpagenodes }
+\usetikzlibrary { decorations.markings }
+\usetikzlibrary { decorations.text }
+\ExplSyntaxOn
+
+\RequirePackage { exam-zh-font }
+\RequirePackage { exam-zh-question }
+\RequirePackage { exam-zh-choices }
+\RequirePackage { exam-zh-symbols }
+\RequirePackage { exam-zh-chinese-english }
+
+\AtEndPreamble
+ {
+ \RequirePackage { hyperref }
+ \hypersetup
+ {
+ bookmarksnumbered = true,
+ psdextra = true,
+ unicode = true,
+ hidelinks
+ }
+ }
+
+
+% 对冲突的宏包报错。
+\msg_new:nnn { exam-zh } { package-conflict }
+ { The~ "#2"~ package~ is~ incompatible~ with~ "#1". }
+
+\cs_new:Npn \examzh_package_conflict:nn #1#2
+ {
+ \AtEndOfPackageFile* {#1}
+ {
+ \AtBeginOfPackageFile* {#2}
+ { \msg_error:nnnn { exam-zh } { package-conflict } {#1} {#2} }
+ }
+ }
+
+\examzh_package_conflict:nn { unicode-math } { amscd }
+\examzh_package_conflict:nn { unicode-math } { amsfonts }
+\examzh_package_conflict:nn { unicode-math } { amssymb }
+\examzh_package_conflict:nn { unicode-math } { bbm }
+\examzh_package_conflict:nn { unicode-math } { bm }
+\examzh_package_conflict:nn { unicode-math } { eucal }
+\examzh_package_conflict:nn { unicode-math } { eufrak }
+\examzh_package_conflict:nn { unicode-math } { mathrsfs }
+\examzh_package_conflict:nn { unicode-math } { newtxmath }
+\examzh_package_conflict:nn { unicode-math } { upgreek }
+
+\examzh_package_conflict:nn { enumitem } { paralist }
+
+
+% 标点处理
+\tl_const:Nn \c__examzh_fwid_full_stop_tl { ^^^^ff0e }
+
+\keys_define:nn { exam-zh }
+ { style .meta:nn = { exam-zh / style } {#1} }
+\keys_define:nn { exam-zh / style }
+ {
+ fullwidth-stop .choice:,
+ fullwidth-stop .value_required:n = true,
+ fullwidth-stop / catcode .code:n =
+ {
+ \__examzh_set_fullwidth_stop_catcode:
+ },
+ fullwidth-stop / false .code:n = { }
+ }
+\cs_new:Npn \__examzh_set_fullwidth_stop_catcode:
+ {
+ \char_set_active_eq:NN ^^^^3002 \c__examzh_fwid_full_stop_tl
+ \char_set_catcode_active:N ^^^^3002
+ }
+
+\keys_set:nn { exam-zh / style }
+ {
+ fullwidth-stop = false
+ }
+
+\keys_set:nn { ctex }
+ {
+ % 修改目录层级
+ tocdepth = 0,
+ chapter =
+ {
+ numbering = false,
+ beforeskip = -4ex,
+ afterskip = 4ex minus 1ex
+ }
+ }
+
+% 师生两版
+
+% 用户自定义统一控制的预设 (将所需要控制的键值进行预设置)
+
+\NewDocumentCommand { \ExamPrintAnswerSet } { O{} m }
+ % #1: 命令
+ % #2: 键值 foo/bar
+ {
+ \clist_const:Nn \g__examzh_print_answer_cmd_set_clist {#1}
+ \clist_const:Nn \g__examzh_print_answer_keys_set_clist {#2}
+ }
+
+\NewDocumentCommand { \ExamPrintAnswer } { }
+ {
+ \clist_use:Nn \g__examzh_print_answer_cmd_set_clist {}
+ \clist_if_empty:NF \g__examzh_print_answer_keys_set_clist
+ {
+ \keys_set:nx { exam-zh }
+ { \g__examzh_print_answer_keys_set_clist }
+ }
+ }
+
+
+
+\str_new:N \l__examzh_latexmk_engine_str
+\str_new:N \g__examzh_student_version_jobname_str
+\str_new:N \l__examzh_student_version_suffix_str
+\str_const:Nn \l__examzh_latexmk_str { latexmk }
+
+\keys_define:nn { exam-zh / style }
+ {
+ student-version-suffix .code:n =
+ { \str_set:Nn \l__examzh_student_version_suffix_str {#1} },
+ student-version-cleanaux .bool_set:N = \l__examzh_student_version_clean_aux_bool
+ }
+\keys_set:nn { exam-zh / style }
+ {
+ student-version-suffix = { _student_version },
+ student-version-cleanaux = true
+ }
+
+\cs_new:Nn \__examzh_build_student_version_jobname:
+ {
+ \str_gset:Nx \g__examzh_student_version_jobname_str { \c_sys_jobname_str }
+ \str_gremove_all:Nn \g__examzh_student_version_jobname_str { " }
+ \str_gput_left:Nn \g__examzh_student_version_jobname_str { " }
+ \str_gput_right:Nx \g__examzh_student_version_jobname_str { \l__examzh_student_version_suffix_str }
+ \str_gput_right:Nn \g__examzh_student_version_jobname_str { " }
+ }
+
+\AtEndPreamble
+ {
+ \sys_if_shell_unrestricted:T
+ {
+ \str_set:Nn \l__examzh_latexmk_engine_str { -xelatex }
+ \__examzh_build_student_version_jobname:
+ \sys_shell_now:x
+ {
+ \l__examzh_latexmk_str \c_space_tl
+ \l__examzh_latexmk_engine_str \c_space_tl
+ -pretex='
+ % \string\RequirePackage{etoolbox}
+ % \string\BeforeBeginEnvironment{document}{\string\ExamPrintAnswer}
+ \string\AddToHook{env/document/before}{\string\ExamPrintAnswer}
+ % \string\AtBeginDocument{\string\ExamPrintAnswer}
+ ' \c_space_tl
+ -usepretex \c_space_tl
+ -jobname=\g__examzh_student_version_jobname_str \c_space_tl
+ \c_sys_jobname_str
+ \bool_if:NT \l__examzh_student_version_clean_aux_bool
+ {
+ &&
+ \l__examzh_latexmk_str \c_space_tl
+ \l__examzh_latexmk_engine_str \c_space_tl
+ -c \c_space_tl
+ -jobname=\g__examzh_student_version_jobname_str \c_space_tl
+ \c_sys_jobname_str
+ }
+ }
+ \sys_shell_now:x
+ {
+ \l__examzh_latexmk_str \c_space_tl
+ \l__examzh_latexmk_engine_str \c_space_tl
+ \c_sys_jobname_str
+ \bool_if:NT \l__examzh_student_version_clean_aux_bool
+ {
+ &&
+ \l__examzh_latexmk_str \c_space_tl
+ \l__examzh_latexmk_engine_str \c_space_tl
+ -c \c_space_tl
+ \c_sys_jobname_str
+ }
+ }
+ \stop
+ }
+ }
+
+
+% 处理目录
+\patchcmd { \tableofcontents }
+ { \@starttoc{toc} }
+ {
+ \thispagestyle { empty }
+ \pagestyle { empty }
+ \@starttoc{toc}
+ }
+ {}{\fail}
+\cs_set_eq:NN \t@bleofcontents \tableofcontents
+\RenewDocumentCommand { \tableofcontents } { }
+ {
+ \newpage
+ \int_set:Nn \c@page { 0 }
+ \group_begin:
+ % \str_case:VnT \g__examzh_sealline_scope_str
+ % {
+ % { everypage } {}
+ % { oddpage } {}
+ % }
+ % {
+ % \RemoveFromHook { shipout / background }
+ \cs_set_eq:NN \onecolumn \twocolumn
+ \bool_set_true:N \g__examzh_page_show_chapter_bool
+ \keys_set:nn { ctex }
+ {
+ chapter =
+ {
+ beforeskip = 1pt,
+ afterskip = 2ex minus 1ex
+ }
+ }
+ \t@bleofcontents
+ \group_end:
+ \newpage
+ % 将页码计数器重设置为 1
+ \int_set:Nn \c@page { 1 }
+ }
+
+\AtEndPreamble
+ {
+ % A3 情况 separate 的目录页码需要改为 2* -1
+ \bool_lazy_and:nnT
+ {
+ ! \bool_if_p:c { g__examzh_page_size_a4paper_bool }
+ }
+ {
+ ! \bool_if_p:c { g__examzh_page_a3paper_foot_common_bool }
+ }
+ {
+ \cs_set_eq:Nc \addcontentsline { __examzh_addcontentsline_a3paper_separate:nnn }
+ }
+ }
+% https://tex.stackexchange.com/questions/650823/why-my-patch-to-addcontentsline-is-broken-in-atendpreamble-and-bool-ifnt
+% 改自 hyperref.sty
+\cs_set:cpn { __examzh_addcontentsline_a3paper_separate:nnn } #1#2#3
+ {
+ \begingroup
+ \let\label\@gobble
+ \ifx\@currentHref\@empty
+ \Hy@Warning{
+ No destination for bookmark of \string\addcontentsline,%
+ \MessageBreak destination is added%
+ }
+ \phantomsection
+ \fi
+ \expandafter\ifx\csname toclevel@#2\endcsname\relax
+ \begingroup
+ \def\Hy@tempa{#1}
+ \ifx\Hy@tempa\Hy@bookmarkstype
+ \Hy@WarningNoLine{
+ bookmark level for unknown #2 defaults to 0%
+ }
+ \else
+ \Hy@Info{bookmark level for unknown #2 defaults to 0}%
+ \fi
+ \endgroup
+ \expandafter\gdef\csname toclevel@#2\endcsname{0}%
+ \fi
+ \edef\Hy@toclevel{\csname toclevel@#2\endcsname}%
+ \Hy@writebookmark{\csname the#2\endcsname}%
+ {#3}
+ {\@currentHref}
+ {\Hy@toclevel}
+ {#1}
+ \ifHy@verbose
+ \begingroup
+ \def\Hy@tempa{#3}
+ \@onelevel@sanitize\Hy@tempa
+ \let\temp@online\on@line
+ \let\on@line\@empty
+ \Hy@Info{
+ bookmark\temp@online:\MessageBreak
+ thecounter {\csname the#2\endcsname}\MessageBreak
+ text {\Hy@tempa}\MessageBreak
+ reference {\@currentHref}\MessageBreak
+ toclevel {\Hy@toclevel}\MessageBreak
+ type {#1}
+ }
+ \endgroup
+ \fi
+ \addtocontents{#1}{
+ \protect\contentsline{#2}{#3}
+ % {\thepage}
+ { \int_eval:n { 2 * \c@page - 1 } }
+ {\@currentHref}\protected@file@percent
+ }
+ \endgroup
+ }
+\keys_define:nn { exam-zh / page }
+ {
+ show-chapter .bool_gset:N = \g__examzh_page_show_chapter_bool
+ }
+\keys_set:nn { exam-zh / page }
+ {
+ show-chapter = true
+ }
+
+\cs_set_eq:NN \__examzh_chapter:nn \chapter
+\cs_new:Npn \__examzh_chapter_star:n #1
+ {
+ \__examzh_chapter:nn * {#1}
+ }
+\RenewDocumentCommand{ \chapter }{ s o m }
+ {
+ \keys_set:nn { exam-zh / question }
+ { index = 1 }
+ \int_set:Nn \c@section { 0 }
+ \bool_if:NTF \g__examzh_page_show_chapter_bool
+ {
+ \IfBooleanTF {#1}
+ { \__examzh_chapter_star:n {#3} }
+ {
+ \IfNoValueTF {#2}
+ { \__examzh_chapter:nn {#3} }
+ { \__examzh_chapter:nn [#2] {#3} }
+ }
+ \pagestyle { plain }
+ }
+ {
+ \IfBooleanF {#1}
+ {
+ \newpage
+ % 只录入目录
+ \phantomsection
+ \addcontentsline { toc } { chapter } {#3}
+ \pagestyle { plain }
+ }
+ \clearpage
+ }
+ }
+
+% 纸张和页面布局
+
+% 控制 a3paper 和 a4paper
+\bool_new:c { g__examzh_page_size_a4paper_bool }
+% a3paper 的页脚:两页共用一个或者仍然一页一个
+\bool_new:c { g__examzh_page_a3paper_foot_common_bool }
+
+\keys_define:nn { exam-zh / page }
+ {
+ % 页面大小
+ size .choice:,
+ size / a3paper .code:n =
+ {
+ \bool_gset_false:c { g__examzh_page_size_a4paper_bool }
+ },
+ size / a4paper .code:n =
+ {
+ \bool_gset_true:c { g__examzh_page_size_a4paper_bool }
+ },
+ size .value_required:n = true,
+ % 页脚的类型
+ foot-type .choice:,
+ foot-type / common .code:n =
+ {
+ \bool_gset_true:c
+ { g__examzh_page_a3paper_foot_common_bool }
+ },
+ foot-type / separate .code:n =
+ {
+ \bool_gset_false:c
+ { g__examzh_page_a3paper_foot_common_bool }
+ }
+ }
+\keys_set:nn { exam-zh / page }
+ {
+ size = a4paper,
+ foot-type = separate,
+ }
+
+\keys_define:nn { exam-zh }
+ {
+ page .meta:nn = { exam-zh / page } {#1}
+ }
+
+
+% 字体
+
+% 中文字体
+
+% 在 ctex 的字体配置的基础上进行一些修改
+% 将苹方和微软雅黑分别替换为华文黑体和中易黑体
+
+\str_if_eq:onTF { \g__ctex_fontset_tl } { mac }
+ {
+ % \setCJKmainfont{Source~Han~Serif~SC}
+ % [
+ % ItalicFont = FZKai-Z03,
+ % ]
+ \setCJKsansfont { Heiti~ SC~ Light } [ BoldFont = Heiti~ SC~ Medium ]
+ }
+ {
+ \str_if_eq:onT { \g__ctex_fontset_tl } { windows }
+ {
+ % \setCJKmainfont{Source~Han~Serif~SC}
+ % [
+ % ItalicFont = FZKai-Z03,
+ % ]
+ \setCJKsansfont { SimHei }
+ }
+ }
+
+% 罗马数字使用中文字体
+\xeCJKDeclareCharClass { CJK } { "2160 -> "217F }
+% 带圈数字
+\xeCJKDeclareCharClass { CJK } { "2460 -> "2473 }
+
+
+% 如果有内容较高(如分式)使得行间距小于 0.5em,则将其增加至 0.5em。
+\dim_set:Nn \lineskiplimit { .5em }
+\skip_set:Nn \lineskip { .5em }
+
+
+
+% 设置 enumitem 列表格式
+\keys_define:nn { exam-zh / list }
+ {
+ step-name .tl_set:N = \l__examzh_list_step_name_tl,
+ method-name .tl_set:N = \l__examzh_list_method_name_tl,
+ case-name .tl_set:N = \l__examzh_list_case_name_tl,
+ step-punct .tl_set:N = \l__examzh_list_step_punct_tl,
+ method-punct .tl_set:N = \l__examzh_list_method_punct_tl,
+ case-punct .tl_set:N = \l__examzh_list_case_punct_tl,
+ }
+\keys_set:nn { exam-zh / list }
+ {
+ step-name = 步骤,
+ method-name = 方法,
+ case-name = 情形,
+ step-punct = .,
+ method-punct = ,
+ case-punct = .,
+ }
+\keys_define:nn { exam-zh }
+ { list .meta:nn = { exam-zh / list } {#1} }
+
+\setlist{nosep}
+
+\setlist[enumerate, 1]
+ {
+ labelindent = \parindent,
+ leftmargin = *,
+ label = { \arabic * .}
+ }
+
+\setlist[enumerate, 2]
+ {
+ left = 2em,
+ labelsep = 0pt,
+ label = { ( \arabic * ) }
+ }
+
+% 多种方法: method环境
+\newlist{method}{enumerate}{1}
+\setlist[method, 1]
+ {
+ label = {\bfseries \l__examzh_list_method_name_tl \zhnum*\l__examzh_list_method_punct_tl},
+ labelindent = !,
+ labelwidth = 1.3cm,
+ labelsep* = 0.5em,
+ leftmargin = 1.4cm
+ }
+% 分类讨论: case环境
+\newlist{case}{enumerate}{2}
+\setlist[case, 1]
+ {
+ label = {\bfseries \l__examzh_list_case_name_tl \arabic*\l__examzh_list_case_punct_tl},
+ % labelindent=-3em ,labelwidth=1.3cm, labelsep*=1em, leftmargin=20pt
+ labelindent = !,
+ labelwidth = 1.3cm,
+ labelsep* = 0.5em,
+ leftmargin = 1.7cm
+ % labelindent=\parindent, leftmargin=0pt, widest=0, itemindent=*
+ }
+\setlist[case, 2]
+ {
+ label = {\bfseries \l__examzh_list_case_name_tl \arabic{casei}.\arabic*\l__examzh_list_case_punct_tl},
+ % labelindent=-1em ,labelwidth=1.3cm, labelsep*=1em, leftmargin =20pt
+ labelindent = -0.5em,
+ labelwidth = 1.3cm,
+ labelsep* = 0.5em,
+ leftmargin = 0cm
+ }
+% 分步: step环境
+\newlist{step}{enumerate}{2}
+\setlist[step, 1]
+ {
+ label = {\bfseries \l__examzh_list_step_name_tl \arabic*\l__examzh_list_step_punct_tl},
+ labelindent = !,
+ labelwidth = 1.3cm,
+ labelsep* = 0.5em,
+ leftmargin = 1.7cm
+ % labelindent=\parindent, leftmargin = 0pt, widest = 0, itemindent = *
+ }
+\setlist[step, 2]
+ {
+ label = {\bfseries \l__examzh_list_step_name_tl \arabic{stepi}.\arabic*\l__examzh_list_step_punct_tl},
+ labelindent = -0.5em,
+ labelwidth = 1.3cm,
+ labelsep* = 0.5em,
+ leftmargin = 0cm
+ }
+
+% 横向的个人信息
+
+\clist_new:N \l__examzh_horizontal_information_clist
+
+\NewDocumentCommand \information { O{\quad} m }
+% #1 分隔符
+% #2 信息内容
+ {
+ \clist_set:Nn \l__examzh_horizontal_information_clist {#2}
+ \__examzh_print_horizontal_information:n {#1}
+ }
+\cs_new:Npn \__examzh_print_horizontal_information:n #1
+ {
+ \par \null \hfill
+ \clist_use:Nn \l__examzh_horizontal_information_clist {#1}
+ \hfill \null \par
+ }
+
+% 警告,如“在此卷上答题无效”
+\NewDocumentCommand \warning { O{\large \sffamily \bfseries} m }
+ {
+ \group_begin:
+ #1
+ \hfill #2 \hfill \null
+ \group_end:
+ \par
+ }
+
+
+% 标题处理
+\keys_define:nn { exam-zh / title }
+ {
+ title-format .tl_set:N = \l__examzh_title_format_tl,
+ subject-format .tl_set:N = \l__examzh_subject_format_tl,
+ top-sep .skip_set:N = \l__examzh_title_top_sep_skip,
+ bottom-sep .skip_set:N = \l__examzh_title_bottom_sep_skip,
+ }
+\keys_set:nn { exam-zh / title }
+ {
+ title-format = \Large,
+ subject-format = \sffamily \bfseries \huge,
+ top-sep = -.5em plus 0.3em minus 0.2em,
+ bottom-sep = 0em plus 0.3em minus 0.2em,
+ }
+\keys_define:nn { exam-zh }
+ { title .meta:nn = { exam-zh / title } {#1} }
+
+\cs_new_protected:Npn \__examzh_spread_box:nn #1#2
+ {
+ \mode_leave_vertical:
+ \hbox_to_wd:nn {#1}
+ { \tl_map_inline:xn {#2} { ##1 \hfil } \unskip }
+ }
+
+% 科目
+\tl_new:N \l__exam_zh_subject_tl
+\NewDocumentCommand \subject { o m }
+ {
+ \IfNoValueTF {#1}
+ {
+ % 默认使用自然宽度
+ \hbox_set:Nn \l_tmpa_box {#2}
+ \dim_set:Nn \l_tmpa_dim { \box_wd:N \l_tmpa_box * 2 }
+ \tl_set:Nn \l__exam_zh_subject_tl
+ {
+ \__examzh_spread_box:nn { \l_tmpa_dim } {#2}
+ }
+ }
+ {
+ % 手动调整宽度
+ \tl_set:Nn \l__exam_zh_subject_tl
+ {
+ \__examzh_spread_box:nn {#1} {#2}
+ }
+ }
+ }
+
+% 输出标题
+\RenewDocumentCommand \maketitle { }
+ {
+ \par
+ \vspace { \l__examzh_title_top_sep_skip }
+ \begin { center }
+ \let \footnote \thanks
+ { \l__examzh_title_format_tl \@title \par }
+ \tl_if_blank:VF \l__exam_zh_subject_tl
+ {
+ \addvspace { 1em }
+ { \l__examzh_subject_format_tl \l__exam_zh_subject_tl }
+ }
+ \end { center }
+ \par
+ \vspace { \l__examzh_title_bottom_sep_skip }
+ }
+
+
+
+\prg_new_conditional:Npnn \examzh_if_defined:N #1 { T , F , TF }
+ {
+ \if_meaning:w #1 \@undefined
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ }
+
+% 绝密 启用前
+\NewDocumentCommand \secret { O{\bfseries} }
+ {
+ \par \noindent
+ \group_begin:
+ #1
+ 绝密 $\bigstar$ 启用前
+ \group_end:
+ \par
+ }
+
+% 祝考试顺利
+\NewDocumentCommand \goodluck { O{祝考试顺利} }
+ {
+ \group_begin:
+ \centering
+ \examzh_if_defined:NTF \lishu
+ { \lishu }
+ { \bfseries }
+ \Large
+ $\bigstar$ #1 $\bigstar$
+ \par
+ \group_end:
+ }
+
+
+% 注意事项环境 notice
+\keys_define:nn { exam-zh / notice }
+ {
+ label .tl_set:N = \l__examzh_notice_label_tl,
+ label-format .tl_set:N = \l__examzh_notice_label_format_tl,
+ top-sep .skip_set:N = \l__examzh_notice_top_sep_skip,
+ bottom-sep .skip_set:N = \l__examzh_notice_bottom_sep_skip,
+
+ }
+\keys_set:nn { exam-zh / notice }
+ {
+ label = 注意事项:,
+ label-format = \sffamily \bfseries,
+ top-sep = .25em plus .25em minus .1em,
+ bottom-sep = .25em plus .25em minus .1em,
+ }
+\NewDocumentEnvironment { notice } { O { } O { } }
+ {
+ \keys_set:nn { exam-zh / notice } {#1}
+ \par
+ \vspace { \l__examzh_notice_top_sep_skip }
+ \noindent
+ \group_begin:
+ \l__examzh_notice_label_format_tl
+ \l__examzh_notice_label_tl
+ \group_end:
+ \begin { enumerate }
+ [
+ leftmargin = 0pt ,
+ itemindent = 3.5em ,
+ labelsep = 0.5em ,
+ labelwidth = 1.5em ,
+ align = right ,
+ label = { \arabic * . } ,
+ #2
+ ]
+ }
+ {
+ \end { enumerate }
+ \vspace { \l__examzh_notice_bottom_sep_skip }
+ }
+
+
+% 大题的标题使用 \ctexset 设置 \section 的格式
+
+\ctexset
+ {
+ section =
+ {
+ format = \heiti \bfseries ,
+ number = \chinese { section } ,
+ aftername = { 、 } ,
+ beforeskip = 2ex plus 1ex minus .5ex,
+ afterskip = 1ex plus .2ex minus 1ex
+ }
+ }
+
+
+% 正体的 e 和 i
+\NewDocumentCommand \eu { } { \mathrm{ e } }
+\NewDocumentCommand \iu { } { \mathrm{ i } }
+
+
+% 兼容 siunitx v2.x 的一些命令
+\AtEndOfPackageFile* { siunitx }
+ {
+ \ProvideDocumentCommand \unit { } { \si }
+ \ProvideDocumentCommand \qty { } { \SI }
+ \ProvideDocumentCommand \qtyproduct { } { \SI }
+ }
+
+
+
+% 密封线
+\str_new:N \g__examzh_sealline_odd_type_str
+\str_new:N \g__examzh_sealline_even_type_str
+
+\keys_define:nn { exam-zh / sealline }
+ {
+ % 是否显示密封线
+ show .bool_gset:N = \g__examzh_sealline_show_bool,
+ % 密封线类型(也理解为出现的类型,比如只在第一页,只在奇数页)
+ scope .choices:nn =
+ { firstpage, oddpage, everypage, first-and-last, mod-2, mod-3, mod-4, mod-6 }
+ { \str_gset:Nx \g__examzh_sealline_scope_str { \l_keys_choice_tl } },
+ type .choices:nn =
+ { firstpage, oddpage, everypage, first-and-last, mod-2, mod-3, mod-4, mod-6 }
+ { \str_gset:Nx \g__examzh_sealline_scope_str { \l_keys_choice_tl } },
+ % 线的厚度
+ odd-line-thickness .dim_set:N = \g__examzh_sealline_odd_line_thickness_dim,
+ even-line-thickness .dim_set:N = \g__examzh_sealline_even_line_thickness_dim,
+ line-thickness .code:n =
+ {
+ \dim_set:Nn \g__examzh_sealline_odd_line_thickness_dim {#1}
+ \dim_set:Nn \g__examzh_sealline_even_line_thickness_dim {#1}
+ },
+ % 线的偏移
+ odd-line-xshift .dim_set:N = \g__examzh_sealline_odd_line_xshift_dim,
+ odd-line-yshift .dim_set:N = \g__examzh_sealline_odd_line_yshift_dim,
+ even-line-xshift .dim_set:N = \g__examzh_sealline_even_line_xshift_dim,
+ even-line-yshift .dim_set:N = \g__examzh_sealline_even_line_yshift_dim,
+ line-xshift .code:n =
+ {
+ \dim_gset:Nn \g__examzh_sealline_odd_line_xshift_dim {#1}
+ \dim_gset:Nn \g__examzh_sealline_even_line_xshift_dim {#1}
+ },
+ line-yshift .code:n =
+ {
+ \dim_set:Nn \g__examzh_sealline_odd_line_yshift_dim {#1}
+ \dim_set:Nn \g__examzh_sealline_even_line_yshift_dim {#1}
+ },
+ % 密封线的线类型
+ % odd-line-type .str_set:N = \g__examzh_sealline_odd_type_str,
+ % even-line-type .str_set:N = \g__examzh_sealline_even_type_str,
+ odd-line-type .code:n =
+ {
+ \str_set:Nn \g__examzh_sealline_odd_type_str {#1}
+ },
+ even-line-type .code:n =
+ {
+ \str_set:Nn \g__examzh_sealline_even_type_str {#1}
+ },
+ line-type .code:n =
+ {
+ \str_gset:Nn \g__examzh_sealline_odd_type_str {#1}
+ \str_gset:Nn \g__examzh_sealline_even_type_str {#1}
+ },
+ % 密封线路径的文字内容
+ odd-text .tl_set:N = \g__examzh_sealline_odd_text_tl,
+ even-text .tl_set:N = \g__examzh_sealline_even_text_tl,
+ text .code:n =
+ {
+ \tl_gset:Nn \g__examzh_sealline_odd_text_tl {#1}
+ \tl_gset:Nn \g__examzh_sealline_even_text_tl {#1}
+ },
+ % 密封线路径的文字内容偏移
+ odd-text-xshift .dim_set:N = \g__examzh_sealline_odd_text_xshift_dim,
+ even-text-xshift .dim_set:N = \g__examzh_sealline_even_text_xshift_dim,
+ odd-text-yshift .dim_set:N = \g__examzh_sealline_odd_text_yshift_dim,
+ even-text-yshift .dim_set:N = \g__examzh_sealline_even_text_yshift_dim,
+ text-xshift .code:n =
+ {
+ \dim_gset:Nn \g__examzh_sealline_odd_text_xshift_dim {#1}
+ \dim_gset:Nn \g__examzh_sealline_even_text_xshift_dim {#1}
+ },
+ text-yshift .code:n =
+ {
+ \dim_gset:Nn \g__examzh_sealline_odd_text_yshift_dim {#1}
+ \dim_gset:Nn \g__examzh_sealline_even_text_yshift_dim {#1}
+ },
+ % 密封线路径文字的宽度
+ odd-text-width .dim_set:N = \g__examzh_sealline_odd_text_width_dim,
+ even-text-width .dim_set:N = \g__examzh_sealline_even_text_width_dim,
+ text-width .code:n =
+ {
+ \dim_gset:Nn \g__examzh_sealline_odd_text_width_dim {#1}
+ \dim_gset:Nn \g__examzh_sealline_even_text_width_dim {#1}
+ },
+ % 密封线路径文字的字体
+ odd-text-format .tl_set:N = \g__examzh_sealline_odd_text_format_tl,
+ even-text-format .tl_set:N = \g__examzh_sealline_even_text_format_tl,
+ text-format .code:n =
+ {
+ \tl_gset:Nn \g__examzh_sealline_odd_text_format_tl {#1}
+ \tl_gset:Nn \g__examzh_sealline_even_text_format_tl {#1}
+ },
+ % 密封线路径文字的方向
+ odd-text-direction-vertical .bool_gset:N = \g__examzh_sealline_odd_text_direction_vertical_bool,
+ even-text-direction-vertical .bool_gset:N = \g__examzh_sealline_even_text_direction_vertical_bool,
+ text-direction-vertical .choice:,
+ text-direction-vertical / true .code:n =
+ {
+ \bool_gset_true:N \g__examzh_sealline_odd_text_direction_vertical_bool
+ \bool_gset_true:N \g__examzh_sealline_even_text_direction_vertical_bool
+ },
+ text-direction-vertical / false .code:n =
+ {
+ \bool_gset_false:N \g__examzh_sealline_odd_text_direction_vertical_bool
+ \bool_gset_false:N \g__examzh_sealline_even_text_direction_vertical_bool
+ },
+ % 密封线路径文字的防缩比例
+ odd-text-xscale .fp_set:N = \g__examzh_sealline_odd_text_xscale_fp,
+ odd-text-yscale .fp_set:N = \g__examzh_sealline_odd_text_yscale_fp,
+ even-text-xscale .fp_set:N = \g__examzh_sealline_even_text_xscale_fp,
+ even-text-yscale .fp_set:N = \g__examzh_sealline_even_text_yscale_fp,
+ text-xscale .code:n =
+ {
+ \fp_gset:Nn \g__examzh_sealline_odd_text_xscale_fp {#1}
+ \fp_gset:Nn \g__examzh_sealline_even_text_xscale_fp {#1}
+ },
+ text-yscale .code:n =
+ {
+ \fp_gset:Nn \g__examzh_sealline_odd_text_yscale_fp {#1}
+ \fp_gset:Nn \g__examzh_sealline_even_text_yscale_fp {#1}
+ },
+ % 密封线上圆圈的参数
+ % --控制显示--
+ odd-circle-show .bool_set:N = \g__examzh_sealline_odd_circle_show_bool,
+ even-circle-show .bool_set:N = \g__examzh_sealline_even_circle_show_bool,
+ circle-show .choice:,
+ circle-show / true .code:n =
+ {
+ \bool_gset_true:N \g__examzh_sealline_odd_circle_show_bool
+ \bool_gset_true:N \g__examzh_sealline_even_circle_show_bool
+ },
+ circle-show / false .code:n =
+ {
+ \bool_gset_false:N \g__examzh_sealline_odd_circle_show_bool
+ \bool_gset_false:N \g__examzh_sealline_even_circle_show_bool
+ },
+ % --开始--
+ odd-circle-start .fp_set:N = \g__examzh_sealline_odd_circle_start_fp,
+ even-circle-start .fp_set:N = \g__examzh_sealline_even_circle_start_fp,
+ circle-start .code:n =
+ {
+ \fp_gset:Nn \g__examzh_sealline_odd_circle_start_fp {#1}
+ \fp_gset:Nn \g__examzh_sealline_even_circle_start_fp {#1}
+ },
+ % --结束--
+ odd-circle-end .fp_set:N = \g__examzh_sealline_odd_circle_end_fp,
+ even-circle-end .fp_set:N = \g__examzh_sealline_even_circle_end_fp,
+ circle-end .code:n =
+ {
+ \fp_gset:Nn \g__examzh_sealline_odd_circle_end_fp {#1}
+ \fp_gset:Nn \g__examzh_sealline_even_circle_end_fp {#1}
+ },
+ % --步长--
+ odd-circle-step .dim_set:N = \g__examzh_sealline_odd_circle_step_dim,
+ even-circle-step .dim_set:N = \g__examzh_sealline_even_circle_step_dim,
+ circle-step .code:n =
+ {
+ \dim_gset:Nn \g__examzh_sealline_odd_circle_step_dim {#1}
+ \dim_gset:Nn \g__examzh_sealline_even_circle_step_dim {#1}
+ },
+ % --直径--
+ odd-circle-diameter .dim_set:N = \g__examzh_sealline_odd_circle_diameter_dim,
+ even-circle-diameter .dim_set:N = \g__examzh_sealline_even_circle_diameter_dim,
+ circle-diameter .code:n =
+ {
+ \dim_gset:Nn \g__examzh_sealline_odd_circle_diameter_dim {#1}
+ \dim_gset:Nn \g__examzh_sealline_even_circle_diameter_dim {#1}
+ },
+ % --偏移--
+ odd-circle-xshift .dim_set:N = \g__examzh_sealline_odd_circle_xshift_dim,
+ even-circle-xshift .dim_set:N = \g__examzh_sealline_even_circle_xshift_dim,
+ circle-xshift .code:n =
+ {
+ \dim_gset:Nn \g__examzh_sealline_odd_circle_xshift_dim {#1}
+ \dim_gset:Nn \g__examzh_sealline_even_circle_xshift_dim {#1}
+ },
+ % 学生信息
+ % --内容--
+ odd-info-content .clist_set:N = \g__examzh_sealline_odd_info_content_clist,
+ % --分隔符--
+ odd-info-seperator .tl_set:N = \g__examzh_sealline_odd_info_seperator_tl,
+ % --对齐--
+ odd-info-align .tl_set:N = \g__examzh_sealline_odd_info_align_tl,
+ % --偏移--
+ odd-info-xshift .dim_set:N = \g__examzh_sealline_odd_info_xshift_dim,
+ odd-info-yshift .dim_set:N = \g__examzh_sealline_odd_info_yshift_dim,
+ }
+\keys_set:nn { exam-zh / sealline }
+ {
+ show = false,
+ % scope = firstpage,
+ % scope = oddpage,
+ scope = everypage,
+ line-thickness = 1pt,
+ line-xshift = 8mm,
+ line-yshift = 0mm,
+ line-type = loosely-dashed,
+ text = 密封线内不得答题,
+ text-xshift = 11mm,
+ text-yshift = 0pt,
+ text-width = 0.8\textheight,
+ text-format = \zihao{4}\sffamily,
+ text-xscale = 1.0,
+ text-yscale = 0.8,
+ text-direction-vertical = false,
+ circle-show = true,
+ circle-start = 0.07,
+ circle-end = 0.92,
+ circle-step = 3.5em,
+ circle-diameter = 3mm,
+ circle-xshift = 8mm,
+ odd-info-content = {
+ {\kaishu 姓名}:{\underline{\hspace*{8em}}},
+ {\kaishu 准考证号}:{\underline{\hspace*{8em}}},
+ {\kaishu 考场号}:{\underline{\hspace*{8em}}},
+ {\kaishu 座位号}:{\underline{\hspace*{8em}}}
+ },
+ odd-info-seperator = \hspace*{3em},
+ odd-info-align = center,
+ odd-info-xshift = 20mm,
+ odd-info-yshift = 0mm
+ }
+\keys_define:nn { exam-zh }
+ { sealline .meta:nn = { exam-zh / sealline } {#1} }
+
+% 只在第一页出现
+\cs_new:Npn \__examzh_sealline_scope_firstpage:
+ {
+ \AddToHook { shipout / firstpage } [ sealline ]
+ {
+ \put (0cm, 0cm)
+ { \__examzh_sealline_odd: }
+ }
+ }
+% 只在第一页和最后一页出现
+\cs_new:Npn \__examzh_sealline_scope_firstpage_and_lastpage:
+ {
+ \AddToHook { shipout / firstpage } [ sealline ]
+ {
+ \put (0cm, 0cm)
+ { \__examzh_sealline_odd: }
+ }
+ \AddToHook { shipout / lastpage } [ sealline ]
+ {
+ \put (0cm, 0cm)
+ {
+ \int_if_odd:nTF { \c@page }
+ { \__examzh_sealline_odd: }
+ { \__examzh_sealline_even: }
+ }
+ }
+ }
+% 只在奇数页出现
+\cs_new:Npn \__examzh_sealline_scope_oddpage:
+ {
+ \AddToHook { shipout / background } [ sealline ]
+ {
+ \put (0cm, 0cm)
+ {
+ \int_if_odd:nT { \c@page }
+ { \__examzh_sealline_odd: }
+ }
+ }
+ }
+% 每页都有,奇偶不同
+\cs_new:Npn \__examzh_sealline_scope_everypage:
+ {
+ \AddToHook { shipout / background } [ sealline ]
+ {
+ \put (0cm, 0cm)
+ {
+ \int_if_odd:nTF { \c@page }
+ { \__examzh_sealline_odd: }
+ { \__examzh_sealline_even: }
+ }
+ }
+ }
+% mod 2 = 1 的类型
+\cs_new:cpn { __examzh_sealline_scope_mod_2_equals_1: }
+ {
+ \AddToHook { shipout / background } [ sealline ]
+ {
+ \put (0cm, 0cm)
+ {
+ \int_compare:nNnT { \int_mod:nn { \c@page } { 2 } } = {1} { \__examzh_sealline_odd: }
+ }
+ }
+ }
+% mod 3 = 1 的类型
+\cs_new:cpn { __examzh_sealline_scope_mod_3_equals_1: }
+ {
+ \AddToHook { shipout / background } [ sealline ]
+ {
+ \put (0cm, 0cm)
+ {
+ \int_compare:nNnT { \int_mod:nn { \c@page } { 3 } } = {1} { \__examzh_sealline_odd: }
+ }
+ }
+ }
+% mod 4 = 1 的类型
+\cs_new:cpn { __examzh_sealline_scope_mod_4_equals_1: }
+ {
+ \AddToHook { shipout / background } [ sealline ]
+ {
+ \put (0cm, 0cm)
+ {
+ \int_compare:nNnT { \int_mod:nn { \c@page } { 4 } } = {1} { \__examzh_sealline_odd: }
+ }
+ }
+ }
+% mod 6 = 1 的类型
+\cs_new:cpn { __examzh_sealline_scope_mod_6_equals_1: }
+ {
+ \AddToHook { shipout / background } [ sealline ]
+ {
+ \put (0cm, 0cm)
+ {
+ \int_compare:nNnT { \int_mod:nn { \c@page } { 6 } } = {1} { \__examzh_sealline_odd: }
+ }
+ }
+ }
+
+
+\AtBeginDocument
+ { \__examzh_sealline_set: }
+\cs_new:Npn \__examzh_sealline_set:
+ {
+ \bool_if:NT \g__examzh_sealline_show_bool
+ {
+ \__examzh_sealline_scope_set:
+ \str_case:Vn \g__examzh_sealline_scope_str
+ {
+ { firstpage } { \__examzh_sealline_scope_firstpage: }
+ { oddpage } { \__examzh_sealline_scope_oddpage: }
+ { everypage } { \__examzh_sealline_scope_everypage: }
+ { first-and-last } { \__examzh_sealline_scope_firstpage_and_lastpage: }
+ { mod-2 } { \use:c { __examzh_sealline_scope_mod_2_equals_1: } }
+ { mod-3 } { \use:c { __examzh_sealline_scope_mod_3_equals_1: } }
+ { mod-4 } { \use:c { __examzh_sealline_scope_mod_4_equals_1: } }
+ { mod-6 } { \use:c { __examzh_sealline_scope_mod_6_equals_1: } }
+ }
+ }
+ }
+\cs_new:Npn \__examzh_sealline_scope_set:
+ {
+ \tl_gset:Nx \g__examzh_sealline_odd_type_parameter_tl
+ {
+ \str_case:Vn \g__examzh_sealline_odd_type_str
+ {
+ { solid } { solid }
+ { dotted } { dotted }
+ { densely-dotted } { densely~dotted }
+ { loosely-dotted } { loosely~dotted }
+ { dashed } { dashed }
+ { densely-dashed } { densely~dashed }
+ { loosely-dashed } { loosely~dashed }
+ { dash-dot } { dash~dot }
+ { densely-dash-dot } { densely~dash~dot }
+ { loosely-dash-dot } { loosely~dash~dot }
+ { dash-dot-dot } { dash~dot~dot }
+ { densely-dash-dot-dot } { densely~dash~dot~dot }
+ { loosely-dash-dot-dot } { loosely~dash~dot~dot }
+ }
+ }
+ \tl_gset:Nx \g__examzh_sealline_even_type_parameter_tl
+ {
+ \str_case:Vn \g__examzh_sealline_even_type_str
+ {
+ { solid } { solid }
+ { dotted } { dotted }
+ { densely-dotted } { densely~dotted }
+ { loosely-dotted } { loosely~dotted }
+ { dashed } { dashed }
+ { densely-dashed } { densely~dashed }
+ { loosely-dashed } { loosely~dashed }
+ { dash-dot } { dash~dot }
+ { densely-dash-dot } { densely~dash~dot }
+ { loosely-dash-dot } { loosely~dash~dot }
+ { dash-dot-dot } { dash~dot~dot }
+ { densely-dash-dot-dot } { densely~dash~dot~dot }
+ { loosely-dash-dot-dot } { loosely~dash~dot~dot }
+ }
+ }
+ }
+
+\keys_define:nn { exam-zh / page }
+ {
+ show-columnline .bool_set:N = \l__examzh_show_columnline_bool,
+ columnline-width .dim_set:N = \l__examzh_columnline_dim,
+ }
+\keys_set:nn { exam-zh / page }
+ {
+ show-columnline = true,
+ columnline-width = 0.4pt
+ }
+
+\AtEndPreamble
+ {
+ \bool_if:cTF { g__examzh_page_size_a4paper_bool }
+ {
+ % a4paper
+ \bool_if:NTF \g__examzh_sealline_show_bool
+ {
+ % 有密封线
+ \geometry
+ {
+ twoside,
+ paper = a4paper,
+ margin = 1in,
+ inner = 1.3in,
+ outer = 0.8in,
+ }
+ }
+ {
+ % 无密封线
+ \geometry
+ {
+ paper = a4paper,
+ margin = 1in,
+ }
+ }
+ }
+ {
+ % a3paper
+ \bool_if:NT \l__examzh_show_columnline_bool
+ { \dim_set:Nn \columnseprule { \l__examzh_columnline_dim } }
+ \bool_if:NTF \g__examzh_sealline_show_bool
+ {
+ % 有密封线
+ \geometry
+ {
+ twoside,
+ paper = a3paper,
+ landscape,
+ twocolumn,
+ columnsep = 30mm,
+ margin = 1in,
+ inner = 1.2in,
+ outer = 0.8in,
+ % showframe
+ }
+ }
+ {
+ % 无密封线
+ \geometry
+ {
+ paper = a3paper,
+ landscape,
+ twocolumn,
+ columnsep = 30mm,
+ margin = 1in,
+ }
+ }
+ }
+ }
+
+
+\cs_new:Npn \__examzh_sealline_odd:
+ {
+ \begin{tikzpicture}
+ [
+ remember~picture,
+ overlay,
+ ]
+ % 密封线:线
+ \__examzh_sealline_odd_line:
+ % 密封线:小圆圈
+ \__examzh_sealline_odd_circle:
+ % 线上的文字
+ \__examzh_sealline_odd_text_around_line:
+ % 学生信息
+ \__examzh_sealline_odd_infomation:
+ \end{tikzpicture}
+ }
+
+\cs_new:Npn \__examzh_sealline_even:
+ {
+ \begin{tikzpicture}[remember~picture, overlay]
+ % 密封线:线
+ \__examzh_sealline_even_line:
+ % 密封线:小圆圈
+ \__examzh_sealline_even_circle:
+ % 线上的文字
+ \__examzh_sealline_even_text_around_line:
+ \end{tikzpicture}
+ }
+
+% 线
+\cs_new:Npn \__examzh_sealline_odd_line:
+ {
+ \use:x
+ {
+ \exp_not:N \draw
+ [
+ \g__examzh_sealline_odd_type_parameter_tl,
+ line~width = \dim_use:N \g__examzh_sealline_odd_line_thickness_dim
+ ]
+ }
+ ([xshift = -\g__examzh_sealline_odd_line_xshift_dim, yshift = -\g__examzh_sealline_odd_line_yshift_dim]current~page~text~area.north~west)
+ --
+ ([xshift = -\g__examzh_sealline_odd_line_xshift_dim, yshift = \g__examzh_sealline_odd_line_yshift_dim]current~page~text~area.south~west);
+ }
+\cs_new:Npn \__examzh_sealline_even_line:
+ {
+ \use:x
+ {
+ \exp_not:N \draw
+ [
+ \g__examzh_sealline_even_type_parameter_tl,
+ line~width = \dim_use:N \g__examzh_sealline_even_line_thickness_dim
+ ]
+ }
+ ([xshift = \g__examzh_sealline_even_line_xshift_dim, yshift = -\g__examzh_sealline_even_line_yshift_dim]current~page~text~area.north~east)
+ --
+ ([xshift = \g__examzh_sealline_even_line_xshift_dim, yshift = \g__examzh_sealline_even_line_yshift_dim]current~page~text~area.south~east);
+ }
+
+% 小圆圈
+\cs_new:Npn \__examzh_sealline_odd_circle:
+ {
+ \bool_if:NT \g__examzh_sealline_odd_circle_show_bool
+ {
+ \use:x
+ {
+ \exp_not:N
+ \fill
+ [
+ decorate,
+ decoration =
+ {
+ markings,
+ mark =
+ between~positions~
+ \fp_use:N \g__examzh_sealline_odd_circle_start_fp
+ ~and~
+ \fp_use:N \g__examzh_sealline_odd_circle_end_fp
+ ~step~
+ \dim_use:N \g__examzh_sealline_odd_circle_step_dim
+ ~with
+ {
+ \exp_not:N
+ \node
+ [
+ circle,
+ draw = black,
+ fill = white,
+ minimum~size = \dim_use:N \g__examzh_sealline_odd_circle_diameter_dim
+ ]
+ {};
+ }
+ }
+ ]
+ }
+ ([xshift = -\g__examzh_sealline_odd_circle_xshift_dim]current~page~text~area.north~west)
+ --
+ ([xshift = -\g__examzh_sealline_odd_circle_xshift_dim]current~page~text~area.south~west);
+ }
+ }
+\cs_new:Npn \__examzh_sealline_even_circle:
+ {
+ \bool_if:NT \g__examzh_sealline_even_circle_show_bool
+ {
+ \use:x
+ {
+ \exp_not:N
+ \fill
+ [
+ decorate,
+ decoration =
+ {
+ markings,
+ mark =
+ between~positions~
+ \fp_use:N \g__examzh_sealline_even_circle_start_fp
+ ~and~
+ \fp_use:N \g__examzh_sealline_even_circle_end_fp
+ ~step~
+ \dim_use:N \g__examzh_sealline_even_circle_step_dim
+ ~with
+ {
+ \exp_not:N
+ \node
+ [
+ circle,
+ draw = black,
+ fill = white,
+ minimum~size = \dim_use:N \g__examzh_sealline_even_circle_diameter_dim
+ ]
+ {};
+ }
+ }
+ ]
+ }
+ ([xshift = \g__examzh_sealline_even_circle_xshift_dim]current~page~text~area.north~east)
+ --
+ ([xshift = \g__examzh_sealline_even_circle_xshift_dim]current~page~text~area.south~east);
+ }
+ }
+% 线上的文字(密封线外不得答题)
+\cs_new_protected:Npn \__examzh_sealline_odd_spread_box:nn #1#2
+ {
+ \mode_leave_vertical:
+ \bool_if:NTF \g__examzh_sealline_odd_text_direction_vertical_bool
+ {
+ \hbox_set_to_wd:Nnn \l_tmpa_box {#1}
+ {
+ \tl_set:Nx \l_tmpa_tl {#2}
+ \tl_reverse:N \l_tmpa_tl
+ \tl_map_inline:xn { \l_tmpa_tl }
+ {
+ \hbox_set:Nn \l_tmpb_box {##1}
+ \box_rotate:Nn \l_tmpb_box { -90 }
+ \box_use_drop:N \l_tmpb_box
+ \hfil
+ }
+ \unskip
+ }
+ }
+ {
+ \hbox_set_to_wd:Nnn \l_tmpa_box {#1}
+ {
+ \tl_map_inline:xn {#2} { ##1 \hfil } \unskip
+ }
+ }
+ \box_scale:Nnn \l_tmpa_box
+ { \fp_use:N \g__examzh_sealline_odd_text_xscale_fp }
+ { \fp_use:N \g__examzh_sealline_odd_text_yscale_fp }
+ \box_rotate:Nn \l_tmpa_box { 90 }
+ \box_move_down:nn
+ { #1 / 2 }
+ { \box_use_drop:N \l_tmpa_box }
+ }
+\cs_new_protected:Npn \__examzh_sealline_even_spread_box:nn #1#2
+ {
+ \mode_leave_vertical:
+ \bool_if:NTF \g__examzh_sealline_odd_text_direction_vertical_bool
+ {
+ \hbox_set_to_wd:Nnn \l_tmpa_box {#1}
+ {
+ \tl_map_inline:xn {#2}
+ {
+ \hbox_set:Nn \l_tmpb_box {##1}
+ \box_rotate:Nn \l_tmpb_box { 90 }
+ \box_use_drop:N \l_tmpb_box
+ \hfil
+ }
+ \unskip
+ }
+ }
+ {
+ \hbox_set_to_wd:Nnn \l_tmpa_box {#1}
+ {
+ \tl_map_inline:xn {#2} { ##1 \hfil } \unskip
+ }
+ }
+ \box_scale:Nnn \l_tmpa_box
+ { \fp_use:N \g__examzh_sealline_odd_text_xscale_fp }
+ { \fp_use:N \g__examzh_sealline_odd_text_yscale_fp }
+ \box_rotate:Nn \l_tmpa_box { -90 }
+ \box_move_up:nn
+ { #1 / 2 }
+ { \box_use_drop:N \l_tmpa_box }
+ }
+\cs_new:Npn \__examzh_sealline_odd_text_around_line:
+ {
+ \node [ anchor = east ]
+ at ([xshift = -\g__examzh_sealline_odd_text_xshift_dim, yshift = \g__examzh_sealline_odd_text_yshift_dim]current~page~text~area.west)
+ {
+ \g__examzh_sealline_odd_text_format_tl
+ \__examzh_sealline_odd_spread_box:nn { \g__examzh_sealline_odd_text_width_dim }
+ { \g__examzh_sealline_odd_text_tl }
+ };
+ }
+\cs_new:Npn \__examzh_sealline_even_text_around_line:
+ {
+ \bool_if:NTF \g__examzh_sealline_odd_text_direction_vertical_bool
+ {
+ \dim_set_eq:NN \l_tmpa_dim \g__examzh_sealline_even_text_yshift_dim
+ }
+ {
+ \dim_set:Nn \l_tmpa_dim { - \g__examzh_sealline_even_text_yshift_dim }
+ }
+ \dim_set_eq:NN \g__examzh_sealline_even_text_yshift_dim \l_tmpa_dim
+ \node [ anchor = west ]
+ at ([xshift = \g__examzh_sealline_even_text_xshift_dim, yshift = \g__examzh_sealline_even_text_yshift_dim]current~page~text~area.east)
+ {
+ \g__examzh_sealline_even_text_format_tl
+ \__examzh_sealline_even_spread_box:nn { \g__examzh_sealline_even_text_width_dim }
+ { \g__examzh_sealline_even_text_tl }
+ };
+ }
+% 学生信息
+\cs_new:Npn \__examzh_sealline_odd_infomation:
+ {
+ \use:x
+ {
+ \exp_not:N
+ \path
+ [
+ decorate,
+ decoration =
+ {
+ text~along~path,
+ text~align = \g__examzh_sealline_odd_info_align_tl,
+ reverse~path,
+ text = {
+ \clist_use:Nn \g__examzh_sealline_odd_info_content_clist
+ { { \g__examzh_sealline_odd_info_seperator_tl } }
+ }
+ }
+ ]
+ }
+ ([xshift = -\g__examzh_sealline_odd_info_xshift_dim, yshift = 0mm]current~page~text~area.north~west)
+ --
+ ([xshift = -\g__examzh_sealline_odd_info_xshift_dim, yshift = \g__examzh_sealline_odd_info_yshift_dim]current~page~text~area.south~west);
+ }
+
+% 信息的方格
+\keys_define:nn { exam-zh / square }
+ {
+ x-length .dim_set:N = \l__examzh_information_square_x_dim,
+ y-length .dim_set:N = \l__examzh_information_square_y_dim,
+ baseline .dim_set:N = \l__examzh_information_square_baseline_dim,
+ linewidth .dim_set:N = \l__examzh_information_square_linewidth_dim,
+ xshift .dim_set:N = \l__examzh_information_square_xshift_dim
+ }
+\keys_set:nn { exam-zh / square }
+ {
+ x-length = 1.4em,
+ y-length = 1.2em,
+ baseline = 3pt,
+ linewidth = 0.4pt,
+ }
+\keys_define:nn { exam-zh }
+ { square .meta:nn = { exam-zh / square } {#1} }
+\cs_new:Npn \__examzh_information_square_single:
+ {
+ \begin{tikzpicture}[baseline = \l__examzh_information_square_baseline_dim]
+ \draw[line~width = \l__examzh_information_square_linewidth_dim] (0,0) rectangle
+ ( \l__examzh_information_square_x_dim , \l__examzh_information_square_y_dim);
+ \end{tikzpicture}
+ }
+\cs_new:Npn \__examzh_information_square_multiple:n #1
+ {
+ \dim_compare:nNnT { \l__examzh_information_square_xshift_dim } = { 0pt }
+ {
+ \dim_set_eq:NN
+ \l__examzh_information_square_xshift_dim
+ \l__examzh_information_square_linewidth_dim
+ }
+ \int_compare:nNnTF { #1 } = { 1 }
+ { \__examzh_information_square_single: }
+ {
+ \__examzh_information_square_single:
+ \prg_replicate:nn { #1 - 1 }
+ {
+ \hspace*{ -\l__examzh_information_square_xshift_dim }
+ \__examzh_information_square_single:
+ }
+ }
+ }
+
+\NewDocumentCommand { \examsquare } { O{ } m }
+ {
+ \group_begin:
+ \keys_set:nn { exam-zh / square } { #1 }
+ \__examzh_information_square_multiple:n { #2 }
+ \group_end:
+ }
+
+
+% 页眉和页脚
+
+
+\keys_define:nn { exam-zh / page }
+ {
+ show-foot .bool_set:N = \l__examzh_show_foot_bool,
+ foot-content .tl_set:N = \l__examzh_foot_content_format_tl
+ % foo, bar: foo <page> bar
+ % foo, bar, baz: foo <page> bar <lastpage> baz
+ }
+\keys_set:nn { exam-zh / page }
+ {
+ show-foot = true,
+ foot-content = {数学试题第;页(共~;页)}
+ }
+
+\int_new:N \l__examzh_foot_content_count_semicolon_int
+\tl_new:N \l__examzh_foot_content_before_page_tl
+\tl_new:N \l__examzh_foot_content_after_page_tl
+\tl_new:N \l__examzh_foot_content_after_lastpage_tl
+\cs_generate_variant:Nn \regex_count:nnN { nxN }
+
+\cs_new:Npn \__examzh_foot_content_only_page_input:ww #1 ; #2 \q_stop
+ {
+ \tl_set:Nn \l__examzh_foot_content_before_page_tl {#1}
+ \tl_set:Nn \l__examzh_foot_content_after_page_tl {#2}
+ }
+\cs_new:Npn \__examzh_foot_content_only_page_input:n #1
+ {
+ \__examzh_foot_content_only_page_input:ww #1 \q_stop
+ }
+\cs_generate_variant:Nn \__examzh_foot_content_only_page_input:n { V }
+
+\cs_new:Npn \__examzh_foot_content_page_and_lastpage_input:www #1 ; #2 ; #3 \q_stop
+ {
+ \tl_set:Nn \l__examzh_foot_content_before_page_tl {#1}
+ \tl_set:Nn \l__examzh_foot_content_after_page_tl {#2}
+ \tl_set:Nn \l__examzh_foot_content_after_lastpage_tl {#3}
+ }
+\cs_new:Npn \__examzh_foot_content_page_and_lastpage_input:n #1
+ {
+ \__examzh_foot_content_page_and_lastpage_input:www #1 \q_stop
+ }
+\cs_generate_variant:Nn \__examzh_foot_content_page_and_lastpage_input:n { V }
+
+\cs_new:Npn \__examzh_foot_content_no_page_or_lastpage_output:
+ {
+ \l__examzh_foot_content_format_tl
+ }
+\cs_new:Npn \__examzh_foot_content_only_page_output:
+ {
+ \l__examzh_foot_content_before_page_tl \thepage { }
+ \l__examzh_foot_content_after_page_tl
+ }
+\cs_new:cpn { __examzh_foot_content_only_page_a3paper_left_output: }
+ {
+ \l__examzh_foot_content_before_page_tl \int_eval:n { 2 * \c@page - 1 } { }
+ \l__examzh_foot_content_after_page_tl
+ }
+\cs_new:cpn { __examzh_foot_content_only_page_a3paper_right_output: }
+ {
+ \l__examzh_foot_content_before_page_tl \int_eval:n { 2 * \c@page } { }
+ \l__examzh_foot_content_after_page_tl
+ }
+\cs_new:Npn \__examzh_foot_content_page_and_lastpage_output:
+ {
+ \l__examzh_foot_content_before_page_tl \thepage { }
+ \l__examzh_foot_content_after_page_tl \unskip \c_space_tl \pageref { LastPage }~
+ \l__examzh_foot_content_after_lastpage_tl
+ }
+\cs_new:cpn { __examzh_foot_content_page_and_lastpage_a3paper_left_output: }
+ {
+ \__examzh_foot_lastpage_tmp_set:
+ \l__examzh_foot_content_before_page_tl \int_eval:n { 2 * \c@page - 1 } { }
+ \l__examzh_foot_content_after_page_tl ~\int_eval:n { 2 * \l__examzh_tmp_int }~
+ \l__examzh_foot_content_after_lastpage_tl
+ }
+\cs_new:cpn { __examzh_foot_content_page_and_lastpage_a3paper_right_output: }
+ {
+ \__examzh_foot_lastpage_tmp_set:
+ \l__examzh_foot_content_before_page_tl \int_eval:n { 2 * \c@page } { }
+ \l__examzh_foot_content_after_page_tl ~\int_eval:n { 2 * \l__examzh_tmp_int }~
+ \l__examzh_foot_content_after_lastpage_tl
+ }
+\cs_new_nopar:Npn \__examzh_relax: { \relax }
+\cs_new:Npn \__examzh_foot_lastpage_tmp_set:
+ {
+ \cs_if_eq:NNTF \lastpage@lastpage \__examzh_relax:
+ { \int_set:Nn \l__examzh_tmp_int { 0 } }
+ { \int_set:Nn \l__examzh_tmp_int { \lastpage@lastpage } }
+ }
+\msg_new:nnn { exam-zh } { foot-semicolon-number-error }
+ {
+ The~number~of~semicolon~of~foot-line~must~be~1,~2~or~3!
+ }
+\cs_new:cpn { __examzh_foot_content_a4paper_output: }
+ {
+ % 检测输入有多少个 ;
+ \regex_count:nxN { ; }
+ { \l__examzh_foot_content_format_tl }
+ \l__examzh_foot_content_count_semicolon_int
+ \int_case:nnF { \l__examzh_foot_content_count_semicolon_int }
+ {
+ {0} { \__examzh_foot_content_no_page_or_lastpage_output: }
+ {1}
+ {
+ % 将输入“分解”
+ \__examzh_foot_content_only_page_input:V \l__examzh_foot_content_format_tl
+ % 然后输出
+ \__examzh_foot_content_only_page_output:
+ }
+ {2}
+ {
+ % 将输入“分解”
+ \__examzh_foot_content_page_and_lastpage_input:V \l__examzh_foot_content_format_tl
+ % 然后输出
+ \__examzh_foot_content_page_and_lastpage_output:
+ }
+ }
+ {
+ \msg_error:nn { exam-zh } { foot-semicolon-number-error }
+ }
+ }
+\cs_set_eq:cc
+ { __examzh_foot_content_a3paper_common_output: }
+ { __examzh_foot_content_a4paper_output: }
+\cs_new:cpn { __examzh_foot_content_a3paper_separate_left_output: }
+ {
+ % 检测输入有多少个 ;
+ \regex_count:nxN { ; }
+ { \l__examzh_foot_content_format_tl }
+ \l__examzh_foot_content_count_semicolon_int
+ \int_case:nnF { \l__examzh_foot_content_count_semicolon_int }
+ {
+ {0} { \__examzh_foot_content_no_page_or_lastpage_output: }
+ {1}
+ {
+ % 将输入“分解”
+ \__examzh_foot_content_only_page_input:V \l__examzh_foot_content_format_tl
+ % 然后输出
+ \use:c { __examzh_foot_content_only_page_a3paper_left_output: }
+ }
+ {2}
+ {
+ % 将输入“分解”
+ \__examzh_foot_content_page_and_lastpage_input:V \l__examzh_foot_content_format_tl
+ % 然后输出
+ \use:c { __examzh_foot_content_page_and_lastpage_a3paper_left_output: }
+ }
+ }
+ {
+ \msg_error:nn { exam-zh } { foot-semicolon-number-error }
+ }
+ }
+\cs_new:cpn { __examzh_foot_content_a3paper_separate_right_output: }
+ {
+ % 检测输入有多少个 ;
+ \regex_count:nxN { ; }
+ { \l__examzh_foot_content_format_tl }
+ \l__examzh_foot_content_count_semicolon_int
+ \int_case:nnF { \l__examzh_foot_content_count_semicolon_int }
+ {
+ {0} { \__examzh_foot_content_no_page_or_lastpage_output: }
+ {1}
+ {
+ % 将输入“分解”
+ \__examzh_foot_content_only_page_input:V \l__examzh_foot_content_format_tl
+ % 然后输出
+ \use:c { __examzh_foot_content_only_page_a3paper_right_output: }
+ }
+ {2}
+ {
+ % 将输入“分解”
+ \__examzh_foot_content_page_and_lastpage_input:V \l__examzh_foot_content_format_tl
+ % 然后输出
+ \use:c { __examzh_foot_content_page_and_lastpage_a3paper_right_output: }
+ }
+ }
+ {
+ \msg_error:nn { exam-zh } { foot-semicolon-number-error }
+ }
+ }
+
+\tl_set:Nn \headrulewidth { 0pt }
+% \cs_set_eq:NN \@mkboth \use_none:n
+\cs_set_eq:NN \sectionmark \use_none:n
+\cs_set_eq:NN \subsectionmark \use_none:n
+
+\cs_new:Npn \__examzh_column_box:n #1
+ {
+ \makebox [ \columnwidth ] {#1}
+ }
+
+
+\fancypagestyle { plain }
+ {
+ \fancyhf { }
+ \bool_if:cTF { g__examzh_page_size_a4paper_bool }
+ {
+ % a4paper
+ \bool_if:NT \l__examzh_show_foot_bool
+ {
+ \fancyfoot [ C ]
+ {
+ \small
+ \use:c { __examzh_foot_content_a4paper_output: }
+ % \l__exam_zh_subject_tl 试题第 \thepage { } 页(共 \pageref { LastPage } ~ 页)
+ }
+ }
+ }
+ {
+ % a3paper
+ \bool_if:NT \l__examzh_show_foot_bool
+ {
+ \bool_if:cTF
+ { g__examzh_page_a3paper_foot_common_bool }
+ {
+ % 两页共用一个页脚
+ \fancyfoot [ C ]
+ {
+ \small
+ % \l__exam_zh_subject_tl 试题第 \thepage { } 页(共 \pageref { LastPage } ~ 页)
+ \use:c { __examzh_foot_content_a3paper_common_output: }
+ }
+ }
+ {
+ % 每页一个页脚
+ \fancyfoot [ L ]
+ {
+ \__examzh_column_box:n
+ {
+ \small
+ \use:c { __examzh_foot_content_a3paper_separate_left_output: }
+ % \l__exam_zh_subject_tl 试题第
+ % % \thepage
+ % \int_eval:n { 2 * \c@page - 1 }
+ % { } 页
+ % (共
+ % % \pageref { LastPage }
+ % \int_eval:n { 2 * \l__examzh_tmp_int }
+ % ~ 页)
+ % \use:c { l__examzh_foot_content_a3paper_left_tl }
+ }
+ }
+ \fancyfoot [ R ]
+ {
+ \__examzh_column_box:n
+ {
+ \small
+ \use:c { __examzh_foot_content_a3paper_separate_right_output: }
+ % % \int_gincr:N \c@page
+ % \int_set:Nn \l__examzh_tmp_int { \lastpage@lastpage }
+
+ % \l__exam_zh_subject_tl 试题第
+ % \int_eval:n { 2 * \c@page }
+ % { }
+ % 页
+ % (共
+ % % \pageref { LastPage }
+ % \int_eval:n { 2 * \l__examzh_tmp_int }
+ % ~ 页)
+ % % \use:c { l__examzh_foot_content_a3paper_right_tl }
+ }
+ }
+ }
+ }
+ }
+ }
+\AtBeginDocument { \pagestyle { plain } }
+
+
+
+% 草稿纸
+
+% “草稿纸”三个字的尺寸
+\dim_new:N \l__examzh_draft_watermark_size_dim
+% 控制是否自动添加草稿纸
+\bool_new:N \l__examzh_draft_show_auto_bool
+
+\keys_define:nn { exam-zh / draft }
+ {
+ watermark-size .code:n =
+ {
+ % 之所以这样设置而不是 .dim_set:N 是因为 a4 和 a3 的切换不是文档选项
+ % 而是通过 \examsetup 更改的。所以要设置默认值必须用 \AtEndPreamble
+ % 来检测 g__examzh_page_size_a4paper_bool 的值才行,但这样的话就会
+ % 把 watermark-size 的值覆盖,所以得实现“watermark-size” 的设置要盖掉 \AtEndPreamble
+ % 设置的默认值,才可以达到用户输入产生效果
+ \AtEndPreamble
+ {
+ \dim_set:Nn \l__examzh_draft_watermark_size_dim {#1}
+ }
+ },
+ show-watermark .bool_set:N = \l__examzh_draft_show_watermark_bool,
+ show-draft .choice:,
+ show-draft / auto .code:n =
+ { \bool_set_true:N \l__examzh_draft_show_auto_bool },
+ show-draft / manual .code:n =
+ { \bool_set_false:N \l__examzh_draft_show_auto_bool },
+ }
+\keys_set:nn { exam-zh / draft }
+ {
+ show-watermark = true,
+ show-draft = manual,
+ }
+% “草稿纸”尺寸默认值
+\AtEndPreamble
+ {
+ \bool_if:cTF { g__examzh_page_size_a4paper_bool }
+ {
+ \keys_set:nn { exam-zh / draft }
+ { watermark-size = 100pt }
+ }
+ {
+ \keys_set:nn { exam-zh / draft }
+ { watermark-size = 180pt }
+ }
+ }
+\AtEndDocument
+ {
+ \bool_if:NT \l__examzh_draft_show_auto_bool
+ { \draftpaper \draftpaper }
+ }
+\NewDocumentCommand { \draftpaper } { O{} }
+ {
+ \group_begin:
+ \keys_set:nn { exam-zh / draft } {#1}
+ \bool_if:NTF \l__examzh_draft_show_watermark_bool
+ { \__examzh_draft_with_watermark: }
+ { \__examzh_draft_without_watermark: }
+ \group_end:
+ }
+\cs_new:Npn \__examzh_draft_with_watermark:
+ {
+ \clearpage
+ \null
+ \thispagestyle { empty }
+ \begin{tikzpicture}
+ [
+ remember~picture,
+ overlay,
+ font = \sffamily\fontsize{ \l__examzh_draft_watermark_size_dim }{180pt}\selectfont
+ ]
+ \node[text = lightgray!40] at (current~page.center) {草\quad 稿\quad 纸};
+ \end{tikzpicture}
+ \clearpage
+ }
+\cs_new:Npn \__examzh_draft_without_watermark:
+ {
+ \clearpage
+ \null
+ \thispagestyle { empty }
+ \clearpage
+ }
+
+
+
+% 评分框 scoring box
+
+\bool_new:N \g__examzh_combine_section_with_scoringbox_position_left_bool
+
+\NewCommandCopy { \examzholdsection } { \section }
+\cs_new:Npn \__examzh_combine_section_with_twocolumn_scoringbox:
+ {
+ \bool_if:NTF \g__examzh_combine_section_with_scoringbox_position_left_bool
+ {
+ \RenewDocumentCommand { \section } { m }
+ {
+ \par\addvspace{1.5em}\noindent
+ \begin{tabular}{lc}
+ \begin{minipage}{0.2\columnwidth}
+ \begin{tabular}{|c|c|}
+ \hline
+ 得分 & \rule{3em}{0pt}\rule[-0.7em]{0pt}{2em} \\\hline
+ 阅卷人 & \rule{3em}{0pt}\rule[-0.7em]{0pt}{2em} \\\hline
+ \end{tabular}
+ \end{minipage} &
+ \begin{minipage}{0.745\columnwidth}
+ \examzholdsection {##1}
+ \end{minipage}
+ \end{tabular}
+ \par
+ \addvspace{1em}
+ }
+ }
+ {
+ \RenewDocumentCommand { \section } { m }
+ {
+ \par\addvspace{1.5em}\noindent
+ \begin{tabular}{lc}
+ \begin{minipage}{0.745\columnwidth}
+ \examzholdsection {##1}
+ \end{minipage} &
+ \begin{minipage}{0.2\columnwidth}
+ \begin{tabular}{|c|c|}
+ \hline
+ 得分 & \rule{3em}{0pt}\rule[-0.7em]{0pt}{2em} \\\hline
+ 阅卷人 & \rule{3em}{0pt}\rule[-0.7em]{0pt}{2em} \\\hline
+ \end{tabular}
+ \end{minipage}
+ \end{tabular}
+ \par
+ \addvspace{1em}
+ }
+ }
+ }
+\cs_new:Npn \__examzh_combine_section_with_onecolumn_scoringbox:
+ {
+ \bool_if:NTF \g__examzh_combine_section_with_scoringbox_position_left_bool
+ {
+ \RenewDocumentCommand { \section } { m }
+ {
+ \par\addvspace{1.5em}\noindent
+ \begin{tabular}{cc}
+ \begin{varwidth}{3.5em}
+ \begin{tabular}{|c|}
+ \hline
+ 得分\rule[-0.7em]{0pt}{2em} \\\hline
+ \rule[-0.7em]{0pt}{2em} \\\hline
+ \end{tabular}
+ \end{varwidth} &
+ \begin{varwidth}{0.865\columnwidth}
+ \examzholdsection {##1}
+ \end{varwidth}
+ \end{tabular}
+ \par
+ \addvspace{1em}
+ }
+ }
+ {
+ \RenewDocumentCommand { \section } { m }
+ {
+ \par\addvspace{1.5em}\noindent
+ \begin{tabular}{cc}
+ \begin{varwidth}{0.865\columnwidth}
+ \examzholdsection {##1}
+ \end{varwidth} &
+ \begin{varwidth}{3.5em}
+ \begin{tabular}{|c|}
+ \hline
+ 得分\rule[-0.7em]{0pt}{2em} \\\hline
+ \rule[-0.7em]{0pt}{2em} \\\hline
+ \end{tabular}
+ \end{varwidth}
+ \end{tabular}
+ \par
+ \addvspace{1em}
+ }
+ }
+ }
+\cs_new:Npn \__examzh_restore_section:
+ {
+ \RenewCommandCopy { \section } { \examzholdsection }
+ }
+
+\keys_define:nn { exam-zh / scoringbox }
+ {
+ type .choice:,
+ type / onecolumn .code:n =
+ {
+ \AtEndPreamble { \__examzh_combine_section_with_onecolumn_scoringbox: }
+ },
+ type / twocolumn .code:n =
+ {
+ \AtEndPreamble { \__examzh_combine_section_with_twocolumn_scoringbox: }
+ },
+ type / none .code:n = { \__examzh_restore_section: },
+ position .choice:,
+ position / left .code:n =
+ {
+ \bool_gset_true:N \g__examzh_combine_section_with_scoringbox_position_left_bool
+ },
+ position / right .code:n =
+ {
+ \bool_gset_false:N \g__examzh_combine_section_with_scoringbox_position_left_bool
+ },
+ }
+\keys_set:nn { exam-zh / scoringbox }
+ {
+ type = none,
+ position = left
+ }
+\keys_define:nn { exam-zh }
+ { scoringbox .meta:nn = { exam-zh / scoringbox } {#1} }
+
+
+\NewDocumentCommand { \scoringbox } { s }
+ {
+ \IfBooleanTF {#1}
+ { \__examzh_scoringbox_onecolumn: }
+ { \__examzh_scoringbox_twocolumn: }
+ }
+\cs_new_protected:Nn \__examzh_scoringbox_twocolumn:
+ {
+ \begin{tabular}{|c|c|}
+ \hline
+ 得分 & \rule{3em}{0pt}\rule[-0.7em]{0pt}{2em} \\\hline
+ 阅卷人 & \rule{3em}{0pt}\rule[-0.7em]{0pt}{2em} \\\hline
+ \end{tabular}
+ }
+\cs_new_protected:Nn \__examzh_scoringbox_onecolumn:
+ {
+ \begin{tabular}{|c|}
+ \hline
+ 得分\rule[-0.7em]{0pt}{2em} \\\hline
+ \rule[-0.7em]{0pt}{2em} \\\hline
+ \end{tabular}
+ }
+
+
+
+% 脚注
+% 摘自 fduthesis.cls
+
+\cs_new_protected:Npn \__examzh_define_fn_style:nn #1#2
+ { \tl_const:cn { c__examzh_fn_style_ #1 _tl } {#2} }
+\cs_new:Npn \__examzh_symbol:n #1 { \tex_char:D #1 \scan_stop: }
+
+\clist_map_inline:nn
+ {
+ { plain } { plain },
+ { libertinus } { libertinus },
+ { libertinus_neg } { libertinus* },
+ { libertinus_sans } { libertinus-sans },
+ { pifont } { pifont },
+ { pifont_neg } { pifont* },
+ { pifont_sans } { pifont-sans },
+ { pifont_sans_neg } { pifont-sans* },
+ { xits } { xits },
+ { xits_sans } { xits-sans },
+ { xits_sans_neg } { xits-sans* }
+ }
+ { \__examzh_define_fn_style:nn #1 }
+\tl_new:N \l__examzh_fn_style_tl
+\keys_define:nn { exam-zh / style }
+ {
+ footnote-style .choices:nn =
+ {
+ plain,
+ libertinus, libertinus*, libertinus-sans,
+ pifont, pifont*, pifont-sans, pifont-sans*,
+ xits, xits-sans, xits-sans*
+ }
+ {
+ \tl_gset_eq:NN \l__examzh_fn_style_tl \l_keys_choice_tl
+ \int_compare:nT { 5 <= \l_keys_choice_int <= 8 }
+ { \RequirePackage { pifont } }
+ },
+ footnote-style .value_required:n = true
+ }
+\keys_set:nn { exam-zh / style }
+ {
+ footnote-style = libertinus
+ }
+\cs_new:Npn \__examzh_fn_symbol_libertinus:n #1
+ {
+ \int_compare:nTF { #1 >= 21 }
+ {
+ \int_compare:nTF { #1 >= 47 }
+ { \__examzh_symbol:n { \int_eval:n { "24B6 - 47 + #1 } } }
+ { \__examzh_symbol:n { \int_eval:n { "24D0 - 21 + #1 } } }
+ }
+ { \__examzh_symbol:n { \int_eval:n { "2460 - 1 + #1 } } }
+ }
+\cs_new:Npn \__examzh_fn_symbol_libertinus_neg:n #1
+ {
+ \int_compare:nTF { #1 >= 11 }
+ { \__examzh_symbol:n { \int_eval:n { "24EB - 11 + #1 } } }
+ { \__examzh_symbol:n { \int_eval:n { "2776 - 1 + #1 } } }
+ }
+\cs_new_eq:NN \__examzh_fn_symbol_libertinus_sans:n \__examzh_fn_symbol_libertinus:n
+\cs_new:Npn \__examzh_fn_symbol_pifont:n #1
+ { \ding { \int_eval:n { 171 + #1 } } }
+\cs_new:Npn \__examzh_fn_symbol_pifont_neg:n #1
+ { \ding { \int_eval:n { 181 + #1 } } }
+\cs_new:Npn \__examzh_fn_symbol_pifont_sans:n #1
+ { \ding { \int_eval:n { 191 + #1 } } }
+\cs_new:Npn \__examzh_fn_symbol_pifont_sans_neg:n #1
+ { \ding { \int_eval:n { 201 + #1 } } }
+\cs_new:Npn \__examzh_fn_symbol_xits:n #1
+ {
+ \int_compare:nTF { #1 >= 10 }
+ {
+ \int_compare:nTF { #1 >= 36 }
+ { \__examzh_symbol:n { \int_eval:n { "24B6 - 36 + #1 } } }
+ { \__examzh_symbol:n { \int_eval:n { "24D0 - 10 + #1 } } }
+ }
+ { \__examzh_symbol:n { \int_eval:n { "2460 - 1 + #1 } } }
+ }
+\cs_new:Npn \__examzh_fn_symbol_xits_sans:n #1
+ { \__examzh_symbol:n { \int_eval:n { "2780 - 1 + #1 } } }
+\cs_new:Npn \__examzh_fn_symbol_xits_sans_neg:n #1
+ { \__examzh_symbol:n { \int_eval:n { "278A - 1 + #1 } } }
+\cs_set:Npn \thefootnote { \examzh_footnote_number:N \c@footnote }
+\cs_new:Npn \examzh_footnote_number:N #1
+ {
+ \tl_case:NnF \l__examzh_fn_style_tl
+ {
+ \c__examzh_fn_style_plain_tl
+ { \int_use:N #1 }
+ \c__examzh_fn_style_libertinus_tl
+ {
+ \fontspec { LibertinusSerif-Regular .otf }
+ \__examzh_fn_symbol_libertinus:n {#1}
+ }
+ \c__examzh_fn_style_libertinus_neg_tl
+ {
+ \fontspec { LibertinusSerif-Regular .otf }
+ \__examzh_fn_symbol_libertinus_neg:n {#1}
+ }
+ \c__examzh_fn_style_libertinus_sans_tl
+ {
+ \fontspec { LibertinusSans-Regular .otf }
+ \__examzh_fn_symbol_libertinus_sans:n {#1}
+ }
+ \c__examzh_fn_style_pifont_tl
+ { \__examzh_fn_symbol_pifont:n {#1} }
+ \c__examzh_fn_style_pifont_neg_tl
+ { \__examzh_fn_symbol_pifont_neg:n {#1} }
+ \c__examzh_fn_style_pifont_sans_tl
+ { \__examzh_fn_symbol_pifont_sans:n {#1} }
+ \c__examzh_fn_style_pifont_sans_neg_tl
+ { \__examzh_fn_symbol_pifont_sans_neg:n {#1} }
+ \c__examzh_fn_style_xits_tl
+ {
+ \fontspec { XITS-Regular .otf }
+ \__examzh_fn_symbol_xits:n {#1}
+ }
+ \c__examzh_fn_style_xits_sans_tl
+ {
+ \fontspec { XITS-Regular .otf }
+ \__examzh_fn_symbol_xits_sans:n {#1}
+ }
+ \c__examzh_fn_style_xits_sans_neg_tl
+ {
+ \fontspec { XITS-Regular .otf }
+ \__examzh_fn_symbol_xits_sans_neg:n {#1}
+ }
+ }
+ { \int_use:N #1 }
+ }
+\cs_set:Npn \@makefntext #1
+ {
+ \mode_leave_vertical:
+ \hbox_to_wd:nn { 1.5 em } { \@thefnmark \hfil }
+ #1
+ } \ No newline at end of file