% This is the YaX package. % Relevant information can be found in yax-doc.pdf % % Author: Paul Isambert. % E-mail: zappathustra AT free DOT fr % Comments and suggestions are welcome. % Date: January 2011. % \ifcsname yax@already_loaded\endcsname \expandafter\endinput \fi \input texapi % Everything I need. It figures: I wrote it for this. \ifdefined\texapiversion \ifdim\texapiversion pt<1.03pt \senderror{YaX}{You need texapi with version at least 1.03. I quit} \expandafter\expandafter\expandafter\endinput \fi \else % \texapiversion was introduced in v.1.02. \senderror{YaX}{You need texapi with version at least 1.03. I quit} \expandafter\endinput \fi \setcatcodes{@_=11} \def\yaxversion{1.03} \let\yax@already_loaded\relax \def\yax@error{\senderror{YaX}} % % Retrieval of parameter and attribute. % \def\yax@getparameter#1#2:{% \passtrim{#2}{#1}% } \def\yax@defparameter#1#2{% \def\yax@parameter{#2}#1 } % #1 and #2 are thing_to_do and parameter. \def\yax@getattribute#1#2#3 {% \ifemptystring{#3}{\yax@getattribute{#1}{#2}} {#1{#2}{#3}}% } % \yax@getall\foo % => \foo{}{} \def\yax@getall#1{% \yax@getparameter{\yax@getattribute{#1}}% } % \long\def\yax@get_topar#1#2\par{% #1{#2}% } % % % % %%%%%%%%%%%%%%% SETTING PARAMETERS %%%%%%%%%%%%%%% % % The crux of the biscuit. % % \setparameter : % = % = % ... % = % \par % % A generic loop for space-delimited lists. % The the texapi documentation for the information on the \newfor loop. % \newfornoempty\yax@space_loop{1}#2 {#1{#2}}% % \pdef\setparameter{% \yax@getparameter\yax@setparameter_getattributes } \long\def\yax@setparameter_getattributes#1#2\par{% \yax@setparameter_getpairs{}{#2 }% \expandafter\yax@space_loop\expandafter{\expandafter\yax@setparameter_assign\expandafter{\yax@setparameters_pairs}}{#1 }% \yax@space_loop\yax@setparameter_execute{#1 }% } \newfor\yax@setparameter_getpairs{1}#2={% \pausefor{\skipspace{\passtrim{#2}{\yax@setparameter_checkprefix{\yax@setparameter_howgiven{#1}}}}}% }[\def\yax@setparameters_pairs{#1}] \newstring{e:} \newstring{g:} \newstring{x:} \long\def\yax@setparameter_checkprefix#1#2{% \ifprefix{e:}{#2} {\removeprefixand{e:}{#2}\passtrim{#1\edefcs}} {\ifprefix{g:}{#2} {\removeprefixand{g:}{#2}\passtrim{#1\gdefcs}} {\ifprefix{x:}{#2} {\removeprefixand{x:}{#2}\passtrim{#1\xdefcs}} {#1\defcs{#2}}}}% } \long\def\yax@setparameter_howgiven#1#2#3{% \ifnextnospace" {\yax@setparameter_getquote{#1}{#2}{#3}} % No need for a new nospace: it has been removed {\ifcatnext\foo {\yax@setparameter_getcommand{#1}{#2}{#3}} {\yax@setparameter_getspace{#1}{#2}{#3}}}% } \long\def\yax@setparameter_getquote#1#2#3"#4"{% \skipspace{\resumefor\yax@setparameter_getpairs{#1{#2}{#3}{#4}}}% Better not to forget this! } \long\def\yax@setparameter_getcommand#1#2#3#4{% \skipspace{\resumefor\yax@setparameter_getpairs{#1{#2}{#3}{#4}}}% } \long\def\yax@setparameter_getspace#1#2#3#4 {% \skipspace{\resumefor\yax@setparameter_getpairs{#1{#2}{#3}{#4}}}% } \long\def\yax@setparameter_assign#1#2{% \yax@setparameter_assignloop{#2}{#1}% } \newfor\yax@setparameter_assignloop{1}#2#3#4{% \yax@space_loop{\yax@setparameter_do{#1}{#2}{#4}}{#3 }% } \newif\ifyax@makedef % #1 = parameter; #2 = \<|e|g|x>defcs; #3 = value; #4 = attribute \long\def\yax@setparameter_do#1#2#3#4{% \yax@makedeftrue \iffcs{yax@#1@restricted}% Parameter restricted. {\reverse\iffcs{yax@#1:#4@allowed}% Attribute not allowed. {\yax@makedeffalse \yax@error{Attribute `#4' is not allowed in parameter `#1'. Authorized attributes are `\unexpandedcs{yax@#1@restricted}'}}}% \ifcs{yax@#1:#4@restricted}% Attribute restricted in this parameter. {\reverse\iffcs{yax@#1:#4:\detokenize{#3}@allowed}% Value not allowed. {\yax@makedeffalse \yax@error{Value `\detokenize{#4}' is not allowed in attribute `#1:#4'. Authorized values are `\unexpandedcs{yax@#1:#4@restricted}'}}}% {\iffcs{yax@attribute@#4@restricted}% Attribute restricted in all parameters. {\reverse\iffcs{yax@attribute@#4:\detokenize{#3}@allowed}% Value not allowed. {\yax@makedeffalse \yax@error{Value `\detokenize{#3}' is not allowed in attribute `#4'. Authorized values are `\unexpandedcs{yax@attribute@#4@restricted}'}}}}% \ifyax@makedef \reverse\iffcs{yax@#1@attributelist}{\gdefcs{yax@#1@attributelist}{}}% \ifx#2\gdefcs \passexpandedcs{\yax@parameterlist_add\global{#1}{#4}}{yax@#1@attributelist}% \else\ifx#2\xdefcs \passexpandedcs{\yax@parameterlist_add\global{#1}{#4}}{yax@#1@attributelist}% \else \passexpandedcs{\yax@parameterlist_add{}{#1}{#4}}{yax@#1@attributelist}% \fi\fi #2{yax@#1:#4}{#3}% \fi } \newfor\yax@parameterlist_add{3}#4{% \iffstring{#3}{#4}{\breakfor{}}% }[#1\eaddrightcs{yax@#2@attributelist}{{#3}}] \def\yax@setparameter_execute#1{% \iffcs{yax@#1@active}{\usecs{yax@#1@def}}% } % % \setparameterlist [|*]=, ... % \def\setparameterlist#1{% \ifnextnospace[ {\yax@setparameterlist_getdefault{#1}} {\yax@setparameterlist_getdefault{#1}[]}% } \def\yax@setparameterlist_getdefault#1[#2]#3{% \yax@setparameterlist_loop{#1}{#2}{#3,}% \yax@space_loop\yax@setparameter_execute{#1 }% } \newstring{=} \newfornoempty\yax@setparameterlist_loop{2}#3,{% \ifcontains={#3} {\yax@setparameterlist_getargs{#1}#3\yax@endofentry} {\ifemptystring{#2} {\yax@setparameterlist_getargs{#1}#3=true\yax@endofentry} {\passtrim{#3}{#2}}}% } \long\def\yax@setparameterlist_getargs#1#2=#3\yax@endofentry{% \yax@setparameter_checkprefix{\passtrim{#3}{\yax@setparameterlist_assign{#1}}}{#2}% } \long\def\yax@setparameterlist_assign#1#2#3#4{% \yax@space_loop{\yax@setparameterlist_do{#3}{#2}{#4}}{#1 }% } \long\def\yax@setparameterlist_do#1#2#3#4{% \yax@space_loop{\yax@setparameter_do{#4}{#1}{#2}}{#3 }% } % % \setattribute : = % \def\yax@removesign#1#2#3#4={#1{#2}{#3}}% \pdef\setattribute{% \yax@getall{\yax@removesign{\yax@setattribute\defcs}}% } \pdef\esetattribute{% \yax@getall{\yax@removesign{\yax@setattribute\edefcs}}% } \pdef\gsetattribute{% \yax@getall{\yax@removesign{\yax@setattribute\gdefcs}}% } \pdef\xsetattribute{% \yax@getall{\yax@removesign{\yax@setattribute\xdefcs}}% } \def\yax@setattribute#1#2#3{% \skipspace{\yax@setattribute_getvalue{#1}{#2}{#3}}% } \long\def\yax@setattribute_getvalue#1#2#3#4 {% \yax@setparameter_do{#2}{#1}{#4}{#3}% } % % \copyparameter : % \pdef\copyparameter{% \yax@getall{\yax@copyparameter{}}% } \pdef\gcopyparameter{% \yax@getall{\yax@copyparameter\global}% } \def\yax@copyparameter#1#2#3{% \reverse\iffcs{yax@#3@attributelist}{#1\letcs{yax@#3@attributelist}\emptycs}% \yax@space_loop{\yax@copyparameter_do{#1}{#3}}{#2 }% } \def\yax@copyparameter_do#1#2#3{% \iffcs{yax@#3@attributelist}{% \passexpandedcs{\yax@parameterlist_copy{#1}{#3}{#2}}{yax@#3@attributelist}}% } \newfor\yax@parameterlist_copy{3}#4{% #1\letcstocs{yax@#3:#4}{yax@#2:#4}% \passexpandedcs{\yax@parameterlist_add{#1}{#3}{#4}}{yax@#3@attributelist}% } % % % % \deleteparameter : % \pdef\deleteparameter{% \yax@getparameter{\yax@deleteparameter{}}% } \pdef\gdeleteparameter{% \yax@getparameter{\yax@deleteparameter\global}% } \def\yax@deleteparameter#1#2{% \yax@space_loop{\yax@deleteparameter_do{#1}}{#2 }% } \def\yax@deleteparameter_do#1#2{% \iffcs{yax@#2@attributelist}{\passexpandedcs{\yax@parameterlist_delete{#1}{#2}}{yax@#2@attributelist}}% } \newfor\yax@parameterlist_delete{2}#3{% #1\letcs{yax@#2:#3}\yax@somethinghopefullyundefined }[#1\letcs{yax@#2@attributelist}\yax@somethinghopefullyundefined] % % % \deleteattribute : % \def\deleteattribute{% \yax@getall{\yax@deleteattribute{}}% } \def\gdeleteattribute{% \yax@getall{\yax@deleteattribute\global}% } \def\yax@deleteattribute#1#2#3{% \iffcs{yax@#2@attributelist}{% #1\letcs{yax@#2:#3}\yax@undefined \passexpandedcs{\yax@parameterlist_remove{#1\edefcs}{#2}{#3}{}}{yax@#2@attributelist}}% } \newfor\yax@parameterlist_remove{4}#5{% \reverse\iffstring{#3}{#5}{\passarguments{#1}{#2}{#3}{#4{#5}}}% }[#1{yax@#2@attributelist}{#4}] % % % % % \restrictparameter : % % % ... % % \par % \pdef\restrictparameter{% \yax@getparameter\yax@restrictparameter_getrestrictions }% \long\def\yax@restrictparameter_getrestrictions#1#2\par{% \yax@space_loop{\yax@restrictparameter{#2 meta }}{#1 }% Meta is always allowed. } \long\def\yax@restrictparameter#1#2{% \def\yax@parameter{#2}% \yax@space_loop\yax@restrictparameter_readrestrictions{#1}% } \long\def\yax@restrictparameter_readrestrictions#1{% \letcs{yax@\yax@parameter :#1@allowed}\relax \ifcs{yax@\yax@parameter @restricted} {\addrightcs{yax@\yax@parameter @restricted}{, #1}} {\defcs{yax@\yax@parameter @restricted}{#1}}% } % % \restrictattribute : % % % ... % %\par % \pdef\restrictattribute{% \yax@getall\yax@restrictattribute_getrestrictions } \long\def\yax@restrictattribute_getrestrictions#1#2#3\par{% \yax@space_loop{\yax@restrictattribute_readrestrictions{#1}{#2}}{#3 }% } \long\def\yax@restrictattribute_readrestrictions#1#2#3{% \letcs{yax@#1:#2:\detokenize{#3}@allowed}\relax \ifcs{yax@#1:#2@restricted} {\addrightcs{yax@#1:#2@restricted}{, #3}} {\defcs{yax@#1:#2@restricted}{#3}}% } % % \restrictallattributes % % % ... % %\par % \long\pdef\restrictallattributes#1 #2\par{% \yax@space_loop{\yax@restrictallattributes_readrestrictions{#1}}{#2 }% } \long\def\yax@restrictallattributes_readrestrictions#1#2{% \letcs{yax@attribute@#1:\detokenize{#2}@allowed}\relax \ifcs{yax@attribute@#1@restricted} {\addrightcs{yax@attribute@#1@restricted}{, #2}} {\defcs{yax@attribute@#1@restricted}{#2}}% } % % % % % \defparameter{} % \defactiveparameter{} % \executeparameter : % \newif\ifyax@activeparameter \def\defparameter#1#{% \def\yax@parameter{#1 }% \afterassignment\yax@defparameter_do \def\yax@temp##1% }% \def\yax@defparameter_do{% \passexpanded{\yax@space_loop\yax@defparameter_def}\yax@parameter \yax@activeparameterfalse } \def\defactiveparameter{% \yax@activeparametertrue\defparameter }% \long\def\yax@defparameter_def#1{% \edefcs{yax@#1@def}{\primunexpanded\expandafter{\yax@temp{#1}}}% \ifyax@activeparameter \letcs{yax@#1@active}\relax \fi } \def\executeparameter{% \yax@getparameter\yax@executeparameter } \def\yax@executeparameter#1{% \iffcs{yax@#1@def}{\csname yax@#1@def\endcsname}% } % % % % %%%%%%%%%%%%%%%%%% USING VALUES %%%%%%%%%%%%%%%%%% % % These are the loops used to check whether : exists, % and if not to search the meta-parameters. They are used of course in % \usevalue and associates. % I could use one loop only for all macros, but then I should have used more % internal code to pass arguments here and there. % % #1 = list of parameters already checked (used to spot loops in meta-search) % => becomes {#1{#3}} on each iteration. % #2 = command executed on yax@: if it exists. % => doesn't change from one iteration to the next. % #3 = % => becomes \usecs{yax@:} on each iteration, thus % returning a new to be searched. % #4 = % => doesn't change from one iteration to the next. % #5 = if alone, when #6 exists. % #6 = . % => neither change. % % The loop does the following: % If : exists, then execute #2 on it followed by if any. % Or, if has a meta attribute, it calls % the \yax@ifattribute_checkmeta subloop with and % as passed arguments and as the list argument. % This command compares each item in the list with , and if they % have the same meta, it means we're in a meta-loop, we break and execute . % If no match obtains, we rerun the original loop (with #3 turned to its meta). % Or, if had no meta in the first place, we break and execute . % \newwhile\yax@ifattribute_noarg4{#1{#3}}{#2}{\usecs{yax@#3:meta}}{#4}{% \ifcs{yax@#3:#4} {\breakwhile{#2{yax@#3:#4}}} {\ifcs{yax@#3:meta}% has no . {\yax@ifattribute_checkmeta{}{#3}{#1}}% It has a meta, though. We do some testing (see next macro). {\breakwhile{}}}% No meta, we break the loop, gobble and release } \newwhile\yax@ifattribute_or5{#1{#3}}{#2}{\usecs{yax@#3:meta}}{#4}{#5}{% \ifcs{yax@#3:#4} {\breakwhile{#2{yax@#3:#4}}} {\ifcs{yax@#3:meta} {\yax@ifattribute_checkmeta{#5}{#3}{#1}} {\breakwhile{#5}}}% } \newwhile\yax@ifattribute_and6{#1{#3}}{#2}{\usecs{yax@#3:meta}}{#4}{#5}{#6}{% \ifcs{yax@#3:#4} {\breakwhile{#2{yax@#3:#4}#5}} {\ifcs{yax@#3:meta} {\yax@ifattribute_checkmeta{#6}{#3}{#1}} {\breakwhile{#6}}}% } % The _if version pass to the execution of the parameter, % since a test is supposed to happen. \newwhile\yax@ifattribute_if6{#1{#3}}{#2}{\usecs{yax@#3:meta}}{#4}{#5}{#6}{% \ifcs{yax@#3:#4} {\breakwhile{#2{yax@#3:#4}{#5}{#6}}} {\ifcs{yax@#3:meta} {\yax@ifattribute_checkmeta{#6}{#3}{#1}} {\breakwhile{#6}}}% } \newfor\yax@ifattribute_checkmeta{2}#3{% \iffxcscs{yax@#2:meta}{yax@#3:meta}% Both parameters have the same meta. So we're in a meta-loop, and we break. {\breakfor{\breakwhile{#1}}}% } % % The nometa version are definitely simpler. % \long\def\yax@ifattributenometa_and#1#2#3#4#5{% \ifcs{yax@#2:#3}{#1{yax@#2:#3}#4}{#5}% } \long\def\yax@ifattributenometa_or#1#2#3#4{% \ifcs{yax@#2:#3}{#1{yax@#2:#3}}{#4}% } \def\yax@ifattributenometa_noarg#1#2#3{% \iffcs{yax@#2:#3}{#1{yax@#2:#3}}% } % % % % % \nometa % \def\nometa#1{% \ifcs{yax@\commandtoname#1_nometa} {\usecs{yax@\commandtoname#1_nometa}} {\yax@error{You can't use \noexpand\nometa before \string#1}}% } % % % % Defining \, \or and \and at once, % with the \nometa-variant. % \def\yax@def_noarg#1#2{% \def#1{\yax@getall{\yax@ifattribute_noarg{}{#2}}}% \defcs{\commandtoname#1or}{\yax@getall{\yax@ifattribute_or{}{#2}}}% \defcs{\commandtoname#1and}{\yax@getall{\yax@ifattribute_and{}{#2}}}% % \defcs{yax@\commandtoname#1_nometa}{\yax@getall{\yax@ifattributenometa_noarg{#2}}}% \defcs{yax@\commandtoname#1or_nometa}{\yax@getall{\yax@ifattributenometa_or{#2}}}% \defcs{yax@\commandtoname#1and_nometa}{\yax@getall{\yax@ifattributenometa_and{#2}}}% } \def\yax@def_onearg#1#2{% \def#1##1{\yax@getall{\yax@ifattribute_noarg{}{#2{##1}}}}% \defcs{\commandtoname#1or}##1{\yax@getall{\yax@ifattribute_or{}{#2{##1}}}}% \defcs{\commandtoname#1and}##1{\yax@getall{\yax@ifattribute_and{}{#2{##1}}}}% % \defcs{yax@\commandtoname#1_nometa}##1{\yax@getall{\yax@ifattributenometa_noarg{#2{##1}}}}% \defcs{yax@\commandtoname#1or_nometa}##1{\yax@getall{\yax@ifattributenometa_or{#2{##1}}}}% \defcs{yax@\commandtoname#1and_nometa}##1{\yax@getall{\yax@ifattributenometa_and{#2{##1}}}}% } % % % % % \ifattribute % \def\ifattribute{% \yax@getall{\yax@ifattribute_and{}\gobbleone}% }% \def\yax@ifattribute_nometa{% \yax@getall{\yax@ifattributenometa_and\gobbleone}% } % % % % % \passvalue % \yax@def_onearg\passvalue\yax@passvalue \def\yax@passvalue#1#2{% \passexpandedcs{#1}{#2}% } \yax@def_onearg\passvaluenobraces\yax@passvalue_nobrace \def\yax@passvalue_nobrace#1#2{% \passexpandedcs\swapargs{#2}{#1}% } % % % % % \usevalue % \yax@def_noarg\usevalue\usecs % % % % % \settovalue (not expandable, obviously, % although it leaves nothing in the input but % the assignment. % \yax@def_onearg\settovalue\yax@settovalue \def\yax@settovalue#1#2{% #1 \usecs{#2}\relax } % % % % % \storevalue (like \settovalue, basically). % \yax@def_onearg\storevalue\yax@storevalue \def\yax@storevalue#1#2{% \lettocs#1{#2}% }% % % % % % \ifvalue % \def\ifvalue{% \yax@getall{\yax@removesign\yax@ifvalue_getvalue}% }% \def\yax@ifvalue_nometa{% \yax@getall{\yax@removesign\yax@ifvaluenometa_getvalue}% }% \long\def\yax@ifvalue_getvalue#1#2#3 {% \ifemptystring{#3} {\yax@ifvalue_getvalue{#1}{#2}} {\yax@ifattribute_if{}{\passexpandedcs{\ifstring{#3}}}{#1}{#2}}% } \def\yax@ifvaluenometa_getvalue#1#2#3 {% \ifemptystring{#3} {\yax@ifvaluenometa_getvalue{#1}{#2}} {\ifcs{yax@#1:#2}{\passexpandedcs{\ifstring{#3}}{yax@#1:#2}}\secondoftwo}% } % % % % % \ifcasevalue % \let\yax@ifcasevalue_passvalueor\passvalueor % just in case \passvalue is redefined by a \newsyntax. \let\yax@yax@ifcasevalue_passvalueor_nometa\yax@passvalueor_nometa \letcstocs{yax@yax@ifcasevalue_passvalueor_nometa}{yax@passvalueor_nometa} \def\ifcasevalue{% \yax@getall\yax@ifcasevalue_getvalue } \def\yax@ifcasevalue_nometa{% \yax@getall{\expandafter\nometa\yax@ifcasevalue_getvalue}% } \def\yax@ifcasevalue_getvalue#1#2{% \yax@ifcasevalue_passvalueor\yax@ifcasevalue_scan#1:#2 \yax@ifcasevalue_novalue } \newstring\val \newstring\elseval \long\def\yax@ifcasevalue_novalue#1\endval{% \iffcontains{\elseval}{#1}{\splitstringat{\elseval}{#1}\yax@ifcasevalue_doelse}% } \def\yax@ifcasevalue_doelse#1#2{\trim{#2}} \def\yax@ifcasevalue_scan#1#2\endval{% \ifcontains{\elseval}{#2} {\splitstringat{\elseval}{#2}\yax@ifcasevalue_dotest{#1}} {\yax@ifcasevalue_dotest{#2}{}{#1}}% } \def\yax@ifcasevalue_dotest#1#2#3{% \yax@ifcasevalue_loop{#3}{#2}{{yax@dummy_value} #1\val}% } \newfor\yax@ifcasevalue_loop{2}#3 #4\val{% \iffstring{#1}{#3}{\passtrim{#4}\breakfor}% }[\passtrim{#2}\unbrace] % % % % % \parameterloop: % \def\parameterloop{% \yax@getparameter\yax@parameterloop } \long\def\yax@parameterloop#1#2{% \yax@space_loop{\yax@parameterloop_launch{#2}}{#1 }% } \long\def\yax@parameterloop_launch#1#2{% \iffcs{yax@#2@attributelist} {\passexpandedcs{\yax@parameterloop_do{#1}{#2}}{yax@#2@attributelist}}% } \newfor\yax@parameterloop_do{2}#3{% \passvalue{#1{#2}{#3}}{#2}:{#3} } % % % % % \newsyntax % \long\def\newsyntax#1#{% \yax@newsyntax{#1}% } \long\def\yax@newsyntax_noarg#1#2#3{% \defcs{#1}#2{\yax@ifattribute_noarg{}{#3}{##1}{##2}}% \defcs{#1or}#2{\yax@ifattribute_or{}{#3}{##1}{##2}}% \defcs{#1and}#2{\yax@ifattribute_and{}{#3}{##1}{##2}}% % \defcs{yax@#1_nometa}#2{\yax@ifattributenometa_noarg{#3}{##1}{##2}}% \defcs{yax@#1or_nometa}#2{\yax@ifattributenometa_or{#3}{##1}{##2}}% \defcs{yax@#1and_nometa}#2{\yax@ifattributenometa_and{#3}{##1}{##2}}% } \long\def\yax@newsyntax_onearg#1#2#3{% \defcs{#1}##1#2{\yax@ifattribute_noarg{}{#3{##1}}{##2}{##3}}% \defcs{#1or}##1#2{\yax@ifattribute_or{}{#3{##1}}{##2}{##3}}% \defcs{#1and}##1#2{\yax@ifattribute_and{}{#3{##1}}{##2}{##3}}% % \defcs{yax@#1_nometa}##1#2{\yax@ifattributenometa_noarg{#3{##1}}{##2}{##3}}% \defcs{yax@#1or_nometa}##1#2{\yax@ifattributenometa_or{#3{##1}}{##2}{##3}}% \defcs{yax@#1and_nometa}##1#2{\yax@ifattributenometa_and{#3{##1}}{##2}{##3}}% } \long\def\yax@newsyntax#1#2{% \defcs{#2restrictattribute}#1{\yax@restrictattribute_getrestrictions{##1}{##2}}% \defcs{#2deleteattribute}#1{\letcs{yax@##1:##2}\yax@undefined}% \defcs{#2setattribute}#1{\yax@removesign{\skipspace{\yax@setattribute\defcs}}{##1}{##2}}% \defcs{#2esetattribute}#1{\yax@removesign{\skipspace{\yax@setattribute\edefcs}}{##1}{##2}}% \defcs{#2gsetattribute}#1{\yax@removesign{\skipspace{\yax@setattribute\gdefcs}}{##1}{##2}}% \defcs{#2xsetattribute}#1{\yax@removesign{\skipspace{\yax@setattribute\xdefcs}}{##1}{##2}}% \defcs{#2ifattribute}#1{\yax@ifattribute_and{}\gobbleone{##1}{##2}}% \defcs{yax@#2ifattribute_nometa}#1{\yax@ifattributenometa_and\gobbleone{##1}{##2}}% \yax@newsyntax_noarg{#2usevalue}{#1}\usecs \def\yax@temp##1##2{#1}% \passexpanded{\yax@newsyntax_onearg{#2passvalue}}{\yax@temp{##2}{##3}}\yax@passvalue \passexpanded{\yax@newsyntax_onearg{#2passvaluenobraces}}{\yax@temp{##2}{##3}}\yax@passvalue_nobrace \passexpanded{\yax@newsyntax_onearg{#2settovalue}}{\yax@temp{##2}{##3}}\yax@settovalue \passexpanded{\yax@newsyntax_onearg{#2storevalue}}{\yax@temp{##2}{##3}}\yax@storevalue \defcs{#2ifvalue}#1{\yax@removesign\yax@ifvalue_getvalue{##1}{##2}}% \defcs{yax@#2ifvalue_nometa}#1{\yax@removesign\yax@ifvaluenometa_getvalue{##1}{##2}}% \defcs{#2ifcasevalue}#1{\yax@ifcasevalue_getvalue{##1}{##2}}% \defcs{yax@#2ifcasevalue_nometa}#1{\expandafter\nometa\yax@ifcasevalue_getvalue{##1}{##2}}% } \def\yax@let#1#2#3{% \letcstocs{#2#1}{#3#1}% \letcstocs{yax@#2#1_nometa}{yax@#3#1_nometa}% } \def\yax@let_all#1#2#3{% \yax@let{#1}{#2}{#3}\yax@let{#1or}{#2}{#3}\yax@let{#1and}{#2}{#3}% } \def\copysyntax#1#2{% \letcstocs{#1restrictattribute}{#2restrictattribute}% \letcstocs{#1deleteattribute}{#2deleteattribute}% \letcstocs{#1setattribute}{#2setattribute}% \letcstocs{#1esetattribute}{#2esetattribute}% \letcstocs{#1gsetattribute}{#2gsetattribute}% \letcstocs{#1xsetattribute}{#2xsetattribute}% \yax@let{ifattribute}{#1}{#2}% \yax@let_all{usevalue}{#1}{#2}\yax@let_all{passvalue}{#1}{#2}\yax@let_all{passvaluenobraces}{#1}{#2}% \yax@let_all{settovalue}{#1}{#2}\yax@let_all{storevalue}{#1}{#2}% \yax@let{ifvalue}{#1}{#2}% \yax@let{ifcasevalue}{#1}{#2}% } \def\letyaxcommand#1#2{% \let#1#2% Base \let. \ifcs{yax@\commandtoname#2and_nometa} % #2 is a YaX command with -and -or variants. {\letcstocs{\commandtoname#1or}{\commandtoname#2or}% \letcstocs{\commandtoname#1and}{\commandtoname#2and}% \letcstocs{yax@\commandtoname#1_nometa}{yax@\commandtoname#2_nometa}% \letcstocs{yax@\commandtoname#1or_nometa}{yax@\commandtoname#2or_nometa}% \letcstocs{yax@\commandtoname#1and_nometa}{yax@\commandtoname#2and_nometa}}% {\iffcs{yax@\commandtoname#2_nometa}% #2 is a YaX command without variants but with \nometa (i.e. the \if...). {\letcstocs{yax@\commandtoname#1_nometa}{yax@\commandtoname#2_nometa}}}% } \restorecatcodes \endinput