\RequirePackage{xparse,l3keys2e,leftindex,semtex} \ProvidesExplPackage{semantex}{2020/11/05}{0.463}{} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % SemanTeX -- semantic, keyval-based mathematics % % https://ctan.org/pkg/semantex % % (C) 2020 Sebastian Ørsted % % sorsted@gmail.com % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \cs_set_eq:NN \semantex_keyval_parse:NNn \keyval_parse:NNn \keys_define:nn { semantex } { keyvalparser .code:n = \cs_set_eq:NN \semantex_keyval_parse:NNn #1, keyvalparser .value_required:n = true, semtexfile .choice:, semtexfile / true .code:n = \semantex_turn_semtex_file_on:, semtexfile / false .code:n = \semantex_turn_semtex_file_off:, semtexfile / .code:n = \semantex_turn_semtex_file_on:, semtexfile / unknown .code:n = \msg_error:nnnn { semantex } { semantex_setup_key_value_not_found } { semtexfile } { #1 }, unknown .code:n = \msg_error:nnx { semantex } { semantex_setup_key_not_found } { \l_keys_key_str } } \DeclareDocumentCommand\SemantexSetup { m } { \keys_set:nn { semantex } { #1 } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % THE .semtex FILE % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \bool_new:N \g__semantex_semtex_file_was_opened_bool \iow_new:N \g__semantex_semtex_file_stream_temp_iow \cs_new_protected:Npn \semantex_turn_semtex_file_on: { \bool_if:NF \g__semantex_semtex_file_was_opened_bool { \iow_open:Nn \g__semantex_semtex_file_stream_temp_iow { \jobname.semtex } \iow_now:Nn \g__semantex_semtex_file_stream_temp_iow { \DeclareClass {\SemantexBaseObject } } \iow_now:Nn \g__semantex_semtex_file_stream_temp_iow { \DeclareObject {\SemantexDelimiterSize } } } \cs_set:Npn\semantex_write_to_semtex_file:n##1 { \iow_now:Nn \g__semantex_semtex_file_stream_temp_iow { ##1 } } \cs_set:Npn\semantex_write_to_semtex_file_V:N ##1 { % We use this command instead of a :V variant % in order to save time; when semtexfile=false, % there is no reason to V-expand the argument. \semantex_write_to_semtex_file:V ##1 } \bool_set_true:N \g__semantex_semtex_file_was_opened_bool } \cs_new_protected:Npn \semantex_turn_semtex_file_off: { \bool_if:NT \g__semantex_semtex_file_was_opened_bool { \iow_close:N \g__semantex_semtex_file_stream_temp_iow } \cs_set:Npn\semantex_write_to_semtex_file:n##1 {} \cs_set:Npn\semantex_write_to_semtex_file_V:N ##1 {} % We use this command instead of a :V variant % in order to save time; when semtexfile=false, % there is no reason to V-expand the argument. \bool_set_false:N \g__semantex_semtex_file_was_opened_bool } \semantex_turn_semtex_file_off: \cs_generate_variant:Nn \semantex_write_to_semtex_file:n { V } \cs_new_protected:Npn\semantex_write_original_source_to_semtex_file:n#1 { \semantex_write_to_semtex_file:n { \BeginSource } \semantex_write_to_semtex_file:n { #1 } } \cs_set_eq:NN\SemantexRecordSource\semantex_write_original_source_to_semtex_file:n \cs_new_protected:Npn\semantex_add_to_existing_original_source_in_semtex_file:n#1 { \semantex_write_to_semtex_file:n { #1 } } \cs_set_eq:NN\SemantexAddToRecordedSource\semantex_add_to_existing_original_source_in_semtex_file:n \cs_new_protected:Npn\semantex_write_output_to_semtex_file:n#1 { \semantex_write_to_semtex_file:n { \EndSource } \semantex_write_to_semtex_file:n { \BeginOutput } \semantex_write_to_semtex_file:n { #1 } \semantex_write_to_semtex_file:n { \EndOutput } } \cs_set_eq:NN\SemantexRecordOutput\semantex_write_output_to_semtex_file:n \cs_new_protected:Npn\semantex_write_output_to_semtex_file_V:N#1 { \semantex_write_to_semtex_file:n { \EndSource } \semantex_write_to_semtex_file:n { \BeginOutput } \semantex_write_to_semtex_file_V:N #1 \semantex_write_to_semtex_file:n { \EndOutput } } \cs_new_protected:Npn\semantex_write_class_declaration_to_semtex_file:n#1 { \semantex_write_to_semtex_file:n { \DeclareClass{#1} } } \cs_new_protected:Npn\semantex_write_object_declaration_to_semtex_file:n#1 { \semantex_write_to_semtex_file:n { \DeclareObject{#1} } } \cs_new_protected:Npn\SemantexIDcommand#1 { \semantex_write_to_semtex_file:n { \SemantexID{#1} } } \cs_set_eq:NN\SemantexRecordObject\semantex_write_object_declaration_to_semtex_file:n %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % USER COMMANDS FOR CREATING NEW CLASSES % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \DeclareDocumentCommand\semantex_new_simple_class:Nw{mO{}} % new simple-type class { % #1 = class name % #2 = options \semantex_new_class:Nn { #1 } { \semantex_class_set_keys:Nn #1 { #2 } } \DeclareDocumentCommand{#1}{m} { % the actual \#1 command \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } } \semantex_render_class:Nn #1 { \semantex_class_set_symbol:Nn #1 { ##1 } } } \exp_args:Nc\DeclareDocumentCommand{__semantex_make_object_of_\semantex_class_to_register:N #1_with_options:nnw}{mm} { %\semantex_add_to_existing_original_source_in_semtex_file:n { } % add nothing to file \semantex_render_class:Nn #1 { \semantex_class_set_symbol:Nn #1 { ##2 } ##1 } } \exp_args:Nc\DeclareDocumentCommand{__semantex_new_object_of_\semantex_class_to_register:N #1:Nw}{mgO{}} { % the command for creating a new object of class #1 % ##1 = command name, with backslash % ##2 = symbol % ##3 = options \IfValueTF{##2} { \semantex_new_object:NNn #1 ##1 { \semantex_object_set_symbol:Nn ##1 { ##2 } \semantex_object_set_keys:Nn ##1 { ##3 } } } { \semantex_new_object:NNn #1 ##1 { \semantex_object_set_keys:Nn ##1 { ##3 } } } % create the object with name ##1 \DeclareDocumentCommand{##1}{} { % the actual \##1 command \semantex_write_original_source_to_semtex_file:n { ##1 } \semantex_render_object:Nn ##1 { } } } } \tl_set_eq:NN\NewSimpleClass\semantex_new_simple_class:Nw \DeclareDocumentCommand\semantex_new_symbol_class:Nw{mO{}} % new symbol-type class { % #1 = class name % #2 = options \semantex_new_class:Nn { #1 } { \semantex_class_set_keys:Nn #1 { #2 } } \DeclareDocumentCommand{#1}{mo} { % the actual \#1 command \IfValueTF{##2} { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } { ##2 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##1 } \semantex_class_set_keys:Nn #1 { ##2 } } } { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } } \semantex_render_class:Nn #1 { \semantex_class_set_symbol:Nn #1 { ##1 } } } } \exp_args:Nc\DeclareDocumentCommand{__semantex_make_object_of_\semantex_class_to_register:N #1_with_options:nnw}{mmo} { \IfValueTF{##3} { \semantex_add_to_existing_original_source_in_semtex_file:n { [##3] } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##2 } ##1 \semantex_class_set_keys:Nn #1 { ##3 } } } { %\semantex_add_to_existing_original_source_in_semtex_file:n { } % write nothing to file \semantex_render_class:Nn #1 { \semantex_class_set_symbol:Nn #1 { ##2 } ##1 } } } \exp_args:Nc\DeclareDocumentCommand{__semantex_new_object_of_\semantex_class_to_register:N #1:Nw}{mgO{}} { % the command for creating a new object of class #1 % ##1 = command name, with backslash % ##2 = symbol % ##3 = options \IfValueTF{##2} { \semantex_new_object:NNn #1 ##1 { \semantex_object_set_symbol:Nn ##1 { ##2 } \semantex_object_set_keys:Nn ##1 { ##3 } } } { \semantex_new_object:NNn #1 ##1 { \semantex_object_set_keys:Nn ##1 { ##3 } } } % create the object with name ##1 \DeclareDocumentCommand{##1}{o} { % the actual \##1 command \IfValueTF { ####1 } { \semantex_write_original_source_to_semtex_file:n { ##1 [ ####1 ] } \semantex_render_object:Nn ##1 { \semantex_object_do_output:N ##1 \semantex_object_set_keys:Nn ##1 { ####1 } } } { \semantex_write_original_source_to_semtex_file:n { ##1 } \semantex_render_object:Nn ##1 { } } } } } \tl_set_eq:NN\NewSymbolClass\semantex_new_symbol_class:Nw \DeclareDocumentCommand\semantex_new_variable_class:Nw{mO{}} % new variable-type class { % #1 = class name % #2 = options \semantex_new_class:Nn { #1 } { \semantex_class_set_keys:Nn #1 { #2 } } %\semantex_new_class:Nn #1 { #2 } \DeclareDocumentCommand{#1}{mog} { % the actual \#1 command \IfValueTF { ##2 } { \IfValueTF { ##3 } { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } [ ##2 ] { ##3 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##1 } \semantex_class_set_keys:Nn #1 { ##2 } \semantex_class_set_arg:Nn #1 { ##3 } } } { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } [ ##2 ] } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##1 } \semantex_class_set_keys:Nn #1 { ##2 } } } } { \IfValueTF { ##3 } { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } { ##3 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##1 } \semantex_class_set_arg:Nn #1 { ##3 } } } { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } } \semantex_render_class:Nn #1 { \semantex_class_set_symbol:Nn #1 { ##1 } } } } } \exp_args:Nc\DeclareDocumentCommand{__semantex_make_object_of_\semantex_class_to_register:N #1_with_options:nnw}{mmog} { \IfValueTF { ##3 } { \IfValueTF { ##4 }{ \semantex_add_to_existing_original_source_in_semtex_file:n { [ ##3 ] { ##4 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##2 } ##1 \semantex_class_set_keys:Nn #1 { ##3 } \semantex_class_set_arg:Nn #1 { ##4 } } } { \semantex_add_to_existing_original_source_in_semtex_file:n { [ ##3 ] } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##2 } ##1 \semantex_class_set_keys:Nn #1 { ##3 } } } } { \IfValueTF { ##4 } { \semantex_add_to_existing_original_source_in_semtex_file:n { { ##4 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##2 } ##1 \semantex_class_set_arg:Nn #1 { ##4 } } } { % \semantex_add_to_existing_original_source_in_semtex_file:n { } % write nothing to file \semantex_render_class:Nn #1 { \semantex_class_set_symbol:Nn #1 { ##2 } ##1 } } } } \exp_args:Nc\DeclareDocumentCommand{__semantex_new_object_of_\semantex_class_to_register:N #1:Nw}{mgO{}} { % the command for creating a new object of class #1 % ##1 = command name, with backslash % ##2 = symbol % ##3 = options \IfValueTF{##2} { \semantex_new_object:NNn #1 ##1 { \semantex_object_set_symbol:Nn ##1 { ##2 } \semantex_object_set_keys:Nn ##1 { ##3 } } } { \semantex_new_object:NNn #1 ##1 { \semantex_object_set_keys:Nn ##1 { ##3 } } } % creates the object with name ##1 \DeclareDocumentCommand{##1}{og}{ % the actual \##1 command \IfValueTF{####1}{ \IfValueTF{####2} { \semantex_write_original_source_to_semtex_file:n { ##1 [ ####1 ] { ####2 } } \semantex_render_object:Nn ##1 { \semantex_object_do_output:N ##1 \semantex_object_set_keys:Nn ##1 { ####1 } \semantex_object_set_arg:Nn ##1 { ####2 } } } { \semantex_write_original_source_to_semtex_file:n { ##1 [ ####1 ] } \semantex_render_object:Nn ##1 { \semantex_object_do_output:N ##1 \semantex_object_set_keys:Nn ##1 { ####1 } } } } { \IfValueTF{####2} { \semantex_write_original_source_to_semtex_file:n { ##1 {####2} } \semantex_render_object:Nn ##1 { \semantex_object_do_output:N ##1 \semantex_object_set_arg:Nn ##1 { ####2 } } } { \semantex_write_original_source_to_semtex_file:n { ##1 } \semantex_render_object:Nn ##1 {} } } } } } \cs_set_eq:NN\NewVariableClass\semantex_new_variable_class:Nw \DeclareDocumentCommand\semantex_new_cohomology_class:Nw{mO{}} % new cohomology-type class { % #1 = class name % #2 = options \semantex_new_class:Nn { #1 } { \semantex_class_set_keys:Nn #1 { #2 } } \DeclareDocumentCommand{#1}{mogg}{ % the actual \#1 command \IfValueTF{##2} { \IfValueTF { ##3 } { \str_if_eq:nnTF { ##3 }{ * } { \IfValueTF { ##4 } { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } [ ##2 ] { * } { ##4 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##1 } \semantex_class_set_keys:Nn #1 { ##2 } \semantex_class_use_bullet:N #1 \semantex_class_set_arg:Nn #1 { ##4 } } } { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } [ ##2 ] { * } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##1 } \semantex_class_set_keys:Nn #1 { ##2 } \semantex_class_use_bullet:N #1 } } } { \str_if_eq:nnTF { ##3 }{ ** } { \IfValueTF { ##4 } { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } [ ##2 ] { ** } { ##4 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##1 } \semantex_class_set_keys:Nn #1 { ##2 } \semantex_class_use_double_bullet:N #1 \semantex_class_set_arg:Nn #1 { ##4 } } } { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } [ ##2 ] { ** } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##1 } \semantex_class_set_keys:Nn #1 { ##2 } \semantex_class_use_double_bullet:N #1 } } } { \IfValueTF { ##4 } { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } [ ##2 ] { ##3 } { ##4 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##1 } \semantex_class_set_keys:Nn #1 { ##2 } \semantex_class_set_degreedefault:Nn #1 { ##3 } \semantex_class_set_arg:Nn #1 { ##4 } } } { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } [ ##2 ] { ##3 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##1 } \semantex_class_set_keys:Nn #1 { ##2 } \semantex_class_set_degreedefault:Nn #1 { ##3 } } } } } } { \IfValueTF { ##4 } { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } [ ##2 ] { ##4 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##1 } \semantex_class_set_keys:Nn #1 { ##2 } \semantex_class_set_arg:Nn #1 { ##4 } } } { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } [ ##2 ] } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##1 } \semantex_class_set_keys:Nn #1 { ##2 } } } } } { \IfValueTF { ##3 } { \str_if_eq:nnTF { ##3 }{ * } { \IfValueTF { ##4 } { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } { * } { ##4 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##1 } \semantex_class_use_bullet:N #1 \semantex_class_set_arg:Nn #1 { ##4 } } } { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } { * } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##1 } \semantex_class_use_bullet:N #1 } } } { \str_if_eq:nnTF { ##3 }{ ** } { \IfValueTF { ##4 } { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } { ** } { ##4 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##1 } \semantex_class_use_double_bullet:N #1 \semantex_class_set_arg:Nn #1 { ##4 } } } { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } { ** } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##1 } \semantex_class_use_double_bullet:N #1 } } } { \IfValueTF { ##4 } { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } { ##3 } { ##4 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##1 } \semantex_class_set_degreedefault:Nn #1 { ##3 } \semantex_class_set_arg:Nn #1 { ##4 } } } { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } { ##3 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##1 } \semantex_class_set_degreedefault:Nn #1 { ##3 } } } } } } { \IfValueTF { ##4 } { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } { ##4 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##1 } \semantex_class_set_arg:Nn #1 { ##4 } } } { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } } \semantex_render_class:Nn #1 { \semantex_class_set_symbol:Nn #1 { ##1 } } } } } } \exp_args:Nc\DeclareDocumentCommand{__semantex_make_object_of_\semantex_class_to_register:N #1_with_options:nnw}{mmogg} { \IfValueTF{##3} { \IfValueTF { ##4 } { \str_if_eq:nnTF { ##4 }{ * } { \IfValueTF { ##5 } { \semantex_add_to_existing_original_source_in_semtex_file:n { [ ##3 ] { * } { ##5 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##2 } ##1 \semantex_class_set_keys:Nn #1 { ##3 } \semantex_class_use_bullet:N #1 \semantex_class_set_arg:Nn #1 { ##5 } } } { \semantex_add_to_existing_original_source_in_semtex_file:n { [ ##3 ] { * } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##2 } ##1 \semantex_class_set_keys:Nn #1 { ##3 } \semantex_class_use_bullet:N #1 } } } { \str_if_eq:nnTF { ##4 }{ ** } { \IfValueTF { ##5 } { \semantex_add_to_existing_original_source_in_semtex_file:n { [ ##3 ] { ** } { ##5 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##2 } ##1 \semantex_class_set_keys:Nn #1 { ##3 } \semantex_class_use_double_bullet:N #1 \semantex_class_set_arg:Nn #1 { ##5 } } } { \semantex_add_to_existing_original_source_in_semtex_file:n { [ ##3 ] { ** } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##2 } ##1 \semantex_class_set_keys:Nn #1 { ##3 } \semantex_class_use_double_bullet:N #1 } } } { \IfValueTF { ##5 } { \semantex_add_to_existing_original_source_in_semtex_file:n { [ ##3 ] { ##4 } { ##5 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##2 } ##1 \semantex_class_set_keys:Nn #1 { ##3 } \semantex_class_set_degreedefault:Nn #1 { ##4 } \semantex_class_set_arg:Nn #1 { ##5 } } } { \semantex_add_to_existing_original_source_in_semtex_file:n { [ ##3 ] { ##4 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##2 } ##1 \semantex_class_set_keys:Nn #1 { ##3 } \semantex_class_set_degreedefault:Nn #1 { ##4 } } } } } } { \IfValueTF { ##5 } { \semantex_add_to_existing_original_source_in_semtex_file:n { [ ##3 ] { ##5 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##2 } ##1 \semantex_class_set_keys:Nn #1 { ##3 } \semantex_class_set_arg:Nn #1 { ##5 } } } { \semantex_add_to_existing_original_source_in_semtex_file:n { [ ##3 ] } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##2 } ##1 \semantex_class_set_keys:Nn #1 { ##3 } } } } } { \IfValueTF { ##4 } { \str_if_eq:nnTF { ##4 }{ * } { \IfValueTF { ##5 } { \semantex_add_to_existing_original_source_in_semtex_file:n { { * } { ##5 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##2 } ##1 \semantex_class_use_bullet:N #1 \semantex_class_set_arg:Nn #1 { ##5 } } } { \semantex_add_to_existing_original_source_in_semtex_file:n { { * } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##2 } ##1 \semantex_class_use_bullet:N #1 } } } { \str_if_eq:nnTF { ##4 }{ ** } { \IfValueTF { ##5 } { \semantex_add_to_existing_original_source_in_semtex_file:n { { ** } { ##5 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##2 } ##1 \semantex_class_use_double_bullet:N #1 \semantex_class_set_arg:Nn #1 { ##5 } } } { \semantex_add_to_existing_original_source_in_semtex_file:n { { ** } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##2 } ##1 \semantex_class_use_double_bullet:N #1 } } } { \IfValueTF { ##5 } { \semantex_add_to_existing_original_source_in_semtex_file:n { { ##4 } { ##5 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##2 } ##1 \semantex_class_set_degreedefault:Nn #1 { ##4 } \semantex_class_set_arg:Nn #1 { ##5 } } } { \semantex_add_to_existing_original_source_in_semtex_file:n { { ##4 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##2 } ##1 \semantex_class_set_degreedefault:Nn #1 { ##4 } } } } } } { \IfValueTF { ##5 } { \semantex_add_to_existing_original_source_in_semtex_file:n { { ##5 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##2 } ##1 \semantex_class_set_arg:Nn #1 { ##5 } } } { % \semantex_add_to_existing_original_source_in_semtex_file:n { } % write nothing to file \semantex_render_class:Nn #1 { \semantex_class_set_symbol:Nn #1 { ##2 } ##1 } } } } } \exp_args:Nc\DeclareDocumentCommand{__semantex_new_object_of_\semantex_class_to_register:N #1:Nw}{mgO{}} { % the command for creating a new object of class #1 % ##1 = command name, with backslash % ##2 = symbol % ##3 = options \IfValueTF{##2} { \semantex_new_object:NNn #1 { ##1 }{ \semantex_object_set_symbol:Nn ##1 { ##2 } \semantex_object_set_keys:Nn ##1 { ##3 } } } { \semantex_new_object:NNn #1 { ##1 }{ \semantex_object_set_keys:Nn ##1 { ##3 } } } % creates the object with name ##1 \DeclareDocumentCommand{##1}{ogg} { % the actual \##1 command \IfValueTF{####1} { \IfValueTF{####2} { \str_if_eq:nnTF { ####2 } { * } { \IfValueTF{####3} { \semantex_write_original_source_to_semtex_file:n { ##1 [ ####1 ] { * } { ####3 } } \semantex_render_object:Nn ##1 { \semantex_object_do_output:N ##1 \semantex_object_set_keys:Nn ##1 { ####1 } \semantex_object_use_bullet:N ##1 \semantex_object_set_arg:Nn ##1 { ####3 } } } { \semantex_write_original_source_to_semtex_file:n { ##1 [ ####1 ] { * } } \semantex_render_object:Nn ##1 { \semantex_object_do_output:N ##1 \semantex_object_set_keys:Nn ##1 { ####1 } \semantex_object_use_bullet:N ##1 } } } { \str_if_eq:nnTF { ####2 } { ** } { \IfValueTF{####3} { \semantex_write_original_source_to_semtex_file:n { ##1 [ ####1 ] { ** } { ####3 } } \semantex_render_object:Nn ##1 { \semantex_object_do_output:N ##1 \semantex_object_set_keys:Nn ##1 { ####1 } \semantex_object_use_double_bullet:N ##1 \semantex_object_set_arg:Nn ##1 { ####3 } } } { \semantex_write_original_source_to_semtex_file:n { ##1 [ ####1 ] { ** } } \semantex_render_object:Nn ##1 { \semantex_object_do_output:N ##1 \semantex_object_set_keys:Nn ##1 { ####1 } \semantex_object_use_double_bullet:N ##1 } } } { \IfValueTF{####3} { \semantex_write_original_source_to_semtex_file:n { ##1 [ ####1 ] { ####2 } { ####3 } } \semantex_render_object:Nn ##1 { \semantex_object_do_output:N ##1 \semantex_object_set_keys:Nn ##1 { ####1 } \semantex_object_set_degreedefault:Nn ##1 { ####2 } \semantex_object_set_arg:Nn ##1 { ####3 } } } { \semantex_write_original_source_to_semtex_file:n { ##1 [ ####1 ] { ####2 } } \semantex_render_object:Nn ##1 { \semantex_object_do_output:N ##1 \semantex_object_set_keys:Nn ##1 { ####1 } \semantex_object_set_degreedefault:Nn ##1 { ####2 } } } } } } { \IfValueTF{####3} { \semantex_write_original_source_to_semtex_file:n { ##1 [ ####1 ] { ####3 } } \semantex_render_object:Nn ##1 { \semantex_object_do_output:N ##1 \semantex_object_set_keys:Nn ##1 { ####1 } \semantex_object_set_arg:Nn ##1 { ####3 } } } { \semantex_write_original_source_to_semtex_file:n { ##1 [ ####1 ] } \semantex_render_object:Nn ##1 { \semantex_object_do_output:N ##1 \semantex_object_set_keys:Nn ##1 { ####1 } } } } } { \IfValueTF{####2} { \str_if_eq:nnTF { ####2 } { * } { \IfValueTF{####3} { \semantex_write_original_source_to_semtex_file:n { ##1 { * } { ####3 } } \semantex_render_object:Nn ##1 { \semantex_object_do_output:N ##1 \semantex_object_use_bullet:N ##1 \semantex_object_set_arg:Nn ##1 { ####3 } } } { \semantex_write_original_source_to_semtex_file:n { ##1 { * } } \semantex_render_object:Nn ##1 { \semantex_object_do_output:N ##1 \semantex_object_use_bullet:N ##1 } } } { \str_if_eq:nnTF { ####2 } { ** } { \IfValueTF{####3} { \semantex_write_original_source_to_semtex_file:n { ##1 { ** } { ####3 } } \semantex_render_object:Nn ##1 { \semantex_object_do_output:N ##1 \semantex_object_use_double_bullet:N ##1 \semantex_object_set_arg:Nn ##1 { ####3 } } } { \semantex_write_original_source_to_semtex_file:n { ##1 { ** } } \semantex_render_object:Nn ##1 { \semantex_object_do_output:N ##1 \semantex_object_use_double_bullet:N ##1 } } } { \IfValueTF{####3} { \semantex_write_original_source_to_semtex_file:n { ##1 { ####2 } { ####3 } } \semantex_render_object:Nn ##1 { \semantex_object_do_output:N ##1 \semantex_object_set_degreedefault:Nn ##1 { ####2 } \semantex_object_set_arg:Nn ##1 { ####3 } } } { \semantex_write_original_source_to_semtex_file:n { ##1 { ####2 } } \semantex_render_object:Nn ##1 { \semantex_object_do_output:N ##1 \semantex_object_set_degreedefault:Nn ##1 { ####2 } } } } } } { \IfValueTF{####3} { \semantex_write_original_source_to_semtex_file:n { ##1 { ####3 } } \semantex_render_object:Nn ##1 { \semantex_object_do_output:N ##1 \semantex_object_set_arg:Nn ##1 { ####3 } } } { \semantex_write_original_source_to_semtex_file:n { ##1 } \semantex_render_object:Nn ##1 { } } } } } } } \cs_set_eq:NN\NewCohomologyClass\semantex_new_cohomology_class:Nw \DeclareDocumentCommand\semantex_new_delimiter_class:Nw{mO{}} % new delimiter-type class { % #1 = class name % #2 = options \semantex_new_class:Nn { #1 } { \semantex_class_set_keys:Nn #1 { #2 } } \DeclareDocumentCommand{#1}{mog} % maybe this does not even make sense for delimiters { \IfValueTF { ##2 } { \IfValueTF { ##3 } { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } [ ##2 ] { ##3 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##1 } \semantex_class_set_keys:Nn #1 { ##2 } \semantex_class_set_arg:Nn #1 { ##3 } } } { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } [ ##2 ] } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##1 } \semantex_class_set_keys:Nn #1 { ##2 } } } } { \IfValueTF { ##3 } { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } { ##3 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##1 } \semantex_class_set_arg:Nn #1 { ##3 } } } { \semantex_write_original_source_to_semtex_file:n { #1 { ##1 } } \semantex_render_class:Nn #1 { \semantex_class_set_symbol:Nn #1 { ##1 } } } } } % the actual \#1 command \exp_args:Nc\DeclareDocumentCommand{__semantex_make_object_of_\semantex_class_to_register:N #1_with_options:nnw}{mmog} { \IfValueTF { ##3 } { \IfValueTF { ##4 } { \semantex_add_to_existing_original_source_in_semtex_file:n { [ ##3 ] { ##4 } } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##2 } ##1 \semantex_class_set_keys:Nn #1 { ##3 } \semantex_class_set_arg:Nn #1 { ##4 } } } { \semantex_add_to_existing_original_source_in_semtex_file:n { [ ##3 ] } \semantex_render_class:Nn #1 { \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##2 } ##1 \semantex_class_set_keys:Nn #1 { ##3 } } } } { \IfValueTF { ##4 } { \semantex_render_class:Nn #1 { \semantex_add_to_existing_original_source_in_semtex_file:n { { ##4 } } \semantex_class_do_output:N #1 \semantex_class_set_symbol:Nn #1 { ##2 } ##1 \semantex_class_set_arg:Nn #1 { ##4 } } } { % \semantex_add_to_existing_original_source_in_semtex_file:n { } % write nothing to file \semantex_render_class:Nn #1 { \semantex_class_set_symbol:Nn #1 { ##2 } ##1 } } } } \exp_args:Nc\DeclareDocumentCommand{__semantex_new_object_of_\semantex_class_to_register:N #1:Nw}{mmmO{}} { % the command for creating a new object of class #1 % ##1 = command name, with backslash % ##2 = symbol % ##3 = options \semantex_new_object:NNn #1 { ##1 }{ \semantex_object_set_leftpar:Nn ##1 { ##2 } \semantex_object_set_rightpar:Nn ##1 { ##3 } \semantex_object_set_keys:Nn ##1 { ##4 } } % creates the object with name ##1 \DeclareDocumentCommand{##1}{og} { % the actual \##1 command \IfValueTF { ####1 } { \IfValueTF { ####2 } { \semantex_write_original_source_to_semtex_file:n { ##1 [ ####1] { ####2 } } \semantex_render_object:Nn ##1 { \semantex_object_do_output:N ##1 \semantex_object_set_keys:Nn ##1 { ####1 } \semantex_object_set_arg:Nn ##1 { ####2 } } } { \semantex_write_original_source_to_semtex_file:n { ##1 [ ####1] } \semantex_render_object:Nn ##1 { \semantex_object_do_output:N ##1 \semantex_object_set_keys:Nn ##1 { ####1 } } } } { \IfValueTF { ####2 } { \semantex_write_original_source_to_semtex_file:n { ##1 { ####2 } } \semantex_render_object:Nn ##1 { \semantex_object_do_output:N ##1 \semantex_object_set_arg:Nn ##1 { ####2 } } } { \semantex_write_original_source_to_semtex_file:n { ##1 } \semantex_render_object:Nn ##1 { } } } } } } \cs_set_eq:NN\NewDelimiterClass\semantex_new_delimiter_class:Nw %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % COMMANDS FOR CREATING AND HANDLING CLASSES AND OJBECTS % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Internally, objects and classes are both special cases of what we call "registers". % A register is a collection of data and key definitions, and different registers can % inherit from each other. Each register has a name which is a token list, with no % backslash. The class \ corresponds to the register "class_", % and the object \ corresponds to the register "object_". % Firstly, we need a couple of commands to convert class and object names into % register names. \cs_new:Npn\semantex_class_to_register:N#1 { % #1 = name of class class_\cs_to_str:N #1 } \cs_new:Npn\semantex_object_to_register:N#1 { % #1 = name of object object_\cs_to_str:N #1 } \DeclareDocumentCommand\NewObject { m } { % #1 = name of object \semantex_class_if_exist:NTF #1 { \use:c { __semantex_new_object_of_\semantex_class_to_register:N #1:Nw } } { \msg_error:nnn { semantex } { created_object_of_unknown_class } { #1 } } } \DeclareDocumentCommand\UseClassInCommand { mo } { \semantex_class_if_exist:NTF #1 { \IfValueTF { #2 } { \use:c { __semantex_make_object_of_\semantex_class_to_register:N #1_with_options:nnw } { \semantex_keys_set:nn { \semantex_class_to_register:N #1 } { #2 } } } { \use:c { __semantex_make_object_of_\semantex_class_to_register:N #1_with_options:nnw } {} } } { \msg_error:nnn { semantex } { used_unknown_class } { #1 } } } \cs_new_protected:Npn \semantex_new_register:nn#1#2 { % create new register % #1 = name of register % #2 = standard keyval setup \semantex_data_tl_provide:nn { #1 } { parent } \semantex_data_tl_set:nnn { #1 } { parent } { class_SemantexBaseObject } % The parent class by default is \SemantexBaseObject \cs_set:cpn { __semantex_data_cs_#1_valuekey:nn } ##1##2 % command controlling valuekeys { \semantex_valuekey:nnn { #1 } { ##1 } { ##2 } } \cs_set:cpn { __semantex_data_cs_#1_singlekey:n } ##1 % command controlling singlekeys { \semantex_singlekey:nn { #1 } { ##1 } } \cs_generate_variant:cn { __semantex_data_cs_#1_valuekey:nn } { nx } \cs_set:cpn { __semantex_data_cs_#1_singlekey_x:n } ##1 % command controlling executed singlekeys { \semantex_singlekey_x:nn { #1 } { ##1 } } % Now a similar collection of keyval commands for the *argument* \cs_set:cpn { __semantex_data_cs_#1_arg_valuekey:nn } ##1##2 { \semantex_arg_valuekey:nnn { #1 } { ##1 } { ##2 } } \cs_set:cpn { __semantex_data_cs_#1_arg_singlekey:n } ##1 { \semantex_arg_singlekey:nn { #1 } { ##1 } } \cs_generate_variant:cn { __semantex_data_cs_#1_arg_valuekey:nn } { nx } \cs_set:cpn { __semantex_data_cs_#1_arg_singlekey_x:n } ##1 { \semantex_arg_singlekey_x:nn { #1 } { ##1 } } % This is used to set up the register when creating it #2 } \cs_generate_variant:Nn \semantex_new_register:nn { xn } \cs_new_protected:Npn \semantex_new_class:Nn#1#2 { % create a new class % #1 = name of class % #2 = standard keyval setup \semantex_class_if_exist:NTF #1 { \msg_error:nnn { semantex } { class_already_defined } { #1 } } { \semantex_add_to_list_of_classes:N #1 \semantex_new_register:xn { \semantex_class_to_register:N #1 } { #2 } } } \cs_set_protected:Npn \semantex_new_object:NNn#1#2#3 { % create a new object % #1 = name of class % #2 = name of object % #3 = standard keyval setup \semantex_object_if_exist:NTF #2 { \msg_error:nnn { semantex } { object_already_defined } { #2 } } { \semantex_add_to_list_of_objects:N #2 \semantex_new_register:xn { \semantex_object_to_register:N #2 } { \semantex_object_set_class:Nn #2 { #1 } #3 } } } % The following commands are used in the code for creating class types: % Writing the actual content of the commands is not that much more % complicated, but I've decided to use them anyway to make it more % user-friendly to create your own class type. \cs_new_protected:Npn\semantex_class_set_symbol:Nn#1#2 { \semantex_valuekey:nnn { \semantex_class_to_register:N #1 } { symbol } { #2 } } \cs_new_protected:Npn\semantex_object_set_symbol:Nn#1#2 { \semantex_valuekey:nnn { \semantex_object_to_register:N #1 } { symbol } { #2 } } \cs_new_protected:Npn\semantex_class_do_output:N#1 { \semantex_data_bool_set_true:nn { \semantex_class_to_register:N #1 } { output } } \cs_new_protected:Npn\semantex_object_do_output:N#1 { \semantex_data_bool_set_true:nn { \semantex_object_to_register:N #1 } { output } } \cs_new_protected:Npn\semantex_class_set_keys:Nn#1#2 { \semantex_keys_set:nn { \semantex_class_to_register:N #1 } { #2 } } \cs_new_protected:Npn\semantex_object_set_keys:Nn#1#2 { \semantex_keys_set:nn { \semantex_object_to_register:N #1 } { #2 } } \cs_new_protected:Npn\semantex_class_set_arg:Nn#1#2 { \semantex_valuekey:nnn { \semantex_class_to_register:N #1 } { arg } { #2 } } \cs_new_protected:Npn\semantex_object_set_arg:Nn#1#2 { \semantex_valuekey:nnn { \semantex_object_to_register:N #1 } { arg } { #2 } } \cs_new_protected:Npn\semantex_class_set_degreedefault:Nn#1#2 { \semantex_valuekey:nnn { \semantex_class_to_register:N #1 } { degreedefault } { #2 } } \cs_new_protected:Npn\semantex_object_set_degreedefault:Nn#1#2 { \semantex_valuekey:nnn { \semantex_object_to_register:N #1 } { degreedefault } { #2 } } \cs_new_protected:Npn\semantex_class_use_bullet:N#1 { \semantex_singlekey:nn { \semantex_class_to_register:N #1 } { * } } \cs_new_protected:Npn\semantex_object_use_bullet:N#1 { \semantex_singlekey:nn { \semantex_object_to_register:N #1 } { * } } \cs_new_protected:Npn\semantex_class_use_double_bullet:N#1 { \semantex_singlekey:nn { \semantex_class_to_register:N #1 } { * } } \cs_new_protected:Npn\semantex_object_use_double_bullet:N#1 { \semantex_singlekey:nn { \semantex_object_to_register:N #1 } { * } } \cs_new_protected:Npn\semantex_class_set_leftpar:Nn#1#2 { \semantex_data_tl_set:nnn { \semantex_class_to_register:N #1 } { leftpar } { #2 } } \cs_new_protected:Npn\semantex_object_set_leftpar:Nn#1#2 { \semantex_data_tl_set:nnn { \semantex_object_to_register:N #1 } { leftpar } { #2 } } \cs_new_protected:Npn\semantex_class_set_rightpar:Nn#1#2 { \semantex_data_tl_set:nnn { \semantex_class_to_register:N #1 } { rightpar } { #2 } } \cs_new_protected:Npn\semantex_object_set_rightpar:Nn#1#2 { \semantex_data_tl_set:nnn { \semantex_object_to_register:N #1 } { rightpar } { #2 } } \cs_new_protected:Npn\semantex_object_set_class:Nn#1#2 { \semantex_data_class_set:nn { \semantex_object_to_register:N #1 } { #2 } } \seq_new:N \g__semantex_all_classes_seq % a list of all objects created \cs_new_protected:Npn\semantex_add_to_list_of_classes:N#1 { \seq_put_right:Nx\g__semantex_all_classes_seq { \semantex_class_to_register:N #1 } \semantex_write_class_declaration_to_semtex_file:n { #1 } } \cs_new_protected:Npn\semantex_class_if_exist:NTF#1#2#3 { \seq_if_in:NxTF\g__semantex_all_classes_seq { \semantex_class_to_register:N #1 } { #2 } { #3 } } \seq_new:N \g__semantex_all_objects_seq % a list of all objects created \cs_new_protected:Npn\semantex_add_to_list_of_objects:N#1 { \seq_put_right:Nx\g__semantex_all_objects_seq { \semantex_object_to_register:N #1 } \semantex_write_object_declaration_to_semtex_file:n { #1 } } \cs_new_protected:Npn\semantex_object_if_exist:NTF#1#2#3 { \seq_if_in:NxTF\g__semantex_all_objects_seq { \semantex_object_to_register:N #1 } { #2 } { #3 } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % COMMANDS FOR RENDERING REGISTERS % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \cs_generate_variant:Nn\tl_if_blank:nTF { xTF } \cs_new_protected:Npn \semantex_render_register:nn#1#2 { % the main command for rendering a register % #1 = name of register % #2 = options \group_begin: \cs_set:Nn\semantex_this: { #1 } #2 % This is where keys can be set up \semantex_parse:n { #1 } % Run the "parse" routine, i.e. run the collection of code that the user has added via the key "parseoptions" \semantex_data_bool_get:nnTF { #1 } { output } % Checks if the register is supposed to output { \semantex_inner_return:n { #1 } \tl_set:Nx \l__semantex_render_output_class_temp_tl { \semantex_data_tl_get:nn { #1 } { output } } % The output class \exp_args:NNx\cs_set:Nn\l__semantex_render_outputoptions_temp_cs:n { \semantex_data_tl_get_exp_not:nn { #1 } { outputoptions } } % \cs_set:Nx did not work here, as it changes ##1 to #1, which we don't want. \tl_set:Nn\l__semantex_render_outputoptions_temp_tl { \l__semantex_render_outputoptions_temp_cs:n } \tl_put_right:Nx \l__semantex_render_outputoptions_temp_tl { { \l__semantex_render_output_class_temp_tl } } \exp_args:NNo\tl_set:No \l__semantex_render_outputoptions_temp_tl { \l__semantex_render_outputoptions_temp_tl } % This was necessary, trust me. \semantex_data_int_if_positive:nnTF { #1 } { numberofarguments } % Checks if more than one argument has been received, i.e. whether we want to render any argument { \semantex_data_bool_get:nnTF { #1 } { leftargument } % Checks if left or right argument { \semantex_left_indices_pre_return:n { #1 } \semantex_left_arg_pre_return:n { #1 } \tl_set:Nx\l__semantex_render_symbol_temp_tl { \semantex_data_tl_get_exp_not:nn { #1 } { symbol } } % Stores the symbol in a temporary command \tl_set:Nx \l__semantex_render_temp_tl { \exp_not:c { __semantex_make_object_of_\l__semantex_render_output_class_temp_tl _with_options:nnw } % This is for outputting -- the command % \__semantex_make_object_of_class_???_with_options:nnw % makes a one-time object of class ??? and allows us to % immediately pass options to it { \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { upperputleft } { \semantex_data_tl_get_exp_not:nn { #1 } { upper } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { lowerputleft } { \semantex_data_tl_get_exp_not:nn { #1 } { lower } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { preupper } { \semantex_data_tl_get_exp_not:nn { #1 } { preupper } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { postupper } { \semantex_data_tl_get_exp_not:nn { #1 } { postupper } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { prelower } { \semantex_data_tl_get_exp_not:nn { #1 } { prelower } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { postlower } { \semantex_data_tl_get_exp_not:nn { #1 } { postlower } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { mathclass } { \semantex_data_tl_get_exp_not:nn { #1 } { mathclass } } \exp_not:V \l__semantex_render_outputoptions_temp_tl % These are the options we pass to the output class so that it % can eventually render it } { \exp_not:V \l__semantex_render_symbol_temp_tl } } } { \semantex_right_indices_pre_return:n { #1 } \semantex_right_arg_pre_return:n { #1 } \tl_set:Nx\l__semantex_render_symbol_temp_tl { \semantex_data_tl_get_exp_not:nn { #1 } { symbol } } % Stores the symbol in a temporary command \tl_set:Nx \l__semantex_render_temp_tl { \exp_not:c { __semantex_make_object_of_\l__semantex_render_output_class_temp_tl _with_options:nnw } % This is for outputting -- the command % \__semantex_make_object_of_class_???_with_options:nnw % makes a one-time object of class ??? and allows us to % immediately pass options to it { \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { upperleftputright } { \semantex_data_tl_get_exp_not:nn { #1 } { upperleft } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { lowerleftputright } { \semantex_data_tl_get_exp_not:nn { #1 } { lowerleft } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { preupperleft } { \semantex_data_tl_get_exp_not:nn { #1 } { preupperleft } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { postupperleft } { \semantex_data_tl_get_exp_not:nn { #1 } { postupperleft } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { prelowerleft } { \semantex_data_tl_get_exp_not:nn { #1 } { prelowerleft } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { postlowerleft } { \semantex_data_tl_get_exp_not:nn { #1 } { postlowerleft } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { heightphantom } { \semantex_data_tl_get_exp_not:nn { #1 } { heightphantom } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { slantingphantom } { \semantex_data_tl_get_exp_not:nn { #1 } { slantingphantom } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { mathclass } { \semantex_data_tl_get_exp_not:nn { #1 } { mathclass } } \exp_not:V \l__semantex_render_outputoptions_temp_tl % These are the options we pass to the output class so that it % can eventually render it } { \exp_not:V \l__semantex_render_symbol_temp_tl } } } } { \tl_set:Nx\l__semantex_render_symbol_temp_tl { \semantex_data_tl_get_exp_not:nn { #1 } { symbol } } % Stores the symbol in a temporary command \tl_set:Nx \l__semantex_render_temp_tl { \exp_not:c { __semantex_make_object_of_\l__semantex_render_output_class_temp_tl _with_options:nnw } % This is for outputting -- the command % \__semantex_make_object_of_class_???_with_options:nnw % makes a one-time object of class ??? and allows us to % immediately pass options to it { \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { upperputleft } { \semantex_data_tl_get_exp_not:nn { #1 } { upper } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { lowerputleft } { \semantex_data_tl_get_exp_not:nn { #1 } { lower } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { upperleftputright } { \semantex_data_tl_get_exp_not:nn { #1 } { upperleft } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { lowerleftputright } { \semantex_data_tl_get_exp_not:nn { #1 } { lowerleft } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { preupper } { \semantex_data_tl_get_exp_not:nn { #1 } { preupper } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { postupper } { \semantex_data_tl_get_exp_not:nn { #1 } { postupper } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { prelower } { \semantex_data_tl_get_exp_not:nn { #1 } { prelower } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { postlower } { \semantex_data_tl_get_exp_not:nn { #1 } { postlower } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { preupperleft } { \semantex_data_tl_get_exp_not:nn { #1 } { preupperleft } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { postupperleft } { \semantex_data_tl_get_exp_not:nn { #1 } { postupperleft } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { prelowerleft } { \semantex_data_tl_get_exp_not:nn { #1 } { prelowerleft } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { postlowerleft } { \semantex_data_tl_get_exp_not:nn { #1 } { postlowerleft } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { heightphantom } { \semantex_data_tl_get_exp_not:nn { #1 } { heightphantom } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { slantingphantom } { \semantex_data_tl_get_exp_not:nn { #1 } { slantingphantom } } \exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl } { mathclass } { \semantex_data_tl_get_exp_not:nn { #1 } { mathclass } } \exp_not:V \l__semantex_render_outputoptions_temp_tl % These are the options we pass to the output class so that it % can eventually render it } { \exp_not:V \l__semantex_render_symbol_temp_tl } } } } { \semantex_pre_return:n { #1 } % Performs the pre_return routine, i.e. adds all remaining indices and arguments to the symbol \tl_if_blank:xTF { \semantex_data_tl_get_exp_not:nn { #1 } { mathclass } } % Checks whether the mathclass register has been declared -- this is % where you store \mathord, \mathbin, \mathrel, etc., if you want % the object to be eventually wrapped in this. { \tl_set:Nx\l__semantex_render_temp_tl { \semantex_data_tl_get_exp_not:nn { #1 } { symbol } } } { \tl_set:Nx\l__semantex_render_temp_tl { \semantex_data_tl_get_exp_not:nn { #1 } { mathclass } { \semantex_data_tl_get_exp_not:nn { #1 } { symbol } } } } \group_begin: \semantex_write_output_to_semtex_file_V:N \l__semantex_render_temp_tl % Adds the output to the .semtex file, if this has been turned on, % which it is not by default. \group_end: } \exp_last_unbraced:NV \group_end: \l__semantex_render_temp_tl % This neat trick allows outputting to different classes to work as expected } \cs_generate_variant:Nn \semantex_render_register:nn { xn } \cs_new_protected:Npn\semantex_render_class:Nn#1#2 % a front-end command { \semantex_render_register:xn { \semantex_class_to_register:N #1 } { #2 } } \cs_new_protected:Npn\semantex_render_object:Nn#1#2 { \semantex_render_register:xn { \semantex_object_to_register:N #1 } { #2 } % Actually, it seems to all still work out fine with n-type % instead of x-type, but better be sure } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % COMMANDS FOR HANDLING PARENTHESES % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \DeclareDocumentCommand\SemantexDelimiterSize { } { \semantex_write_original_source_to_semtex_file:n { \SemantexDelimiterSize } \semantex_write_output_to_semtex_file_V:N \l_semantex_delimiter_size_temp_tl \l_semantex_delimiter_size_temp_tl } \DeclareDocumentCommand\RecordSemantexDelimiterSize { } { \semantex_write_output_to_semtex_file_V:N \l_semantex_delimiter_size_temp_tl } \DeclareDocumentCommand\SemantexDelimiterSizeNoRecord { } { \l_semantex_delimiter_size_temp_tl } \DeclareDocumentCommand\SemantexMathOpen { mm } { \group_begin: \tl_set:Nn\l_semantex_delimiter_size_temp_tl { #1 } \str_if_eq:nnF { #2 } { . } { \mathopen #1 #2 } } \DeclareDocumentCommand\SemantexMathClose { mm } { \str_if_eq:nnF { #2 } { . } { \mathclose #1 #2 } \group_end: } \DeclareDocumentCommand\SemantexMathOpenAuto { m } { \group_begin: \tl_set:Nn\l_semantex_delimiter_size_temp_tl { \middle } \SemantexLeft #1 } \DeclareDocumentCommand\SemantexMathCloseAuto { m } { \SemantexRight #1 \group_end: } \DeclareDocumentCommand\SemantexMathOpenNoPar { } { \group_begin: \tl_clear:N\l_semantex_delimiter_size_temp_tl } \DeclareDocumentCommand\SemantexMathCloseNoPar { } { \group_end: } \cs_new_protected:Npn \semantex_parentheses_store:nN#1#2 { \semantex_data_tl_get_store:nnN { #1 } { parsize } \l__semantex_parentheses_store_temp_tl \str_case:VnF { \l__semantex_parentheses_store_temp_tl } % This is where \big,\Big, etc. go. { { normal } { \tl_set:Nx #2 { \exp_not:N \SemantexMathOpen { } \semantex_data_tl_get_exp_not:nn { #1 } { leftpar } \semantex_data_tl_get_exp_not:nn { #1 } { prearg } \semantex_data_tl_get_exp_not:nn { #1 } { arg } \semantex_data_tl_get_exp_not:nn { #1 } { postarg } \exp_not:N \SemantexMathClose { } \semantex_data_tl_get_exp_not:nn { #1 } { rightpar } } } { auto } { \tl_set:Nx #2 { \exp_not:N \SemantexMathOpenAuto \semantex_data_tl_get_exp_not:nn { #1 } { leftpar } \semantex_data_tl_get_exp_not:nn { #1 } { prearg } \semantex_data_tl_get_exp_not:nn { #1 } { arg } \semantex_data_tl_get_exp_not:nn { #1 } { postarg } \exp_not:N \SemantexMathCloseAuto \semantex_data_tl_get_exp_not:nn { #1 } { rightpar } } } { * } { \tl_set:Nx #2 { \exp_not:N \SemantexMathOpenAuto \semantex_data_tl_get_exp_not:nn { #1 } { leftpar } \semantex_data_tl_get_exp_not:nn { #1 } { prearg } \semantex_data_tl_get_exp_not:nn { #1 } { arg } \semantex_data_tl_get_exp_not:nn { #1 } { postarg } \exp_not:N \SemantexMathCloseAuto \semantex_data_tl_get_exp_not:nn { #1 } { rightpar } } } } { \tl_set:Nx #2 { \exp_not:N \SemantexMathOpen \exp_not:V \l__semantex_parentheses_store_temp_tl \semantex_data_tl_get_exp_not:nn { #1 } { leftpar } \semantex_data_tl_get_exp_not:nn { #1 } { prearg } \semantex_data_tl_get_exp_not:nn { #1 } { arg } \semantex_data_tl_get_exp_not:nn { #1 } { postarg } \exp_not:N \SemantexMathClose \exp_not:V \l__semantex_parentheses_store_temp_tl \semantex_data_tl_get_exp_not:nn { #1 } { rightpar } } } } \cs_generate_variant:Nn \str_case:nnF { VnF } \cs_generate_variant:Nn \str_if_eq:nnF { xnF } \cs_new_protected:Npn \semantex_no_parentheses_store:nN#1#2 % The central command for handling the rendering of arguments with no parentheses around { \tl_set:Nx#2 { \exp_not:N\SemantexMathOpenNoPar \semantex_data_tl_get_exp_not:nn { #1 } { prearg } \semantex_data_tl_get_exp_not:nn { #1 } { arg } \semantex_data_tl_get_exp_not:nn { #1 } { postarg } \exp_not:N\SemantexMathCloseNoPar } } \cs_new_protected:Npn \__semantex_symbol_parentheses_store:nnnnN#1#2#3#4#5 % The central command handling the rendering of symbol parentheses { \str_case:nnF { #1 } % This is where \big,\Big, etc. go. { { normal } { \tl_set:Nn#5 { #4 } \str_if_eq:nnF { #2 } { . } { \tl_put_left:Nn#5 { \mathopen #2 } } \str_if_eq:nnF { #3 } { . } { \tl_put_right:Nn#5 { \mathclose #3 } } } { auto } { \tl_set:Nn#5 { \SemantexLeft #2 #4 \SemantexRight #3 } } { * } { \tl_set:Nn#5 { \SemantexLeft #2 #4 \SemantexRight #3 } } } { \tl_set:Nn#5 { \mathopen #1 #2 #4 \mathclose #1 #3 } } } \cs_generate_variant:Nn \__semantex_symbol_parentheses_store:nnnnN { xxxxN } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % COMMANDS FOR THE RETURN ROUTINES % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \cs_new_protected:Npn\semantex_return:n#1 { % This is an umbrella key that runs all of the three % return routines, innerreturn, rightreturn, and leftreturn \semantex_inner_return:n { #1 } \semantex_left_index_return:n { #1 } \semantex_left_arg_return:n { #1 } \semantex_right_index_return:n { #1 } \semantex_right_arg_return:n { #1 } } \cs_new_protected:Npn\semantex_pre_return:n#1 { % The pre-return routines are like the return routines, except % they do not reset all the parameters we need. This is only % intended for use when rendering and not outputting, as % resetting parameters in this case would just waste % time. \semantex_inner_pre_return:n { #1 } \semantex_left_indices_pre_return:n { #1 } \semantex_left_arg_pre_return:n { #1 } \semantex_right_indices_pre_return:n { #1 } \semantex_right_arg_pre_return:n { #1 } } \cs_new_protected:Npn\semantex_inner_return:n#1 { \semantex_inner_pre_return:n { #1 } \semantex_data_seq_clear:nn { #1 } { commands_sequence } } \cs_new_protected:Npn\semantex_inner_pre_return:n#1 { % This adds all of the commands added via the command key % to the symbol \semantex_data_seq_get_store:nnN { #1 } { commands_sequence } \l__semantex_data_seq_commands_sequence_temp \seq_map_inline:Nn \l__semantex_data_seq_commands_sequence_temp { \semantex_data_tl_set:nnx { #1 } { symbol } { \exp_not:N ##1 { \semantex_data_tl_get_exp_not:nn { #1 } { symbol } } } } \semantex_data_seq_clear:nn { #1 } { commands_sequence } } \cs_new_protected:Npn\semantex_right_return:n#1 { \semantex_inner_return:n { #1 } \semantex_right_index_return:n { #1 } \semantex_right_arg_return:n { #1 } } \cs_new_protected:Npn\semantex_right_index_return:n#1 { \semantex_right_indices_pre_return:n { #1 } \semantex_data_tl_clear:nn { #1 } { upper } \semantex_data_tl_clear:nn { #1 } { preupper } \semantex_data_tl_clear:nn { #1 } { postupper } \semantex_data_bool_set_false:nn { #1 } { nextupperwithsep } \semantex_data_int_clear:nn { #1 } { numberofupperindices } \semantex_data_tl_clear:nn { #1 } { lower } \semantex_data_tl_clear:nn { #1 } { prelower } \semantex_data_tl_clear:nn { #1 } { postlower } \semantex_data_bool_set_false:nn { #1 } { nextlowerwithsep } \semantex_data_int_clear:nn { #1 } { numberoflowerindices } } \cs_new_protected:Npn\semantex_right_indices_pre_return:n#1 { \_semantex_right_index_return_store:nN { #1 } \l__semantex_rightreturn_right_indices_temp \semantex_data_tl_put_right:nnx { #1 } { symbol } { \exp_not:V \l__semantex_rightreturn_right_indices_temp } } \cs_new_protected:Npn \_semantex_right_index_return_store:nN#1#2 { \tl_set:Nn#2{} \semantex_data_int_if_positive:nnTF { #1 } { numberoflowerindices } { \tl_put_right:Nx#2 { \sb{ \semantex_data_tl_get_exp_not:nn { #1 } { prelower } \semantex_data_tl_get_exp_not:nn { #1 } { lower } \semantex_data_tl_get_exp_not:nn { #1 } { postlower } } } } { % do nothing } \semantex_data_int_if_positive:nnTF { #1 } { numberofupperindices } { \tl_put_right:Nx#2 { \sp{ \semantex_data_tl_get_exp_not:nn { #1 } { preupper } \semantex_data_tl_get_exp_not:nn { #1 } { upper } \semantex_data_tl_get_exp_not:nn { #1 } { postupper } } } } { % do nothing } } \cs_new_protected:Npn\semantex_left_return:n#1 { \semantex_inner_return:n { #1 } \semantex_left_index_return:n { #1 } \semantex_left_arg_return:n { #1 } } \cs_new_protected:Npn\semantex_left_index_return:n#1 { \semantex_left_indices_pre_return:n { #1 } \semantex_data_tl_clear:nn { #1 } { upperleft } \semantex_data_tl_clear:nn { #1 } { preupperleft } \semantex_data_tl_clear:nn { #1 } { postupperleft } \semantex_data_bool_set_false:nn { #1 } { nextupperleftwithsep } \semantex_data_int_clear:nn { #1 } { numberofupperleftindices } \semantex_data_tl_clear:nn { #1 } { lowerleft } \semantex_data_tl_clear:nn { #1 } { prelowerleft } \semantex_data_tl_clear:nn { #1 } { postlowerleft } \semantex_data_bool_set_false:nn { #1 } { nextlowerleftwithsep } \semantex_data_int_clear:nn { #1 } { numberoflowerleftindices } \semantex_data_tl_set:nnx { #1 } { heightphantom } { \semantex_data_tl_get_exp_not:nn { #1 } { symbol } } \semantex_data_tl_clear:nn { #1 } { slantingphantom } } \cs_new_protected:Npn\semantex_left_indices_pre_return:n#1 { \_semantex_left_index_return_store:nN { #1 } \l__semantex_leftreturn_left_indices_temp \semantex_data_tl_put_left:nnx { #1 } { symbol } { \exp_not:V \l__semantex_leftreturn_left_indices_temp } } \cs_new_protected:Npn \_semantex_left_index_return_store:nN#1#2 { \tl_set:Nn#2{} \semantex_data_int_if_positive:nnTF { #1 } { numberofupperleftindices } { \tl_put_right:Nn #2 { \manualleftindex } \tl_put_right:Nx #2 { { \semantex_data_tl_get_exp_not:nn { #1 } { heightphantom } } { \semantex_data_tl_get_exp_not:nn { #1 } { slantingphantom} } { \semantex_data_tl_get_exp_not:nn { #1 } { preupperleft } \semantex_data_tl_get_exp_not:nn { #1 } { upperleft } \semantex_data_tl_get_exp_not:nn { #1 } { postupperleft } } } \semantex_data_int_if_positive:nnTF { #1 } { numberoflowerleftindices } { \tl_put_right:Nx#2 { { \semantex_data_tl_get_exp_not:nn { #1 } { prelowerleft } \semantex_data_tl_get_exp_not:nn { #1 } { lowerleft } \semantex_data_tl_get_exp_not:nn { #1 } { postlowerleft } } } } { \tl_put_right:Nn#2 { { } } } } { \semantex_data_int_if_positive:nnTF { #1 } { numberoflowerleftindices } { \tl_put_right:Nn #2 { \manualleftindex } \tl_put_right:Nx #2 { { \semantex_data_tl_get_exp_not:nn { #1 } { heightphantom } } { \semantex_data_tl_get_exp_not:nn { #1 } { slantingphantom} } { } { \semantex_data_tl_get_exp_not:nn { #1 } { prelowerleft } \semantex_data_tl_get_exp_not:nn { #1 } { lowerleft } \semantex_data_tl_get_exp_not:nn { #1 } { postlowerleft } } } } { % do nothing } } } \cs_new_protected:Npn\semantex_right_arg_return:n#1 { \semantex_data_bool_get:nnTF { #1 } { leftargument } { % do nothing } { \_semantex_arg_return_store:nN { #1 } \l__semantex_rightreturn_arg_temp \semantex_data_tl_put_right:nnx { #1 } { symbol } { \exp_not:V \l__semantex_rightreturn_arg_temp } \semantex_data_tl_clear:nn { #1 } { arg } \semantex_data_tl_clear:nn { #1 } { prearg } \semantex_data_tl_clear:nn { #1 } { postarg } \semantex_data_int_clear:nn { #1 } { numberofarguments } \semantex_data_bool_set_false:nn { #1 } { nextargwithsep } } } \cs_new_protected:Npn\semantex_right_arg_pre_return:n#1 { \semantex_data_bool_get:nnTF { #1 } { leftargument } { % do nothing } { \_semantex_arg_return_store:nN { #1 } \l__semantex_rightreturn_arg_temp \semantex_data_tl_put_right:nnx { #1 } { symbol } { \exp_not:V \l__semantex_rightreturn_arg_temp } } } \cs_new_protected:Npn\semantex_left_arg_return:n#1 { \semantex_data_bool_get:nnTF { #1 } { leftargument } { \_semantex_arg_return_store:nN { #1 } \l__semantex_leftreturn_arg_temp \semantex_data_tl_put_left:nnx { #1 } { symbol } { \exp_not:V \l__semantex_leftreturn_arg_temp } \semantex_data_tl_clear:nn { #1 } { arg } \semantex_data_tl_clear:nn { #1 } { prearg } \semantex_data_tl_clear:nn { #1 } { postarg } \semantex_data_int_clear:nn { #1 } { numberofarguments } \semantex_data_bool_set_false:nn { #1 } { nextargwithsep } } { % do nothing } } \cs_new_protected:Npn\semantex_left_arg_pre_return:n#1 { \semantex_data_bool_get:nnTF { #1 } { leftargument } { \_semantex_arg_return_store:nN { #1 } \l__semantex_leftreturn_arg_temp \semantex_data_tl_put_left:nnx { #1 } { symbol } { \exp_not:V \l__semantex_leftreturn_arg_temp } } { % do nothing } } \cs_new_protected:Npn\semantex_arg_return:n#1 { \semantex_arg_pre_return:n { #1 } \semantex_data_tl_clear:nn { #1 } { arg } \semantex_data_tl_clear:nn { #1 } { prearg } \semantex_data_tl_clear:nn { #1 } { postarg } \semantex_data_int_clear:nn { #1 } { numberofarguments } \semantex_data_bool_set_false:nn { #1 } { nextargwithsep } } \cs_new_protected:Npn\semantex_arg_pre_return:n#1 { \semantex_data_bool_get:nnTF { #1 } { leftargument } { \_semantex_arg_return_store:nN { #1 } \l__semantex_leftreturn_arg_temp \semantex_data_tl_put_left:nnx { #1 } { symbol } { \exp_not:V \l__semantex_leftreturn_arg_temp } } { \_semantex_arg_return_store:nN { #1 } \l__semantex_rightreturn_arg_temp \semantex_data_tl_put_right:nnx { #1 } { symbol } { \exp_not:V \l__semantex_rightreturn_arg_temp } } } \cs_new_protected:Npn \_semantex_arg_return_store:nN#1#2 { \semantex_data_bool_get:nnTF { #1 } { par } { \semantex_data_int_if_positive:nnTF { #1 } { numberofarguments } { \semantex_parentheses_store:nN { #1 } #2 } { \tl_set:Nn#2{} } } { \semantex_data_bool_get:nnTF { #1 } { flexpar } { \semantex_data_int_if_greater_than_one:nnTF { #1 } { numberofarguments } { \semantex_parentheses_store:nN { #1 } #2 } { \semantex_data_int_if_positive:nnTF { #1 } { numberofarguments } { \semantex_no_parentheses_store:nN { #1 } #2 } { \tl_set:Nn#2{} } } } { \semantex_data_int_if_positive:nnTF { #1 } { numberofarguments } { \semantex_no_parentheses_store:nN { #1 } #2 } { \tl_set:Nn#2{} } } } } \cs_generate_variant:Nn \__semantex_parentheses_store:nnnnN { xxxxN , ooooN } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % COMMANDS HADNLING "spar" -- SYMBOL PARENTHESES % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \cs_new_protected:Npn\semantex_spar:nn#1#2 { % Abbreviation for "symbol parentheses" % Adds parentheses around the current symbol \semantex_return:n { #1 } \tl_if_blank:nTF { #2 } { \semantex_data_tl_get_store:nnN { #1 } { sparsize } \l__semantex_spar_sparsize_temp_tl } { \tl_set:Nn \l__semantex_spar_sparsize_temp_tl { #2 } } \__semantex_symbol_parentheses_store:xxxxN { \exp_not:V\l__semantex_spar_sparsize_temp_tl } { \semantex_data_tl_get_exp_not:nn { #1 } { leftspar } } { \semantex_data_tl_get_exp_not:nn { #1 } { rightspar } } { \semantex_data_tl_get_exp_not:nn { #1 } { symbol } } \l__semantex_spar_temp_tl \semantex_data_tl_set:nnx { #1 } { symbol } { \exp_not:V \l__semantex_spar_temp_tl } \semantex_spar_set_height_phantom_to_parentheses_size:nx { #1 } { \exp_not:V \l__semantex_spar_sparsize_temp_tl } } \cs_new_protected:Npn\semantex_other_spar:nnn#1#2#3 { \semantex_return:n { #1 } \semantex_data_tl_get_store:nnN { #1 } { sparsize } \l__semantex_other_spar_sparsize_temp_tl \__semantex_symbol_parentheses_store:xxxxN { \exp_not:V \l__semantex_other_spar_sparsize_temp_tl } { \exp_not:n { #2 } } { \exp_not:n { #3 } } { \semantex_data_tl_get_exp_not:nn { #1 } { symbol } } \l__semantex_other_spar_temp_tl \semantex_data_tl_set:nnx { #1 } { symbol } { \exp_not:V \l__semantex_other_spar_temp_tl } \semantex_spar_set_height_phantom_to_parentheses_size:nx { #1 } { \exp_not:V \l__semantex_other_spar_sparsize_temp_tl } } \cs_new_protected:Npn\semantex_other_spar_with_size:nnnn#1#2#3#4 { \semantex_return:n { #1 } \__semantex_symbol_parentheses_store:xxxxN { \exp_not:n { #4 } } { \exp_not:n { #2 } } { \exp_not:n { #3 } } { \semantex_data_tl_get_exp_not:nn { #1 } { symbol } } \l__semantex_other_spar_with_size_temp_tl \semantex_data_tl_set:nnx { #1 } { symbol } { \exp_not:V \l__semantex_other_spar_with_size_temp_tl } \semantex_spar_set_height_phantom_to_parentheses_size:nn { #1 } { #4 } } \cs_new_protected:Npn\semantex_spar_set_height_phantom_to_parentheses_size:nn#1#2 { % #1 = register % #2 = parentheses size \str_case:nnF { #2 } { { normal } { \semantex_data_tl_set:nnn { #1 } { heightphantom } { \vert } } { auto } { \semantex_data_tl_set:nnx { #1 } { heightphantom } { \semantex_data_tl_get_exp_not:nn { #1 } { symbol } } } { * } { \semantex_data_tl_set:nnx { #1 } { heightphantom } { \semantex_data_tl_get_exp_not:nn { #1 } { symbol } } } } { \semantex_data_tl_set:nnx { #1 } { heightphantom } { \exp_not:n { #2 \vert } } } } \cs_generate_variant:Nn \semantex_spar_set_height_phantom_to_parentheses_size:nn { nx } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % COMMANDS FOR MODIFYING AND OBTAINING DATA % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % COMMANDS FOR HANDLING THE PARENT OF A CLASS/OBJECT: \cs_new:Npn \semantex_data_parent_get:n#1 { % #1 = register % A command to get the parent of an object \use:c { g__semantex_data_tl_#1_parent } } \cs_new_protected:Npn \semantex_data_parent_set:nn#1#2 { % #1 = reigster % Sets the parent \semantex_class_if_exist:NTF { #2 } { \tl_set:cx { g__semantex_data_tl_#1_parent } { \semantex_class_to_register:N #2 } } { \semantex_msg_error:nnnn { #1 } { class_not_found } { parent } { #2 } } } \cs_new_protected:Npn \semantex_data_class_set:nn#1#2 { % #1 = register % Sets the parent to be a class \semantex_class_if_exist:NTF { #2 } { \tl_set:cx { g__semantex_data_tl_#1_parent } { \semantex_class_to_register:N #2 } } { \semantex_msg_error:nnnn { #1 } { class_not_found } { class } { #2 } } } \cs_generate_variant:Nn \semantex_data_class_set:nn { xn } \cs_new_protected:Npn \semantex_data_copy_object:nn#1#2 { \semantex_object_if_exist:NTF { #2 } { \tl_set:cx { g__semantex_data_tl_#1_parent } { \semantex_object_to_register:N #2 } } { \semantex_msg_error:nnnn { #1 } { object_not_found } { copy } { #2 } } } % COMMANDS FOR HANDLING DATA CONSISTING OF TOKEN LISTS \cs_new:Npn \semantex_data_tl_get:nn#1#2 { % #1 = name of object % #2 = the data to get \__semantex_data_tl_get_auxiliary:nnn { #1 } { #2 } { #1 } } \cs_new:Npn \__semantex_data_tl_get_auxiliary:nnn#1#2#3 { % #1 = name of register % #2 = the data to get % #3 = the original register, used for error messaging \tl_if_exist:cTF { g__semantex_data_tl_#1_#2 } { \use:c { g__semantex_data_tl_#1_#2 } } { \str_if_eq:nnTF { #1 } { class_SemantexBaseObject } { \semantex_msg_error:nnx { #3 } { data_tl_not_found } { #2 } } { \__semantex_data_tl_get_auxiliary:fnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 } } } } \cs_generate_variant:Nn \__semantex_data_tl_get_auxiliary:nnn { fnn } \cs_new:Npn \semantex_data_tl_get_exp_not:nn#1#2 { % #1 = name of register % #2 = the data to get \__semantex_data_tl_get_exp_not_auxiliary:nnn { #1 } { #2 } { #1 } } \cs_new:Npn \__semantex_data_tl_get_exp_not_auxiliary:nnn#1#2#3 { % #1 = name of register % #2 = the data to get % #3 = the original register, used for error messaging \tl_if_exist:cTF { g__semantex_data_tl_#1_#2 } { \exp_not:v { g__semantex_data_tl_#1_#2 } } { \str_if_eq:nnTF { #1 } { class_SemantexBaseObject } { \semantex_msg_error:nnx { #3 } { data_tl_not_found } { #2 } } { \__semantex_data_tl_get_exp_not_auxiliary:fnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 } } } } \cs_generate_variant:Nn \__semantex_data_tl_get_exp_not_auxiliary:nnn { fnn } \cs_new_protected:Npn \semantex_data_tl_get_store:nnN#1#2#3 { % #1 = name of object % #2 = the data to get % #3 = where to store it \__semantex_data_tl_get_store_auxiliary:nnNn { #1 } { #2 } #3 { #1 } } \cs_new_protected:Npn \__semantex_data_tl_get_store_auxiliary:nnNn#1#2#3#4 { % #1 = name of register % #2 = the data to get % #3 = where to store it % #4 = name of original register, for error message purposes \tl_if_exist:cTF { g__semantex_data_tl_#1_#2 } { \tl_set_eq:Nc #3 { g__semantex_data_tl_#1_#2 } } { \str_if_eq:nnTF { #1 } { class_SemantexBaseObject } { \semantex_msg_error:nnx { #4 } { data_tl_not_found } { #2 } } { \__semantex_data_tl_get_store_auxiliary:fnNn { \semantex_data_parent_get:n { #1 } } { #2 } #3 { #4 } } } } \cs_generate_variant:Nn \__semantex_data_tl_get_store_auxiliary:nnNn { fnNn } \cs_generate_variant:Nn \semantex_data_tl_get_store:nnN { nnc } \cs_new_protected:Npn\semantex_data_tl_provide:nn#1#2 { % #1 = name of register % #2 = the data to provide \tl_if_exist:cF { g__semantex_data_tl_#1_#2 } { \tl_set:cn { g__semantex_data_tl_#1_#2 } {} } } \cs_new_protected:Npn\semantex_data_tl_inherit:nn#1#2 { % #1 = register % #2 = piece of token list data % Takes the data #2 from the parent of #1 and saves it locally % to the object #1. After this, no more inheritance is taking place % from the parent, and the data can be changed locally on the level % of #1. \tl_if_exist:cF { g__semantex_data_tl_#1_#2 } { \semantex_data_tl_get_store:nnc { \semantex_data_parent_get:n { #1 } } { #2 } { g__semantex_data_tl_#1_#2 } } } \cs_new_protected:Npn \semantex_data_tl_set:nnn#1#2#3 { \tl_set:cn { g__semantex_data_tl_#1_#2 } { #3 } } \cs_generate_variant:Nn \semantex_data_tl_set:nnn { nnx } \cs_new_protected:Npn \semantex_data_tl_put_right:nnn#1#2#3 { \semantex_data_tl_inherit:nn { #1 } { #2 } \tl_put_right:cn { g__semantex_data_tl_#1_#2 } { #3 } } \cs_generate_variant:Nn \semantex_data_tl_put_right:nnn { nnx } \cs_new_protected:Npn \semantex_data_tl_put_left:nnn#1#2#3 { \semantex_data_tl_inherit:nn { #1 } { #2 } \tl_put_left:cn { g__semantex_data_tl_#1_#2 } { #3 } } \cs_generate_variant:Nn \semantex_data_tl_put_left:nnn { nnx } \cs_new_protected:Npn \semantex_data_tl_clear:nn#1#2 { \semantex_data_tl_provide:nn { #1 } { #2 } \tl_clear:c { g__semantex_data_tl_#1_#2 } } % DATA OF TYPE INTEGER: \cs_new_protected:Npn\semantex_data_int_provide:nn#1#2 { \bool_if_exist:cTF { g__semantex_data_int_#1_#2_bool_if_provided } { \bool_if:cF { g__semantex_data_int_#1_#2_bool_if_provided } { \bool_set_true:c { g__semantex_data_int_#1_#2_bool_if_provided } } } { \bool_new:c { g__semantex_data_int_#1_#2_bool_if_provided } \bool_set_true:c { g__semantex_data_int_#1_#2_bool_if_provided } \int_new:c { g__semantex_data_int_#1_#2 } } } \cs_new_protected:Npn\semantex_data_int_inherit:nn#1#2 { \bool_if_exist:cTF { g__semantex_data_int_#1_#2_bool_if_provided } { \bool_if:cF { g__semantex_data_int_#1_#2_bool_if_provided } { \semantex_data_int_get_store:nnc { \semantex_data_parent_get:n { #1 } } { #2 } { g__semantex_data_int_#1_#2 } \bool_set_true:c { g__semantex_data_int_#1_#2_bool_if_provided } } } { \bool_new:c { g__semantex_data_int_#1_#2_bool_if_provided } \bool_set_true:c { g__semantex_data_int_#1_#2_bool_if_provided } \int_new:c { g__semantex_data_int_#1_#2 } \semantex_data_int_get_store:nnc { \semantex_data_parent_get:n { #1 } } { #2 } { g__semantex_data_int_#1_#2 } } } \cs_new:Npn \semantex_data_int_get:nn#1#2{ % #1 = name of object % #2 = the integer to get \__semantex_data_int_get_auxiliary:nnn { #1 } { #2 } { #1 } } \cs_new:Npn \__semantex_data_int_get_auxiliary:nnn#1#2#3{ % #1 = name of object % #2 = the integer to get % #3 = stores the original register, for error message purposes \bool_if_exist:cTF { g__semantex_data_int_#1_#2_bool_if_provided } { \bool_if:cTF { g__semantex_data_int_#1_#2_bool_if_provided } { \int_use:c { g__semantex_data_int_#1_#2 } } { \str_if_eq:nnTF { #1 } { class_SemantexBaseObject } { \semantex_msg_error:nnx { #3 } { data_int_not_found } { #2 } } { \__semantex_data_int_get_auxiliary:fnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 } } } } { \str_if_eq:nnTF { #1 } { class_SemantexBaseObject } { \semantex_msg_error:nnx { #3 } { data_int_not_found } { #2 } } { \__semantex_data_int_get_auxiliary:fnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 } } } } \cs_generate_variant:Nn \__semantex_data_int_get_auxiliary:nnn { fnn } \cs_new_protected:Npn \semantex_data_int_get_store:nnN#1#2#3{ % #1 = name of object % #2 = the integer to get % #3 = the command to store it in \__semantex_data_int_get_store_auxiliary:nnNn { #1 } { #2 } #3 { #1 } } \cs_new_protected:Npn\__semantex_data_int_get_store_auxiliary:nnNn#1#2#3#4{ % #1 = name of object % #2 = the integer to get % #3 = the command to store it in \bool_if_exist:cTF { g__semantex_data_int_#1_#2_bool_if_provided } { \bool_if:cTF { g__semantex_data_int_#1_#2_bool_if_provided } { \int_set_eq:Nc#3 { g__semantex_data_int_#1_#2 } } { \str_if_eq:nnTF { #1 } { class_SemantexBaseObject } { \semantex_msg_error:nnx { #4 } { data_int_not_found } { #2 } } { \__semantex_data_int_get_store_auxiliary:fnNn { \semantex_data_parent_get:n { #1 } } { #2 } #3 { #4 } } } } { \str_if_eq:nnTF { #1 } { class_SemantexBaseObject } { \semantex_msg_error:nnx { #4 } { data_int_not_found } { #2 } } { \__semantex_data_int_get_store_auxiliary:fnNn { \semantex_data_parent_get:n { #1 } } { #2 } #3 { #4 } } } } \cs_generate_variant:Nn \__semantex_data_int_get_store_auxiliary:nnNn { fnNn } \cs_generate_variant:Nn \semantex_data_int_get_store:nnN { nnc } \cs_new_protected:Npn\semantex_data_int_incr:nn#1#2 { \semantex_data_int_inherit:nn { #1 } { #2 } \int_incr:c { g__semantex_data_int_#1_#2 } } \cs_new_protected:Npn\semantex_data_int_set:nnn#1#2#3 { \semantex_data_int_provide:nn { #1 } { #2 } \int_set:cn { g__semantex_data_int_#1_#2 } { #3 } } \cs_new_protected:Npn\semantex_data_int_if_positive:nnTF#1#2#3#4 { \int_compare:nNnTF { \semantex_data_int_get:nn { #1 } { #2 } } > { 0 } { #3 } { #4 } } \cs_new_protected:Npn\semantex_data_int_if_greater_than_one:nnTF#1#2#3#4 { \int_compare:nNnTF { \semantex_data_int_get:nn { #1 } { #2 } } > { 1 } { #3 } { #4 } } \cs_new_protected:Npn\semantex_data_int_clear:nn#1#2 { \semantex_data_int_provide:nn { #1 } { #2 } \int_zero:c { g__semantex_data_int_#1_#2 } } % COMMANDS FOR HANDLING DATA OF SEQUENCE TYPE \cs_new_protected:Npn \semantex_data_seq_get_store:nnN#1#2#3{ % #1 = name of object % #2 = the sequence to get % #3 = the command to store it in \bool_if_exist:cTF { g__semantex_data_seq_#1_#2_bool_if_provided } { \bool_if:cTF { g__semantex_data_seq_#1_#2_bool_if_provided } { \seq_set_eq:Nc#3 { g__semantex_data_seq_#1_#2 } } { \semantex_data_seq_get_store:nnN { \semantex_data_parent_get:n { #1 } } { #2 } #3 } } { \semantex_data_seq_get_store:nnN { \semantex_data_parent_get:n { #1 } } { #2 } #3 } } \cs_generate_variant:Nn \semantex_data_seq_get_store:nnN { nnc } \cs_new_protected:Npn\semantex_data_seq_provide:nn#1#2 { \bool_if_exist:cTF { g__semantex_data_seq_#1_#2_bool_if_provided } { \bool_if:cF { g__semantex_data_seq_#1_#2_bool_if_provided } { \bool_set_true:c { g__semantex_data_seq_#1_#2_bool_if_provided } } } { \seq_new:c { g__semantex_data_seq_#1_#2 } \bool_new:c { g__semantex_data_seq_#1_#2_bool_if_provided } \bool_set_true:c { g__semantex_data_seq_#1_#2_bool_if_provided } } } \cs_new_protected:Npn\semantex_data_seq_inherit:nn#1#2 { \bool_if_exist:cTF { g__semantex_data_seq_#1_#2_bool_if_provided } { \bool_if:cF { g__semantex_data_seq_#1_#2_bool_if_provided } { \semantex_data_seq_get_store:nnc { \semantex_data_parent_get:n { #1 } } { #2 } { g__semantex_data_seq_#1_#2 } \bool_set_true:c { g__semantex_data_seq_#1_#2_bool_if_provided } } } { \bool_new:c { g__semantex_data_seq_#1_#2_bool_if_provided } \bool_set_true:c { g__semantex_data_seq_#1_#2_bool_if_provided } \seq_if_exist:cF { g__semantex_data_seq_#1_#2 } { \seq_new:c { g__semantex_data_seq_#1_#2 } } \semantex_data_seq_get_store:nnc { \semantex_data_parent_get:n { #1 } } { #2 } { g__semantex_data_seq_#1_#2 } } } \cs_new_protected:Npn\semantex_data_seq_put_right:nnn#1#2#3 { \semantex_data_seq_inherit:nn { #1 } { #2 } \seq_put_right:cn { g__semantex_data_seq_#1_#2 } { #3 } } \cs_new_protected:Npn\semantex_data_seq_clear:nn#1#2 { \semantex_data_seq_provide:nn { #1 } { #2 } \seq_clear:c { g__semantex_data_seq_#1_#2 } } % COMMANDS FOR HANDLING DATA OF TYPE BOOLEAN: \cs_new:Npn\semantex_data_bool_get:nnTF#1#2#3#4 { % #1 = name of the register % #2 = boolean to get % #3 = if true % #4 = if false \__semantex_data_bool_get_auxiliary:nnTFn { #1 } { #2 } { #3 } { #4 } { #1 } } \cs_new:Npn\__semantex_data_bool_get_auxiliary:nnTFn#1#2#3#4#5 { % We keep the somewhat unusual order of the arguments % to be consistent with how these commands look elsewhere. % #1 = name of the register % #2 = boolean to get % #3 = if true % #4 = if false % #5 = name of the original register, to be used for error messaging \bool_if_exist:cTF { g__semantex_data_bool_#1_if_#2_bool_if_provided } { \bool_if:cTF { g__semantex_data_bool_#1_if_#2_bool_if_provided } { \bool_if:cTF { g__semantex_data_bool_#1_if_#2 } { #3 } { #4 } } { \str_if_eq:nnTF { #1 } { class_SemantexBaseObject } { #4 } { \__semantex_data_bool_get_auxiliary:fnTFn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 } { #4 } { #5 } } } } { \str_if_eq:nnTF { #1 } { class_SemantexBaseObject } { \semantex_msg_error:nnx { #5 } { data_bool_not_found } { #2 } } { \__semantex_data_bool_get_auxiliary:fnTFn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 } { #4 } { #5 } } } } \cs_generate_variant:Nn \__semantex_data_bool_get_auxiliary:nnTFn { fnTFn } \cs_generate_variant:Nn \semantex_data_bool_get:nnTF { nnT } \cs_new:Npn\semantex_data_bool_get:nnF#1#2#3 { \semantex_data_bool_get:nnTF { #1 } { #2 } { } { #3 } } \cs_new_protected:Npn\semantex_data_bool_provide:nn#1#2 { % #1 = name of the register % #2 = boolean to provide \bool_if_exist:cTF { g__semantex_data_bool_#1_if_#2_bool_if_provided } { \bool_if:cF { g__semantex_data_bool_#1_if_#2_bool_if_provided } { \bool_set_true:c { g__semantex_data_bool_#1_if_#2_bool_if_provided } } } { \bool_new:c { g__semantex_data_bool_#1_if_#2 } \bool_new:c { g__semantex_data_bool_#1_if_#2_bool_if_provided } \bool_set_true:c { g__semantex_data_bool_#1_if_#2_bool_if_provided } } } \cs_new_protected:Npn\semantex_data_bool_set_true:nn#1#2 { % #1 = name of the register % #2 = boolean to set true \semantex_data_bool_provide:nn { #1 } { #2 } \bool_set_true:c { g__semantex_data_bool_#1_if_#2 } } \cs_new_protected:Npn\semantex_data_bool_set_false:nn#1#2 { % #1 = name of the register % #2 = boolean to set false \semantex_data_bool_provide:nn { #1 } { #2 } \bool_set_false:c { g__semantex_data_bool_#1_if_#2 } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % COMMANDS FOR HANDLING KEYVAL INTERFACES % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \cs_generate_variant:Nn \semantex_keyval_parse:NNn { ccn } \cs_new_protected:Npn \semantex_keys_set:nn#1#2 { \cs_set_eq:NN\l__semantex_keys_set_old_this_temp_cs:\semantex_this: \cs_set:Nn\semantex_this:{#1} % The central command for doing keyval setup % #1 = object % #2 = keys \semantex_keyval_parse:ccn % Used to use o-type expansions, but no longer seems necessary { __semantex_data_cs_#1_singlekey:n } { __semantex_data_cs_#1_valuekey:nn } { #2 } \cs_set_eq:NN\semantex_this:\l__semantex_keys_set_old_this_temp_cs: } \cs_new_protected:Npn \semantex_keys_set_x:nn#1#2 { \cs_set_eq:NN\l__semantex_keys_set_old_this_temp_cs:\semantex_this: \cs_set:Nn\semantex_this:{#1} % The central command for doing expanded keyval setup % #1 = object % #2 = keys \semantex_keyval_parse:ccn % Used to use o-type expansions, but no longer seems necessary { __semantex_data_cs_#1_singlekey_x:n } { __semantex_data_cs_#1_valuekey:nx } { #2 } \cs_set_eq:NN\semantex_this:\l__semantex_keys_set_old_this_temp_cs: } \cs_new_protected:Npn \semantex_arg_keys_set:nn#1#2 { % The central command for doing keyval setup for the argument % #1 = object % #2 = keys \semantex_keyval_parse:ccn % See last command { __semantex_data_cs_#1_arg_singlekey:n } { __semantex_data_cs_#1_arg_valuekey:nn } { #2 } } \cs_new_protected:Npn \semantex_arg_keys_set_x:nn#1#2 { % The central command for doing expanded keyval setup for the argument % #1 = object % #2 = keys \semantex_keyval_parse:ccn % See last command { __semantex_data_cs_#1_arg_singlekey_x:n } { __semantex_data_cs_#1_arg_valuekey:nx } { #2 } } \cs_generate_variant:Nn \clist_map_function:nN { nc } \cs_new_protected:Npn \semantex_arg_singlekeys_set:nn#1#2 { % This command is necessary because you sometimes want to only allow singlekeys % and not valuekeys in arguments (for instance, if you allow valuekeys, anything % containing an equality sign will die horribly in the argument of any object) \clist_map_function:nc {#2} { __semantex_data_cs_#1_arg_singlekey:n } } \DeclareDocumentCommand\SetupClass{mm}{ % a user-level command for setting up the object % #1 = class % #2 = setup \semantex_class_if_exist:NTF #1 { \semantex_keys_set:nn { \semantex_class_to_register:N #1 }{ #2 } } { \semantex_msg_error:nn { \semantex_class_to_register:N #1 } { setup_unknown_class } } } \DeclareDocumentCommand\SetupObject{mm}{% % #1 = object % #2 = setup \semantex_object_if_exist:NTF #1 { \semantex_keys_set:nn { \semantex_object_to_register:N #1 }{ #2 } } { \semantex_msg_error:nn { \semantex_object_to_register:N #1 } { setup_unknown_object } } } \cs_new_protected:Npn\semantex_valuekey:nnn#1#2#3 { % The central command for executing valuekeys, % i.e. keys taking a value % #1 = register % #2 = name of the key % #3 = value \__semantex_valuekey:nnnn { #1 } { #2 } { #3 } { #1 } } \cs_new_protected:Npn \__semantex_valuekey:nnnn#1#2#3#4 { \cs_if_exist:cTF { __semantex_data_cs_custom_valuekey_#1_#2:nn } { \use:c { __semantex_data_cs_custom_valuekey_#1_#2:nn } { #4 } { #3 } } { \str_if_eq:nnTF { #1 } { class_SemantexBaseObject } { \semantex_msg_error:nnn { #4 } { valuekey_not_found } { #2 } } { \__semantex_valuekey:fnnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 } { #4 } } } } \cs_generate_variant:Nn \__semantex_valuekey:nnnn { fnnn } \cs_generate_variant:Nn \semantex_valuekey:nnn { nnx } \cs_new_protected:Npn\semantex_base_object_valuekey:nnn#1#2#3 { % Skips through the steps above to go directly to the % valuekey as defined by \SemantexBaseObject. % This is only being used in the rendering routine, % so so far, an corresponding command for singlekeys % has not been needed. % #1 = register % #2 = key % #3 = value \use:c { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_#2:nn } { #1 } { #3 } } \cs_new_protected:Npn\semantex_singlekey:nn#1#2 { % The central command for executing singlekeys, % i.e. keys taking no % #1 = register % #2 = name of the key \__semantex_singlekey:nnn { #1 } { #2 } { #1 } } \cs_new_protected:Npn\__semantex_singlekey:nnn#1#2#3 { \cs_if_exist:cTF { __semantex_data_cs_custom_singlekey_#1_\tl_to_str:n{ #2 }:n } % This is necessary in order to allow the case where something nasty % and unexpandable gets passed as singlekey -- this often happens % because of the convention that \[] % just prints { \use:c { __semantex_data_cs_custom_singlekey_#1_#2:n } { #3 } } { \str_if_eq:nnTF { #1 } { class_SemantexBaseObject } { \semantex_valuekey:nnn { #3 } { default } { #2 } } { \__semantex_singlekey:fnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 } } } } \cs_generate_variant:Nn \__semantex_singlekey:nnn { fnn } \cs_new_protected:Npn\semantex_singlekey_x:nn#1#2 { % The central command for executing expanded singlekeys, % i.e. keys taking no % #1 = register % #2 = name of the key \__semantex_singlekey_x:nnn { #1 } { #2 } { #1 } } \cs_new_protected:Npn\__semantex_singlekey_x:nnn#1#2#3 { \cs_if_exist:cTF { __semantex_data_cs_custom_singlekey_#1_\tl_to_str:n{ #2 }:n } { \use:c { __semantex_data_cs_custom_singlekey_#1_#2:n } { #3 } % and no, we don't want :x here; we don't need to expand % the name of the register } { \str_if_eq:nnTF { #1 } { class_SemantexBaseObject } { \semantex_valuekey:nnx { #3 } { default } { #2 } } { \__semantex_singlekey_x:fnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 } } } } \cs_generate_variant:Nn \__semantex_singlekey_x:nnn { fnn } \cs_new_protected:Npn\semantex_arg_valuekey:nnn#1#2#3 { % Takes care of argument valuekeys, % i.e. argument keys with a value % #1 = register % #2 = name of the key % #3 = value of the key \__semantex_arg_valuekey:nnnn { #1 } { #2 } { #3 } { #1 } } \cs_new_protected:Npn \__semantex_arg_valuekey:nnnn#1#2#3#4 { \cs_if_exist:cTF { __semantex_data_cs_custom_arg_valuekey_#1_#2:nn } { \use:c { __semantex_data_cs_custom_arg_valuekey_#1_#2:nn } { #4 } { #3 } } { \str_if_eq:nnTF { #1 } { class_SemantexBaseObject } { \semantex_msg_error:nnn { #1 } { arg_valuekey_not_found } { #2 } } { \__semantex_arg_valuekey:fnnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 } { #4 } } } } \cs_generate_variant:Nn \__semantex_arg_valuekey:nnnn { fnnn } \cs_generate_variant:Nn \semantex_arg_valuekey:nnn { nnx } \cs_new_protected:Npn \semantex_arg_singlekey:nn#1#2 { % The central command for executing argument singlekeys, % i.e. keys taking no % #1 = register % #2 = name of the key \__semantex_arg_singlekey:nnn { #1 } { #2 } { #1 } } \cs_new_protected:Npn \__semantex_arg_singlekey:nnn#1#2#3 { \cs_if_exist:cTF { __semantex_data_cs_custom_arg_singlekey_#1_\tl_to_str:n{ #2 }:n } { \use:c { __semantex_data_cs_custom_arg_singlekey_#1_#2:n } { #3 } } { \str_if_eq:nnTF { #1 } { class_SemantexBaseObject } { \semantex_arg_valuekey:nnn { #3 } { default } { #2 } } { \__semantex_arg_singlekey:fnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 } } } } \cs_generate_variant:Nn \__semantex_arg_singlekey:nnn { fnn } \cs_new_protected:Npn \semantex_arg_singlekey_x:nn#1#2 { % The central command for executing expanded argument singlekeys, % i.e. keys taking no % #1 = register % #2 = name of the key \__semantex_arg_singlekey_x:nnn { #1 } { #2 } { #1 } } \cs_new_protected:Npn \__semantex_arg_singlekey_x:nnn#1#2#3 { \cs_if_exist:cTF { \tl_to_str:n{__semantex_data_cs_custom_arg_singlekey_#1_#2:n } } { \use:c { __semantex_data_cs_custom_arg_singlekey_#1_#2:n } { #3 } % and no, we don't want :x here; we don't need to expand % the name of the register } { \str_if_eq:nnTF { #1 } { class_SemantexBaseObject } { \semantex_arg_valuekey:nnx { #3 } { default } { #2 } } { \__semantex_arg_singlekey:fnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 } } } } \cs_generate_variant:Nn \__semantex_arg_singlekey_x:nnn { fnn } \cs_new_protected:Npn\semantex_arg_without_keyval:nn#1#2 { % Sets the argument (no keyval interface allowed) \semantex_data_tl_put_right:nnn { #1 } { arg } { #2 } \semantex_data_int_incr:nn { #1 } { numberofarguments } \semantex_data_bool_set_true:nn { #1 } { nextargwithsep } } \cs_generate_variant:Nn \semantex_arg_without_keyval:nn { nx } % NOW SOME KEYS FOR DEFINING NEW KEYS: % First, we define the central commands for preprocessing keys \cs_generate_variant:Nn \semantex_keyval_parse:NNn { NNo } \cs_new_protected:Npn\semantex_preprocess_keys:nN#1#2 { \cs_set:Npn\l__semantex_preprocess_singlekey_temp_cs:n##1 { \__semantex_preprocess_singlekey:nnN { ####1 } { ##1 } #2 } \cs_set:Npn\l__semantex_preprocess_valuekey_temp_cs:nn##1##2 { \__semantex_preprocess_valuekey:nnnN { ####1 } { ##1 } { ##2 } #2 } \semantex_keyval_parse:NNn \l__semantex_preprocess_singlekey_temp_cs:n \l__semantex_preprocess_valuekey_temp_cs:nn { #1 } } \cs_generate_variant:Nn \semantex_preprocess_keys:nN { oN } \cs_new_protected:Npn\__semantex_preprocess_singlekey:nnN#1#2#3 { \tl_put_right:Nn#3 { \semantex_singlekey:nn { #1 } { #2 } } } \cs_new_protected:Npn\__semantex_preprocess_valuekey:nnnN#1#2#3#4 { \str_case:nnF { #2 } { { execute }{ \tl_put_right:Nn #4 { #3 } } { setkeys }{ \semantex_preprocess_keys:nN { #3 } #4 } { keysset }{ \semantex_preprocess_keys:nN { #3 } #4 } { setkeysx }{ \semantex_preprocess_keys_x:nN { #3 } #4 } { keyssetx }{ \semantex_preprocess_keys_x:nN { #3 } #4 } { setargkeys }{ \semantex_preprocess_arg_keys:nN { #3 } #4 } { argkeysset }{ \semantex_preprocess_arg_keys:nN { #3 } #4 } { setargkeysx }{ \semantex_preprocess_arg_keys_x:nN { #3 } #4 } { argkeyssetx }{ \semantex_preprocess_arg_keys_x:nN { #3 } #4 } { setargsinglekeys }{ \semantex_preprocess_arg_singlekeys:nN { #3 } #4 } { argsinglekeysset }{ \semantex_preprocess_arg_singlekeys:nN { #3 } #4 } { setargsinglekeysx }{ \semantex_preprocess_arg_singlekeys_x:nN { #3 } #4 } { argsinglekeyssetx }{ \semantex_preprocess_arg_singlekeys_x:nN { #3 } #4 } { parseoptions }{ \tl_put_right:Nn#4 { \semantex_add_raw_commands_to_parse_options:nn { #1 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys:nN { #3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } } { outputoptions }{ \tl_put_right:Nn#4 { \semantex_add_raw_commands_to_output_options:nn { #1 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_pre_temp_tl {} \semantex_preprocess_keys:nN { #3 } \l__semantex_preprocess_valuekey_keys_pre_temp_tl \cs_set:Npo\l__semantex_preprocess_valuekey_keys_temp_cs:nn##1##2 { \l__semantex_preprocess_valuekey_keys_pre_temp_tl } \tl_set:No\l__semantex_preprocess_valuekey_keys_temp_tl { \l__semantex_preprocess_valuekey_keys_temp_cs:nn { ###1 } { ##2 } } \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } } { boolifTF }{ \cs_set:Npn \l__semantex_preprocess_valuekey_boolifTF_temp_cs:nTF##1##2##3 { \tl_put_right:Nn#4 { \semantex_data_bool_get:nnTF { ####1 } { \tl_trim_spaces:n { ##1 } } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys:nN { ##2 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V \l__semantex_preprocess_valuekey_keys_temp_tl } } } \l__semantex_preprocess_valuekey_boolifTF_temp_cs:nTF #3 } { boolifT }{ \cs_set:Npn \l__semantex_preprocess_valuekey_boolifT_temp_cs:nT##1##2 { \tl_put_right:Nn#4 { \semantex_data_bool_get:nnTF { ####1 } { \tl_trim_spaces:n { ##1 } } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys:nN { ##2 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } { } } } \l__semantex_preprocess_valuekey_boolifT_temp_cs:nT #3 } { boolifF }{ \cs_set:Npn \l__semantex_preprocess_valuekey_boolifF_temp_cs:nF##1##2 { \tl_put_right:Nn#4 { \semantex_data_bool_get:nnTF { ####1 } { \tl_trim_spaces:n { ##1 } } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys:nN { ##2 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { } { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } } \l__semantex_preprocess_valuekey_boolifF_temp_cs:nF #3 } { ifblankTF }{ \cs_set:Npn \l__semantex_preprocess_valuekey_ifblankTF_temp_cs:nTF##1##2##3 { \tl_put_right:Nn#4 { \tl_if_blank:xTF { ##1 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys:nN { ##2 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V \l__semantex_preprocess_valuekey_keys_temp_tl } } } \l__semantex_preprocess_valuekey_ifblankTF_temp_cs:nTF #3 } { ifblankT }{ \cs_set:Npn \l__semantex_preprocess_valuekey_ifblankT_temp_cs:nT##1##2 { \tl_put_right:Nn#4 { \tl_if_blank:xTF { ##1 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys:nN { ##2 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } { } } } \l__semantex_preprocess_valuekey_ifblankT_temp_cs:nT #3 } { ifblankF }{ \cs_set:Npn \l__semantex_preprocess_valuekey_ifblankF_temp_cs:nF##1##2 { \tl_put_right:Nn#4 { \tl_if_blank:xTF { ##1 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys:nN { ##2 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { } { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } } \l__semantex_preprocess_valuekey_ifblankF_temp_cs:nF #3 } { strifeqTF }{ \cs_set:Npn \l__semantex_preprocess_valuekey_strifeqTF_temp_cs:nnTF##1##2##3##4 { \tl_put_right:Nn#4 { \str_if_eq:xxTF { ##1 } { ##2 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys:nN { ##4 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V \l__semantex_preprocess_valuekey_keys_temp_tl } } } \l__semantex_preprocess_valuekey_strifeqTF_temp_cs:nnTF #3 } { strifeqT }{ \cs_set:Npn \l__semantex_preprocess_valuekey_strifeqT_temp_cs:nnT##1##2##3 { \tl_put_right:Nn#4 { \str_if_eq:xxTF { ##1 } { ##2 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } { } } } \l__semantex_preprocess_valuekey_strifeqT_temp_cs:nnT #3 } { strifeqF }{ \cs_set:Npn \l__semantex_preprocess_valuekey_strifeqF_temp_cs:nnF##1##2##3 { \tl_put_right:Nn#4 { \str_if_eq:xxTF { ##1 } { ##2 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { } { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } } \l__semantex_preprocess_valuekey_strifeqF_temp_cs:nnF #3 } { intifgreaterTF }{ \cs_set:Npn \l__semantex_preprocess_valuekey_intifgreaterTF_temp_cs:nnTF##1##2##3##4 { \tl_put_right:Nn#4 { \int_compare:nNnTF { ##1 } > { ##2 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys:nN { ##4 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V \l__semantex_preprocess_valuekey_keys_temp_tl } } } \l__semantex_preprocess_valuekey_intifgreaterTF_temp_cs:nnTF #3 } { intifgreaterT }{ \cs_set:Npn \l__semantex_preprocess_valuekey_intifgreaterT_temp_cs:nnT##1##2##3 { \tl_put_right:Nn#4 { \int_compare:nNnTF { ##1 } > { ##2 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } { } } } \l__semantex_preprocess_valuekey_intifgreaterT_temp_cs:nnT #3 } { intifgreaterF }{ \cs_set:Npn \l__semantex_preprocess_valuekey_intifgreaterF_temp_cs:nnF##1##2##3 { \tl_put_right:Nn#4 { \int_compare:nNnTF { ##1 } > { ##2 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { } { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } } \l__semantex_preprocess_valuekey_intifgreaterF_temp_cs:nnF #3 } { intifeqTF }{ \cs_set:Npn \l__semantex_preprocess_valuekey_intifeqTF_temp_cs:nnTF##1##2##3##4 { \tl_put_right:Nn#4 { \int_compare:nNnTF { ##1 } = { ##2 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys:nN { ##4 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V \l__semantex_preprocess_valuekey_keys_temp_tl } } } \l__semantex_preprocess_valuekey_intifeqTF_temp_cs:nnTF #3 } { intifeqT }{ \cs_set:Npn \l__semantex_preprocess_valuekey_intifeqT_temp_cs:nnT##1##2##3 { \tl_put_right:Nn#4 { \int_compare:nNnTF { ##1 } = { ##2 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } { } } } \l__semantex_preprocess_valuekey_intifeqT_temp_cs:nnT #3 } { intifeqF }{ \cs_set:Npn \l__semantex_preprocess_valuekey_intifeqF_temp_cs:nnF##1##2##3 { \tl_put_right:Nn#4 { \int_compare:nNnTF { ##1 } = { ##2 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { } { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } } \l__semantex_preprocess_valuekey_intifeqF_temp_cs:nnF #3 } { intiflessTF }{ \cs_set:Npn \l__semantex_preprocess_valuekey_intiflessTF_temp_cs:nnTF##1##2##3##4 { \tl_put_right:Nn#4 { \int_compare:nNnTF { ##1 } < { ##2 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys:nN { ##4 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V \l__semantex_preprocess_valuekey_keys_temp_tl } } } \l__semantex_preprocess_valuekey_intiflessTF_temp_cs:nnTF #3 } { intiflessT }{ \cs_set:Npn \l__semantex_preprocess_valuekey_intiflessT_temp_cs:nnT##1##2##3 { \tl_put_right:Nn#4 { \int_compare:nNnTF { ##1 } < { ##2 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } { } } } \l__semantex_preprocess_valuekey_intiflessT_temp_cs:nnT #3 } { intiflessF }{ \cs_set:Npn \l__semantex_preprocess_valuekey_intiflessF_temp_cs:nnF##1##2##3 { \tl_put_right:Nn#4 { \int_compare:nNnTF { ##1 } < { ##2 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { } { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } } \l__semantex_preprocess_valuekey_intiflessF_temp_cs:nnF #3 } } { \tl_put_right:Nn#4 { \semantex_valuekey:nnn { #1 } { #2 } { #3 } } } } % The x version: \cs_new_protected:Npn\semantex_preprocess_keys_x:nN#1#2 { \cs_set:Npn\l__semantex_preprocess_singlekey_x_temp_cs:n##1 { \__semantex_preprocess_singlekey_x:nnN { ####1 } { ##1 } #2 } \cs_set:Npn\l__semantex_preprocess_valuekey_x_temp_cs:nn##1##2 { \__semantex_preprocess_valuekey_x:nnnN { ####1 } { ##1 } { ##2 } #2 } \semantex_keyval_parse:NNn \l__semantex_preprocess_singlekey_x_temp_cs:n \l__semantex_preprocess_valuekey_x_temp_cs:nn { #1 } } \cs_new_protected:Npn\__semantex_preprocess_singlekey_x:nnN#1#2#3 { \tl_put_right:Nn#3 { \semantex_singlekey_x:nn { #1 } { #2 } } } \cs_new_protected:Npn\__semantex_preprocess_valuekey_x:nnnN#1#2#3#4 { \str_case:nnF { #2 } { { execute } { \tl_put_right:Nn#4 { #3 } } { setkeys }{ \semantex_preprocess_keys:nN { #3 } #4 } { keysset }{ \semantex_preprocess_keys:nN { #3 } #4 } { setkeysx }{ \semantex_preprocess_keys_x:nN { #3 } #4 } { keyssetx }{ \semantex_preprocess_keys_x:nN { #3 } #4 } { setargkeys }{ \semantex_preprocess_arg_keys:nN { #3 } #4 } { argkeysset }{ \semantex_preprocess_arg_keys:nN { #3 } #4 } { setargkeysx }{ \semantex_preprocess_arg_keys_x:nN { #3 } #4 } { argkeyssetx }{ \semantex_preprocess_arg_keys_x:nN { #3 } #4 } { setargsinglekeys }{ \semantex_preprocess_arg_singlekeys:nN { #3 } #4 } { argsinglekeysset }{ \semantex_preprocess_arg_singlekeys:nN { #3 } #4 } { setargsinglekeysx }{ \semantex_preprocess_arg_singlekeys_x:nN { #3 } #4 } { argsinglekeyssetx }{ \semantex_preprocess_arg_singlekeys_x:nN { #3 } #4 } { parseoptions }{ \tl_put_right:Nn#4 { \semantex_add_raw_commands_to_parse_options:nn { #1 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys_x:nN { #3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } } { outputoptions }{ \tl_put_right:Nn#4 { \semantex_add_raw_commands_to_output_options:nn { #1 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_pre_temp_tl {} \semantex_preprocess_keys_x:nN { #3 } \l__semantex_preprocess_valuekey_keys_pre_temp_tl \cs_set:Npo\l__semantex_preprocess_valuekey_keys_temp_cs:nn##1##2 { \l__semantex_preprocess_valuekey_keys_pre_temp_tl } \tl_set:No\l__semantex_preprocess_valuekey_keys_temp_tl { \l__semantex_preprocess_valuekey_keys_temp_cs:nn { ###1 } { ##2 } } \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } } { boolifTF }{ \cs_set:Npn \l__semantex_preprocess_valuekey_boolifTF_temp_cs:nTF##1##2##3 { \tl_put_right:Nn#4 { \semantex_data_bool_get:nnTF { ####1 } { \tl_trim_spaces:n { ##1 } } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys_x:nN { ##2 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V \l__semantex_preprocess_valuekey_keys_temp_tl } } } \l__semantex_preprocess_valuekey_boolifTF_temp_cs:nTF #3 } { boolifT }{ \cs_set:Npn \l__semantex_preprocess_valuekey_boolifT_temp_cs:nT##1##2 { \tl_put_right:Nn#4 { \semantex_data_bool_get:nnTF { ####1 } { \tl_trim_spaces:n { ##1 } } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys_x:nN { ##2 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } { } } } \l__semantex_preprocess_valuekey_boolifT_temp_cs:nT #3 } { boolifF }{ \cs_set:Npn \l__semantex_preprocess_valuekey_boolifF_temp_cs:nF##1##2 { \tl_put_right:Nn#4 { \semantex_data_bool_get:nnTF { ####1 } { \tl_trim_spaces:n { ##1 } } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys_x:nN { ##2 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { } { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } } \l__semantex_preprocess_valuekey_boolifF_temp_cs:nF #3 } { ifblankTF }{ \cs_set:Npn \l__semantex_preprocess_valuekey_ifblankTF_temp_cs:nTF##1##2##3 { \tl_put_right:Nn#4 { \tl_if_blank:xTF { ##1 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys_x:nN { ##2 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V \l__semantex_preprocess_valuekey_keys_temp_tl } } } \l__semantex_preprocess_valuekey_ifblankTF_temp_cs:nTF #3 } { ifblankT }{ \cs_set:Npn \l__semantex_preprocess_valuekey_ifblankT_temp_cs:nT##1##2 { \tl_put_right:Nn#4 { \tl_if_blank:xTF { ##1 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys_x:nN { ##2 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } { } } } \l__semantex_preprocess_valuekey_ifblankT_temp_cs:nT #3 } { ifblankF }{ \cs_set:Npn \l__semantex_preprocess_valuekey_ifblankF_temp_cs:nF##1##2 { \tl_put_right:Nn#4 { \tl_if_blank:xTF { ##1 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys_x:nN { ##2 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { } { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } } \l__semantex_preprocess_valuekey_ifblankF_temp_cs:nF #3 } { strifeqTF }{ \cs_set:Npn \l__semantex_preprocess_valuekey_strifeqTF_temp_cs:nnTF##1##2##3##4 { \tl_put_right:Nn#4 { \str_if_eq:xxTF { ##1 } { ##2 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys_x:nN { ##4 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V \l__semantex_preprocess_valuekey_keys_temp_tl } } } \l__semantex_preprocess_valuekey_strifeqTF_temp_cs:nnTF #3 } { strifeqT }{ \cs_set:Npn \l__semantex_preprocess_valuekey_strifeqT_temp_cs:nnT##1##2##3 { \tl_put_right:Nn#4 { \str_if_eq:xxTF { ##1 } { ##2 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } { } } } \l__semantex_preprocess_valuekey_strifeqT_temp_cs:nnT #3 } { strifeqF }{ \cs_set:Npn \l__semantex_preprocess_valuekey_strifeqF_temp_cs:nnF##1##2##3 { \tl_put_right:Nn#4 { \str_if_eq:xxTF { ##1 } { ##2 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { } { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } } \l__semantex_preprocess_valuekey_strifeqF_temp_cs:nnF #3 } { intifgreaterTF }{ \cs_set:Npn \l__semantex_preprocess_valuekey_intifgreaterTF_temp_cs:nnTF##1##2##3##4 { \tl_put_right:Nn#4 { \int_compare:nNnTF { ##1 } > { ##2 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys_x:nN { ##4 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V \l__semantex_preprocess_valuekey_keys_temp_tl } } } \l__semantex_preprocess_valuekey_intifgreaterTF_temp_cs:nnTF #3 } { intifgreaterT }{ \cs_set:Npn \l__semantex_preprocess_valuekey_intifgreaterT_temp_cs:nnT##1##2##3 { \tl_put_right:Nn#4 { \int_compare:nNnTF { ##1 } > { ##2 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } { } } } \l__semantex_preprocess_valuekey_intifgreaterT_temp_cs:nnT #3 } { intifgreaterF }{ \cs_set:Npn \l__semantex_preprocess_valuekey_intifgreaterF_temp_cs:nnF##1##2##3 { \tl_put_right:Nn#4 { \int_compare:nNnTF { ##1 } > { ##2 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { } { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } } \l__semantex_preprocess_valuekey_intifgreaterF_temp_cs:nnF #3 } { intifeqTF }{ \cs_set:Npn \l__semantex_preprocess_valuekey_intifeqTF_temp_cs:nnTF##1##2##3##4 { \tl_put_right:Nn#4 { \int_compare:nNnTF { ##1 } = { ##2 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys_x:nN { ##4 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V \l__semantex_preprocess_valuekey_keys_temp_tl } } } \l__semantex_preprocess_valuekey_intifeqTF_temp_cs:nnTF #3 } { intifeqT }{ \cs_set:Npn \l__semantex_preprocess_valuekey_intifeqT_temp_cs:nnT##1##2##3 { \tl_put_right:Nn#4 { \int_compare:nNnTF { ##1 } = { ##2 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } { } } } \l__semantex_preprocess_valuekey_intifeqT_temp_cs:nnT #3 } { intifeqF }{ \cs_set:Npn \l__semantex_preprocess_valuekey_intifeqF_temp_cs:nnF##1##2##3 { \tl_put_right:Nn#4 { \int_compare:nNnTF { ##1 } = { ##2 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { } { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } } \l__semantex_preprocess_valuekey_intifeqF_temp_cs:nnF #3 } { intiflessTF }{ \cs_set:Npn \l__semantex_preprocess_valuekey_intiflessTF_temp_cs:nnTF##1##2##3##4 { \tl_put_right:Nn#4 { \int_compare:nNnTF { ##1 } < { ##2 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys_x:nN { ##4 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V \l__semantex_preprocess_valuekey_keys_temp_tl } } } \l__semantex_preprocess_valuekey_intiflessTF_temp_cs:nnTF #3 } { intiflessT }{ \cs_set:Npn \l__semantex_preprocess_valuekey_intiflessT_temp_cs:nnT##1##2##3 { \tl_put_right:Nn#4 { \int_compare:nNnTF { ##1 } < { ##2 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } { } } } \l__semantex_preprocess_valuekey_intiflessT_temp_cs:nnT #3 } { intiflessF }{ \cs_set:Npn \l__semantex_preprocess_valuekey_intiflessF_temp_cs:nnF##1##2##3 { \tl_put_right:Nn#4 { \int_compare:nNnTF { ##1 } < { ##2 } } \group_begin: \tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {} \semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl \exp_args:NNNx \group_end: \tl_put_right:Nn#4 { { } { \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl } } } \l__semantex_preprocess_valuekey_intiflessF_temp_cs:nnF #3 } } { \tl_put_right:Nn#4 { \semantex_valuekey:nnx { #1 } { #2 } { #3 } } } } \cs_new_protected:Npn\semantex_define_valuekeys:nn#1#2 { % Add new valuekeys \clist_map_inline:nn { #2 }{ \__semantex_valuekey_format_auxiliary:nnn { #1 } ##1 } } \cs_new_protected:Npn\__semantex_valuekey_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_valuekey_auxiliary_temp_cs:n##1 { #3 } \tl_set:Nn \l__semantex_valuekey_auxiliary_temp_tl {} \semantex_preprocess_keys:oN { \l__semantex_valuekey_auxiliary_temp_cs:n { ##2 } } \l__semantex_valuekey_auxiliary_temp_tl \cs_set_protected:cpo { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2 { \l__semantex_valuekey_auxiliary_temp_tl } } \cs_generate_variant:Nn \cs_set:Npn { Npo } \cs_generate_variant:Nn \cs_set_protected:Npn { cpo , Npo } \cs_new_protected:Npn\semantex_remove_valuekey:nn#1#2 { \cs_undefine:c { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } } \cs_new_protected:Npn\semantex_define_singlekeys:nn#1#2 { % Add keys taking no values \clist_map_inline:nn { #2 }{ \__semantex_singlekeys_format_auxiliary:nnn { #1 } ##1 } } \cs_new_protected:Npn \__semantex_singlekeys_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_singlekey_auxiliary_temp_cs: { #3 } \tl_set:Nn \l__semantex_singlekey_auxiliary_temp_tl {} \semantex_preprocess_keys:oN { \l__semantex_singlekey_auxiliary_temp_cs: } \l__semantex_singlekey_auxiliary_temp_tl \cs_set_protected:cpo { __semantex_data_cs_custom_singlekey_#1_\tl_trim_spaces:n{#2}:n } ##1 { \l__semantex_singlekey_auxiliary_temp_tl } } \cs_new_protected:Npn\semantex_remove_singlekey:nn#1#2 { \cs_undefine:c { __semantex_data_cs_custom_singlekey_#1_#2:n } } \cs_new_protected:Npn\semantex_define_two_valuekeys:nn#1#2 { % Add new valuekeys with 2 values \clist_map_inline:nn { #2 }{ \__semantex_two_valuekey_format_auxiliary:nnn { #1 } ##1 } } \cs_new_protected:Npn\__semantex_two_valuekey_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_two_valuekey_auxiliary_temp_cs:nn##1##2 { #3 } \tl_set:Nn\l__semantex_two_valuekey_auxiliary_temp_tl{} \semantex_preprocess_keys:oN { \l__semantex_two_valuekey_auxiliary_temp_cs:nn { ##2 } { ##3 } } \l__semantex_two_valuekey_auxiliary_temp_tl \cs_set_protected:cpo { __semantex_data_cs_custom_two_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnn } ##1##2##3 { \l__semantex_two_valuekey_auxiliary_temp_tl } \cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2 { \use:c { __semantex_data_cs_custom_two_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnn } { ##1 } ##2 } } \cs_new_protected:Npn\semantex_define_three_valuekeys:nn#1#2 { % Add new valuekeys with 3 values \clist_map_inline:nn { #2 }{ \__semantex_three_valuekey_format_auxiliary:nnn {#1} ##1 } } \cs_new_protected:Npn\__semantex_three_valuekey_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_three_valuekey_auxiliary_temp_cs:nnn##1##2##3 { #3 } \tl_set:Nn\l__semantex_three_valuekey_auxiliary_temp_tl{} \semantex_preprocess_keys:oN { \l__semantex_three_valuekey_auxiliary_temp_cs:nnn { ##2 } { ##3 } { ##4 } } \l__semantex_three_valuekey_auxiliary_temp_tl \cs_set_protected:cpo { __semantex_data_cs_custom_three_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnn } ##1##2##3##4 { \l__semantex_three_valuekey_auxiliary_temp_tl } \cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2 { \use:c { __semantex_data_cs_custom_three_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnn } { ##1 } ##2 } } \cs_new_protected:Npn\semantex_define_four_valuekeys:nn#1#2 { % Add new valuekeys with 4 values \clist_map_inline:nn { #2 }{ \__semantex_four_valuekey_format_auxiliary:nnn{#1}##1 } } \cs_new_protected:Npn\__semantex_four_valuekey_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_four_valuekey_auxiliary_temp_cs:nnnn##1##2##3##4 { #3 } \tl_set:Nn\l__semantex_four_valuekey_auxiliary_temp_tl{} \semantex_preprocess_keys:oN { \l__semantex_four_valuekey_auxiliary_temp_cs:nnnn { ##2 } { ##3 } { ##4 } { ##5 } } \l__semantex_four_valuekey_auxiliary_temp_tl \cs_set_protected:cpo { __semantex_data_cs_custom_four_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnn } ##1##2##3##4##5 { \l__semantex_four_valuekey_auxiliary_temp_tl } \cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2 { \use:c { __semantex_data_cs_custom_four_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnn } { ##1 } ##2 } } \cs_new_protected:Npn\semantex_define_five_valuekeys:nn#1#2 { % Add new valuekeys with 5 values \clist_map_inline:nn { #2 }{ \__semantex_five_valuekey_format_auxiliary:nnn{#1}##1 } } \cs_new_protected:Npn\__semantex_five_valuekey_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_five_valuekey_auxiliary_temp_cs:nnnnn##1##2##3##4##5 { #3 } \tl_set:Nn\l__semantex_five_valuekey_auxiliary_temp_tl{} \semantex_preprocess_keys:oN { \l__semantex_five_valuekey_auxiliary_temp_cs:nnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } } \l__semantex_five_valuekey_auxiliary_temp_tl \cs_set_protected:cpo { __semantex_data_cs_custom_five_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnn } ##1##2##3##4##5##6 { \l__semantex_five_valuekey_auxiliary_temp_tl } \cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2 { \use:c { __semantex_data_cs_custom_five_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnn } { ##1 } ##2 } } \cs_new_protected:Npn\semantex_define_six_valuekeys:nn#1#2 { % Add new valuekeys with 6 values \clist_map_inline:nn { #2 }{ \__semantex_six_valuekey_format_auxiliary:nnn{#1}##1 } } \cs_new_protected:Npn\__semantex_six_valuekey_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_six_valuekey_auxiliary_temp_cs:nnnnnn##1##2##3##4##5##6 { #3 } \tl_set:Nn\l__semantex_six_valuekey_auxiliary_temp_tl{} \semantex_preprocess_keys:oN { \l__semantex_six_valuekey_auxiliary_temp_cs:nnnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } } \l__semantex_six_valuekey_auxiliary_temp_tl \cs_set_protected:cpo { __semantex_data_cs_custom_six_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnn } ##1##2##3##4##5##6##7 { \l__semantex_six_valuekey_auxiliary_temp_tl } \cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2 { \use:c { __semantex_data_cs_custom_six_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnn } { ##1 } ##2 } } \cs_new_protected:Npn\semantex_define_seven_valuekeys:nn#1#2 { % Add new valuekeys with 7 values \clist_map_inline:nn { #2 }{ \__semantex_seven_valuekey_format_auxiliary:nnn{#1}##1 } } \cs_new_protected:Npn\__semantex_seven_valuekey_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_seven_valuekey_auxiliary_temp_cs:nnnnnnn##1##2##3##4##5##6##7 { #3 } \tl_set:Nn\l__semantex_seven_valuekey_auxiliary_temp_tl{} \semantex_preprocess_keys:oN { \l__semantex_seven_valuekey_auxiliary_temp_cs:nnnnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } } \l__semantex_seven_valuekey_auxiliary_temp_tl \cs_set_protected:cpo { __semantex_data_cs_custom_seven_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnn } ##1##2##3##4##5##6##7##8 { \l__semantex_seven_valuekey_auxiliary_temp_tl } \cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2 { \use:c { __semantex_data_cs_custom_seven_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnn } { ##1 } ##2 } } \cs_new_protected:Npn\semantex_define_eight_valuekeys:nn#1#2 { % Add new valuekeys with 8 values \clist_map_inline:nn { #2 }{ \__semantex_eight_valuekey_format_auxiliary:nnn{#1}##1 } } \cs_new_protected:Npn\__semantex_eight_valuekey_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_eight_valuekey_auxiliary_temp_cs:nnnnnnnn##1##2##3##4##5##6##7##8 { #3 } \tl_set:Nn\l__semantex_eight_valuekey_auxiliary_temp_tl{} \semantex_preprocess_keys:oN { \l__semantex_eight_valuekey_auxiliary_temp_cs:nnnnnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 } } \l__semantex_eight_valuekey_auxiliary_temp_tl \cs_set_protected:cpo { __semantex_data_cs_custom_eight_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } ##1##2##3##4##5##6##7##8##9 { \l__semantex_eight_valuekey_auxiliary_temp_tl } \cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2 { \use:c { __semantex_data_cs_custom_eight_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } { ##1 } ##2 } } \cs_new_protected:Npn\semantex_define_nine_valuekeys:nn#1#2 { % Add new valuekeys with 9 values \clist_map_inline:nn { #2 }{ \__semantex_nine_valuekey_format_auxiliary:nnn{#1}##1 } } \cs_new_protected:Npn\__semantex_nine_valuekey_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_nine_valuekey_auxiliary_temp_cs:nnnnnnnnn##1##2##3##4##5##6##7##8##9 { #3 } \tl_set:Nn\l__semantex_nine_valuekey_auxiliary_temp_tl{} \cs_set:Npn\l__semantex_nine_valuekey_auxiliary_singlekey_temp_cs:n##1 { \__semantex_preprocess_singlekey:nnN { \__semantex_nine_valuekey_format_auxiliary_name_of_register_temp_tl } { ##1 } \l__semantex_nine_valuekey_auxiliary_temp_tl } \cs_set:Npn\l__semantex_nine_valuekey_auxiliary_valuekey_temp_cs:nn##1##2 { \__semantex_preprocess_valuekey:nnnN { \__semantex_nine_valuekey_format_auxiliary_name_of_register_temp_tl } { ##1 } { ##2 } \l__semantex_nine_valuekey_auxiliary_temp_tl } \semantex_keyval_parse:NNo \l__semantex_nine_valuekey_auxiliary_singlekey_temp_cs:n \l__semantex_nine_valuekey_auxiliary_valuekey_temp_cs:nn { \l__semantex_nine_valuekey_auxiliary_temp_cs:nnnnnnnnn { ##1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 } } \cs_set_protected:cpo { __semantex_data_cs_custom_nine_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } ##1##2##3##4##5##6##7##8##9 { \l__semantex_nine_valuekey_auxiliary_temp_tl } \cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2 { \tl_set:Nn \__semantex_nine_valuekey_format_auxiliary_name_of_register_temp_tl { ##1 } \use:c { __semantex_data_cs_custom_nine_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } ##2 } } % SETTING UP THE ARGUMENT KEYVAL INTERFACE \cs_new_protected:Npn\semantex_preprocess_arg_keys:nN#1#2 { \cs_set:Npn\l__semantex_preprocess_arg_singlekey_temp_cs:n##1 { \__semantex_preprocess_arg_singlekey:nnN { ####1 } { ##1 } #2 } \cs_set:Npn\l__semantex_preprocess_arg_valuekey_temp_cs:nn##1##2 { \__semantex_preprocess_arg_valuekey:nnnN { ####1 } { ##1 } { ##2 } #2 } \semantex_keyval_parse:NNn \l__semantex_preprocess_arg_singlekey_temp_cs:n \l__semantex_preprocess_arg_valuekey_temp_cs:nn { #1 } } \cs_generate_variant:Nn \semantex_preprocess_arg_keys:nN { oN } \cs_new_protected:Npn\semantex_preprocess_arg_singlekeys:nN#1#2 { \cs_set:Npn\l__semantex_preprocess_arg_singlekey_temp_cs:n##1 { \__semantex_preprocess_arg_singlekey:nnN { ####1 } { ##1 } #2 } \clist_map_function:nN { #1 } \l__semantex_preprocess_arg_singlekey_temp_cs:n } \cs_new_protected:Npn\__semantex_preprocess_arg_singlekey:nnN#1#2#3 { \tl_put_right:Nn#3 { \semantex_arg_singlekey:nn { #1 } { #2 } } } \cs_new_protected:Npn\__semantex_preprocess_arg_valuekey:nnnN#1#2#3#4 { \str_case:nnF { #2 } { { execute }{ \tl_put_right:Nn#4 { #3 } } { setkeys }{ \semantex_preprocess_keys:nN { #3 } #4 } { keysset }{ \semantex_preprocess_keys:nN { #3 } #4 } { setkeysx }{ \semantex_preprocess_keys_x:nN { #3 } #4 } { keyssetx }{ \semantex_preprocess_keys_x:nN { #3 } #4 } { setargkeys }{ \semantex_preprocess_arg_keys:nN { #3 } #4 } { argkeysset }{ \semantex_preprocess_arg_keys:nN { #3 } #4 } { setargkeysx }{ \semantex_preprocess_arg_keys_x:nN { #3 } #4 } { argkeyssetx }{ \semantex_preprocess_arg_keys_x:nN { #3 } #4 } { setargsinglekeys }{ \semantex_preprocess_arg_singlekeys:nN { #3 } #4 } { argsinglekeysset }{ \semantex_preprocess_arg_singlekeys:nN { #3 } #4 } { setargsinglekeysx }{ \semantex_preprocess_arg_singlekeys_x:nN { #3 } #4 } { argsinglekeyssetx }{ \semantex_preprocess_arg_singlekeys_x:nN { #3 } #4 } } { \tl_put_right:Nn#4 { \semantex_arg_valuekey:nnn { #1 } { #2 } { #3 } } } } % The x version: \cs_new_protected:Npn\semantex_preprocess_arg_keys_x:nN#1#2 { \cs_set:Npn\l__semantex_preprocess_arg_singlekey_x_temp_cs:n##1 { \__semantex_preprocess_arg_singlekey_x:nnN { ####1 } { ##1 } #2 } \cs_set:Npn\l__semantex_preprocess_arg_valuekey_x_temp_cs:nn##1##2 { \__semantex_preprocess_arg_valuekey_x:nnnN { ####1 } { ##1 } { ##2 } #2 } \semantex_keyval_parse:NNn \l__semantex_preprocess_arg_singlekey_x_temp_cs:n \l__semantex_preprocess_arg_valuekey_x_temp_cs:nn { #1 } } \cs_new_protected:Npn\semantex_preprocess_arg_singlekeys_x:nN#1#2 { \cs_set:Npn\l__semantex_preprocess_arg_singlekey_x_temp_cs:n##1 { \__semantex_preprocess_arg_singlekey_x:nnN { ####1 } { ##1 } #2 } \clist_map_function:nN { #1 } \l__semantex_preprocess_arg_singlekey_x_temp_cs:n } \cs_new_protected:Npn\__semantex_preprocess_arg_singlekey_x:nnN#1#2#3 { \tl_put_right:Nn#3 { \semantex_arg_singlekey_x:nn { #1 } { #2 } } } \cs_new_protected:Npn\__semantex_preprocess_arg_valuekey_x:nnnN#1#2#3#4 { \str_case:nnF { #2 } { { execute } { \tl_put_right:Nn#4 { #3 } } { setkeys }{ \semantex_preprocess_keys:nN { #3 } #4 } { keysset }{ \semantex_preprocess_keys:nN { #3 } #4 } { setkeysx }{ \semantex_preprocess_keys_x:nN { #3 } #4 } { keyssetx }{ \semantex_preprocess_keys_x:nN { #3 } #4 } { setargkeys }{ \semantex_preprocess_arg_keys:nN { #3 } #4 } { argkeysset }{ \semantex_preprocess_arg_keys:nN { #3 } #4 } { setargkeysx }{ \semantex_preprocess_arg_keys_x:nN { #3 } #4 } { argkeyssetx }{ \semantex_preprocess_arg_keys_x:nN { #3 } #4 } { setargsinglekeys }{ \semantex_preprocess_arg_singlekeys:nN { #3 } #4 } { argsinglekeysset }{ \semantex_preprocess_arg_singlekeys:nN { #3 } #4 } { setargsinglekeysx }{ \semantex_preprocess_arg_singlekeys_x:nN { #3 } #4 } { argsinglekeyssetx }{ \semantex_preprocess_arg_singlekeys_x:nN { #3 } #4 } } { \tl_put_right:Nn#4 { \semantex_arg_valuekey:nnx { #1 } { #2 } { #3 } } } } \cs_new_protected:Npn\semantex_define_arg_valuekeys:nn#1#2 { % Add new valuekeys \clist_map_inline:nn { #2 }{ \__semantex_arg_valuekey_format_auxiliary:nnn{#1}##1 } } \cs_generate_variant:Nn \l__semantex_auxiliary_preprocess_arg_keys_temp:n { o } \cs_new_protected:Npn\__semantex_arg_valuekey_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_arg_valuekey_auxiliary_temp_cs:n##1 { #3 } \tl_set:Nn \l__semantex_arg_valuekey_auxiliary_temp_tl {} \semantex_preprocess_arg_keys:oN { \l__semantex_arg_valuekey_auxiliary_temp_cs:n { ##2 } } \l__semantex_arg_valuekey_auxiliary_temp_tl \cs_set_protected:cpo { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2 { \l__semantex_arg_valuekey_auxiliary_temp_tl } } \cs_new_protected:Npn\semantex_remove_arg_valuekey:nn#1#2 { \cs_undefine:c { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } } \cs_new_protected:Npn\semantex_define_arg_singlekeys:nn#1#2 { % Add keys taking no values \clist_map_inline:nn { #2 }{ \__semantex_arg_singlekey_format_auxiliary:nnn{#1}##1 } } \cs_new_protected:Npn \__semantex_arg_singlekey_format_auxiliary:nnn#1#2#3{ \cs_set:Npn\l__semantex_arg_singlekey_auxiliary_temp_cs: { #3 } \tl_set:Nn \l__semantex_arg_singlekey_auxiliary_temp_tl {} \semantex_preprocess_arg_keys:oN { \l__semantex_arg_singlekey_auxiliary_temp_cs: } \l__semantex_arg_singlekey_auxiliary_temp_tl \cs_set_protected:cpo { __semantex_data_cs_custom_arg_singlekey_#1_\tl_trim_spaces:n{#2}:n } ##1 { \l__semantex_arg_singlekey_auxiliary_temp_tl } } \cs_new_protected:Npn\semantex_remove_arg_singlekey:nn#1#2 { \cs_undefine:c { __semantex_data_cs_custom_arg_singlekey_#1_#2:n } } \cs_new_protected:Npn\semantex_define_arg_two_valuekeys:nn#1#2 { % Add new argument valuekeys with 2 values \clist_map_inline:nn { #2 }{ \__semantex_arg_two_valuekey_format_auxiliary:nnn{#1}##1 } } \cs_new_protected:Npn\__semantex_arg_two_valuekey_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_arg_two_valuekey_auxiliary_temp_cs:nn##1##2 { #3 } \tl_set:Nn\l__semantex_arg_two_valuekey_auxiliary_temp_tl{} \semantex_preprocess_arg_keys:oN { \l__semantex_arg_two_valuekey_auxiliary_temp_cs:nn { ##2 } { ##3 } } \l__semantex_arg_two_valuekey_auxiliary_temp_tl \cs_set_protected:cpo { __semantex_data_cs_custom_arg_two_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnn } ##1##2##3 { \l__semantex_arg_two_valuekey_auxiliary_temp_tl } \cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2 { \use:c { __semantex_data_cs_custom_arg_two_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnn } { ##1 } ##2 } } \cs_new_protected:Npn\semantex_define_arg_three_valuekeys:nn#1#2 { % Add new argument valuekeys with 3 values \clist_map_inline:nn { #2 }{ \__semantex_three_arg_valuekey_format_auxiliary:nnn{#1}##1 } } \cs_new_protected:Npn\__semantex_three_arg_valuekey_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_arg_three_valuekey_auxiliary_temp_cs:nnn##1##2##3 { #3 } \tl_set:Nn\l__semantex_arg_three_valuekey_auxiliary_temp_tl{} \semantex_preprocess_arg_keys:oN { \l__semantex_arg_three_valuekey_auxiliary_temp_cs:nnn { ##2 } { ##3 } { ##4 } } \l__semantex_arg_three_valuekey_auxiliary_temp_tl \cs_set_protected:cpo { __semantex_data_cs_custom_arg_three_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnn } ##1##2##3##4 { \l__semantex_arg_three_valuekey_auxiliary_temp_tl } \cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2 { \use:c { __semantex_data_cs_custom_arg_three_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnn } { ##1 } ##2 } } \cs_new:Npn\semantex_define_arg_four_valuekeys:nn#1#2 { % Add new argument valuekeys with 4 values \clist_map_inline:nn { #2 }{ \__semantex_four_arg_valuekey_format_auxiliary:nnn{#1}##1 } } \cs_new_protected:Npn\__semantex_four_arg_valuekey_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_arg_four_valuekey_auxiliary_temp_cs:nnnn##1##2##3##4 { #3 } \tl_set:Nn\l__semantex_arg_four_valuekey_auxiliary_temp_tl{} \semantex_preprocess_arg_keys:oN { \l__semantex_arg_four_valuekey_auxiliary_temp_cs:nnnn { ##2 } { ##3 } { ##4 } { ##5 } } \l__semantex_arg_four_valuekey_auxiliary_temp_tl \cs_set_protected:cpo { __semantex_data_cs_custom_arg_four_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnn } ##1##2##3##4##5 { \l__semantex_arg_four_valuekey_auxiliary_temp_tl } \cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2 { \use:c { __semantex_data_cs_custom_arg_four_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnn } { ##1 } ##2 } } \cs_new_protected:Npn\semantex_define_arg_five_valuekeys:nn#1#2 { % Add new argument valuekeys with 5 values \clist_map_inline:nn { #2 }{ \__semantex_five_arg_valuekey_format_auxiliary:nnn{#1}##1 } } \cs_new_protected:Npn\__semantex_five_arg_valuekey_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_arg_five_valuekey_auxiliary_temp_cs:nnnnn##1##2##3##4##5 { #3 } \tl_set:Nn\l__semantex_arg_five_valuekey_auxiliary_temp_tl{} \semantex_preprocess_arg_keys:oN { \l__semantex_arg_five_valuekey_auxiliary_temp_cs:nnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } } \l__semantex_arg_five_valuekey_auxiliary_temp_tl \cs_set_protected:cpo { __semantex_data_cs_custom_arg_five_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnn } ##1##2##3##4##5##6 { \l__semantex_arg_five_valuekey_auxiliary_temp_tl } \cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2 { \use:c { __semantex_data_cs_custom_arg_five_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnn } { ##1 } ##2 } } \cs_new_protected:Npn\semantex_define_arg_six_valuekeys:nn#1#2 { % Add new argument valuekeys with 6 values \clist_map_inline:nn { #2 }{ \__semantex_six_arg_valuekey_format_auxiliary:nnn{#1}##1 } } \cs_new_protected:Npn\__semantex_six_arg_valuekey_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_arg_six_valuekey_auxiliary_temp_cs:nnnnnn##1##2##3##4##5##6 { #3 } \tl_set:Nn\l__semantex_arg_six_valuekey_auxiliary_temp_tl{} \semantex_preprocess_arg_keys:oN { \l__semantex_arg_six_valuekey_auxiliary_temp_cs:nnnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } } \l__semantex_arg_six_valuekey_auxiliary_temp_tl \cs_set_protected:cpo { __semantex_data_cs_custom_arg_six_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnn } ##1##2##3##4##5##6##7 { \l__semantex_arg_six_valuekey_auxiliary_temp_tl } \cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2 { \use:c { __semantex_data_cs_custom_arg_six_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnn } { ##1 } ##2 } } \cs_new_protected:Npn\semantex_define_arg_seven_valuekeys:nn#1#2 { % Add new argument valuekeys with 7 values \clist_map_inline:nn { #2 }{ \__semantex_seven_arg_valuekey_format_auxiliary:nnn{#1}##1 } } \cs_new_protected:Npn\__semantex_seven_arg_valuekey_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_arg_seven_valuekey_auxiliary_temp_cs:nnnnnnn##1##2##3##4##5##6##7 { #3 } \tl_set:Nn\l__semantex_arg_seven_valuekey_auxiliary_temp_tl{} \semantex_preprocess_arg_keys:oN { \l__semantex_arg_seven_valuekey_auxiliary_temp_cs:nnnnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } } \l__semantex_arg_seven_valuekey_auxiliary_temp_tl \cs_set_protected:cpo { __semantex_data_cs_custom_arg_seven_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnn } ##1##2##3##4##5##6##7##8 { \l__semantex_arg_seven_valuekey_auxiliary_temp_tl } \cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2 { \use:c { __semantex_data_cs_custom_arg_seven_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnn } { ##1 } ##2 } } \cs_new_protected:Npn\semantex_define_arg_eight_valuekeys:nn#1#2 { % Add new argument valuekeys with 8 values \clist_map_inline:nn { #2 }{ \__semantex_eight_arg_valuekey_format_auxiliary:nnn{#1}##1 } } \cs_new_protected:Npn\__semantex_eight_arg_valuekey_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_arg_eight_valuekey_auxiliary_temp_cs:nnnnnnnn##1##2##3##4##5##6##7##8 { #3 } \tl_set:Nn\l__semantex_arg_eight_valuekey_auxiliary_temp_tl{} \semantex_preprocess_arg_keys:oN { \l__semantex_arg_eight_valuekey_auxiliary_temp_cs:nnnnnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 } } \l__semantex_arg_eight_valuekey_auxiliary_temp_tl \cs_set_protected:cpo { __semantex_data_cs_custom_arg_eight_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } ##1##2##3##4##5##6##7##8##9 { \l__semantex_arg_eight_valuekey_auxiliary_temp_tl } \cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2 { \use:c { __semantex_data_cs_custom_arg_eight_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } { ##1 } ##2 } } \cs_new_protected:Npn\semantex_define_arg_nine_valuekeys:nn#1#2 { % Add new argument valuekeys with 9 values \clist_map_inline:nn { #2 }{ \__semantex_nine_arg_valuekey_format_auxiliary:nnn{#1}##1 } } \cs_new_protected:Npn\__semantex_nine_arg_valuekey_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_arg_nine_valuekey_auxiliary_temp_cs:nnnnnnnnn##1##2##3##4##5##6##7##8##9 { #3 } \tl_set:Nn\l__semantex_arg_nine_valuekey_auxiliary_temp_tl{} \cs_set:Npn\l__semantex_arg_nine_valuekey_auxiliary_singlekey_temp_cs:n##1 { \__semantex_preprocess_arg_singlekey:nnN { \__semantex_arg_nine_valuekey_format_auxiliary_name_of_register_temp_tl } { ##1 } \l__semantex_arg_nine_valuekey_auxiliary_temp_tl } \cs_set:Npn\l__semantex_arg_nine_valuekey_auxiliary_valuekey_temp_cs:nn##1##2 { \__semantex_preprocess_arg_valuekey:nnnN { \__semantex_arg_nine_valuekey_format_auxiliary_name_of_register_temp_tl } { ##1 } { ##2 } \l__semantex_arg_nine_valuekey_auxiliary_temp_tl } \semantex_keyval_parse:NNo \l__semantex_arg_nine_valuekey_auxiliary_singlekey_temp_cs:n \l__semantex_arg_nine_valuekey_auxiliary_valuekey_temp_cs:nn { \l__semantex_arg_nine_valuekey_auxiliary_temp_cs:nnnnnnnnn { ##1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 } } \cs_set_protected:cpo { __semantex_data_cs_custom_arg_nine_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } ##1##2##3##4##5##6##7##8##9 { \l__semantex_arg_nine_valuekey_auxiliary_temp_tl } \cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2 { \tl_set:Nn \__semantex_arg_nine_valuekey_format_auxiliary_name_of_register_temp_tl { ##1 } \use:c { __semantex_data_cs_custom_arg_nine_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } ##2 } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % COMMANDS HANDLING THE PARSE ROUTINE % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \cs_new_protected:Npn\semantex_parse:n#1 { % This command runs all the keys that the user may have % stored via the parseoptions key \exp_args:NNx\cs_set_protected:Nn\l__semantex_parse_temp_cs:n % \cs_set:Nx gave us ##1 where we wanted #1 { \semantex_data_tl_get_exp_not:nn { #1 } { parseoptions } } \l__semantex_parse_temp_cs:n { #1 } \semantex_data_tl_clear:nn { #1 } { parseoptions } } \cs_new_protected:Npn\semantex_add_to_parse_options:nn#1#2 { \tl_set:Nn\l__semantex_parseoptions_auxiliary_temp_tl{} \semantex_preprocess_keys:nN { #2 } \l__semantex_parseoptions_auxiliary_temp_tl \semantex_add_raw_commands_to_parse_options:no { #1 } { \l__semantex_parseoptions_auxiliary_temp_tl } } \cs_new_protected:Npn\semantex_add_raw_commands_to_parse_options:nn#1#2 { \semantex_data_tl_put_right:nnn { #1 } { parseoptions } { #2 } } \cs_generate_variant:Nn \semantex_add_raw_commands_to_parse_options:nn { no } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % COMMANDS HANDLING OUTPUT OPTIONS % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \cs_new_protected:Npn\semantex_set_output:nn#1#2 { % Tells what class the register is supposed to output \semantex_class_if_exist:NTF #2 { \semantex_data_tl_set:nnx { #1 } { output } { \semantex_class_to_register:N #2 } } { \semantex_msg_error:nnnn { #1 } { class_not_found } { output } { #2 } } } \cs_new_protected:Npn\semantex_add_to_output_options:nn#1#2 { \tl_set:Nn\l__semantex_output_options_auxiliary_temp_tl{} \semantex_preprocess_keys:nN { #2 } \l__semantex_output_options_auxiliary_temp_tl \semantex_add_raw_commands_to_output_options:no { #1 } { \l__semantex_output_options_auxiliary_temp_tl } } \cs_new_protected:Npn\semantex_add_raw_commands_to_output_options:nn#1#2 { \semantex_data_tl_put_right:nnn { #1 } { outputoptions } { #2 } } \cs_generate_variant:Nn \semantex_add_raw_commands_to_output_options:nn { no } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % USER-LEVEL PROGRAMMING KEYS % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \cs_generate_variant:Nn\str_if_eq:nnTF { xxTF } \cs_generate_variant:Nn\str_if_eq:nnT { xxT } \cs_generate_variant:Nn\str_if_eq:nnF { xxF } \cs_generate_variant:Nn\tl_if_blank:nTF { xTF, xT } \cs_generate_variant:Nn \tl_if_blank:nF { xF } \cs_generate_variant:Nn \semantex_keys_set:nn { on } \cs_generate_variant:Nn \semantex_keys_set_x:nn { on } \cs_new:Npn\semantex_this:{ \msg_error:nn { semantex } { SemantexThis_in_input_stream } } \cs_new:Npn\SemantexThis{\semantex_this:} \cs_new_protected:Npn\SemantexDataProvide#1{\semantex_data_tl_provide:nn{\semantex_this:}{\tl_trim_spaces:n{#1}}} \cs_new_protected:Npn\SemantexDataSet#1#2{\semantex_data_tl_set:nnn{\semantex_this:}{\tl_trim_spaces:n{#1}}{#2}} \cs_new_protected:Npn\SemantexDataSetx#1#2{\semantex_data_tl_set:nnx{\semantex_this:}{\tl_trim_spaces:n{#1}}{#2}} \cs_new_protected:Npn\SemantexDataPutRight#1#2{\semantex_data_tl_put_right:nnn{\semantex_this:}{\tl_trim_spaces:n{#1}}{#2}} \cs_new_protected:Npn\SemantexDataPutRightx#1#2{\semantex_data_tl_put_right:nnx{\semantex_this:}{\tl_trim_spaces:n{#1}}{#2}} \cs_new_protected:Npn\SemantexDataPutLeft#1#2{\semantex_data_tl_put_left:nnn{\semantex_this:}{\tl_trim_spaces:n{#1}}{#2}} \cs_new_protected:Npn\SemantexDataPutLeftx#1#2{\semantex_data_tl_put_left:nnx{\semantex_this:}{\tl_trim_spaces:n{#1}}{#2}} \cs_new:Npn\SemantexDataGet#1{\semantex_data_tl_get:nn{\semantex_this:}{\tl_trim_spaces:n{#1}}} \cs_new:Npn\SemantexDataGetExpNot#1{\semantex_data_tl_get_exp_not:nn{\semantex_this:}{\tl_trim_spaces:n{#1}}} \cs_new_protected:Npn\SemantexDataClear#1{\semantex_data_tl_clear:nn{\semantex_this:}{\tl_trim_spaces:n{#1}}} \cs_new_protected:Npn\SemantexSetKeys#1{\semantex_keys_set:on{\semantex_this:}{#1}} \cs_new_protected:Npn\SemantexKeysSet#1{\semantex_keys_set:on{\semantex_this:}{#1}} \cs_new_protected:Npn\SemantexSetKeysx#1{\semantex_keys_set_x:on{\semantex_this:}{#1}} \cs_new_protected:Npn\SemantexKeysSetx#1{\semantex_keys_set_x:on{\semantex_this:}{#1}} \cs_new_protected:Npn\SemantexSetArgKeys#1{\semantex_arg_keys_set:nn { \semantex_this: } { #1 }} \cs_new_protected:Npn\SemantexArgKeysSet#1{\semantex_arg_keys_set:nn { \semantex_this: } { #1 }} \cs_new_protected:Npn\SemantexSetArgKeysx#1{\semantex_arg_keys_set_x:nn { \semantex_this: } { #1 }} \cs_new_protected:Npn\SemantexArgKeysSetx#1{\semantex_arg_keys_set_x:nn { \semantex_this: } { #1 }} \cs_new_protected:Npn\SemantexSetArgSingleKeys#1{\semantex_arg_singlekeys_set:nn { \semantex_this: } { #1 } } \cs_new_protected:Npn\SemantexArgSingleKeysSet#1{\semantex_arg_singlekeys_set:nn { \semantex_this: } { #1 } } \cs_new_protected:Npn\SemantexSetArgSingleKeysx#1{\semantex_arg_singlekeys_set_x:nn { \semantex_this: } { #1 } } \cs_new_protected:Npn\SemantexArgSingleKeysSetx#1{\semantex_arg_singlekeys_set_x:nn { \semantex_this: } { #1 } } \cs_new_protected:Npn\SemantexSetOneArgSingleKey#1{\semantex_arg_singlekey:nn { \semantex_this: } { #1 } } \cs_new_protected:Npn\SemantexOneSingleArgKeySet#1{\semantex_arg_singlekey:nn { \semantex_this: } { #1 } } \cs_new_protected:Npn\SemantexSetOneArgSingleKeyx#1{\semantex_arg_singlekey_x:nn { \semantex_this: } { #1 } } \cs_new_protected:Npn\SemantexOneSingleArgKeySetx#1{\semantex_arg_singlekey_x:nn { \semantex_this: } { #1 } } \cs_new_protected:Npn\SemantexSetArgWithoutKeyval#1{\semantex_arg_without_keyval:nn { \semantex_this: } { #1 } } \cs_new_protected:Npn\SemantexArgWithoutKeyvalSet#1{\semantex_arg_without_keyval:nn { \semantex_this: } { #1 } } \cs_new_protected:Npn\SemantexSetArgWithoutKeyvalx#1{\semantex_arg_without_keyval:nx { \semantex_this: } { #1 } } \cs_new_protected:Npn\SemantexArgWithoutKeyvalSetx#1{\semantex_arg_without_keyval:nx { \semantex_this: } { #1 } } \cs_new_protected:Npn\SemantexStrIfEqTF#1#2#3#4{\str_if_eq:xxTF{#1}{#2}{#3}{#4}} \cs_new_protected:Npn\SemantexStrIfEqT#1#2#3{\str_if_eq:xxT{#1}{#2}{#3}} \cs_new_protected:Npn\SemantexStrIfEqF#1#2#3{\str_if_eq:xxF{#1}{#2}{#3}} \cs_new_protected:Npn\SemantexIfBlankTF#1#2#3{\tl_if_blank:xTF{#1}{#2}{#3}} \cs_new_protected:Npn\SemantexIfBlankT#1#2{\tl_if_blank:xT{#1}{#2}} \cs_new_protected:Npn\SemantexIfBlankF#1#2{\tl_if_blank:xF{#1}{#2}} \cs_new_protected:Npn\SemantexBoolProvide#1{\semantex_data_bool_provide:nn{\semantex_this:}{\tl_trim_spaces:n{#1}}} \cs_new_protected:Npn\SemantexBoolSetTrue#1{\semantex_data_bool_set_true:nn{\semantex_this:}{\tl_trim_spaces:n{#1}}} \cs_new_protected:Npn\SemantexBoolSetFalse#1{\semantex_data_bool_set_false:nn{\semantex_this:}{\tl_trim_spaces:n{#1}}} \cs_new:Npn\SemantexBoolIfTF#1#2#3{\semantex_data_bool_get:nnTF{\semantex_this:}{\tl_trim_spaces:n{#1}}{#2}{#3}} \cs_new:Npn\SemantexBoolIfT#1#2{\semantex_data_bool_get:nnTF{\semantex_this:}{\tl_trim_spaces:n{#1}}{#2}{}} \cs_new:Npn\SemantexBoolIfF#1#2{\semantex_data_bool_get:nnTF{\semantex_this:}{\tl_trim_spaces:n{#1}}{}{#2}} \cs_new_protected:Npn\SemantexIntProvide#1{\semantex_data_int_provide:nn{\semantex_this:}{\tl_trim_spaces:n{#1}}} \cs_new:Npn\SemantexIntGet#1{\semantex_data_int_get:nn{\semantex_this:}{\tl_trim_spaces:n{#1}}} \cs_new_protected:Npn\SemantexIntClear#1{\semantex_data_int_clear:nn{\semantex_this:}{\tl_trim_spaces:n{#1}}} \cs_new_protected:Npn\SemantexIntIncr#1{\semantex_data_int_incr:nn{\semantex_this:}{\tl_trim_spaces:n{#1}}} \cs_new_protected:Npn\SemantexIntSet#1#2{\semantex_data_int_set:nnn{\semantex_this:}{\tl_trim_spaces:n{#1}}{#2}} \cs_new:Npn\SemantexIntIfGreaterTF#1#2#3#4 { \int_compare:nNnTF { #1 } > { #2 } { #3 } { #4 } } \cs_new:Npn\SemantexIntIfGreaterT#1#2#3 { \int_compare:nNnTF { #1 } > { #2 } { #3 } { } } \cs_new:Npn\SemantexIntIfGreaterF#1#2#3 { \int_compare:nNnTF { #1 } > { #2 } { } { #3 } } \cs_new:Npn\SemantexIntIfEqTF#1#2#3#4 { \int_compare:nNnTF { #1 } = { #2 } { #3 } { #4 } } \cs_new:Npn\SemantexIntIfEqT#1#2#3 { \int_compare:nNnTF { #1 } = { #2 } { #3 } { } } \cs_new:Npn\SemantexIntIfEqF#1#2#3 { \int_compare:nNnTF { #1 } = { #2 } { } { #3 } } \cs_new:Npn\SemantexIntIfLessTF#1#2#3#4 { \int_compare:nNnTF { #1 } < { #2 } { #3 } { #4 } } \cs_new:Npn\SemantexIntIfLessT#1#2#3 { \int_compare:nNnTF { #1 } < { #2 } { #3 } { } } \cs_new:Npn\SemantexIntIfLessF#1#2#3 { \int_compare:nNnTF { #1 } < { #2 } { } { #3 } } \cs_new:Npn\SemantexExpNot#1{\exp_not:n{#1}} \cs_new:Npn\SemantexERRORKeyValueNotFound#1#2 { \semantex_error_key_value_not_found:nnn { \semantex_this: } { #1 } { #2 } } \cs_new:Npn\SemantexERRORArgKeyValueNotFound#1#2 { \semantex_error_arg_key_value_not_found:nnn { \semantex_this: } { #1 } { #2 } } \cs_new:Npn\SemantexERROR#1 { \semantex_error_generic:nn { \semantex_this: } { #1 } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ERROR MESSAGES % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \msg_new:nnnn { semantex } { semantex_setup_key_not_found } { Unknown~key~#1~passed~to~\SemantexSetup~on~line~\msg_line_number: } {} \msg_new:nnnn { semantex } { semantex_setup_key_value_not_found } { Unknown~value~#2~passed~to~key~#1~in~\SemantexSetup~on~line~\msg_line_number: } {} \msg_new:nnnn { semantex } { valuekey_not_found } { Unknown~key~#2~passed~to~#1 on~line~\msg_line_number: } {} \msg_new:nnnn { semantex } { arg_valuekey_not_found } { Unknown~argument~key~#2~passed~to~#1on~line~\msg_line_number: } {} \msg_new:nnnn { semantex } { data_tl_not_found } { Unknown~data~#2~requested~from~#1 on~line~\msg_line_number: } {} \msg_new:nnnn { semantex } { data_int_not_found } { Unknown~integer~#2~requested~from~#1 on~line~\msg_line_number: } {} \msg_new:nnnn { semantex } { data_bool_not_found } { Unknown~boolean~#2~requested~from~#1 on~line~\msg_line_number: } {} \msg_new:nnnn { semantex } { data_cs_not_found } { Unknown~command~sequence~#2~requested~from~#1 on~line~\msg_line_number: } {} \msg_new:nnnn { semantex } { data_prop_not_found } { Unknown~property~list~#2~requested~from~#1 on~line~\msg_line_number: } {} \msg_new:nnnn { semantex } { key_value_not_found } { Unknown~value~#3~passed~to~key~#2~in~#1 on~line~\msg_line_number: } {} \msg_new:nnnn { semantex } { arg_key_value_not_found } { Unknown~value~#3~passed~to~argument~key~#2~in~#1 on~line~\msg_line_number: } {} \msg_new:nnnn { semantex } { class_already_defined } { Class~#1 already~defined;~you~tried~defining~it~again~on~line~\msg_line_number: } {} \msg_new:nnnn { semantex } { object_already_defined } { Object~#1 already~defined;~you~tried~defining~it~again~on~line~\msg_line_number: } {} \msg_new:nnnn { semantex } { class_not_found } { Unknown~class~#3 declared~as~#2~of~#1 on~line~\msg_line_number: } {} \msg_new:nnnn { semantex } { object_not_found } { You~set~#1 as~#2~of~unknown~object~#3 on~line~\msg_line_number: } {} \msg_new:nnnn { semantex } { created_object_of_unknown_class } { Unknown~class~#1 declared~as~class~of~#2 on~line~\msg_line_number: } {} \msg_new:nnnn { semantex } { used_unknown_class } { Unknown~class~#1 received~by~\token_to_str:N\UseClassInCommand~on~line~\msg_line_number: } {} \msg_new:nnnn { semantex } { setup_unknown_class } { You~tried~setting~up~an~unknown~#1 on~line~\msg_line_number: } {} \msg_new:nnnn { semantex } { setup_unknown_object } { You~tried~setting~up~an~unknown~#1 on~line~\msg_line_number: } {} \msg_new:nnnn { semantex } { created_a_SemantexBaseObject } { Never~create~objects~of~class~\token_to_str:N\SemantexBaseObject;~create~a~new~class~yourself~instead.~You~created~the~object~#1 on~line~\msg_line_number: } {} \msg_new:nnnn { semantex } { SemantexThis_in_input_stream } { The~command~\token_to_str:N\SemantexThis~was~found~outside~a~class~or~object~on~line~\msg_line_number:;~did~you~forget~to~use~setkeysx={...}? } {} \msg_new:nnnn { semantex } { generic_error } { #2~#1 on~line~\msg_line_number: } {} \cs_generate_variant:Nn \msg_error:nnnn { nnnx } \tl_new:N\l__semantex_error_output_format_temp \cs_new_protected:Npn\semantex_error_output_format:nN#1#2 { \tl_set:Nn \l__semantex_error_output_format_temp { #1 } \tl_replace_all:Nnn \l__semantex_error_output_format_temp { object_ } { object~\cs:w } \tl_replace_all:Nnn \l__semantex_error_output_format_temp { class_ } { class~\cs:w } \tl_put_right:Nn \l__semantex_error_output_format_temp { \cs_end: } \tl_trim_spaces:N \l__semantex_error_output_format_temp \tl_set_eq:NN #2 \l__semantex_error_output_format_temp } \cs_generate_variant:Nn \semantex_error_output_format:nN { xN } \cs_generate_variant:Nn \msg_error:nnn { nnx } \cs_generate_variant:Nn \msg_error:nnnn { nnxn } \cs_generate_variant:Nn \msg_error:nnnnn { nnxnn } \cs_new_protected:Npn \semantex_msg_error:nn#1#2 { \semantex_error_output_format:xN { #1 } \l__semantex_msg_error_nnn_temp_tl \msg_error:nnx { semantex } { #2 } { \l__semantex_msg_error_nnn_temp_tl } } \cs_new_protected:Npn \semantex_msg_error:nnn#1#2#3 { \semantex_error_output_format:xN { #1 } \l__semantex_msg_error_nnnn_temp_tl \msg_error:nnxn { semantex } { #2 } { \l__semantex_msg_error_nnnn_temp_tl } { #3 } } \cs_generate_variant:Nn \semantex_msg_error:nnn { nnx } \cs_new_protected:Npn \semantex_msg_error:nnnn#1#2#3#4 { \semantex_error_output_format:xN { #1 } \l__semantex_msg_error_nnnnn_temp_tl \msg_error:nnxnn { semantex } { #2 } { \l__semantex_msg_error_nnnnn_temp_tl } { #3 } { #4 } } \cs_new_protected:Npn\semantex_error_key_value_not_found:nnn#1#2#3 { \semantex_msg_error:nnnn { #1 } { key_value_not_found } { #2 } { #3 } } \cs_new_protected:Npn\semantex_error_arg_key_value_not_found:nnn#1#2#3 { \semantex_msg_error:nnnn { #1 } { arg_key_value_not_found } { #2 } { #3 } } \cs_new_protected:Npn\semantex_error_generic:nn#1#2 { \semantex_msg_error:nnn { #1 } { generic_error } { #2 } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % SETTING UP THE BASE CLASS \SemantexBaseObject % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \semantex_define_valuekeys:nn { \semantex_class_to_register:N \SemantexBaseObject } { {definekeys[1]}{execute={ \semantex_define_valuekeys:nn { ##1 } { #1 } }}, } \semantex_new_simple_class:Nw \SemantexBaseObject [ definekeys[1]={ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % THE MOST BASIC KEYS, INCLUDING PROGRAMMING KEYS % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% {execute}{ execute={#1} }, % Yes, this really does make sense % -- check how \semantex_define_valuekeys:nn was defined % Keys for setting up the keyval interface {definekeys}{ execute={ \semantex_define_singlekeys:nn { ##1 } { #1 } } }, {definekeys[0]}{ execute={ \semantex_define_singlekeys:nn { ##1 } { #1 } } }, {definekeys[{0}]}{ execute={ \semantex_define_singlekeys:nn { ##1 } { #1 } } }, {definekeys[{1}]}{ execute={ \semantex_define_valuekeys:nn { ##1 } { #1 } } }, {definekeys[2]}{ execute={ \semantex_define_two_valuekeys:nn { ##1 } { #1 } } }, {definekeys[{2}]}{ execute={ \semantex_define_two_valuekeys:nn { ##1 } { #1 } } }, {definekeys[3]}{ execute={ \semantex_define_three_valuekeys:nn { ##1 } { #1 } } }, {definekeys[{3}]}{ execute={ \semantex_define_three_valuekeys:nn { ##1 } { #1 } } }, {definekeys[4]}{ execute={ \semantex_define_four_valuekeys:nn { ##1 } { #1 } } }, {definekeys[{4}]}{ execute={ \semantex_define_four_valuekeys:nn { ##1 } { #1 } } }, {definekeys[5]}{ execute={ \semantex_define_five_valuekeys:nn { ##1 } { #1 } } }, {definekeys[{5}]}{ execute={ \semantex_define_five_valuekeys:nn { ##1 } { #1 } } }, {definekeys[6]}{ execute={ \semantex_define_six_valuekeys:nn { ##1 } { #1 } } }, {definekeys[{6}]}{ execute={ \semantex_define_six_valuekeys:nn { ##1 } { #1 } } }, {definekeys[7]}{ execute={ \semantex_define_seven_valuekeys:nn { ##1 } { #1 } } }, {definekeys[{7}]}{ execute={ \semantex_define_seven_valuekeys:nn { ##1 } { #1 } } }, {definekeys[8]}{ execute={ \semantex_define_eight_valuekeys:nn { ##1 } { #1 } } }, {definekeys[{8}]}{ execute={ \semantex_define_eight_valuekeys:nn { ##1 } { #1 } } }, {definekeys[9]}{ execute={ \semantex_define_nine_valuekeys:nn { ##1 } { #1 } } }, {definekeys[{9}]}{ execute={ \semantex_define_nine_valuekeys:nn { ##1 } { #1 } } }, {removekey}{ execute={ \semantex_remove_singlekey:nn { ##1 } { #1 } } }, {removekey[0]}{ execute={ \semantex_remove_singlekey:nn { ##1 } { #1 } } }, {removekey[{0}]}{ execute={ \semantex_remove_singlekey:nn { ##1 } { #1 } } }, {removekey[1]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } }, {removekey[{1}]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } }, {removekey[2]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } }, {removekey[{2}]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } }, {removekey[3]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } }, {removekey[{3}]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } }, {removekey[4]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } }, {removekey[{5}]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } }, {removekey[6]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } }, {removekey[{6}]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } }, {removekey[7]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } }, {removekey[{7}]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } }, {removekey[8]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } }, {removekey[{8}]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } }, {removekey[9]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } }, {removekey[{9}]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } }, % Keys for setting up the argument keyval interface: {defineargkeys}{ execute={ \semantex_define_arg_singlekeys:nn { ##1 } { #1 } } }, {defineargkeys[0]}{ execute={ \semantex_define_arg_singlekeys:nn { ##1 } { #1 } } }, {defineargkeys[{0}]}{ execute={ \semantex_define_arg_singlekeys:nn { ##1 } { #1 } } }, {defineargkeys[1]}{ execute={ \semantex_define_arg_valuekeys:nn { ##1 } { #1 } } }, {defineargkeys[{1}]}{ execute={ \semantex_define_arg_valuekeys:nn { ##1 } { #1 } } }, {defineargkeys[2]}{ execute={ \semantex_define_arg_two_valuekeys:nn { ##1 } { #1 } } }, {defineargkeys[{2}]}{ execute={ \semantex_define_arg_two_valuekeys:nn { ##1 } { #1 } } }, {defineargkeys[3]}{ execute={ \semantex_define_arg_three_valuekeys:nn { ##1 } { #1 } } }, {defineargkeys[{3}]}{ execute={ \semantex_define_arg_three_valuekeys:nn { ##1 } { #1 } } }, {defineargkeys[4]}{ execute={ \semantex_define_arg_four_valuekeys:nn { ##1 } { #1 } } }, {defineargkeys[{4}]}{ execute={ \semantex_define_arg_four_valuekeys:nn { ##1 } { #1 } } }, {defineargkeys[5]}{ execute={ \semantex_define_arg_five_valuekeys:nn { ##1 } { #1 } } }, {defineargkeys[{5}]}{ execute={ \semantex_define_arg_five_valuekeys:nn { ##1 } { #1 } } }, {defineargkeys[6]}{ execute={ \semantex_define_arg_six_valuekeys:nn { ##1 } { #1 } } }, {defineargkeys[{6}]}{ execute={ \semantex_define_arg_six_valuekeys:nn { ##1 } { #1 } } }, {defineargkeys[7]}{ execute={ \semantex_define_arg_seven_valuekeys:nn { ##1 } { #1 } } }, {defineargkeys[{7}]}{ execute={ \semantex_define_arg_seven_valuekeys:nn { ##1 } { #1 } } }, {defineargkeys[8]}{ execute={ \semantex_define_arg_eight_valuekeys:nn { ##1 } { #1 } } }, {defineargkeys[{8}]}{ execute={ \semantex_define_arg_eight_valuekeys:nn { ##1 } { #1 } } }, {defineargkeys[9]}{ execute={ \semantex_define_arg_nine_valuekeys:nn { ##1 } { #1 } } }, {defineargkeys[{9}]}{ execute={ \semantex_define_arg_nine_valuekeys:nn { ##1 } { #1 } } }, {removeargkey}{ execute={ \semantex_remove_arg_singlekey:nn { ##1 } { #1 } } }, {removeargkey[0]}{ execute={ \semantex_remove_arg_singlekey:nn { ##1 } { #1 } } }, {removeargkey[{0}]}{ execute={ \semantex_remove_arg_singlekey:nn { ##1 } { #1 } } }, {removeargkey[1]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } }, {removeargkey[{1}]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } }, {removeargkey[2]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } }, {removeargkey[{2}]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } }, {removeargkey[3]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } }, {removeargkey[{3}]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } }, {removeargkey[4]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } }, {removeargkey[{5}]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } }, {removeargkey[6]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } }, {removeargkey[{6}]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } }, {removeargkey[7]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } }, {removeargkey[{7}]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } }, {removeargkey[8]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } }, {removeargkey[{8}]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } }, {removeargkey[9]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } }, {removeargkey[{9}]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } }, % Keys for programming: {dataprovide}{ execute={ \semantex_data_tl_provide:nn { ##1 } { \tl_trim_spaces:n { #1 } } } }, {dataclear}{ execute={ \semantex_data_tl_clear:nn { ##1 } { \tl_trim_spaces:n { #1 } } }, }, {keysset}{ execute={ \semantex_keys_set:nn { ##1 } { #1 } } }, {setkeys}{ execute={ \semantex_keys_set:nn { ##1 } { #1 } } }, {keyssetx}{ execute={ \semantex_keys_set_x:nn { ##1 } { #1 } } }, {setkeysx}{ execute={ \semantex_keys_set_x:nn { ##1 } { #1 } } }, {boolprovide}{ execute={ \semantex_data_bool_provide:nn { ##1 } { \tl_trim_spaces:n { #1 } } }, }, {boolsettrue}{ execute={ \semantex_data_bool_set_true:nn { ##1 } { \tl_trim_spaces:n { #1 } } }, }, {boolsetfalse}{ execute={ \semantex_data_bool_set_false:nn { ##1 } { \tl_trim_spaces:n { #1 } } }, }, {intprovide}{ execute={ \semantex_data_int_provide:nn { ##1 } { \tl_trim_spaces:n { #1 } } }, }, {intclear}{ execute={ \semantex_data_int_clear:nn { ##1 } { \tl_trim_spaces:n { #1 } } }, }, {intincr}{ execute={ \semantex_data_int_incr:nn { ##1 } { \tl_trim_spaces:n { #1 } } }, }, {ERROR}{ execute={ \semantex_error_generic:nn { ##1 } { #1 } }, }, }, definekeys[2]={ {dataset}{ execute={ \semantex_data_tl_set:nnn { ##1 } { \tl_trim_spaces:n { #1 } } { #2 } }, }, {datasetx}{ execute={ \semantex_data_tl_set:nnx { ##1 } { \tl_trim_spaces:n { #1 } } { #2 } }, }, {dataputright}{ execute={ \semantex_data_tl_put_right:nnn { ##1 } { \tl_trim_spaces:n { #1 } } { #2 } }, }, {dataputrightx}{ execute={ \semantex_data_tl_put_right:nnx { ##1 } { \tl_trim_spaces:n { #1 } } { #2 } }, }, {dataputleft}{ execute={ \semantex_data_tl_put_left:nnn { ##1 } { \tl_trim_spaces:n { #1 } } { #2 } }, }, {dataputleftx}{ execute={ \semantex_data_tl_put_left:nnx { ##1 } { \tl_trim_spaces:n { #1 } } { #2 } }, }, {ifblankT}{ execute={ \tl_if_blank:xTF { #1 } { \semantex_keys_set:nn { ##1 } { #2 } } { } }, }, {ifblankF}{ execute={ \tl_if_blank:xTF { #1 } { } { \semantex_keys_set:nn { ##1 } { #2 } } }, }, {boolifT}{ execute={ \semantex_data_bool_get:nnTF { ##1 } { \tl_trim_spaces:n { #1 } } { \semantex_keys_set:nn { ##1 } { #2 } } { } }, }, {boolifF}{ execute={ \semantex_data_bool_get:nnTF { ##1 } { \tl_trim_spaces:n { #1 } } { } { \semantex_keys_set:nn { ##1 } { #2 } } }, }, {intset}{ execute={ \semantex_data_int_set:nnn { ##1 } { \tl_trim_spaces:n { #1 } } { #2 } }, }, {ERRORkeyvaluenotfound}{ execute={ \semantex_error_key_value_not_found:nnn { ##1 } { #1 } { #2 } }, }, {ERRORargkeyvaluenotfound}{ execute={ \semantex_error_arg_key_value_not_found:nnn { ##1 } { #1 } { #2 } }, }, }, definekeys[3]={ {strifeqT}{ execute={ \str_if_eq:xxTF { #1 } { #2 } { \semantex_keys_set:nn { ##1 } { #3 } } { } }, }, {strifeqF}{ execute={ \str_if_eq:xxTF { #1 } { #2 } { } { \semantex_keys_set:nn { ##1 } { #3 } } }, }, {ifblankTF}{ execute={ \tl_if_blank:xTF { #1 } { \semantex_keys_set:nn { ##1 } { #2 } } { \semantex_keys_set:nn { ##1 } { #3 } } }, }, {boolifTF}{ execute={ \semantex_data_bool_get:nnTF { ##1 } { \tl_trim_spaces:n { #1 } } { \semantex_keys_set:nn { ##1 } { #2 } } { \semantex_keys_set:nn { ##1 } { #3 } } }, }, {intifgreaterT}{ execute={ \int_compare:nNnTF { #1 } > { #2 } { \semantex_keys_set:nn { ##1 } { #3 } } { } }, }, {intifgreaterF}{ execute={ \int_compare:nNnTF { #1 } > { #2 } { } { \semantex_keys_set:nn { ##1 } { #3 } } }, }, {intifeqT}{ execute={ \int_compare:nNnTF { #1 } = { #2 } { \semantex_keys_set:nn { ##1 } { #3 } } { } }, }, {intifeqF}{ execute={ \int_compare:nNnTF { #1 } = { #2 } { } { \semantex_keys_set:nn { ##1 } { #3 } } }, }, {intiflessT}{ execute={ \int_compare:nNnTF { #1 } < { #2 } { \semantex_keys_set:nn { ##1 } { #3 } } { } }, }, {intiflessF}{ execute={ \int_compare:nNnTF { #1 } < { #2 } { } { \semantex_keys_set:nn { ##1 } { #3 } } }, }, }, definekeys[4]={ {strifeqTF}{ execute={ \str_if_eq:xxTF { #1 } { #2 } { \semantex_keys_set:nn { ##1 } { #3 } } { \semantex_keys_set:nn { ##1 } { #4 } } }, }, {intifgreaterTF}{ execute={ \int_compare:nNnTF { #1 } > { #2 } { \semantex_keys_set:nn { ##1 } { #3 } } { \semantex_keys_set:nn { ##1 } { #4 } } }, }, {intifeqTF}{ execute={ \int_compare:nNnTF { #1 } = { #2 } { \semantex_keys_set:nn { ##1 } { #3 } } { \semantex_keys_set:nn { ##1 } { #4 } } }, }, {intiflessTF}{ execute={ \int_compare:nNnTF { #1 } < { #2 } { \semantex_keys_set:nn { ##1 } { #3 } } { \semantex_keys_set:nn { ##1 } { #4 } } }, }, }, %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % THE COLLECTION OF SLIGHTLY LESS FUNDAMENTAL KEYS % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% dataprovide=symbol, boolprovide=uppergrading, boolsettrue=uppergrading, boolprovide=output, dataprovide=outputoptions, boolprovide=par, boolsettrue=par, boolprovide=flexpar, dataprovide=parseoptions, dataprovide=mathclass, boolprovide=leftargument, dataprovide=heightphantom, dataprovide=slantingphantom, execute={ \semantex_data_seq_provide:nn { \semantex_this: } { commands_sequence } }, definekeys[1]={ {parent}{ execute={ \semantex_data_parent_set:nn { ##1 } { #1 } } }, {class}{ execute={ \semantex_data_class_set:nn { ##1 } { #1 } } }, {copy}{ execute={ \semantex_data_copy_object:nn { ##1 } { #1 } } }, {mathclass}{ execute={ \semantex_data_tl_set:nnn { ##1 } { mathclass } { #1 } } }, {symbol}{ execute={ \semantex_data_tl_set:nnn { ##1 } { symbol } { #1 } \semantex_data_tl_set:nnn { ##1 } { heightphantom } { #1 } \semantex_data_tl_set:nnn { ##1 } { slantingphantom } { #1 } } }, {symbolputright}{ execute={ \semantex_data_tl_put_right:nnn { ##1 } { symbol } { #1 } } }, {symbolputleft}{ execute={ \semantex_data_tl_put_left:nnn { ##1 } { symbol } { #1 } } }, {heightphantom}{ execute={ \semantex_data_tl_set:nnn { ##1 } { heightphantom } { #1 } } }, {slantingphantom}{ execute={ \semantex_data_tl_set:nnn { ##1 } { slantingphantom } { #1 } } }, {parseoptions}{ execute={ \semantex_add_to_parse_options:nn { ##1 } { #1 } } }, {command}{ execute={ \semantex_data_seq_put_right:nnn { ##1 } { commands_sequence } { #1 } } }, {output}{ execute={ \semantex_set_output:nn { ##1 } { #1 } } }, {outputoptions}{ execute={ \semantex_add_to_output_options:nn { ##1 } { #1 } } }, {dooutput}{ strifeqTF={#1}{true} { boolsettrue={output}, } { strifeqTF={#1}{false} { boolsetfalse={output}, } { ERRORkeyvaluenotfound={dooutput}{#1}, } }, }, {gradingposition}{ strifeqTF={#1}{upper} { boolsettrue={uppergrading}, } { strifeqTF={#1}{lower} { boolsetfalse={uppergrading}, } { ERRORkeyvaluenotfound={gradingposition}{#1}, }, }, }, {gradingpos}{ strifeqTF={#1}{upper} { boolsettrue={uppergrading}, } { strifeqTF={#1}{lower} { boolsetfalse={uppergrading}, } { ERRORkeyvaluenotfound={gradingpos}{#1}, }, }, }, {default}{sepi={#1}}, {degreedefault}{sepd={#1}}, {arg}{ execute={ \semantex_arg_singlekeys_set:nn { ##1 } { #1 } } }, {*withothersep}{ d*withothersep={#1}, }, {**withothersep}{ d**withothersep={#1}, }, }, output=\SemantexBaseObject, definekeys={ {return}{ execute={ \semantex_return:n { ##1 } } }, {innerreturn}{ execute={ \semantex_inner_return:n { ##1 } } }, {rightreturn}{ execute={ \semantex_right_return:n { ##1 } } }, {leftreturn}{ execute={ \semantex_left_return:n { ##1 } } }, {rightindexreturn}{ execute={ \semantex_right_index_return:n { ##1 } } }, {leftindexreturn}{ execute={ \semantex_left_index_return:n { ##1 } } }, {indexreturn}{ leftindexreturn, rightindexreturn }, {rightargreturn}{ execute={ \semantex_right_arg_return:n { ##1 } } }, {leftargreturn}{ execute={ \semantex_left_arg_return:n { ##1 } } }, {argreturn}{ execute={ \semantex_arg_return:n { ##1 } } }, {parse}{ execute={ \semantex_parse:n { ##1 } } }, {clearcommand}{ execute={ \semantex_data_seq_clear:nn { ##1 } { commands_sequence } } }, {dots}{sepidots}, {...}{dots}, {slot}{sepislot}, {-}{slot}, {*}{sepd*}, {**}{sepd**}, }, % The "spar" routine: definekeys={ {spar}{spar=}, }, definekeys[1]={ {spar}{ execute={ \semantex_spar:nn { ##1 } { #1 } } }, {sparsize}{ execute={ \semantex_data_tl_set:nnn { ##1 } { sparsize } { #1 } } }, {leftspar}{ execute={ \semantex_data_tl_set:nnn { ##1 } { leftspar } { #1 } } }, {rightspar}{ execute={ \semantex_data_tl_set:nnn { ##1 } { rightspar } { #1 } } }, }, definekeys[2]={ {otherspar}{ execute={ \semantex_other_spar:nnn { ##1 } { #1 } { #2 } } }, }, definekeys[3]={ {Otherspar}{ execute={ \semantex_other_spar_with_size:nnnn { ##1 } { #1 } { #2 } { #3 } } }, }, leftspar=(, rightspar=), sparsize=normal, % The argument: dataprovide=arg, boolprovide=nextargwithsep, intprovide=numberofarguments, dataprovide=prearg, dataprovide=postarg, definekeys={ {argdots}{setargkeys={...}}, {arg...}{setargkeys={dots}}, {commaargdots}{setargkeys={commadots}}, {commaarg...}{setargkeys={comma...}}, {argslot}{setargkeys={slot}}, {arg-}{setargkeys={-}}, {commaargslot}{setargkeys={commaslot}}, {commaarg-}{setargkeys={comma-}}, {cleararg}{ execute={ \semantex_data_tl_clear:nn { ##1 } { arg } \semantex_data_int_clear:nn { ##1 } { numberofarguments } \semantex_data_bool_set_false:nn { ##1 } { nextargwithsep } } }, {clearprearg}{ execute={ \semantex_data_tl_clear:nn { ##1 } { prearg } } }, {clearpostarg}{ execute={ \semantex_data_tl_clear:nn { ##1 } { postarg } } }, }, definekeys[1]={ {setargkeys}{ execute={ \semantex_arg_keys_set:nn { ##1 } { #1 } } }, {argkeysset}{ execute={ \semantex_arg_keys_set:nn { ##1 } { #1 } } }, {setargkeysx}{ execute={ \semantex_arg_keys_set_x:nn { ##1 } { #1 } } }, {argkeyssetx}{ execute={ \semantex_arg_keys_set_x:nn { ##1 } { #1 } } }, {setargsinglekeys}{ execute={ \semantex_arg_singlekeys_set:nn { ##1 } { #1 } } }, {argsinglekeysset}{ execute={ \semantex_arg_singlekeys_set:nn { ##1 } { #1 } } }, {setargsinglekeysx}{ execute={ \semantex_arg_singlekeys_set_x:nn { ##1 } { #1 } } }, {argsinglekeyssetx}{ execute={ \semantex_arg_singlekeys_set_x:nn { ##1 } { #1 } } }, {setoneargsinglekey}{ execute={ \semantex_arg_singlekey:nn { ##1 } { #1 } } }, {oneargsinglekeyset}{ execute={ \semantex_arg_singlekey:nn { ##1 } { #1 } } }, {setoneargsinglekeyx}{ execute={ \semantex_arg_singlekey_x:nn { ##1 } { #1 } } }, {oneargsinglekeysetx}{ execute={ \semantex_arg_singlekey_x:nn { ##1 } { #1 } } }, {setargwithoutkeyval}{ execute={ \semantex_arg_without_keyval:nn { ##1 } { #1 } } }, {argwithoutkeyvalset}{ execute={ \semantex_arg_without_keyval:nn { ##1 } { #1 } } }, {setargwithoutkeyvalx}{ execute={ \semantex_arg_without_keyval:nx { ##1 } { #1 } } }, {argwithoutkeyvalsetx}{ execute={ \semantex_arg_without_keyval:nx { ##1 } { #1 } } }, {prearg}{ execute={ \semantex_data_tl_put_right:nnn { ##1 } { prearg } { #1 } } }, {postarg}{ execute={ \semantex_data_tl_put_left:nnn { ##1 } { postarg } { #1 } } }, {setargsep}{ execute={ \semantex_data_tl_set:nnn { ##1 } { argsep } { #1 } } }, {setargslot}{ execute={ \semantex_data_tl_set:nnn { ##1 } { argslot } { #1 } } }, {setargdots}{ execute={ \semantex_data_tl_set:nnn { ##1 } { argdots } { #1 } } }, {argkeyval}{ strifeqTF={#1}{true} { definekeys[1]={ {arg}{execute={ \semantex_arg_keys_set:nn { ########1 } { ####1 } }}, }, } { strifeqTF={#1}{false} { definekeys[1]={ {arg}{ execute={ \semantex_arg_without_keyval:nn { ########1 } { ####1 } } }, }, } { strifeqTF={#1}{singlekeys} { definekeys[1]={ {arg}{ execute={ \semantex_arg_singlekeys_set:nn { ########1 } { ####1 } } }, }, } { strifeqTF={#1}{onesinglekey} { definekeys[1]={ {arg}{ execute={ \semantex_arg_singlekey:nn { ########1 } { ####1 } } }, }, } { ERRORkeyvaluenotfound={argkeyval}{#1}, }, }, }, }, }, {argposition}{ strifeqTF={#1}{left} { boolsettrue={leftargument}, } { strifeqTF={#1}{right} { boolsetfalse={leftargument}, } { ERRORkeyvaluenotfound={argposition}{#1}, }, }, }, {nextargwithsep}{ strifeqTF={#1}{true} { boolsettrue={nextargwithsep}, } { strifeqTF={#1}{false} { boolsetfalse={nextargwithsep}, } { ERRORkeyvaluenotfound={nextargwithsep}{#1}, }, }, }, {separg}{setargkeys={sep={#1}}}, {commaarg}{setargkeys={comma={#1}}}, {argdotswithothersep}{setargkeys={dotswithothersep={#1}}}, {arg...withothersep}{setargkeys={dotswithothersep={#1}}}, {argslotwithothersep}{setargkeys={slotwithothersep={#1}}}, {arg-withothersep}{setargkeys={slotwithothersep={#1}}}, }, definekeys[2]={ {argwithothersep}{setargkeys={othersep={#1}{#2}}}, }, setargsep={,}, setargslot={ {-} }, setargdots={ \dots }, % Parentheses: definekeys={ {par}{usepar=true}, {neverpar}{usepar=never}, {nopar}{usepar=false}, }, definekeys[1]={ {par}{ execute={ \semantex_data_tl_set:nnn { ##1 } { parsize } { #1 } \semantex_data_bool_set_true:nn { ##1 } { par } }, }, {parsize}{ execute={ \semantex_data_tl_set:nnn { ##1 } { parsize } { #1 } }, }, {leftpar}{ execute={ \semantex_data_tl_set:nnn { ##1 } { leftpar } { #1 } }, }, {rightpar}{ execute={ \semantex_data_tl_set:nnn { ##1 } { rightpar } { #1 } }, }, {usepar}{ strifeqTF={#1}{true} { boolsettrue={par}, boolsetfalse={flexpar}, } { strifeqTF={#1}{false} { boolsetfalse={par}, boolsettrue={flexpar}, } { strifeqTF={#1}{never} { boolsetfalse={par}, boolsetfalse={flexpar}, } { ERRORkeyvaluenotfound={usepar}{#1}, }, }, }, }, }, leftpar=(, rightpar=), par=normal, % Accents, primes, bullets, etc.: definekeys={ {smash}{command=\smash}, {prime}{upper={\prime},nextupperwithsep=false}, {'}{prime}, {''}{prime,prime}, {'''}{prime,prime,prime}, }, % Upper indices: dataprovide=upper, boolprovide=nextupperwithsep, intprovide=numberofupperindices, dataprovide=preupper, dataprovide=postupper, definekeys={ {upperslot}{ setkeysx={ upper=\semantex_data_tl_get_exp_not:nn { ##1 } { upperslot } } }, {upper-}{upperslot}, {sepupperslot}{ setkeysx={ sepupper=\semantex_data_tl_get_exp_not:nn { ##1 } { upperslot } } }, {sepupper-}{sepupperslot}, {commaupperslot}{ setkeysx={ commaupper=\semantex_data_tl_get_exp_not:nn { ##1 } { upperslot } } }, {commaupper-}{commaupperslot}, {upperdots}{ setkeysx={ upper=\semantex_data_tl_get_exp_not:nn { ##1 } { upperdots } } }, {upper...}{upperdots}, {sepupperdots}{ setkeysx={ sepupper=\semantex_data_tl_get_exp_not:nn { ##1 } { upperdots } } }, {sepupper...}{sepupperdots}, {commaupperdots}{ setkeysx={ commaupper=\semantex_data_tl_get_exp_not:nn { ##1 } { upperdots } } }, {commaupper...}{commaupperdots}, {clearupper}{ execute={ \semantex_data_tl_clear:nn { ##1 } { upper } \semantex_data_bool_set_false:nn { ##1 } { nextupperwithsep } \semantex_data_int_clear:nn { ##1 } { numberofupperindices } }, }, {clearpreupper}{ execute={ \semantex_data_tl_clear:nn { ##1 } { preupper } }, }, {clearpostupper}{ execute={ \semantex_data_tl_clear:nn { ##1 } { postupper } }, }, {upper*}{upper=\SemantexBullet}, {upper**}{upper=\SemantexDoubleBullet}, {sepupper*}{sepupper=\SemantexBullet}, {sepupper**}{sepupper=\SemantexDoubleBullet}, {commaupper*}{commaupper=\SemantexBullet}, {commaupper**}{commaupper=\SemantexDoubleBullet}, }, definekeys[1]={ {upper}{ execute={ \tl_if_blank:nF { #1 } { \semantex_data_tl_put_right:nnn { ##1 } { upper } { #1 } \semantex_data_bool_set_true:nn { ##1 } { nextupperwithsep } \semantex_data_int_incr:nn { ##1 } { numberofupperindices } } }, }, {sepupper}{ execute={ \tl_if_blank:nF { #1 } { \semantex_data_bool_get:nnTF { ##1 } { nextupperwithsep } { \semantex_data_tl_put_right:nnx { ##1 } { upper } { \semantex_data_tl_get_exp_not:nn { ##1 } { uppersep } } \semantex_data_tl_put_right:nnn { ##1 } { upper } { #1 } } { \semantex_data_tl_put_right:nnn { ##1 } { upper } { #1 } } \semantex_data_bool_set_true:nn { ##1 } { nextupperwithsep } \semantex_data_int_incr:nn { ##1 } { numberofupperindices } } }, }, {commaupper}{ execute={ \tl_if_blank:nF{#1} { \semantex_data_bool_get:nnTF { ##1 } { nextupperwithsep } { \semantex_data_tl_put_right:nnn { ##1 } { upper } { , #1 } } { \semantex_data_tl_put_right:nnn { ##1 } { upper } { #1 } } \semantex_data_bool_set_true:nn { ##1 } { nextupperwithsep } \semantex_data_int_incr:nn { ##1 } { numberofupperindices } } } }, {preupper}{ execute={ \tl_if_blank:nF{#1}{ \semantex_data_tl_put_right:nnn { ##1 } { preupper } { #1 } } }, }, {postupper}{ execute={ \tl_if_blank:nF{#1}{ \semantex_data_tl_put_left:nnn { ##1 } { postupper } { #1 } } }, }, {upperputleft}{ execute={ \tl_if_blank:nF { #1 } { \semantex_data_tl_put_left:nnn { ##1 } { upper } { #1 } \semantex_data_bool_set_true:nn { ##1 } { nextupperwithsep } \semantex_data_int_incr:nn { ##1 } { numberofupperindices } } }, }, {setupperslot}{ execute={ \semantex_data_tl_set:nnn { ##1 } { upperslot } { #1 } }, }, {upperslotwithothersep}{ execute={ \semantex_valuekey:nnx { ##1 } { upperwithothersep } { { \exp_not:n { #1 } } { \semantex_data_tl_get_exp_not:nn { ##1 } { upperslot } } } }, }, {upper-withothersep}{ execute={ \semantex_valuekey:nnx { ##1 } { upperwithothersep } { { \exp_not:n { #1 } } { \semantex_data_tl_get_exp_not:nn { ##1 } { upperslot } } } }, }, {setupperdots}{ execute={ \semantex_data_tl_set:nnn { ##1 } { upperdots } { #1 } }, }, {upperdotswithothersep}{ execute={ \semantex_valuekey:nnx { ##1 } { upperwithothersep } { { \exp_not:n { #1 } } { \semantex_data_tl_get_exp_not:nn { ##1 } { upperdots } } } }, }, {upper...withothersep}{ execute={ \semantex_valuekey:nnx { ##1 } { upperwithothersep } { { \exp_not:n { #1 } } { \semantex_data_tl_get_exp_not:nn { ##1 } { upperdots } } } }, }, {upper*withothersep}{upperwithothersep={#1}{\SemantexBullet}}, {upper**withothersep}{upperwithothersep={#1}{\SemantexDoubleBullet}}, {setuppersep}{ execute={ \semantex_data_tl_set:nnn { ##1 } { uppersep } { #1 } }, }, {nextupperwithsep}{ strifeqTF={#1}{false} { boolsetfalse={nextupperwithsep}, } { strifeqTF={#1}{true} { boolsettrue={nextupperwithsep}, } { ERRORkeyvaluenotfound={nextupperwithsep}{#1}, }, }, }, }, definekeys[2]={ {upperwithothersep}{ execute={ \semantex_data_bool_get:nnTF { ##1 } { nextupperwithsep } { \semantex_data_tl_put_right:nnn { ##1 } { upper } { #1 #2 } } { \semantex_data_tl_put_right:nnn { ##1 } { upper } { #2 } } \semantex_data_bool_set_true:nn { ##1 } { nextupperwithsep } \semantex_data_int_incr:nn { ##1 } { numberofupperindices } }, }, }, setuppersep={ , }, setupperdots={ \dots }, setupperslot={ {-} }, % Lower indices: dataprovide=lower, boolprovide=nextlowerwithsep, intprovide=numberoflowerindices, dataprovide=prelower, dataprovide=postlower, definekeys={ {lowerslot}{ setkeysx={ lower=\semantex_data_tl_get_exp_not:nn { ##1 } { lowerslot } } }, {lower-}{lowerslot}, {seplowerslot}{ setkeysx={ seplower=\semantex_data_tl_get_exp_not:nn { ##1 } { lowerslot } } }, {seplower-}{seplowerslot}, {commalowerslot}{ setkeysx={ commalower=\semantex_data_tl_get_exp_not:nn { ##1 } { lowerslot } } }, {commalower-}{commalowerslot}, {lowerdots}{ setkeysx={ lower=\semantex_data_tl_get_exp_not:nn { ##1 } { lowerdots } } }, {lower...}{lowerdots}, {seplowerdots}{ setkeysx={ seplower=\semantex_data_tl_get_exp_not:nn { ##1 } { lowerdots } } }, {seplower...}{seplowerdots}, {commalowerdots}{ setkeysx={ commalower=\semantex_data_tl_get_exp_not:nn { ##1 } { lowerdots } } }, {commalower...}{commalowerdots}, {clearlower}{ execute={ \semantex_data_tl_clear:nn { ##1 } { lower } \semantex_data_bool_set_false:nn { ##1 } { nextlowerwithsep } \semantex_data_int_clear:nn { ##1 } { numberoflowerindices } }, }, {clearprelower}{ execute={ \semantex_data_tl_clear:nn { ##1 } { prelower } }, }, {clearpostlower}{ execute={ \semantex_data_tl_clear:nn { ##1 } { postlower } }, }, {lower*}{lower=\SemantexBullet}, {lower**}{lower=\SemantexDoubleBullet}, {seplower*}{seplower=\SemantexBullet}, {seplower**}{seplower=\SemantexDoubleBullet}, {commalower*}{commalower=\SemantexBullet}, {commalower**}{commalower=\SemantexDoubleBullet}, }, definekeys[1]={ {lower}{ execute={ \tl_if_blank:nF{#1}{ \semantex_data_tl_put_right:nnn { ##1 } { lower } { #1 } \semantex_data_bool_set_true:nn { ##1 } { nextlowerwithsep } \semantex_data_int_incr:nn { ##1 } { numberoflowerindices } } }, }, {seplower}{ execute={ \tl_if_blank:nF { #1 } { \semantex_data_bool_get:nnTF { ##1 } { nextlowerwithsep } { \semantex_data_tl_put_right:nnx { ##1 } { lower } { \semantex_data_tl_get_exp_not:nn { ##1 } { lowersep } } \semantex_data_tl_put_right:nnn { ##1 } { lower } { #1 } } { \semantex_data_tl_put_right:nnn { ##1 } { lower } { #1 } } \semantex_data_bool_set_true:nn { ##1 } { nextlowerwithsep } \semantex_data_int_incr:nn { ##1 } { numberoflowerindices } } }, }, {commalower}{ execute={ \tl_if_blank:nF{#1} { \semantex_data_bool_get:nnTF { ##1 } { nextlowerwithsep } { \semantex_data_tl_put_right:nnn { ##1 } { lower } { , #1 } } { \semantex_data_tl_put_right:nnn { ##1 } { lower } { #1 } } \semantex_data_bool_set_true:nn { ##1 } { nextlowerwithsep } \semantex_data_int_incr:nn { ##1 } { numberoflowerindices } } } }, {prelower}{ execute={ \tl_if_blank:nF{#1}{ \semantex_data_tl_put_right:nnn { ##1 } { prelower } { #1 } } }, }, {postlower}{ execute={ \tl_if_blank:nF{#1}{ \semantex_data_tl_put_left:nnn { ##1 } { postlower } { #1 } } }, }, {lowerputleft}{ execute={ \tl_if_blank:nF { #1 } { \semantex_data_tl_put_left:nnn { ##1 } { lower } { #1 } \semantex_data_bool_set_true:nn { ##1 } { nextlowerwithsep } \semantex_data_int_incr:nn { ##1 } { numberoflowerindices } } }, }, {setlowerslot}{ execute={ \semantex_data_tl_set:nnn { ##1 } { lowerslot } { #1 } }, }, {lowerslotwithothersep}{ execute={ \semantex_valuekey:nnx { ##1 } { lowerwithothersep } { { \exp_not:n { #1 } } { \semantex_data_tl_get_exp_not:nn { ##1 } { lowerslot } } } }, }, {lower-withothersep}{ execute={ \semantex_valuekey:nnx { ##1 } { lowerwithothersep } { { \exp_not:n { #1 } } { \semantex_data_tl_get_exp_not:nn { ##1 } { lowerslot } } } }, }, {setlowerdots}{ execute={ \semantex_data_tl_set:nnn { ##1 } { lowerdots } { #1 } }, }, {lowerdotswithothersep}{ execute={ \semantex_valuekey:nnx { ##1 } { lowerwithothersep } { { \exp_not:n { #1 } } { \semantex_data_tl_get_exp_not:nn { ##1 } { lowerdots } } } }, }, {lower...withothersep}{ execute={ \semantex_valuekey:nnx { ##1 } { lowerwithothersep } { { \exp_not:n { #1 } } { \semantex_data_tl_get_exp_not:nn { ##1 } { lowerdots } } } }, }, {lower*withothersep}{lowerwithothersep={#1}{\SemantexBullet}}, {lower**withothersep}{lowerwithothersep={#1}{\SemantexDoubleBullet}}, {setlowersep}{ execute={ \semantex_data_tl_set:nnn { ##1 } { lowersep } { #1 } }, }, {nextlowerwithsep}{ strifeqTF={#1}{false} { boolsetfalse={nextlowerwithsep}, } { strifeqTF={#1}{true} { boolsettrue={nextlowerwithsep}, } { ERRORkeyvaluenotfound={nextlowerwithsep}{#1}, }, }, }, }, definekeys[2]={ {lowerwithothersep}{ execute={ \semantex_data_bool_get:nnTF { ##1 } { nextlowerwithsep } { \semantex_data_tl_put_right:nnn { ##1 } { lower } { #1 #2 } } { \semantex_data_tl_put_right:nnn { ##1 } { lower } { #2 } } \semantex_data_bool_set_true:nn { ##1 } { nextlowerwithsep } \semantex_data_int_incr:nn { ##1 } { numberoflowerindices } }, }, }, setlowersep={ , }, setlowerdots={ \dots }, setlowerslot={ {-} }, % Upper left indices: dataprovide=upperleft, intprovide=nextupperleftwithsep, intprovide=numberofupperleftindices, dataprovide=preupperleft, dataprovide=postupperleft, definekeys={ {upperleftslot}{ setkeysx={ upperleft=\semantex_data_tl_get_exp_not:nn { ##1 } { upperleftslot } } }, {upperleft-}{upperleftslot}, {sepupperleftslot}{ setkeysx={ sepupperleft=\semantex_data_tl_get_exp_not:nn { ##1 } { upperleftslot } } }, {sepupperleft-}{sepupperleftslot}, {commaupperleftslot}{ setkeysx={ commaupperleft=\semantex_data_tl_get_exp_not:nn { ##1 } { upperleftslot } } }, {commaupperleft-}{commaupperleftslot}, {upperleftdots}{ setkeysx={ upperleft=\semantex_data_tl_get_exp_not:nn { ##1 } { upperleftdots } } }, {upperleft...}{upperleftdots}, {sepupperleftdots}{ setkeysx={ sepupperleft=\semantex_data_tl_get_exp_not:nn { ##1 } { upperleftdots } } }, {sepupperleft...}{sepupperleftdots}, {commaupperleftdots}{ setkeysx={ commaupperleft=\semantex_data_tl_get_exp_not:nn { ##1 } { upperleftdots } } }, {commaupperleft...}{commaupperleftdots}, {clearupperleft}{ execute={ \semantex_data_tl_clear:nn { ##1 } { upperleft } \semantex_data_bool_set_false:nn { ##1 } { nextupperleftwithsep } \semantex_data_int_clear:nn { ##1 } { numberofupperleftindices } }, }, {clearpreupperleft}{ execute={ \semantex_data_tl_clear:nn { ##1 } { preupperleft } }, }, {clearpostupperleft}{ execute={ \semantex_data_tl_clear:nn { ##1 } { postupperleft } }, }, {upperleft*}{upperleft=\SemantexBullet}, {upperleft**}{upperleft=\SemantexDoubleBullet}, {sepupperleft*}{sepupperleft=\SemantexBullet}, {sepupperleft**}{sepupperleft=\SemantexDoubleBullet}, {commaupperleft*}{commaupperleft=\SemantexBullet}, {commaupperleft**}{commaupperleft=\SemantexDoubleBullet}, }, definekeys[1]={ {upperleft}{ execute={ \tl_if_blank:nF{#1}{ \semantex_data_tl_put_left:nnn { ##1 } { upperleft } { #1 } \semantex_data_bool_set_true:nn { ##1 } { nextupperleftwithsep } \semantex_data_int_incr:nn { ##1 } { numberofupperleftindices } } }, }, {sepupperleft}{ execute={ \tl_if_blank:nF { #1 } { \semantex_data_bool_get:nnTF { ##1 } { nextupperleftwithsep } { \semantex_data_tl_put_left:nnx { ##1 } { upperleft } { \semantex_data_tl_get_exp_not:nn { ##1 } { upperleftsep } } \semantex_data_tl_put_left:nnn { ##1 } { upperleft } { #1 } } { \semantex_data_tl_put_left:nnn { ##1 } { upperleft } { #1 } } \semantex_data_bool_set_true:nn { ##1 } { nextupperleftwithsep } \semantex_data_int_incr:nn { ##1 } { numberofupperleftindices } } }, }, {commaupperleft}{ execute={ \tl_if_blank:nF{#1} { \semantex_data_bool_get:nnTF { ##1 } { nextupperleftwithsep } { \semantex_data_tl_put_left:nnn { ##1 } { upperleft } { , #1 } } { \semantex_data_tl_put_left:nnn { ##1 } { upperleft } { #1 } } \semantex_data_bool_set_true:nn { ##1 } { nextupperleftwithsep } \semantex_data_int_incr:nn { ##1 } { numberofupperleftindices } } } }, {preupperleft}{ execute={ \tl_if_blank:nF{#1}{ \semantex_data_tl_put_right:nnn { ##1 } { preupperleft } { #1 } } }, }, {postupperleft}{ execute={ \tl_if_blank:nF{#1}{ \semantex_data_tl_put_left:nnn { ##1 } { postupperleft } { #1 } } }, }, {upperleftputright}{ execute={ \tl_if_blank:nF { #1 } { \semantex_data_tl_put_right:nnn { ##1 } { upperleft } { #1 } \semantex_data_bool_set_true:nn { ##1 } { nextupperleftwithsep } \semantex_data_int_incr:nn { ##1 } { numberofupperleftindices } } }, }, {setupperleftslot}{ execute={ \semantex_data_tl_set:nnn { ##1 } { upperleftslot } { #1 } }, }, {upperleftslotwithothersep}{ execute={ \semantex_valuekey:nnx { ##1 } { upperleftwithothersep } { { \exp_not:n { #1 } } { \semantex_data_tl_get_exp_not:nn { ##1 } { upperleftslot } } } }, }, {upperleft-withothersep}{ execute={ \semantex_valuekey:nnx { ##1 } { upperleftwithothersep } { { \exp_not:n { #1 } } { \semantex_data_tl_get_exp_not:nn { ##1 } { upperleftslot } } } }, }, {setupperleftdots}{ execute={ \semantex_data_tl_set:nnn { ##1 } { upperleftdots } { #1 } }, }, {upperleftdotswithothersep}{ execute={ \semantex_valuekey:nnx { upperleftwithothersep } { { \exp_not:n { #1 } } { \semantex_data_tl_get_exp_not:nn { ##1 } { upperleftdots } } } }, }, {upperleft...withothersep}{ execute={ \semantex_valuekey:nnx { upperleftwithothersep } { { \exp_not:n { #1 } } { \semantex_data_tl_get_exp_not:nn { ##1 } { upperleftdots } } } }, }, {upperleft*withothersep}{upperleftwithothersep={#1}{\SemantexBullet}}, {upperleft**withothersep}{upperleftwithothersep={#1}{\SemantexDoubleBullet}}, {setupperleftsep}{ execute={ \semantex_data_tl_set:nnn { ##1 } { upperleftsep } { #1 } }, }, {nextupperleftwithsep}{ strifeqTF={#1}{false} { boolsetfalse={nextupperleftwithsep}, } { strifeqTF={#1}{true} { boolsettrue={nextupperleftwithsep}, } { ERRORkeyvaluenotfound={nextupperleftwithsep}{#1}, }, }, }, }, definekeys[2]={ {upperleftwithothersep}{ execute={ \semantex_data_bool_get:nnTF { ##1 } { nextupperleftwithsep } { \semantex_data_tl_put_left:nnn { ##1 } { upperleft } { #2 #1 } } { \semantex_data_tl_put_left:nnn { ##1 } { upperleft } { #2 } } \semantex_data_bool_set_true:nn { ##1 } { nextupperleftwithsep } \semantex_data_int_incr:nn { ##1 } { numberofupperleftindices } }, }, }, setupperleftsep={ , }, setupperleftdots={ \dots }, setupperleftslot={ {-} }, % Lower left indices: dataprovide=lowerleft, boolprovide=nextlowerleftwithsep, intprovide=numberoflowerleftindices, dataprovide=prelowerleft, dataprovide=postlowerleft, definekeys={ {lowerleftslot}{ setkeysx={ lowerleft=\semantex_data_tl_get_exp_not:nn { ##1 } { lowerleftslot } } }, {lowerleft-}{lowerleftslot}, {seplowerleftslot}{ setkeysx={ seplowerleft=\semantex_data_tl_get_exp_not:nn { ##1 } { lowerleftslot } } }, {seplowerleft-}{seplowerleftslot}, {commalowerleftslot}{ setkeysx={ commalowerleft=\semantex_data_tl_get_exp_not:nn { ##1 } { lowerleftslot } } }, {commalowerleft-}{commalowerleftslot}, {lowerleftdots}{ setkeysx={ lowerleft=\semantex_data_tl_get_exp_not:nn { ##1 } { lowerleftdots } } }, {lowerleft...}{lowerleftdots}, {seplowerleftdots}{ setkeysx={ seplowerleft=\semantex_data_tl_get_exp_not:nn { ##1 } { lowerleftdots } } }, {seplowerleft...}{seplowerleftdots}, {commalowerleftdots}{ setkeysx={ commalowerleft=\semantex_data_tl_get_exp_not:nn { ##1 } { lowerleftdots } } }, {commalowerleft...}{commalowerleftdots}, {clearlowerleft}{ execute={ \semantex_data_tl_clear:nn { ##1 } { lowerleft } \semantex_data_bool_set_false:nn { ##1 } { nextlowerleftwithsep } \semantex_data_int_clear:nn { ##1 } { numberoflowerleftindices } }, }, {clearprelowerleft}{ execute={ \semantex_data_tl_clear:nn { ##1 } { prelowerleft } }, }, {clearpostlowerleft}{ execute={ \semantex_data_tl_clear:nn { ##1 } { postlowerleft } }, }, {lowerleft*}{lowerleft=\SemantexBullet}, {lowerleft**}{lowerleft=\SemantexDoubleBullet}, {seplowerleft*}{seplowerleft=\SemantexBullet}, {seplowerleft**}{seplowerleft=\SemantexDoubleBullet}, {commalowerleft*}{commalowerleft=\SemantexBullet}, {commalowerleft**}{commalowerleft=\SemantexDoubleBullet}, }, definekeys[1]={ {lowerleft}{ execute={ \tl_if_blank:nF{#1}{ \semantex_data_tl_put_left:nnn { ##1 } { lowerleft } { #1 } \semantex_data_bool_set_true:nn { ##1 } { nextlowerleftwithsep } \semantex_data_int_incr:nn { ##1 } { numberoflowerleftindices } } }, }, {seplowerleft}{ execute={ \tl_if_blank:nF { #1 } { \semantex_data_bool_get:nnTF { ##1 } { nextlowerleftwithsep } { \semantex_data_tl_put_left:nnx { ##1 } { lowerleft } { \semantex_data_tl_get_exp_not:nn { ##1 } { lowerleftsep } } \semantex_data_tl_put_left:nnn { ##1 } { lowerleft } { #1 } } { \semantex_data_tl_put_left:nnn { ##1 } { lowerleft } { #1 } } \semantex_data_bool_set_true:nn { ##1 } { nextlowerleftwithsep } \semantex_data_int_incr:nn { ##1 } { numberoflowerleftindices } } }, }, {commalowerleft}{ execute={ \tl_if_blank:nF{#1} { \semantex_data_bool_get:nnTF { ##1 } { nextlowerleftwithsep } { \semantex_data_tl_put_left:nnn { ##1 } { lowerleft } { , #1 } } { \semantex_data_tl_put_left:nnn { ##1 } { lowerleft } { #1 } } \semantex_data_bool_set_true:nn { ##1 } { nextlowerleftwithsep } \semantex_data_int_incr:nn { ##1 } { numberoflowerleftindices } } } }, {prelowerleft}{ execute={ \tl_if_blank:nF{#1}{ \semantex_data_tl_put_right:nnn { ##1 } { prelowerleft } { #1 } } }, }, {postlowerleft}{ execute={ \tl_if_blank:nF{#1}{ \semantex_data_tl_put_left:nnn { ##1 } { postlowerleft } { #1 } } }, }, {lowerleftputright}{ execute={ \tl_if_blank:nF { #1 } { \semantex_data_tl_put_right:nnn { ##1 } { lowerleft } { #1 } \semantex_data_bool_set_true:nn { ##1 } { nextlowerleftwithsep } \semantex_data_int_incr:nn { ##1 } { numberoflowerleftindices } } }, }, {setlowerleftslot}{ execute={ \semantex_data_tl_set:nnn { ##1 } { lowerleftslot } { #1 } }, }, {lowerleftslotwithothersep}{ execute={ \semantex_valuekey:nnx { ##1 } { lowerleftwithothersep } { { \exp_not:n { #1 } } { \semantex_data_tl_get_exp_not:nn { ##1 } { lowerleftslot } }, } }, }, {lowerleft-withothersep}{ execute={ \semantex_valuekey:nnx { ##1 } { lowerleftwithothersep } { { \exp_not:n { #1 } } { \semantex_data_tl_get_exp_not:nn { ##1 } { lowerleftslot } }, } }, }, {setlowerleftdots}{ execute={ \semantex_data_tl_set:nnn { ##1 } { lowerleftdots } { #1 } }, }, {lowerleftdotswithothersep}{ execute={ \semantex_valuekey:nnx { ##1 } { lowerleftwithothersep } { { \exp_not:n { #1 } } { \semantex_data_tl_get_exp_not:nn { ##1 } { lowerleftdots } } } }, }, {lowerleft...withothersep}{ execute={ \semantex_valuekey:nnx { ##1 } { lowerleftwithothersep } { { \exp_not:n { #1 } } { \semantex_data_tl_get_exp_not:nn { ##1 } { lowerleftdots } } } }, }, {lowerleft*withothersep}{lowerleftwithothersep={#1}{\SemantexBullet}}, {lowerleft**withothersep}{lowerleftwithothersep={#1}{\SemantexDoubleBullet}}, {setlowerleftsep}{ execute={ \semantex_data_tl_set:nnn { ##1 } { lowerleftsep } { #1 } }, }, {nextlowerleftwithsep}{ strifeqTF={#1}{false} { boolsetfalse={nextlowerleftwithsep}, } { strifeqTF={#1}{true} { boolsettrue={nextlowerleftwithsep}, } { ERRORkeyvaluenotfound={nextlowerleftwithsep}{#1}, }, }, }, }, definekeys[2]={ {lowerleftwithothersep}{ execute={ \semantex_data_bool_get:nnTF { ##1 } { nextlowerleftwithsep } { \semantex_data_tl_put_left:nnn { ##1 } { lowerleft } { #2 #1 } } { \semantex_data_tl_put_left:nnn { ##1 } { lowerleft } { #2 } } \semantex_data_bool_set_true:nn { ##1 } { nextlowerleftwithsep } \semantex_data_int_incr:nn { ##1 } { numberoflowerleftindices } }, }, }, setlowerleftsep={ , }, setlowerleftdots={ \dots }, setlowerleftslot={ {-} }, % The "d" index: definekeys={ {dslot}{ boolifTF={uppergrading} { upperslot } { lowerslot }, }, {d-}{dslot}, {sepdslot}{ boolifTF={uppergrading} { sepupperslot } { seplowerslot }, }, {sepd-}{sepdslot}, {commadslot}{ boolifTF={uppergrading} { commaupperslot } { commalowerslot }, }, {commad-}{commadslot}, {ddots}{ boolifTF={uppergrading} { upperdots } { lowerdots }, }, {d...}{ddots}, {sepddots}{ boolifTF={uppergrading} { sepupperdots } { seplowerdots }, }, {sepd...}{sepddots}, {commaddots}{ boolifTF={uppergrading} { commaupperdots } { commalowerdots }, }, {commad...}{commaddots}, {cleard}{ boolifTF={uppergrading} { clearupper } { clearlower }, }, {clearpred}{ boolifTF={uppergrading} { clearpreupper } { clearprelower }, }, {clearpostd}{ boolifTF={uppergrading} { clearpostupper } { clearpostlower }, }, {d*}{ boolifTF={uppergrading} { upper* } { lower* }, }, {d**}{ boolifTF={uppergrading} { upper** } { lower** }, }, {sepd*}{ boolifTF={uppergrading} { sepupper* } { seplower* }, }, {sepd**}{ boolifTF={uppergrading} { sepupper** } { seplower** }, }, {commad*}{ boolifTF={uppergrading} { commaupper* } { commalower* }, }, {commad**}{ boolifTF={uppergrading} { commaupper** } { commalower** }, }, }, definekeys[1]={ {d}{ execute={ \semantex_data_bool_get:nnTF { ##1 } { uppergrading } { \semantex_valuekey:nnn { ##1 } { upper } { #1 } } { \semantex_valuekey:nnn { ##1 } { lower } { #1 } } }, }, {sepd}{ execute={ \semantex_data_bool_get:nnTF { ##1 } { uppergrading } { \semantex_valuekey:nnn { ##1 } { sepupper } { #1 } } { \semantex_valuekey:nnn { ##1 } { seplower } { #1 } } }, }, {commad}{ execute={ \semantex_data_bool_get:nnTF { ##1 } { uppergrading } { \semantex_valuekey:nnn { ##1 } { commaupper } { #1 } } { \semantex_valuekey:nnn { ##1 } { commalower } { #1 } } }, }, {pred}{ boolifTF={uppergrading} { preupper={#1}, } { prelower={#1}, }, }, {postd}{ boolifTF={uppergrading} { postupper={#1}, } { postlower={#1}, }, }, {dputleft}{ boolifTF={uppergrading} { upperputleft={#1}, } { lowerputleft={#1}, }, }, {setdslot}{ boolifTF={uppergrading} { setupperslot={#1}, } { setlowerslot={#1}, } }, {dslotwithothersep}{ boolifTF={uppergrading} { upperslotwithothersep={#1}, } { lowerslotwithothersep={#1}, }, }, {d-withothersep}{ dslotwithothersep={#1}, }, {setddots}{ boolifTF={uppergrading} { setupperdots={#1}, } { setlowerdots={#1}, } }, {ddotswithothersep}{ boolifTF={uppergrading} { upperdotswithothersep={#1}, } { lowerdotswithothersep={#1}, }, }, {d...withothersep}{ ddotswithothersep={#1}, }, {d*withothersep}{ boolifTF={uppergrading} { upper*withothersep={#1} } { lower*withothersep={#1} }, }, {d**withothersep}{ boolifTF={uppergrading} { upper**withothersep={#1} } { lower**withothersep={#1} }, }, {setdsep}{ boolifTF={uppergrading} { setuppersep={#1}, } { setlowersep={#1}, }, }, {nextdwithsep}{ strifeqTF={#1}{true} { boolifTF={uppergrading} { nextupperwithsep=true, } { nextlowerwithsep=true, }, } { strifeqTF={#1}{false} { boolifTF={uppergrading} { nextupperwithsep=false, } { nextlowerwithsep=false, }, } { ERRORkeyvaluenotfound={nextdwithothersep}{#1}, }, }, }, }, definekeys[2]={ {dwithothersep}{ boolifTF={uppergrading} { upperwithothersep={#1}{#2}, } { lowerwithothersep={#1}{#2}, }, }, }, % The "i" index: definekeys={ {islot}{ boolifTF={uppergrading} { lowerslot } { upperslot }, }, {i-}{islot}, {sepislot}{ boolifTF={uppergrading} { seplowerslot } { sepupperslot }, }, {sepi-}{sepislot}, {commaislot}{ boolifTF={uppergrading} { commalowerslot } { commaupperslot }, }, {commai-}{commaislot}, {idots}{ boolifTF={uppergrading} { lowerdots } { upperdots }, }, {i...}{idots}, {sepidots}{ boolifTF={uppergrading} { seplowerdots } { sepupperdots }, }, {sepi...}{sepidots}, {commaidots}{ boolifTF={uppergrading} { commalowerdots } { commaupperdots }, }, {commai...}{commaidots}, {cleari}{ boolifTF={uppergrading} { clearlower } { clearupper }, }, {clearprei}{ boolifTF={uppergrading} { clearprelower } { clearpreupper }, }, {clearposti}{ boolifTF={uppergrading} { clearpostlower } { clearpostupper }, }, {i*}{ boolifTF={uppergrading} { lower* } { upper* }, }, {i**}{ boolifTF={uppergrading} { lower** } { upper** }, }, {sepi*}{ boolifTF={uppergrading} { seplower* } { sepupper* }, }, {sepi**}{ boolifTF={uppergrading} { seplower** } { sepupper** }, }, {commai*}{ boolifTF={uppergrading} { commalower* } { commaupper* }, }, {commai**}{ boolifTF={uppergrading} { commalower** } { commaupper** }, }, }, definekeys[1]={ {i}{ execute={ \semantex_data_bool_get:nnTF { ##1 } { uppergrading } { \semantex_valuekey:nnn { ##1 } { lower } { #1 } } { \semantex_valuekey:nnn { ##1 } { upper } { #1 } } }, }, {sepi}{ execute={ \semantex_data_bool_get:nnTF { ##1 } { uppergrading } { \semantex_valuekey:nnn { ##1 } { seplower } { #1 } } { \semantex_valuekey:nnn { ##1 } { sepupper } { #1 } } }, }, {commai}{ execute={ \semantex_data_bool_get:nnTF { ##1 } { uppergrading } { \semantex_valuekey:nnn { ##1 } { commalower } { #1 } } { \semantex_valuekey:nnn { ##1 } { commaupper } { #1 } } }, }, {prei}{ boolifTF={uppergrading} { prelower={#1}, } { preupper={#1}, }, }, {posti}{ boolifTF={uppergrading} { postlower={#1}, } { postupper={#1}, }, }, {iputleft}{ boolifTF={uppergrading} { lowerputleft={#1}, }{ upperputleft={#1}, }, }, {setislot}{ boolifTF={uppergrading} { setlowerslot={#1}, } { setupperslot={#1}, } }, {islotwithothersep}{ boolifTF={uppergrading} { lowerslotwithothersep={#1}, } { upperslotwithothersep={#1}, }, }, {i-withothersep}{ islotwithothersep={#1}, }, {setidots}{ boolifTF={uppergrading} { setlowerdots={#1}, } { setupperdots={#1}, } }, {idotswithothersep}{ boolifTF={uppergrading} { lowerdotswithothersep={#1}, } { upperdotswithothersep={#1}, }, }, {i...withothersep}{ idotswithothersep={#1}, }, {i*withothersep}{ boolifTF={uppergrading} { lower*withothersep={#1} } { upper*withothersep={#1} }, }, {i**withothersep}{ boolifTF={uppergrading} { lower**withothersep={#1} } { upper**withothersep={#1} }, }, {setisep}{ boolifTF={uppergrading} { setlowersep={#1}, } { setuppersep={#1}, }, }, {nextiwithsep}{ strifeqTF={#1}{true} { boolifTF={uppergrading} { nextlowerwithsep={#1}, } { nextupperwithsep={#1}, }, } { strifeqTF={#1}{false} { boolifTF={uppergrading} { nextupperwithsep={#1}, } { nextlowerwithsep={#1}, }, } { ERRORkeyvaluenotfound={nextiwithothersep}{#1}, }, }, }, }, definekeys[2]={ {iwithothersep}{ execute={ \semantex_data_bool_get:nnTF { ##1 } { uppergrading } { \semantex_valuekey:nnn { ##1 } { lowerwithothersep } { { #1 } { #2 } } } { \semantex_valuekey:nnn { ##1 } { upperwithothersep } { { #1 } { #2 } } } }, }, }, % Argument keyval interface defineargkeys[1]={ {execute}{execute={#1}}, {setkeys}{ execute={ \semantex_keys_set:nn { ##1 } { #1 } } }, {keysset}{ execute={ \semantex_keys_set:nn { ##1 } { #1 } } }, {setkeysx}{ execute={ \semantex_keys_set_x:nn { ##1 } { #1 } } }, {keyssetx}{ execute={ \semantex_keys_set_x:nn { ##1 } { #1 } } }, {setargkeys}{ execute={ \semantex_arg_keys_set:nn { ##1 } { #1 } } }, {argkeysset}{ execute={ \semantex_arg_keys_set:nn { ##1 } { #1 } } }, {setargkeysx}{ execute={ \semantex_arg_keys_set_x:nn { ##1 } { #1 } } }, {argkeyssetx}{ execute={ \semantex_arg_keys_set_x:nn { ##1 } { #1 } } }, {setargsinglekeys}{ execute={ \semantex_arg_singlekeys_set:nn { ##1 } { #1 } } }, {argsinglekeysset}{ execute={ \semantex_arg_singlekeys_set:nn { ##1 } { #1 } } }, {setargsinglekeysx}{ execute={ \semantex_arg_singlekeys_set_x:nn { ##1 } { #1 } } }, {argsinglekeyssetx}{ execute={ \semantex_arg_singlekeys_set_x:nn { ##1 } { #1 } } }, {setoneargsinglekey}{ execute={ \semantex_arg_singlekey:nn { ##1 } { #1 } } }, {oneargsinglekeyset}{ execute={ \semantex_arg_singlekey:nn { ##1 } { #1 } } }, {setoneargsinglekeyx}{ execute={ \semantex_arg_singlekey_x:nn { ##1 } { #1 } } }, {oneargsinglekeysetx}{ execute={ \semantex_arg_singlekey_x:nn { ##1 } { #1 } } }, {setargwithoutkeyval}{ execute={ \semantex_arg_without_keyval:nn { ##1 } { #1 } } }, {argwithoutkeyvalset}{ execute={ \semantex_arg_without_keyval:nn { ##1 } { #1 } } }, {setargwithoutkeyvalx}{ execute={ \semantex_arg_without_keyval:nx { ##1 } { #1 } } }, {argwithoutkeyvalsetx}{ execute={ \semantex_arg_without_keyval:nx { ##1 } { #1 } } }, {default}{sep={#1}}, {-withothersep}{slotwithothersep={#1}}, {...withothersep}{dotswithothersep={#1}}, {sep}{ execute={ \semantex_data_bool_get:nnTF { ##1 } { nextargwithsep } { \semantex_data_tl_put_right:nnx { ##1 } { arg } { \semantex_data_tl_get_exp_not:nn { ##1 } { argsep } } } { % do nothing } \semantex_data_tl_put_right:nnn { ##1 } { arg } { #1 } \semantex_data_int_incr:nn { ##1 } { numberofarguments } \semantex_data_bool_set_true:nn { ##1 } { nextargwithsep } } }, {comma}{ execute={ \semantex_data_bool_get:nnTF { ##1 } { nextargwithsep } { \semantex_data_tl_put_right:nnn { ##1 } { arg } { , #1 } } { \semantex_data_tl_put_right:nnn { ##1 } { arg } { #1 } } \semantex_data_int_incr:nn { ##1 } { numberofarguments } \semantex_data_bool_set_true:nn { ##1 } { nextargwithsep } } }, {dotswithothersep}{ execute={ \semantex_arg_valuekey:nnx { ##1 } { othersep } { { \exp_not:n { #1 } } { \semantex_data_tl_get_exp_not:nn { ##1 } { argdots } } } }, }, {slotwithothersep}{ execute={ \semantex_arg_valuekey:nnx { ##1 } { othersep } { { \exp_not:n { #1 } } { \semantex_data_tl_get_exp_not:nn { ##1 } { argslot } } } }, }, }, defineargkeys={ {dots}{ execute={ \semantex_arg_valuekey:nnx { ##1 } { sep } { \semantex_data_tl_get_exp_not:nn { ##1 } { argdots } } }, }, {...}{dots}, {commadots}{ execute={ \semantex_arg_valuekey:nnx { ##1 } { comma } { \semantex_data_tl_get_exp_not:nn { ##1 } { argdots } } }, }, {comma...}{commadots}, {slot}{ execute={ \semantex_arg_valuekey:nnx { ##1 } { sep } { \semantex_data_tl_get_exp_not:nn { ##1 } { argslot } } }, }, {-}{slot}, {commaslot}{ execute={ \semantex_arg_valuekey:nnx { ##1 } { comma } { \semantex_data_tl_get_exp_not:nn { ##1 } { argslot } } }, }, {comma-}{commaslot}, }, defineargkeys[2]={ {othersep}{ execute={ \semantex_data_bool_get:nnTF { ##1 } { nextargwithsep } { \semantex_data_tl_put_right:nnn { ##1 } { arg } { #1 #2 } } { \semantex_data_tl_put_right:nnn { ##1 } { arg } { #2 } } \semantex_data_int_incr:nn { ##1 } { numberofarguments } \semantex_data_bool_set_true:nn { ##1 } { nextargwithsep } }, }, }, ] \cs_set_eq:NN\__semantex_old_version_of_semantex_new_object_of_class_SemantexBaseObject:Nw \__semantex_new_object_of_class_SemantexBaseObject:Nw \cs_set_protected:Npn \__semantex_new_object_of_class_SemantexBaseObject:Nw#1 { \msg_error:nnn { semantex } { created_a_SemantexBaseObject } { #1 } \__semantex_old_version_of_semantex_new_object_of_class_SemantexBaseObject:Nw #1 } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % PROCESSING PACKAGE KEYVAL SETUP % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \ProcessKeysOptions { semantex } % ... and they lived happily ever after.