summaryrefslogtreecommitdiff
path: root/tex/context/base/mult-aux.mkiv
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mult-aux.mkiv')
-rw-r--r--tex/context/base/mult-aux.mkiv180
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