mult-aux.mkiv /size: 59 Kb    last modification: 2020-07-01 14:35
1
%D \module
2
%D [ file=mult-aux,
3
%D version=2010.08.2,
4
%D title=\CONTEXT\ Multilingual Macros,
5
%D subtitle=Helpers,
6
%D author=Hans Hagen,
7
%D date=\currentdate,
8
%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9
%C
10
%C This module is part of the \CONTEXT\ macro||package and is
11
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12
%C details.
13 14
%D A generalization of \MKIV-like inheritance. Just something to play with
15
%D (interface might change). The code here evolved in an email exchange between me
16
%D and Wolgang Schuster.
17 18
\writestatus
{
loading
}{
ConTeXt
Multilingual
Macros
/
Helpers
}
19 20
\registerctxluafile
{
mult
-
aux
}{}
21 22
\unprotect
23 24
\edef
\??empty
{
\Uchar
2
5
}
\letvalue
{
\Uchar
2
5
}
\empty
% hex 19
25 26
% \edef\s!parent{\Uchar29} % inlining  is ugly, a tiny bit faster, but neglectable on a run
27 28
%D \starttyping
29
%D \unprotect
30
%D \def\????aa{@@@@aa}
31
%D
32
%D \installparameterhandler \????aa {whatever}
33
%D \installsetuphandler \????aa {whatever}
34
%D \installdefinehandler \????aa {whatever} \????aa % #3 == defaultroot
35
%D \installfontandcolorhandler\????aa {whatever}
36
%D
37
%D % \installcommandhandler \????aa {whatever} \????aa
38
%D \protect
39
%D
40
%D % \whateverparameter \c!test
41
%D % \whateverparameterhash \c!test
42
%D % \namedwhateverparameter \mycurrentwhatever \c!test
43
%D % \usewhateverstyleandcolor \c!style \c!color
44
%D % \everydefinewhatever (sets \currentwhatever)
45
%D % \everypresetwhatever (can be used to reset parameters as we can redefine)
46
%D % \everysetupwhatever (sets \currentwhatever)
47
%D
48
%D \starttext
49
%D \definewhatever[first] \definewhatever[second][first]
50
%D test: \def\currentwhatever{first} \whateverparameter{method} \par
51
%D \setupwhatever [method=unset] test: \def\currentwhatever{first} \whateverparameter{method} \par
52
%D \setupwhatever[first] [method=first] test: \def\currentwhatever{first} \whateverparameter{method} \par
53
%D test: \def\currentwhatever{second} \whateverparameter{method} \par
54
%D \setupwhatever[second][method=second] test: \def\currentwhatever{second} \whateverparameter{method} \par
55
%D \stoptext
56
%D \stoptyping
57 58
% problem: every* could clash
59
%
60
% There can be less {} in the following definitions if we assume \??aa and \c!somecs
61
%
62
% todo: \def\detokenized...parameter#1{\detokenize\expandafter\expandafter\expandafter{\csname#1#2\endcsname}} % always root
63
%
64
% it might be more efficient to do this at the lua and
65
%
66
% watch the push/pop and predefinition of current .. this is needed for nested
67
% definitions and overloaded defines using the predefined one
68 69
% todo: add (relaxed) postsetup and postdefine hooks, just after the everys
70 71
%D Start of experimental code: especially tables can have many assignments and
72
%D although most time is spent in the typesetting anyway, we can squeeze out a
73
%D little bit. Of course having 500 rows of 50 columns each with some setting does
74
%D not happen that often. One should keep in mind that in the average document
75
%D having some 500 assignments is no exception but there we're talking of
76
%D neglectable runtime for them. Of course in the definitions below there is no real
77
%D gain, only in the generated \setup* commands. Another situation with many
78
%D assignments is \XML\ where we can pass attributes and normally don't do testing
79
%D of them making sense.
80
%
81
% \testfeatureonce{100000}{\getparameters[bla][a=111,b=222,c=333]}% 1.669s
82
% \testfeatureonce{100000}{\mult_interfaces_get_parameters{bla} [a=111,b=222,c=333]}% 1.529s
83
% \testfeatureonce{100000}{\def\m_mult_interfaces_namespace{bla}\mult_interfaces_get_parameters_indeed[a=111,b=222,c=333]}% 1.466s
84 85
\let
\m_mult_interfaces_namespace
\empty
86 87
\def
\mult_interfaces_get_parameters
#
1
[#
2
%
88
{
\if\noexpand
#
2
]
%
89
\expandafter
\gobbleoneargument
90
\else
91
\def
\m_mult_interfaces_namespace
{
#
1
}
%
92
\expandafter
\mult_interfaces_get_parameters_indeed
93
\fi
#
2
}
94 95
\def
\mult_interfaces_get_parameters_indeed
#
1
]
% namespace already set
96
{
\mult_interfaces_get_parameters_item
#
1
,
]
,
^^^^
0
0
0
4
}
97 98
\def
\mult_interfaces_get_parameters_item
#
1
,
#
2
% #2 takes space before ,
99
{
\if
,
#
1
,
% dirty trick for testing #1=empty
100
\expandafter
\mult_interfaces_get_parameters_item
101
\else\if
]#
1
%
102
\doubleexpandafter\gobbleoneargument
103
\else
104
\mult_interfaces_get_parameters_assign
#
1
==
\empty
^^^^
0
0
0
4
%
105
% \doubleexpandafter\mult_interfaces_get_parameters_item % saves skipping when at end
106
\fi\fi
#
2
}
107 108
\def
\mult_interfaces_get_parameters_error
#
1
#
2
% #3%
109
{
\mult_interfaces_get_parameters_error_indeed
{
#
1
}{
#
2
}
%
110
\gobbleoneargument
}
111 112
\def
\mult_interfaces_get_parameters_error_indeed
#
1
#
2
%
113
{
\showassignerror
{
#
2
}{
\the\inputlineno
\space
(#
1
)
}}
114 115
\def
\mult_interfaces_get_parameters_assign
#
1
=#
2
=#
3
#
4
^^^^
0
0
0
4
%
116
{
\ifx
\empty
#
1
\empty
117
\expandafter
\mult_interfaces_get_parameters_error
118
\else\ifx
#
3
\empty
119
\doubleexpandafter
\mult_interfaces_get_parameters_error
120
\else
121
\doubleexpandafter
\mult_interfaces_def
122
\fi\fi
123
\m_mult_interfaces_namespace
{
#
1
}{
#
2
}
%
124
\doubleexpandafter
\mult_interfaces_get_parameters_item
}
125 126
\startinterface
english
127 128
% some 10% faster
129 130
\let
\mult_interfaces_get_parameters_error
\undefined
131 132
\def
\mult_interfaces_get_parameters_error_one
#
1
\csname
#
2
#
3
\endcsname
#
4
%
133
{
\mult_interfaces_get_parameters_error_indeed
{
#
2
}{
#
3
}
\iftrue
}
134 135
\def
\mult_interfaces_get_parameters_error_two
#
1
\csname
#
2
#
3
\endcsname
#
4
%
136
{
\mult_interfaces_get_parameters_error_indeed
{
#
2
}{
#
3
}}
137 138
\def
\mult_interfaces_get_parameters_assign
#
1
=#
2
=#
3
#
4
^^^^
0
0
0
4
%
139
{
\ifx
\empty
#
1
\empty
140
\mult_interfaces_get_parameters_error_one
141
\else\ifx
#
3
\empty
142
\mult_interfaces_get_parameters_error_two
143
\else
144
\expandafter\def\csname
\m_mult_interfaces_namespace
#
1
\endcsname
{
#
2
}
%
145
\fi\fi
146
\doubleexpandafter
\mult_interfaces_get_parameters_item
}
147 148
% interesting but not faster
149
%
150
% \def\mult_interfaces_get_parameters_error_one#1\m_mult_interfaces_namespace#2\fi\fi%
151
% {\mult_interfaces_get_parameters_error_indeed\m_mult_interfaces_namespace{#2}\m_mult_interfaces_namespace\s!dummy\fi}
152
%
153
% \def\mult_interfaces_get_parameters_error_two#1\m_mult_interfaces_namespace#2\fi\fi%
154
% {\mult_interfaces_get_parameters_error_indeed\m_mult_interfaces_namespace{#2}\m_mult_interfaces_namespace\s!dummy\fi\fi}
155
%
156
% \def\mult_interfaces_get_parameters_assign#1=#2=#3#4^^^^0004%
157
% {\expandafter\def\csname
158
% \ifx\empty#1\empty
159
% \mult_interfaces_get_parameters_error_one
160
% \else\ifx#3\empty
161
% \mult_interfaces_get_parameters_error_two
162
% \else
163
% \m_mult_interfaces_namespace#1%
164
% \fi\fi
165
% \endcsname{#2}
166
% \doubleexpandafter\mult_interfaces_get_parameters_item}
167 168
\stopinterface
169 170
\newif
\ifassignment
171 172
\def
\mult_check_for_assignment_indeed
#
1
=#
2
#
3
^^^^
0
0
0
4
%
173
{
\if
#
2
^^^^
0
0
0
3
\assignmentfalse
\else
\assignmenttrue
\fi
}
174 175
\def
\mult_check_for_assignment_indeed_begin_
#
1
=#
2
#
3
^^^^
0
0
0
4
%
176
{
\if
#
2
^^^^
0
0
0
3
}
177 178
\def
\mult_check_for_assignment
#
1
%
179
{
\expandafter
\mult_check_for_assignment_indeed
\detokenize
{
#
1
}
=
^^^^
0
0
0
3
^^^^
0
0
0
3
^^^^
0
0
0
4
}
180 181
% End of experimental code.
182 183
%D This can give wrong results when we pass e.g. \type{\c!format}, so either we need
184
%D to use the \type {\k!} ones, but these are not defined in the english interface
185
%D so from now on we assume that the low level ones are used with the symbolic names
186
%D and that only the high level setup commands are used with language specific
187
%D interfaces.
188 189
% \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}
190
% \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}
191
% \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}
192
% \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}
193
% \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}
194
% \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}
195 196
% \startinterface english
197
\unexpanded
\def
\mult_interfaces_let
#
1
#
2
{
\expandafter
\let\csname
#
1
#
2
\endcsname
}
198
\unexpanded
\def
\mult_interfaces_lete
#
1
#
2
{
\expandafter
\let\csname
#
1
#
2
\endcsname
\empty
}
199
\unexpanded
\def
\mult_interfaces_def
#
1
#
2
{
\expandafter
\def\csname
#
1
#
2
\endcsname
}
200
\unexpanded
\def
\mult_interfaces_edef
#
1
#
2
{
\expandafter\edef\csname
#
1
#
2
\endcsname
}
201
\unexpanded
\def
\mult_interfaces_gdef
#
1
#
2
{
\expandafter\gdef\csname
#
1
#
2
\endcsname
}
202
\unexpanded
\def
\mult_interfaces_xdef
#
1
#
2
{
\expandafter\xdef\csname
#
1
#
2
\endcsname
}
203
% \stopinterface
204 205
%D Do, we only interface the assignment definition:
206 207
\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
}
208 209
\startinterface
english
210
\unexpanded
\def
\mult_interfaces_adef
#
1
#
2
{
\expandafter
\def\csname
#
1
#
2
\endcsname
}
211
\stopinterface
212 213
% the commented detokenized variant that backtracks ... needs testing usage first
214
%
215
% \let\whatever\relax
216
%
217
% \definetest[oeps][bagger=\whatever]
218
%
219
% \def\currenttest{oeps} \edef\hans{\detokenizedtestparameter{bagger}}\meaning\hans\par
220
% \def\currenttest{oeps} \edef\hans{\detokenizedtestparameter{reggab}}\meaning\hans\par
221
%
222
% 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}%
223 224
%D pre-expansion can be a bit faster but handly any effect on a normal run so let's
225
%D go for saving some memory
226 227
\def
\mult_interfaces_detokenize
{
\expandafter\expandafter\expandafter\detokenize\expandafter\expandafter\expandafter
}
228 229
\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)
230
{
\ifx
#
2
\relax\let
#
2
\empty
\fi
% it is hardly faster but produces less expansion tracing
231
\def
#
3
##
1
{
\csname\ifcsname
#
1
#
2
:
##
1
\endcsname
#
1
#
2
:
##
1
\else\expandafter
#
5
\csname
#
1
#
2
:
\s!parent
\endcsname
{
##
1
}
\fi\endcsname
}
%
232
\def
#
4
##
1
##
2
{
\ifcsname
##
1
:
##
2
\endcsname
##
1
:
##
2
\else\expandafter
#
5
\csname
##
1
:
\s!parent
\endcsname
{
##
2
}
\fi
}
%
233
%\def#5##1##2{\ifx##1\relax\??empty\else#4{##1}{##2}\fi}% is {} needed around ##1 ?
234
%\def#5##1##2{\ifx##1\relax\??empty\else#4##1{##2}\fi}% is {} needed around ##1 ?
235
\def
#
5
##
1
##
2
{
\ifx
##
1
\relax
^^^^
0
0
1
9
\else
#
4
##
1
{
##
2
}
\fi
}
% is {} needed around ##1 ?
236
\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
}
%
237
\def
#
7
##
1
{
\detokenize\expandafter\expandafter\expandafter
{
\csname
#
1
#
2
:
##
1
\endcsname
}}
% always root, no backtrack
238
\def
#
8
##
1
{
\begincsname
#
1
#
2
:
##
1
\endcsname
}
239
\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
}}
240 241
\unexpanded
\def
\installparameterhandler
#
1
#
2
%
242
{
\normalexpanded
243
{
\mult_interfaces_install_parameter_handler
244
{
\noexpand
#
1
}
% \??aa
245
\expandafter\noexpand\csname
current
#
2
\endcsname
246
\expandafter\noexpand\csname
#
2
parameter
\endcsname
247
\expandafter\noexpand\csname
do
#
2
parameter
\endcsname
% or : #2_parameter
248
\expandafter\noexpand\csname
do
#
2
parentparameter
\endcsname
% or : #2_parent_parameter
249
\expandafter\noexpand\csname
named
#
2
parameter
\endcsname
250
\expandafter\noexpand\csname
detokenized
#
2
parameter
\endcsname
251
\expandafter\noexpand\csname
direct
#
2
parameter
\endcsname
252
\expandafter\noexpand\csname
letfrom
#
2
parameter
\endcsname
}}
% strict#2parameter is gone
253 254
\unexpanded
\def
\mult_interfaces_install_root_parameter_handler
#
1
#
2
#
3
%
255
{
\def
#
2
##
1
{
\detokenize\expandafter\expandafter\expandafter
{
\csname
#
1
:
##
1
\endcsname
}}
% always root
256
\def
#
3
##
1
{
\begincsname
#
1
:
##
1
\endcsname
}}
257 258
\unexpanded
\def
\installrootparameterhandler
#
1
#
2
%
259
{
\normalexpanded
260
{
\mult_interfaces_install_root_parameter_handler
261
{
\noexpand
#
1
}
% \??aa
262
\expandafter\noexpand\csname
detokenizedroot
#
2
parameter
\endcsname
263
\expandafter\noexpand\csname
root
#
2
parameter
\endcsname
}}
264 265
\unexpanded
\def
\mult_interfaces_install_parameter_hash_handler
#
1
#
2
#
3
#
4
#
5
#
6
#
7
#
8
#
9
%
266
{
\ifx
#
2
\relax\let
#
2
\empty
\fi
267
\def
#
3
##
1
{
#
1
#
4
{
#
1
#
2
}{
##
1
}
:
}
% leading #1 was missing .. is this one used?
268
\def
#
4
##
1
##
2
{
\ifcsname
##
1
:
##
2
\endcsname
##
1
\else\expandafter
#
5
\csname
##
1
:
\s!parent
\endcsname
{
##
2
}
\fi
}
%
269
%\def#5##1##2{\ifx##1\relax\else#4{##1}{##2}\fi}%
270
\def
#
5
##
1
##
2
{
\ifx
##
1
\relax\else
#
4
##
1
{
##
2
}
\fi
}
%
271
\def
#
6
{
#
1
#
2
:
}
%
272
\def
#
7
##
1
{
#
1
##
1
:
}
%
273
\def
#
8
{
\ifx
#
2
\empty
\else\ifcsname
#
1
#
2
:
\s!parent
\endcsname\else\expandafter\let\csname
#
1
#
2
:
\s!parent
\endcsname
#
1
\fi\fi
}
%
274
\unexpanded
\def
#
9
##
1
{
\expandafter\edef\csname
#
1
##
1
:
\s!parent
\endcsname
{
#
1
#
2
}}}
275 276
\unexpanded
\def
\installparameterhashhandler
#
1
#
2
%
277
{
\expandafter\let\csname
#
2
namespace
\endcsname
#
1
%
278
\normalexpanded
279
{
\mult_interfaces_install_parameter_hash_handler
280
{
\noexpand
#
1
}
% \??aa
281
\expandafter\noexpand\csname
current
#
2
\endcsname
282
\expandafter\noexpand\csname
#
2
parameterhash
\endcsname
283
\expandafter\noexpand\csname
do
#
2
parameterhash
\endcsname
% or : #2_parameter_hash
284
\expandafter\noexpand\csname
do
#
2
parentparameterhash
\endcsname
% or : #2_parent_parameter_hash
285
\expandafter\noexpand\csname
current
#
2
hash
\endcsname
286
\expandafter\noexpand\csname
named
#
2
hash
\endcsname
287
\expandafter\noexpand\csname
check
#
2
parent
\endcsname
288
\expandafter\noexpand\csname
chaintocurrent
#
2
\endcsname
}}
289 290
%D In \MKIV\ we can probably use the english variant for all other languages too.
291 292
% todo: inline the def/let
293 294
% \unexpanded\def\mult_interfaces_install_parameter_set_handler#1#2#3#4#5#6%
295
% {\ifx#2\relax\let#2\empty\fi
296
% \unexpanded\def#3{\mult_interfaces_def {#1#2:}}% ##1 {##2} (braces are mandate)
297
% \unexpanded\def#4{\mult_interfaces_edef{#1#2:}}% ##1 {##2} (braces are mandate)
298
% \unexpanded\def#5{\mult_interfaces_let {#1#2:}}% ##1 ##2
299
% \unexpanded\def#6{\mult_interfaces_lete{#1#2:}}}% ##1
300
%
301
% \startinterface english
302
\unexpanded
\def
\mult_interfaces_install_parameter_set_handler
#
1
#
2
#
3
#
4
#
5
#
6
%
303
{
\ifx
#
2
\relax\let
#
2
\empty
\fi
304
\unexpanded
\def
#
3
##
1
{
\expandafter
\def\csname
#
1
#
2
:
##
1
\endcsname
}
% ##1 {##2} (braces are mandate)
305
\unexpanded
\def
#
4
##
1
{
\expandafter\edef\csname
#
1
#
2
:
##
1
\endcsname
}
% ##1 {##2} (braces are mandate)
306
\unexpanded
\def
#
5
##
1
{
\expandafter
\let\csname
#
1
#
2
:
##
1
\endcsname
}
% ##1 ##2
307
\unexpanded
\def
#
6
##
1
{
\expandafter
\let\csname
#
1
#
2
:
##
1
\endcsname
\empty
}}
% ##1
308
% \stopinterface
309 310
\unexpanded
\def
\installparametersethandler
#
1
#
2
%
311
{
\normalexpanded
312
{
\mult_interfaces_install_parameter_set_handler
313
{
\noexpand
#
1
}
% \??aa
314
\expandafter\noexpand\csname
current
#
2
\endcsname
315
\expandafter\noexpand\csname
set
#
2
parameter
\endcsname
316
\expandafter\noexpand\csname
setexpanded
#
2
parameter
\endcsname
317
\expandafter\noexpand\csname
let
#
2
parameter
\endcsname
318
\expandafter\noexpand\csname
reset
#
2
parameter
\endcsname
}}
319 320
\let
\dousecurrentstyleparameter
\relax
321
\let
\dousecurrentcolorparameter
\relax
322 323
\let
\currentstyleparameter
\empty
324
\let
\currentcolorparameter
\empty
325 326
\unexpanded
\def
\mult_interfaces_install_style_and_color_handler
#
1
#
2
#
3
#
4
%
327
{
\unexpanded
\def
#
2
##
1
##
2
% style color
328
{
\edef
\currentstyleparameter
{
#
1
{
##
1
}}
% this name is public (can also set color e.g. in underline)
329
\ifx
\currentstyleparameter
\empty
\else
\dousecurrentstyleparameter
\fi
330
\edef
\currentcolorparameter
{
#
1
{
##
2
}}
% this name is public (so we do this after the style switch)
331
\ifx
\currentcolorparameter
\empty
\else
\dousecurrentcolorparameter
\fi
}
%
332
\unexpanded
\def
#
3
##
1
% style
333
{
\edef
\currentstyleparameter
{
#
1
{
##
1
}}
% this name is public
334
\ifx
\currentstyleparameter
\empty
\else
\dousecurrentstyleparameter
\fi
}
%
335
\unexpanded
\def
#
4
##
1
% color
336
{
\edef
\currentcolorparameter
{
#
1
{
##
1
}}
% this name is public
337
\ifx
\currentcolorparameter
\empty
\else
\dousecurrentcolorparameter
\fi
}}
338 339
\unexpanded
\def
\installstyleandcolorhandler
#
1
#
2
%
340
{
\normalexpanded
341
{
\mult_interfaces_install_style_and_color_handler
342
\expandafter\noexpand\csname
#
2
parameter
\endcsname
343
\expandafter\noexpand\csname
use
#
2
styleandcolor
\endcsname
% maybe an alias use#2styleandcolorparameters
344
\expandafter\noexpand\csname
use
#
2
styleparameter
\endcsname
345
\expandafter\noexpand\csname
use
#
2
colorparameter
\endcsname
}}
346 347
\let
\definehandlerparent
\empty
348 349
\def
\mult_check_for_parent
#
1
#
2
#
3
#
4
%
350
{
\ifcsname
#
1
#
4
:
\s!parent
\endcsname
\else
\ifx
#
4
\empty
\else
351
\writestatus
\m!system
{
error
:
invalid
parent
#
4
for
#
3
,
#
4
defined
too
(
best
check
it
)
}
%
352
\expandafter\edef\csname
#
1
#
4
:
\s!parent
\endcsname
{
#
2
}
%
353
\fi
\fi
}
354 355
%def\mult_interfaces_chain#1#2{\ifcsname#1#2:\s!chain\endcsname\csname#1#2:\s!chain\endcsname\space\fi}
356
%def\getparentchain #1#2{\ifcsname#1#2:\s!chain\endcsname\csname#1#2:\s!chain\endcsname\fi}
357
%def\getcurrentparentchain#1#2{\ifcsname#1#2:\s!chain\endcsname\csname#1#2:\s!chain\endcsname\fi}
358 359
\def
\mult_interfaces_chain
#
1
#
2
{
\ifcsname
#
1
#
2
:
\s!chain
\endcsname\lastnamedcs
\space
\fi
}
360
\def
\getparentchain
#
1
#
2
{
\begincsname
#
1
#
2
:
\s!chain
\endcsname
}
361
\def
\getcurrentparentchain
#
1
#
2
{
\begincsname
#
1
#
2
:
\s!chain
\endcsname
}
362 363
% \unexpanded\def\mult_interfaces_install_define_handler#1#2#3#4#5#6#7#8#9% why is \expanded still needed in clones
364
% {\ifx#4\relax\let#4\empty\fi % see \defineregister
365
% \unexpanded\def#2{\dotripleempty#5}%
366
% \newtoks#6%
367
% \newtoks#7%
368
% \unexpanded\def#5[##1][##2][##3]% [child][parent][settings] | [child][settings] | [child][parent] | [child]
369
% {\let#9#4%
370
% \edef#4{##1}%
371
% \ifthirdargument
372
% \the#6% predefine
373
% \edef#8{##2}%
374
% \mult_check_for_parent{#1}{#3}#4#8%
375
% \expandafter\edef\csname#1#4:\s!chain\endcsname{\mult_interfaces_chain#1{##2}##1}%
376
% \expandafter\edef\csname#1#4:\s!parent\endcsname{#1##2}%
377
% \mult_interfaces_get_parameters{#1#4:}[##3]%
378
% \else\ifsecondargument
379
% \the#6% predefine
380
% \expandafter\mult_check_for_assignment_indeed\detokenize{##2}=^^^^0003^^^^0003^^^^0004%
381
% \ifassignment
382
% \let#8\empty
383
% \expandafter\edef\csname#1#4:\s!chain\endcsname{##1}%
384
% \expandafter\edef\csname#1#4:\s!parent\endcsname{#3}%
385
% \mult_interfaces_get_parameters{#1#4:}[##2]%
386
% \else
387
% \edef#8{##2}%
388
% \mult_check_for_parent{#1}{#3}#4#8%
389
% \expandafter\edef\csname#1#4:\s!chain\endcsname{\mult_interfaces_chain#1{##2}##1}%
390
% \expandafter\edef\csname#1#4:\s!parent\endcsname{#1##2}%
391
% \fi
392
% \else
393
% \the#6% predefine
394
% \let#8\empty
395
% \expandafter\edef\csname#1#4:\s!chain\endcsname{##1}%
396
% \expandafter\edef\csname#1#4:\s!parent\endcsname{#3}%
397
% \fi\fi
398
% \the#7%
399
% \let#4#9}}
400 401
\unexpanded
\def
\mult_interfaces_install_define_handler
#
1
#
2
#
3
#
4
#
5
#
6
#
7
#
8
#
9
% why is \expanded still needed in clones
402
{
\ifx
#
4
\relax\let
#
4
\empty
\fi
% see \defineregister
403
\unexpanded
\def
#
2
{
\dotripleempty
#
5
}
%
404
\newtoks
#
6
%
405
\newtoks
#
7
%
406
\unexpanded
\def
#
5
[##
1
][##
2
][##
3
]
% [child][parent][settings] | [child][settings] | [child][parent] | [child]
407
{
\let
#
9
#
4
%
408
\edef
#
4
{
##
1
}
%
409
\ifthirdargument
410
\the
#
6
% predefine
411
\edef
#
8
{
##
2
}
%
412
\mult_check_for_parent
{
#
1
}{
#
3
}
#
4
#
8
%
413
\expandafter\edef\csname
#
1
#
4
:
\s!chain
\endcsname
{
\mult_interfaces_chain
#
1
{
##
2
}
##
1
}
%
414
\expandafter\edef\csname
#
1
#
4
:
\s!parent
\endcsname
{
#
1
##
2
}
%
415
\mult_interfaces_get_parameters
{
#
1
#
4
:
}
[##
3
]
%
416
\else
\ifsecondargument
417
\the
#
6
% predefine
418
\ifcondition
\expandafter
\mult_check_for_assignment_indeed_begin_
\detokenize
{
##
2
}
=
^^^^
0
0
0
3
^^^^
0
0
0
3
^^^^
0
0
0
4
%
419
\edef
#
8
{
##
2
}
%
420
\mult_check_for_parent
{
#
1
}{
#
3
}
#
4
#
8
%
421
\expandafter\edef\csname
#
1
#
4
:
\s!chain
\endcsname
{
\mult_interfaces_chain
#
1
{
##
2
}
##
1
}
%
422
\expandafter\edef\csname
#
1
#
4
:
\s!parent
\endcsname
{
#
1
##
2
}
%
423
\else
424
\let
#
8
\empty
425
\expandafter\edef\csname
#
1
#
4
:
\s!chain
\endcsname
{
##
1
}
%
426
\expandafter\edef\csname
#
1
#
4
:
\s!parent
\endcsname
{
#
3
}
%
427
\mult_interfaces_get_parameters
{
#
1
#
4
:
}
[##
2
]
%
428
\fi
429
\else
430
\the
#
6
% predefine
431
\let
#
8
\empty
432
\expandafter\edef\csname
#
1
#
4
:
\s!chain
\endcsname
{
##
1
}
%
433
\expandafter\edef\csname
#
1
#
4
:
\s!parent
\endcsname
{
#
3
}
%
434
\fi\fi
435
\the
#
7
%
436
\let
#
4
#
9
}}
437 438
\unexpanded
\def
\installdefinehandler
#
1
#
2
#
3
%
439
{
\normalexpanded
440
{
\mult_interfaces_install_define_handler
441
{
\noexpand
#
1
}
% \??aa
442
\expandafter\noexpand\csname
define
#
2
\endcsname
443
{
\noexpand
#
3
}
% root
444
\expandafter\noexpand\csname
current
#
2
\endcsname
445
\expandafter\noexpand\csname
define
_
#
2
\endcsname
% semi-public
446
\expandafter\noexpand\csname
everypreset
#
2
\endcsname
447
\expandafter\noexpand\csname
everydefine
#
2
\endcsname
448
\expandafter\noexpand\csname
current
#
2
parent
\endcsname
449
\expandafter\noexpand\csname
saved
_
defined
_
#
2
\endcsname
}}
450 451
\unexpanded
\def
\mult_interfaces_install_setup_handler
#
1
#
2
#
3
#
4
#
5
#
6
#
7
#
8
#
9
%
452
{
\ifx
#
3
\relax\let
#
3
\empty
\fi
453
\unexpanded
\def
#
2
{
\dodoubleempty
#
4
}
%
454
\unexpanded
\def
#
6
{
\mult_interfaces_get_parameters
{
#
1
#
3
:
}}
% no every ! don't change it
455
\newtoks
#
5
%
456
\newtoks
#
8
%
457
\unexpanded
\def
#
4
[##
1
][##
2
]
% maybe helper
458
{
\let
#
7
#
3
%
459
\ifsecondargument
460
\def
#
9
####
1
% we will have a simple one as well
461
{
\edef
#
3
{
####
1
}
%
462
\mult_interfaces_get_parameters
{
#
1
#
3
:
}
[##
2
]
%
463
\the
#
5
}
%
464
\processcommalist
[##
1
]#
9
%
465
\else
466
\let
#
3
\empty
467
\mult_interfaces_get_parameters
{
#
1
:
}
[##
1
]
%
468
\the
#
5
%
469
\fi
470
\let
#
3
#
7
%
471
\the
#
8
}}
472 473
\unexpanded
\def
\installsetuphandler
#
1
#
2
%
474
{
\normalexpanded
475
{
\mult_interfaces_install_setup_handler
476
{
\noexpand
#
1
}
% \??aa
477
\expandafter\noexpand\csname
setup
#
2
\endcsname
478
\expandafter\noexpand\csname
current
#
2
\endcsname
479
\expandafter\noexpand\csname
setup
_
#
2
\endcsname
% semi-public
480
\expandafter\noexpand\csname
everysetup
#
2
\endcsname
481
\expandafter\noexpand\csname
setupcurrent
#
2
\endcsname
482
\expandafter\noexpand\csname
saved
_
setup
_
current
#
2
\endcsname
483
\expandafter\noexpand\csname
everysetup
#
2
root
\endcsname
484
\expandafter\noexpand\csname
nested
_
setup
_
current
#
2
\endcsname
}}
485 486
\let
\doingrootsetupnamed
\plusone
% \setuplayout[name][key=value]
487
\let
\doingrootsetuproot
\plustwo
% \setuplayout [key=value]
488
\let
\doingrootsetnamed
\plusthree
% \setuplayout[name]
489
\let
\doingrootsetroot
\plusfour
% \setuplayout
490 491
\unexpanded
\def
\mult_interfaces_install_switch_setup_handler_a
#
1
#
2
#
3
#
4
#
5
%
492
{
\ifx
#
3
\relax\let
#
3
\empty
\fi
493
\unexpanded
\def
#
2
{
\dodoubleempty
#
4
}
%
494
\unexpanded
\def
#
5
{
\mult_interfaces_get_parameters
{
#
1
#
3
:
}}}
495 496
% \unexpanded\def\mult_interfaces_install_switch_setup_handler_b#1#2#3#4#5#6#7#8#9%
497
% {\newtoks#5%
498
% \newconstant#2%
499
% \newtoks#8%
500
% \newtoks#9%
501
% \ifx#6\relax\let#6\empty\fi
502
% \unexpanded\def#4[##1][##2]% maybe helper
503
% {\ifsecondargument % no commalist here
504
% % \setuplayout[whatever][key=value]
505
% \let#7#3%
506
% \let#6#3%
507
% \edef#3{##1}%
508
% #2\doingrootsetupnamed
509
% \mult_interfaces_get_parameters{#1#3:}[##2]%
510
% \the#5%
511
% \ifx#3#6\the#8\fi % only switchsetups if previous == current
512
% \let#3#7%
513
% \else\iffirstargument
514
% % \mult_check_for_assignment{##1}%
515
% \expandafter\mult_check_for_assignment_indeed\detokenize{##1}=^^^^0003^^^^0003^^^^0004%
516
% \ifassignment
517
% % \setuplayout[key=value]
518
% \let#7#3%
519
% \let#6#3%
520
% \let#3\empty
521
% #2\doingrootsetuproot
522
% \mult_interfaces_get_parameters{#1:}[##1]%
523
% \the#5%
524
% \the#8% switchsetups
525
% \let#3#7%
526
% \else
527
% % \setuplayout[whatever]
528
% \let#6#3% % previous becomes current
529
% \edef#3{##1}% this will catch reset so one needs to test for it
530
% #2\doingrootsetnamed
531
% \the#5% % we can check for previous vs current
532
% \the#8% switchsetups
533
% \fi
534
% \else
535
% % \setuplayout
536
% \let#6#3% % previous becomes current
537
% \let#3\empty % current becomes empty
538
% #2\doingrootsetroot
539
% \the#5%
540
% \the#8% switchsetups
541
% \fi\fi
542
% #2\zerocount % mode is always zero at the end
543
% \the#9}}
544 545
\unexpanded
\def
\mult_interfaces_install_switch_setup_handler_b
#
1
#
2
#
3
#
4
#
5
#
6
#
7
#
8
#
9
%
546
{
\newtoks
#
5
%
547
\newconstant
#
2
%
548
\newtoks
#
8
%
549
\newtoks
#
9
%
550
\ifx
#
6
\relax\let
#
6
\empty
\fi
551
\unexpanded
\def
#
4
[##
1
][##
2
]
% maybe helper
552
{
\ifsecondargument
% no commalist here
553
% \setuplayout[whatever][key=value]
554
\let
#
7
#
3
%
555
\let
#
6
#
3
%
556
\edef
#
3
{
##
1
}
%
557
#
2
\doingrootsetupnamed
558
\mult_interfaces_get_parameters
{
#
1
#
3
:
}
[##
2
]
%
559
\the
#
5
%
560
\ifx
#
3
#
6
\the
#
8
\fi
% only switchsetups if previous == current
561
\let
#
3
#
7
%
562
\else
\iffirstargument
563
% \mult_check_for_assignment{##1}%
564
\ifcondition
\expandafter
\mult_check_for_assignment_indeed_begin_
\detokenize
{
##
1
}
=
^^^^
0
0
0
3
^^^^
0
0
0
3
^^^^
0
0
0
4
%
565
% \setuplayout[whatever]
566
\let
#
6
#
3
% % previous becomes current
567
\edef
#
3
{
##
1
}
% this will catch reset so one needs to test for it
568
#
2
\doingrootsetnamed
569
\the
#
5
% % we can check for previous vs current
570
\the
#
8
% switchsetups
571
\else
572
% \setuplayout[key=value]
573
\let
#
7
#
3
%
574
\let
#
6
#
3
%
575
\let
#
3
\empty
576
#
2
\doingrootsetuproot
577
\mult_interfaces_get_parameters
{
#
1
:
}
[##
1
]
%
578
\the
#
5
%
579
\the
#
8
% switchsetups
580
\let
#
3
#
7
%
581
\fi
582
\else
583
% \setuplayout
584
\let
#
6
#
3
% % previous becomes current
585
\let
#
3
\empty
% current becomes empty
586
#
2
\doingrootsetroot
587
\the
#
5
%
588
\the
#
8
% switchsetups
589
\fi\fi
590
#
2
\zerocount
% mode is always zero at the end
591
\the
#
9
}}
592 593
\unexpanded
\def
\installswitchsetuphandler
#
1
#
2
%
594
{
\normalexpanded
595
{
\mult_interfaces_install_switch_setup_handler_a
596
{
\noexpand
#
1
}
% \??aa
597
\expandafter\noexpand\csname
setup
#
2
\endcsname
598
\expandafter\noexpand\csname
current
#
2
\endcsname
599
\expandafter\noexpand\csname
setup
_
#
2
\endcsname
% semi-public
600
\expandafter\noexpand\csname
setupcurrent
#
2
\endcsname
601
\mult_interfaces_install_switch_setup_handler_b
602
{
\noexpand
#
1
}
% \??aa
603
\expandafter\noexpand\csname
#
2
setupmode
\endcsname
604
\expandafter\noexpand\csname
current
#
2
\endcsname
605
\expandafter\noexpand\csname
setup
_
#
2
\endcsname
% semi-public
606
\expandafter\noexpand\csname
everysetup
#
2
\endcsname
607
\expandafter\noexpand\csname
previous
#
2
\endcsname
608
\expandafter\noexpand\csname
saved
_
setup
_
current
#
2
\endcsname
609
\expandafter\noexpand\csname
everyswitch
#
2
\endcsname
610
\expandafter\noexpand\csname
everysetup
#
2
root
\endcsname
}}
611 612
\unexpanded
\def
\mult_interfaces_install_auto_setup_handler
#
1
#
2
#
3
#
4
#
5
#
6
#
7
#
8
#
9
%
613
{
\ifx
#
3
\relax\let
#
3
\empty
\fi
614
\unexpanded
\def
#
2
{
\dotripleempty
#
4
}
%
615
\unexpanded
\def
#
6
{
\mult_interfaces_get_parameters
{
#
1
#
3
:
}}
%
616
\newtoks
#
5
%
617
\def
#
4
[##
1
][##
2
][##
3
]
%
618
{
\let
#
8
#
3
%
619
\ifthirdargument
620
\def
#
9
####
1
%
621
{
\edef
#
3
{
####
1
}
%
622
\expandafter\def\csname
#
1
#
3
:
\s!parent
\endcsname
{
#
1
##
2
}
%
623
\mult_interfaces_get_parameters
{
#
1
#
3
:
}
[##
3
]
% always sets parent
624
\the
#
5
}
%
625
\processcommalist
[##
1
]#
9
%
626
\else
\ifsecondargument
627
\def
#
9
####
1
%
628
{
\edef
#
3
{
####
1
}
%
629
#
7
% checks parent and sets if needed
630
\mult_interfaces_get_parameters
{
#
1
#
3
:
}
[##
2
]
%
631
\the
#
5
}
%
632
\processcommalist
[##
1
]#
9
%
633
\else
634
\let
#
3
\empty
635
\mult_interfaces_get_parameters
{
#
1
:
}
[##
1
]
%
636
\the
#
5
%
637
\fi\fi
638
\let
#
3
#
8
}}
639 640
\unexpanded
\def
\installautosetuphandler
#
1
#
2
%
641
{
\normalexpanded
642
{
\mult_interfaces_install_auto_setup_handler
643
{
\noexpand
#
1
}
% \??aa
644
\expandafter\noexpand\csname
setup
#
2
\endcsname
645
\expandafter\noexpand\csname
current
#
2
\endcsname
646
\expandafter\noexpand\csname
setup
_
#
2
\endcsname
% semi-public
647
\expandafter\noexpand\csname
everysetup
#
2
\endcsname
648
\expandafter\noexpand\csname
setupcurrent
#
2
\endcsname
649
\expandafter\noexpand\csname
check
#
2
parent
\endcsname
650
\expandafter\noexpand\csname
saved
_
setup
_
current
#
2
\endcsname
651
\expandafter\noexpand\csname
nested
_
setup
_
current
#
2
\endcsname
}}
652 653
\unexpanded
\def
\installbasicparameterhandler
#
1
#
2
%
654
{
\installparameterhandler
{
#
1
}{
#
2
}
%
655
\installparameterhashhandler
{
#
1
}{
#
2
}
%
656
\installparametersethandler
{
#
1
}{
#
2
}
%
657
\installrootparameterhandler
{
#
1
}{
#
2
}}
658 659
\unexpanded
\def
\installbasicautosetuphandler
#
1
#
2
#
3
% \??self name \??parent (can be \??self)
660
{
\installbasicparameterhandler
{
#
1
}{
#
2
}
%
661
\installautosetuphandler
{
#
1
}{
#
2
}}
662 663
\unexpanded
\def
\installstylisticautosetuphandler
#
1
#
2
#
3
% \??self name \??parent (can be \??self)
664
{
\installbasicparameterhandler
{
#
1
}{
#
2
}
%
665
\installautosetuphandler
{
#
1
}{
#
2
}
%
666
\installstyleandcolorhandler
{
#
1
}{
#
2
}}
667 668
\unexpanded
\def
\installcommandhandler
#
1
#
2
#
3
% \??self name \??parent (can be \??self)
669
{
\installbasicparameterhandler
{
#
1
}{
#
2
}
%
670
\installdefinehandler
{
#
1
}{
#
2
}{
#
3
}
%
671
\installsetuphandler
{
#
1
}{
#
2
}
%
672
\installstyleandcolorhandler
{
#
1
}{
#
2
}}
673 674
\unexpanded
\def
\installswitchcommandhandler
#
1
#
2
#
3
% \??self name \??parent (can be \??self)
675
{
\installbasicparameterhandler
{
#
1
}{
#
2
}
%
676
\installdefinehandler
{
#
1
}{
#
2
}{
#
3
}
%
677
\installswitchsetuphandler
{
#
1
}{
#
2
}
%
678
\installstyleandcolorhandler
{
#
1
}{
#
2
}}
679 680
\unexpanded
\def
\installautocommandhandler
#
1
#
2
#
3
% automatically defined cloned setups
681
{
\installbasicparameterhandler
{
#
1
}{
#
2
}
%
682
\installdefinehandler
{
#
1
}{
#
2
}{
#
3
}
%
683
\installautosetuphandler
{
#
1
}{
#
2
}
%
684
\installstyleandcolorhandler
{
#
1
}{
#
2
}}
685 686
\unexpanded
\def
\installsimplecommandhandler
#
1
#
2
#
3
% no define (experiment) - use \check*parent when defining
687
{
\installbasicparameterhandler
{
#
1
}{
#
2
}
%
688
\installsetuphandler
{
#
1
}{
#
2
}
%
689
\installstyleandcolorhandler
{
#
1
}{
#
2
}}
690 691
%D Many mechanisms have some kind of inheritance in place, and these are the
692
%D speed||critical ones. Therefore there is no reason to stick to \type {\@@xxkey}
693
%D for the sake of performance. For this reason we also provide a direct variant.
694
%D This permits a more consistent treatment of namespaces. A \type
695
%D {\whateverparameter} call is three times slower and a \type
696
%D {\directwhateverparameter} call two times but for some 100K expansions we only
697
%D loose some .1 second which is neglectable given the small amount of expansions in
698
%D real runs.
699 700
%D We don't need colons for such simple cases.
701 702
\unexpanded
\def
\mult_interfaces_install_direct_parameter_handler
#
1
#
2
#
3
#
4
#
5
%
703
%%{\def#3##1{\csname\ifcsname#1##1\endcsname#1##1\else\s!empty\fi\endcsname}%
704
{
\def
#
3
##
1
{
\begincsname
#
1
##
1
\endcsname
}
%
705
\def
#
4
##
1
{
\detokenize\expandafter\expandafter\expandafter
{
\csname
#
1
##
1
\endcsname
}}
%
706
% \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}}%
707
\def
#
5
##
1
{
\begincsname
#
1
##
1
\endcsname
}}
708 709
\unexpanded
\def
\installdirectparameterhandler
#
1
#
2
%
710
{
\normalexpanded
711
{
\mult_interfaces_install_direct_parameter_handler
712
{
\noexpand
#
1
}
%
713
\expandafter\noexpand\csname
current
#
2
\endcsname
714
\expandafter\noexpand\csname
#
2
parameter
\endcsname
715
\expandafter\noexpand\csname
detokenized
#
2
parameter
\endcsname
716
\expandafter\noexpand\csname
direct
#
2
parameter
\endcsname
}}
717 718
\unexpanded
\def
\mult_interfaces_install_direct_setup_handler
#
1
#
2
#
3
#
4
#
5
%
719
{
\unexpanded
\def
#
2
{
\dosingleempty
#
3
}
%
720
\newtoks
#
5
%
721
\def
#
3
[##
1
]
{
\mult_interfaces_get_parameters
#
1
[##
1
]
\the
#
5
}
%
722
\def
#
4
{
\mult_interfaces_get_parameters
#
1
}}
723 724
\unexpanded
\def
\installdirectsetuphandler
#
1
#
2
%
725
{
\normalexpanded
726
{
\mult_interfaces_install_direct_setup_handler
727
{
\noexpand
#
1
}
% \??aa
728
\expandafter\noexpand\csname
setup
#
2
\endcsname
729
\expandafter\noexpand\csname
setup
_
#
2
\endcsname
% semi-public
730
\expandafter\noexpand\csname
setupcurrent
#
2
\endcsname
% no \every (we use 'current' for consistency)
731
\expandafter\noexpand\csname
everysetup
#
2
\endcsname
}}
732 733
% \unexpanded\def\mult_interfaces_install_direct_parameter_set_handler#1#2#3#4#5%
734
% {\unexpanded\def#2{\mult_interfaces_def #1}%
735
% \unexpanded\def#3{\mult_interfaces_edef#1}%
736
% \unexpanded\def#4{\mult_interfaces_let #1}%
737
% \unexpanded\def#5{\mult_interfaces_let #1\empty}}%
738 739
% \startinterface english
740
\unexpanded
\def
\mult_interfaces_install_direct_parameter_set_handler
#
1
#
2
#
3
#
4
#
5
%
741
{
\unexpanded
\def
#
2
##
1
{
\expandafter
\def\csname
#
1
##
1
\endcsname
}
%
742
\unexpanded
\def
#
3
##
1
{
\expandafter\edef\csname
#
1
##
1
\endcsname
}
%
743
\unexpanded
\def
#
4
##
1
{
\expandafter
\let\csname
#
1
##
1
\endcsname
}
%
744
\unexpanded
\def
#
5
##
1
{
\expandafter
\let\csname
#
1
##
1
\endcsname
\empty
}}
%
745
% \stopinterface
746 747
\unexpanded
\def
\installdirectparametersethandler
#
1
#
2
%
748
{
\normalexpanded
749
{
\mult_interfaces_install_direct_parameter_set_handler
750
{
\noexpand
#
1
}
% \??aa
751
\expandafter\noexpand\csname
set
#
2
parameter
\endcsname
752
\expandafter\noexpand\csname
setexpanded
#
2
parameter
\endcsname
753
\expandafter\noexpand\csname
let
#
2
parameter
\endcsname
754
\expandafter\noexpand\csname
reset
#
2
parameter
\endcsname
}}
755 756
\let
\installdirectstyleandcolorhandler\installstyleandcolorhandler
757 758
\unexpanded
\def
\installdirectcommandhandler
#
1
#
2
%
759
{
\installdirectparameterhandler
{
#
1
}{
#
2
}
%
760
\installdirectsetuphandler
{
#
1
}{
#
2
}
%
761
\installdirectparametersethandler
{
#
1
}{
#
2
}
%
762
\installdirectstyleandcolorhandler
{
#
1
}{
#
2
}}
763 764
\unexpanded
\def
\installsetuponlycommandhandler
#
1
#
2
%
765
{
\installdirectparameterhandler
{
#
1
}{
#
2
}
%
766
\installdirectsetuphandler
{
#
1
}{
#
2
}
%
767
}
% maybe \installdirectparametersethandler {#1}{#2}%
768 769
% Experiment:
770 771
% \installcorenamespace {one}
772
% \installcorenamespace {two}
773
%
774
% \installcommandhandler \??one {one} \??one
775
% \installcommandhandler \??two {two} \??two
776
%
777
% \defineone[test] \setupone[test][alpha=first]
778
% \definetwo[test] \setuptwo[test][beta=second]
779
%
780
% \protect
781
%
782
% \def\currentone{test}
783
% \def\currenttwo{test}
784
%
785
% \relateparameterhandlers {two} {test} {one} {test}
786
%
787
% yes:\oneparameter{alpha}\par
788
% nop:\oneparameter{beta}\par
789
% yes:\twoparameter{alpha}\par
790
% yes:\twoparameter{beta}\par
791 792
\unexpanded
\def
\relateparameterhandlers
#
1
#
2
#
3
#
4
% {from} {instance} {to} {instance}
793
{
\expandafter\edef\csname\csname
#
1
namespace
\endcsname
#
2
:
\s!parent
\endcsname
{
\csname
#
3
namespace
\endcsname
#
4
}}
794 795
\unexpanded
\def
\relateparameterhandlersbyns
#
1
#
2
#
3
#
4
% {from} {instance} {to} {instance}
796
{
\expandafter\edef\csname
#
1
#
2
:
\s!parent
\endcsname
{
#
3
#
4
}}
797 798
%D Here is another experiment:
799 800
\unexpanded
\def
\installactionhandler
#
1
%
801
{
\normalexpanded
802
{
\mult_interfaces_install_action_handler
803
{
#
1
}
%
804
\expandafter\noexpand\csname
current
#
1
\endcsname
805
\expandafter\noexpand\csname
setupcurrent
#
1
\endcsname
806
\expandafter\noexpand\csname
#
1
_
action
\endcsname
}}
807 808
% \unexpanded\def\mult_interfaces_install_action_handler#1#2#3#4%
809
% {\unexpanded\expandafter\def\csname#1\endcsname{\dodoubleempty#4}%
810
% \unexpanded\def#4[##1][##2]%
811
% {\begingroup
812
% \ifsecondargument
813
% \edef#2{##1}%
814
% #3[##2]%
815
% \else\iffirstargument
816
% \doifelseassignment{##1}
817
% {\let#2\empty
818
% #3[##1]}%
819
% {\edef#2{##1}}%
820
% \else
821
% \let#2\empty
822
% \fi\fi
823
% \directsetup{handler:action:#1}%
824
% \endgroup}}
825 826
\unexpanded
\def
\mult_interfaces_install_action_handler
#
1
#
2
#
3
#
4
%
827
{
\unexpanded
\expandafter\def\csname
#
1
\endcsname
{
\dodoubleempty
#
4
}
%
828
\unexpanded
\def
#
4
[##
1
][##
2
]
%
829
{
\begingroup
830
\ifsecondargument
831
\edef
#
2
{
##
1
}
%
832
#
3
[##
2
]
%
833
\else
\iffirstargument
834
\ifcondition
\expandafter
\mult_check_for_assignment_indeed_begin_
\detokenize
{
##
1
}
=
^^^^
0
0
0
3
^^^^
0
0
0
3
^^^^
0
0
0
4
%
835
\edef
#
2
{
##
1
}
%
836
\else
837
\let
#
2
\empty
838
#
3
[##
1
]
%
839
\fi
840
\else
841
\let
#
2
\empty
842
\fi\fi
843
\directsetup
{
handler
:
action
:
#
1
}
%
844
\endgroup
}}
845 846
% First we had, in tune with the regular system variables:
847
%
848
% \starttyping
849
% \unexpanded\def\installnamespace#1{\setvalue{????#1}{@@@@#1}}
850
% \stoptyping
851
%
852
% The following variant is nicer and in principle faster but that gets unnoticed
853
% unless lots of expansion happens. Also, we can use long tags but the internal
854
% expansion will be relatively small (and unlikely more than 4 characters). For
855
% instance, \??xx used to expand to @@xx but now becomes for instance 123::. This
856
% is one character more but in quite some cases we had : after such a tag in the
857
% old situation. In the new situation we create more namespaces and don't need that
858
% : any more, so we end up with on the average the same amount of tokens and
859
% definitely less when we consider cases like \??xx:\c!align: which now is just
860
% \??somealign and therefore has length 5 now (instead of 4+1+5+1=10).
861
%
862
% Eventualy we will have a verbose \blablanamespace and the difference between core
863
% and regular can go ... after all, \xxxparameter can already clash between the two
864
% prefix groups .. if users use this mechanism a lot they should use verbose names
865
% anyway (the old two character names were mostly an optimization as they also
866
% expanded to these characters).
867 868
% todo: register namespaces at lua end for logging and reverse resolve
869
% todo: move this to syst-ini so that we can use it real early
870 871
\newcount
\c_mult_interfaces_n_of_namespaces
872 873
%def\v_interfaces_prefix_template{\number \c_mult_interfaces_n_of_namespaces>}
874
%def\v_interfaces_prefix_template{\characters\c_mult_interfaces_n_of_namespaces>}
875 876
%def\v_interfaces_prefix_template % consistently %03i>
877
% {\ifnum\c_mult_interfaces_n_of_namespaces<\plusten00\else\ifnum\c_mult_interfaces_n_of_namespaces<\plushundred0\fi\fi
878
% \number\c_mult_interfaces_n_of_namespaces>}
879 880
\def
\v_interfaces_prefix_template
881
{
\number
\c_mult_interfaces_n_of_namespaces
>
}
882 883
\unexpanded
\def
\installnamespace
#
1
% for modules and users
884
{
\ifcsname
?
?
?
?
#
1
\endcsname
885
\writestatus
\m!system
{
duplicate
user
namespace
'
#
1
'
}
\wait
886
\else
887
\global\advance
\c_mult_interfaces_n_of_namespaces
\plusone
888
\expandafter\edef\csname
?
?
?
?
#
1
\endcsname
{
\v_interfaces_prefix_template
}
%
889
\fi
}
890 891
\unexpanded
\def
\installcorenamespace
#
1
%
892
{
\ifcsname
?
?
#
1
\endcsname
893
\writestatus
\m!system
{
duplicate
core
namespace
'
#
1
'
}
\wait
894
\else
895
\global\advance
\c_mult_interfaces_n_of_namespaces
\plusone
896
\expandafter\edef\csname
?
?
#
1
\endcsname
{
\v_interfaces_prefix_template
}
%
897
\clf_registernamespace
\c_mult_interfaces_n_of_namespaces
{
#
1
}
%
898
\fi
}
899 900
\def
\mult_interfaces_get_parameters_error_indeed
#
1
#
2
%
901
{
\clf_showassignerror
{
#
1
}{
#
2
}
\inputlineno
}
902 903
% We install two core namespaces here, as we want nice error messages. Maybe
904
% we will reserve the first 9.
905 906
\installcorenamespace
{
fontinstanceready
}
907
\installcorenamespace
{
fontinstancebasic
}
908
\installcorenamespace
{
fontinstanceclass
}
909 910
%D The next one is handy for local assignments.
911 912
\installcorenamespace
{
dummy
}
913 914
\letvalue
\??dummy
\empty
915 916
\def
\dummyparameter
#
1
{
\begincsname
\??dummy
#
1
\endcsname
}
917
\def
\directdummyparameter
#
1
{
\begincsname
\??dummy
#
1
\endcsname
}
918
\unexpanded
\def
\setdummyparameter
#
1
{
\expandafter\def\csname
\??dummy
#
1
\endcsname
}
919
\unexpanded
\def
\setexpandeddummyparameter
#
1
{
\expandafter\edef\csname
\??dummy
#
1
\endcsname
}
920
\unexpanded
\def
\letdummyparameter
#
1
{
\expandafter\let\csname
\??dummy
#
1
\endcsname
}
921 922
% \unexpanded\def\getdummyparameters
923
% {\mult_interfaces_get_parameters\??dummy}
924 925
\unexpanded
\def
\getdummyparameters
[#
1
%
926
{
\if\noexpand
#
1
]
%
927
\expandafter
\gobbleoneargument
928
\else
929
\let
\m_mult_interfaces_namespace
\??dummy
930
\expandafter
\mult_interfaces_get_parameters_indeed
931
\fi
#
1
}
932 933
\mult_interfaces_install_style_and_color_handler
934
\directdummyparameter
935
\usedummystyleandcolor
936
\usedummystyleparameter
937
\usedummycolorparameter
938 939
% Maybe a \definecorenamespace[name][directparameter,directsetup][parent] but we
940
% don't gain much. Actually we might just inline all definitions.
941 942
% \enabletrackers[interfaces.namespaces,context.flush]
943
%
944
% \definenamespace
945
% [xy]
946
% [type=module,
947
% comment=test module,
948
% version=1,
949
% name=test,
950
% style=yes,
951
% command=yes,
952
% setup=list,
953
% set=yes,
954
% parent=xy]
955
%
956
% \unprotect
957
% \getparameters
958
% [\????xy]
959
% [text=]
960
% \protect
961
%
962
% \definetest[one]
963
%
964
% \starttext
965
%
966
% “\testparameter{text}”
967
%
968
% \setuptest[text=foo]
969
%
970
% “\testparameter{text}”
971
%
972
% \setuptest[one][text=bar]
973
%
974
% “\testparameter{text}”
975
%
976
% \stoptext
977
%
978
% This is a user (module) command:
979 980
\unexpanded
\def
\definenamespace
981
{
\dodoubleargument
\mult_interfaces_define_name_space
}
982 983
\def
\mult_interfaces_define_name_space
[#
1
][#
2
]
% namespace settings
984
{
\clf_definenamespace
{
#
1
}{
#
2
}}
985 986
\def
\listnamespaces
987
{
\clf_listnamespaces
}
988 989
%D Helper:
990
%D
991
%D \starttyping
992
%D \showparentchain{@@am}{left}
993
%D \stoptyping
994 995
\unexpanded
\def
\showparentchain
#
1
#
2
%
996
{
\writestatus
\m!system
{
chain
:
[
\mult_interfaces_show_parent_chain
{
#
1
#
2
}
]
}}
997 998
% \def\mult_interfaces_show_parent_chain#1%
999
% {#1 => %
1000
% \ifcsname#1:\s!parent\endcsname
1001
% \expandafter\mult_interfaces_show_parent_chain\csname#1:\s!parent\endcsname
1002
% \fi}
1003 1004
\def
\mult_interfaces_show_parent_chain
#
1
%
1005
{
#
1
=>
%
1006
\ifcsname
#
1
:
\s!parent
\endcsname
1007
%\expandafter\mult_interfaces_show_parent_chain\csname#1:\s!parent\endcsname
1008
\expandafter
\mult_interfaces_show_parent_chain
\lastnamedcs
1009
\fi
}
1010 1011
%D Another helper (needs to be applied):
1012 1013
\unexpanded
\def
\doifelsecommandhandler
#
1
#
2
% namespace name
1014
{
\ifcsname
#
1
#
2
:
\s!parent
\endcsname
1015
\expandafter
\firstoftwoarguments
1016
\else
1017
\expandafter
\secondoftwoarguments
1018
\fi
}
1019 1020
\let
\doifcommandhandlerelse\doifelsecommandhandler
1021 1022
\unexpanded
\def
\doifcommandhandler
#
1
#
2
% namespace name
1023
{
\ifcsname
#
1
#
2
:
\s!parent
\endcsname
1024
\expandafter
\firstofoneargument
1025
\else
1026
\expandafter
\gobbleoneargument
1027
\fi
}
1028 1029
\unexpanded
\def
\doifnotcommandhandler
#
1
#
2
% namespace name
1030
{
\ifcsname
#
1
#
2
:
\s!parent
\endcsname
1031
\expandafter
\gobbleoneargument
1032
\else
1033
\expandafter
\firstofoneargument
1034
\fi
}
1035 1036
\let
\doifcommandhandlerelse\doifelsecommandhandler
1037 1038
% another set of (fast) helpers (grep for usage):
1039 1040
\def
\expandnamespaceparameter
#
1
#
2
#
3
% \??xx \getp \c!xx \v!yy
1041
{
\csname
#
1
\ifcsname
#
1
\expandafter\expandafter\expandafter
\mult_aux_expand_namespace_parameter
#
2
#
3
}
1042 1043
\def
\mult_aux_expand_namespace_parameter
#
1
#
2
% \cs \v!yy
1044
{
#
1
\endcsname
#
1
\else
#
2
\fi\endcsname
}
1045 1046
\def
\expandnamespacemacro
#
1
#
2
#
3
% \??xx \some_edefed_cs \c!yy
1047
{
\csname
#
1
\ifcsname
#
1
#
2
\endcsname
#
2
\else
#
3
\fi\endcsname
}
1048 1049
\def
\expandnamespacevalue
#
1
#
2
% \??xx {...} \c!yy == optimized \expandcheckedcsname
1050
{
\csname
#
1
\ifcsname
#
1
\normalexpanded
{
\noexpand
\syst_helpers_expand_checked_value
{
#
2
}}}
1051 1052
\def
\syst_helpers_expand_checked_value
#
1
#
2
%
1053
{
#
1
\endcsname
#
1
\else
#
2
\fi\endcsname
}
1054 1055
%D Conventions:
1056
%D
1057
%D \starttyping
1058
%D \newcount \c_class_whatever
1059
%D \newconditional \c_class_whatever
1060
%D \newconstant \c_class_whatever
1061
%D \newdimen \d_class_whatever
1062
%D \newskip \s_class_whatever
1063
%D \newmuskip \s_class_whatever
1064
%D \newbox \b_class_whatever
1065
%D \newtoks \t_class_whatever
1066
%D
1067
%D \edef\p_class_whatever{\classparameter\c!whatever}
1068
%D \edef\m_class_whatever{whatever}
1069
%D \stoptyping
1070 1071
% experiment: in principle this is faster but not that noticeable as we don't do that
1072
% many assignments and mechanism that do are also slow; the advantage is mostly nicer
1073
% in tracing
1074 1075
\def
\s!simple
{
simple
}
1076
\def
\s!single
{
single
}
1077
\def
\s!double
{
double
}
1078
\def
\s!triple
{
triple
}
1079 1080
% \unexpanded\def\syst_helpers_double_empty#1#2#3%
1081
% {\syst_helpers_argument_reset
1082
% \doifelsenextoptional
1083
% {\syst_helpers_double_empty_one_yes_mult#2#3}%
1084
% {\syst_helpers_double_empty_one_nop_mult#1}}
1085
%
1086
% \def\syst_helpers_double_empty_one_yes_mult#1#2[#3]%
1087
% {\firstargumenttrue
1088
% \doifelsenextoptional
1089
% {\secondargumenttrue#2[{#3}]}%
1090
% {\syst_helpers_double_empty_two_nop_mult#1{#3}}}
1091
%
1092
% \def\syst_helpers_double_empty_one_nop_mult% #1%
1093
% {\firstargumentfalse
1094
% \secondargumentfalse
1095
% }% #1}
1096
%
1097
% \def\syst_helpers_double_empty_two_nop_mult
1098
% {\secondargumentfalse
1099
% \if_next_blank_space_token
1100
% \expandafter\syst_helpers_double_empty_one_spaced_mult
1101
% \else
1102
% \expandafter\syst_helpers_double_empty_one_normal_mult
1103
% \fi}
1104
%
1105
% \def\syst_helpers_double_empty_one_spaced_mult#1#2{#1[{#2}] }
1106
% \def\syst_helpers_double_empty_one_normal_mult#1#2{#1[{#2}]}
1107
%
1108
% \unexpanded\def\mult_interfaces_install_setup_handler#1#2#3#4#5#6#7#8%
1109
% {\ifx#3\relax\let#3\empty\fi
1110
% \unexpanded\def#5{\mult_interfaces_get_parameters{#1#3:}}% no every ! don't change it
1111
% \newtoks#4%
1112
% \newtoks#7%
1113
% \edef\m_mult_interface_setup{\csstring#2_}%
1114
% \unexpanded\edef#2{\syst_helpers_double_empty
1115
% \csname\m_mult_interface_setup\s!simple\endcsname
1116
% \csname\m_mult_interface_setup\s!single\endcsname
1117
% \csname\m_mult_interface_setup\s!double\endcsname}%
1118
% \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!double\endcsname[##1][##2]%
1119
% {\let#6#3%
1120
% \def#8####1% we will have a simple one as well
1121
% {\edef#3{####1}%
1122
% \mult_interfaces_get_parameters{#1#3:}[##2]%
1123
% \the#4}%
1124
% \processcommalist[##1]#8%
1125
% \let#3#6%
1126
% \the#7}%
1127
% \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!single\endcsname[##1]%
1128
% {\let#6#3%
1129
% \let#3\empty
1130
% \mult_interfaces_get_parameters{#1:}[##1]%
1131
% \the#4%
1132
% \let#3#6%
1133
% \the#7}%
1134
% \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!simple\endcsname%
1135
% {\let#6#3%
1136
% \let#3\empty
1137
% \the#4%
1138
% \let#3#6%
1139
% \the#7}}
1140 1141
% \unexpanded\def\installsetuphandler#1#2%
1142
% {\normalexpanded
1143
% {\mult_interfaces_install_setup_handler
1144
% {\noexpand#1}% \??aa
1145
% \expandafter\noexpand\csname setup#2\endcsname
1146
% \expandafter\noexpand\csname current#2\endcsname
1147
% \expandafter\noexpand\csname everysetup#2\endcsname
1148
% \expandafter\noexpand\csname setupcurrent#2\endcsname
1149
% \expandafter\noexpand\csname saved_setup_current#2\endcsname
1150
% \expandafter\noexpand\csname everysetup#2root\endcsname
1151
% \expandafter\noexpand\csname nested_setup_current#2\endcsname}}
1152
%
1153
% \unexpanded\def\syst_helpers_triple_empty#1#2#3#4%
1154
% {\syst_helpers_argument_reset
1155
% \doifelsenextoptional
1156
% {\syst_helpers_triple_empty_one_yes_mult#2#3#4}%
1157
% {\syst_helpers_triple_empty_one_nop_mult#1}}
1158
%
1159
% \def\syst_helpers_triple_empty_one_yes_mult#1#2#3[#4]%
1160
% {\firstargumenttrue
1161
% \doifelsenextoptional
1162
% {\syst_helpers_triple_empty_two_yes_mult#2#3{#4}}%
1163
% {\syst_helpers_triple_empty_two_nop_mult#1{#4}}}
1164
%
1165
% \def\syst_helpers_triple_empty_two_yes_mult#1#2#3[#4]%
1166
% {\secondargumenttrue
1167
% \doifelsenextoptional
1168
% {\thirdargumenttrue#2[{#3}][{#4}]}%
1169
% {\syst_helpers_triple_empty_three_nop_mult#1{#3}{#4}}}
1170
%
1171
% \def\syst_helpers_triple_empty_one_nop_mult % #1%
1172
% {\firstargumentfalse
1173
% \secondargumentfalse
1174
% \thirdargumentfalse
1175
% } % #1
1176
%
1177
% \def\syst_helpers_triple_empty_two_nop_mult
1178
% {\secondargumentfalse
1179
% \thirdargumentfalse
1180
% \if_next_blank_space_token
1181
% \expandafter\syst_helpers_triple_empty_two_spaced_mult
1182
% \else
1183
% \expandafter\syst_helpers_triple_empty_two_normal_mult
1184
% \fi}
1185
%
1186
% \def\syst_helpers_triple_empty_three_nop_mult
1187
% {\thirdargumentfalse
1188
% \if_next_blank_space_token
1189
% \expandafter\syst_helpers_triple_empty_three_spaced_mult
1190
% \else
1191
% \expandafter\syst_helpers_triple_empty_three_normal_mult
1192
% \fi}
1193
%
1194
% \def\syst_helpers_triple_empty_two_spaced_mult #1#2{#1[{#2}] }
1195
% \def\syst_helpers_triple_empty_two_normal_mult #1#2{#1[{#2}]}
1196
% \def\syst_helpers_triple_empty_three_spaced_mult#1#2#3{#1[{#2}][{#3}] }
1197
% \def\syst_helpers_triple_empty_three_normal_mult#1#2#3{#1[{#2}][{#3}]}
1198
%
1199
% \unexpanded\def\mult_interfaces_install_auto_setup_handler#1#2#3#4#5#6#7#8%
1200
% {\ifx#3\relax\let#3\empty\fi
1201
% \unexpanded\def#5{\mult_interfaces_get_parameters{#1#3:}}%
1202
% \newtoks#4%
1203
% \edef\m_mult_interface_setup{\csstring#2_}%
1204
% \unexpanded\edef#2{\syst_helpers_triple_empty
1205
% \csname\m_mult_interface_setup\s!simple\endcsname
1206
% \csname\m_mult_interface_setup\s!single\endcsname
1207
% \csname\m_mult_interface_setup\s!double\endcsname
1208
% \csname\m_mult_interface_setup\s!triple\endcsname}%
1209
% \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!triple\endcsname[##1][##2][##3]%
1210
% {\let#7#3%
1211
% \def#8####1%
1212
% {\edef#3{####1}%
1213
% \expandafter\def\csname#1#3:\s!parent\endcsname{#1##2}%
1214
% \mult_interfaces_get_parameters{#1#3:}[##3]% always sets parent
1215
% \the#4}%
1216
% \processcommalist[##1]#8%
1217
% \let#3#7}%
1218
% \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!double\endcsname[##1][##2]%
1219
% {\let#7#3%
1220
% \def#8####1%
1221
% {\edef#3{####1}%
1222
% #6% checks parent and sets if needed
1223
% \mult_interfaces_get_parameters{#1#3:}[##2]%
1224
% \the#4}%
1225
% \processcommalist[##1]#8%
1226
% \let#3#7}%
1227
% \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!single\endcsname[##1]%
1228
% {\let#7#3%
1229
% \let#3\empty
1230
% \mult_interfaces_get_parameters{#1:}[##1]%
1231
% \the#4%
1232
% \let#3#7}%
1233
% \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!simple\endcsname%
1234
% {\let#7#3%
1235
% \let#3\empty
1236
% \the#4%
1237
% \let#3#7}}
1238
%
1239
% \unexpanded\def\installautosetuphandler#1#2%
1240
% {\normalexpanded
1241
% {\mult_interfaces_install_auto_setup_handler
1242
% {\noexpand#1}% \??aa
1243
% \expandafter\noexpand\csname setup#2\endcsname
1244
% \expandafter\noexpand\csname current#2\endcsname
1245
% \expandafter\noexpand\csname everysetup#2\endcsname
1246
% \expandafter\noexpand\csname setupcurrent#2\endcsname
1247
% \expandafter\noexpand\csname check#2parent\endcsname
1248
% \expandafter\noexpand\csname saved_setup_current#2\endcsname
1249
% \expandafter\noexpand\csname nested_setup_current#2\endcsname}}
1250 1251
% okay, we can also get rid of the #9, but this code looks pretty bad, while the previous is
1252
% still okay given that we can also use #6 as setup (so in fact we can save some cs again and
1253
% only use one extra)
1254
%
1255
% \global\advance\commalevel \plusone
1256
% \expandafter\def\csname\??nextcommalevel\the\commalevel\endcsname####1,%
1257
% {\edef#3{####1}%
1258
% \mult_interfaces_get_parameters{#1#3:}[##2]%
1259
% \the#5%
1260
% \syst_helpers_do_process_comma_item}%
1261
% \expandafter\syst_helpers_do_do_process_comma_item\gobbleoneargument\relax##1,]\relax
1262
% % \syst_helpers_do_do_process_comma_item##1,]\relax
1263
% \global\advance\commalevel \minusone
1264 1265
% The next one is experimental (and used in publications):
1266 1267
\let
\c_mult_set
\relax
1268 1269
\unexpanded
\def
\mult_interfaces_install_definition_set
#
1
#
2
#
3
#
4
#
5
#
6
#
7
%
1270
{
\newcount
#
3
%
1271
\let
#
6
\empty
1272
\unexpanded
\def
#
2
%
1273
{
\expandafter\let\expandafter
\c_mult_set
\csname
#
1
_
t
_
#
6
\endcsname
1274
\ifx
\c_mult_set
\relax
1275
\expandafter
\newtoks
\c_mult_set
1276
\expandafter\let\csname
#
1
_
t
_
#
6
\endcsname
\c_mult_set
1277
\fi
}
1278
\unexpanded
\def
#
4
##
1
%
1279
{
\pushmacro
#
6
%
1280
\advance
#
3
\plusone
1281
\edef
#
6
{
##
1
}
%
1282
\unprotect
}
%
1283
\unexpanded
\def
#
5
%
1284
{
\protect
1285
\advance
#
3
\minusone
1286
\popmacro
#
6
}
%
1287
\unexpanded
\def
#
7
##
1
%
1288
{
\edef
#
6
{
##
1
}
%
1289
#
2
%
1290
\the
\c_mult_set
\relax
}}
1291 1292
\unexpanded
\def
\installdefinitionset
#
1
#
2
%
1293
{
\normalexpanded
1294
{
\mult_interfaces_install_definition_set
1295
{
\noexpand
#
1
}
% \??aa
1296
\expandafter\noexpand\csname
set
_
#
2
_
toks
\endcsname
1297
\expandafter\noexpand\csname
#
2
_
nesting
_
depth
\endcsname
1298
\expandafter\noexpand\csname
push
#
2
\endcsname
1299
\expandafter\noexpand\csname
pop
#
2
\endcsname
1300
\expandafter\noexpand\csname
current
#
2
\endcsname
1301
\expandafter\noexpand\csname
use
#
2
\endcsname
}}
1302 1303
\unexpanded
\def
\mult_interfaces_install_definition_set_member
#
1
#
2
#
3
#
4
#
5
#
6
#
7
#
8
#
9
% no everysetups etc
1304
{
\let
#
5
#
2
%
1305
\unexpanded
\def
#
2
%
1306
{
\ifcase
#
4
\relax\expandafter
#
5
\else\expandafter
#
6
\fi
}
%
1307
\unexpanded
\def
#
6
%
1308
{
\dodoubleempty
#
7
}
%
1309
\unexpanded
\def
#
7
[##
1
][##
2
]
%
1310
{
\ifsecondargument
1311
%#3\c_mult_set\expandafter{\the\c_mult_set#9[##1][##2]}%
1312
#
3
\toksapp
\c_mult_set
{
#
9
[##
1
][##
2
]
}
%
1313
\else
\iffirstargument
1314
%#3\c_mult_set\expandafter{\the\c_mult_set#8[##1]}%
1315
#
3
\toksapp
\c_mult_set
{
#
8
[##
1
]
}
%
1316
\fi\fi
}}
1317 1318
\unexpanded
\def
\installdefinitionsetmember
#
1
#
2
#
3
#
4
%
1319
{
\normalexpanded
1320
{
\mult_interfaces_install_definition_set_member
1321
{
\noexpand
#
3
}
% \??aa
1322
\expandafter\noexpand\csname
setup
#
4
\endcsname
1323
\expandafter\noexpand\csname
set
_
#
2
_
toks
\endcsname
1324
\expandafter\noexpand\csname
#
2
_
nesting
_
depth
\endcsname
1325
\expandafter\noexpand\csname
normal
_
setup
_
#
4
\endcsname
1326
\expandafter\noexpand\csname
delayed
_
setup
_
#
4
\endcsname
1327
\expandafter\noexpand\csname
do
_
delayed
_
setup
_
#
4
\endcsname
1328
\expandafter\noexpand\csname
setup
#
4
_
\s!single
\endcsname
1329
\expandafter\noexpand\csname
setup
#
4
_
\s!double
\endcsname
}}
1330 1331
%D Another experiment:
1332 1333
\unexpanded
\def
\mult_interfaces_install_parent_injector
#
1
#
2
#
3
#
4
%
1334
{
\unexpanded
\def
#
4
##
1
%
1335
{
\ifx
#
3
\empty
1336
\expandafter\def\csname
#
1
#
2
:
\s!parent
\endcsname
{
#
1
##
1
}
%
1337
\fi
}}
1338 1339
\unexpanded
\def
\installparentinjector
#
1
#
2
%
1340
{
\normalexpanded
{
\mult_interfaces_install_parent_injector
1341
{
\noexpand
#
1
}
%
1342
\expandafter\noexpand\csname
current
#
2
\endcsname
1343
\expandafter\noexpand\csname
current
#
2
parent
\endcsname
1344
\expandafter\noexpand\csname
inject
#
2
parent
\endcsname
}}
1345 1346
% Faster but not used that much to make a dent in performance. But, because it's
1347
% cleaner anyway and also gives less tracing, we apply it a few times.
1348 1349
\unexpanded
\def
\syst_helpers_install_macro_stack
#
1
#
2
#
3
%
1350
{
\xdef
\m_syst_helpers_push_macro
{
\csstring
#
1
}
%
1351
\ifcsname
#
3
\m_syst_helpers_push_macro
\endcsname\else
1352
\expandafter
\newcount
\csname
#
3
\m_syst_helpers_push_macro
\endcsname
1353
\expandafter\edef\csname
push
_
macro
_
\m_syst_helpers_push_macro
\endcsname
1354
{
\noexpand\expandafter
\glet
1355
\noexpand\csname
\m_syst_helpers_push_macro
\noexpand\the\csname
#
3
\m_syst_helpers_push_macro
\endcsname\endcsname
1356
\noexpand
#
1
%
1357
\global\advance\csname
#
3
\m_syst_helpers_push_macro
\endcsname
\plusone
}
%
1358
\expandafter\edef\csname
pop
_
macro
_
\m_syst_helpers_push_macro
\endcsname
1359
{
\global\advance\csname
#
3
\m_syst_helpers_push_macro
\endcsname
\minusone
1360
\noexpand\expandafter
#
2
%
1361
\noexpand\expandafter\noexpand
#
1
%
1362
\noexpand\csname
\m_syst_helpers_push_macro
\noexpand\the\csname
#
3
\m_syst_helpers_push_macro
\endcsname\endcsname
}
%
1363
\fi
}
1364 1365
\unexpanded
\def
\installmacrostack
#
1
{
\syst_helpers_install_macro_stack
#
1
\let
\??localpushedmacro
}
1366
\unexpanded
\def
\installglobalmacrostack
#
1
{
\syst_helpers_install_macro_stack
#
1
\glet
\??globalpushedmacro
}
1367 1368
% \unprotect
1369
%
1370
% \installcorenamespace {test} \installcommandhandler \??test {test} \??test
1371
% \unexpanded\def\TestMeA[#1]%
1372
% {\edef\currenttest{#1}
1373
% \edef\p_before{\testparameter\c!before}%
1374
% \ifx\p_before\empty \relax \else \relax \fi}
1375
% \unexpanded\def\TestMeB[#1]%
1376
% {\edef\currenttest{#1}
1377
% \doifelsenothing{\testparameter\c!before}\relax\relax}
1378
% \unexpanded\def\TestMeC[#1]%
1379
% {\edef\currenttest{#1}
1380
% \expandafter\expandafter\expandafter\ifx\testparameter\c!before\empty \relax \else \relax \fi}
1381
% \unexpanded\def\TestMeD[#1]%
1382
% {\edef\currenttest{#1}
1383
% \doubleexpandafter\ifx\testparameter\c!before\empty \relax \else \relax \fi}
1384
%
1385
% \protect
1386
%
1387
% \starttext
1388
% \definetest[foo] \definetest[bar][foo] \setuptest[bar][before=indeed]
1389
% \testfeatureonce{100000}{\TestMeA[bar]} A:\elapsedtime \par % 0.502
1390
% \testfeatureonce{100000}{\TestMeB[bar]} B:\elapsedtime \par % 0.530
1391
% \testfeatureonce{100000}{\TestMeC[bar]} C:\elapsedtime \par % 0.487
1392
% \testfeatureonce{100000}{\TestMeD[bar]} D:\elapsedtime \par % 0.493
1393
% \stoptext
1394 1395
% There is no real demand for this ... even if this is two to three times as fast we
1396
% only gain a few milliseconds:
1397
%
1398
% \starttyping
1399
% \unexpanded\def\foo#1{[foo:#1]}
1400
%
1401
% \installcommalistprocessor {foo} \foo
1402
% \installcommalistprocessorcommand \processfoolist \foo
1403
%
1404
% \infofont
1405
%
1406
% \commalistprocessor{foo}[a,b,c,{x,y,z},d]\par
1407
% \processfoolist[a, b, c, {x,y,z}, d]\par
1408
% \processcommalist[{x,y,z}]\foo\blank
1409
%
1410
% \commalistprocessor{foo}[{x,y,z},a]\par
1411
% \commalistprocessor{foo}[{x,y,z}]\par
1412
% \processfoolist[{x,y,z},a]\par
1413
% \processfoolist[{x,y,z}]\par
1414
% \processcommalist[{x,y,z}]\foo\blank
1415
%
1416
% \unexpanded\def\foo#1{}
1417
%
1418
% \testfeatureonce{400000}{\processfoolist [fixed,middle,bar]} \elapsedtime\quad
1419
%%\testfeatureonce{400000}{\commalistprocessor{foo}[fixed,middle,bar]} \elapsedtime\quad
1420
% \testfeatureonce{400000}{\processcommalist [fixed,middle,bar]\foo} \elapsedtime\quad
1421
% \stoptyping
1422
%
1423
% For instance the luatex manual only has some 3000 calls. But I keep this around as one
1424
% never knows when we might need it.
1425 1426
\installcorenamespace
{
commalistprocessor
}
1427
\installcorenamespace
{
commalistprocessorwrap
}
1428
\installcorenamespace
{
commalistprocessorfirst
}
1429
\installcorenamespace
{
commalistprocessornext
}
1430
\installcorenamespace
{
commalistprocessoraction
}
1431 1432
\installcorenamespace
{
commalistprocessorcheck
}
1433
\installcorenamespace
{
commalistprocessorspace
}
1434
\installcorenamespace
{
commalistprocessorpickup
}
1435
\installcorenamespace
{
commalistprocessorfinish
}
1436 1437
\unexpanded
\def
\installcommalistprocessor
#
1
#
2
% 8 macro names overhead
1438
{
\let
\nexttoken
\relax
1439
\unexpanded
\expandafter\edef\csname
\??commalistprocessor
#
1
\endcsname
[
%
1440
{
\futurelet
\nexttoken
\csname
\??commalistprocessorcheck
#
1
\endcsname
}
%
1441
\unexpanded
\expandafter\edef\csname
\??commalistprocessorcheck
#
1
\endcsname
1442
{
\noexpand\ifx
\nexttoken
]
%
1443
\noexpand\expandafter\noexpand
\gobblethreearguments
1444
\noexpand\else
1445
\noexpand\expandafter\csname
\??commalistprocessorwrap
#
1
\endcsname
1446
\noexpand\fi
1447
\relax
}
% this one preserved the next {}
1448
\unexpanded
\expandafter\edef\csname
\??commalistprocessorwrap
#
1
\endcsname
##
1
]
%
1449
{
\csname
\??commalistprocessorfirst
#
1
\endcsname
##
1
,
]
\relax
}
%
1450
\unexpanded
\expandafter\edef\csname
\??commalistprocessorfirst
#
1
\endcsname
##
1
% picks up \relax
1451
{
\csname
\??commalistprocessornext
#
1
\endcsname
}
%
1452
\unexpanded
\expandafter\edef\csname
\??commalistprocessornext
#
1
\endcsname
1453
{
\noexpand\ifx
\nexttoken
\noexpand
\blankspace
1454
\noexpand\expandafter\csname
\??commalistprocessorspace
#
1
\endcsname
1455
\noexpand\else
1456
\noexpand\expandafter\csname
\??commalistprocessorfinish
#
1
\endcsname
1457
\noexpand\fi
}
%
1458
\unexpanded
\expandafter\edef\csname
\??commalistprocessorfinish
#
1
\endcsname
1459
{
\noexpand\ifx
\nexttoken
]
%
1460
\noexpand\expandafter\noexpand
\gobbleoneargument
1461
\noexpand\else
1462
\noexpand\expandafter\csname
\??commalistprocessoraction
#
1
\endcsname
1463
\noexpand\fi
}
%
1464
\unexpanded
\expandafter\edef\csname
\??commalistprocessoraction
#
1
\endcsname
##
1
,
%
1465
{
\noexpand
#
2
{
##
1
}
%
1466
\futurelet
\nexttoken
\csname
\??commalistprocessornext
#
1
\endcsname
}
%
1467
\let
\next
\:
%
1468
\unexpanded
\edef
\:
{
\csname
\??commalistprocessorspace
#
1
\endcsname
}
%
1469
\unexpanded
\expandafter\edef
\:
{
\futurelet
\nexttoken
\csname
\??commalistprocessornext
#
1
\endcsname
}
%
1470
\let
\:
\next
}
1471 1472
\unexpanded
\def
\installcommalistprocessorcommand
#
1
#
2
% \processor \action
1473
{
\edef
\p_name
{
\csstring
#
2
}
%
1474
\installcommalistprocessor
\p_name
{
#
2
}
%
1475
\expandafter\let\expandafter
#
1
\csname
\??commalistprocessor
\p_name
\endcsname
}
1476 1477
\unexpanded
\def
\commalistprocessor
#
1
{
\csname
\??commalistprocessor
#
1
\endcsname
}
1478 1479
\protect
\endinput
1480