diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/mult-aux.mkiv')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkiv/mult-aux.mkiv | 603 |
1 files changed, 315 insertions, 288 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/mult-aux.mkiv b/Master/texmf-dist/tex/context/base/mkiv/mult-aux.mkiv index 5e7de227096..99d252c6b67 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/mult-aux.mkiv +++ b/Master/texmf-dist/tex/context/base/mkiv/mult-aux.mkiv @@ -11,17 +11,9 @@ %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) - -% 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. - -% todo: doifelse<whatever> +%D A generalization of \MKIV-like inheritance. Just something to play with +%D (interface might change). The code here evolved in an email exchange between me +%D and Wolgang Schuster. \writestatus{loading}{ConTeXt Multilingual Macros / Helpers} @@ -29,9 +21,9 @@ \unprotect -\edef\??empty{\Uchar25} \letvalue{\Uchar25}\empty % cancel: dec:24 hex:18 +\edef\??empty{\Uchar25} \letvalue{\Uchar25}\empty % hex 19 -%edef\s!parent{\Uchar29} \letvalue{\Uchar29}\empty % + inlining is ugly, a tiny bit faster, but neglectable on a run +% \edef\s!parent{\Uchar29} % inlining is ugly, a tiny bit faster, but neglectable on a run %D \starttyping %D \unprotect @@ -76,15 +68,15 @@ % 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. +%D Start of experimental code: especially tables can have many assignments and +%D although most time is spent in the typesetting anyway, we can squeeze out a +%D little bit. Of course having 500 rows of 50 columns each with some setting does +%D not happen that often. One should keep in mind that in the average document +%D having some 500 assignments is no exception but there we're talking of +%D neglectable runtime for them. Of course in the definitions below there is no real +%D gain, only in the generated \setup* commands. Another situation with many +%D assignments is \XML\ where we can pass attributes and normally don't do testing +%D 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 @@ -101,7 +93,7 @@ \fi#2} \def\mult_interfaces_get_parameters_indeed#1]% namespace already set - {\mult_interfaces_get_parameters_item#1,],\_e_o_p_} + {\mult_interfaces_get_parameters_item#1,],^^^^0004} \def\mult_interfaces_get_parameters_item#1,#2% #2 takes space before , {\if,#1,% dirty trick for testing #1=empty @@ -109,7 +101,7 @@ \else\if]#1% \doubleexpandafter\gobbleoneargument \else - \mult_interfaces_get_parameters_assign#1==\empty\_e_o_p_ + \mult_interfaces_get_parameters_assign#1==\empty^^^^0004% % \doubleexpandafter\mult_interfaces_get_parameters_item % saves skipping when at end \fi\fi#2} @@ -120,7 +112,7 @@ \def\mult_interfaces_get_parameters_error_indeed#1#2% {\showassignerror{#2}{\the\inputlineno\space(#1)}} -\def\mult_interfaces_get_parameters_assign#1=#2=#3#4\_e_o_p_ +\def\mult_interfaces_get_parameters_assign#1=#2=#3#4^^^^0004% {\ifx\empty#1\empty \expandafter\mult_interfaces_get_parameters_error \else\ifx#3\empty @@ -143,7 +135,7 @@ \def\mult_interfaces_get_parameters_error_two#1\csname#2#3\endcsname#4% {\mult_interfaces_get_parameters_error_indeed{#2}{#3}} - \def\mult_interfaces_get_parameters_assign#1=#2=#3#4\_e_o_p_ + \def\mult_interfaces_get_parameters_assign#1=#2=#3#4^^^^0004% {\ifx\empty#1\empty \mult_interfaces_get_parameters_error_one \else\ifx#3\empty @@ -161,7 +153,7 @@ % \def\mult_interfaces_get_parameters_error_two#1\m_mult_interfaces_namespace#2\fi\fi% % {\mult_interfaces_get_parameters_error_indeed\m_mult_interfaces_namespace{#2}\m_mult_interfaces_namespace\s!dummy\fi\fi} % - % \def\mult_interfaces_get_parameters_assign#1=#2=#3#4\_e_o_p_ + % \def\mult_interfaces_get_parameters_assign#1=#2=#3#4^^^^0004% % {\expandafter\def\csname % \ifx\empty#1\empty % \mult_interfaces_get_parameters_error_one @@ -177,34 +169,45 @@ \newif\ifassignment -\def\mult_check_for_assignment_indeed#1=#2#3\_end_ - {\if#2@\assignmentfalse\else\assignmenttrue\fi} - -\def\mult_check_for_assignment_indeed_begin_#1=#2#3\_end_ - {\if#2@} +\def\mult_check_for_assignment_indeed#1=#2#3^^^^0004% + {\if#2^^^^0003\assignmentfalse\else\assignmenttrue\fi} +\def\mult_check_for_assignment_indeed_begin_#1=#2#3^^^^0004% + {\if#2^^^^0003} \def\mult_check_for_assignment#1% - {\expandafter\mult_check_for_assignment_indeed\detokenize{#1}=@@\_end_} + {\expandafter\mult_check_for_assignment_indeed\detokenize{#1}=^^^^0003^^^^0003^^^^0004} % End of experimental code. -\unexpanded\def\mult_interfaces_let #1#2{\expandafter\let \csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname} -\unexpanded\def\mult_interfaces_lete#1#2{\expandafter\let \csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname\empty} -\unexpanded\def\mult_interfaces_def #1#2{\expandafter\def \csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname} -\unexpanded\def\mult_interfaces_edef#1#2{\expandafter\edef\csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname} -\unexpanded\def\mult_interfaces_gdef#1#2{\expandafter\gdef\csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname} -\unexpanded\def\mult_interfaces_xdef#1#2{\expandafter\xdef\csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname} +%D This can give wrong results when we pass e.g. \type{\c!format}, so either we need +%D to use the \type {\k!} ones, but these are not defined in the english interface +%D so from now on we assume that the low level ones are used with the symbolic names +%D and that only the high level setup commands are used with language specific +%D interfaces. -\startinterface english +% \unexpanded\def\mult_interfaces_let #1#2{\expandafter\let \csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname} +% \unexpanded\def\mult_interfaces_lete#1#2{\expandafter\let \csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname\empty} +% \unexpanded\def\mult_interfaces_def #1#2{\expandafter\def \csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname} +% \unexpanded\def\mult_interfaces_edef#1#2{\expandafter\edef\csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname} +% \unexpanded\def\mult_interfaces_gdef#1#2{\expandafter\gdef\csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname} +% \unexpanded\def\mult_interfaces_xdef#1#2{\expandafter\xdef\csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname} +% \startinterface english \unexpanded\def\mult_interfaces_let #1#2{\expandafter \let\csname#1#2\endcsname} \unexpanded\def\mult_interfaces_lete#1#2{\expandafter \let\csname#1#2\endcsname\empty} \unexpanded\def\mult_interfaces_def #1#2{\expandafter \def\csname#1#2\endcsname} \unexpanded\def\mult_interfaces_edef#1#2{\expandafter\edef\csname#1#2\endcsname} \unexpanded\def\mult_interfaces_gdef#1#2{\expandafter\gdef\csname#1#2\endcsname} \unexpanded\def\mult_interfaces_xdef#1#2{\expandafter\xdef\csname#1#2\endcsname} +% \stopinterface + +%D Do, we only interface the assignment definition: + +\unexpanded\def\mult_interfaces_adef#1#2{\expandafter\def \csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname} +\startinterface english + \unexpanded\def\mult_interfaces_adef#1#2{\expandafter \def\csname#1#2\endcsname} \stopinterface % the commented detokenized variant that backtracks ... needs testing usage first @@ -217,21 +220,23 @@ % \def\currenttest{oeps} \edef\hans{\detokenizedtestparameter{reggab}}\meaning\hans\par % % slower: \def#3##1{\csname\ifcsname#1#2:##1\endcsname\expandafter\csstring\lastnamedcs\else\expandafter#5\csname#1#2:\s!parent\endcsname{##1}\fi\endcsname}% -% -% pre-expansion can be a bit faster but handly any effect on a normal run so let's go for -% saving some memory + +%D pre-expansion can be a bit faster but handly any effect on a normal run so let's +%D go for saving some memory \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% 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 +\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\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\??empty\else#4{##1}{##2}\fi}% is {} needed around ##1 ? - \def#5##1##2{\ifx##1\relax\??empty\else#4##1{##2}\fi}% is {} needed around ##1 ? + %\def#5##1##2{\ifx##1\relax\??empty\else#4##1{##2}\fi}% is {} needed around ##1 ? + \def#5##1##2{\ifx##1\relax^^^^0019\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{\begincsname#1#2:##1\endcsname}} + \def#8##1{\begincsname#1#2:##1\endcsname} + \def#9##1##2{\expandafter\let\expandafter##1\csname\ifcsname#1#2:##2\endcsname#1#2:##2\else\expandafter#5\csname#1#2:\s!parent\endcsname{##2}\fi\endcsname}} \unexpanded\def\installparameterhandler#1#2% {\normalexpanded @@ -243,7 +248,8 @@ \expandafter\noexpand\csname do#2parentparameter\endcsname % or : #2_parent_parameter \expandafter\noexpand\csname named#2parameter\endcsname \expandafter\noexpand\csname detokenized#2parameter\endcsname - \expandafter\noexpand\csname direct#2parameter\endcsname}} % strict#2parameter is gone + \expandafter\noexpand\csname direct#2parameter\endcsname + \expandafter\noexpand\csname letfrom#2parameter\endcsname}} % strict#2parameter is gone \unexpanded\def\mult_interfaces_install_root_parameter_handler#1#2#3% {\def#2##1{\detokenize\expandafter\expandafter\expandafter{\csname#1:##1\endcsname}}% always root @@ -281,28 +287,25 @@ \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. +%D In \MKIV\ we can probably use the english variant for all other languages too. % todo: inline the def/let -\unexpanded\def\mult_interfaces_install_parameter_set_handler#1#2#3#4#5#6% - {\ifx#2\relax\let#2\empty\fi - \unexpanded\def#3{\mult_interfaces_def {#1#2:}}% ##1 {##2} (braces are mandate) - \unexpanded\def#4{\mult_interfaces_edef{#1#2:}}% ##1 {##2} (braces are mandate) - \unexpanded\def#5{\mult_interfaces_let {#1#2:}}% ##1 ##2 - \unexpanded\def#6{\mult_interfaces_lete{#1#2:}}}% ##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{\mult_interfaces_def {#1#2:}}% ##1 {##2} (braces are mandate) +% \unexpanded\def#4{\mult_interfaces_edef{#1#2:}}% ##1 {##2} (braces are mandate) +% \unexpanded\def#5{\mult_interfaces_let {#1#2:}}% ##1 ##2 +% \unexpanded\def#6{\mult_interfaces_lete{#1#2:}}}% ##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 +% \stopinterface \unexpanded\def\installparametersethandler#1#2% {\normalexpanded @@ -357,44 +360,6 @@ \def\getparentchain #1#2{\begincsname#1#2:\s!chain\endcsname} \def\getcurrentparentchain#1#2{\begincsname#1#2:\s!chain\endcsname} -\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% - \unexpanded\def#5[##1][##2][##3]% [child][parent][settings] | [child][settings] | [child][parent] | [child] - {\let#9#4% - \edef#4{##1}% - \ifthirdargument - \the#6% predefine - \edef#8{##2}% - \mult_check_for_parent{#1}{#3}#4#8% - \expandafter\edef\csname#1#4:\s!chain\endcsname{\mult_interfaces_chain#1{##2}##1}% - \expandafter\edef\csname#1#4:\s!parent\endcsname{#1##2}% - \mult_interfaces_get_parameters{#1#4:}[##3]% - \else\ifsecondargument - \the#6% predefine - \expandafter\mult_check_for_assignment_indeed\detokenize{##2}=@@\_end_ - \ifassignment - \let#8\empty - \expandafter\edef\csname#1#4:\s!chain\endcsname{##1}% - \expandafter\edef\csname#1#4:\s!parent\endcsname{#3}% - \mult_interfaces_get_parameters{#1#4:}[##2]% - \else - \edef#8{##2}% - \mult_check_for_parent{#1}{#3}#4#8% - \expandafter\edef\csname#1#4:\s!chain\endcsname{\mult_interfaces_chain#1{##2}##1}% - \expandafter\edef\csname#1#4:\s!parent\endcsname{#1##2}% - \fi - \else - \the#6% predefine - \let#8\empty - \expandafter\edef\csname#1#4:\s!chain\endcsname{##1}% - \expandafter\edef\csname#1#4:\s!parent\endcsname{#3}% - \fi\fi - \the#7% - \let#4#9}} - % \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}% @@ -412,16 +377,17 @@ % \mult_interfaces_get_parameters{#1#4:}[##3]% % \else\ifsecondargument % \the#6% predefine -% \ifcondition\expandafter\mult_check_for_assignment_indeed_begin_\detokenize{##2}=@@\_end_ -% \edef#8{##2}% -% \mult_check_for_parent{#1}{#3}#4#8% -% \expandafter\edef\csname#1#4:\s!chain\endcsname{\mult_interfaces_chain#1{##2}##1}% -% \expandafter\edef\csname#1#4:\s!parent\endcsname{#1##2}% -% \else +% \expandafter\mult_check_for_assignment_indeed\detokenize{##2}=^^^^0003^^^^0003^^^^0004% +% \ifassignment % \let#8\empty % \expandafter\edef\csname#1#4:\s!chain\endcsname{##1}% % \expandafter\edef\csname#1#4:\s!parent\endcsname{#3}% % \mult_interfaces_get_parameters{#1#4:}[##2]% +% \else +% \edef#8{##2}% +% \mult_check_for_parent{#1}{#3}#4#8% +% \expandafter\edef\csname#1#4:\s!chain\endcsname{\mult_interfaces_chain#1{##2}##1}% +% \expandafter\edef\csname#1#4:\s!parent\endcsname{#1##2}% % \fi % \else % \the#6% predefine @@ -432,6 +398,43 @@ % \the#7% % \let#4#9}} +\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% + \unexpanded\def#5[##1][##2][##3]% [child][parent][settings] | [child][settings] | [child][parent] | [child] + {\let#9#4% + \edef#4{##1}% + \ifthirdargument + \the#6% predefine + \edef#8{##2}% + \mult_check_for_parent{#1}{#3}#4#8% + \expandafter\edef\csname#1#4:\s!chain\endcsname{\mult_interfaces_chain#1{##2}##1}% + \expandafter\edef\csname#1#4:\s!parent\endcsname{#1##2}% + \mult_interfaces_get_parameters{#1#4:}[##3]% + \else\ifsecondargument + \the#6% predefine + \ifcondition\expandafter\mult_check_for_assignment_indeed_begin_\detokenize{##2}=^^^^0003^^^^0003^^^^0004% + \edef#8{##2}% + \mult_check_for_parent{#1}{#3}#4#8% + \expandafter\edef\csname#1#4:\s!chain\endcsname{\mult_interfaces_chain#1{##2}##1}% + \expandafter\edef\csname#1#4:\s!parent\endcsname{#1##2}% + \else + \let#8\empty + \expandafter\edef\csname#1#4:\s!chain\endcsname{##1}% + \expandafter\edef\csname#1#4:\s!parent\endcsname{#3}% + \mult_interfaces_get_parameters{#1#4:}[##2]% + \fi + \else + \the#6% predefine + \let#8\empty + \expandafter\edef\csname#1#4:\s!chain\endcsname{##1}% + \expandafter\edef\csname#1#4:\s!parent\endcsname{#3}% + \fi\fi + \the#7% + \let#4#9}} + \unexpanded\def\installdefinehandler#1#2#3% {\normalexpanded {\mult_interfaces_install_define_handler @@ -490,55 +493,6 @@ \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 - \unexpanded\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}% - \expandafter\mult_check_for_assignment_indeed\detokenize{##1}=@@\_end_ - \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\mult_interfaces_install_switch_setup_handler_b#1#2#3#4#5#6#7#8#9% % {\newtoks#5% % \newconstant#2% @@ -558,14 +512,8 @@ % \let#3#7% % \else\iffirstargument % % \mult_check_for_assignment{##1}% -% \ifcondition\expandafter\mult_check_for_assignment_indeed_begin_\detokenize{##1}=@@\_end_ -% % \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 -% \else +% \expandafter\mult_check_for_assignment_indeed\detokenize{##1}=^^^^0003^^^^0003^^^^0004% +% \ifassignment % % \setuplayout[key=value] % \let#7#3% % \let#6#3% @@ -575,6 +523,13 @@ % \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 @@ -587,6 +542,54 @@ % #2\zerocount % mode is always zero at the end % \the#9}} +\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 + \unexpanded\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}% + \ifcondition\expandafter\mult_check_for_assignment_indeed_begin_\detokenize{##1}=^^^^0003^^^^0003^^^^0004% + % \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 + \else + % \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% + \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 @@ -685,14 +688,14 @@ \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 Many mechanisms have some kind of inheritance in place, and these are the +%D speed||critical ones. Therefore there is no reason to stick to \type {\@@xxkey} +%D for the sake of performance. For this reason we also provide a direct variant. +%D This permits a more consistent treatment of namespaces. A \type +%D {\whateverparameter} call is three times slower and a \type +%D {\directwhateverparameter} call two times but for some 100K expansions we only +%D loose some .1 second which is neglectable given the small amount of expansions in +%D real runs. %D We don't need colons for such simple cases. @@ -727,21 +730,19 @@ \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% - {\unexpanded\def#2{\mult_interfaces_def #1}% - \unexpanded\def#3{\mult_interfaces_edef#1}% - \unexpanded\def#4{\mult_interfaces_let #1}% - \unexpanded\def#5{\mult_interfaces_let #1\empty}}% - -\startinterface english +% \unexpanded\def\mult_interfaces_install_direct_parameter_set_handler#1#2#3#4#5% +% {\unexpanded\def#2{\mult_interfaces_def #1}% +% \unexpanded\def#3{\mult_interfaces_edef#1}% +% \unexpanded\def#4{\mult_interfaces_let #1}% +% \unexpanded\def#5{\mult_interfaces_let #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 +% \stopinterface \unexpanded\def\installdirectparametersethandler#1#2% {\normalexpanded @@ -804,6 +805,24 @@ \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 +% \doifelseassignment{##1} +% {\let#2\empty +% #3[##1]}% +% {\edef#2{##1}}% +% \else +% \let#2\empty +% \fi\fi +% \directsetup{handler:action:#1}% +% \endgroup}} + \unexpanded\def\mult_interfaces_install_action_handler#1#2#3#4% {\unexpanded\expandafter\def\csname#1\endcsname{\dodoubleempty#4}% \unexpanded\def#4[##1][##2]% @@ -812,10 +831,12 @@ \edef#2{##1}% #3[##2]% \else\iffirstargument - \doifelseassignment{##1} - {\let#2\empty - #3[##1]}% - {\edef#2{##1}}% + \ifcondition\expandafter\mult_check_for_assignment_indeed_begin_\detokenize{##1}=^^^^0003^^^^0003^^^^0004% + \edef#2{##1}% + \else + \let#2\empty + #3[##1]% + \fi \else \let#2\empty \fi\fi @@ -828,22 +849,21 @@ % \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). +% 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). +% 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 @@ -878,7 +898,7 @@ \fi} \def\mult_interfaces_get_parameters_error_indeed#1#2% - {\clf_showassignerror{#1}{#2}\inputlineno} % no longer \waitonfatalerror + {\clf_showassignerror{#1}{#2}\inputlineno} % We install two core namespaces here, as we want nice error messages. Maybe % we will reserve the first 9. @@ -916,8 +936,8 @@ \usedummystyleparameter \usedummycolorparameter -% Maybe a \definecorenamespace[name][directparameter,directsetup][parent] -% but we don't gain much. Actually we might just inline all definitions. +% 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] % @@ -1328,23 +1348,23 @@ \unexpanded\def\syst_helpers_install_macro_stack#1#2#3% {\xdef\m_syst_helpers_push_macro{\csstring#1}% - \expandafter\newcount\csname#3\m_syst_helpers_push_macro\endcsname - \expandafter\edef\csname push_macro_\m_syst_helpers_push_macro\endcsname - {\noexpand\expandafter\glet - \noexpand\csname\m_syst_helpers_push_macro\noexpand\the\csname#3\m_syst_helpers_push_macro\endcsname\endcsname - \noexpand#1% - \global\advance\csname#3\m_syst_helpers_push_macro\endcsname\plusone}% - \expandafter\edef\csname pop_macro_\m_syst_helpers_push_macro\endcsname - {\global\advance\csname#3\m_syst_helpers_push_macro\endcsname\minusone - \noexpand\expandafter#2% - \noexpand\expandafter\noexpand#1% - \noexpand\csname\m_syst_helpers_push_macro\noexpand\the\csname#3\m_syst_helpers_push_macro\endcsname\endcsname}} + \ifcsname#3\m_syst_helpers_push_macro\endcsname\else + \expandafter\newcount\csname#3\m_syst_helpers_push_macro\endcsname + \expandafter\edef\csname push_macro_\m_syst_helpers_push_macro\endcsname + {\noexpand\expandafter\glet + \noexpand\csname\m_syst_helpers_push_macro\noexpand\the\csname#3\m_syst_helpers_push_macro\endcsname\endcsname + \noexpand#1% + \global\advance\csname#3\m_syst_helpers_push_macro\endcsname\plusone}% + \expandafter\edef\csname pop_macro_\m_syst_helpers_push_macro\endcsname + {\global\advance\csname#3\m_syst_helpers_push_macro\endcsname\minusone + \noexpand\expandafter#2% + \noexpand\expandafter\noexpand#1% + \noexpand\csname\m_syst_helpers_push_macro\noexpand\the\csname#3\m_syst_helpers_push_macro\endcsname\endcsname}% + \fi} \unexpanded\def\installmacrostack #1{\syst_helpers_install_macro_stack#1\let \??localpushedmacro } \unexpanded\def\installglobalmacrostack#1{\syst_helpers_install_macro_stack#1\glet\??globalpushedmacro} -\protect - % \unprotect % % \installcorenamespace {test} \installcommandhandler \??test {test} \??test @@ -1366,87 +1386,94 @@ % % \starttext % \definetest[foo] \definetest[bar][foo] \setuptest[bar][before=indeed] -% \resettimer \dorecurse{100000}{\TestMeA[bar]} A:\elapsedtime \par % 0.502 -% \resettimer \dorecurse{100000}{\TestMeB[bar]} B:\elapsedtime \par % 0.530 -% \resettimer \dorecurse{100000}{\TestMeC[bar]} C:\elapsedtime \par % 0.487 -% \resettimer \dorecurse{100000}{\TestMeD[bar]} D:\elapsedtime \par % 0.493 +% \testfeatureonce{100000}{\TestMeA[bar]} A:\elapsedtime \par % 0.502 +% \testfeatureonce{100000}{\TestMeB[bar]} B:\elapsedtime \par % 0.530 +% \testfeatureonce{100000}{\TestMeC[bar]} C:\elapsedtime \par % 0.487 +% \testfeatureonce{100000}{\TestMeD[bar]} D:\elapsedtime \par % 0.493 % \stoptext -% There is no real demand for this ... even if this is twice as fast we only gain -% a few milliseconds: -% -% \unexpanded\def\foo#1{[foo:#1]} +% There is no real demand for this ... even if this is two to three times as fast we +% only gain a few milliseconds: % -% \installcommalistprocessor {foo} \foo -% \installcommalistprocessorcommand \processfoolist {foo} \foo +% \starttyping +% \unexpanded\def\foo#1{[foo:#1]} % -% \commalistprocessor{foo}[a,b,c,d] -% \processfoolist [a, b, c, d] +% \installcommalistprocessor {foo} \foo +% \installcommalistprocessorcommand \processfoolist \foo % -% \testfeatureonce{30000}{} \elapsedtime\par % 0.01 -> 0.00 -% \testfeatureonce{30000}{\processfoolist [fixed,middle]} \elapsedtime\par % 0.07 -> 0.06 -% \testfeatureonce{30000}{\commalistprocessor{foo}[fixed,middle]} \elapsedtime\par % 0.09 -> 0.08 -% \testfeatureonce{30000}{\processcommalist [fixed,middle]\foo} \elapsedtime\par % 0.13 -> 0.12 +% \infofont % -% For instance the luatex manual only has some 3000 calls. But I keep this around as one -% never knows when we might need it. +% \commalistprocessor{foo}[a,b,c,{x,y,z},d]\par +% \processfoolist[a, b, c, {x,y,z}, d]\par +% \processcommalist[{x,y,z}]\foo\blank % -% \installcorenamespace{commalistprocessor} -% \installcorenamespace{commalistprocessorcheck} -% \installcorenamespace{commalistprocessorwrap} -% \installcorenamespace{commalistprocessorfirst} -% \installcorenamespace{commalistprocessorcheckspace} -% \installcorenamespace{commalistprocessorcheckfinish} -% \installcorenamespace{commalistprocessoraction} -% \installcorenamespace{commalistprocessorgobblespace} +% \commalistprocessor{foo}[{x,y,z},a]\par +% \commalistprocessor{foo}[{x,y,z}]\par +% \processfoolist[{x,y,z},a]\par +% \processfoolist[{x,y,z}]\par +% \processcommalist[{x,y,z}]\foo\blank % -% \unexpanded\def\installcommalistprocessor#1#2% 7 macro names overhead -% {\let\nexttoken\relax -% % -% \unexpanded\expandafter\edef\csname\??commalistprocessor#1\endcsname[% -% {\futurelet\nexttoken\csname\??commalistprocessorcheck#1\endcsname}% -% % -% \unexpanded\expandafter\edef\csname\??commalistprocessorcheck#1\endcsname -% {\noexpand\ifx\nexttoken]% -% \noexpand\expandafter\noexpand\gobblethreearguments -% \noexpand\else -% \noexpand\expandafter\csname\??commalistprocessorwrap#1\endcsname -% \noexpand\fi -% \relax}% this one preserved the next {} -% % -% \unexpanded\expandafter\edef\csname\??commalistprocessorwrap#1\endcsname##1]% -% {\csname\??commalistprocessorfirst#1\endcsname##1,]\relax}% -% % -% \unexpanded\expandafter\edef\csname\??commalistprocessorfirst#1\endcsname##1% picks up \relax -% {\csname\??commalistprocessorcheckspace#1\endcsname}% -% % -% \unexpanded\expandafter\edef\csname\??commalistprocessorcheckspace#1\endcsname -% {\noexpand\ifx\nexttoken\noexpand\blankspace -% \noexpand\expandafter\csname\??commalistprocessorgobblespace#1\endcsname -% \noexpand\else -% \noexpand\expandafter\csname\??commalistprocessorcheckfinish#1\endcsname -% \noexpand\fi}% -% % -% \unexpanded\expandafter\edef\csname\??commalistprocessorcheckfinish#1\endcsname -% {\noexpand\ifx\nexttoken]% -% \noexpand\expandafter\noexpand\gobbleoneargument -% \noexpand\else -% \noexpand\expandafter\csname\??commalistprocessoraction#1\endcsname -% \noexpand\fi}% -% % -% \unexpanded\expandafter\edef\csname\??commalistprocessoraction#1\endcsname##1,% -% {\noexpand#2{##1}% -% \futurelet\nexttoken\csname\??commalistprocessorcheckspace#1\endcsname}% -% % -% \let\next\:% -% \unexpanded\edef \:{\csname\??commalistprocessorgobblespace#1\endcsname}% -% \unexpanded\expandafter\edef\: {\futurelet\nexttoken\csname\??commalistprocessorcheckspace#1\endcsname}% -% \let\:\next -% % -% } +% \unexpanded\def\foo#1{} % -% \unexpanded\def\installcommalistprocessorcommand#1#2#3% -% {\installcommalistprocessor{#2}{#3}% -% \expandafter\let\expandafter#1\csname\??commalistprocessor#2\endcsname} +% \testfeatureonce{400000}{\processfoolist [fixed,middle,bar]} \elapsedtime\quad +%%\testfeatureonce{400000}{\commalistprocessor{foo}[fixed,middle,bar]} \elapsedtime\quad +% \testfeatureonce{400000}{\processcommalist [fixed,middle,bar]\foo} \elapsedtime\quad +% \stoptyping % -% \unexpanded\def\commalistprocessor#1{\csname\??commalistprocessor#1\endcsname} +% For instance the luatex manual only has some 3000 calls. But I keep this around as one +% never knows when we might need it. + +\installcorenamespace{commalistprocessor} +\installcorenamespace{commalistprocessorwrap} +\installcorenamespace{commalistprocessorfirst} +\installcorenamespace{commalistprocessornext} +\installcorenamespace{commalistprocessoraction} + +\installcorenamespace{commalistprocessorcheck} +\installcorenamespace{commalistprocessorspace} +\installcorenamespace{commalistprocessorpickup} +\installcorenamespace{commalistprocessorfinish} + +\unexpanded\def\installcommalistprocessor#1#2% 8 macro names overhead + {\let\nexttoken\relax + \unexpanded\expandafter\edef\csname\??commalistprocessor#1\endcsname[% + {\futurelet\nexttoken\csname\??commalistprocessorcheck#1\endcsname}% + \unexpanded\expandafter\edef\csname\??commalistprocessorcheck#1\endcsname + {\noexpand\ifx\nexttoken]% + \noexpand\expandafter\noexpand\gobblethreearguments + \noexpand\else + \noexpand\expandafter\csname\??commalistprocessorwrap#1\endcsname + \noexpand\fi + \relax}% this one preserved the next {} + \unexpanded\expandafter\edef\csname\??commalistprocessorwrap#1\endcsname##1]% + {\csname\??commalistprocessorfirst#1\endcsname##1,]\relax}% + \unexpanded\expandafter\edef\csname\??commalistprocessorfirst#1\endcsname##1% picks up \relax + {\csname\??commalistprocessornext#1\endcsname}% + \unexpanded\expandafter\edef\csname\??commalistprocessornext#1\endcsname + {\noexpand\ifx\nexttoken\noexpand\blankspace + \noexpand\expandafter\csname\??commalistprocessorspace#1\endcsname + \noexpand\else + \noexpand\expandafter\csname\??commalistprocessorfinish#1\endcsname + \noexpand\fi}% + \unexpanded\expandafter\edef\csname\??commalistprocessorfinish#1\endcsname + {\noexpand\ifx\nexttoken]% + \noexpand\expandafter\noexpand\gobbleoneargument + \noexpand\else + \noexpand\expandafter\csname\??commalistprocessoraction#1\endcsname + \noexpand\fi}% + \unexpanded\expandafter\edef\csname\??commalistprocessoraction#1\endcsname##1,% + {\noexpand#2{##1}% + \futurelet\nexttoken\csname\??commalistprocessornext#1\endcsname}% + \let\next\:% + \unexpanded\edef \:{\csname\??commalistprocessorspace#1\endcsname}% + \unexpanded\expandafter\edef\: {\futurelet\nexttoken\csname\??commalistprocessornext#1\endcsname}% + \let\:\next} + +\unexpanded\def\installcommalistprocessorcommand#1#2% \processor \action + {\edef\p_name{\csstring#2}% + \installcommalistprocessor\p_name{#2}% + \expandafter\let\expandafter#1\csname\??commalistprocessor\p_name\endcsname} + +\unexpanded\def\commalistprocessor#1{\csname\??commalistprocessor#1\endcsname} + +\protect \endinput |