diff options
Diffstat (limited to 'tex/context/base/mult-aux.mkiv')
-rw-r--r-- | tex/context/base/mult-aux.mkiv | 180 |
1 files changed, 142 insertions, 38 deletions
diff --git a/tex/context/base/mult-aux.mkiv b/tex/context/base/mult-aux.mkiv index b4c6ad039..dc6aca920 100644 --- a/tex/context/base/mult-aux.mkiv +++ b/tex/context/base/mult-aux.mkiv @@ -2,7 +2,7 @@ %D [ file=mult-aux, %D version=2010.08.2, %D title=\CONTEXT\ Multilingual Macros, -%D subtitle=helpers, +%D subtitle=Helpers, %D author=Hans Hagen, %D date=\currentdate, %D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] @@ -14,6 +14,9 @@ % todo: setupxxx and setupxxxs (so a plural for the root setup and % we can consider blocking the root) +% todo (e.g for columnsets and registers): \definexxx[parent][1] +% + %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. @@ -41,7 +44,7 @@ %D % \whateverparameter \c!test %D % \whateverparameterhash \c!test %D % \namedwhateverparameter \mycurrentwhatever \c!test -%D % \dosetwhateverstyleandcolor \c!style \c!color +%D % \usewhateverstyleandcolor \c!style \c!color %D % \everydefinewhatever (sets \currentwhatever) %D % \everypresetwhatever (can be used to reset parameters as we can redefine) %D % \everysetupwhatever (sets \currentwhatever) @@ -93,12 +96,8 @@ \expandafter\mult_interfaces_get_parameters_indeed \fi#2} -% \def\mult_interfaces_get_parameters#1% we can assume that the test already happened -% {\def\m_mult_interfaces_namespace{#1}% -% \mult_interfaces_get_parameters_indeed} - \def\mult_interfaces_get_parameters_indeed#1]% namespace already set - {\mult_interfaces_get_parameters_item#1,],\@relax@} + {\mult_interfaces_get_parameters_item#1,],\_e_o_p_} \def\mult_interfaces_get_parameters_item#1,#2% #2 takes space before , {\if,#1,% dirty trick for testing #1=empty @@ -106,14 +105,14 @@ \else\if]#1% \doubleexpandafter\gobbleoneargument \else - \mult_interfaces_get_parameters_assign#1==\empty\@relax@ + \mult_interfaces_get_parameters_assign#1==\empty\_e_o_p_ \doubleexpandafter\mult_interfaces_get_parameters_item \fi\fi#2} \def\mult_interfaces_get_parameters_error#1#2#3% {\showassignerror{#2}{\the\inputlineno\space(#1)}} -\def\mult_interfaces_get_parameters_assign#1=#2=#3#4\@relax@ +\def\mult_interfaces_get_parameters_assign#1=#2=#3#4\_e_o_p_ {\ifx\empty#1\empty \expandafter\mult_interfaces_get_parameters_error \else\ifx#3\empty @@ -125,21 +124,35 @@ \newif\ifassignment -\def\mult_check_for_assignment#1=#2#3\_end_ - {\expandafter\if\detokenize{#2}@\assignmentfalse\else\assignmenttrue\fi} +\def\mult_check_for_assignment_indeed#1=#2#3\_end_ + {\if#2@\assignmentfalse\else\assignmenttrue\fi} -% usage: \mult_check_for_assignment##1=@@_end_ +\def\mult_check_for_assignment#1% + {\expandafter\mult_check_for_assignment_indeed\detokenize{#1}=@@\_end_} % End of experimental code. +% the commented detokenized variant that backtracks ... needs testing usage first +% +% \let\whatever\relax +% +% \definetest[oeps][bagger=\whatever] +% +% \def\currenttest{oeps} \edef\hans{\detokenizedtestparameter{bagger}}\meaning\hans\par +% \def\currenttest{oeps} \edef\hans{\detokenizedtestparameter{reggab}}\meaning\hans\par + +\def\mult_interfaces_detokenize{\expandafter\expandafter\expandafter\detokenize\expandafter\expandafter\expandafter} + \unexpanded\def\mult_interfaces_install_parameter_handler#1#2#3#4#5#6#7#8#9% inlining \csname*\endcsname is more efficient (#3 and #6 only) - {\ifx#2\relax\let#2\empty\fi % it is hardly faster but produces less expansion tracing + {\ifx#2\relax\let#2\empty\fi % it is hardly faster but produces less expansion tracing %\def#3##1{\csname#4{#1#2}{##1}\endcsname}% \def#3##1{\csname\ifcsname#1#2:##1\endcsname#1#2:##1\else\expandafter#5\csname#1#2:\s!parent\endcsname{##1}\fi\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}% is {} needed around ##1 ? \def#6##1##2{\csname\ifcsname#1##1:##2\endcsname#1##1:##2\else\expandafter#5\csname#1##1:\s!parent\endcsname{##2}\fi\endcsname}% \def#7##1{\detokenize\expandafter\expandafter\expandafter{\csname#1#2:##1\endcsname}}% always root, no backtrack + % \def#7##1{\mult_interfaces_detokenize{\csname#4{#1#2}{##1}\endcsname}}% compact version + % \def#7##1{\mult_interfaces_detokenize{\csname\ifcsname#1#2:##1\endcsname#1#2:##1\else\expandafter#5\csname#1#2:\s!parent\endcsname{##1}\fi\endcsname}}% \def#8##1{\csname\ifcsname#1#2:##1\endcsname#1#2:##1\else\s!empty\fi\endcsname}% \def#9##1{\csname#1#2:##1\endcsname}} @@ -251,30 +264,34 @@ \let\definehandlerparent\empty -\unexpanded\def\mult_interfaces_install_define_handler#1#2#3#4#5#6#7#8#9% - {\ifx#4\relax\let#4\empty\fi +\unexpanded\def\mult_interfaces_install_define_handler#1#2#3#4#5#6#7#8#9% why is \expanded still needed in clones + {\ifx#4\relax\let#4\empty\fi % see \defineregister \unexpanded\def#2{\dotripleempty#5}% \newtoks#6% \newtoks#7% - \def#5[##1][##2][##3]% [child][parent][settings] | [child][settings] | [child][parent] | [child] + \unexpanded\def#5[##1][##2][##3]% [child][parent][settings] | [child][settings] | [child][parent] | [child] {\let#9#4% \edef#4{##1}% - \the#6% predefine \ifthirdargument + \the#6% predefine \edef#8{##2}% - \mult_interfaces_get_parameters{#1#4:}[\s!parent=#1##2,##3]% + \expandafter\edef\csname#1#4:\s!parent\endcsname{#1##2}% + \mult_interfaces_get_parameters{#1#4:}[##3]% \else\ifsecondargument - \mult_check_for_assignment##2=@@\_end_ + \the#6% predefine + \expandafter\mult_check_for_assignment_indeed\detokenize{##2}=@@\_end_ \ifassignment \let#8\empty - \mult_interfaces_get_parameters{#1#4:}[\s!parent=#3,##2]% + \expandafter\edef\csname#1#4:\s!parent\endcsname{#3}% + \mult_interfaces_get_parameters{#1#4:}[##2]% \else \edef#8{##2}% - \mult_interfaces_get_parameters{#1#4:}[\s!parent=#1##2]% + \expandafter\edef\csname#1#4:\s!parent\endcsname{#1##2}% \fi \else + \the#6% predefine \let#8\empty - \mult_interfaces_get_parameters{#1#4:}[\s!parent=#3]% + \expandafter\edef\csname#1#4:\s!parent\endcsname{#3}% \fi\fi \the#7% \let#4#9}} @@ -298,7 +315,7 @@ \unexpanded\def#6{\mult_interfaces_get_parameters{#1#3:}}% no every ! don't change it \newtoks#5% \newtoks#8% - \def#4[##1][##2]% maybe helper + \unexpanded\def#4[##1][##2]% maybe helper {\let#7#3% \ifsecondargument \def\mult_interfaces_with_comma_list_element####1% we will have a simple one as well @@ -342,7 +359,7 @@ \newtoks#8% \newtoks#9% \ifx#6\relax\let#6\empty\fi - \def#4[##1][##2]% maybe helper + \unexpanded\def#4[##1][##2]% maybe helper {\ifsecondargument % no commalist here % \setuplayout[whatever][key=value] \let#7#3% @@ -354,7 +371,8 @@ \ifx#3#6\the#8\fi % only switchsetups if previous == current \let#3#7% \else\iffirstargument - \mult_check_for_assignment##1=@@\_end_ % \docheckassignment{##1}% + % \mult_check_for_assignment{##1}% + \expandafter\mult_check_for_assignment_indeed\detokenize{##1}=@@\_end_ \ifassignment % \setuplayout[key=value] \let#7#3% @@ -413,7 +431,8 @@ \ifthirdargument \def\mult_interfaces_with_comma_list_element####1% {\edef#3{####1}% - \mult_interfaces_get_parameters{#1#3:}[\s!parent=#1##2,##3]% always sets parent + \expandafter\def\csname#1#3:\s!parent\endcsname{#1##2}% + \mult_interfaces_get_parameters{#1#3:}[##3]% always sets parent \the#5}% \processcommalist[##1]\mult_interfaces_with_comma_list_element \else\ifsecondargument @@ -486,25 +505,26 @@ %D We don't need colons for such simple cases. -\unexpanded\def\mult_interfaces_install_direct_parameter_handler#1#2#3#4% - {\def#2##1{\csname\ifcsname#1##1\endcsname#1##1\else\s!empty\fi\endcsname}% - \def#3##1{\detokenize\expandafter\expandafter\expandafter{\csname#1##1\endcsname}}% - \def#4##1{\csname#1##1\endcsname}} +\unexpanded\def\mult_interfaces_install_direct_parameter_handler#1#2#3#4#5% + {\def#3##1{\csname\ifcsname#1##1\endcsname#1##1\else\s!empty\fi\endcsname}% + \def#4##1{\detokenize\expandafter\expandafter\expandafter{\csname#1##1\endcsname}}% + % \def#4##1{\mult_interfaces_detokenize{\csname\ifcsname#1#2:##1\endcsname#1#2:##1\else\expandafter#5\csname#1#2:\s!parent\endcsname{##1}\fi\endcsname}}% + \def#5##1{\csname#1##1\endcsname}} \unexpanded\def\installdirectparameterhandler#1#2% {\normalexpanded {\mult_interfaces_install_direct_parameter_handler {\noexpand#1}% + \expandafter\noexpand\csname current#2\endcsname \expandafter\noexpand\csname #2parameter\endcsname \expandafter\noexpand\csname detokenized#2parameter\endcsname \expandafter\noexpand\csname direct#2parameter\endcsname}} -\unexpanded\def\mult_interfaces_install_direct_setup_handler#1#2#3#4% +\unexpanded\def\mult_interfaces_install_direct_setup_handler#1#2#3#4#5% {\unexpanded\def#2{\dosingleempty#3}% - \newtoks#4% - \def#3[##1]% - {\mult_interfaces_get_parameters#1[##1]% - \the#4}} + \newtoks#5% + \def#3[##1]{\mult_interfaces_get_parameters#1[##1]\the#5}% + \def#4{\mult_interfaces_get_parameters#1}} \unexpanded\def\installdirectsetuphandler#1#2% {\normalexpanded @@ -512,6 +532,7 @@ {\noexpand#1}% \??aa \expandafter\noexpand\csname setup#2\endcsname \expandafter\noexpand\csname setup_#2\endcsname % semi-public + \expandafter\noexpand\csname setupcurrent#2\endcsname % no \every (we use 'current' for consistency) \expandafter\noexpand\csname everysetup#2\endcsname}} \unexpanded\def\mult_interfaces_install_direct_parameter_set_handler#1#2#3#4#5% @@ -578,6 +599,34 @@ \unexpanded\def\relateparameterhandlers#1#2#3#4% {from} {instance} {to} {instance} {\expandafter\edef\csname\csname#1namespace\endcsname#2:\s!parent\endcsname{\csname#3namespace\endcsname#4}} +%D Here is another experiment: + +\unexpanded\def\installactionhandler#1% + {\normalexpanded + {\mult_interfaces_install_action_handler + {#1}% + \expandafter\noexpand\csname current#1\endcsname + \expandafter\noexpand\csname setupcurrent#1\endcsname + \expandafter\noexpand\csname #1_action\endcsname}} + +\unexpanded\def\mult_interfaces_install_action_handler#1#2#3#4% + {\unexpanded\expandafter\def\csname#1\endcsname{\dodoubleempty#4}% + \unexpanded\def#4[##1][##2]% + {\begingroup + \ifsecondargument + \edef#2{##1}% + #3[##2]% + \else\iffirstargument + \doifassignmentelse{##1} + {\let#2\empty + #3[##1]}% + {\edef#2{##1}}% + \else + \let#2\empty + \fi\fi + \directsetup{handler:action:#1}% + \endgroup}} + % First we had, in tune with the regular system variables: % % \starttyping @@ -606,9 +655,7 @@ \newcount\c_mult_interfaces_n_of_namespaces -\def\v_interfaces_prefix_template{\number \c_mult_interfaces_n_of_namespaces::} -\def\v_interfaces_prefix_template{\characters\c_mult_interfaces_n_of_namespaces::} -\def\v_interfaces_prefix_template{\number \c_mult_interfaces_n_of_namespaces>} +%def\v_interfaces_prefix_template{\number \c_mult_interfaces_n_of_namespaces>} \def\v_interfaces_prefix_template{\characters\c_mult_interfaces_n_of_namespaces>} \def\v_interfaces_prefix_template % consistently %03i> @@ -635,6 +682,10 @@ \ctxcommand{registernamespace(\number\c_mult_interfaces_n_of_namespaces,"#1")}% \fi} +\def\mult_interfaces_get_parameters_error#1#2#3% redefined + {\ctxcommand{showassignerror("#1","#2","#3",\the\inputlineno)}% + \waitonfatalerror} + % We install two core namespaces here, as we want nice error messages. Maybe % we will reserve the first 9. @@ -642,6 +693,34 @@ \installcorenamespace{fontinstancebasic} \installcorenamespace{fontinstanceclass} +%D The next one is handy for local assignments. + +\installcorenamespace{dummy} + +\letvalue\??dummy\empty + + \def\dummyparameter #1{\csname\??dummy\ifcsname\??dummy#1\endcsname#1\fi\endcsname} + \def\directdummyparameter#1{\csname\??dummy#1\endcsname} +\unexpanded\def\setdummyparameter #1{\expandafter\def\csname\??dummy#1\endcsname} +\unexpanded\def\letdummyparameter #1{\expandafter\let\csname\??dummy#1\endcsname} + +% \unexpanded\def\getdummyparameters +% {\mult_interfaces_get_parameters\??dummy} + +\unexpanded\def\getdummyparameters[#1% + {\if\noexpand#1]% + \expandafter\gobbleoneargument + \else + \let\m_mult_interfaces_namespace\??dummy + \expandafter\mult_interfaces_get_parameters_indeed + \fi#1} + +\mult_interfaces_install_style_and_color_handler + \directdummyparameter + \usedummystyleandcolor + \usedummystyleparameter + \usedummycolorparameter + % Maybe a \definecorenamespace[name][directparameter,directsetup][parent] % but we don't gain much. Actually we might just inline all definitions. @@ -707,6 +786,31 @@ \expandafter\mult_interfaces_show_parent_chain\csname#1:\s!parent\endcsname \fi} +%D Another helper: + +\unexpanded\def\doifelsecommandhandler#1#2% namespace name + {\ifcsname#1#2:\s!parent\endcsname + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +\unexpanded\def\doifcommandhandler#1#2% namespace name + {\ifcsname#1#2:\s!parent\endcsname + \expandafter\firstofoneargument + \else + \expandafter\gobbleoneargument + \fi} + +\unexpanded\def\doifnotcommandhandler#1#2% namespace name + {\ifcsname#1#2:\s!parent\endcsname + \expandafter\gobbleoneargument + \else + \expandafter\firstofoneargument + \fi} + +\let\doifcommandhandlerelse\doifelsecommandhandler + %D Conventions: %D %D \starttyping |