From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- macros/generic/yax/yax.tex | 707 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 707 insertions(+) create mode 100644 macros/generic/yax/yax.tex (limited to 'macros/generic/yax/yax.tex') diff --git a/macros/generic/yax/yax.tex b/macros/generic/yax/yax.tex new file mode 100644 index 0000000000..3bf7429841 --- /dev/null +++ b/macros/generic/yax/yax.tex @@ -0,0 +1,707 @@ +% 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 -- cgit v1.2.3