%% %% This is file `grading-scheme.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% grading-scheme.dtx (with options: `package') %% ___________________________________________________________ %% The grading-scheme package %% Copyright (C) 2022 Maximilian Kessler %% License information appended. %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \ProvidesExplPackage {grading-scheme} {2022/02/24} {0.1.1} {Typeset grading schemes in tabular format} \bool_new:N \g__grading_scheme_pipe_syntax_bool \keys_define:nn { grading-scheme } { pipe .bool_gset:N = \g__grading_scheme_pipe_syntax_bool, pipe .default:n = { true }, unknown .code:n = { \msg_error:nnn { grading-scheme } { unknown-option} { \l_keys_key_str } } } \msg_new:nnn { grading-scheme } { unknown-option} { Unknown ~ option ~ '#1'. } \RequirePackage { l3keys2e } \ProcessKeysOptions { grading-scheme } \RequirePackage{multirow} \RequirePackage{rotating} \cs_set_eq:NN \__grading_scheme_multicolumn:nnn \multicolumn \cs_set_eq:NN \__grading_scheme_multirow:nnn \multirow \cs_set_eq:NN \__grading_scheme_cline:n \cline \cs_new:Npn \__grading_scheme_cline:nn #1 #2 { \__grading_scheme_cline:n { #1 - #2 } } \cs_set_eq:NN \__grading_scheme_hline: \hline \cs_new:Npn \__grading_scheme_rotatebox:nnn #1 %implicit #2, #3 { \rotatebox [ #1 ] } \cs_new:Npn \__grading_scheme_points:n #1 { \textbf{ #1 ~ P. } } \cs_new:Npn \__grading_scheme_operation:n #1 { { \sc #1 } } \int_new:N \g__ptr_counter_int \str_new:N \l__ptr_var_prefix_str \cs_new:Npn \ptr_new:N #1 { \__ptr_get_var_prefix:NN #1 \l__ptr_var_prefix_str \ptr_new:NVn #1 \l__ptr_var_prefix_str { any } } \cs_new:Npn \ptr_new:Nn #1 #2 { \ptr_new:Nnn { #1 } { #2 } { any } } \cs_new:Npn \ptr_new:Nnn #1 #2 %i #3 { \str_case:nnT { #2 } { { l } { } { g } { } } { \tl_new:N #1 } \__ptr_init:Nnn #1 { #2 } %i { #3 } } \cs_generate_variant:Nn \ptr_new:Nnn { N V n } \cs_new:Npn \__ptr_init:Nnn #1 #2 % implicit #3 { \__ptr_get_var_prefix:NN #1 \l__ptr_var_prefix_str \str_case:VnF \l__ptr_var_prefix_str { { l } { \cs_set_eq:NN \__ptr_poly_tl_set:Nx \tl_set:Nx } { g } { \cs_set_eq:NN \__ptr_poly_tl_set:Nx \tl_gset:Nx } { c } { \cs_set_eq:NN \__ptr_poly_tl_set:Nx \tl_const:Nx } } { \str_show:N \l__ptr_var_prefix_str % TODO: show error } \__ptr_init_aux:Nnn #1 { #2 } } \cs_generate_variant:Nn \__ptr_init:Nnn { N V n } \cs_new:Npn \__ptr_init_aux:Nnn #1 #2 #3 { \__ptr_poly_tl_set:Nx #1 { \exp_not:c { #2 __ptr__unique__ \int_use:N \g__ptr_counter_int _ #3 } } \int_gincr:N \g__ptr_counter_int } \cs_generate_variant:Nn \__ptr_init:Nnn { N V n } \cs_new:Npn \__ptr_get_var_prefix:NN #1 #2 { \tl_if_head_eq_charcode:fNTF { \cs_to_str:N #1 } l { \str_set:Nn #2 { l } } { \tl_if_head_eq_charcode:fNTF { \cs_to_str:N #1 } g { \str_set:Nn #2 { g } } { \tl_if_head_eq_charcode:fNTF { \cs_to_str:N #1 } c { \str_set:Nn #2 { c } } { \msg_error:nnx { ptr } { variable-name-illegal-prefix } { \token_to_str:N #1 } } } } } \msg_new:nnnn { ptr } { variable-name-illegal-prefix } { Requested ~ new ~ pointer ~ '#1' ~ has ~ illegal ~ prefix. } { Prefix ~ should ~ be ~ one ~ of ~ 'l', ~ 'g' ~ or ~ 'c'. } \cs_new:Npn \ptr_clear:N #1 { \__ptr_get_var_prefix:NN #1 \l__ptr_var_prefix_str \__ptr_init:NVn #1 \l__ptr_var_prefix_str { any } } \cs_new:Npn \ptr_clear:Nn #1 #2 { \__ptr_init:Nnn #1 { #2 } { any } } \cs_set_eq:NN \ptr_set:NN \tl_set:Nn \cs_set_eq:NN \ptr_set_eq:NN \tl_set_eq:NN \cs_set_eq:NN \ptr_use:N \tl_use:N \cs_new:Npn \__ptr_check:N #1 { \tl_if_single:NF #1 { \msg_error:nnx { ptr } { is-not-a-pointer } { \token_to_str:N #1 } } } \msg_new:nnn { ptr } { is-not-a-pointer } { The ~ control ~ sequence ~ '#1' ~ is ~ not ~ a ~ valid ~ pointer. } \cs_new:Npn \__ptr_check:NN #1 #2 { \__ptr_check:N #2 #1 #2 } \cs_new:Npn \__ptr_check:nN #1 #2 { \__ptr_check:N #2 { #1 } #2 } \tl_new:N \l__ptr_content_tl \cs_new:Npn \exp_args:NP #1 #2 { \__ptr_check:N #2 \exp_last_unbraced:No #1 #2 } \cs_new:Npn \exp_args:NNP #1 #2 #3 { \__ptr_check:N #3 \exp_last_unbraced:NNo #1 #2 #3 } \cs_new:Npn \exp_args:NNNP #1 #2 #3 #4 { \__ptr_check:N #4 \exp_last_unbraced:NNNo #1 #2 #3 #4 } \cs_new:Npn \exp_args:NNNNP #1 #2 #3 #4 #5 { \__ptr_check:N #5 \exp_last_unbraced:NNNNo #1 #2 #3 #4 #5 } \cs_new:Npn \exp_args:NPP #1 #2 #3 { \__ptr_check:N #2 \__ptr_check:N #3 \exp_last_two_unbraced:Noo #1 #2 #3 } \cs_new:Npn \ptr_if_null:NT { \exp_args:NP \cs_if_exist:NF } \cs_new:Npn \ptr_if_null:NF { \exp_args:NP \cs_if_exist:NT } \cs_new:Npn \ptr_if_null:NTF #1 #2 #3 { \exp_args:NP \cs_if_exist:NTF #1 { #3 } { #2 } } \cs_new:Npn \tl_set_eq:NP { \exp_args:NNP \tl_set_eq:NN } \cs_new:Npn \tl_set_eq:PN { \exp_args:NP \tl_set_eq:NN } \cs_new:Npn \tl_set_eq:PP { \exp_args:NPP \tl_set_eq:NN } \cs_new:Npn \tl_use:P { \exp_args:NP \tl_use:N } \cs_new:Npn \exp_not:P { \exp_args:NP\exp_not:N } \cs_new:Npn \clist_new:P { \exp_args:NP \clist_new:N } \cs_new:Npn \clist_show:P { \exp_args:NP \clist_show:N } \cs_new:Npn \clist_put_right:Pn { \exp_args:NP \clist_put_right:Nn } \cs_new:Npn \clist_gput_right:Pn { \exp_args:NP \clist_gput_right:Nn } \cs_new:Npn \clist_map_function:PN { \exp_args:NP \clist_map_function:NN } \cs_new:Npn \prop_show:P { \exp_args:NP \prop_show:N } \cs_new:Npn \ptr_show:N #1 { \__ptr_check:N #1 \ptr_if_null:NTF #1 { \tl_show:x { \token_to_str:N #1 -> \exp_not:P #1 = NULL } } { \tl_show:x { \token_to_str:N #1 -> \exp_not:P #1 -> \exp_args:NP \exp_not:V #1 } } } \cs_set_eq:NN \grading_scheme_entry_new:N \prop_new:N \cs_set_eq:NN \grading_scheme_entry_clear:N \prop_clear:N \cs_set_eq:NN \grading_scheme_entry_set_eq:NN \prop_set_eq:NN \cs_set_eq:NN \grading_scheme_entry_gclear:N \prop_gclear:N \cs_set_eq:NN \grading_scheme_entry_gset_eq:NN \prop_gset_eq:NN \int_new:N \l__grading_scheme_entry_points_int \tl_new:N \l__grading_scheme_entry_description_tl \cs_new:Npn \grading_scheme_entry_set_description:Nn #1 % implicit description { \prop_put:Nnn #1 { description } } \cs_new:Npn \grading_scheme_entry_gset_description:Nn #1 % implicit description { \prop_gput:Nnn #1 { description } } \cs_new:Npn \grading_scheme_entry_set_points:Nn #1 #2 { \prop_put:Nnx #1 { points } { \int_eval:n { #2 } } } \cs_new:Npn \grading_scheme_entry_gset_points:Nn #1 #2 { \prop_gput:Nnn #1 { points } { \int_eval:n { #2 } } } \cs_new:Npn \grading_scheme_entry_get_description:NN #1 %implicit #2 { \prop_get:NnN #1 { description } } \cs_new:Npn \grading_scheme_entry_get_points:NN #1 %implicit #2 { \prop_get:NnN #1 { points } } \cs_new:Npn \__grading_scheme_entry_load_points:N #1 { \grading_scheme_entry_get_points:NN #1 \l__grading_scheme_entry_points_int } \cs_new:Npn \__grading_scheme_entry_load_description:N #1 { \grading_scheme_entry_get_description:NN #1 \l__grading_scheme_entry_description_tl } \cs_new:Npn \grading_scheme_entry_format:NnnN { \cs_set_eq:NN \__grading_scheme_tl_put_right:Nx \tl_put_right:Nx \__grading_scheme_entry_format:NnnN } \cs_new:Npn \grading_scheme_entry_gformat:NnnN { \cs_set_eq:NN \__grading_scheme_tl_put_right:Nx \tl_gput_right:Nx \__grading_scheme_entry_format:NnnN } \cs_new:Npn \grading_scheme_entry_format:PnnN { \exp_args:NP \grading_scheme_entry_format:NnnN } \cs_new:Npn \grading_scheme_entry_gformat:PnnN { \exp_args:NP \grading_scheme_entry_gformat:NnnN } \cs_new:Npn \__grading_scheme_entry_format:NnnN #1 #2 #3 #4 { \__grading_scheme_entry_assert_description:N #1 % implicitly loads value \__grading_scheme_entry_assert_points:N #1 % implicitly loads value \__grading_scheme_tl_put_right:Nx #4 { \prg_replicate:nn { #2 } { & } \exp_not:N \__grading_scheme_multicolumn:nnn { \int_eval:n { #3 -1 } } { l } { \exp_not:V \l__grading_scheme_entry_description_tl } & \exp_not:N \__grading_scheme_points:n { \tl_use:N \l__grading_scheme_entry_points_int } \\ } } \cs_new:Npn \__grading_scheme_entry_forrmat:PnnN % implicit #1-4 { \exp_args:NP \__grading_scheme_entry_format:NnnN } \cs_new:Npn \__grading_scheme_entry_assert_description:N #1 { \__grading_scheme_entry_load_description:N #1 \quark_if_no_value:NT \l__grading_scheme_entry_description_tl { \msg_error:nnxxx { grading-scheme } { missing-value } { entry } { \token_to_str:N #1 } { description } } } \cs_new:Npn \__grading_scheme_entry_assert_points:N #1 { \__grading_scheme_entry_load_points:N #1 \quark_if_no_value:NT \l__grading_scheme_entry_points_int { \msg_error:nnxxx { grading-scheme } { missing-value } { entry } { \token_to_str:N #1 } { points } } } \msg_new:nnn { grading-scheme } { missing-value } { #1 ~ '#2' ~ has ~ no ~ #3. } \cs_set_eq:NN \grading_scheme_block_new:N \prop_new:N \cs_set_eq:NN \grading_scheme_block_clear:N \prop_clear:N \cs_set_eq:NN \grading_scheme_block_set_eq:NN \prop_gset_eq:NN \cs_set_eq:NN \grading_scheme_block_gclear:N \prop_gclear:N \cs_set_eq:NN \grading_scheme_block_gset_eq:NN \prop_gset_eq:NN \ptr_new:N \l__grading_scheme_block_elements_clist_ptr \tl_new:N \l__grading_scheme_block_description_tl \tl_new:N \l__grading_scheme_block_operation_tl \cs_new:Npn \grading_scheme_block_set_description:Nn #1 % implicit description { \prop_put:Nnn #1 { description } } \cs_new:Npn \grading_scheme_block_gset_description:Nn #1 % implicit description { \prop_gput:Nnn #1 { description } } \cs_new:Npn \grading_scheme_block_set_operation:Nn #1 % implicit operation { \prop_put:Nnn #1 { operation } } \cs_new:Npn \grading_scheme_block_gset_operation:Nn #1 % implicit operation { \prop_gput:Nnn #1 { operation } } \cs_new:Npn \grading_scheme_block_set_elements:NN #1 % implicit elements clist { \prop_put:Nnn #1 { elements } } \cs_new:Npn \grading_scheme_block_gset_elements:NN #1 % implicit elements clist { \prop_gput:Nnn #1 { elements } } \cs_new:Npn \grading_scheme_block_set_elements:NP { \exp_args:NNP \grading_scheme_block_set_elements:NN } \cs_new:Npn \grading_scheme_block_gset_elements:NP { \exp_args:NNP \grading_scheme_block_gset_elements:NN } \cs_new:Npn \grading_scheme_block_get_description:NN #1 % implicit #2 { \prop_get:NnN #1 { description } } \cs_new:Npn \grading_scheme_block_get_operation:NN #1 % implicit #2 { \prop_get:NnN #1 { operation } } \cs_new:Npn \grading_scheme_block_get_elements:NN #1 % implicit #2 { \prop_get:NnN #1 { elements } } \cs_new:Npn \__grading_scheme_block_load_description:N #1 { \grading_scheme_block_get_description:NN #1 \l__grading_scheme_block_description_tl } \cs_new:Npn \__grading_scheme_block_load_operation:N #1 { \grading_scheme_block_get_operation:NN #1 \l__grading_scheme_block_operation_tl } \cs_new:Npn \__grading_scheme_block_load_elements:N #1 { \grading_scheme_block_get_elements:NN #1 \l__grading_scheme_block_elements_clist_ptr } \cs_new:Npn \__grading_scheme_block_ensure_elements:N % implicit #1 { \cs_set_eq:NN \__grading_scheme_block_set_elements_optg:NP \grading_scheme_block_set_elements:NP \__grading_scheme_block_ensure_elements_aux:nN { l } } \cs_new:Npn \__grading_scheme_block_gensure_elements:N % implicit #1 { \cs_set_eq:NN \__grading_scheme_block_set_elements_optg:NP \grading_scheme_block_gset_elements:NP \__grading_scheme_block_ensure_elements_aux:nN { g } %i #1 } \cs_new:Npn \__grading_scheme_block_ensure_elements_aux:nN #1 #2 { \__grading_scheme_block_load_elements:N #2 \quark_if_no_value:NT \l__grading_scheme_block_elements_clist_ptr { \ptr_clear:Nn \l__grading_scheme_block_elements_clist_ptr { #1 } \__grading_scheme_block_set_elements_optg:NP #2 \l__grading_scheme_block_elements_clist_ptr } \ptr_if_null:NT \l__grading_scheme_block_elements_clist_ptr { \clist_new:P \l__grading_scheme_block_elements_clist_ptr } } \cs_new:Npn \grading_scheme_block_add_element:NN #1 % implicit element { \__grading_scheme_block_ensure_elements:N #1 % also loads local variable \clist_put_right:Pn \l__grading_scheme_block_elements_clist_ptr } \cs_new:Npn \grading_scheme_block_gadd_element:NN #1 % implicit element { \__grading_scheme_block_gensure_elements:N #1 % also loads local variable \clist_gput_right:Pn \l__grading_scheme_block_elements_clist_ptr } \cs_new:Npn \grading_scheme_block_add_element:PP { \exp_args:NPP \grading_scheme_block_add_element:NN } \cs_new:Npn \grading_scheme_block_gadd_element:PP { \exp_args:NPP \grading_scheme_block_gadd_element:NN } \cs_new:Npn \grading_scheme_block_add_element:PN { \exp_args:NP \grading_scheme_block_add_element:NN } \cs_new:Npn \grading_scheme_block_gadd_element:PN { \exp_args:NP \grading_scheme_block_gadd_element:NN } \cs_new:Npn \grading_scheme_block_format:NnnnN %implicit #1-5 { \cs_set_eq:NN \__grading_scheme_tl_put_right:Nx \tl_put_right:Nx \cs_set_eq:NN \__grading_scheme_element_format_optg:NnnnN \grading_scheme_element_format:NnnnN \cs_set_eq:NN \__grading_scheme_tl_set:Nn \tl_set:Nn \__grading_scheme_block_format:NnnnN } \cs_new:Npn \grading_scheme_block_gformat:NnnnN %implicit #1-5 { \cs_set_eq:NN \__grading_scheme_tl_put_right:Nx \tl_gput_right:Nx \cs_set_eq:NN \__grading_scheme_element_format_optg:NnnnN \grading_scheme_element_gformat:NnnnN \cs_set_eq:NN \__grading_scheme_tl_set:Nn \tl_gset:Nn \__grading_scheme_block_format:NnnnN } \cs_new:Npn \grading_scheme_block_format:PnnnN % implicit #1-5 { \exp_args:NP \grading_scheme_block_format:NnnnN } \cs_new:Npn \grading_scheme_block_gformat:PnnnN % implicit #1-5 { \exp_args:NP \grading_scheme_block_gformat:NnnnN } \bool_new:N \l__grading_scheme_block_indent_bool \int_new:N \l__grading_scheme_block_height_int \cs_new:Npn \__grading_scheme_block_format:NnnnN #1 #2 #3 #4 #5 { \bool_set:Nn \l__grading_scheme_block_indent_bool { #4 && \c_true_bool } \group_begin: \__grading_scheme_block_load_description:N #1 \grading_scheme_block_get_height:NN #1 \l__grading_scheme_block_height_int \quark_if_no_value:NF \l__grading_scheme_block_description_tl { \__grading_scheme_block_indent:nN { #2 } #5 \__grading_scheme_tl_put_right:Nx #5 { \exp_not:N \__grading_scheme_multicolumn:nnn { \int_eval:n { #3 } } { l| } { \exp_not:V \l__grading_scheme_block_description_tl } \\ \exp_not:N \__grading_scheme_cline:nn { \int_eval:n { #2 + 2 } } { \int_eval:n { #2 + #3 } } } } \__grading_scheme_block_indent:nN { #2 } #5 \__grading_scheme_block_assert_operation:N #1 \__grading_scheme_tl_put_right:Nx #5 { \exp_not:N \__grading_scheme_multirow:nnn { \int_eval:n { \int_use:N \l__grading_scheme_block_height_int - 1 } } { * } { \exp_not:N \__grading_scheme_rotatebox:nnn { origin = c } { 90 } { \exp_not:N \__grading_scheme_operation:n { \exp_not:V \l__grading_scheme_block_operation_tl } } } & } \bool_set_false:N \l__grading_scheme_block_indent_bool \cs_set:Npn \__grading_scheme_block_format_element:N ##1 { \__grading_scheme_element_format_optg:NnnnN ##1 { #2 + 1 } % indent is one more that the current block { #3 - 1 } % width is one less than current block { \l__grading_scheme_block_indent_bool } #5 \bool_set_true:N \l__grading_scheme_block_indent_bool } \__grading_scheme_block_ensure_elements:N #1 % load + sanitize elements \clist_map_function:PN \l__grading_scheme_block_elements_clist_ptr \__grading_scheme_block_format_element:N \exp_args:NNNV \group_end: \__grading_scheme_tl_set:Nn #5 #5 } \cs_new:Npn \__grading_scheme_block_format:PnnnN { \exp_args:NP \__grading_scheme_block_format:NnnnN } \cs_new:Npn \__grading_scheme_block_assert_operation:N #1 { \__grading_scheme_block_load_operation:N #1 \quark_if_no_value:NT \l__grading_scheme_block_operation_tl { \msg_error:nnxxx { grading-scheme } { missing-value} { block } { \token_to_str:N #1 } { operation } } } \cs_new:Npn \__grading_scheme_block_indent:nN #1 #2 { \bool_if:NT \l__grading_scheme_block_indent_bool { \__grading_scheme_tl_put_right:Nx #2 { \prg_replicate:nn { #1 } { & } } } \bool_set_true:N \l__grading_scheme_block_indent_bool } \int_new:N \l__grading_scheme_height_sum_int \int_new:N \l__grading_scheme_height_acc_int \cs_new:Npn \grading_scheme_block_get_height:NN #1 #2 { \group_begin: \__grading_scheme_block_load_elements:N #1 \int_zero:N \l__grading_scheme_height_sum_int \clist_map_function:PN \l__grading_scheme_block_elements_clist_ptr \__grading_scheme_block_height_accumulator:N \grading_scheme_block_if_description:NT #1 { \int_incr:N \l__grading_scheme_height_sum_int } \exp_args:NNNV \group_end: \int_set:Nn #2 \l__grading_scheme_height_sum_int } \cs_new:Npn \grading_scheme_block_get_height:PN { \exp_args:NP \grading_scheme_block_get_height:NN } \cs_new:Npn \__grading_scheme_block_height_accumulator:N #1 { \grading_scheme_element_get_height:NN #1 \l__grading_scheme_height_acc_int \int_add:Nn \l__grading_scheme_height_sum_int { \int_use:N \l__grading_scheme_height_acc_int } } \cs_new:Npn \grading_scheme_block_if_description:NT #1 % implicit #2 { \__grading_scheme_block_load_description:N #1 \quark_if_no_value:NF \l__grading_scheme_block_description_tl } \cs_new:Npn \grading_scheme_block_if_description:NF #1 % implicit #2 { \__grading_scheme_block_load_description:N #1 \quark_if_no_value:NT \l__grading_scheme_block_description_tl } \cs_new:Npn \grading_scheme_block_if_description:NTF #1 #2 #3 { \__grading_scheme_block_load_description:N #1 \quark_if_no_value:NTF \l__grading_scheme_block_description_tl { #3 } { #2 } } \int_new:N \l__grading_scheme_max_width_int \int_new:N \l__grading_scheme_width_acc_int \cs_new:Npn \grading_scheme_block_get_natural_width:NN #1 #2 { \group_begin: \__grading_scheme_block_load_elements:N #1 \int_zero:N \l__grading_scheme_max_width_int \clist_map_function:PN \l__grading_scheme_block_elements_clist_ptr \__grading_scheme_block_width_accumulator:N \int_incr:N \l__grading_scheme_max_width_int \exp_args:NNNV \group_end: \int_set:Nn #2 \l__grading_scheme_max_width_int } \cs_new:Npn \grading_scheme_block_get_natural_width:PN { \exp_args:NP \grading_scheme_block_get_natural_width:NN } \cs_new:Npn \__grading_scheme_block_width_accumulator:N #1 { \grading_scheme_element_get_natural_width:NN #1 \l__grading_scheme_width_acc_int \int_set:Nn \l__grading_scheme_max_width_int { \int_max:nn \l__grading_scheme_width_acc_int \l__grading_scheme_max_width_int } } \cs_set_eq:NN \grading_scheme_element_new:N \prop_new:N \cs_set_eq:NN \grading_scheme_element_clear:N \prop_clear:N \cs_set_eq:NN \grading_scheme_element_set_eq:NN \prop_set_eq:NN \cs_set_eq:NN \grading_scheme_element_gclear:N \prop_gclear:N \cs_set_eq:NN \grading_scheme_element_gset_eq:NN \prop_gset_eq:NN \ptr_new:N \l__grading_scheme_element_content_void_ptr \str_new:N \l__grading_scheme_element_type_str \cs_new:Npn \grading_scheme_element_set_block:NN #1 % implicit #2 { \prop_put:Nnn #1 { type } { block } \prop_put:Nnn #1 { content } } \cs_new:Npn \grading_scheme_element_gset_block:NN #1 % implicit #2 { \prop_gput:Nnn #1 { type } { block } \prop_gput:Nnn #1 { content } } \cs_new:Npn \grading_scheme_element_set_entry:NN #1 % implicit #2 { \prop_put:Nnn #1 { type } { entry } \prop_put:Nnn #1 { content } } \cs_new:Npn \grading_scheme_element_gset_entry:NN #1 % implicit #2 { \prop_gput:Nnn #1 { type } { entry } \prop_gput:Nnn #1 { content } } \cs_new:Npn \grading_scheme_element_get_content:NN #1 % implicit #2 { \prop_get:NnN #1 { content } } \cs_new:Npn \grading_scheme_element_get_type:NN #1 % implicit #2 { \prop_get:NnN #1 { type } } \cs_new:Npn \__grading_scheme_element_load_content:N #1 { \grading_scheme_element_get_content:NN #1 \l__grading_scheme_element_content_void_ptr } \cs_new:Npn \__grading_scheme_element_load_type:N #1 { \grading_scheme_element_get_type:NN #1 \l__grading_scheme_element_type_str } \cs_new:Npn \grading_scheme_element_cases:Nnn % implicit #1-3 { \cs_set_eq:NN \__grading_scheme_str_case:Vnw \str_case:Vn \__grading_scheme_element_cases:Nnnw } \cs_new:Npn \grading_scheme_element_cases:NnnT % implicit #1-4 { \cs_set_eq:NN \__grading_scheme_str_case:Vnw \str_case:VnT \__grading_scheme_element_cases:Nnnw } \cs_new:Npn \grading_scheme_element_cases:NnnF % implicit #1-4 { \cs_set_eq:NN \__grading_scheme_str_case:Vnw \str_case:VnF \__grading_scheme_element_cases:Nnnw } \cs_new:Npn \grading_scheme_element_cases:NnnTF % implicit #1-5 { \cs_set_eq:NN \__grading_scheme_str_case:Vnw \str_case:VnTF \__grading_scheme_element_cases:Nnnw } \cs_new:Npn \__grading_scheme_element_cases:Nnnw #1 #2 #3 % implicit branches { \__grading_scheme_element_load_type:N #1 \__grading_scheme_str_case:Vnw \l__grading_scheme_element_type_str { { entry } { #2 } { block } { #3 } } % implicit branches } \cs_new:Npn \grading_scheme_element_format:NnnnN % implicit #1-5 { \cs_set_eq:NN \__grading_scheme_entry_format_aux:PnnN \grading_scheme_entry_format:PnnN \cs_set_eq:NN \__grading_scheme_block_format_aux:PnnnN \grading_scheme_block_format:PnnnN \cs_set_eq:NN \__grading_scheme_tl_put_right:Nx \tl_put_right:Nx \__grading_scheme_element_format:NnnnN } \cs_new:Npn \grading_scheme_element_gformat:NnnnN % implicit #1-5 { \cs_set_eq:NN \__grading_scheme_entry_format_aux:PnnN \grading_scheme_entry_gformat:PnnN \cs_set_eq:NN \__grading_scheme_block_format_aux:PnnnN \grading_scheme_block_gformat:PnnnN \cs_set_eq:NN \__grading_scheme_tl_put_right:Nx \tl_put_gright:Nx \__grading_scheme_element_format:NnnnN } \cs_new:Npn \grading_scheme_element_format:PnnnN % implicit #1-5 { \exp_args:NP \grading_scheme_element_format:NnnnN } \cs_new:Npn \grading_scheme_element_gformat:PnnnN % implicit #1-5 { \exp_args:NP \grading_scheme_element_gformat:NnnnN } \cs_new:Npn \__grading_scheme_element_format:NnnnN #1 #2 #3 #4 #5 { \__grading_scheme_element_load_content:N #1 \grading_scheme_element_cases:NnnF #1 { \bool_if:nTF { #4 } { \__grading_scheme_entry_format_aux:PnnN \l__grading_scheme_element_content_void_ptr { #2 } { #3 } #5 } { \__grading_scheme_entry_format_aux:PnnN \l__grading_scheme_element_content_void_ptr { 0 } { #3 } #5 } } { \__grading_scheme_block_format_aux:PnnnN \l__grading_scheme_element_content_void_ptr { #2 } { #3 } { #4 } #5 } { \msg_error:nnxxx { grading-scheme } { missing-value } { element } { \token_to_str:N #1 } { type / content } } \__grading_scheme_tl_put_right:Nx #5 { \exp_not:N \__grading_scheme_cline:nn { \int_eval:n { #2 +1 } } { \int_eval:n { #2 + #3 } } } } \cs_new:Npn \__grading_scheme_element_format:PnnnN % implicit #1-5 { \exp_args:NP \__grading_scheme_element_format:NnnnN } \cs_new:Npn \grading_scheme_element_get_height:NN #1 #2 { \grading_scheme_element_cases:NnnF #1 { \int_set:Nn #2 { 1 } } { \__grading_scheme_element_load_content:N #1 \grading_scheme_block_get_height:PN \l__grading_scheme_element_content_void_ptr #2 } { \msg_error:nnxxx { grading-scheme } { missing-value } { element } { \token_to_str:N #1 } { type / content } } } \cs_new:Npn \grading_scheme_element_get_height:PN { \exp_args:NP \grading_scheme_element_get_height:NN } \cs_new:Npn \grading_scheme_element_get_natural_width:NN #1 #2 { \grading_scheme_element_cases:NnnF #1 { \int_set:Nn { #2 } { 2 } } { \__grading_scheme_element_load_content:N #1 \grading_scheme_block_get_natural_width:PN \l__grading_scheme_element_content_void_ptr #2 } { \msg_error:nnxxx { grading-scheme } { missing-value } { element } { \token_to_str:N #1 } { type / content } } } \cs_new:Npn \grading_scheme_element_get_natural_width:PN { \exp_args:NP \grading_scheme_element_get_natural_width:NN } \int_new:N \l__grading_scheme_width_int \tl_new:N \g__grading_scheme_table_tl \cs_new:Npn \grading_scheme_element_typeset:N #1 { \grading_scheme_element_get_natural_width:NN #1 \l__grading_scheme_width_int \tl_gclear:N \g__grading_scheme_table_tl \tl_gput_right:Nn \g__grading_scheme_table_tl { \begin{tabular} } \tl_gput_right:Nx \g__grading_scheme_table_tl { { \prg_replicate:nn { \l__grading_scheme_width_int -1 } { |l } | l | } \exp_not:N \__grading_scheme_hline: } \grading_scheme_element_gformat:NnnnN #1 { 0 } { \l__grading_scheme_width_int } { \c_false_bool } \g__grading_scheme_table_tl \tl_gput_right:Nn \g__grading_scheme_table_tl { \end{tabular} } \group_begin: \tl_set:Nn \arraystretch { 1.5 } \tl_use:N \g__grading_scheme_table_tl \group_end: } \cs_new:Npn \grading_scheme_element_typeset:P { \exp_args:NP \grading_scheme_element_typeset:N } \cs_new:Npn \grading_scheme_entry_new:Nnn #1 #2 % implcit #3 { \grading_scheme_entry_new:N #1 \grading_scheme_entry_gset_description:Nn #1 { #2 } \grading_scheme_entry_gset_points:Nn #1 } \cs_new:Npn \grading_scheme_entry_new:Pnn { \exp_args:NP \grading_scheme_entry_new:Nnn } \cs_new:Npn \grading_scheme_block_new:Nnn #1 #2 % implicit #3 { \grading_scheme_block_new:N #1 \grading_scheme_block_gset_description:Nn #1 { #2 } \grading_scheme_block_gset_operation:Nn #1 } \cs_new:Npn \grading_scheme_block_new:Pnn { \exp_args:NP \grading_scheme_block_new:Nnn } \cs_new:Npn \grading_scheme_block_new:Nn #1 % implicit #2 { \grading_scheme_block_new:N #1 \grading_scheme_block_gset_operation:Nn #1 } \cs_new:Npn \grading_scheme_block_new:Pn { \exp_args:NP \grading_scheme_block_new:Nn } \cs_new:Npn \grading_scheme_element_from_entry_new:NN #1 #2 { \grading_scheme_element_new:N #1 \grading_scheme_element_set_entry:NN #1 #2 } \cs_new:Npn \grading_scheme_element_from_entry_new:NP { \exp_args:NP \grading_scheme_element_from_entry_new:NN } \cs_new:Npn \grading_scheme_element_from_entry_new:PP { \exp_args:NPP \grading_scheme_element_from_entry_new:NN } \cs_new:Npn \grading_scheme_element_gfrom_entry_new:NN #1 #2 { \grading_scheme_element_new:N #1 \grading_scheme_element_gset_entry:NN #1 #2 } \cs_new:Npn \grading_scheme_element_gfrom_entry_new:NP { \exp_args:NP \grading_scheme_element_gfrom_entry_new:NN } \cs_new:Npn \grading_scheme_element_gfrom_entry_new:PP { \exp_args:NPP \grading_scheme_element_gfrom_entry_new:NN } \cs_new:Npn \grading_scheme_element_from_block_new:NN #1 #2 { \grading_scheme_element_new:N #1 \grading_scheme_element_set_block:NN #1 #2 } \cs_new:Npn \grading_scheme_element_from_block_new:NP { \exp_args:NP \grading_scheme_element_from_block_new:NN } \cs_new:Npn \grading_scheme_element_from_block_new:PP { \exp_args:NPP \grading_scheme_element_from_block_new:NN } \cs_new:Npn \grading_scheme_element_gfrom_block_new:NN #1 #2 { \grading_scheme_element_new:N #1 \grading_scheme_element_gset_block:NN #1 #2 } \cs_new:Npn \grading_scheme_element_gfrom_block_new:NP { \exp_args:NP \grading_scheme_element_gfrom_block_new:NN } \cs_new:Npn \grading_scheme_element_gfrom_block_new:PP { \exp_args:NPP \grading_scheme_element_gfrom_block_new:NN } \ptr_new:Nn \l__grading_scheme_entry_ptr { g } \ptr_new:Nn \l__grading_scheme_element_ptr { g } \ptr_new:Nn \l__grading_scheme_curr_block_ptr { g } \cs_new:Npn \__grading_scheme_entry:nn #1 #2 { \ptr_clear:Nn \l__grading_scheme_entry_ptr { g } \ptr_clear:Nn \l__grading_scheme_element_ptr { g } \grading_scheme_entry_new:Pnn \l__grading_scheme_entry_ptr { #1 } { #2 } \grading_scheme_element_gfrom_entry_new:PP \l__grading_scheme_element_ptr \l__grading_scheme_entry_ptr \grading_scheme_block_gadd_element:PP \l__grading_scheme_curr_block_ptr \l__grading_scheme_element_ptr } \cs_new:Npn \__grading_scheme_block_begin:nn % implicit #1, #2 { \ptr_clear:Nn \l__grading_scheme_curr_block_ptr { g } \grading_scheme_block_new:Pnn \l__grading_scheme_curr_block_ptr } \cs_new:Npn \__grading_scheme_block_begin:n % implicit #1 { \ptr_clear:Nn \l__grading_scheme_curr_block_ptr { g } \grading_scheme_block_new:Pn \l__grading_scheme_curr_block_ptr } \cs_new:Npn \__grading_scheme_block_end: { \ptr_clear:Nn \l__grading_scheme_element_ptr { g } \grading_scheme_element_gfrom_block_new:PP \l__grading_scheme_element_ptr \l__grading_scheme_curr_block_ptr \cs_gset:Npx \__grading_scheme_after_group: { \exp_not:N \grading_scheme_block_gadd_element:PN \exp_not:N \l__grading_scheme_curr_block_ptr \exp_not:P \l__grading_scheme_element_ptr } \group_insert_after:N \__grading_scheme_after_group: } \NewDocumentCommand \entry { m m } { \__grading_scheme_entry:nn { #1 } { #2 } } \NewDocumentEnvironment { block } { o m } { \IfValueTF { #1 } { \__grading_scheme_block_begin:nn { #1 } { #2 } } { \__grading_scheme_block_begin:n { #2 } } } { \__grading_scheme_block_end: } \NewDocumentEnvironment {gradingscheme} { o m } { \bool_if:NT \g__grading_scheme_pipe_syntax_bool { \char_set_active_eq:NN | \__grading_scheme_entry_oneline:w \char_set_catcode_active:N | } \IfValueTF { #1 } { \__grading_scheme_block_begin:nn { #1 } { #2 } } { \__grading_scheme_block_begin:n { #2 } } } { \ptr_clear:Nn \l__grading_scheme_element_ptr { g } \grading_scheme_element_gfrom_block_new:PP \l__grading_scheme_element_ptr \l__grading_scheme_curr_block_ptr \grading_scheme_element_typeset:P \l__grading_scheme_element_ptr } \bool_if:NF \g__grading_scheme_pipe_syntax_bool { \endinput } \scan_new:N \s__grading_scheme_endline \cs_new:Npn \__grading_scheme_parse_entry:w #1 & #2 \s_endline { \__grading_scheme_entry:nn { #1 } { #2 } } \cs_new:Npn \__grading_scheme_replace_newline:w { \group_begin: \char_set_catcode_active:N\^^M \__grading_scheme_replace_newline_aux:w } \char_set_catcode_active:N\^^M \cs_new:Npn \__grading_scheme_replace_newline_aux:w #1 ^^M { \group_end: #1 \s_endline } \char_set_catcode_end_line:N\^^M \cs_new:Npn \__grading_scheme_entry_oneline:w { \__grading_scheme_replace_newline:w \__grading_scheme_parse_entry:w } %% %% Copyright 2022 Maximilian Kessler %% %% Distributable under the LaTeX Project Public License, %% version 1.3c or higher (your choice). The latest version of %% this license is at: http://www.latex-project.org/lppl.txt %% %% This work is "author-maintained" %% %% This work consists of the files grading-scheme.dtx, grading-scheme.ins, %% a README file %% and the derived files grading-scheme.sty and grading-scheme.pdf. %% %% %% End of file `grading-scheme.sty'.