\RequirePackage{expl3,xparse} \ProvidesExplPackage{semantex}{2020/07/07}{0.201alpha}{} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ERROR MESSAGES % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \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~#1~on~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 } { 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~object~#2~on~line~\msg_line_number: } {} \msg_new:nnnn { semantex } { created_a_SemantexVariable } { Never~create~objects~of~class~\SemantexVariable;~create~a~new~class~yourself~instead.~You~created~the~object~#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: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 \msg_error:nnnnn { nnxnn } \cs_generate_variant:Nn \msg_error:nnnn { nnxn } \cs_generate_variant:Nn \msg_error:nnn { nnx } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % COMMANDS FOR BULLETS AND SLOTS % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \box_new:N \l__semantex_bullet_box \hbox_set:Nn \l__semantex_bullet_box { $\cdot$ } \box_scale:Nnn \l__semantex_bullet_box {1.2} {1.2} \tl_set:Nn\g_semantex_bullet { \box_move_up:nn{-0.25ex}{\box_use:N \l__semantex_bullet_box} } \tl_set:Nn\g_semantex_double_bullet{\g_semantex_bullet \g_semantex_bullet} \tl_set_eq:NN\SemantexBullet \g_semantex_bullet \tl_set_eq:NN \SemantexDoubleBullet \g_semantex_double_bullet \tl_set:Nn \g_semantex_slot { \mathord{-} } \tl_set_eq:NN \SemantexSlot \g_semantex_slot %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % 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 } { #2 } \DeclareDocumentCommand{#1}{mo}{ % the actual \#1 command \IfValueTF{##2} { \semantex_render_class:Nn #1 { ifoutput=true, symbol = { ##1 }, ##2 } } { \semantex_render_class:Nn #1 { symbol = { ##1 } } } } \exp_args:Nc\DeclareDocumentCommand{__semantex_make_object_of_class_\cs_to_str:N #1_with_options:nnw}{mmo}{ \IfValueTF{##3} { \semantex_render_class:Nn #1 { ifoutput=true, symbol = { ##2 }, ##1, ##3 } } { \semantex_render_class:Nn #1 { symbol = { ##2 }, ##1 } } } \exp_args:Nc\DeclareDocumentCommand{__semantex_new_object_of_class_\cs_to_str: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 { symbol = { ##2 }, ##3 } } { \semantex_new_object:NNn { #1 } ##1 { ##3 } } % create the object with name ##1 \DeclareDocumentCommand{##1}{o}{ % the actual \##1 command \IfValueTF { ####1 } { \semantex_render_object:Nn ##1 { ifoutput=true,####1 } } { \semantex_render_object:Nn ##1 { } } } } } \tl_set_eq:NN\NewSimpleClass\semantex_new_simple_class:Nw %IM Consider using \semantexIfNoValueOrDotTF on the argument \DeclareDocumentCommand\semantex_new_variable_class:Nw{mO{}} % new variable-type class { % #1 = class name % #2 = options \semantex_new_class:Nn { #1 } { #2 } \DeclareDocumentCommand{#1}{mog}{ % the actual \#1 command \IfValueTF { ##2 } { \IfValueTF { ##3 } { \semantex_render_class:Nn #1 { ifoutput=true,symbol={##1},##2,arg={##3} } } { \semantex_render_class:Nn #1 { ifoutput=true,symbol={##1},##2} } } { \IfValueTF { ##3 } { \semantex_render_class:Nn #1 { ifoutput=true,symbol={##1},arg={##3} } } { \semantex_render_class:Nn #1 { symbol={##1} } } } } \exp_args:Nc\DeclareDocumentCommand{__semantex_make_object_of_class_\cs_to_str:N #1_with_options:nnw}{mmog}{ \IfValueTF { ##3 } { \IfValueTF { ##4 }{ \semantex_render_class:Nn #1 { ifoutput=true,symbol={##2}, ##1, ##3,arg={##4} } } { \semantex_render_class:Nn #1 { ifoutput=true,symbol={##2}, ##1, ##3 } } } { \IfValueTF { ##4 } { \semantex_render_class:Nn #1 { ifoutput=true,symbol={##2}, ##1,arg={##4} } } { \semantex_render_class:Nn #1 { symbol={##2}, ##1 } } } } \exp_args:Nc\DeclareDocumentCommand{__semantex_new_object_of_class_\cs_to_str: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 { symbol = { ##2 }, ##3 } } { \semantex_new_object:NNn { #1 } ##1 { ##3 } } % creates the object with name ##1 \DeclareDocumentCommand{##1}{og}{ % the actual \##1 command \IfValueTF{####1}{ \IfValueTF{####2} { \semantex_render_object:Nn ##1 { ifoutput=true,####1, arg={####2} } } { \semantex_render_object:Nn ##1 { ifoutput=true,####1} } } { \IfValueTF{####2} { \semantex_render_object:Nn ##1 { ifoutput=true,arg={####2} } } { \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 } { #2 } \DeclareDocumentCommand{#1}{mogg}{ % the actual \#1 command \IfValueTF{##2} { \IfValueTF { ##3 } { \tl_if_eq:nnTF { ##3 }{ * } { \IfValueTF { ##4 } { \semantex_render_class:Nn #1 { ifoutput=true,symbol={##1}, ##2, *, arg={##4} } } { \semantex_render_class:Nn #1 { ifoutput=true,symbol={##1}, ##2, * } } } { \tl_if_eq:nnTF { ##3 }{ ** } { \IfValueTF { ##4 } { \semantex_render_class:Nn #1 { ifoutput=true,symbol={##1}, ##2, **, arg={##4} } } { \semantex_render_class:Nn #1 { ifoutput=true,symbol={##1}, ##2, ** } } } { \IfValueTF { ##4 } { \semantex_render_class:Nn #1 { ifoutput=true,symbol={##1}, ##2, degreedefault={##3}, arg={##4} } } { \semantex_render_class:Nn #1 { ifoutput=true,symbol={##1}, ##2, degreedefault={##3} } } } } } { \IfValueTF { ##4 } { \semantex_render_class:Nn #1 { ifoutput=true,symbol={##1}, ##2, arg={##4} } } { \semantex_render_class:Nn #1 { ifoutput=true,symbol={##1}, ##2 } } } } { \IfValueTF { ##3 } { \tl_if_eq:nnTF { ##3 }{ * } { \IfValueTF { ##4 } { \semantex_render_class:Nn #1 { ifoutput=true, symbol={##1}, *, arg={##4} } } { \semantex_render_class:Nn #1 { ifoutput=true, symbol={##1}, *} } } { \tl_if_eq:nnTF { ##3 }{ ** } { \IfValueTF { ##4 } { \semantex_render_class:Nn #1 { ifoutput=true,symbol={##1}, **, arg={##4} } } { \semantex_render_class:Nn #1 { ifoutput=true,symbol={##1}, ** } } } { \IfValueTF { ##4 } { \semantex_render_class:Nn #1 { ifoutput=true,symbol={##1}, degreedefault={##3}, arg={##4} } } { \semantex_render_class:Nn #1 { ifoutput=true,symbol={##1}, degreedefault={##3} } } } } } { \IfValueTF { ##4 } { \semantex_render_class:Nn #1 { ifoutput=true,symbol={##1}, arg={##4} } } { \semantex_render_class:Nn #1 { symbol={##1}, arg={##4} } } } } } \exp_args:Nc\DeclareDocumentCommand{__semantex_make_object_of_class_\cs_to_str:N #1_with_options:nnw}{mmogg}{ \IfValueTF{##3} { \IfValueTF { ##4 } { \tl_if_eq:nnTF { ##4 }{ * } { \IfValueTF { ##5 } { \semantex_render_class:Nn #1 { ifoutput=true,symbol={##2}, ##1, ##3, *, arg={##5} } } { \semantex_render_class:Nn #1 { ifoutput=true,symbol={##2}, ##1, ##3, * } } } { \tl_if_eq:nnTF { ##4 }{ ** } { \IfValueTF { ##5 } { \semantex_render_class:Nn #1 {ifoutput=true, symbol={##2}, ##1, ##3, **, arg={##5} } } { \semantex_render_class:Nn #1 {ifoutput=true, symbol={##2}, ##1, ##3, ** } } } { \IfValueTF { ##5 } { \semantex_render_class:Nn #1 { ifoutput=true,symbol={##2}, ##1,##3, degreedefault={##4}, arg={##5} } } { \semantex_render_class:Nn #1 { ifoutput=true,symbol={##2}, ##1,##3, degreedefault={##4} } } } } } { \IfValueTF { ##5 } { \semantex_render_class:Nn #1 { ifoutput=true,symbol={##2}, ##1, ##3, arg={##5} } } { \semantex_render_class:Nn #1 { ifoutput=true,symbol={##2}, ##1, ##3 } } } } { \IfValueTF { ##4 } { \tl_if_eq:nnTF { ##4 }{ * } { \IfValueTF { ##5 } { \semantex_render_class:Nn #1 { ifoutput=true, symbol={##2} ,##1, *, arg={##5} } } { \semantex_render_class:Nn #1 { ifoutput=true, symbol={##2} ,##1, *} } } { \tl_if_eq:nnTF { ##4 }{ ** } { \IfValueTF { ##5 } { \semantex_render_class:Nn #1 { ifoutput=true, symbol={##2} , ##1, **, arg={##5} } } { \semantex_render_class:Nn #1 { ifoutput=true, symbol={##2} , ##1, ** } } } { \IfValueTF { ##5 } { \semantex_render_class:Nn #1 { ifoutput=true, symbol={##2}, ##1, degreedefault={##4}, arg={##5} } } { \semantex_render_class:Nn #1 { ifoutput=true, symbol={##2}, ##1, degreedefault={##4} } } } } } { \IfValueTF { ##5 } { \semantex_render_class:Nn #1 { ifoutput=true,symbol={##2}, ##1, arg={##5} } } { \semantex_render_class:Nn #1 { symbol={##2}, ##1 } } } } } \exp_args:Nc\DeclareDocumentCommand{__semantex_new_object_of_class_\cs_to_str: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 }{ symbol = { ##2 }, ##3 } } { \semantex_new_object:NNn { #1 } { ##1 }{ ##3 } } % creates the object with name ##1 \DeclareDocumentCommand{##1}{ogg}{ % the actual \##1 command \IfValueTF{####1} { \IfValueTF{####2} { \tl_if_eq:nnTF { ####2 } { * } { \IfValueTF{####3} { \semantex_render_object:Nn ##1 { ifoutput=true,####1, *, arg={ ####3 } } } { \semantex_render_object:Nn ##1 { ifoutput=true,####1, * } } } { \tl_if_eq:nnTF { ####2 } { ** } { \IfValueTF{####3} { \semantex_render_object:Nn ##1 { ifoutput=true, ####1, **, arg={ ####3 } } } { \semantex_render_object:Nn ##1 { ifoutput=true, ####1, ** } } } { \IfValueTF{####3} { \semantex_render_object:Nn ##1 { ifoutput=true,####1, degreedefault={ ####2 }, arg={ ####3 } } } { \semantex_render_object:Nn ##1 { ifoutput=true,####1, degreedefault={ ####2 } } } } } } { \IfValueTF{####3} { \semantex_render_object:Nn ##1 { ifoutput=true,####1, arg={ ####3 } } } { \semantex_render_object:Nn ##1 { ifoutput=true,####1 } } } } { \IfValueTF{####2} { \tl_if_eq:nnTF { ####2 } { * } { \IfValueTF{####3} { \semantex_render_object:Nn ##1 { ifoutput=true, *, arg={ ####3 } } } { \semantex_render_object:Nn ##1 { ifoutput=true, * } } } { \tl_if_eq:nnTF { ####2 } { ** } { \IfValueTF{####3} { \semantex_render_object:Nn ##1 { ifoutput=true,**, arg={ ####3 } } } { \semantex_render_object:Nn ##1 { ifoutput=true,** } } } { \IfValueTF{####3} { \semantex_render_object:Nn ##1 { ifoutput=true,degreedefault={ ####2 }, arg={ ####3 } } } { \semantex_render_object:Nn ##1 { ifoutput=true,degreedefault={ ####2 } } } } } } { \IfValueTF{####3} { \semantex_render_object:Nn ##1 { ifoutput=true, arg={ ####3 } } } { \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 } { #2 } \DeclareDocumentCommand{#1}{mog} % maybe this does not even make sense for delimiters { \IfValueTF { ##2 } { \IfValueTF { ##3 } { \semantex_render_class:Nn #1 { ifoutput=true, symbol = { ##1 }, ##2, arg = { ##3 } } } { \semantex_render_class:Nn #1 { ifoutput=true, symbol = { ##1 }, ##2 } } } { \IfValueTF { ##3 } { \semantex_render_class:Nn #1 { ifoutput=true, symbol = { ##1 }, arg = { ##3 } } } { \semantex_render_class:Nn #1 { symbol = { ##1 } } } } } % the actual \#1 command \exp_args:Nc\DeclareDocumentCommand{__semantex_make_object_of_class_\cs_to_str:N #1_with_options:nnw}{mmog} { \IfValueTF { ##3 } { \IfValueTF { ##4 } { \semantex_render_class:Nn #1 { ifoutput=true, symbol = { ##2 }, ##1, ##3, arg = { ##4 } } } { \semantex_render_class:Nn #1 { ifoutput=true, symbol = { ##2 }, ##1, ##3 } } } { \IfValueTF { ##4 } { \semantex_render_class:Nn #1 { ifoutput=true, symbol = { ##2 }, ##1, arg = { ##4 } } } { \semantex_render_class:Nn #1 { symbol = { ##2 }, ##1 } } } } \exp_args:Nc\DeclareDocumentCommand{__semantex_new_object_of_class_\cs_to_str: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 }{ leftpar = { ##2 }, rightpar = { ##3 }, ##4 } % creates the object with name ##1 \DeclareDocumentCommand{##1}{og}{ % the actual \##1 command \IfValueTF { ####1 } { \IfValueTF { ####2 } { \semantex_render_object:Nn ##1 { ifoutput=true,####1, arg = { ####2 } } } { \semantex_render_object:Nn ##1 { ifoutput=true,####1 } } } { \IfValueTF { ####2 } { \semantex_render_object:Nn ##1 { ifoutput=true, arg = { ####2 } } } { \semantex_render_object:Nn ##1 { } } } } } } \cs_set_eq:NN\NewDelimiterClass\semantex_new_delimiter_class:Nw %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % COMMANDS FOR CREATING AND HANDLING CLASSES AND OJBECTS % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \cs_new:Npn\NewObject#1 { \cs_if_exist_use:cF { __semantex_new_object_of_class_\cs_to_str:N#1:Nw } { \msg_error:nnnn { semantex } { created_object_of_unknown_class } { #1 } } } %\cs_new:Npn\MakeObject#1{ \use:c { __semantex_make_object_of_class_#1:nw } } \cs_new:Npn \__semantex_new_class_or_object:nn#1#2{ % create new object % #1 = name of command, without backslash % #2 = standard keyval setup \semantex_data_tl_provide:nn { #1 } { parent } \semantex_data_tl_set:nnn { #1 } { parent } { class_SemantexVariable } \cs_set:cpn { __semantex_data_cs_#1_valuekey:nn } ##1##2 % command controlling valuekeys { \semantex_valuekey:nnn { ##2 } { ##1 } { #1 } } \cs_set:cpn { __semantex_data_cs_#1_singlekey:n } ##1 % command controlling singlekeys { \semantex_singlekey: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 { ##2 } { ##1 }{ #1 } } \cs_set:cpn { __semantex_data_cs_#1_arg_singlekey:n } ##1 { \semantex_arg_singlekey:nn { ##1 } { #1 } } % initially sets up the keyval interface of the object \semantex_keys_set:nn { #1 } { #2 } % \seq_put_right:Nx \g__semantex_all_objects_seq { #1 } } \cs_generate_variant:Nn \__semantex_new_class_or_object:nn { xn } \cs_new:Npn \semantex_new_class:Nn#1#2{ % create a new class % #1 = name of class % #2 = standard keyval setup; the parent class by default is SemantexVariable \semantex_class_if_exist:NTF { #1 } { \msg_error:nnn { semantex } { class_already_defined } { #1 } } { \semantex_class_register:N { #1 } \__semantex_new_class_or_object:xn { class_\cs_to_str:N #1 } { #2 } } } \cs_set:Npn \semantex_new_object:NNn#1#2#3 { \semantex_object_if_exist:NTF { #2 } { \msg_error:nnn { semantex } { object_already_defined } { #2 } } { \semantex_object_register:N { #2 } \__semantex_new_class_or_object:xn { object_\cs_to_str:N #2 } { class=#1, #3 } } } \seq_new:N \g__semantex_all_classes_seq % a register for all objects created \cs_new:Npn\semantex_class_register:N#1 { \seq_put_right:Nx\g__semantex_all_classes_seq { class_\cs_to_str:N #1 } } \cs_new:Npn\semantex_class_if_exist:NTF#1#2#3 { \seq_if_in:NxTF\g__semantex_all_classes_seq { class_\cs_to_str:N#1 } { #2 } { #3 } } \seq_new:N \g__semantex_all_objects_seq % a register for all objects created \cs_new:Npn\semantex_object_register:N#1 { \seq_put_right:Nx\g__semantex_all_objects_seq { object_\cs_to_str:N #1 } } \cs_new:Npn\semantex_object_if_exist:NTF#1#2#3 { \seq_if_in:NxTF\g__semantex_all_objects_seq { object_\cs_to_str:N#1 } { #2 } { #3 } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % COMMANDS FOR RENDERING OBJECTS AND CLASSES % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \cs_generate_variant:Nn\tl_if_blank:nTF { xTF } \cs_new_protected:Npn \__semantex_render:nn#1#2 { % the main command for rendering a class/object % #1 = name of object % #2 = options \group_begin: \semantex_data_tl_inherit:nn { #1 } { symbol } % Inherit the symbol from parent if not done already \semantex_keys_set:nn { #1 } { #2 } % Setup the keys \semantex_primitive_valuekey_parse:nn { #1 } { } % Run the "parse" routine, i.e. the collection of code that the user has added to the parse register \semantex_data_bool_get:nnTF { #1 } { output } % Checks if the object/class is supposed to output { \semantex_primitive_valuekey_innerreturn:nn { #1 }{} \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_primitive_valuekey_leftreturn:nn { #1 }{} } { \semantex_primitive_valuekey_rightreturn:nn { #1 }{} } } { % do nothing } \tl_set:Nx\l__semantex_render_symbol_temp { \semantex_data_tl_get:nn { #1 } { symbol } } % Stores the symbol in a temporary command \tl_set:Nx \l__semantex_render_temp { \exp_not:c { __semantex_make_object_of_\semantex_data_tl_get:nn { #1 } { output }_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 parse options to it { upperputleft={\semantex_data_tl_get_exp_not:nn { #1 } { upper }}, lowerputleft={\semantex_data_tl_get_exp_not:nn { #1 } { lower }}, upperleftputright={\semantex_data_tl_get_exp_not:nn { #1 } { upperleft }}, lowerleftputright={\semantex_data_tl_get_exp_not:nn { #1 } { lowerleft }}, preupper={\semantex_data_tl_get_exp_not:nn { #1 } { preupper }}, postupper={\semantex_data_tl_get_exp_not:nn { #1 } { postupper }}, prelower={\semantex_data_tl_get_exp_not:nn { #1 } { prelower }}, postlower={\semantex_data_tl_get_exp_not:nn { #1 } { postlower }}, preupperleft={\semantex_data_tl_get_exp_not:nn { #1 } { preupperleft }}, postupperleft={\semantex_data_tl_get_exp_not:nn { #1 } { postupperleft }}, prelowerleft={\semantex_data_tl_get_exp_not:nn { #1 } { prelowerleft }}, postlowerleft={\semantex_data_tl_get_exp_not:nn { #1 } { postlowerleft }}, texclass={\semantex_data_tl_get:nn { #1 } { texclass }}, \semantex_data_tl_get_exp_not:nn { #1 } { outputoptions }, % These are the options we parse to our object -- this is all % information that we pass on to the output class so that it % can eventually render it } { \exp_not:V \l__semantex_render_symbol_temp } } } { \semantex_primitive_valuekey_return:nn { #1 }{} % Returns the object/class, i.e. adds all remaining indices and arguments to it \tl_if_blank:xTF { \semantex_data_tl_get:nn { #1 } { texclass } } % Checks whether the texclass 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_symbol_temp { \semantex_data_tl_get:nn { #1 } { symbol } } } { \tl_set:Nx\l__semantex_render_symbol_temp { \semantex_data_tl_get:nn { #1 } { texclass } { \semantex_data_tl_get:nn { #1 } { symbol } } } } \tl_set:Nx\l__semantex_render_temp { \exp_not:V \l__semantex_render_symbol_temp } } \exp_last_unbraced:NV \group_end: \l__semantex_render_temp % This neat trick allows outputting to different classes to work as expected } \cs_generate_variant:Nn \__semantex_render:nn { xn } \cs_set:Npn\semantex_render_class:Nn#1#2 % a front-end command { \__semantex_render:xn { class_\cs_to_str:N #1 } { #2 } } \cs_set:Npn\semantex_render_object:Nn#1#2 { \__semantex_render:xn { object_\cs_to_str: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 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \tl_new:N\SemantexDelimiterSize %%So far, this is experimental: %%\makeatletter %this part requires amsmath %\tl_set:Nn\semantexnormalscaling{\bBigg@{0.8}} %\tl_set:Nn\semantexnormalscalingl{\mathopen\semantexnormalscaling} %\tl_set:Nn\semantexnormalscalingr{\mathclose\semantexnormalscaling} %\tl_set:Nn\semantexnormalscalingm{\mathrel\semantexnormalscaling} %%\makeatother \cs_new:Npn \__semantex_parentheses_normal:nnn#1#2#3 { \group_begin: %\semantexnormalscalingl#2 #4 #5 #6 \semantexnormalscalingr#3 \mathopen#1 #3 \mathclose#2 \group_end: } \cs_new:Npn \__semantex_parentheses_auto:nnn#1#2#3 { \group_begin: \tl_set:Nn\SemantexDelimiterSize{\middle} %\tl_set_eq:NN\SemantexDelimiterSize\middle \mathopen{}\mathclose\bgroup\left#1 #3 \aftergroup\egroup\right#2 \group_end: } \cs_new:Npn \__semantex_parentheses_other:nnnn#1#2#3#4 { \group_begin: \tl_set_eq:NN\SemantexDelimiterSize#4 %\tl_set:Nx\SemantexDelimiterSize{\exp_not:N#1} \mathopen#4#1 #3 \mathclose#4#2 \group_end: } \cs_generate_variant:Nn \str_case:nnF { xnF } \cs_new:Npn \__semantex_parentheses_store:nnnnN#1#2#3#4#5 % The central command handling the rendering of argument parentheses { \tl_set:Nx#5 { { #2 } { #3 } { #4 } } \str_case:xnF { #1 } % This is where \big,\Big, etc. go. To my surprise, an x-type expansion did not cause any issues with this { { normal } { \tl_put_left:Nn#5 { \exp_not:N \__semantex_parentheses_normal:nnn } } { auto } { \tl_put_left:Nn#5 { \exp_not:N \__semantex_parentheses_auto:nnn } } { * } { \tl_put_left:Nn#5 { \exp_not:N \__semantex_parentheses_auto:nnn } } } { \tl_put_right:Nx#5 { { \exp_not:V #1 } } \tl_put_left:Nn#5 { \exp_not:N \__semantex_parentheses_other:nnnn } } } \cs_new:Npn \__semantex_no_parentheses:n#1 { \group_begin: \tl_clear:N\SemantexDelimiterSize #1 \group_end: } \cs_new: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 { { #1 } } \tl_put_left:Nn#2 { \exp_not:N \__semantex_no_parentheses:n } } \cs_new:Npn \__semantex_symbol_parentheses_normal:nnn#1#2#3 { \mathopen#1 #3 \mathclose#2 } \cs_new:Npn \__semantex_symbol_parentheses_auto:nnn#1#2#3 { \mathopen{}\mathclose\bgroup\left#1 #3 \aftergroup\egroup\right#2 } \cs_new:Npn \__semantex_symbol_parentheses_other:nnnn#1#2#3#4 { \mathopen#4#1 #3 \mathclose#4#2 } \cs_new:Npn \__semantex_symbol_parentheses_store:nnnnN#1#2#3#4#5 % The central command handling the rendering of symbol parentheses { \tl_set:Nx#5 { { #2 } { #3 } { #4 } } \str_case:xnF { #1 } % This is where \big,\Big, etc. go. To my surprise, an x-type expansion did not cause any issues with this { { normal } { \tl_put_left:Nn#5 { \exp_not:N \__semantex_symbol_parentheses_normal:nnn } } { auto } { \tl_put_left:Nn#5 { \exp_not:N \__semantex_symbol_parentheses_auto:nnn } } { * } { \tl_put_left:Nn#5 { \exp_not:N \__semantex_symbol_parentheses_auto:nnn } } } { \tl_put_right:Nx#5 { { \exp_not:V #1 } } \tl_put_left:Nn#5 { \exp_not:N \__semantex_symbol_parentheses_other:nnnn } } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % COMMANDS FOR MODIFYING AND OBTAINING DATA % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %-------------------------------------------- % Commands to modify and obtain data %\cs_new:Npn \semantex_data_tl_get_proto:nnn#1#2#3 %{ % % #1 = name of object % % #2 = the data to get % % #3 = also the name of object, but being stored % % when passing to the parent, in order to make % % error messages meaningful % \tl_if_exist:cTF { g__semantex_data_tl_#1_#2 } % { % \use:c { g__semantex_data_tl_#1_#2 } % } % { % \tl_if_eq:nnTF { #1 } { SemantexVariable } % { % \msg_error:nnnn { semantex } { data_tl_not_found } { #2 } { #3 } % } % { % \semantex_data_tl_get_proto:nnn { \semantex_data_tl_get:nn { #1 } { parent } } { #2 } { #1 } % } % } %} % %\cs_new:Npn \semantex_data_tl_get:nn#1#2 %{ % \semantex_data_tl_get_proto:nnn { #1 } { #2 } { #1 } %} % COMMANDS FOR HANDLING THE PARENT OF A CLASS/OBJECT: \cs_new:Npn \semantex_data_parent_get:n#1 { % #1 = object % A command to get the parent of an object \use:c { g__semantex_data_tl_#1_parent } } \cs_new:Npn \semantex_data_parent_set:nn#1#2 { \semantex_class_if_exist:NTF { #2 } { \tl_set:cx { g__semantex_data_tl_#1_parent } { class_\cs_to_str:N#2 } } { \semantex_error_output_format:nN { #1 } \l__semantex_data_parent_set_temp \msg_error:nnxnn { semantex } { class_not_found } { \l__semantex_data_parent_set_temp } { parent } { #2 } } } \cs_new:Npn \semantex_data_class_set:nn#1#2 { \semantex_class_if_exist:NTF { #2 } { \tl_set:cx { g__semantex_data_tl_#1_parent } { class_\cs_to_str:N#2 } } { \semantex_error_output_format:nN { #1 } \l__semantex_data_class_set_temp \msg_error:nnxnn { semantex } { class_not_found } { \l__semantex_data_class_set_temp } { class } { #2 } } } \cs_new:Npn \semantex_data_copy_object:nn#1#2 { \semantex_object_if_exist:NTF { #2 } { \tl_set:cx { g__semantex_data_tl_#1_parent } { object_\cs_to_str:N#2 } } { \semantex_error_output_format:nN { #1 } \l__semantex_data_copy_object_temp \msg_error:nnxnn { semantex } { object_not_found } { \l__semantex_data_copy_object_temp } { copy } { #2 } } } \cs_new:Npn \semantex_data_clone_object:nn#1#2 { \semantex_object_if_exist:NTF { #2 } { \tl_set:cx { g__semantex_data_tl_#1_parent } { object_\cs_to_str:N#2 } } { \semantex_error_output_format:nN { #1 } \l__semantex_data_clone_object_temp \msg_error:nnxnn { semantex } { object_not_found } { \l__semantex_data_clone_object_temp } { clone } { #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_generate_variant:Nn \str_if_eq:nnTF { fnTF } \cs_generate_variant:Nn \tl_if_eq:nnTF { fnTF } \cs_new:Npn \__semantex_data_tl_get_auxiliary:nnn#1#2#3 { % #1 = name of class/object % #2 = the data to get % #3 = the original class/object, 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_SemantexVariable } % Apparently, f-type expansion seemed to work here for once { \semantex_error_output_format:nN { #3 } \__semantex_data_tl_get_auxiliary_temp \msg_error:nnxn { semantex } { data_tl_not_found } { \__semantex_data_tl_get_auxiliary_temp } { #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 object % % #2 = the data to get % \tl_if_exist:cTF { g__semantex_data_tl_#1_#2 } % { % \exp_not:v { g__semantex_data_tl_#1_#2 } % } % { % \semantex_data_tl_get:nn { \semantex_data_parent_get:n { #1 } } { #2 } % } %} \cs_new:Npn \semantex_data_tl_get_exp_not:nn#1#2 { % #1 = name of object % #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 class/object % #2 = the data to get % #3 = the original class/object, 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_SemantexVariable } % Apparently, f-type expansion seemed to work here for once { \semantex_error_output_format:nN { #3 } \l__semantex_data_tl_get_exp_not_auxiliary_temp \msg_error:nnxn { semantex } { data_tl_not_found } { \l__semantex_data_tl_get_exp_not_auxiliary_temp } { #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:Npn \semantex_data_tl_get_store:nnN#1#2#3% maybe should be PROTECTED?? { % #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:Npn \__semantex_data_tl_get_store_auxiliary:nnNn#1#2#3#4% maybe should be PROTECTED?? { % #1 = name of object % #2 = the data to get % #3 = where to store it \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_SemantexVariable } { \semantex_error_output_format:nN { #4 } \l__semantex_data_tl_get_store_auxiliary_temp \msg_error:nnxn { semantex } { data_tl_not_found } { \l__semantex_data_tl_get_store_auxiliary_temp } { #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:Npn\semantex_data_tl_provide:nn#1#2 { \tl_if_exist:cF { g__semantex_data_tl_#1_#2 } { \tl_set:cn { g__semantex_data_tl_#1_#2 } {} } } \cs_new:Npn\semantex_data_tl_inherit:nn#1#2 { % #1 = object % #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_set_eq:NN\semantex_data_tl_inherit_x:nn\semantex_data_tl_inherit:nn % The same as inherit; historically, this one did an x type % expansion first, but after changes in other places, this % no longer appeard to be necessary. I decided to keep up the % separation of the two, just in case. \cs_new: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: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: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: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: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: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{% maybe should be PROTECTED?? % #1 = name of object % #2 = the intuence to get % #3 = the command to store it in \__semantex_data_int_get_auxiliary:nnn { #1 } { #2 } { #1 } } \cs_new:Npn \__semantex_data_int_get_auxiliary:nnn#1#2#3{% maybe should be PROTECTED?? % #1 = name of object % #2 = the intuence 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_use:c { g__semantex_data_int_#1_#2 } } { \str_if_eq:nnTF { #1 } { class_SemantexVariable } { \semantex_error_output_format:nN { #3 } \__semantex_data_int_get_auxiliary_temp \msg_error:nnxn { semantex } { data_int_not_found } { \__semantex_data_int_get_auxiliary_temp } { #2 } } { \__semantex_data_int_get_auxiliary:fnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 } } } } { \str_if_eq:nnTF { #1 } { class_SemantexVariable } { \semantex_error_output_format:nN { #3 } \__semantex_data_int_get_auxiliary_temp \msg_error:nnxn { semantex } { data_int_not_found } { \__semantex_data_int_get_auxiliary_temp } { #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:Npn \semantex_data_int_get_store:nnN#1#2#3{% maybe should be PROTECTED?? % #1 = name of object % #2 = the intuence to get % #3 = the command to store it in \__semantex_data_int_get_store_auxiliary:nnNn { #1 } { #2 } #3 { #1 } } \cs_new:Npn\__semantex_data_int_get_store_auxiliary:nnNn#1#2#3#4{% maybe should be PROTECTED?? % #1 = name of object % #2 = the intuence 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_SemantexVariable } { \semantex_error_output_format:nN { #4 } \l__semantex_data_int_get_store_auxiliary_temp \msg_error:nnxn { semantex } { data_int_not_found } { \l__semantex_data_int_get_store_auxiliary_temp } { #2 } } { \__semantex_data_int_get_store_auxiliary:fnNn { \semantex_data_parent_get:n { #1 } } { #2 } #3 { #4 } } } } { \str_if_eq:nnTF { #1 } { class_SemantexVariable } { \semantex_error_output_format:nN { #4 } \l__semantex_data_int_get_store_auxiliary_temp \msg_error:nnxn { semantex } { data_int_not_found } { \l__semantex_data_int_get_store_auxiliary_temp } { #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: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: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:Npn\semantex_data_int_if_positive:nnTF#1#2#3#4 { % \semantex_data_int_inherit:nn { #1 } { #2 } % This should not be necessary, ubt is, for unkonwn reasons \int_compare:nNnTF { \semantex_data_int_get:nn { #1 } { #2 } } > { 0 } { #3 } { #4 } } \cs_generate_variant:Nn\semantex_data_int_if_positive:nnTF { nnT } \cs_new:Npn\semantex_data_int_if_positive:nnF#1#2#3 { \semantex_data_int_if_positive:nnTF { #1 } { #2 } { } { #3 } } \cs_new: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_generate_variant:Nn\semantex_data_int_if_greater_than_one:nnTF { nnT } \cs_new:Npn\semantex_data_int_if_greater_than_one:nnF#1#2#3 { \semantex_data_int_if_greater_than_one:nnTF { #1 } { #2 } { } { #3 } } \cs_new: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:Npn \semantex_data_seq_get_store:nnN#1#2#3{% maybe should be PROTECTED?? % #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 { vnN, nnc, vnc } % Remove these later \cs_new: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: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 } } } { \semantex_data_seq_get_store:nnc { \semantex_data_parent_get:n { #1 } } { #2 } { 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 } \seq_if_exist:cF { g__semantex_data_seq_#1_#2 } { \seq_new:c { g__semantex_data_seq_#1_#2 } } } } \cs_new: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: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 PROPERTY LIST: \cs_new:Npn \semantex_data_prop_provide:nn#1#2 { % #1 = name of the object % #2 = name of the prop \prop_if_exist:cF { g__semantex_data_prop_#1_#2 } { \prop_new:c { g__semantex_data_prop_#1_#2 } } } \cs_new:Npn \semantex_data_prop_put:nnnn#1#2#3#4 { \semantex_data_prop_provide:nn { #1 } { #2 } % important that we do not inherit! This is crucial for getting the right inheritance for key interfaces \prop_put:cnn { g__semantex_data_prop_#1_#2 } { #3 } { #4 } } \cs_new:Npn\semantex_data_prop_remove:nnn#1#2#3 { \prop_if_exist:cT { g__semantex_data_prop_#1_#2 } { \prop_remove:cn { g__semantex_data_prop_#1_#2 } { #3 } } } \cs_new:Npn \semantex_valuekey_get:nnNTF#1#2#3#4#5{% % #1 = name of the object % #2 = keyval data to get % #3 = command to store possible data in % #4 = if true (not to be used) % #5 = if false \prop_get:cnNTF { g__semantex_data_prop_#1_custom_valuekeys } { #2 } #3 { #4 } { \str_if_eq:nnTF { #1 } { class_SemantexVariable } { #5 } { \semantex_valuekey_get:fnNTF { \semantex_data_parent_get:n { #1 } } { #2 } #3 { #4 } { #5 } } } } \cs_new:Npn\semantex_valuekey_remove:nn#1#2 { \semantex_data_prop_remove:nnn { #1 } { custom_valuekeys } { #2 } } \cs_generate_variant:Nn \semantex_valuekey_get:nnNTF { fnNTF, vnNTF, xnNTF } \cs_new:Npn \semantex_singlekey_get:nnNTF#1#2#3#4#5{% % #1 = name of the object % #2 = singlekey data to get % #3 = command to store possible data in % #4 = if true (not to be used) % #5 = if false \prop_get:cnNTF { g__semantex_data_prop_#1_custom_singlekeys } { #2 } #3 { #4 } { \str_if_eq:nnTF { #1 } { class_SemantexVariable } { #5 } { \semantex_singlekey_get:fnNTF { \semantex_data_parent_get:n { #1 } } { #2 } #3 { #4 } { #5 } } } } \cs_new:Npn\semantex_singlekey_remove:nn#1#2 { \semantex_data_prop_remove:nnn { #1 } { custom_singlekeys } { #2 } } \cs_generate_variant:Nn \semantex_singlekey_get:nnNTF { fnNTF, vnNTF, xnNTF } \cs_new:Npn \semantex_arg_valuekey_get:nnNTF#1#2#3#4#5{% % #1 = name of the object % #2 = keyval data to get % #3 = command to store possible data in % #4 = if true (not to be used) % #5 = if false \prop_get:cnNTF { g__semantex_data_prop_#1_custom_arg_valuekeys } { #2 }#3%\l_semantex_valuekey_get_temp { #4 } { \str_if_eq:nnTF { #1 } { class_SemantexVariable } { #5 } { \semantex_arg_valuekey_get:fnNTF { \semantex_data_parent_get:n { #1 } } { #2 } #3 { #4 } { #5 } } } } \cs_generate_variant:Nn \semantex_arg_valuekey_get:nnNTF { fnNTF, vnNTF, xnNTF } \cs_new:Npn\semantex_arg_valuekey_remove:nn#1#2 { \semantex_data_prop_remove:nnn { #1 } { custom_arg_valuekeys } { #2 } } \cs_new:Npn \semantex_arg_singlekey_get:nnNTF#1#2#3#4#5{% % #1 = name of the object % #2 = singlekey data to get % #3 = command to store possible data in % #4 = if true (not to be used) % #5 = if false \prop_get:cnNTF { g__semantex_data_prop_#1_custom_arg_singlekeys } { #2 } #3 { #4 } { \str_if_eq:nnTF { #1 } { class_SemantexVariable } { #5 } { \semantex_arg_singlekey_get:fnNTF { \semantex_data_parent_get:n { #1 } } { #2 } #3 { #4 } { #5 } } } } \cs_generate_variant:Nn \semantex_arg_singlekey_get:nnNTF { fnNTF, vnNTF, xnNTF } \cs_new:Npn\semantex_arg_singlekey_remove:nn#1#2 { \semantex_data_prop_remove:nnn { #1 } { custom_arg_singlekeys } { #2 } } % COMMANDS FOR HANDLING DATA OF TYPE BOOLEAN: \cs_new:Npn\semantex_data_bool_get:nnTF#1#2#3#4 { % #1 = name of the object % #2 = boolean to get % #3 = if true % #4 = if false \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_SemantexVariable } { #4 } { \semantex_data_bool_get:fnTF { \semantex_data_parent_get:n { #1 } } { #2 } { #3 } { #4 } } } } { \str_if_eq:nnTF { #1 } { class_SemantexVariable } { #4 } { \semantex_data_bool_get:fnTF { \semantex_data_parent_get:n { #1 } } { #2 } { #3 } { #4 } } } } \cs_generate_variant:Nn \semantex_data_bool_get:nnTF { onTF, fnTF, xnTF, vnTF, nnT } \cs_new:Npn\semantex_data_bool_get:nnF#1#2#3 { \semantex_data_bool_get:nnTF { #1 } { #2 } { } { #3 } } \cs_new:Npn\semantex_data_bool_provide:nn#1#2 { % #1 = name of the object % #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:Npn\semantex_data_bool_set_true:nn#1#2 { % #1 = name of the object % #2 = boolean to provide \semantex_data_bool_provide:nn { #1 } { #2 } \bool_set_true:c { g__semantex_data_bool_#1_if_#2 } } \cs_new:Npn\semantex_data_bool_set_false:nn#1#2 { % #1 = name of the object % #2 = boolean to provide \semantex_data_bool_provide:nn { #1 } { #2 } \bool_set_false:c { g__semantex_data_bool_#1_if_#2 } } % COMMANDS FOR HANDLING COMMAND SEQUENCE DATA AND KEYVAL SYNTAX: \cs_new:Npn\semantex_data_cs_get:nnn#1#2#3 { % #1 = name of the object % #2 = command sequence to get % #3 = what to apply said command sequence to \cs_if_exist:cTF { __semantex_data_cs_#1_#2:n } { \use:c { __semantex_data_cs_#1_#2:n } { #3 } } { \str_if_eq:nnTF { #1 } { class_SemantexVariable } { % should probably throw an error by now, but later! } { \semantex_data_cs_get:xnn { \semantex_data_parent_get:n {#1} } { #2 } { #3 } } } } \cs_generate_variant:Nn \semantex_data_cs_get:nnn { xnn } \cs_generate_variant:Nn \keyval_parse:NNn { cco } \cs_new:Npn \semantex_keys_set:nn#1#2 { % The central command for doing keyval setup % #1 = object % #2 = keys \keyval_parse:cco % Could be nice to get rid of o-type expansion, but so far has not been possible { __semantex_data_cs_#1_singlekey:n } { __semantex_data_cs_#1_valuekey:nn } { #2 } } \cs_new:Npn \semantex_arg_keys_set:nn#1#2 { % The central command for doing keyval setup for the argument % #1 = object % #2 = keys \keyval_parse:cco % See last command { __semantex_data_cs_#1_arg_singlekey:n } { __semantex_data_cs_#1_arg_valuekey:nn } { #2 } } \cs_generate_variant:Nn \clist_map_function:nN { nc } \cs_new: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 } } \cs_generate_variant:Nn \semantex_keys_set:nn { xn } \DeclareDocumentCommand\SetupClass{mm}{ % a user-level command for setting up the object % #1 = class % #2 = setup \semantex_keys_set:xn { class_\cs_to_str:N #1 }{ #2 } } \DeclareDocumentCommand\SetupObject{mm}{% % #1 = object % #2 = setup \semantex_keys_set:xn { object_\cs_to_str:N #1 } { #2 } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % THE PRIMITIVE VALUEKEYS % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Now for the commands that are the basis of the keyval interface. % This basis consists of a collection of so-called "primitive" % valuekeys, which all use the syntax % \semantex_primitive_:nn % These are like primitive TeX commands -- they are not defined in % terms of other keys, and all other keys have to defined in terms % of these, one way or another. % For all of them, #1 = name of the class/object, and #2 = value of % the key. To keep the system as simple as possible, I chose only to % make primitive valuekeys, so there is no such thing as a primitive % singlekey. Therefore, for instance, the singlekey "return" is % defined as "return=", where return is a primitive valuekey that % does not use the value of the key for anything. % First, some very simple keys that we shall need over and over again: \cs_new:Npn\semantex_grab_first_argument_of_two:nn#1#2{#1} \cs_new:Npn\semantex_grab_second_argument_of_two:nn#1#2{#2} \cs_new:Npn\semantex_grab_first_argument_of_three:nnn#1#2#3{#1} \cs_new:Npn\semantex_grab_second_argument_of_three:nnn#1#2#3{#2} \cs_new:Npn\semantex_grab_third_argument_of_three:nnn#1#2#3{#3} \cs_new:Npn\semantex_grab_first_argument_of_four:nnnn#1#2#3#4{#1} \cs_new:Npn\semantex_grab_second_argument_of_four:nnnn#1#2#3#4{#2} \cs_new:Npn\semantex_grab_third_argument_of_four:nnnn#1#2#3#4{#3} \cs_new:Npn\semantex_grab_fourth_argument_of_four:nnnn#1#2#3#4{#4} \cs_new:Npn\semantex_grab_first_argument_of_five:nnnnn#1#2#3#4#5{#1} \cs_new:Npn\semantex_grab_second_argument_of_five:nnnnn#1#2#3#4#5{#2} \cs_new:Npn\semantex_grab_third_argument_of_five:nnnnn#1#2#3#4#5{#3} \cs_new:Npn\semantex_grab_fourth_argument_of_five:nnnnn#1#2#3#4#5{#4} \cs_new:Npn\semantex_grab_fifth_argument_of_five:nnnnn#1#2#3#4#5{#5} \cs_new:Npn\semantex_grab_first_argument_of_six:nnnnnn#1#2#3#4#5#6{#1} \cs_new:Npn\semantex_grab_second_argument_of_six:nnnnnn#1#2#3#4#5#6{#2} \cs_new:Npn\semantex_grab_third_argument_of_six:nnnnnn#1#2#3#4#5#6{#3} \cs_new:Npn\semantex_grab_fourth_argument_of_six:nnnnnn#1#2#3#4#5#6{#4} \cs_new:Npn\semantex_grab_fifth_argument_of_six:nnnnnn#1#2#3#4#5#6{#5} \cs_new:Npn\semantex_grab_sixth_argument_of_six:nnnnnn#1#2#3#4#5#6{#6} \cs_new:Npn\semantex_grab_first_argument_of_seven:nnnnnnn#1#2#3#4#5#6#7{#1} \cs_new:Npn\semantex_grab_second_argument_of_seven:nnnnnnn#1#2#3#4#5#6#7{#2} \cs_new:Npn\semantex_grab_third_argument_of_seven:nnnnnnn#1#2#3#4#5#6#7{#3} \cs_new:Npn\semantex_grab_fourth_argument_of_seven:nnnnnnn#1#2#3#4#5#6#7{#4} \cs_new:Npn\semantex_grab_fifth_argument_of_seven:nnnnnnn#1#2#3#4#5#6#7{#5} \cs_new:Npn\semantex_grab_sixth_argument_of_seven:nnnnnnn#1#2#3#4#5#6#7{#6} \cs_new:Npn\semantex_grab_seventh_argument_of_seven:nnnnnnn#1#2#3#4#5#6#7{#7} \cs_new:Npn\semantex_grab_first_argument_of_eight:nnnnnnnn#1#2#3#4#5#6#7#8{#1} \cs_new:Npn\semantex_grab_second_argument_of_eight:nnnnnnnn#1#2#3#4#5#6#7#8{#2} \cs_new:Npn\semantex_grab_third_argument_of_eight:nnnnnnnn#1#2#3#4#5#6#7#8{#3} \cs_new:Npn\semantex_grab_fourth_argument_of_eight:nnnnnnnn#1#2#3#4#5#6#7#8{#4} \cs_new:Npn\semantex_grab_fifth_argument_of_eight:nnnnnnnn#1#2#3#4#5#6#7#8{#5} \cs_new:Npn\semantex_grab_sixth_argument_of_eight:nnnnnnnn#1#2#3#4#5#6#7#8{#6} \cs_new:Npn\semantex_grab_seventh_argument_of_eight:nnnnnnnn#1#2#3#4#5#6#7#8{#7} \cs_new:Npn\semantex_grab_eighth_argument_of_eight:nnnnnnnn#1#2#3#4#5#6#7#8{#8} \cs_new:Npn\semantex_grab_first_argument_of_nine:nnnnnnnnn#1#2#3#4#5#6#7#8#9{#1} \cs_new:Npn\semantex_grab_second_argument_of_nine:nnnnnnnnn#1#2#3#4#5#6#7#8#9{#2} \cs_new:Npn\semantex_grab_third_argument_of_nine:nnnnnnnnn#1#2#3#4#5#6#7#8#9{#3} \cs_new:Npn\semantex_grab_fourth_argument_of_nine:nnnnnnnnn#1#2#3#4#5#6#7#8#9{#4} \cs_new:Npn\semantex_grab_fifth_argument_of_nine:nnnnnnnnn#1#2#3#4#5#6#7#8#9{#5} \cs_new:Npn\semantex_grab_sixth_argument_of_nine:nnnnnnnnn#1#2#3#4#5#6#7#8#9{#6} \cs_new:Npn\semantex_grab_seventh_argument_of_nine:nnnnnnnnn#1#2#3#4#5#6#7#8#9{#7} \cs_new:Npn\semantex_grab_eighth_argument_of_nine:nnnnnnnnn#1#2#3#4#5#6#7#8#9{#8} \cs_new:Npn\semantex_grab_ninth_argument_of_nine:nnnnnnnnn#1#2#3#4#5#6#7#8#9{#9} \cs_generate_variant:Nn\str_if_eq:nnTF {xxTF,ooTF} \cs_generate_variant:Nn\str_if_eq:nnT {xxT, ooT} \cs_generate_variant:Nn\str_if_eq:nnF {xxF, ooF} \cs_generate_variant:Nn\tl_if_blank:nTF { xTF, xT } \cs_generate_variant:Nn \tl_if_blank:nF { xF } \cs_new:Npn\semantex_primitive_valuekey_execute:nn#1#2 { % This keys just executes whatever data you plug into it. % Possibly, going forward, it might make more sense to define all % of these commands in the keyval handling command % so that the get commands are accessible from all keys. \cs_set:Npn\SemantexDataProvide##1{\semantex_data_tl_provide:nn{#1}{##1}} \cs_set:Npn\SemantexDataSet##1##2{\semantex_data_tl_set:nnn{#1}{##1}{##2}} \cs_set:Npn\SemantexDataSetx##1##2{\semantex_data_tl_set:nnx{#1}{##1}{##2}} \cs_set:Npn\SemantexDataPutRight##1##2{\semantex_data_tl_put_right:nnn{#1}{##1}{##2}} \cs_set:Npn\SemantexDataPutRightx##1##2{\semantex_data_tl_put_right:nnx{#1}{##1}{##2}} \cs_set:Npn\SemantexDataPutLeft##1##2{\semantex_data_tl_put_left:nnn{#1}{##1}{##2}} \cs_set:Npn\SemantexDataPutLeftx##1##2{\semantex_data_tl_put_left:nnx{#1}{##1}{##2}} \cs_set:Npn\SemantexDataGet##1{\semantex_data_tl_get:nn{#1}{##1}} \cs_set:Npn\SemantexDataGetExpNot##1{\semantex_data_tl_get_exp_not:nn{#1}{##1}} \cs_set:Npn\SemantexDataClear##1{\semantex_data_tl_clear:nn{#1}{##1}} \cs_set:Npn\SemantexKeysSet##1{\semantex_keys_set:nn{#1}{##1}} \cs_set:Npn\SemantexKeysSetx##1{\semantex_keys_set:nx{#1}{##1}} \cs_set:Npn\SemantexStrIfEqTF##1##2##3##4{\str_if_eq:xxTF{##1}{##2}{##3}{##4}} \cs_set:Npn\SemantexStrIfEqT##1##2##3{\str_if_eq:xxT{##1}{##2}{##3}} \cs_set:Npn\SemantexStrIfEqF##1##2##3{\str_if_eq:xxF{##1}{##2}{##3}} \cs_set:Npn\SemantexIfBlankTF##1##2##3{\tl_if_blank:xTF{##1}{##2}{##3}} \cs_set:Npn\SemantexIfBlankT##1##2{\tl_if_blank:xT{##1}{##2}} \cs_set:Npn\SemantexIfBlankF##1##2{\tl_if_blank:xF{##1}{##2}} \cs_set:Npn\SemantexBoolProvide##1{\semantex_data_bool_provide:nn{#1}{##1}} \cs_set:Npn\SemantexBoolSetTrue##1{\semantex_data_bool_set_true:nn{#1}{##1}} \cs_set:Npn\SemantexBoolSetFalse##1{\semantex_data_bool_set_false:nn{#1}{##1}} \cs_set:Npn\SemantexBoolIfTF##1##2##3{\semantex_data_bool_get:nnTF{#1}{##1}{##2}{##3}} \cs_set:Npn\SemantexBoolIfT##1##2{\semantex_data_bool_get:nnTF{#1}{##1}{##2}{}} \cs_set:Npn\SemantexBoolIfF##1##2{\semantex_data_bool_get:nnTF{#1}{##1}{}{##2}} \cs_set:Npn\SemantexIntProvide##1{\semantex_data_int_provide:nn{#1}{##1}} \cs_set:Npn\SemantexIntGet##1{\semantex_data_int_get:nn{#1}{##1}} \cs_set:Npn\SemantexIntClear##1{\semantex_data_int_clear:nn{#1}{##1}} \cs_set:Npn\SemantexIntIncr##1{\semantex_data_int_incr:nn{#1}{##1}} \cs_set:Npn\SemantexIntSet##1##2{\semantex_data_int_set:nnn{#1}{##1}{##2}} \cs_set:Npn\SemantexIntIfPositiveTF##1##2##3{\semantex_data_int_if_positive:nnTF{#1}{##1}{##2}{##3}} \cs_set:Npn\SemantexIntIfPositiveT##1##2{\semantex_data_int_if_positive:nnT{#1}{##1}{##2}} \cs_set:Npn\SemantexIntIfPositiveF##1##2{\semantex_data_int_if_positive:nnF{#1}{##1}{##2}} \cs_set:Npn\SemantexIntIfGreaterThanOneTF##1##2##3{\semantex_data_int_if_greater_than_one:nnTF{#1}{##1}{##2}{##3}} \cs_set:Npn\SemantexIntIfGreaterThanOneT##1##2{\semantex_data_int_if_greater_than_one:nnT{#1}{##1}{##2}} \cs_set:Npn\SemantexIntIfGreaterThanOneF##1##2{\semantex_data_int_if_greater_than_one:nnF{#1}{##1}{##2}} \cs_set:Npn\SemantexExpNot##1{\exp_not:n{##1}} %\exp_not:n{#2} % how about forget? #2 } \cs_new:Npn\semantex_primitive_valuekey_parse:nn#1#2 { % This command runs all the keys that the user may have % stored via the parseoptions key %\semantex_data_tl_inherit:nn { #1 } { parseoptions } \semantex_keys_set:nx { #1 } { \semantex_data_tl_get_exp_not:nn { #1 } { parseoptions } } \semantex_data_tl_clear:nn { #1 } { parseoptions } % this is probably necessary } \cs_new:Npn\semantex_primitive_valuekey_parseoptions:nn#1#2 { % This adds keys to the parseoptions token list \semantex_data_tl_put_right:nnn { #1 } { parseoptions } { #2 } } \cs_new:Npn\semantex_primitive_valuekey_return:nn#1#2 { % This is an umbrella key that runs all of the three % return routines, innerreturn, rightreturn, and leftreturn \semantex_primitive_valuekey_innerreturn:nn { #1 }{} \semantex_primitive_valuekey_rightreturn:nn { #1 }{} \semantex_primitive_valuekey_leftreturn:nn { #1 }{} } \cs_new:Npn\semantex_primitive_valuekey_innerreturn:nn#1#2 { % This adds all of the commands added via the command key % to the symbol \semantex_data_tl_inherit:nn { #1 } { symbol } \semantex_data_seq_inherit:nn { #1 } { commands_sequence } \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 {\exp_not:N ##1} { \semantex_data_tl_get_exp_not:nn { #1 } { symbol } } % This was the solution that happened to solve % the expansion issues best } } \semantex_data_seq_clear:nn { #1 } { commands_sequence } } \cs_generate_variant:Nn \semantex_keys_set:nn { nx , no } \cs_new:Npn\semantex_primitive_valuekey_rightreturn:nn#1#2 { \semantex_right_indices_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 } \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:Npn\semantex_primitive_valuekey_leftreturn:nn#1#2 { \semantex_left_indices_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 } \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:Npn \semantex_left_indices_return_store:nN#1#2 { \semantex_data_tl_inherit_x:nn { #1 } { upperleft } \semantex_data_tl_inherit_x:nn { #1 } { lowerleft } \semantex_data_tl_inherit_x:nn { #1 } { preupperleft } \semantex_data_tl_inherit_x:nn { #1 } { postupperleft } \semantex_data_tl_inherit_x:nn { #1 } { prelowerleft } \semantex_data_tl_inherit_x:nn { #1 } { postlowerleft } \tl_set:Nn#2{} \semantex_data_int_if_positive:nnTF { #1 } { numberofupperleftindices } { \semantex_data_int_if_positive:nnTF { #1 } { numberoflowerleftindices } { \tl_put_right:Nx#2 { {}\sp{ \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 } } \sb{ \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:Nx#2 { {}\sp{ \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 { {}\sb{ \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 } } \semantex_data_tl_clear:nn { #1 } { upperleft } \semantex_data_bool_provide:nn { #1 } { nextupperleftwithsep } % is it necessary to provide it before declaring it false? \semantex_data_bool_set_false:nn { #1 } { nextupperleftwithsep } \semantex_data_tl_clear:nn { #1 } { lowerleft } \semantex_data_bool_provide:nn { #1 } { nextlowerleftwithsep } % is it necessary to provide it before declaring it false? \semantex_data_bool_set_false:nn { #1 } { nextlowerleftwithsep } \semantex_data_tl_clear:nn { #1 } { preupperleft } \semantex_data_tl_clear:nn { #1 } { postupperleft } \semantex_data_tl_clear:nn { #1 } { prelowerleft } \semantex_data_tl_clear:nn { #1 } { postlowerleft } \semantex_data_int_clear:nn { #1 } { numberofupperleftindices } \semantex_data_int_clear:nn { #1 } { numberoflowerleftindices } } \cs_new:Npn \semantex_arg_return_store:nN#1#2 { \semantex_data_tl_inherit_x:nn { #1 } { arg } \semantex_data_int_inherit:nn { #1 } { numberofarguments } %\semantex_data_tl_inherit:nn { #1 } { parsize } % This was necessary for unkonwn reasons -- otherwise it will fail when doing inheritance \semantex_data_tl_get_store:nnN { #1 } { parsize } \l__semantex_primitive_valuekey_rightreturn_parsize_temp \semantex_data_bool_get:nnTF { #1 } { par } { \semantex_data_int_if_positive:nnTF { #1 } { numberofarguments } { \__semantex_parentheses_store:nnnnN { \l__semantex_primitive_valuekey_rightreturn_parsize_temp } { \semantex_data_tl_get_exp_not:nn { #1 } { leftpar } } { \semantex_data_tl_get_exp_not:nn { #1 } { rightpar } } { \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 } } #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:nnnnN { \l__semantex_primitive_valuekey_rightreturn_parsize_temp } { \semantex_data_tl_get_exp_not:nn { #1 } { leftpar } } { \semantex_data_tl_get_exp_not:nn { #1 } { rightpar } } { \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 } } #2 } { \semantex_data_int_if_positive:nnTF { #1 } { numberofarguments } { \__semantex_no_parentheses_store:nN { \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 } } #2 } { \tl_set:Nn#2{} } } } { \semantex_data_int_if_positive:nnTF { #1 } { numberofarguments } { \__semantex_no_parentheses_store:nN { \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 } } #2 } { \tl_set:Nn#2{} } } } \semantex_data_tl_clear:nn { #1 } { arg } \semantex_data_tl_clear:nn { #1 } { prearg } % Is it right to clear these? \semantex_data_tl_clear:nn { #1 } { postarg } \semantex_data_int_clear:nn { #1 } { numberofarguments } \semantex_data_bool_provide:nn { #1 } { nextargwithsep } % is it necessary to provide it before declaring it false? \semantex_data_bool_set_false:nn { #1 } { nextargwithsep } } \cs_new:Npn \semantex_right_indices_return_store:nN#1#2 { \semantex_data_tl_inherit_x:nn { #1 } { upper } \semantex_data_tl_inherit_x:nn { #1 } { lower } \semantex_data_tl_inherit_x:nn { #1 } { preupper } \semantex_data_tl_inherit_x:nn { #1 } { postupper } \semantex_data_tl_inherit_x:nn { #1 } { prelower } \semantex_data_tl_inherit_x:nn { #1 } { postlower } \tl_set:Nn#2{} \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 } \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_tl_clear:nn { #1 } { upper } \semantex_data_bool_provide:nn { #1 } { nextupperwithsep } % is it necessary to provide it before declaring it false? \semantex_data_bool_set_false:nn { #1 } { nextupperwithsep } \semantex_data_tl_clear:nn { #1 } { lower } \semantex_data_bool_provide:nn { #1 } { nextlowerwithsep } % is it necessary to provide it before declaring it false? \semantex_data_bool_set_false:nn { #1 } { nextlowerwithsep } \semantex_data_tl_clear:nn { #1 } { preupper } \semantex_data_tl_clear:nn { #1 } { postupper } \semantex_data_tl_clear:nn { #1 } { prelower } \semantex_data_tl_clear:nn { #1 } { postlower } \semantex_data_int_clear:nn { #1 } { numberofupperindices } \semantex_data_int_clear:nn { #1 } { numberoflowerindices } } \cs_new:Npn\semantex_primitive_valuekey_parent:nn#1#2{ % Must inherit everything from the parent class \semantex_data_parent_set:nn { #1 } { #2 } } \cs_new:Npn\semantex_primitive_valuekey_class:nn#1#2{ % Must inherit everything from the parent class \semantex_data_class_set:nn { #1 } { #2 } } \cs_new:Npn\semantex_primitive_valuekey_copy:nn#1#2{ % Similarly to parent and class, but inherits from other objects rather than classes \semantex_data_copy_object:nn { #1 } { #2 } } \cs_new:Npn\semantex_primitive_valuekey_clone:nn#1#2{ % Similarly to parent and class, but inherits from other objects rather than classes \semantex_data_clone_object:nn { #1 } { #2 } } \cs_new:Npn\semantex_primitive_valuekey_valuekeys:nn#1#2{ % Add new valuekeys \semantex_data_prop_provide:nn { #1 } { custom_valuekeys } \clist_map_inline:nn { #2 }{ \__semantex_valuekey_equality_format_auxiliary:nnn{#1}##1 } } \cs_generate_variant:Nn\semantex_data_prop_put:nnnn {nnno} \cs_new:Npn\__semantex_valuekey_equality_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_valuekey_equality_format_auxiliary_temp:n##1{#3} \semantex_data_prop_put:nnno {#1} {custom_valuekeys} {#2} { \l__semantex_valuekey_equality_format_auxiliary_temp:n { \l__semantex_key_value_temp } } %IM Remove spaces in #2 } \cs_new:Npn\semantex_primitive_valuekey_removevaluekey:nn#1#2 { \semantex_valuekey_remove:nn { #1 } { #2 } } \cs_set_eq:cN { semantex_primitive_valuekey_1valuekeys:nn } \semantex_primitive_valuekey_valuekeys:nn \cs_new:cpn { semantex_primitive_valuekey_2valuekeys:nn }#1#2{ % Add new valuekeys \semantex_data_prop_provide:nn { #1 } { custom_valuekeys } \clist_map_inline:nn { #2 }{ \__semantex_two_valuekey_equality_format_auxiliary:nnn{#1}##1 } } \cs_new:Npn\__semantex_two_valuekey_equality_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_two_valuekey_equality_format_auxiliary_temp:nn##1##2{#3} \semantex_data_prop_put:nnno {#1} {custom_valuekeys} {#2} { \l__semantex_two_valuekey_equality_format_auxiliary_temp:nn { \exp_not:N\semantex_grab_first_argument_of_two:nn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_second_argument_of_two:nn\l__semantex_key_value_temp } } %IM Remove spaces in #2 } \cs_new:cpn { semantex_primitive_valuekey_3valuekeys:nn }#1#2{ % Add new valuekeys \semantex_data_prop_provide:nn { #1 } { custom_valuekeys } \clist_map_inline:nn { #2 }{ \__semantex_three_valuekey_equality_format_auxiliary:nnn{#1}##1 } } \cs_new:Npn\__semantex_three_valuekey_equality_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_three_valuekey_equality_format_auxiliary_temp:nnn##1##2##3{#3} \semantex_data_prop_put:nnno {#1} {custom_valuekeys} {#2} { \l__semantex_three_valuekey_equality_format_auxiliary_temp:nnn { \exp_not:N\semantex_grab_first_argument_of_three:nnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_second_argument_of_three:nnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_third_argument_of_three:nnn\l__semantex_key_value_temp } } %IM Remove spaces in #2 } \cs_new:cpn { semantex_primitive_valuekey_4valuekeys:nn }#1#2{ % Add new valuekeys \semantex_data_prop_provide:nn { #1 } { custom_valuekeys } \clist_map_inline:nn { #2 }{ \__semantex_four_valuekey_equality_format_auxiliary:nnn{#1}##1 } } \cs_new:Npn\__semantex_four_valuekey_equality_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_four_valuekey_equality_format_auxiliary_temp:nnnn##1##2##3##4{#3} \semantex_data_prop_put:nnno {#1} {custom_valuekeys} {#2} { \l__semantex_four_valuekey_equality_format_auxiliary_temp:nnnn { \exp_not:N\semantex_grab_first_argument_of_four:nnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_second_argument_of_four:nnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_third_argument_of_four:nnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_fourth_argument_of_four:nnnn\l__semantex_key_value_temp } } %IM Remove spaces in #2 } \cs_new:cpn { semantex_primitive_valuekey_5valuekeys:nn }#1#2{ % Add new valuekeys \semantex_data_prop_provide:nn { #1 } { custom_valuekeys } \clist_map_inline:nn { #2 }{ \__semantex_five_valuekey_equality_format_auxiliary:nnn{#1}##1 } } \cs_new:Npn\__semantex_five_valuekey_equality_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_five_valuekey_equality_format_auxiliary_temp:nnnnn##1##2##3##4##5{#3} \semantex_data_prop_put:nnno {#1} {custom_valuekeys} {#2} { \l__semantex_five_valuekey_equality_format_auxiliary_temp:nnnnn { \exp_not:N\semantex_grab_first_argument_of_five:nnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_second_argument_of_five:nnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_third_argument_of_five:nnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_fourth_argument_of_five:nnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_fifth_argument_of_five:nnnnn\l__semantex_key_value_temp } } %IM Remove spaces in #2 } \cs_new:cpn { semantex_primitive_valuekey_6valuekeys:nn }#1#2{ % Add new valuekeys \semantex_data_prop_provide:nn { #1 } { custom_valuekeys } \clist_map_inline:nn { #2 }{ \__semantex_six_valuekey_equality_format_auxiliary:nnn{#1}##1 } } \cs_new:Npn\__semantex_six_valuekey_equality_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_six_valuekey_equality_format_auxiliary_temp:nnnnnn##1##2##3##4##5##6{#3} \semantex_data_prop_put:nnno {#1} {custom_valuekeys} {#2} { \l__semantex_six_valuekey_equality_format_auxiliary_temp:nnnnnn { \exp_not:N\semantex_grab_first_argument_of_six:nnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_second_argument_of_six:nnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_third_argument_of_six:nnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_fourth_argument_of_six:nnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_fifth_argument_of_six:nnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_sixth_argument_of_six:nnnnnn\l__semantex_key_value_temp } } %IM Remove spaces in #2 } \cs_new:cpn { semantex_primitive_valuekey_7valuekeys:nn }#1#2{ % Add new valuekeys \semantex_data_prop_provide:nn { #1 } { custom_valuekeys } \clist_map_inline:nn { #2 }{ \__semantex_seven_valuekey_equality_format_auxiliary:nnn{#1}##1 } } \cs_new:Npn\__semantex_seven_valuekey_equality_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_seven_valuekey_equality_format_auxiliary_temp:nnnnnnn##1##2##3##4##5##6##7{#3} \semantex_data_prop_put:nnno {#1} {custom_valuekeys} {#2} { \l__semantex_seven_valuekey_equality_format_auxiliary_temp:nnnnnnn { \exp_not:N\semantex_grab_first_argument_of_seven:nnnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_second_argument_of_seven:nnnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_third_argument_of_seven:nnnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_fourth_argument_of_seven:nnnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_fifth_argument_of_seven:nnnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_sixth_argument_of_seven:nnnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_seventh_argument_of_seven:nnnnnnn\l__semantex_key_value_temp } } %IM Remove spaces in #2 } \cs_new:cpn { semantex_primitive_valuekey_8valuekeys:nn }#1#2{ % Add new valuekeys \semantex_data_prop_provide:nn { #1 } { custom_valuekeys } \clist_map_inline:nn { #2 }{ \__semantex_eight_valuekey_equality_format_auxiliary:nnn{#1}##1 } } \cs_new:Npn\__semantex_eight_valuekey_equality_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_eight_valuekey_equality_format_auxiliary_temp:nnnnnnnn##1##2##3##4##5##6##7##8{#3} \semantex_data_prop_put:nnno {#1} {custom_valuekeys} {#2} { \l__semantex_eight_valuekey_equality_format_auxiliary_temp:nnnnnnnn { \exp_not:N\semantex_grab_first_argument_of_eight:nnnnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_second_argument_of_eight:nnnnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_third_argument_of_eight:nnnnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_fourth_argument_of_eight:nnnnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_fifth_argument_of_eight:nnnnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_sixth_argument_of_eight:nnnnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_seventh_argument_of_eight:nnnnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_eighth_argument_of_eight:nnnnnnnn\l__semantex_key_value_temp } } %IM Remove spaces in #2 } \cs_new:cpn { semantex_primitive_valuekey_9valuekeys:nn }#1#2{ % Add new valuekeys \semantex_data_prop_provide:nn { #1 } { custom_valuekeys } \clist_map_inline:nn { #2 }{ \__semantex_nine_valuekey_equality_format_auxiliary:nnn{#1}##1 } } \cs_new:Npn\__semantex_nine_valuekey_equality_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_nine_valuekey_equality_format_auxiliary_temp:nnnnnnnnn##1##2##3##4##5##6##7##8##9{#3} \semantex_data_prop_put:nnno {#1} {custom_valuekeys} {#2} { \l__semantex_nine_valuekey_equality_format_auxiliary_temp:nnnnnnnnn { \exp_not:N\semantex_grab_first_argument_of_nine:nnnnnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_second_argument_of_nine:nnnnnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_third_argument_of_nine:nnnnnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_fourth_argument_of_nine:nnnnnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_fifth_argument_of_nine:nnnnnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_sixth_argument_of_nine:nnnnnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_seventh_argument_of_nine:nnnnnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_eighth_argument_of_nine:nnnnnnnnn\l__semantex_key_value_temp } { \exp_not:N\semantex_grab_ninth_argument_of_nine:nnnnnnnnn\l__semantex_key_value_temp } } %IM Remove spaces in #2 } \cs_new:Npn\semantex_primitive_valuekey_singlekeys:nn#1#2{ % Add keys taking no values \semantex_data_prop_provide:nn { #1 } { custom_singlekeys } \clist_map_inline:nn { #2 }{ \__semantex_singlekeys_noequality_format_auxiliary:nnn{#1}##1 } } \cs_new:Npn \__semantex_singlekeys_noequality_format_auxiliary:nnn#1#2#3{ \semantex_data_prop_put:nnnn {#1} {custom_singlekeys} {#2} {#3} } \cs_set_eq:NN\semantex_primitive_valuekey_novaluekeys:nn\semantex_primitive_valuekey_singlekeys:nn % Previously, "singlekeys" was called "novaluekeys", so I am keeping this alias for backwards compatibility \cs_set_eq:cN { semantex_primitive_valuekey_0valuekeys:nn } \semantex_primitive_valuekey_singlekeys:nn \cs_new:Npn\semantex_primitive_valuekey_removesinglekey:nn#1#2 { \semantex_singlekey_remove:nn { #1 } { #2 } } \cs_set_eq:NN\semantex_primitive_valuekey_removenovaluekey:nn\semantex_primitive_valuekey_removesinglekey:nn % Previously, "singlekeys" was called "novaluekeys", so I am keeping this alias for backwards compatibility \cs_set_eq:cN { semantex_primitive_valuekey_remove0valuekey:nn } \semantex_primitive_valuekey_removesinglekey:nn % KEYS FOR SETTING UP THE ARGUMENT KEYVAL INTERFACE: \cs_new:Npn\semantex_primitive_valuekey_argvaluekeys:nn#1#2{ % Add argument valuekeys \semantex_data_prop_provide:nn { #1 } { custom_arg_valuekeys } \clist_map_inline:nn { #2 }{ \__semantex_arg_valuekey_equality_format_auxiliary:nnn{#1}##1 } } \cs_new:Npn \__semantex_arg_valuekey_equality_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_arg_valuekey_equality_format_auxiliary_temp:n##1{#3} \semantex_data_prop_put:nnno {#1} {custom_arg_valuekeys} {#2} { \l__semantex_arg_valuekey_equality_format_auxiliary_temp:n{ \l__semantex_arg_key_value_temp } } } \cs_new:Npn\semantex_primitive_valuekey_removeargvaluekey:nn#1#2 { \semantex_arg_valuekey_remove:nn { #1 } { #2 } } \cs_set_eq:cN { semantex_primitive_valuekey_arg1valuekeys:nn } \semantex_primitive_arg_valuekey_arg_valuekeys:nn \cs_new:cpn { semantex_primitive_valuekey_arg2valuekeys:nn }#1#2{ % Add new valuekeys \semantex_data_prop_provide:nn { #1 } { custom_arg_valuekeys } \clist_map_inline:nn { #2 }{ \__semantex_two_arg_valuekey_equality_format_auxiliary:nnn{#1}##1 } } \cs_new:Npn\__semantex_two_arg_valuekey_equality_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_two_arg_valuekey_equality_format_auxiliary_temp:nn##1##2{#3} \semantex_data_prop_put:nnno {#1} {custom_arg_valuekeys} {#2} { \l__semantex_two_arg_valuekey_equality_format_auxiliary_temp:nn { \exp_not:N\semantex_grab_first_argument_of_two:nn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_second_argument_of_two:nn\l__semantex_arg_key_value_temp } } %IM Remove spaces in #2 } \cs_new:cpn { semantex_primitive_valuekey_arg3valuekeys:nn }#1#2{ % Add new valuekeys \semantex_data_prop_provide:nn { #1 } { custom_arg_valuekeys } \clist_map_inline:nn { #2 }{ \__semantex_three_arg_valuekey_equality_format_auxiliary:nnn{#1}##1 } } \cs_new:Npn\__semantex_three_arg_valuekey_equality_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_three_arg_valuekey_equality_format_auxiliary_temp:nnn##1##2##3{#3} \semantex_data_prop_put:nnno {#1} {custom_arg_valuekeys} {#2} { \l__semantex_three_arg_valuekey_equality_format_auxiliary_temp:nnn { \exp_not:N\semantex_grab_first_argument_of_three:nnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_second_argument_of_three:nnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_third_argument_of_three:nnn\l__semantex_arg_key_value_temp } } %IM Remove spaces in #2 } \cs_new:cpn { semantex_primitive_valuekey_arg4valuekeys:nn }#1#2{ % Add new valuekeys \semantex_data_prop_provide:nn { #1 } { custom_arg_valuekeys } \clist_map_inline:nn { #2 }{ \__semantex_four_arg_valuekey_equality_format_auxiliary:nnn{#1}##1 } } \cs_new:Npn\__semantex_four_arg_valuekey_equality_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_four_arg_valuekey_equality_format_auxiliary_temp:nnnn##1##2##3##4{#3} \semantex_data_prop_put:nnno {#1} {custom_arg_valuekeys} {#2} { \l__semantex_four_arg_valuekey_equality_format_auxiliary_temp:nnnn { \exp_not:N\semantex_grab_first_argument_of_four:nnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_second_argument_of_four:nnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_third_argument_of_four:nnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_fourth_argument_of_four:nnnn\l__semantex_arg_key_value_temp } } %IM Remove spaces in #2 } \cs_new:cpn { semantex_primitive_valuekey_arg5valuekeys:nn }#1#2{ % Add new valuekeys \semantex_data_prop_provide:nn { #1 } { custom_arg_valuekeys } \clist_map_inline:nn { #2 }{ \__semantex_five_arg_valuekey_equality_format_auxiliary:nnn{#1}##1 } } \cs_new:Npn\__semantex_five_arg_valuekey_equality_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_five_arg_valuekey_equality_format_auxiliary_temp:nnnnn##1##2##3##4##5{#3} \semantex_data_prop_put:nnno {#1} {custom_arg_valuekeys} {#2} { \l__semantex_five_arg_valuekey_equality_format_auxiliary_temp:nnnnn { \exp_not:N\semantex_grab_first_argument_of_five:nnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_second_argument_of_five:nnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_third_argument_of_five:nnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_fourth_argument_of_five:nnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_fifth_argument_of_five:nnnnn\l__semantex_arg_key_value_temp } } %IM Remove spaces in #2 } \cs_new:cpn { semantex_primitive_valuekey_arg6valuekeys:nn }#1#2{ % Add new valuekeys \semantex_data_prop_provide:nn { #1 } { custom_arg_valuekeys } \clist_map_inline:nn { #2 }{ \__semantex_six_arg_valuekey_equality_format_auxiliary:nnn{#1}##1 } } \cs_new:Npn\__semantex_six_arg_valuekey_equality_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_six_arg_valuekey_equality_format_auxiliary_temp:nnnnnn##1##2##3##4##5##6{#3} \semantex_data_prop_put:nnno {#1} {custom_arg_valuekeys} {#2} { \l__semantex_six_arg_valuekey_equality_format_auxiliary_temp:nnnnnn { \exp_not:N\semantex_grab_first_argument_of_six:nnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_second_argument_of_six:nnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_third_argument_of_six:nnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_fourth_argument_of_six:nnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_fifth_argument_of_six:nnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_sixth_argument_of_six:nnnnnn\l__semantex_arg_key_value_temp } } %IM Remove spaces in #2 } \cs_new:cpn { semantex_primitive_valuekey_arg7valuekeys:nn }#1#2{ % Add new valuekeys \semantex_data_prop_provide:nn { #1 } { custom_arg_valuekeys } \clist_map_inline:nn { #2 }{ \__semantex_seven_arg_valuekey_equality_format_auxiliary:nnn{#1}##1 } } \cs_new:Npn\__semantex_seven_arg_valuekey_equality_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_seven_arg_valuekey_equality_format_auxiliary_temp:nnnnnnn##1##2##3##4##5##6##7{#3} \semantex_data_prop_put:nnno {#1} {custom_arg_valuekeys} {#2} { \l__semantex_seven_arg_valuekey_equality_format_auxiliary_temp:nnnnnnn { \exp_not:N\semantex_grab_first_argument_of_seven:nnnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_second_argument_of_seven:nnnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_third_argument_of_seven:nnnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_fourth_argument_of_seven:nnnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_fifth_argument_of_seven:nnnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_sixth_argument_of_seven:nnnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_seventh_argument_of_seven:nnnnnnn\l__semantex_arg_key_value_temp } } %IM Remove spaces in #2 } \cs_new:cpn { semantex_primitive_valuekey_arg8valuekeys:nn }#1#2{ % Add new valuekeys \semantex_data_prop_provide:nn { #1 } { custom_arg_valuekeys } \clist_map_inline:nn { #2 }{ \__semantex_eight_arg_valuekey_equality_format_auxiliary:nnn{#1}##1 } } \cs_new:Npn\__semantex_eight_arg_valuekey_equality_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_eight_arg_valuekey_equality_format_auxiliary_temp:nnnnnnnn##1##2##3##4##5##6##7##8{#3} \semantex_data_prop_put:nnno {#1} {custom_arg_valuekeys} {#2} { \l__semantex_eight_arg_valuekey_equality_format_auxiliary_temp:nnnnnnnn { \exp_not:N\semantex_grab_first_argument_of_eight:nnnnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_second_argument_of_eight:nnnnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_third_argument_of_eight:nnnnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_fourth_argument_of_eight:nnnnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_fifth_argument_of_eight:nnnnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_sixth_argument_of_eight:nnnnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_seventh_argument_of_eight:nnnnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_eighth_argument_of_eight:nnnnnnnn\l__semantex_arg_key_value_temp } } %IM Remove spaces in #2 } \cs_new:cpn { semantex_primitive_valuekey_arg9valuekeys:nn }#1#2{ % Add new valuekeys \semantex_data_prop_provide:nn { #1 } { custom_arg_valuekeys } \clist_map_inline:nn { #2 }{ \__semantex_nine_arg_valuekey_equality_format_auxiliary:nnn{#1}##1 } } \cs_new:Npn\__semantex_nine_arg_valuekey_equality_format_auxiliary:nnn#1#2#3 { \cs_set:Npn\l__semantex_nine_arg_valuekey_equality_format_auxiliary_temp:nnnnnnnnn##1##2##3##4##5##6##7##8##9{#3} \semantex_data_prop_put:nnno {#1} {custom_arg_valuekeys} {#2} { \l__semantex_nine_arg_valuekey_equality_format_auxiliary_temp:nnnnnnnnn { \exp_not:N\semantex_grab_first_argument_of_nine:nnnnnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_second_argument_of_nine:nnnnnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_third_argument_of_nine:nnnnnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_fourth_argument_of_nine:nnnnnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_fifth_argument_of_nine:nnnnnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_sixth_argument_of_nine:nnnnnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_seventh_argument_of_nine:nnnnnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_eighth_argument_of_nine:nnnnnnnnn\l__semantex_arg_key_value_temp } { \exp_not:N\semantex_grab_ninth_argument_of_nine:nnnnnnnnn\l__semantex_arg_key_value_temp } } %IM Remove spaces in #2 } \cs_new:Npn\semantex_primitive_valuekey_argsinglekeys:nn#1#2{ % Add argument keys taking no values \semantex_data_prop_provide:nn { #1 } { custom_arg_singlekeys } \clist_map_inline:nn { #2 }{ \__semantex_arg_singlekeys_noequality_format_auxiliary:nnn{#1}##1 } } \cs_new:Npn \__semantex_arg_singlekeys_noequality_format_auxiliary:nnn#1#2#3{ \semantex_data_prop_put:nnnn {#1} {custom_arg_singlekeys} {#2} {#3} } \cs_set_eq:NN\semantex_primitive_valuekey_argnovaluekeys:nn\semantex_primitive_valuekey_argsinglekeys:nn % Previously, "singlekeys" was called "novaluekeys", so I am keeping this alias for backwards compatibility \cs_new:Npn\semantex_primitive_valuekey_removeargsinglekey:nn#1#2 { \semantex_arg_singlekey_remove:nn { #1 } { #2 } } \cs_set_eq:NN\semantex_primitive_valuekey_removeargnovaluekey:nn\semantex_primitive_valuekey_removeargsinglekey:nn % Previously, "singlekeys" was called "novaluekeys", so I am keeping this alias for backwards compatibility \cs_set_eq:cN { semantex_primitive_valuekey_removearg0valuekey:nn } \semantex_primitive_valuekey_removeargsinglekey:nn % THESE ARE REALLY THE COMMANDS MANIPULATING DATA: \cs_new:Npn\semantex_primitive_valuekey_symbol:nn#1#2{ % Sets the value of the symbol \semantex_data_tl_set:nnn { #1 } { symbol } { \exp_not:n { #2 } } } \cs_new:Npn\semantex_primitive_valuekey_texclass:nn#1#2{ % Sets the TeX class of the output, e.g. \mathord, \mathbin, \mathop etc. \semantex_data_tl_set:nnn { #1 } { texclass } { \exp_not:n { #2 } } } \cs_new:Npn\semantex_primitive_valuekey_setslot:nn#1#2{ % Sets the argument slot, i.e. the - in f(-,x) \semantex_data_tl_set:nnn { #1 } { argslot } { \exp_not:n { #2 } } } \cs_new:Npn\semantex_primitive_valuekey_symbolputright:nn#1#2{ % Add something to the right of the symbol \semantex_data_tl_put_right:nnn { #1 } { symbol } { \exp_not:n { #2 } } } \cs_new:Npn\semantex_primitive_valuekey_symbolputleft:nn#1#2{ % Add something to the left of the symbol \semantex_data_tl_put_left:nnn { #1 } { symbol } { \exp_not:n { #2 } } } \cs_new:Npn\semantex_primitive_valuekey_command:nn#1#2{ % Adds one entry on the left of the command % sequence to be applied to the symbol \semantex_data_seq_put_right:nnn { #1 } { commands_sequence } { #2 } %IM maybe \exp_not:n { #2 }? } \cs_new:Npn\semantex_primitive_valuekey_clearcommand:nn#1#2{ % Adds one entry on the left of the command % sequence to be applied to the symbol \semantex_data_seq_clear:nn { #1 } { commands_sequence } } \cs_new:Npn\semantex_primitive_valuekey_argwithkeyval:nn#1#2{ % Sets the argument (allows keyval interface) \semantex_arg_keys_set:nn { #1 } { #2 } %IMPORTANT: Previously, we needed three braces around #2, but suddenly % this changed, even though I did not really change anything related % to this (except I added _auxiliary_ in the command names related % to arg keyvals) } \cs_new:Npn\semantex_primitive_valuekey_argwithsinglekeys:nn#1#2{ % Sets the argument (only allows singlekeys) \semantex_arg_singlekeys_set:nn { #1 } { #2 } } \cs_new:Npn\semantex_primitive_valuekey_argwithonesinglekey:nn#1#2{ % Sets the argument (only allows one singlekey) \use:c { __semantex_data_cs_#1_arg_singlekey:n } {{{{ #2 }}}} } \cs_new:Npn\semantex_primitive_valuekey_argwithoutkeyval:nn#1#2{ % Sets the argument (no keyval interface allowed) \semantex_data_tl_put_right:nnn { #1 } { arg } { \exp_not:n { #2 } } \semantex_data_int_incr:nn { #1 } { numberofarguments } % Check if this has been added elsewhere \semantex_data_bool_set_true:nn { #1 } { nextargwithsep } } \cs_new:Npn\semantex_primitive_valuekey_setargsep:nn#1#2 { % Sets the argument separator \semantex_data_tl_set:nnn { #1 } { argsep } { \exp_not:n { #2 } } } \cs_new:Npn\semantex_primitive_valuekey_setargdots:nn#1#2 { % Sets the argument dot command \semantex_data_tl_set:nnn { #1 } { argdots } { \exp_not:n { #2 } } } \cs_new:Npn\semantex_primitive_valuekey_setargslot:nn#1#2 { % Sets the argument dot command \semantex_data_tl_set:nnn { #1 } { argslot } { \exp_not:n { #2 } } } \cs_new:Npn\semantex_primitive_valuekey_prearg:nn#1#2{ % Sets something to write before the argument \tl_if_blank:nF{#2} { \semantex_data_tl_put_left:nnn { #1 } { prearg } { \exp_not:n { #2 } } } } \cs_new:Npn\semantex_primitive_valuekey_clearprearg:nn#1#2 { \semantex_data_tl_clear:nn { #1 } { prearg } } \cs_new:Npn\semantex_primitive_valuekey_postarg:nn#1#2{ % Sets something to write after the argument \tl_if_blank:nF{#2} { \semantex_data_tl_put_right:nnn { #1 } { postarg } { \exp_not:n{ #2 } } } } \cs_new:Npn\semantex_primitive_valuekey_clearpostarg:nn#1#2 { \semantex_data_tl_clear:nn { #1 } { postarg } } \cs_new:Npn\semantex_primitive_valuekey_output:nn#1#2 { % Tells what class the object is supposed to output \semantex_class_if_exist:NTF { #2 } { \semantex_data_tl_set:nnx { #1 } { output } { class_\cs_to_str:N #2 } } { \semantex_error_output_format:nN { #1 } \__semantex_primitive_valuekey_output_temp \msg_error:nnxnn { semantex } { class_not_found } { \__semantex_primitive_valuekey_output_temp } { output } { #2 } } % Maybe allow output=self } \cs_new:Npn\semantex_primitive_valuekey_outputoptions:nn#1#2{ % Sets possible options to pass to the output class \semantex_data_tl_put_right:nnn { #1 } { outputoptions } { ,#2, } } \cs_new:Npn\semantex_primitive_valuekey_ifleftargument:nn#1#2{ % Tells whether to rightreturn before rendering the output. \str_if_eq:nnTF { #2 } { true } { \semantex_data_bool_set_true:nn { #1 } { leftargument } } { \str_if_eq:nnTF { #2 } { false } { \semantex_data_bool_set_false:nn { #1 } { leftargument } } { \semantex_error_output_format:nN { #1 } \l__semantex_primitive_valuekey_ifleftargumen_temp \msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_primitive_valuekey_ifleftargumen_temp } { ifleftargument } { #2 } } } } \cs_new:Npn\semantex_primitive_valuekey_ifoutput:nn#1#2{ %IMPLEMENT THIS % Tells whether to output or not \str_if_eq:nnTF { #2 } { true } { \semantex_data_bool_set_true:nn { #1 } { output } } { \str_if_eq:nnTF { #2 } { false } { \semantex_data_bool_set_false:nn { #1 } { output } } { \semantex_error_output_format:nN { #1 } \l__semantex_primitive_valuekey_ifoutput_temp \msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_primitive_valuekey_ifoutput_temp } { ifoutput } { #2 } } } } \cs_new:Npn\semantex_primitive_valuekey_gradingposition:nn#1#2{ % Tells whether to use upper or lower indices \semantex_data_bool_provide:nn { #1 } { uppergrading } \str_if_eq:nnTF { #2 } { upper } { \semantex_data_bool_set_true:nn { #1 } { uppergrading } } { \str_if_eq:nnTF { #2 } { lower } { \semantex_data_bool_set_false:nn { #1 } { uppergrading } } { \semantex_error_output_format:nN { #1 } \l__semantex_primitive_valuekey_gradingposition_temp \msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_primitive_valuekey_gradingposition_temp } { gradingposition } { #2 } } } } \cs_set_eq:NN \semantex_primitive_valuekey_gradingpos:nn \semantex_primitive_valuekey_gradingposition:nn % Upper and lower right indices: \cs_new:Npn\semantex_primitive_valuekey_upper:nn#1#2{ % adds to the upper index \tl_if_blank:nF{#2}{ \semantex_data_tl_put_right:nnn { #1 } { upper } { \exp_not:n{ #2 } } \semantex_data_bool_set_true:nn { #1 } { nextupperwithsep } \semantex_data_int_incr:nn { #1 } { numberofupperindices } } } \cs_new:Npn\semantex_primitive_valuekey_supper:nn#1#2{ % Adds to the upper index, with a separator \tl_if_blank:nF{#2} { \semantex_data_bool_get:nnTF { #1 } { nextupperwithsep } { \semantex_data_tl_put_right:nnx { #1 } { upper } { \exp_not:n { \semantex_data_tl_get:nn { #1 } { uppersep } } } \semantex_data_tl_put_right:nnn { #1 } { upper } { \exp_not:n { #2 } } } { \semantex_data_tl_put_right:nnn { #1 } { upper } { \exp_not:n { #2 } } } \semantex_data_bool_set_true:nn { #1 } { nextupperwithsep } \semantex_data_int_incr:nn { #1 } { numberofupperindices } } } \cs_new:Npn\semantex_primitive_valuekey_upperputleft:nn#1#2{ % Adds to the left of the upper index \tl_if_blank:nF{#2}{ \semantex_data_tl_put_left:nnn { #1 } { upper } { \exp_not:n{ #2 } } \semantex_data_bool_set_true:nn { #1 } { nextupperwithsep } \semantex_data_int_incr:nn { #1 } { numberofupperindices } } } \cs_new:Npn\semantex_primitive_valuekey_preupper:nn#1#2{ % Sets what to write before upper \tl_if_blank:nF{#2} { \semantex_data_tl_put_left:cn { #1 } { preupper } { \exp_not:n{ #2 } } } } \cs_new:Npn\semantex_primitive_valuekey_postupper:nn#1#2{ % Sets what to write after upper \tl_if_blank:nF{#2} { \semantex_data_tl_put_right:nnn { #1 } { postupper } { \exp_not:n{ #2 } } } } \cs_new:Npn\semantex_primitive_valuekey_clearupper:nn#1#2{ \semantex_data_tl_clear:nn { #1 } { upper } \semantex_data_bool_set_false:nn { #1 } { nextupperwithsep } \semantex_data_int_clear:nn { #1 } { numberofupperindices } } \cs_new:Npn\semantex_primitive_valuekey_clearpreupper:nn#1#2{ \semantex_data_tl_clear:nn { #1 } { preupper } } \cs_new:Npn\semantex_primitive_valuekey_clearpostupper:nn#1#2{ \semantex_data_tl_clear:nn { #1 } { postupper } } \cs_new:Npn\semantex_primitive_valuekey_setupperdots:nn#1#2 { \semantex_data_tl_set:nnn { #1 } { upperdots } { \exp_not:n { #2 } } } \cs_generate_variant:Nn\semantex_primitive_valuekey_upper:nn { nx } \cs_new:Npn\semantex_primitive_valuekey_upperdots:nn#1#2 { \semantex_primitive_valuekey_upper:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperdots } } } \cs_new:Npn\semantex_primitive_valuekey_setupperslot:nn#1#2 { \semantex_data_tl_set:nnn { #1 } { upperslot } { \exp_not:n { #2 } } } \cs_new:Npn\semantex_primitive_valuekey_upperslot:nn#1#2 { \semantex_primitive_valuekey_upper:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperslot } } } \cs_generate_variant:Nn \semantex_primitive_valuekey_supper:nn { nx } \cs_new:Npn\semantex_primitive_valuekey_supperdots:nn#1#2 { \semantex_primitive_valuekey_supper:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperdots } } } \cs_new:Npn\semantex_primitive_valuekey_supperslot:nn#1#2 { \semantex_primitive_valuekey_supper:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperslot } } } \cs_generate_variant:Nn \semantex_primitive_valuekey_cupper:nn { nx } \cs_new:Npn\semantex_primitive_valuekey_cupperdots:nn#1#2 { \semantex_primitive_valuekey_cupper:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperdots } } } \cs_new:Npn\semantex_primitive_valuekey_cupperslot:nn#1#2 { \semantex_primitive_valuekey_cupper:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperslot } } } \cs_generate_variant:Nn \semantex_primitive_valuekey_upperwithothersep:nn { nx } \cs_new:Npn\semantex_primitive_valuekey_upperdotswithothersep:nn#1#2 { \semantex_primitive_valuekey_upperwithothersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get:nn { #1 } { upperdots } } } } \cs_new:Npn\semantex_primitive_valuekey_upperslotwithothersep:nn#1#2 { \semantex_primitive_valuekey_upperwithothersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get:nn { #1 } { upperslot } } } } \cs_new:Npn\semantex_primitive_valuekey_lower:nn#1#2{ % Adds to the lower index \tl_if_blank:nF{#2} { \semantex_data_tl_put_right:nnn { #1 } { lower } { \exp_not:n { #2 } } \semantex_data_bool_set_true:nn { #1 } { nextlowerwithsep } \semantex_data_int_incr:nn { #1 } { numberoflowerindices } } } \cs_new:Npn\semantex_primitive_valuekey_slower:nn#1#2{ % Adds to the lower index, with a separator \tl_if_blank:nF{#2} { \semantex_data_bool_get:nnTF { #1 } { nextlowerwithsep } { \semantex_data_tl_put_right:nnx { #1 } { lower } { \exp_not:n { \semantex_data_tl_get:nn { #1 } { lowersep } } } \semantex_data_tl_put_right:nnn { #1 } { lower } { \exp_not:n { #2 } } } { \semantex_data_tl_put_right:nnn { #1 } { lower } { \exp_not:n { #2 } } } \semantex_data_bool_set_true:nn { #1 } { nextlowerwithsep } \semantex_data_int_incr:nn { #1 } { numberoflowerindices } } } \cs_new:Npn\semantex_primitive_valuekey_lowerputleft:nn#1#2{ % Adds to the lower index \tl_if_blank:nF{#2} { \semantex_data_tl_put_left:nnn { #1 } { lower } { \exp_not:n { #2 } } \semantex_data_bool_set_true:nn { #1 } { nextlowerwithsep } \semantex_data_int_incr:nn { #1 } { numberoflowerindices } } } \cs_new:Npn\semantex_primitive_valuekey_prelower:nn#1#2{ % Sets what to write before the lower index \tl_if_blank:nF{#2} { \semantex_data_tl_put_left:nnn { #1 } { prelower } { \exp_not:n { #2 } } } } \cs_new:Npn\semantex_primitive_valuekey_postlower:nn#1#2{ % Sets what to write after the lower index \tl_if_blank:nF{#2} { \semantex_data_tl_put_right:nnn { #1 } { postlower } { \exp_not:n{ #2 } } } } \cs_new:Npn\semantex_primitive_valuekey_clearlower:nn#1#2{ \semantex_data_tl_clear:nn { #1 } { lower } \semantex_data_bool_set_false:nn { #1 } { nextlowerwithsep } \semantex_data_int_clear:nn { #1 } { numberoflowerindices } } \cs_new:Npn\semantex_primitive_valuekey_clearprelower:nn#1#2{ \semantex_data_tl_clear:nn { #1 } { prelower } } \cs_new:Npn\semantex_primitive_valuekey_clearpostlower:nn#1#2{ \semantex_data_tl_clear:nn { #1 } { postlower } } \cs_new:Npn\semantex_primitive_valuekey_setlowerdots:nn#1#2 { \semantex_data_tl_set:nnn { #1 } { lowerdots } { \exp_not:n { #2 } } } \cs_generate_variant:Nn \semantex_primitive_valuekey_lower:nn { nx } \cs_new:Npn\semantex_primitive_valuekey_lowerdots:nn#1#2 { \semantex_primitive_valuekey_lower:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerdots } } } \cs_new:Npn\semantex_primitive_valuekey_setlowerslot:nn#1#2 { \semantex_data_tl_set:nnn { #1 } { lowerslot } { \exp_not:n { #2 } } } \cs_new:Npn\semantex_primitive_valuekey_lowerslot:nn#1#2 { \semantex_primitive_valuekey_lower:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerslot } } } \cs_generate_variant:Nn \semantex_primitive_valuekey_slower:nn { nx } \cs_new:Npn\semantex_primitive_valuekey_slowerdots:nn#1#2 { \semantex_primitive_valuekey_slower:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerdots } } } \cs_new:Npn\semantex_primitive_valuekey_slowerslot:nn#1#2 { \semantex_primitive_valuekey_slower:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerslot } } } \cs_generate_variant:Nn \semantex_primitive_valuekey_clower:nn { nx } \cs_new:Npn\semantex_primitive_valuekey_clowerdots:nn#1#2 { \semantex_primitive_valuekey_clower:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerdots } } } \cs_new:Npn\semantex_primitive_valuekey_clowerslot:nn#1#2 { \semantex_primitive_valuekey_clower:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerslot } } } \cs_generate_variant:Nn \semantex_primitive_valuekey_lowerwithothersep:nn { nx } \cs_new:Npn\semantex_primitive_valuekey_lowerdotswithothersep:nn#1#2 { \semantex_primitive_valuekey_lowerwithothersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get:nn { #1 } { lowerdots } } } } \cs_new:Npn\semantex_primitive_valuekey_lowerslotwithothersep:nn#1#2 { \semantex_primitive_valuekey_lowerwithothersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get:nn { #1 } { lowerslot } } } } \cs_new:Npn\semantex_primitive_valuekey_upperwithothersep:nn#1#2{ % upperwithsep={separator}{contents} adds contents to the upper index % with the appropriate index separator \semantex_data_bool_get:nnTF { #1 } { nextupperwithsep } { \semantex_data_tl_put_right:nnn { #1 } { upper } { \exp_not:n { \semantex_grab_first_argument_of_two:nn #2 \semantex_grab_second_argument_of_two:nn #2 } } } { \semantex_data_tl_put_right:nnn { #1 } { upper } { \exp_not:n { \semantex_grab_second_argument_of_two:nn #2 } } } \semantex_data_bool_set_true:nn { #1 } { nextupperwithsep } \semantex_data_int_incr:nn { #1 } { numberofupperindices } } \cs_new:Npn\semantex_primitive_valuekey_lowerwithothersep:nn#1#2{ % lowerwithsep={separator}{contents} adds contents to the lower index % with the appropriate index separator \semantex_data_bool_get:nnTF { #1 } { nextlowerwithsep } { \semantex_data_tl_put_right:nnn { #1 } { lower } { \exp_not:n { \semantex_grab_first_argument_of_two:nn #2 \semantex_grab_second_argument_of_two:nn #2 } } } { \semantex_data_tl_put_right:nnn { #1 } { lower } { \exp_not:n { \semantex_grab_second_argument_of_two:nn #2 } } } \semantex_data_bool_set_true:nn { #1 } { nextlowerwithsep } \semantex_data_int_incr:nn { #1 } { numberofupperindices } } \cs_new:Npn\semantex_primitive_valuekey_cupper:nn#1#2{ % Adds to the upper index, with a comma as separator \tl_if_blank:nF{#2} { \semantex_data_bool_get:nnTF { #1 } { nextupperwithsep } { \semantex_data_tl_put_right:nnn { #1 } { upper } { , \exp_not:n { #2 } } } { \semantex_data_tl_put_right:nnn { #1 } { upper } { \exp_not:n { #2 } } } \semantex_data_bool_set_true:nn { #1 } { nextupperwithsep } \semantex_data_int_incr:nn { #1 } { numberofupperindices } } } \cs_new:Npn\semantex_primitive_valuekey_clower:nn#1#2{ % Adds to the lower index, with a comma as separator \tl_if_blank:nF{#2} { \semantex_data_bool_get:nnTF { #1 } { nextlowerwithsep } { \semantex_data_tl_put_right:nnn { #1 } { lower } { , \exp_not:n { #2 } } } { \semantex_data_tl_put_right:nnn { #1 } { lower } { \exp_not:n { #2 } } } \semantex_data_bool_set_true:nn { #1 } { nextlowerwithsep } \semantex_data_int_incr:nn { #1 } { numberoflowerindices } } } \cs_new:Npn\semantex_primitive_valuekey_ifnextupperwithsep:nn#1#2 { % Tells whether the upper index is the first one \tl_if_eq:nnTF { #2 } { false } { \semantex_data_bool_set_false:nn { #1 } { nextupperwithsep } } { \tl_if_eq:nnTF { #2 } { true } { \semantex_data_bool_set_true:nn { #1 } { nextupperwithsep } } { \semantex_error_output_format:nN { #1 } \l__semantex_primitive_valuekey_ifnextupperwithsep_temp \msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_primitive_valuekey_ifnextupperwithsep_temp } { ifnextupperwithsep } { #2 } } } } \cs_new:Npn\semantex_primitive_valuekey_ifnextlowerwithsep:nn#1#2 % should be removed later { % Tells whether the lower index is the first one \tl_if_eq:nnTF { #2 } { false } { \semantex_data_bool_set_false:nn { #1 } { nextlowerwithsep } } { \tl_if_eq:nnTF { #2 } { true } { \semantex_data_bool_set_true:nn { #1 } { nextlowerwithsep } } { \semantex_error_output_format:nN { #1 } \l__semantex_primitive_valuekey_ifnextlowerwithsep_temp \msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_primitive_valuekey_ifnextlowerwithsep_temp } { ifnextlowerwithsep } { #2 } } } } \cs_new:Npn\semantex_primitive_valuekey_setuppersep:nn#1#2 { % Sets the separator for the upper index \semantex_data_tl_set:nnn { #1 } { uppersep } { \exp_not:n { #2 }} } \cs_new:Npn\semantex_primitive_valuekey_setlowersep:nn#1#2 { % Sets the separator for the lower index \semantex_data_tl_set:nnn { #1 } { lowersep } { \exp_not:n { #2 }} } %--------------- Left indices: (I don't repeat all of the documentation) \cs_new:Npn\semantex_primitive_valuekey_upperleft:nn#1#2{ % adds to the upper left index \tl_if_blank:nF{#2}{ \semantex_data_tl_put_left:nnn { #1 } { upperleft } { \exp_not:n{ #2 } } \semantex_data_bool_set_true:nn { #1 } { nextupperleftwithsep } \semantex_data_int_incr:nn { #1 } { numberofupperleftindices } } } \cs_new:Npn\semantex_primitive_valuekey_supperleft:nn#1#2{ \tl_if_blank:nF{#2} { \semantex_data_bool_get:nnTF { #1 } { nextupperwithsep } { \semantex_data_tl_put_left:nnx { #1 } { upperleft } { \exp_not:n { \semantex_data_tl_get:nn { #1 } { uppersep } } } \semantex_data_tl_put_left:nnn { #1 } { upperleft } { \exp_not:n { #2 } } } { \semantex_data_tl_put_left:nnn { #1 } { upperleft } { \exp_not:n { #2 } } } \semantex_data_bool_set_true:nn { #1 } { nextupperleftwithsep } \semantex_data_int_incr:nn { #1 } { numberofupperleftindices } } } \cs_new:Npn\semantex_primitive_valuekey_upperleftputright:nn#1#2{ \tl_if_blank:nF{#2}{ \semantex_data_tl_put_right:nnn { #1 } { upperleft } { \exp_not:n{ #2 } } \semantex_data_bool_set_true:nn { #1 } { nextupperleftwithsep } \semantex_data_int_incr:nn { #1 } { numberofupperleftindices } } } \cs_new:Npn\semantex_primitive_valuekey_preupperleft:nn#1#2{ \tl_if_blank:nF{#2} { \semantex_data_tl_put_left:nnn { #1 } { preupperleft } { \exp_not:n{ #2 } } } } \cs_new:Npn\semantex_primitive_valuekey_postupperleft:nn#1#2{ % adds to the lower index \tl_if_blank:nF{#2} { \semantex_data_tl_put_right:nnn { #1 } { postupperleft } { \exp_not:n{ #2 } } } } \cs_new:Npn\semantex_primitive_valuekey_clearupperleft:nn#1#2{ \semantex_data_tl_clear:nn { #1 } { upperleft } \semantex_data_bool_set_false:nn { #1 } { nextupperleftwithsep } \semantex_data_int_clear:nn { #1 } { numberofupperleftindices } } \cs_new:Npn\semantex_primitive_valuekey_clearpreupperleft:nn#1#2{ \semantex_data_tl_clear:nn { #1 } { preupperleft } } \cs_new:Npn\semantex_primitive_valuekey_clearpostupperleft:nn#1#2{ \semantex_data_tl_clear:nn { #1 } { preupperleft } } \cs_new:Npn\semantex_primitive_valuekey_setupperleftdots:nn#1#2 { \semantex_data_tl_set:nnn { #1 } { upperleftdots } { \exp_not:n { #2 } } } \cs_generate_variant:Nn \semantex_primitive_valuekey_upperleft:nn { nx } \cs_new:Npn\semantex_primitive_valuekey_upperleftdots:nn#1#2 { \semantex_primitive_valuekey_upperleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperleftdots } } } \cs_new:Npn\semantex_primitive_valuekey_setupperleftslot:nn#1#2 { \semantex_data_tl_set:nnn { #1 } { upperleftslot } { \exp_not:n { #2 } } } \cs_new:Npn\semantex_primitive_valuekey_upperleftslot:nn#1#2 { \semantex_primitive_valuekey_upperleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperleftslot } } } \cs_generate_variant:Nn \semantex_primitive_valuekey_supperleft:nn { nx } \cs_new:Npn\semantex_primitive_valuekey_supperleftdots:nn#1#2 { \semantex_primitive_valuekey_supperleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperleftdots } } } \cs_new:Npn\semantex_primitive_valuekey_supperleftslot:nn#1#2 { \semantex_primitive_valuekey_supperleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperleftslot } } } \cs_generate_variant:Nn \semantex_primitive_valuekey_cupperleft:nn { nx } \cs_new:Npn\semantex_primitive_valuekey_cupperleftdots:nn#1#2 { \semantex_primitive_valuekey_cupperleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperleftdots } } } \cs_new:Npn\semantex_primitive_valuekey_cupperleftslot:nn#1#2 { \semantex_primitive_valuekey_cupperleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperleftslot } } } \cs_generate_variant:Nn \semantex_primitive_valuekey_upperleftwithothersep:nn { nx } \cs_new:Npn\semantex_primitive_valuekey_upperleftdotswithothersep:nn#1#2 { \semantex_primitive_valuekey_upperleftwithothersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get:nn { #1 } { upperleftdots } } } } \cs_new:Npn\semantex_primitive_valuekey_upperleftslotwithothersep:nn#1#2 { \semantex_primitive_valuekey_upperleftwithothersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get:nn { #1 } { upperleftslot } } } } \cs_new:Npn\semantex_primitive_valuekey_lowerleft:nn#1#2{ \tl_if_blank:nF{#2} { \semantex_data_tl_put_left:nnn { #1 } { lowerleft } { \exp_not:n{ #2 } } \semantex_data_bool_set_true:nn { #1 } { nextlowerleftwithsep } \semantex_data_int_incr:nn { #1 } { numberoflowerleftindices } } } \cs_new:Npn\semantex_primitive_valuekey_slowerleft:nn#1#2{ \tl_if_blank:nF{#2} { \semantex_data_bool_get:nnTF { #1 } { nextlowerleftwithsep } { \semantex_data_tl_put_left:nnx { #1 } { lowerleft } { \exp_not:n { \semantex_data_tl_get:nn { #1 } { lowerleftsep } } } \semantex_data_tl_put_left:nnn { #1 } { lowerleft } { \exp_not:n { #2 } } } { \semantex_data_tl_put_left:nnn { #1 } { lowerleft } { \exp_not:n { #2 } } } \semantex_data_bool_set_true:nn { #1 } { nextlowerleftwithsep } \semantex_data_int_incr:nn { #1 } { numberoflowerleftindices } } } \cs_new:Npn\semantex_primitive_valuekey_lowerleftputright:nn#1#2{ \tl_if_blank:nF{#2} %This test really shouldn’t be made. { \semantex_data_tl_put_right:nnn { #1 } { lowerleft } { \exp_not:n{ #2 } } \semantex_data_bool_set_true:nn { #1 } { nextlowerleftwithsep } \semantex_data_int_incr:nn { #1 } { numberoflowerleftindices } } } \cs_new:Npn\semantex_primitive_valuekey_prelowerleft:nn#1#2{ \tl_if_blank:nF{#2} { \semantex_data_tl_put_left:nnn { #1 } { prelowerleft } { \exp_not:n{ #2 } } } } \cs_new:Npn\semantex_primitive_valuekey_postlowerleft:nn#1#2{ \tl_if_blank:nF{#2} { \semantex_data_tl_put_right:nnn { #1 } { postlowerleft } { \exp_not:n{ #2 } } } } \cs_new:Npn\semantex_primitive_valuekey_upperleftwithothersep:nn#1#2{ \semantex_data_bool_get:nnTF { #1 } { nextupperleftwithsep } { \semantex_data_tl_put_left:nnn { #1 } { upperleft } { \exp_not:n { \semantex_grab_second_argument_of_two:nn #2 \semantex_grab_first_argument_of_two:nn #2 } } } { \semantex_data_tl_put_left:nnn { #1 } { upperleft } { \exp_not:n { \semantex_grab_second_argument_of_two:nn #2 } } } \semantex_data_bool_set_true:nn { #1 } { nextupperleftwithsep } \semantex_data_int_incr:nn { #1 } { numberofupperleftindices } } \cs_new:Npn\semantex_primitive_valuekey_lowerleftwithothersep:nn#1#2{ \semantex_data_bool_get:nnTF { #1 } { nextlowerleftwithsep } { \semantex_data_tl_put_left:nnn { #1 } { lowerleft } { \exp_not:n { \semantex_grab_second_argument_of_two:nn #2 \semantex_grab_first_argument_of_two:nn #2 } } } { \semantex_data_tl_put_left:nnn { #1 } { lowerleft } { \exp_not:n { \semantex_grab_second_argument_of_two:nn #2 } } } \semantex_data_bool_set_true:nn { #1 } { nextlowerleftwithsep } \semantex_data_int_incr:nn { #1 } { numberoflowerleftindices } } \cs_new:Npn\semantex_primitive_valuekey_clearlowerleft:nn#1#2{ \semantex_data_tl_clear:nn { #1 } { lowerleft } \semantex_data_bool_set_false:nn { #1 } { nextlowerleftwithsep } \semantex_data_int_clear:nn { #1 } { numberoflowerleftindices } } \cs_new:Npn\semantex_primitive_valuekey_clearprelowerleft:nn#1#2{ \semantex_data_tl_clear:nn { #1 } { prelowerleft } } \cs_new:Npn\semantex_primitive_valuekey_clearpostlowerleft:nn#1#2{ \semantex_data_tl_clear:nn { #1 } { prelowerleft } } \cs_new:Npn\semantex_primitive_valuekey_setlowerleftdots:nn#1#2 { \semantex_data_tl_set:nnn { #1 } { lowerleftdots } { \exp_not:n { #2 } } } \cs_generate_variant:Nn \semantex_primitive_valuekey_lowerleft:nn { nx } \cs_new:Npn\semantex_primitive_valuekey_lowerleftdots:nn#1#2 { \semantex_primitive_valuekey_lowerleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerleftdots } } } \cs_new:Npn\semantex_primitive_valuekey_setlowerleftslot:nn#1#2 { \semantex_data_tl_set:nnn { #1 } { lowerleftslot } { \exp_not:n { #2 } } } \cs_new:Npn\semantex_primitive_valuekey_lowerleftslot:nn#1#2 { \semantex_primitive_valuekey_lowerleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerleftslot } } } \cs_generate_variant:Nn \semantex_primitive_valuekey_slowerleft:nn { nx } \cs_new:Npn\semantex_primitive_valuekey_slowerleftdots:nn#1#2 { \semantex_primitive_valuekey_slowerleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerleftdots } } } \cs_new:Npn\semantex_primitive_valuekey_slowerleftslot:nn#1#2 { \semantex_primitive_valuekey_slowerleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerleftslot } } } \cs_generate_variant:Nn \semantex_primitive_valuekey_clowerleft:nn { nx } \cs_new:Npn\semantex_primitive_valuekey_clowerleftdots:nn#1#2 { \semantex_primitive_valuekey_clowerleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerleftdots } } } \cs_new:Npn\semantex_primitive_valuekey_clowerleftslot:nn#1#2 { \semantex_primitive_valuekey_clowerleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerleftslot } } } \cs_generate_variant:Nn \semantex_primitive_valuekey_lowerleftwithothersep:nn { nx } \cs_new:Npn\semantex_primitive_valuekey_lowerleftdotswithothersep:nn#1#2 { \semantex_primitive_valuekey_lowerleftwithothersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get:nn { #1 } { lowerleftdots } } } } \cs_new:Npn\semantex_primitive_valuekey_lowerleftslotwithothersep:nn#1#2 { \semantex_primitive_valuekey_lowerleftwithothersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get:nn { #1 } { lowerleftslot } } } } \cs_new:Npn\semantex_primitive_valuekey_cupperleft:nn#1#2{ \tl_if_blank:nF{#2} { \semantex_data_bool_get:nnTF { #1 } { nextupperleftwithsep } { \semantex_data_tl_put_left:nnn { #1 } { upperleft } { \exp_not:n { #2 } , } } { \semantex_data_tl_put_left:nnn { #1 } { upperleft } { \exp_not:n { #2 } } } \semantex_data_bool_set_true:nn { #1 } { nextupperleftwithsep } \semantex_data_int_incr:nn { #1 } { numberofupperleftindices } } } \cs_new:Npn\semantex_primitive_valuekey_clowerleft:nn#1#2{ \tl_if_blank:nF{#2} { \semantex_data_bool_get:nnTF { #1 } { nextlowerleftwithsep } { \semantex_data_tl_put_left:nnn { #1 } { lowerleft } { \exp_not:n { #2 } , } } { \semantex_data_tl_put_left:nnn { #1 } { lowerleft } { \exp_not:n { #2 } } } \semantex_data_bool_set_true:nn { #1 } { nextlowerleftwithsep } \semantex_data_int_incr:nn { #1 } { numberoflowerleftindices } } } \cs_new:Npn\semantex_primitive_valuekey_ifnextupperleftwithsep:nn#1#2 { \tl_if_eq:nnTF { #2 } { false } { \semantex_data_bool_set_false:nn { #1 } { nextupperleftwithsep } } { \tl_if_eq:nnTF { #2 } { true } { \semantex_data_bool_set_true:nn { #1 } { nextupperleftwithsep } } { \semantex_error_output_format:nN { #1 } \l__semantex_primitive_valuekey_ifnextupperleftwithsep_temp \msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_primitive_valuekey_ifnextupperleftwithsep_temp } { ifnextupperleftwithsep } { #2 } } } } \cs_new:Npn\semantex_primitive_valuekey_ifnextlowerleftwithsep:nn#1#2 { \tl_if_eq:nnTF { #2 } { false } { \semantex_data_bool_set_false:nn { #1 } { nextlowerleftwithsep } } { \tl_if_eq:nnTF { #2 } { true } { \semantex_data_bool_set_true:nn { #1 } { nextlowerleftwithsep } } { semantex_error_output_format:nN { #1 } \l__semantex_primitive_valuekey_ifnextlowerleftwithsep_temp \msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_primitive_valuekey_ifnextlowerleftwithsep_temp } { ifnextlowerleftwithsep } { #2 } } } } \cs_new:Npn\semantex_primitive_valuekey_setupperleftsep:nn#1#2 { \semantex_data_tl_set:nnn { #1 } { upperleftsep } { \exp_not:n { #2 } } } \cs_new:Npn\semantex_primitive_valuekey_setlowerleftsep:nn#1#2 { \semantex_data_tl_set:nnn { #1 } { lowerleftsep } { \exp_not:n { #2 } } } % Contrary to what you might think, the following commands ARE % sometimes needed. \cs_new:Npn\semantex_primitive_valuekey_ifnextdwithsep:nn#1#2 % should be removed later { % Tells whether the d (degree) is empty or not \str_if_eq:nnTF { #2 } { true } { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_ifnextupperwithsep:nn { #1 } { #2 } } { \semantex_primitive_valuekey_ifnextlowerwithsep:nn { #1 } { #2 } } } { \str_if_eq:nnTF { #2 } { false } { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_ifnextupperwithsep:nn { #1 } { #2 } } { \semantex_primitive_valuekey_ifnextlowerwithsep:nn { #1 } { #2 } } } { \semantex_error_output_format:nN { #1 } \l__semantex_primitive_valuekey_ifnextdwithsep_temp \msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_primitive_valuekey_ifnextdwithsep_temp } { ifnextdwithsep } { #2 } } } } \cs_set_eq:NN\semantex_primitive_valuekey_ifnextdegwithsep:nn\semantex_primitive_valuekey_ifnextdwithsep \cs_set_eq:NN\semantex_primitive_valuekey_ifnextdegreewithsep:nn\semantex_primitive_valuekey_ifnextdwithsep \cs_new:Npn\semantex_primitive_valuekey_ifnextiwithsep:nn#1#2 { % Tells whether the i (index) is empty or not \str_if_eq:nnTF { #2 } { true } { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_ifnextlowerwithsep:nn { #1 } { #2 } } { \semantex_primitive_valuekey_ifnextupperwithsep:nn { #1 } { #2 } } } { \str_if_eq:nnTF { #2 } { false } { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_ifnextlowerwithsep:nn { #1 } { #2 } } { \semantex_primitive_valuekey_ifnextupperwithsep:nn { #1 } { #2 } } } { \semantex_error_output_format:nN { #1 } \l__semantex_primitive_valuekey_ifnextiwithsep_temp \msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_primitive_valuekey_ifnextiwithsep_temp } { ifnextiwithsep } { #2 } } } } \cs_set_eq:NN\semantex_primitive_valuekey_ifnextindexwithsep:nn\semantex_primitive_valuekey_ifnextiwithsep:nn \cs_new:Npn\semantex_primitive_valuekey_d:nn#1#2 { % adds to the d-index (upper by default) \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_upper:nn { #1 } { #2 } } { \semantex_primitive_valuekey_lower:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_deg:nn\semantex_primitive_valuekey_d:nn \cs_set_eq:NN\semantex_primitive_valuekey_degree:nn\semantex_primitive_valuekey_d:nn \cs_new:Npn\semantex_primitive_valuekey_sd:nn#1#2 { % adds to the d-index (upper by default) \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_supper:nn { #1 } { #2 } } { \semantex_primitive_valuekey_slower:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_sdeg:nn\semantex_primitive_valuekey_sd:nn \cs_set_eq:NN\semantex_primitive_valuekey_sdegree:nn\semantex_primitive_valuekey_sd:nn \cs_new:Npn\semantex_primitive_valuekey_cd:nn#1#2{ %IM Maybe remove this. % adds to the d-index (upper by default) \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_cupper:nn { #1 } { #2 } } { \semantex_primitive_valuekey_clower:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_sdeg:nn\semantex_primitive_valuekey_cd:nn \cs_set_eq:NN\semantex_primitive_valuekey_sdegree:nn\semantex_primitive_valuekey_cd:nn \cs_new:Npn\semantex_primitive_valuekey_i:nn#1#2{ % adds to the i-index (lower by default) \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_lower:nn { #1 } { #2 } } { \semantex_primitive_valuekey_upper:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_index:nn\semantex_primitive_valuekey_i:nn \cs_new:Npn\semantex_primitive_valuekey_si:nn#1#2{ % adds to the i-index (lower by default) \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_slower:nn { #1 } { #2 } } { \semantex_primitive_valuekey_supper:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_sindex:nn\semantex_primitive_valuekey_si:nn \cs_new:Npn\semantex_primitive_valuekey_ci:nn#1#2{ % adds to the i-index (lower by default) \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_clower:nn { #1 } { #2 } } { \semantex_primitive_valuekey_cupper:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_cindex:nn\semantex_primitive_valuekey_ci:nn \cs_new:Npn\semantex_primitive_valuekey_dwithothersep:nn#1#2 { % adds to the d-index (upper by default) \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_upperwithothersep:nn { #1 } { #2 } } { \semantex_primitive_valuekey_lowerwithothersep:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_degwithothersep:nn\semantex_primitive_valuekey_dwithothersep:nn \cs_set_eq:NN\semantex_primitive_valuekey_degreewithothersep:nn\semantex_primitive_valuekey_dwithothersep:nn \cs_new:Npn\semantex_primitive_valuekey_iwithothersep:nn#1#2{ % adds to the i-index (lower by default) \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_lowerwithothersep:nn { #1 } { #2 } } { \semantex_primitive_valuekey_upperwithothersep:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_indexwithothersep:nn\semantex_primitive_valuekey_iwithothersep:nn \cs_new:Npn\semantex_primitive_valuekey_setdsep:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_setuppersep:nn { #1 } { #2 } } { \semantex_primitive_valuekey_setlowersep:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_setdegsep:nn\semantex_primitive_valuekey_setdsep:nn \cs_set_eq:NN\semantex_primitive_valuekey_setdegreesep:nn\semantex_primitive_valuekey_setdsep:nn \cs_new:Npn\semantex_primitive_valuekey_setisep:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_setlowersep:nn { #1 } { #2 } } { \semantex_primitive_valuekey_setuppersep:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_setindexsep:nn\semantex_primitive_valuekey_setisep:nn \cs_new:Npn\semantex_primitive_valuekey_pred:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_preupper:nn { #1 } { #2 } } { \semantex_primitive_valuekey_prelower:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_predeg:nn\semantex_primitive_valuekey_pred:nn \cs_set_eq:NN\semantex_primitive_valuekey_predegree:nn\semantex_primitive_valuekey_pred:nn \cs_new:Npn\semantex_primitive_valuekey_postd:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_postupper:nn { #1 } { #2 } } { \semantex_primitive_valuekey_postlower:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_postdeg:nn\semantex_primitive_valuekey_postd:nn \cs_set_eq:NN\semantex_primitive_valuekey_postdegree:nn\semantex_primitive_valuekey_postd:nn \cs_set:Npn\semantex_primitive_valuekey_cleard:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_clearupper:nn { #1 } { #2 } } { \semantex_primitive_valuekey_clearlower:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_cleardeg:nn\semantex_primitive_valuekey_cleard:nn \cs_set_eq:NN\semantex_primitive_valuekey_cleardegree:nn\semantex_primitive_valuekey_cleard:nn \cs_set:Npn\semantex_primitive_valuekey_clearpred:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_clearpreupper:nn { #1 } { #2 } } { \semantex_primitive_valuekey_clearprelower:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_clearpredeg:nn\semantex_primitive_valuekey_clearpred:nn \cs_set_eq:NN\semantex_primitive_valuekey_clearpredegree:nn\semantex_primitive_valuekey_clearpred:nn \cs_set:Npn\semantex_primitive_valuekey_clearpostd:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_clearpostupper:nn { #1 } { #2 } } { \semantex_primitive_valuekey_clearpostlower:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_clearpostdeg:nn\semantex_primitive_valuekey_clearpostd:nn \cs_set_eq:NN\semantex_primitive_valuekey_clearpostdegree:nn\semantex_primitive_valuekey_clearpostd:nn \cs_new:Npn\semantex_primitive_valuekey_prei:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_prelower:nn { #1 } { #2 } } { \semantex_primitive_valuekey_preupper:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_preindex:nn\semantex_primitive_valuekey_prei:nn \cs_new:Npn\semantex_primitive_valuekey_posti:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_postlower:nn { #1 } { #2 } } { \semantex_primitive_valuekey_postupper:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_postindex:nn\semantex_primitive_valuekey_posti:nn \cs_set:Npn\semantex_primitive_valuekey_cleari:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_clearlower:nn { #1 } { #2 } } { \semantex_primitive_valuekey_clearupper:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_clearindex:nn\semantex_primitive_valuekey_cleari:nn \cs_set:Npn\semantex_primitive_valuekey_clearprei:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_clearprelower:nn { #1 } { #2 } } { \semantex_primitive_valuekey_clearpreupper:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_clearpreindex:nn\semantex_primitive_valuekey_clearprei:nn \cs_set:Npn\semantex_primitive_valuekey_clearposti:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_clearpostlower:nn { #1 } { #2 } } { \semantex_primitive_valuekey_clearpostupper:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_clearpostindex:nn\semantex_primitive_valuekey_clearposti:nn \cs_new:Npn\semantex_primitive_valuekey_setddots:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_data_tl_set:nnn { #1 } { upperdots } { \exp_not:n s{ #2 } } } { \semantex_data_tl_set:nnn { #1 } { lowerdots } { \exp_not:n { #2 } } } } \cs_set_eq:NN\semantex_primitive_valuekey_setdegdots:nn\semantex_primitive_valuekey_setddots:nn \cs_set_eq:NN\semantex_primitive_valuekey_setdegreedots:nn\semantex_primitive_valuekey_setddots:nn \cs_new:Npn\semantex_primitive_valuekey_ddots:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_upperdots:nn { #1 } { #2 } } { \semantex_primitive_valuekey_lowerdots:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_degdots:nn\semantex_primitive_valuekey_ddots:nn \cs_set_eq:NN\semantex_primitive_valuekey_degreedots:nn\semantex_primitive_valuekey_ddots:nn \cs_new:Npn\semantex_primitive_valuekey_setdslot:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_setupperslot:nn { #1 } { #2 } } { \semantex_primitive_valuekey_setlowerslot:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_setdegslot:nn\semantex_primitive_valuekey_setdslot:nn \cs_set_eq:NN\semantex_primitive_valuekey_setdegreeslot:nn\semantex_primitive_valuekey_setdslot:nn \cs_new:Npn\semantex_primitive_valuekey_dslot:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_upperslot:nn { #1 } { #2 } } { \semantex_primitive_valuekey_lowerslot:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_degslot:nn\semantex_primitive_valuekey_dslot:nn \cs_set_eq:NN\semantex_primitive_valuekey_degreeslot:nn\semantex_primitive_valuekey_dslot:nn \cs_new:Npn\semantex_primitive_valuekey_sddots:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_supperdots:nn { #1 } { #2 } } { \semantex_primitive_valuekey_slowerdots:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_sdegdots:nn\semantex_primitive_valuekey_sddots:nn \cs_set_eq:NN\semantex_primitive_valuekey_sdegreedots:nn\semantex_primitive_valuekey_sddots:nn \cs_new:Npn\semantex_primitive_valuekey_sdslot:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_supperslot:nn { #1 } { #2 } } { \semantex_primitive_valuekey_slowerslot:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_sdegslot:nn\semantex_primitive_valuekey_sdslot:nn \cs_set_eq:NN\semantex_primitive_valuekey_sdegreeslot:nn\semantex_primitive_valuekey_sdslot:nn \cs_new:Npn\semantex_primitive_valuekey_cddots:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_cupperdots:nn { #1 } { #2 } } { \semantex_primitive_valuekey_clowerdots:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_cdegdots:nn\semantex_primitive_valuekey_cddots:nn \cs_set_eq:NN\semantex_primitive_valuekey_cdegreedots:nn\semantex_primitive_valuekey_cddots:nn \cs_new:Npn\semantex_primitive_valuekey_cdslot:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_cupperslot:nn { #1 } { #2 } } { \semantex_primitive_valuekey_clowerslot:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_cdegslot:nn\semantex_primitive_valuekey_cdslot:nn \cs_set_eq:NN\semantex_primitive_valuekey_cdegreeslot:nn\semantex_primitive_valuekey_cdslot:nn \cs_new:Npn\semantex_primitive_valuekey_ddotswithothersep:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_upperdotswithothersep:nn { #1 } { #2 } } { \semantex_primitive_valuekey_lowerdotswithothersep:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_degdotswithothersep:nn\semantex_primitive_valuekey_ddotswithothersep:nn \cs_set_eq:NN\semantex_primitive_valuekey_degreedotswithothersep:nn\semantex_primitive_valuekey_ddotswithothersep:nn \cs_new:Npn\semantex_primitive_valuekey_dslotwithothersep:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_upperslotwithothersep:nn { #1 } { #2 } } { \semantex_primitive_valuekey_lowerslotwithothersep:nn { #1 } { #2 } } } %---------------------------------------------------------- \cs_new:Npn\semantex_primitive_valuekey_setidots:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_data_tl_set:nnn { #1 } { lowerdots } { \exp_not:n { #2 } } } { \semantex_data_tl_set:nnn { #1 } { upperdots } { \exp_not:n { #2 } } } } \cs_set_eq:NN\semantex_primitive_valuekey_setindexdots:nn\semantex_primitive_valuekey_setidots:nn \cs_set_eq:NN\semantex_primitive_valuekey_setdegreedots:nn\semantex_primitive_valuekey_setidots:nn \cs_new:Npn\semantex_primitive_valuekey_idots:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_lowerdots:nn { #1 } { #2 } } { \semantex_primitive_valuekey_upperdots:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_indexdots:nn\semantex_primitive_valuekey_idots:nn \cs_set_eq:NN\semantex_primitive_valuekey_degreedots:nn\semantex_primitive_valuekey_idots:nn \cs_new:Npn\semantex_primitive_valuekey_setislot:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_setlowerslot:nn { #1 } { #2 } } { \semantex_primitive_valuekey_setupperslot:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_setindexslot:nn\semantex_primitive_valuekey_setislot:nn \cs_set_eq:NN\semantex_primitive_valuekey_setdegreeslot:nn\semantex_primitive_valuekey_setislot:nn \cs_new:Npn\semantex_primitive_valuekey_islot:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_lowerslot:nn { #1 } { #2 } } { \semantex_primitive_valuekey_upperslot:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_indexslot:nn\semantex_primitive_valuekey_islot:nn \cs_set_eq:NN\semantex_primitive_valuekey_degreeslot:nn\semantex_primitive_valuekey_islot:nn \cs_new:Npn\semantex_primitive_valuekey_sidots:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_slowerdots:nn { #1 } { #2 } } { \semantex_primitive_valuekey_supperdots:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_sindexdots:nn\semantex_primitive_valuekey_sidots:nn \cs_set_eq:NN\semantex_primitive_valuekey_sdegreedots:nn\semantex_primitive_valuekey_sidots:nn \cs_new:Npn\semantex_primitive_valuekey_sislot:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_slowerslot:nn { #1 } { #2 } } { \semantex_primitive_valuekey_supperslot:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_sindexslot:nn\semantex_primitive_valuekey_sislot:nn \cs_set_eq:NN\semantex_primitive_valuekey_sdegreeslot:nn\semantex_primitive_valuekey_sislot:nn \cs_new:Npn\semantex_primitive_valuekey_cidots:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_clowerdots:nn { #1 } { #2 } } { \semantex_primitive_valuekey_cupperdots:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_cindexdots:nn\semantex_primitive_valuekey_cidots:nn \cs_set_eq:NN\semantex_primitive_valuekey_cdegreedots:nn\semantex_primitive_valuekey_cidots:nn \cs_new:Npn\semantex_primitive_valuekey_cislot:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_clowerslot:nn { #1 } { #2 } } { \semantex_primitive_valuekey_cupperslot:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_cindexslot:nn\semantex_primitive_valuekey_cislot:nn \cs_set_eq:NN\semantex_primitive_valuekey_cdegreeslot:nn\semantex_primitive_valuekey_cislot:nn \cs_new:Npn\semantex_primitive_valuekey_idotswithothersep:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_lowerdotswithothersep:nn { #1 } { #2 } } { \semantex_primitive_valuekey_upperdotswithothersep:nn { #1 } { #2 } } } \cs_set_eq:NN\semantex_primitive_valuekey_indexdotswithothersep:nn\semantex_primitive_valuekey_idotswithothersep:nn \cs_set_eq:NN\semantex_primitive_valuekey_degreedotswithothersep:nn\semantex_primitive_valuekey_idotswithothersep:nn \cs_new:Npn\semantex_primitive_valuekey_islotwithothersep:nn#1#2 { \semantex_data_bool_get:nnTF { #1 } { uppergrading } { \semantex_primitive_valuekey_lowerslotwithothersep:nn { #1 } { #2 } } { \semantex_primitive_valuekey_upperslotwithothersep:nn { #1 } { #2 } } } %---------------------------------------------------------- \cs_set_eq:NN\semantex_primitive_valuekey_degslotwithothersep:nn\semantex_primitive_valuekey_dslotwithothersep:nn \cs_set_eq:NN\semantex_primitive_valuekey_degreeslotwithothersep:nn\semantex_primitive_valuekey_dslotwithothersep:nn \cs_new:Npn\semantex_primitive_valuekey_par:nn#1#2{ % Turns parentheses on, and sets their size \semantex_data_tl_set:nnn { #1 } { parsize }{ \exp_not:n { #2 } } \semantex_primitive_valuekey_ifpar:nn { #1 } { true } } \cs_new:Npn\semantex_primitive_valuekey_parsize:nn#1#2{ % Sets the size of the parentheses \semantex_data_tl_set:nnn { #1 } { parsize }{ \exp_not:n { #2 } } } \cs_new:Npn\semantex_primitive_valuekey_leftpar:nn#1#2{ \semantex_data_tl_set:nnn { #1 } { leftpar }{ \exp_not:n { #2 } } } \cs_new:Npn\semantex_primitive_valuekey_rightpar:nn#1#2{ \semantex_data_tl_set:nnn { #1 } { rightpar }{ \exp_not:n { #2 } } } \cs_new:Npn\semantex_primitive_valuekey_ifpar:nn#1#2{ %IMPLEMENT THIS % tells whether to use the output class or not \semantex_data_bool_provide:nn { #1 } { par } \str_if_eq:nnTF { #2 } { true } { \semantex_data_bool_set_true:nn { #1 } { par } \semantex_data_bool_set_false:nn { #1 } { flexpar } } { \str_if_eq:nnTF { #2 } { never } { \semantex_data_bool_set_false:nn { #1 } { par } \semantex_data_bool_set_false:nn { #1 } { flexpar } } { \str_if_eq:nnTF { #2 } { false } { \semantex_data_bool_set_false:nn { #1 } { par } \semantex_data_bool_set_true:nn { #1 } { flexpar } } { \semantex_error_output_format:nN { #1 } \l__semantex_primitive_valuekey_ifpar_temp \msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_primitive_valuekey_ifpar_temp } { ifpar } { #2 } } } } } \cs_new:Npn\semantex_primitive_valuekey_spar:nn#1#2 { % Abbreviation for "symbol parentheses" % Adds parentheses around the current symbol \semantex_primitive_valuekey_return:nn { #1 }{} \semantex_data_tl_inherit:nn { #1 } { symbol } % Check if really necessary \tl_if_blank:nTF { #2 } { \semantex_data_tl_get_store:nnN { #1 } { sparsize } \l__semantex_primitive_valuekey_spar_sparsize_temp \__semantex_symbol_parentheses_store:nnnnN { \l__semantex_primitive_valuekey_spar_sparsize_temp } { \semantex_data_tl_get:nn { #1 } { leftspar } } { \semantex_data_tl_get:nn { #1 } { rightspar } } { \semantex_data_tl_get_exp_not:nn { #1 } { symbol } } \l__semantex_primitive_valuekey_spar_temp \semantex_data_tl_set:nnx { #1 } { symbol } { \exp_not:V\l__semantex_primitive_valuekey_spar_temp } } { \tl_set:Nn \l__semantex_primitive_valuekey_spar_sparsize_temp { \exp_not:n { #2 } } \__semantex_symbol_parentheses_store:nnnnN { \l__semantex_primitive_valuekey_spar_sparsize_temp } { \semantex_data_tl_get:nn { #1 } { leftspar } } { \semantex_data_tl_get:nn { #1 } { rightspar } } { \semantex_data_tl_get_exp_not:nn { #1 } { symbol } } \l__semantex_primitive_valuekey_spar_temp \semantex_data_tl_set:nnx { #1 } { symbol } { \exp_not:V\l__semantex_primitive_valuekey_spar_temp } } } \cs_new:Npn\semantex_primitive_valuekey_ifnextargwithsep:nn#1#2 { % Tells whether it is the first argument or not \tl_if_eq:nnTF { #2 } { true } { \semantex_data_bool_set_true:nn { #1 } { nextargwithsep } } { \tl_if_eq:nnTF { #2 } { false } { \semantex_data_bool_set_false:nn { #1 } { nextargwithsep } } { \semantex_error_output_format:nN { #1 } \l__semantex_primitive_valuekey_ifnextargwithsep_temp \msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_primitive_valuekey_ifnextargwithsep_temp } { ifnextargwithsep } { #2 } } } } \cs_new:Npn\semantex_primitive_valuekey_otherspar:nn#1#2 { % Uses the syntax otherspar={leftpar}{rightpar} % Adds a new spar, but with these as parentheses \__semantex_primitive_valuekey_otherspar_auxiliary:nnn { #1 } #2 } \cs_new:Npn\__semantex_primitive_valuekey_otherspar_auxiliary:nnn#1#2#3 { \semantex_data_tl_inherit:nn { #1 } { sparsize } % This is necessary for unknown reasons -- otherwise, it will crash when inheriting sparsize \semantex_data_tl_inherit:nn { #1 } { symbol } \semantex_primitive_valuekey_return:nn { #1 }{} \semantex_data_tl_get_store:nnN { #1 } { sparsize } \l__semantex_primitive_valuekey_otherspar_sparsize_temp \__semantex_symbol_parentheses_store:nnnnN { \l__semantex_primitive_valuekey_otherspar_sparsize_temp } { \exp_not:n { \exp_not:n { #2 } } } { \exp_not:n { \exp_not:n { #3 } } } { \semantex_data_tl_get_exp_not:nn { #1 } { symbol } } \l__semantex_primitive_valuekey_otherspar_temp \semantex_data_tl_set:nnx { #1 } { symbol } { \exp_not:V\l__semantex_primitive_valuekey_otherspar_temp } } \cs_new:Npn\semantex_primitive_valuekey_Otherspar:nn#1#2 { % Uses the syntax otherspar={leftpar}{rightpar}{size} % Adds a new spar, but with these as parentheses and size \__semantex_primitive_valuekey_Otherspar_auxiliary:nnnn { #1 } #2 } \cs_new:Npn\__semantex_primitive_valuekey_Otherspar_auxiliary:nnnn#1#2#3#4 { \tl_set:Nn\l__semantex_primitive_valuekey_Otherspar_sparsize_temp { \exp_not:n { #4 } } \__semantex_symbol_parentheses_store:nnnnN { \l__semantex_primitive_valuekey_Otherspar_sparsize_temp } { \exp_not:n { \exp_not:n { #2 } } } { \exp_not:n { \exp_not:n { #3 } } } { \semantex_data_tl_get_exp_not:nn { #1 } { symbol } } \l__semantex_primitive_valuekey_Otherspar_temp \semantex_data_tl_set:nnx { #1 } { symbol } { \exp_not:V\l__semantex_primitive_valuekey_Otherspar_temp } } \cs_new:Npn\semantex_primitive_valuekey_sparsize:nn#1#2{ % sets the size of the parentheses \semantex_data_tl_set:nnn { #1 } { sparsize }{ \exp_not:n { #2 } } } \cs_new:Npn\semantex_primitive_valuekey_leftspar:nn#1#2{ \semantex_data_tl_set:nnn { #1 } { leftspar }{ \exp_not:n { \exp_not:n { #2 } } } %IM Two \exp_not necessary for unknown reasons %IM Doing the same at leftpar yields an error. } \cs_new:Npn\semantex_primitive_valuekey_rightspar:nn#1#2{ \semantex_data_tl_set:nnn { #1 } { rightspar }{ \exp_not:n { \exp_not:n { #2 } } } %IM Two \exp_not necessary for unknown reasons %IM Doing the same at leftpar yields an error. } \cs_generate_variant:Nn \semantex_keys_set:nn { nx, no, nV } % Only the first one is currently being used \cs_new:Npn \semantex_valuekey:nnn#1#2#3{ % Takes care of valuekeys, keys taking a value % For the sake of implementation, the arguments % come in a strange order % #1 = value of key % #2 = name of the key % #3 = object \tl_set:Nn\l__semantex_key_value_temp{\exp_not:n{#1}} %IM think about using extra {...} to avoid interference with keyval str \semantex_valuekey_get:nnNTF { #3 } { #2 } \l__semantex_custom_valuekey_temp { \semantex_keys_set:nx { #3 } { \l__semantex_custom_valuekey_temp } } { \cs_if_exist:cTF { semantex_primitive_valuekey_#2:nn } { \use:c { semantex_primitive_valuekey_#2:nn }{ #3 }{ #1 } } { \semantex_error_output_format:nN { #3 } \__semantex_valuekey_unknown_key_temp \msg_error:nnxn { semantex } { valuekey_not_found } { \__semantex_valuekey_unknown_key_temp } { #2 } } } } \cs_new:Npn \semantex_singlekey:nn#1#2 { % #1 = name of the key % #2 = object % Takes care of single keys, keys without a value \semantex_singlekey_get:nnNTF { #2 } { #1 } \l__semantex_custom_singlekey_temp { \semantex_keys_set:nx { #2 } { \l__semantex_custom_singlekey_temp } } { \semantex_keys_set:nn { #2 } { default = { #1 } } } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % COMMANDS CONTROLLING THE ARGUMENT KEYVAL INTERFACE % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \cs_new:Npn \semantex_primitive_arg_valuekey_othersep:nn#1#2 { % Uses syntax sep={separator}{argument}; adds an argument % with the specified separator \semantex_data_bool_get:nnTF { #1 } { nextargwithsep } { \semantex_data_tl_put_right:nnn { #1 } { arg } { \exp_not:n { \semantex_grab_first_argument_of_two:nn #2 \semantex_grab_second_argument_of_two:nn #2 } } } { \semantex_data_tl_put_right:nnn { #1 } { arg } { \exp_not:n { \semantex_grab_second_argument_of_two:nn #2 } } %IM These do not use :x, unlike the ones below } \semantex_data_int_incr:nn { #1 } { numberofarguments } \semantex_data_bool_set_true:nn { #1 } { nextargwithsep } } \cs_new:Npn \semantex_primitive_arg_valuekey_s:nn#1#2 { % Adds to the argument, with the standard separator \semantex_data_bool_get:nnTF { #1 } { nextargwithsep } { \semantex_data_tl_put_right:nnx { #1 } { arg } { \exp_not:n { \semantex_data_tl_get:nn { #1 } { argsep } } } \semantex_data_tl_put_right:nnn { #1 } { arg } {\exp_not:n { #2 } } % As an experiment, I tried changing cx to cn, and it failed % when changing the separator on the fly. } { \semantex_data_tl_put_right:nnn { #1 } { arg } { \exp_not:n { #2 } } %IM Recently corrected % Previously, this was cx, but I didn’t see any point of this; % this was mostly to create symmetry with the below case where % cx is strictly necessary. } % \semantex_primitive_valuekey_ifoutput:nn { #1 } { true } \semantex_data_int_incr:nn { #1 } { numberofarguments } \semantex_data_bool_set_true:nn { #1 } { nextargwithsep } } \cs_generate_variant:Nn \semantex_primitive_arg_valuekey_s:nn { nx } \cs_new:Npn \semantex_primitive_arg_valuekey_dots:nn#1#2 { % Writes dots in the argument \semantex_primitive_arg_valuekey_s:nx { #1 } { \semantex_data_tl_get_exp_not:nn { #1 } { argdots } } } \cs_new:Npn \semantex_primitive_arg_valuekey_slot:nn#1#2 { % Writes the slot in teh argument \semantex_primitive_arg_valuekey_s:nx { #1 } { \semantex_data_tl_get_exp_not:nn { #1 } { argslot } } } \cs_generate_variant:Nn \semantex_arg_keys_set:nn { nx } \cs_new:Npn \semantex_arg_valuekey:nnn#1#2#3 { % Takes care of valuekeys, keys with a value % For the sake of implementation, the arguments % come in a strange order % #1 = value of key % #2 = name of the key % #3 = object \tl_set:Nn\l__semantex_arg_key_value_temp{\exp_not:n{#1}} % stores the content of the key in the temporary command \l__semantex_key_value_temp \semantex_arg_valuekey_get:nnNTF { #3 } { #2 } \l__semantex_custom_arg_valuekey_temp { \semantex_arg_keys_set:nx { #3 } { \l__semantex_custom_arg_valuekey_temp } } { \cs_if_exist:cTF { semantex_primitive_arg_valuekey_#2:nn } { \use:c { semantex_primitive_arg_valuekey_#2:nn }{ #3 }{ #1 } } { % \msg_error:nnnn { semantex } { arg_valuekey_not_found } { #2 } { #3 } \semantex_error_output_format:nN { #3 } \__semantex_arg_valuekey_unknown_key_temp \msg_error:nnxn { semantex } { arg_valuekey_not_found } { \__semantex_arg_valuekey_unknown_key_temp } { #2 } } } } \cs_new:Npn \semantex_arg_singlekey:nn#1#2 { % #1 = name of the key % #2 = object % % takes care of single keys, keys without a value % the class key is not actually necessary \semantex_arg_singlekey_get:nnNTF { #2 } { #1 } \l__semantex_custom_arg_singlekey_temp { %\exp_args:NNno %\exp_args:Nno \semantex_arg_keys_set:nx { #2 } { \l__semantex_custom_arg_singlekey_temp } } { \semantex_data_tl_inherit_x:nn { #2 } { arg } \semantex_arg_keys_set:nn { #2 } { default={\exp_not:n { #1 } }} %IM THis \exp_not:n was added late, might be needed elsewhere, too. } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % SETTING UP THE BASE CLASS SemantexVariable % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \semantex_data_tl_provide:nn { class_SemantexVariable } { output } \semantex_data_tl_set:nnn { class_SemantexVariable } { output } { class_SemantexVariable } \semantex_data_tl_provide:nn { class_SemantexVariable } { upper } \semantex_data_tl_provide:nn { class_SemantexVariable } { uppersep } \semantex_data_tl_set:nnn { class_SemantexVariable } { uppersep } { , } %IM Also, need commands like forgetupperindex, reverting to the class standard \semantex_data_tl_provide:nn { class_SemantexVariable } { lower } \semantex_data_tl_provide:nn { class_SemantexVariable } { lowersep } \semantex_data_tl_set:nnn { class_SemantexVariable } { lowersep } { , } \semantex_data_tl_provide:nn { class_SemantexVariable } { preupper } \semantex_data_tl_provide:nn { class_SemantexVariable } { postupper } \semantex_data_tl_provide:nn { class_SemantexVariable } { prelower } \semantex_data_tl_provide:nn { class_SemantexVariable } { postlower } \semantex_data_tl_provide:nn { class_SemantexVariable } { upperleft } \semantex_data_tl_provide:nn { class_SemantexVariable } { upperleftsep } \semantex_data_tl_set:nnn { class_SemantexVariable } { upperleftsep } { , } %IM do the same with all the others, INCLUDING if_uppergrading and symbol %IM Also, need commands like forgetupperindex, reverting to the class standard \semantex_data_tl_provide:nn { class_SemantexVariable } { lowerleft } \semantex_data_tl_provide:nn { class_SemantexVariable } { lowerleftsep } \semantex_data_tl_set:nnn { class_SemantexVariable } { lowerleftsep } { , } \semantex_data_tl_provide:nn { class_SemantexVariable } { preupperleft } \semantex_data_tl_provide:nn { class_SemantexVariable } { postupperleft } \semantex_data_tl_provide:nn { class_SemantexVariable } { prelowerleft } \semantex_data_tl_provide:nn { class_SemantexVariable } { postlowerleft } \semantex_data_int_provide:nn { class_SemantexVariable } { numberofarguments } \semantex_data_bool_provide:nn { class_SemantexVariable } { nextargwithsep } \semantex_data_bool_provide:nn { class_SemantexVariable } { nextupperleftwithsep } \semantex_data_bool_provide:nn { class_SemantexVariable } { nextlowerleftwithsep } \semantex_data_int_provide:nn { class_SemantexVariable } { numberofupperleftindices } \semantex_data_int_provide:nn { class_SemantexVariable } { numberoflowerleftindices } \semantex_data_tl_provide:nn { class_SemantexVariable } { prearg } \semantex_data_tl_provide:nn { class_SemantexVariable } { postarg } \semantex_data_tl_provide:nn { class_SemantexVariable } { arg } \semantex_data_tl_provide:nn { class_SemantexVariable } { argsep } \semantex_data_tl_set:nnn { class_SemantexVariable } { argsep } {,} \semantex_data_tl_provide:nn { class_SemantexVariable } { argslot } \semantex_data_tl_set:nnn { class_SemantexVariable } { argslot } { \SemantexSlot } \semantex_data_tl_provide:nn { class_SemantexVariable } { argdots } \semantex_data_tl_set:nnn { class_SemantexVariable } { argdots } {\dots} \semantex_data_tl_provide:nn { class_SemantexVariable } { symbol } \semantex_data_seq_provide:nn { class_SemantexVariable } { commands_sequence } \semantex_data_bool_provide:nn { class_SemantexVariable } { uppergrading } \semantex_data_bool_set_true:nn { class_SemantexVariable } { uppergrading } \semantex_data_bool_provide:nn { class_SemantexVariable } { output } \semantex_data_tl_provide:nn { class_SemantexVariable } { outputoptions } \semantex_data_bool_provide:nn { class_SemantexVariable } { nextupperwithsep } \semantex_data_bool_provide:nn { class_SemantexVariable } { nextlowerwithsep } \semantex_data_int_provide:nn { class_SemantexVariable } { numberofupperindices } \semantex_data_int_provide:nn { class_SemantexVariable } { numberoflowerindices } \semantex_data_bool_provide:nn { class_SemantexVariable } { par } \semantex_data_bool_set_true:nn { class_SemantexVariable } { par } \semantex_data_bool_provide:nn { class_SemantexVariable } { flexpar } \semantex_data_tl_provide:nn { class_SemantexVariable } { parseoptions } \semantex_data_tl_provide:nn { class_SemantexVariable } { texclass } \semantex_data_bool_provide:nn { class_SemantexVariable } { leftargument } \semantex_data_tl_provide:nn { class_SemantexVariable } { upperdots } \semantex_data_tl_provide:nn { class_SemantexVariable } { upperslot } \semantex_data_tl_provide:nn { class_SemantexVariable } { lowerdots } \semantex_data_tl_provide:nn { class_SemantexVariable } { lowerslot } \semantex_data_tl_provide:nn { class_SemantexVariable } { upperleftdots } \semantex_data_tl_provide:nn { class_SemantexVariable } { upperleftslot } \semantex_data_tl_provide:nn { class_SemantexVariable } { lowerleftdots } \semantex_data_tl_provide:nn { class_SemantexVariable } { lowerleftslot } %\tl_set:Nn\g_objectmath_SemantexVariable_upper { hej } %\tl_set:Nn \SemantexVariable_output { class_SemantexVariable } %\bool_new:N \SemantexVariable_output_if_provided %\bool_set_true:N \SemantexVariable_output_if_provided \semantex_new_variable_class:Nw \SemantexVariable [ %parent=SemantexVariable, output=\SemantexVariable, ifoutput=false, symbol=, gradingposition=upper, %upper=, %lower=, leftpar=(, rightpar=), par=normal, leftspar=(, rightspar=), sparsize=normal, %arg=, setupperdots=\dots, setlowerdots=\dots, setupperslot=\g_semantex_bullet, setlowerslot=\g_semantex_bullet, setupperleftdots=\dots, setlowerleftdots=\dots, setupperleftslot=\g_semantex_bullet, setlowerleftslot=\g_semantex_bullet, singlekeys={ {prime}{upper={\prime}}, {'}{prime}, {''}{prime,prime}, {'''}{prime,prime,prime}, {*}{sdegree=\g_semantex_bullet}, {**}{sdegree=\g_semantex_double_bullet}, {degree*}{degree=\g_semantex_bullet}, {degree**}{degree=\g_semantex_double_bullet}, {sdegree*}{sdegree=\g_semantex_bullet}, {sdegree**}{sdegree=\g_semantex_double_bullet}, {cdegree*}{cdegree=\g_semantex_bullet}, {cdegree**}{cdegree=\g_semantex_double_bullet}, {deg*}{deg=\g_semantex_bullet}, {deg**}{deg=\g_semantex_double_bullet}, {sdeg*}{sdeg=\g_semantex_bullet}, {sdeg**}{sdeg=\g_semantex_double_bullet}, {cdeg*}{cdeg=\g_semantex_bullet}, {cdeg**}{cdeg=\g_semantex_double_bullet}, {d*}{d=\g_semantex_bullet}, {d**}{d=\g_semantex_double_bullet}, {sd*}{sd=\g_semantex_bullet}, {sd**}{sd=\g_semantex_double_bullet}, {cd*}{cd=\g_semantex_bullet}, {cd**}{cd=\g_semantex_double_bullet}, {index*}{index=\g_semantex_bullet}, {index**}{index=\g_semantex_double_bullet}, {sindex*}{sindex=\g_semantex_bullet}, {sindex**}{sindex=\g_semantex_double_bullet}, {cindex*}{cindex=\g_semantex_bullet}, {cindex**}{cindex=\g_semantex_double_bullet}, {i*}{i=\g_semantex_bullet}, {i**}{i=\g_semantex_double_bullet}, {si*}{si=\g_semantex_bullet}, {si**}{si=\g_semantex_double_bullet}, {ci*}{ci=\g_semantex_bullet}, {ci**}{ci=\g_semantex_double_bullet}, {smash}{command=\noexpand\smash}, % (widebar}{command=\noexpand\widebar},%For unknown reasons, this only seems to work when run as a primitive {tilde}{command=\noexpand\tilde}, {widetilde}{command=\widetilde}, {overline}{command=\noexpand\overline}, {bar}{command=\noexpand\bar}, {bold}{command=\noexpand\mathbf}, {roman}{command=\noexpand\mathrm}, {mathord}{texclass=\mathord}, {mathbin}{texclass=\mathbin}, {mathop}{texclass=\mathop}, {mathrel}{texclass=\mathrel}, {leftreturn}{leftreturn=}, {innerreturn}{innerreturn=}, {rightreturn}{rightreturn=}, {return}{return=}, {spar}{spar=}, {parse}{parse=}, {par}{ifpar=true}, {neverpar}{ifpar=never}, {nopar}{ifpar=false}, {clearupper}{clearupper=}, {clearlower}{clearlower=}, {clearupperleft}{clearupperleft=}, {clearlowerleft}{clearlowerleft=}, {clearcommand}{clearcommand=}, {cleard}{cleard=}, {cleardeg}{cleardeg=}, {cleardegree}{cleardegree=}, {cleari}{cleari=}, {clearindex}{clearindex=}, {upperdots}{upperdots=}, {upper...}{upperdots=}, {upperslot}{upperslot=}, {upper-}{upperslot=}, {lowerdots}{lowerdots=}, {lower...}{lowerdots=}, {lowerslot}{lowerslot=}, {lower-}{lowerslot=}, {upperleftdots}{upperleftdots=}, {upperleft...}{upperleftdots=}, {upperleftslot}{upperleftslot=}, {upperleft-}{upperleftslot=}, {lowerleftdots}{lowerleftdots=}, {lowerleft...}{lowerleftdots=}, {lowerleftslot}{lowerleftslot=}, {lowerleft-}{lowerleftslot=}, {idots}{idots=}, {indexdots}{indexdots=}, {islot}{islot=}, {indexslot}{indexslot=}, {i...}{idots=}, {index...}{indexdots=}, {i-}{islot=}, {index-}{indexslot=}, {ddots}{ddots=}, {degdots}{degdots=}, {degreedots}{degreedots=}, {dslot}{dslot=}, {degslot}{degslot=}, {degreeslot}{degreeslot=}, {d...}{ddots=}, {deg...}{degdots=}, {degree...}{degreedots=}, {d-}{dslot=}, {deg-}{degslot=}, {degree-}{degreeslot=}, {cupperdots}{cupperdots=}, {cupper...}{cupperdots=}, {cupperslot}{cupperslot=}, {cupper-}{cupperslot=}, {clowerdots}{clowerdots=}, {clower...}{clowerdots=}, {clowerslot}{clowerslot=}, {clower-}{clowerslot=}, {cupperleftdots}{cupperleftdots=}, {cupperleft...}{cupperleftdots=}, {cupperleftslot}{cupperleftslot=}, {cupperleft-}{cupperleftslot=}, {clowerleftdots}{clowerleftdots=}, {clowerleft...}{clowerleftdots=}, {clowerleftslot}{clowerleftslot=}, {clowerleft-}{clowerleftslot=}, {cidots}{cidots=}, {cindexdots}{cindexdots=}, {cislot}{cislot=}, {cindexslot}{cindexslot=}, {ci...}{cidots=}, {cindex...}{cindexdots=}, {ci-}{cislot=}, {cindex-}{cindexslot=}, {cddots}{cddots=}, {cdegdots}{cdegdots=}, {cdegreedots}{cdegreedots=}, {cdslot}{cdslot=}, {cdegslot}{cdegslot=}, {cdegreeslot}{cdegreeslot=}, {cd...}{cddots=}, {cdeg...}{cdegdots=}, {cdegree...}{cdegreedots=}, {cd-}{cdslot=}, {cdeg-}{cdegslot=}, {cdegree-}{cdegreeslot=}, {supperdots}{supperdots=}, {supper...}{supperdots=}, {supperslot}{supperslot=}, {supper-}{supperslot=}, {slowerdots}{slowerdots=}, {slower...}{slowerdots=}, {slowerslot}{slowerslot=}, {slower-}{slowerslot=}, {supperleftdots}{supperleftdots=}, {supperleft...}{supperleftdots=}, {supperleftslot}{supperleftslot=}, {supperleft-}{supperleftslot=}, {slowerleftdots}{slowerleftdots=}, {slowerleft...}{slowerleftdots=}, {slowerleftslot}{slowerleftslot=}, {slowerleft-}{slowerleftslot=}, {sidots}{sidots=}, {sindexdots}{sindexdots=}, {sislot}{sislot=}, {sindexslot}{sindexslot=}, {si...}{sidots=}, {sindex...}{sindexdots=}, {si-}{sislot=}, {sindex-}{sindexslot=}, {sddots}{sddots=}, {sdegdots}{sdegdots=}, {sdegreedots}{sdegreedots=}, {sdslot}{sdslot=}, {sdegslot}{sdegslot=}, {sdegreeslot}{sdegreeslot=}, {sd...}{sddots=}, {sdeg...}{sdegdots=}, {sdegree...}{sdegreedots=}, {sd-}{sdslot=}, {sdeg-}{sdegslot=}, {sdegree-}{sdegreeslot=}, {...}{sidots=}, {-}{sislot=}, % The following four commands do not work due to expansion issues: % {useargwithkeyval}{useargwithkeyval=}, % {argwithkeyval}{ % valuekeys={ % {arg}{argwithkeyval={\noexpand\l__semantex_key_value_temp}}, % }, % }, % {argwithsinglekeys}{ % valuekeys={ % {arg}{argwithsinglekeys={\noexpand\l__semantex_key_value_temp}}, % }, % }, % {argwithoutkeyval}{ % valuekeys={ % {arg}{argwithoutkeyval={\noexpand\l__semantex_key_value_temp}}, % }, % }, % {argwithonesinglekey}{ % valuekeys={ % {arg}{argwithonesinglekey={\noexpand\l__semantex_key_value_temp}}, % }, % }, }, valuekeys={ {default}{sindex={#1}}, % {arg}{argwithkeyval={#1}}, {arg}{argwithsinglekeys={#1}}, {degreedefault}{sdegree={#1}}, {*withothersep}{degreewithothersep={#1}{\g_semantex_bullet}}, {**withothersep}{degreewithothersep={#1}{\g_semantex_double_bullet}}, {degree*withothersep}{degreewithothersep={#1}{\g_semantex_bullet}}, {degree**withothersep}{degreewithothersep={#1}{\g_semantex_double_bullet}}, {deg*withothersep}{degwithothersep={#1}{\g_semantex_bullet}}, {deg**withothersep}{degwithothersep={#1}{\g_semantex_double_bullet}}, {d*withothersep}{dwithothersep={#1}{\g_semantex_bullet}}, {d**withothersep}{dwithothersep={#1}{\g_semantex_double_bullet}}, {index*withothersep}{indexwithothersep={#1}{\g_semantex_bullet}}, {index**withothersep}{indexwithothersep={#1}{\g_semantex_double_bullet}}, {i*withothersep}{iwithothersep={#1}{\g_semantex_bullet}}, {i**withothersep}{iwithothersep={#1}{\g_semantex_double_bullet}}, }, % argwithsinglekeys, argvaluekeys={ {default}{s={#1}}, }, argsinglekeys={ {slot}{slot=}, {-}{slot=}, % {*}{slot=}, % would be confusing since * does not correspond to slot in the indices {...}{dots=}, }, %command=, % useargwithkeyval, ] \cs_set_eq:NN\__semantex_old_version_of_semantex_new_object_of_class_SemantexVariable:Nw \__semantex_new_object_of_class_SemantexVariable:Nw \cs_set:Npn \__semantex_new_object_of_class_SemantexVariable:Nw#1 { \msg_error:nnn { semantex } { created_a_SemantexVariable } { #1 } \__semantex_old_version_of_semantex_new_object_of_class_SemantexVariable:Nw #1 }