diff options
Diffstat (limited to 'Master/texmf-dist/tex/latex/exam-zh/exam-zh-chinese-english.sty')
-rw-r--r-- | Master/texmf-dist/tex/latex/exam-zh/exam-zh-chinese-english.sty | 665 |
1 files changed, 665 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 |