%D \module %D [ file=mult-aux, %D version=2010.08.2, %D title=\CONTEXT\ Multilingual Macros, %D subtitle=helpers, %D author=Hans Hagen, %D date=\currentdate, %D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. %D A generalization of \MKIV-like inheritance. Just something to play %D with (interface might change). The code here evolved in an email %D exchange between me and Wolgang Schuster. \writestatus{loading}{ConTeXt Multilingual Macros / Helpers} \registerctxluafile{mult-aux}{1.001} \unprotect %D \starttyping %D \unprotect %D \def\????aa{@@@@aa} %D %D \installparameterhandler \????aa {whatever} %D \installsetuphandler \????aa {whatever} %D \installdefinehandler \????aa {whatever} \????aa % #3 == defaultroot %D \installattributehandler \????aa {whatever} %D %D % \installcommandhandler \????aa {whatever} \????aa %D \protect %D %D % \whateverparameter \c!test %D % \whateverparameterhash \c!test %D % \namedwhateverparameter \mycurrentwhatever \c!test %D % \dosetwhateverattributes \c!style \c!color %D % \everydefinewhatever (sets \currentwhatever) %D % \everypresetwhatever (can be used to reset parameters as we can redefine) %D % \everysetupwhatever (sets \currentwhatever) %D %D \starttext %D \definewhatever[first] \definewhatever[second][first] %D test: \def\currentwhatever{first} \whateverparameter{method} \par %D \setupwhatever [method=unset] test: \def\currentwhatever{first} \whateverparameter{method} \par %D \setupwhatever[first] [method=first] test: \def\currentwhatever{first} \whateverparameter{method} \par %D test: \def\currentwhatever{second} \whateverparameter{method} \par %D \setupwhatever[second][method=second] test: \def\currentwhatever{second} \whateverparameter{method} \par %D \stoptext %D \stoptyping % problem: every* could clash % % There can be less {} in the following definitions if we assume \??aa and \c!somecs % % todo: \def\detokenized...parameter#1{\detokenize\expandafter\expandafter\expandafter{\csname#1#2\endcsname}} % always root % % it might be more efficient to do this at the lua and % % watch the push/pop and predefinition of current .. this is needed for nested % definitions and overloaded defines using the predefined one \unexpanded\def\doinstallparameterhandler#1#2#3#4#5#6#7% {\ifx#2\relax\let#2\empty\fi \def#3##1{\csname#4{#1#2}{##1}\endcsname}% \def#4##1##2{\ifcsname##1##2\endcsname##1##2\else\expandafter#5\csname##1\s!parent\endcsname{##2}\fi}% \def#5##1##2{\ifx##1\relax\s!empty\else#4{##1}{##2}\fi}% \def#6##1##2{\csname#4{#1##1}{##2}\endcsname}% \def#7##1{\detokenize\expandafter\expandafter\expandafter{\csname#1##1\endcsname}}} % always root \unexpanded\def\installparameterhandler#1#2% {\normalexpanded {\doinstallparameterhandler {\noexpand#1}% \??aa \expandafter\noexpand\csname current#2\endcsname \expandafter\noexpand\csname #2parameter\endcsname \expandafter\noexpand\csname do#2parameter\endcsname \expandafter\noexpand\csname do#2parentparameter\endcsname \expandafter\noexpand\csname named#2parameter\endcsname \expandafter\noexpand\csname detokenized#2parameter\endcsname}} \unexpanded\def\doinstallparameterhashhandler#1#2#3#4#5% {\ifx#2\relax\let#2\empty\fi \def#3##1{#4{#1#2}{##1}}% \def#4##1##2{\ifcsname##1##2\endcsname##1\else\expandafter#5\csname##1\s!parent\endcsname{##2}\fi}% \def#5##1##2{\ifx##1\relax\else#4{##1}{##2}\fi}} \unexpanded\def\installparameterhashhandler#1#2% {\normalexpanded {\doinstallparameterhashhandler {\noexpand#1}% \??aa \expandafter\noexpand\csname current#2\endcsname \expandafter\noexpand\csname #2parameterhash\endcsname \expandafter\noexpand\csname do#2parameterhash\endcsname \expandafter\noexpand\csname do#2parentparameterhash\endcsname}} \unexpanded\def\doinstallparametersethandler#1#2#3#4#5% {\ifx#2\relax\let#2\empty\fi \def#3{\dosetvalue{#1#2}}% ##1 {##2} (braces are mandate) \def#4{\doletvalue{#1#2}}% ##1 ##2 \def#5{\doletvalue{#1#2}\empty}}% ##1 \unexpanded\def\installparametersethandler#1#2% {\normalexpanded {\doinstallparametersethandler {\noexpand#1}% \??aa \expandafter\noexpand\csname current#2\endcsname \expandafter\noexpand\csname set#2parameter\endcsname \expandafter\noexpand\csname let#2parameter\endcsname \expandafter\noexpand\csname reset#2parameter\endcsname}} \unexpanded\def\doinstallattributehandler#1#2#3% #1 not used here {\def#2##1##2% style color {\edef\fontattributehash {#3{##1}}% this name is public \edef\colorattributehash{#3{##2}}% this name is public \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash {##1}\fi \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash{##2}\fi}} \unexpanded\def\installattributehandler#1#2% {\normalexpanded {\doinstallattributehandler {\noexpand#1}% \??aa \expandafter\noexpand\csname doset#2attributes\endcsname \expandafter\noexpand\csname #2parameterhash\endcsname}} \let\definehandlerparent\empty \unexpanded\def\doinstalldefinehandler#1#2#3#4#5#6#7#8% {\ifx#4\relax\let#4\empty\fi \unexpanded\def#2{\dotripleempty#5}% \newtoks#6% \newtoks#7% \def#5[##1][##2][##3]% [child][parent][settings] | [child][settings] | [child][parent] | [child] {\let\saveddefinewhatever#4% \edef#4{##1}% \the#6% predefine \ifthirdargument \edef#8{##2}% \getparameters[#1#4][\s!parent=#1##2,##3]% \else\ifsecondargument \doifassignmentelse{##2} {\let#8\empty \getparameters[#1#4][\s!parent=#3,##2]} {\edef#8{##2}% \getparameters[#1#4][\s!parent=#1##2]}% \else \let#8\empty \getparameters[#1#4][\s!parent=#3]% \fi\fi \the#7% \let#4\saveddefinewhatever}} \unexpanded\def\installdefinehandler#1#2#3% {\normalexpanded {\doinstalldefinehandler {\noexpand#1}% \??aa \expandafter\noexpand\csname define#2\endcsname {\noexpand#3}% root \expandafter\noexpand\csname current#2\endcsname \expandafter\noexpand\csname d@define#2\endcsname \expandafter\noexpand\csname everypreset#2\endcsname \expandafter\noexpand\csname everydefine#2\endcsname \expandafter\noexpand\csname current#2parent\endcsname}} \unexpanded\def\doinstallsetuphandler#1#2#3#4#5#6% {\ifx#3\relax\let#3\empty\fi \unexpanded\def#2{\dodoubleempty#4}% \unexpanded\def#6{\getparameters[#1#3]}% \newtoks#5% \def#4[##1][##2]% maybe helper {\let\savedsetupwhatever#3% \ifsecondargument \def\docommand####1% we will have a simple one as well {\edef#3{####1}% \getparameters[#1#3][##2]% \the#5}% \processcommalist[##1]\docommand \else \let#3\empty \getparameters[#1][##1]% \the#5% \fi \let#3\savedsetupwhatever}} \unexpanded\def\installsetuphandler#1#2% {\normalexpanded {\doinstallsetuphandler {\noexpand#1}% \??aa \expandafter\noexpand\csname setup#2\endcsname \expandafter\noexpand\csname current#2\endcsname \expandafter\noexpand\csname d@setup#2\endcsname \expandafter\noexpand\csname everysetup#2\endcsname \expandafter\noexpand\csname setupcurrent#2\endcsname}} \unexpanded\def\doinstallswitchsetuphandler#1#2#3#4#5#6% {\ifx#3\relax\let#3\empty\fi \unexpanded\def#2{\dodoubleempty#4}% \unexpanded\def#6{\getparameters[#1#3]}% \newtoks#5% \def#4[##1][##2]% maybe helper {\ifsecondargument % no commalist here \let\savedsetupwhatever#3% \edef#3{##1}% \getparameters[#1#3][##2]% \the#5% \let#3\savedsetupwhatever \else\iffirstargument \doifassignmentelse{##1} {\let\savedsetupwhatever#3% \let#3\empty \getparameters[#1][##1]% \the#5% \let#3\savedsetupwhatever} {\edef#3{##1}% this will catch reset \the#5}% \else \let#3\empty \the#5% \fi\fi}} \unexpanded\def\installswitchsetuphandler#1#2% {\normalexpanded {\doinstallswitchsetuphandler {\noexpand#1}% \??aa \expandafter\noexpand\csname setup#2\endcsname \expandafter\noexpand\csname current#2\endcsname \expandafter\noexpand\csname d@setup#2\endcsname \expandafter\noexpand\csname everysetup#2\endcsname \expandafter\noexpand\csname setupcurrent#2\endcsname}} \unexpanded\def\installcommandhandler#1#2#3% \??self name \??parent (can be \??self) {\installparameterhandler {#1}{#2}% \installparameterhashhandler{#1}{#2}% \installparametersethandler {#1}{#2}% \installdefinehandler {#1}{#2}{#3}% \installsetuphandler {#1}{#2}% \installattributehandler {#1}{#2}} \unexpanded\def\installswitchcommandhandler#1#2#3% \??self name \??parent (can be \??self) {\installparameterhandler {#1}{#2}% \installparameterhashhandler{#1}{#2}% \installparametersethandler {#1}{#2}% \installdefinehandler {#1}{#2}{#3}% \installswitchsetuphandler {#1}{#2}% \installattributehandler {#1}{#2}} \unexpanded\def\installnamespace#1% {\setvalue{????#1}{@@@@#1}} % \enabletrackers[interfaces.namespaces,context.flush] % % \definenamespace % [xy] % [type=module, % comment=test module, % version=1, % name=test, % style=yes, % command=yes, % setup=list, % set=yes, % parent=xy] % % \unprotect % \getparameters % [\????xy] % [text=] % \protect % % \definetest[one] % % \starttext % % “\testparameter{text}” % % \setuptest[text=foo] % % “\testparameter{text}” % % \setuptest[one][text=bar] % % “\testparameter{text}” % % \stoptext \unexpanded\def\definenamespace {\dodoubleargument\dodefinenamespace} \def\dodefinenamespace[#1][#2]% namespace settings {\ctxlua{interfaces.namespaces.define(\!!bs#1\!!es,\!!bs#2\!!es)}} \def\listnamespaces {\ctxlua{interfaces.namespaces.list()}} %D Helper: %D %D \starttyping %D \showparentchain{@@am}{left} %D \stoptyping \def\doshowparentchain#1% {#1 => % \ifcsname#1\s!parent\endcsname \expandafter\doshowparentchain\csname#1\s!parent\endcsname \fi} \def\showparentchain#1#2% {\writestatus\m!system{chain: [ \doshowparentchain{#1#2}]}} \protect