summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/mult-aux.mkiv
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mult-aux.mkiv')
-rw-r--r--Master/texmf-dist/tex/context/base/mult-aux.mkiv617
1 files changed, 537 insertions, 80 deletions
diff --git a/Master/texmf-dist/tex/context/base/mult-aux.mkiv b/Master/texmf-dist/tex/context/base/mult-aux.mkiv
index 1dfe6fb8efd..b4c6ad03960 100644
--- a/Master/texmf-dist/tex/context/base/mult-aux.mkiv
+++ b/Master/texmf-dist/tex/context/base/mult-aux.mkiv
@@ -5,16 +5,21 @@
%D subtitle=helpers,
%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright=PRAGMA]
+%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.
+% todo: setupxxx and setupxxxs (so a plural for the root setup and
+% we can consider blocking the root)
+
%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.
+% todo: doifelse<whatever>
+
\writestatus{loading}{ConTeXt Multilingual Macros / Helpers}
\registerctxluafile{mult-aux}{1.001}
@@ -25,18 +30,18 @@
%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 \installparameterhandler \????aa {whatever}
+%D \installsetuphandler \????aa {whatever}
+%D \installdefinehandler \????aa {whatever} \????aa % #3 == defaultroot
+%D \installfontandcolorhandler\????aa {whatever}
%D
-%D % \installcommandhandler \????aa {whatever} \????aa
+%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 % \dosetwhateverstyleandcolor \c!style \c!color
%D % \everydefinewhatever (sets \currentwhatever)
%D % \everypresetwhatever (can be used to reset parameters as we can redefine)
%D % \everysetupwhatever (sets \currentwhatever)
@@ -62,148 +67,583 @@
% 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
+% todo: add (relaxed) postsetup and postdefine hooks, just after the everys
+
+% Start of experimental code: especially tables can have many assignments
+% and although most time is spent in the typesetting anyway, we can squeeze
+% out a little bit. Of course having 500 rows of 50 columns each with some
+% setting does not happen that often. One should keep in mind that in the
+% average document having some 500 assignments is no exception but there we're
+% talking of neglectable runtime for them. Of course in the definitions below
+% there is no real gain, only in the generated \setup* commands. Another
+% situation with many assignments is \XML\ where we can pass attributes
+% and normally don't do testing of them making sense.
+%
+% \testfeatureonce{100000}{\getparameters[bla][a=111,b=222,c=333]}% 1.669s
+% \testfeatureonce{100000}{\mult_interfaces_get_parameters{bla} [a=111,b=222,c=333]}% 1.529s
+% \testfeatureonce{100000}{\def\m_mult_interfaces_namespace{bla}\mult_interfaces_get_parameters_indeed[a=111,b=222,c=333]}% 1.466s
+
+\let\m_mult_interfaces_namespace\empty
+
+\def\mult_interfaces_get_parameters#1[#2%
+ {\if\noexpand#2]%
+ \expandafter\gobbleoneargument
+ \else
+ \def\m_mult_interfaces_namespace{#1}%
+ \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@}
+
+\def\mult_interfaces_get_parameters_item#1,#2% #2 takes space before ,
+ {\if,#1,% dirty trick for testing #1=empty
+ \expandafter\mult_interfaces_get_parameters_item
+ \else\if]#1%
+ \doubleexpandafter\gobbleoneargument
+ \else
+ \mult_interfaces_get_parameters_assign#1==\empty\@relax@
+ \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@
+ {\ifx\empty#1\empty
+ \expandafter\mult_interfaces_get_parameters_error
+ \else\ifx#3\empty
+ \doubleexpandafter\mult_interfaces_get_parameters_error
+ \else
+ \doubleexpandafter\dosetvalue
+ \fi\fi
+ \m_mult_interfaces_namespace{#1}{#2}}
+
+\newif\ifassignment
+
+\def\mult_check_for_assignment#1=#2#3\_end_
+ {\expandafter\if\detokenize{#2}@\assignmentfalse\else\assignmenttrue\fi}
+
+% usage: \mult_check_for_assignment##1=@@_end_
+
+% End of experimental code.
+
+\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
+ %\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#8##1{\csname\ifcsname#1#2:##1\endcsname#1#2:##1\else\s!empty\fi\endcsname}%
+ \def#9##1{\csname#1#2:##1\endcsname}}
\unexpanded\def\installparameterhandler#1#2%
{\normalexpanded
- {\doinstallparameterhandler
+ {\mult_interfaces_install_parameter_handler
{\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 do#2parameter\endcsname % or : #2_parameter_hash
+ \expandafter\noexpand\csname do#2parentparameter\endcsname % or : #2_parent_parameter_hash
\expandafter\noexpand\csname named#2parameter\endcsname
- \expandafter\noexpand\csname detokenized#2parameter\endcsname}}
+ \expandafter\noexpand\csname detokenized#2parameter\endcsname
+ \expandafter\noexpand\csname strict#2parameter\endcsname % checked
+ \expandafter\noexpand\csname direct#2parameter\endcsname}} % unchecked
-\unexpanded\def\doinstallparameterhashhandler#1#2#3#4#5%
+\unexpanded\def\mult_interfaces_install_root_parameter_handler#1#2#3%
+ {\def#2##1{\detokenize\expandafter\expandafter\expandafter{\csname#1:##1\endcsname}}% always root
+ \def#3##1{\csname\ifcsname#1:##1\endcsname#1:##1\else\s!empty\fi\endcsname}}
+
+\unexpanded\def\installrootparameterhandler#1#2%
+ {\normalexpanded
+ {\mult_interfaces_install_root_parameter_handler
+ {\noexpand#1}% \??aa
+ \expandafter\noexpand\csname detokenizedroot#2parameter\endcsname
+ \expandafter\noexpand\csname root#2parameter\endcsname}}
+
+\unexpanded\def\mult_interfaces_install_parameter_hash_handler#1#2#3#4#5#6#7#8#9%
{\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}}
+ \def#3##1{#1#4{#1#2}{##1}:}% leading #1 was missing .. is this one used?
+ \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}%
+ \def#6{#1#2:}%
+ \def#7##1{#1##1:}%
+ \def#8{\ifx#2\empty\else\ifcsname#1#2:\s!parent\endcsname\else\expandafter\let\csname#1#2:\s!parent\endcsname#1\fi\fi}%
+ \unexpanded\def#9##1{\expandafter\edef\csname#1##1:\s!parent\endcsname{#1#2}}}
\unexpanded\def\installparameterhashhandler#1#2%
- {\normalexpanded
- {\doinstallparameterhashhandler
+ {\expandafter\let\csname#2namespace\endcsname#1%
+ \normalexpanded
+ {\mult_interfaces_install_parameter_hash_handler
{\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}}
+ \expandafter\noexpand\csname do#2parameterhash\endcsname % or : #2_parameter_hash
+ \expandafter\noexpand\csname do#2parentparameterhash\endcsname % or : #2_parent_parameter_hash
+ \expandafter\noexpand\csname current#2hash\endcsname
+ \expandafter\noexpand\csname named#2hash\endcsname
+ \expandafter\noexpand\csname check#2parent\endcsname
+ \expandafter\noexpand\csname chaintocurrent#2\endcsname}}
+
+% In \MKIV\ we can probably use the english variant for all other
+% languages too.
-\unexpanded\def\doinstallparametersethandler#1#2#3#4#5%
+\unexpanded\def\mult_interfaces_install_parameter_set_handler#1#2#3#4#5#6% we can speed this up for english
{\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#3{\dosetvalue {#1#2:}}% ##1 {##2} (braces are mandate)
+ \unexpanded\def#4{\dosetevalue{#1#2:}}% ##1 {##2} (braces are mandate)
+ \unexpanded\def#5{\doletvalue {#1#2:}}% ##1 ##2
+ \unexpanded\def#6{\doletvalue {#1#2:}\empty}}% ##1
+
+\startinterface english
+
+ \unexpanded\def\mult_interfaces_install_parameter_set_handler#1#2#3#4#5#6%
+ {\ifx#2\relax\let#2\empty\fi
+ \unexpanded\def#3##1{\expandafter \def\csname#1#2:##1\endcsname}% ##1 {##2} (braces are mandate)
+ \unexpanded\def#4##1{\expandafter\edef\csname#1#2:##1\endcsname}% ##1 {##2} (braces are mandate)
+ \unexpanded\def#5##1{\expandafter \let\csname#1#2:##1\endcsname}% ##1 ##2
+ \unexpanded\def#6##1{\expandafter \let\csname#1#2:##1\endcsname\empty}}% ##1
+
+\stopinterface
\unexpanded\def\installparametersethandler#1#2%
{\normalexpanded
- {\doinstallparametersethandler
+ {\mult_interfaces_install_parameter_set_handler
{\noexpand#1}% \??aa
\expandafter\noexpand\csname current#2\endcsname
\expandafter\noexpand\csname set#2parameter\endcsname
+ \expandafter\noexpand\csname setexpanded#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}}%
- \edef\colorattributehash{#3{##2}}%
- \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash {##1}\fi
- \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash{##2}\fi}}
+\let\dousecurrentstyleparameter\relax
+\let\dousecurrentcolorparameter\relax
+
+\let\currentstyleparameter\empty
+\let\currentcolorparameter\empty
-\unexpanded\def\installattributehandler#1#2%
+\unexpanded\def\mult_interfaces_install_style_and_color_handler#1#2#3#4%
+ {\unexpanded\def#2##1##2% style color
+ {\edef\currentstyleparameter{#1{##1}}% this name is public
+ \edef\currentcolorparameter{#1{##2}}% this name is public
+ \ifx\currentstyleparameter\empty\else\dousecurrentstyleparameter\fi
+ \ifx\currentcolorparameter\empty\else\dousecurrentcolorparameter\fi}%
+ \unexpanded\def#3##1% style
+ {\edef\currentstyleparameter{#1{##1}}% this name is public
+ \ifx\currentstyleparameter\empty\else\dousecurrentstyleparameter\fi}%
+ \unexpanded\def#4##1% color
+ {\edef\currentcolorparameter{#1{##1}}% this name is public
+ \ifx\currentcolorparameter\empty\else\dousecurrentcolorparameter\fi}}
+
+\unexpanded\def\installstyleandcolorhandler#1#2%
{\normalexpanded
- {\doinstallattributehandler
- {\noexpand#1}% \??aa
- \expandafter\noexpand\csname doset#2attributes\endcsname
- \expandafter\noexpand\csname #2parameterhash\endcsname}}
+ {\mult_interfaces_install_style_and_color_handler
+ \expandafter\noexpand\csname #2parameter\endcsname
+ \expandafter\noexpand\csname use#2styleandcolor\endcsname % maybe an alias use#2styleandcolorparameters
+ \expandafter\noexpand\csname use#2styleparameter\endcsname
+ \expandafter\noexpand\csname use#2colorparameter\endcsname}}
\let\definehandlerparent\empty
-\unexpanded\def\doinstalldefinehandler#1#2#3#4#5#6#7#8%
+\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#2{\dotripleempty#5}%
\newtoks#6%
\newtoks#7%
\def#5[##1][##2][##3]% [child][parent][settings] | [child][settings] | [child][parent] | [child]
- {\let\saveddefinewhatever#4%
+ {\let#9#4%
\edef#4{##1}%
\the#6% predefine
\ifthirdargument
\edef#8{##2}%
- \getparameters[#1#4][\s!parent=#1##2,##3]%
+ \mult_interfaces_get_parameters{#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]}%
+ \mult_check_for_assignment##2=@@\_end_
+ \ifassignment
+ \let#8\empty
+ \mult_interfaces_get_parameters{#1#4:}[\s!parent=#3,##2]%
+ \else
+ \edef#8{##2}%
+ \mult_interfaces_get_parameters{#1#4:}[\s!parent=#1##2]%
+ \fi
\else
\let#8\empty
- \getparameters[#1#4][\s!parent=#3]%
+ \mult_interfaces_get_parameters{#1#4:}[\s!parent=#3]%
\fi\fi
\the#7%
- \let#4\saveddefinewhatever}}
+ \let#4#9}}
\unexpanded\def\installdefinehandler#1#2#3%
{\normalexpanded
- {\doinstalldefinehandler
+ {\mult_interfaces_install_define_handler
{\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 define_#2\endcsname % semi-public
\expandafter\noexpand\csname everypreset#2\endcsname
\expandafter\noexpand\csname everydefine#2\endcsname
- \expandafter\noexpand\csname current#2parent\endcsname}}
+ \expandafter\noexpand\csname current#2parent\endcsname
+ \expandafter\noexpand\csname saved_defined_#2\endcsname}}
-\unexpanded\def\doinstallsetuphandler#1#2#3#4#5#6%
+\unexpanded\def\mult_interfaces_install_setup_handler#1#2#3#4#5#6#7#8%
{\ifx#3\relax\let#3\empty\fi
\unexpanded\def#2{\dodoubleempty#4}%
- \unexpanded\def#6{\getparameters[#1#3]}%
+ \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
- {\let\savedsetupwhatever#3%
+ {\let#7#3%
\ifsecondargument
- \def\docommand####1% we will have a simple one as well
+ \def\mult_interfaces_with_comma_list_element####1% we will have a simple one as well
{\edef#3{####1}%
- \getparameters[#1#3][##2]%
+ \mult_interfaces_get_parameters{#1#3:}[##2]%
\the#5}%
- \processcommalist[##1]\docommand
+ \processcommalist[##1]\mult_interfaces_with_comma_list_element
\else
\let#3\empty
- \getparameters[#1][##1]%
+ \mult_interfaces_get_parameters{#1:}[##1]%
\the#5%
\fi
- \let#3\savedsetupwhatever}}
+ \let#3#7%
+ \the#8}}
\unexpanded\def\installsetuphandler#1#2%
{\normalexpanded
- {\doinstallsetuphandler
+ {\mult_interfaces_install_setup_handler
{\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 setup_#2\endcsname % semi-public
\expandafter\noexpand\csname everysetup#2\endcsname
- \expandafter\noexpand\csname setupcurrent#2\endcsname}}
+ \expandafter\noexpand\csname setupcurrent#2\endcsname
+ \expandafter\noexpand\csname saved_setup_current#2\endcsname
+ \expandafter\noexpand\csname everysetup#2root\endcsname}}
-\unexpanded\def\installcommandhandler#1#2#3% \??self name \??parent (can be \??self)
+\let\doingrootsetupnamed\plusone % \setuplayout[name][key=value]
+\let\doingrootsetuproot \plustwo % \setuplayout [key=value]
+\let\doingrootsetnamed \plusthree % \setuplayout[name]
+\let\doingrootsetroot \plusfour % \setuplayout
+
+\unexpanded\def\mult_interfaces_install_switch_setup_handler_a#1#2#3#4#5%
+ {\ifx#3\relax\let#3\empty\fi
+ \unexpanded\def#2{\dodoubleempty#4}%
+ \unexpanded\def#5{\mult_interfaces_get_parameters{#1#3:}}}
+
+\unexpanded\def\mult_interfaces_install_switch_setup_handler_b#1#2#3#4#5#6#7#8#9%
+ {\newtoks#5%
+ \newconstant#2%
+ \newtoks#8%
+ \newtoks#9%
+ \ifx#6\relax\let#6\empty\fi
+ \def#4[##1][##2]% maybe helper
+ {\ifsecondargument % no commalist here
+ % \setuplayout[whatever][key=value]
+ \let#7#3%
+ \let#6#3%
+ \edef#3{##1}%
+ #2\doingrootsetupnamed
+ \mult_interfaces_get_parameters{#1#3:}[##2]%
+ \the#5%
+ \ifx#3#6\the#8\fi % only switchsetups if previous == current
+ \let#3#7%
+ \else\iffirstargument
+ \mult_check_for_assignment##1=@@\_end_ % \docheckassignment{##1}%
+ \ifassignment
+ % \setuplayout[key=value]
+ \let#7#3%
+ \let#6#3%
+ \let#3\empty
+ #2\doingrootsetuproot
+ \mult_interfaces_get_parameters{#1:}[##1]%
+ \the#5%
+ \the#8% switchsetups
+ \let#3#7%
+ \else
+ % \setuplayout[whatever]
+ \let#6#3% % previous becomes current
+ \edef#3{##1}% this will catch reset so one needs to test for it
+ #2\doingrootsetnamed
+ \the#5% % we can check for previous vs current
+ \the#8% switchsetups
+ \fi
+ \else
+ % \setuplayout
+ \let#6#3% % previous becomes current
+ \let#3\empty % current becomes empty
+ #2\doingrootsetroot
+ \the#5%
+ \the#8% switchsetups
+ \fi\fi
+ #2\zerocount % mode is always zero at the end
+ \the#9}}
+
+\unexpanded\def\installswitchsetuphandler#1#2%
+ {\normalexpanded
+ {\mult_interfaces_install_switch_setup_handler_a
+ {\noexpand#1}% \??aa
+ \expandafter\noexpand\csname setup#2\endcsname
+ \expandafter\noexpand\csname current#2\endcsname
+ \expandafter\noexpand\csname setup_#2\endcsname % semi-public
+ \expandafter\noexpand\csname setupcurrent#2\endcsname
+ \mult_interfaces_install_switch_setup_handler_b
+ {\noexpand#1}% \??aa
+ \expandafter\noexpand\csname #2setupmode\endcsname
+ \expandafter\noexpand\csname current#2\endcsname
+ \expandafter\noexpand\csname setup_#2\endcsname % semi-public
+ \expandafter\noexpand\csname everysetup#2\endcsname
+ \expandafter\noexpand\csname previous#2\endcsname
+ \expandafter\noexpand\csname saved_setup_current#2\endcsname
+ \expandafter\noexpand\csname everyswitch#2\endcsname
+ \expandafter\noexpand\csname everysetup#2root\endcsname}}
+
+\unexpanded\def\mult_interfaces_install_auto_setup_handler#1#2#3#4#5#6#7#8%
+ {\ifx#3\relax\let#3\empty\fi
+ \unexpanded\def#2{\dotripleempty#4}%
+ \unexpanded\def#6{\mult_interfaces_get_parameters{#1#3:}}%
+ \newtoks#5%
+ \def#4[##1][##2][##3]%
+ {\let#8#3%
+ \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
+ \the#5}%
+ \processcommalist[##1]\mult_interfaces_with_comma_list_element
+ \else\ifsecondargument
+ \def\mult_interfaces_with_comma_list_element####1%
+ {\edef#3{####1}%
+ #7% checks parent and sets if needed
+ \mult_interfaces_get_parameters{#1#3:}[##2]%
+ \the#5}%
+ \processcommalist[##1]\mult_interfaces_with_comma_list_element
+ \else
+ \let#3\empty
+ \mult_interfaces_get_parameters{#1:}[##1]%
+ \the#5%
+ \fi\fi
+ \let#3#8}}
+
+\unexpanded\def\installautosetuphandler#1#2%
+ {\normalexpanded
+ {\mult_interfaces_install_auto_setup_handler
+ {\noexpand#1}% \??aa
+ \expandafter\noexpand\csname setup#2\endcsname
+ \expandafter\noexpand\csname current#2\endcsname
+ \expandafter\noexpand\csname setup_#2\endcsname % semi-public
+ \expandafter\noexpand\csname everysetup#2\endcsname
+ \expandafter\noexpand\csname setupcurrent#2\endcsname
+ \expandafter\noexpand\csname check#2parent\endcsname
+ \expandafter\noexpand\csname saved_setup_current#2\endcsname}}
+
+\unexpanded\def\installbasicparameterhandler#1#2%
{\installparameterhandler {#1}{#2}%
\installparameterhashhandler{#1}{#2}%
\installparametersethandler {#1}{#2}%
- \installdefinehandler {#1}{#2}{#3}%
- \installsetuphandler {#1}{#2}%
- \installattributehandler {#1}{#2}}
+ \installrootparameterhandler{#1}{#2}}
+
+\unexpanded\def\installbasicautosetuphandler#1#2#3% \??self name \??parent (can be \??self)
+ {\installbasicparameterhandler{#1}{#2}%
+ \installautosetuphandler {#1}{#2}}
+
+\unexpanded\def\installcommandhandler#1#2#3% \??self name \??parent (can be \??self)
+ {\installbasicparameterhandler{#1}{#2}%
+ \installdefinehandler {#1}{#2}{#3}%
+ \installsetuphandler {#1}{#2}%
+ \installstyleandcolorhandler {#1}{#2}}
+
+\unexpanded\def\installswitchcommandhandler#1#2#3% \??self name \??parent (can be \??self)
+ {\installbasicparameterhandler{#1}{#2}%
+ \installdefinehandler {#1}{#2}{#3}%
+ \installswitchsetuphandler {#1}{#2}%
+ \installstyleandcolorhandler {#1}{#2}}
+
+\unexpanded\def\installautocommandhandler#1#2#3% automatically defined cloned setups
+ {\installbasicparameterhandler{#1}{#2}%
+ \installdefinehandler {#1}{#2}{#3}%
+ \installautosetuphandler {#1}{#2}%
+ \installstyleandcolorhandler {#1}{#2}}
+
+\unexpanded\def\installsimplecommandhandler#1#2#3% no define (experiment) - use \check*parent when defining
+ {\installbasicparameterhandler{#1}{#2}%
+ \installsetuphandler {#1}{#2}%
+ \installstyleandcolorhandler {#1}{#2}}
+
+%D Many mechanisms have some kind of inheritance in place, and these are
+%D the speed||critical ones. Therefore there is no reason to stick to
+%D \type {\@@xxkey} for the sake of performance. For this reason we also
+%D provide a direct variant. This permits a more consistent treatment of
+%D namespaces. A \type {\whateverparameter} call is three times slower
+%D and a \type {\directwhateverparameter} call two times but for some
+%D 100K expansions we only loose some .1 second which is neglectable
+%D given the small amount of expansions in real runs.
+
+%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\installdirectparameterhandler#1#2%
+ {\normalexpanded
+ {\mult_interfaces_install_direct_parameter_handler
+ {\noexpand#1}%
+ \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#2{\dosingleempty#3}%
+ \newtoks#4%
+ \def#3[##1]%
+ {\mult_interfaces_get_parameters#1[##1]%
+ \the#4}}
+
+\unexpanded\def\installdirectsetuphandler#1#2%
+ {\normalexpanded
+ {\mult_interfaces_install_direct_setup_handler
+ {\noexpand#1}% \??aa
+ \expandafter\noexpand\csname setup#2\endcsname
+ \expandafter\noexpand\csname setup_#2\endcsname % semi-public
+ \expandafter\noexpand\csname everysetup#2\endcsname}}
+
+\unexpanded\def\mult_interfaces_install_direct_parameter_set_handler#1#2#3#4#5%
+ {\unexpanded\def#2{\dosetvalue #1}%
+ \unexpanded\def#3{\dosetevalue#1}%
+ \unexpanded\def#4{\doletvalue #1}%
+ \unexpanded\def#5{\doletvalue #1\empty}}%
+
+\startinterface english
+
+ \unexpanded\def\mult_interfaces_install_direct_parameter_set_handler#1#2#3#4#5%
+ {\unexpanded\def#2##1{\expandafter \def\csname#1##1\endcsname}%
+ \unexpanded\def#3##1{\expandafter\edef\csname#1##1\endcsname}%
+ \unexpanded\def#4##1{\expandafter \let\csname#1##1\endcsname}%
+ \unexpanded\def#5##1{\expandafter \let\csname#1##1\endcsname\empty}}%
+
+\stopinterface
+
+\unexpanded\def\installdirectparametersethandler#1#2%
+ {\normalexpanded
+ {\mult_interfaces_install_direct_parameter_set_handler
+ {\noexpand#1}% \??aa
+ \expandafter\noexpand\csname set#2parameter\endcsname
+ \expandafter\noexpand\csname setexpanded#2parameter\endcsname
+ \expandafter\noexpand\csname let#2parameter\endcsname
+ \expandafter\noexpand\csname reset#2parameter\endcsname}}
+
+\let\installdirectstyleandcolorhandler\installstyleandcolorhandler
+
+\unexpanded\def\installdirectcommandhandler#1#2%
+ {\installdirectparameterhandler {#1}{#2}%
+ \installdirectsetuphandler {#1}{#2}%
+ \installdirectparametersethandler {#1}{#2}%
+ \installdirectstyleandcolorhandler{#1}{#2}}
+
+\unexpanded\def\installsetuponlycommandhandler#1#2%
+ {\installdirectparameterhandler{#1}{#2}%
+ \installdirectsetuphandler {#1}{#2}%
+ }% maybe \installdirectparametersethandler {#1}{#2}%
-\unexpanded\def\installnamespace#1%
- {\setvalue{????#1}{@@@@#1}}
+% Experiment:
+
+% \installcorenamespace {one}
+% \installcorenamespace {two}
+%
+% \installcommandhandler \??one {one} \??one
+% \installcommandhandler \??two {two} \??two
+%
+% \defineone[test] \setupone[test][alpha=first]
+% \definetwo[test] \setuptwo[test][beta=second]
+%
+% \protect
+%
+% \def\currentone{test}
+% \def\currenttwo{test}
+%
+% \relateparameterhandlers {two} {test} {one} {test}
+%
+% yes:\oneparameter{alpha}\par
+% nop:\oneparameter{beta}\par
+% yes:\twoparameter{alpha}\par
+% yes:\twoparameter{beta}\par
+
+\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}}
+
+% First we had, in tune with the regular system variables:
+%
+% \starttyping
+% \unexpanded\def\installnamespace#1{\setvalue{????#1}{@@@@#1}}
+% \stoptyping
+%
+% The following variant is nicer and in principle faster but that gets
+% unnoticed unless lots of expansion happens. Also, we can use long tags
+% but the internal expansion will be relatively small (and unlikely more
+% than 4 characters). For instance, \??xx used to expand to @@xx but now
+% becomes for instance 123::. This is one character more but in quite some
+% cases we had : after such a tag in the old situation. In the new situation
+% we create more namespaces and don't need that : any more, so we end up
+% with on the average the same amount of tokens and definitely less when
+% we consider cases like \??xx:\c!align: which now is just \??somealign and
+% therefore has length 5 now (instead of 4+1+5+1=10).
+%
+% Eventualy we will have a verbose \blablanamespace and the difference between
+% core and regular can go ... after all, \xxxparameter can already clash between
+% the two prefix groups .. if users use this mechanism a lot they should use
+% verbose names anyway (the old two character names were mostly an optimization
+% as they also expanded to these characters).
+
+% todo: register namespaces at lua end for logging and reverse resolve
+% todo: move this to syst-ini so that we can use it real early
+
+\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{\characters\c_mult_interfaces_n_of_namespaces>}
+
+\def\v_interfaces_prefix_template % consistently %03i>
+ {\ifnum\c_mult_interfaces_n_of_namespaces<\plusten00\else\ifnum\c_mult_interfaces_n_of_namespaces<\plushundred0\fi\fi
+ \number\c_mult_interfaces_n_of_namespaces>}
+
+\def\v_interfaces_prefix_template % consistently %03i>
+ {\number\c_mult_interfaces_n_of_namespaces>}
+
+\unexpanded\def\installnamespace#1% for modules and users
+ {\ifcsname ????#1\endcsname
+ \writestatus\m!system{duplicate user namespace '#1'}\wait
+ \else
+ \global\advance\c_mult_interfaces_n_of_namespaces\plusone
+ \expandafter\edef\csname ????#1\endcsname{\v_interfaces_prefix_template}%
+ \fi}
+
+\unexpanded\def\installcorenamespace#1%
+ {\ifcsname ??#1\endcsname
+ \writestatus\m!system{duplicate core namespace '#1'}\wait
+ \else
+ \global\advance\c_mult_interfaces_n_of_namespaces\plusone
+ \expandafter\edef\csname ??#1\endcsname{\v_interfaces_prefix_template}%
+ \ctxcommand{registernamespace(\number\c_mult_interfaces_n_of_namespaces,"#1")}%
+ \fi}
+
+% We install two core namespaces here, as we want nice error messages. Maybe
+% we will reserve the first 9.
+
+\installcorenamespace{fontinstanceready}
+\installcorenamespace{fontinstancebasic}
+\installcorenamespace{fontinstanceclass}
+
+% Maybe a \definecorenamespace[name][directparameter,directsetup][parent]
+% but we don't gain much. Actually we might just inline all definitions.
% \enabletrackers[interfaces.namespaces,context.flush]
%
@@ -240,11 +680,13 @@
% “\testparameter{text}”
%
% \stoptext
+%
+% This is a user (module) command:
\unexpanded\def\definenamespace
- {\dodoubleargument\dodefinenamespace}
+ {\dodoubleargument\mult_interfaces_define_name_space}
-\def\dodefinenamespace[#1][#2]% namespace settings
+\def\mult_interfaces_define_name_space[#1][#2]% namespace settings
{\ctxlua{interfaces.namespaces.define(\!!bs#1\!!es,\!!bs#2\!!es)}}
\def\listnamespaces
@@ -256,14 +698,29 @@
%D \showparentchain{@@am}{left}
%D \stoptyping
-\def\doshowparentchain#1%
+\unexpanded\def\showparentchain#1#2%
+ {\writestatus\m!system{chain: [ \mult_interfaces_show_parent_chain{#1#2}]}}
+
+\def\mult_interfaces_show_parent_chain#1%
{#1 => %
- \ifcsname#1\s!parent\endcsname
- \expandafter\doshowparentchain\csname#1\s!parent\endcsname
+ \ifcsname#1:\s!parent\endcsname
+ \expandafter\mult_interfaces_show_parent_chain\csname#1:\s!parent\endcsname
\fi}
-\def\showparentchain#1#2%
- {\writestatus\m!system{chain: [ \doshowparentchain{#1#2}]}}
+%D Conventions:
+%D
+%D \starttyping
+%D \newcount \c_class_whatever
+%D \newconditional \c_class_whatever
+%D \newconstant \c_class_whatever
+%D \newdimen \d_class_whatever
+%D \newskip \s_class_whatever
+%D \newmuskip \s_class_whatever
+%D \newbox \b_class_whatever
+%D \newtoks \t_class_whatever
+%D
+%D \edef\p_class_whatever{\classparameter\c!whatever}
+%D \edef\m_class_whatever{whatever}
+%D \stoptyping
\protect
-