From 1014c3be7b2ac6edff2c3ad97fdcf8720e8932b5 Mon Sep 17 00:00:00 2001
From: Karl Berry <karl@freefriends.org>
Date: Wed, 23 Feb 2022 20:55:03 +0000
Subject: grading-scheme (23feb22)

git-svn-id: svn://tug.org/texlive/trunk@62155 c570f23f-e606-0410-a88d-b1316a301751
---
 .../tex/latex/grading-scheme/grading-scheme.sty    | 1143 ++++++++++++++++++++
 1 file changed, 1143 insertions(+)
 create mode 100644 Master/texmf-dist/tex/latex/grading-scheme/grading-scheme.sty

(limited to 'Master/texmf-dist/tex/latex/grading-scheme/grading-scheme.sty')

diff --git a/Master/texmf-dist/tex/latex/grading-scheme/grading-scheme.sty b/Master/texmf-dist/tex/latex/grading-scheme/grading-scheme.sty
new file mode 100644
index 00000000000..2ee191440cc
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/grading-scheme/grading-scheme.sty
@@ -0,0 +1,1143 @@
+%%
+%% 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/22} {bla}
+  {test}
+\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 <ctan@maximilian-kessler.de>
+%% 
+%% 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'.
-- 
cgit v1.2.3

