% % Copyright (c) 2024 Kangwei Xia % Released under the LaTeX Project Public License v1.3c License. % Repository: https://gitee.com/xkwxdyy/exam-zh % \NeedsTeXFormat{LaTeX2e} \RequirePackage{expl3} \ProvidesExplPackage {exam-zh-math} {2024-02-15} {v0.2.1} {exam-zh math module} \RequirePackage { tabularray } \RequirePackage { varwidth } \RequirePackage { graphicx } \RequirePackage { filehook } \file_if_exist:nT { wrapstuff.sty } { \RequirePackage { wrapstuff } \AtEndOfPackageFile* { exam-zh-choices } { \AddToHook { env / choices / before } { \wrapstuffclear } } } \keys_define:nn { exam-zh } { calculations .meta:nn = { exam-zh / calculations } {#1} } %% calculations ������ %% % ��������������� label ��������� \str_new:N \l__examzh_calculations_figure_position_str % coffin type ��������������� \str_new:N \l__examzh_calculations_coffin_align_str \keys_define:nn { exam-zh / calculations } { % calculations ��������� label ������������������������������ index + seq ��������� ##1 ��������������� index��� index .int_set:N = \l__examzh_calculations_label_index_shift_int, % ������������������������������������������ columns .int_set:N = \l__examzh_calculations_column_int, % ������������������������������������������������ fig-pos .choices:nn = { top, above, bottom, below, left, right, left-top } { \str_set:Nx \l__examzh_calculations_figure_position_str { \l_keys_choice_tl } }, % ��������������������������� top-sep .skip_set:N = \l__examzh_calculations_top_sep_skip, % ��������������������������� bottom-sep .skip_set:N = \l__examzh_calculations_bottom_sep_skip, % ��������������������������� hsep .skip_set:N = \l__examzh_calculations_hsep_skip, % ��������������������������� vsep .skip_set:N = \l__examzh_calculations_vsep_skip, % ������������������ xshift .dim_set:N = \l__examzh_calculations_xshift_dim, hshift .dim_set:N = \l__examzh_calculations_xshift_dim, yshift .dim_set:N = \l__examzh_calculations_yshift_dim, vshift .dim_set:N = \l__examzh_calculations_yshift_dim, % label ������������ label-xshift .dim_set:N = \l__examzh_calculations_label_xshift_dim, label-hshift .dim_set:N = \l__examzh_calculations_label_xshift_dim, label-yshift .dim_set:N = \l__examzh_calculations_label_yshift_dim, label-vshift .dim_set:N = \l__examzh_calculations_label_yshift_dim, % ������������ align .choices:nn = { t, m, b } { \str_set:Nx \l__examzh_calculations_coffin_align_str { \l_keys_choice_tl } } } \keys_set:nn { exam-zh / calculations } { index = 0, columns = 2, fig-pos = left-top, xshift = 2em, hsep = 2em, vsep = 0pt, label-xshift = 0pt, align = t, top-sep = 1ex plus .5ex minus .5ex, bottom-sep = 0pt, } % item ��� index ��������������������� item��� \int_new:N \l__examzh_calculations_item_index_int % ��������������� coffin ������ seq ��� \seq_new:N \l__examzh_calculations_store_seq % ��������� seq ��� item ��� \int_new:N \l__examzh_calculations_store_seq_item_int % ������������ tblr ������������ \tl_new:N \l__examzh_calculations_tblr_content_tl % #1: ������ calculations % #2: ��������������� tblr \NewDocumentEnvironment { calculations } { O{ } +O{ } } { \group_begin: \RenewDocumentCommand \item { O{ } } { \__examzh_calculations_item:n {##1} } \int_set:Nn \l__examzh_calculations_item_index_int {0} \seq_clear:N \l__examzh_calculations_store_seq \tl_clear:N \l__examzh_calculations_tblr_content_tl \keys_set:nn { exam-zh / calculations } {#1} } { % ������������ \unskip \end{varwidth} % \end{minipage} \hcoffin_set_end: % ������ label ��� figure \__examzh_calculations_coffin_join: % ������ \__examzh_calculations_coffin_typeset:n {#2} % \par \int_use:N \l__examzh_calculations_item_index_int \group_end: } % ������ label ��� figure \cs_new:Npn \__examzh_calculations_coffin_join: { \int_step_inline:nn { \l__examzh_calculations_item_index_int } { \__examzh_calculations_coffin_join_position_set:n {##1} \seq_gput_right:Nn \l__examzh_calculations_store_seq { \__examzh_calculations_coffin_align_set:n {##1} \kern\l__examzh_calculations_hsep_skip } } } \cs_new:Npn \__examzh_calculations_coffin_align_set:n #1 { \str_case:Vn \l__examzh_calculations_coffin_align_str { {t} { \__examzh_calculations_coffin_align_set_t:n {#1} } {m} { \__examzh_calculations_coffin_align_set_m:n {#1} } {b} { \__examzh_calculations_coffin_align_set_b:n {#1} } } } \cs_new:Npn \__examzh_calculations_coffin_align_set_t:n #1 { \coffin_typeset:cnnnn { l__examzh_calculations_figure_ \int_to_roman:n { #1 } _coffin } { l } { t } % align = t { \l__examzh_calculations_xshift_dim } { \l__examzh_calculations_yshift_dim + 1em } } \cs_new:Npn \__examzh_calculations_coffin_align_set_m:n #1 { \coffin_typeset:cnnnn { l__examzh_calculations_figure_ \int_to_roman:n { #1 } _coffin } { l } { vc } % align = m { \l__examzh_calculations_xshift_dim } { \l__examzh_calculations_yshift_dim } } \cs_new:Npn \__examzh_calculations_coffin_align_set_b:n #1 { \coffin_typeset:cnnnn { l__examzh_calculations_figure_ \int_to_roman:n { #1 } _coffin } { l } { b } % align = b { \l__examzh_calculations_xshift_dim } { \l__examzh_calculations_yshift_dim } } \cs_new:Npn \__examzh_calculations_coffin_join_position_set:n #1 { \use:c { __examzh_calculations_coffin_join_position_set_ \l__examzh_calculations_figure_position_str :n } {#1} } \cs_new:cpn { __examzh_calculations_coffin_join_position_set_left-top :n } #1 { \coffin_join:cnncnnnn { l__examzh_calculations_figure_ \int_to_roman:n {#1} _ coffin } { l } { t } { l__examzh_calculations_label_ \int_to_roman:n {#1} _ coffin } { r } { b } { \l__examzh_calculations_label_xshift_dim } { \l__examzh_calculations_label_yshift_dim -10.6pt} } \cs_new:Npn \__examzh_calculations_coffin_join_position_set_top:n #1 { \coffin_join:cnncnnnn { l__examzh_calculations_figure_ \int_to_roman:n {#1} _ coffin } { hc } { b } { l__examzh_calculations_label_ \int_to_roman:n {#1} _ coffin } { hc } { t } { \l__examzh_calculations_label_xshift_dim } { \l__examzh_calculations_label_yshift_dim - 6pt } } \cs_set_eq:NN \__examzh_calculations_coffin_join_position_set_above:n \__examzh_calculations_coffin_join_position_set_top:n \cs_new:Npn \__examzh_calculations_coffin_join_position_set_bottom:n #1 { \coffin_join:cnncnnnn { l__examzh_calculations_figure_ \int_to_roman:n {#1} _ coffin } { hc } { t } { l__examzh_calculations_label_ \int_to_roman:n {#1} _ coffin } { hc } { b } { \l__examzh_calculations_label_xshift_dim } { \l__examzh_calculations_label_yshift_dim + 6pt } } \cs_set_eq:NN \__examzh_calculations_coffin_join_position_set_below:n \__examzh_calculations_coffin_join_position_set_bottom:n \cs_new:Npn \__examzh_calculations_coffin_join_position_set_left:n #1 { \coffin_join:cnncnnnn { l__examzh_calculations_figure_ \int_to_roman:n {#1} _ coffin } { l } { vc } { l__examzh_calculations_label_ \int_to_roman:n {#1} _ coffin } { r } { vc } { \l__examzh_calculations_label_xshift_dim - 6pt } { \l__examzh_calculations_label_yshift_dim } } \cs_new:Npn \__examzh_calculations_coffin_join_position_set_right:n #1 { \coffin_join:cnncnnnn { l__examzh_calculations_figure_ \int_to_roman:n {#1} _ coffin } { r } { vc } { l__examzh_calculations_label_ \int_to_roman:n {#1} _ coffin } { l } { vc } { \l__examzh_calculations_label_xshift_dim + 2pt } { \l__examzh_calculations_label_yshift_dim } } \cs_new:Npn \__examzh_calculations_coffin_typeset:n #1 { \__examzh_calculations_coffin_typeset_count: \seq_map_indexed_inline:Nn \l__examzh_calculations_store_seq % ##1: index % ##2: content { \int_compare:nNnTF { \int_mod:nn {##1} { \l__examzh_calculations_column_int } } = {0} { \tl_gput_right:Nn \l__examzh_calculations_tblr_content_tl { ##2 \\[\l__examzh_calculations_vsep_skip] } } { \tl_gput_right:Nn \l__examzh_calculations_tblr_content_tl { ##2 & } } } % ������ seq ��� item ��� column ��������������� column ��������������� & \int_compare:nNnT { \l__examzh_calculations_store_seq_item_int } > { \l__examzh_calculations_column_int } { \int_compare:nNnF { \l__examzh_calculations_item_num_mod_column_left_int } = { 0 } { \tl_gput_right:Nx \l__examzh_calculations_tblr_content_tl { \prg_replicate:nn { \l__examzh_calculations_item_num_mod_column_left_int -1 } {&} } % \int_use:N \l__examzh_calculations_item_num_mod_column_left_int } } \par \vspace*{ \l__examzh_calculations_top_sep_skip } \noindent % \centering % \SetTblrInner % { % rowsep = 4pt, % % colsep = 0pt % } \begin{tblr} [ expand = \l__examzh_calculations_tblr_content_tl ] { width = \linewidth, columns = { l, leftsep = 0em, rightsep = 0pt, }, rows = { m, ht=\baselineskip, abovesep = 0pt, belowsep = 0pt, }, stretch=0, #1 } \l__examzh_calculations_tblr_content_tl \end{tblr} \vspace*{ \l__examzh_calculations_bottom_sep_skip } \par } \int_new:N \l__examzh_calculations_item_num_mod_column_left_int \cs_new:Npn \__examzh_calculations_coffin_typeset_count: { % ������ seq ������������ \int_set:Nn \l__examzh_calculations_store_seq_item_int { \seq_count:N \l__examzh_calculations_store_seq } % seq ������������ column ���������column ��������� seq ������ \int_compare:nNnTF { \l__examzh_calculations_store_seq_item_int } < { \l__examzh_calculations_column_int } { \int_set_eq:NN \l__examzh_calculations_column_int \l__examzh_calculations_store_seq_item_int } { % ������ \l__examzh_calculations_store_seq_item_int mod \l__examzh_calculations_column_int ��������������������� & \int_set:Nn \l__examzh_calculations_item_num_mod_column_left_int { \int_mod:nn { \l__examzh_calculations_store_seq_item_int } { \l__examzh_calculations_column_int } } } } \cs_new:Npn \__examzh_calculations_item:n #1 { % ���������������g ������������ \int_gincr:N \l__examzh_calculations_item_index_int % ������ coffin \__examzh_calculations_item_new_coffin: % ������ label��������������������������������������������� gset��� \hcoffin_gset:cn { l__examzh_calculations_label_ \int_to_roman:n { \l__examzh_calculations_item_index_int } _coffin } { % ������ index ��������������������������������������� index % ���\int_eval:n { \l__examzh_calculations_item_index_int + \l__examzh_calculations_label_index_shift_int - 1} ��� % ������ \item ���[] ��������������������������� label ������ % \tl_if_blank:nTF {#1} % { % \box_move_up:nn { 2.7pt } { \hbox{\__examzh_calculations_the_label:} } % \space % #1 % } % { % \__examzh_calculations_the_label: #1 % } % \IfBooleanTF{#1}{#1 yes}{#1 no} % \IfNoValueTF{#1} % { % \dim_set:Nn \l__examzh_calculations_label_yshift_dim { 4pt } % }{#1 yes} } % ������ figure \int_compare:nNnF { \l__examzh_calculations_item_index_int } = {1} { \unskip \end{varwidth} % \end{minipage} % ��������������� item ��������� \hcoffin_set_end: } % ������ \hcoffin_set:cw { l__examzh_calculations_figure_ \int_to_roman:n { \l__examzh_calculations_item_index_int } _coffin } % \begin{varwidth}{\hsize} % ������ columns ������������������ \__examzh_calculations_item_varwidth_width_set: \begin{varwidth}{\l__examzh_calculations_item_varwidth_width_dim} % \begin{minipage}{8cm} \ignorespaces \makebox[0em]{\rule{0pt}{\baselineskip}} \__examzh_calculations_the_label: } \dim_new:N \l__examzh_calculations_item_varwidth_width_dim \cs_new:Npn \__examzh_calculations_item_varwidth_width_set: { \int_case:nnF { \l__examzh_calculations_column_int } { {1} { \dim_set:Nn \l__examzh_calculations_item_varwidth_width_dim {0.8 \textwidth} } {2} { \dim_set:Nn \l__examzh_calculations_item_varwidth_width_dim {0.3 \textwidth} } {3} { \dim_set:Nn \l__examzh_calculations_item_varwidth_width_dim {0.3 \textwidth} } {4} { \dim_set:Nn \l__examzh_calculations_item_varwidth_width_dim {0.2 \textwidth} } } { \dim_set:Nn \l__examzh_calculations_item_varwidth_width_dim { \hsize } } } % ������ coffin \cs_new:Npn \__examzh_calculations_item_new_coffin: { % ������������ coffin \coffin_if_exist:cF { l__examzh_calculations_figure_ \int_to_roman:n { \l__examzh_calculations_item_index_int } _coffin } { \coffin_new:c { l__examzh_calculations_figure_ \int_to_roman:n { \l__examzh_calculations_item_index_int } _coffin } } % ��� label ��� coffin \coffin_if_exist:cF { l__examzh_calculations_label_ \int_to_roman:n { \l__examzh_calculations_item_index_int } _coffin } { \coffin_new:c { l__examzh_calculations_label_ \int_to_roman:n { \l__examzh_calculations_item_index_int } _coffin } } } \tl_new:N \l__examzh_calculations_counters_commands_set_tl \keys_define:nn { exam-zh / calculations } { label .tl_set:N = \l__examzh_calculations_label_tl } \keys_set:nn { exam-zh / calculations } { label = \arabic* } \cs_new:Npn \__examzh_calculations_the_label: { \group_begin: % ������������������������������������ \l__examzh_calculations_counters_commands_set_tl % ������������������ label \l__examzh_calculations_label_tl \group_end: } \NewDocumentCommand \AddCalculationsCounter { m m } { % ��������������������� \tl_put_right:Nn \l__examzh_calculations_counters_commands_set_tl { \__examzh_process_counter:NNn #1 #2 { calculations } } % ������������������������ \cs_set_eq:cN { __examzh_calculations_save_ \cs_to_str:N #1 : } #2 \cs_set_eq:cN { __examzh_calculations_save_ \cs_to_str:N #2 : } #2 } \AddCalculationsCounter \arabic \@arabic \AddCalculationsCounter \alph \@alph \AddCalculationsCounter \Alph \@Alph \AddCalculationsCounter \roman \@roman \AddCalculationsCounter \Roman \@Roman \cs_new:Npn \__examzh_calculations_process_counter_aux:Nn #1#2 { \tl_if_eq:nnTF {#2} { * } { % \Alph* \use:c { __examzh_calculations_save_ \cs_to_str:N #1 : } { \int_eval:n { \l__examzh_calculations_item_index_int + \l__examzh_calculations_label_index_shift_int } } } { % \Alph{...} \use:c { __examzh_calculations_save_ \cs_to_str:N #1 : } {#2} } }