core-env.mkiv /size: 28 Kb    last modification: 2024-01-16 09:02
1%D \module
2%D   [       file=core-env, % was core-new
3%D        version=1995.01.01, % wrong
4%D          title=\CONTEXT\ Core Macros,
5%D       subtitle=New ones,
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\writestatus{loading}{ConTeXt Core Macros / Environments}
15
16\registerctxluafile{core-env}{}
17
18\unprotect
19
20\ifdefined\wildcardsymbol \else \def\wildcardsymbol{*} \fi
21
22%D Modes:
23%D
24%D \starttyping
25%D \enablemode[screen,paper,bound]
26%D
27%D \doifmodeelse {paper}        {this} {that}
28%D \doifmode     {paper,screen} {this}
29%D \doifnotmode  {paper,bound}  {that}
30%D
31%D \startmode [list]
32%D \stopmode
33%D
34%D \startnotmode [list]
35%D \stopnotmode
36%D \stoptyping
37%D
38%D system modes have a * as prefix
39%D
40%D Sometimes, we want to prevent a mode for being set. Think of situations where a
41%D style enables a mode, but an outer level style does not want that. Preventing can
42%D be considered a permanent disabling on forehand.
43
44\let\systemmodeprefix\wildcardsymbol
45
46% we will have \installcorenamespace{mode} but need some hackery at the lua end then
47
48\installcorenamespace{modestack}
49
50\setnewconstant\disabledmode \zerocount
51\setnewconstant\enabledmode  \plusone
52\setnewconstant\preventedmode\plustwo
53
54% fast internal ones
55
56\def\??mode{mode>} % special namespace, also used at lua end
57
58\def\syst_modes_new#1%
59  {\expandafter\newcount\csname\??mode#1\endcsname}
60
61\unexpanded\def\newmode#1% so, no change of already set modes !
62  {\ifcsname\??mode#1\endcsname\else\syst_modes_new{#1}\fi}
63
64\unexpanded\def\setmode#1%
65  {\ifcsname\??mode#1\endcsname\else\syst_modes_new{#1}\fi
66   \lastnamedcs\enabledmode}
67
68\unexpanded\def\resetmode#1%
69  {\ifcsname\??mode#1\endcsname\else\syst_modes_new{#1}\fi
70   \lastnamedcs\disabledmode}
71
72\unexpanded\def\globalsetmode#1%
73  {\ifcsname\??mode#1\endcsname\else\syst_modes_new{#1}\fi
74   \global\lastnamedcs\enabledmode}
75
76\unexpanded\def\globalresetmode#1%
77  {\ifcsname\??mode#1\endcsname\else\syst_modes_new{#1}\fi
78   \global\lastnamedcs\disabledmode}
79
80\unexpanded\def\newsystemmode#1%
81  {\ifcsname\??mode\systemmodeprefix#1\endcsname\else\syst_modes_new{\systemmodeprefix#1}\fi}
82
83\unexpanded\def\setsystemmode#1%
84  {\ifcsname\??mode\systemmodeprefix#1\endcsname\else\syst_modes_new{\systemmodeprefix#1}\fi
85   \lastnamedcs\enabledmode}
86
87\unexpanded\def\resetsystemmode#1%
88  {\ifcsname\??mode\systemmodeprefix#1\endcsname\else\syst_modes_new{\systemmodeprefix#1}\fi
89   \lastnamedcs\disabledmode}
90
91\unexpanded\def\globalsetsystemmode#1%
92  {\ifcsname\??mode\systemmodeprefix#1\endcsname\else\syst_modes_new{\systemmodeprefix#1}\fi
93   \global\lastnamedcs\enabledmode}
94
95\unexpanded\def\globalresetsystemmode#1%
96  {\ifcsname\??mode\systemmodeprefix#1\endcsname\else\syst_modes_new{\systemmodeprefix#1}\fi
97   \global\lastnamedcs\disabledmode}
98
99% \def\dosetsystemmode#1%
100%   {\csname\??mode\systemmodeprefix#1\endcsname\enabledmode}
101%
102% \def\doresetsystemmode#1%
103%   {\csname\??mode\systemmodeprefix#1\endcsname\disabledmode}
104
105% demo: trialtypesetting is a systemmode as well as an if
106
107\pushoverloadmode
108
109\newsystemmode{trialtypesetting}
110
111\expandafter\let\csname\??mode\systemmodeprefix trialtypesetting\endcsname\trialtypesettingstate
112
113\popoverloadmode
114
115\appendtoks
116    \trialtypesettingstate\enabledmode
117    \luacopyinputnodes\plusone
118\to \everysettrialtypesetting
119
120\appendtoks
121    \trialtypesettingstate\disabledmode
122    \luacopyinputnodes\zerocount
123\to \everyresettrialtypesetting
124
125% user ones
126
127\let\syst_mode_prefix\relax
128
129\unexpanded\def\preventmode{\unprotect\syst_modes_prevent}
130\unexpanded\def\enablemode {\unprotect\syst_modes_enable }
131\unexpanded\def\disablemode{\unprotect\syst_modes_disable}
132
133\unexpanded\def\globalpreventmode{\let\syst_mode_prefix\global\unprotect\syst_modes_prevent}
134\unexpanded\def\globalenablemode {\let\syst_mode_prefix\global\unprotect\syst_modes_enable }
135\unexpanded\def\globaldisablemode{\let\syst_mode_prefix\global\unprotect\syst_modes_disable}
136
137% \def\syst_modes_prevent[#1]{\protect\rawprocesscommacommand[#1]\syst_modes_prevent_indeed\let\syst_mode_prefix\relax}
138% \def\syst_modes_enable [#1]{\protect\rawprocesscommacommand[#1]\syst_modes_enable_indeed \let\syst_mode_prefix\relax}
139% \def\syst_modes_disable[#1]{\protect\rawprocesscommacommand[#1]\syst_modes_disable_indeed\let\syst_mode_prefix\relax}
140
141\def\syst_modes_prevent[#1]{\protect\fastprocesscommacommand[#1]\syst_modes_prevent_indeed\let\syst_mode_prefix\relax}
142\def\syst_modes_enable [#1]{\protect\fastprocesscommacommand[#1]\syst_modes_enable_indeed \let\syst_mode_prefix\relax}
143\def\syst_modes_disable[#1]{\protect\fastprocesscommacommand[#1]\syst_modes_disable_indeed\let\syst_mode_prefix\relax}
144
145\def\syst_modes_prevent_indeed#1%
146  {\ifcsname\??mode#1\endcsname\else\syst_modes_new{#1}\fi
147   \syst_mode_prefix\lastnamedcs\preventedmode}
148
149\def\syst_modes_enable_indeed#1% we can speed it up by moving the new outside
150  {\ifcsname\??mode#1\endcsname\else\syst_modes_new{#1}\fi
151   \ifnum\lastnamedcs=\preventedmode\else
152     \syst_mode_prefix\lastnamedcs\enabledmode
153   \fi}
154
155\def\syst_modes_disable_indeed#1%
156  {\ifcsname\??mode#1\endcsname\else\syst_modes_new{#1}\fi
157   \ifnum\lastnamedcs=\preventedmode\else
158     \syst_mode_prefix\lastnamedcs\disabledmode
159   \fi}
160
161%D If you do a lot of mode testing, it makes sense to define modes (or disable them
162%D explicitly if unset. This makes testing twice as fast. Often one enables modes
163%D beforehand, in which case \type {\definemode} would reset the mode. The optional
164%D second argument \type {keep} will prevent changing the already set mode but defines
165%D it when undefined.
166
167\unexpanded\def\definemode
168  {\unprotect
169   \dodoubleempty\syst_modes_define}
170
171\def\syst_modes_define[#1][#2]%
172  {\protect
173   \edef\m_modes_asked{#2}%
174 % \rawprocesscommacommand[#1]\syst_modes_define_indeed}
175   \fastprocesscommacommand[#1]\syst_modes_define_indeed}
176
177\def\syst_modes_define_indeed#1%
178  {\ifcsname\??mode#1\endcsname
179     % already set
180   \else
181     \syst_modes_new{#1}
182   \fi
183   \ifx\m_modes_asked\v!keep
184     % not changes, disabled when undefined
185   \else
186     \lastnamedcs\ifx\m_modes_asked\v!yes\enabledmode\else\disabledmode\fi
187   \fi}
188
189% handy for mp
190
191\def\booleanmodevalue#1%
192  {\ifcsname\??mode#1\endcsname
193     \ifcase\lastnamedcs
194       \s!false
195     \or
196       \s!true
197     \else
198       \s!false
199     \fi
200   \else
201     \s!false
202   \fi}
203
204% check macros
205
206\newconditional\c_checked_mode
207
208% one
209
210\def\syst_modes_check_indeed#1%
211  {\ifcsname\??mode#1\endcsname
212     \ifcase\lastnamedcs\else
213       \let\syst_modes_check_step\gobbleoneargument
214     \fi
215   \fi}
216
217\def\syst_modes_check_nop#1#2#3%
218  {\let\syst_modes_check_step\syst_modes_check_indeed
219 % \rawprocesscommacommand[#3]\syst_modes_check_step
220   \fastprocesscommacommand[#3]\syst_modes_check_step
221   \ifx\syst_modes_check_step\gobbleoneargument
222     \expandafter#1%
223   \else
224     \expandafter#2%
225   \fi}
226
227\def\syst_modes_check_yes#1#2#3%
228  {\ifcase\lastnamedcs
229     \expandafter#2%
230   \or
231     \expandafter#1%
232   \else
233     \expandafter#2%
234   \fi}
235
236\def\syst_modes_check_lr#1#2#3%
237  {\ifcsname\??mode#3\endcsname
238     \expandafter\syst_modes_check_yes
239   \else
240     \expandafter\syst_modes_check_nop
241   \fi#1#2{#3}}
242
243\def\syst_modes_check_ss#1#2[#3]%
244  {\ifcsname\??mode#3\endcsname
245     \expandafter\syst_modes_check_yes
246   \else
247     \expandafter\syst_modes_check_nop
248   \fi#1#2{#3}}
249
250% all
251
252\def\syst_modes_check_all_indeed#1%
253  {\ifcsname\??mode#1\endcsname
254     \ifcase\lastnamedcs
255       \let\syst_modes_check_all_step\gobbleoneargument
256     \or
257       % enabled
258     \else
259       \let\syst_modes_check_all_step\gobbleoneargument
260     \fi
261   \else
262     \let\syst_modes_check_all_step\gobbleoneargument
263   \fi}
264
265\def\syst_modes_check_all_lr#1#2#3%
266  {\let\syst_modes_check_all_step\syst_modes_check_all_indeed
267   \fastprocesscommacommand[#3]\syst_modes_check_all_step
268   \ifx\syst_modes_check_all_step\gobbleoneargument
269     \expandafter#2%
270   \else
271     \expandafter#1%
272   \fi}
273
274\def\syst_modes_check_all_ss#1#2[#3]%
275  {\let\syst_modes_check_all_step\syst_modes_check_all_indeed
276   \fastprocesscommacommand[#3]\syst_modes_check_all_step
277   \ifx\syst_modes_check_all_step\gobbleoneargument
278     \expandafter#2%
279   \else
280     \expandafter#1%
281   \fi}
282
283\unexpanded\def\doifelsemode    {\syst_modes_check_lr\firstoftwoarguments\secondoftwoarguments}
284\unexpanded\def\doifmode        {\syst_modes_check_lr\firstofoneargument\gobbleoneargument}
285\unexpanded\def\doifnotmode     {\syst_modes_check_lr\gobbleoneargument\firstofoneargument}
286\unexpanded\def\startmode       {\syst_modes_check_ss\donothing\syst_modes_stop_yes}
287\unexpanded\def\startnotmode    {\syst_modes_check_ss\syst_modes_stop_nop\donothing}
288\unexpanded\def\doifelseallmodes{\syst_modes_check_all_lr\firstoftwoarguments\secondoftwoarguments}
289\unexpanded\def\doifallmodes    {\syst_modes_check_all_lr\firstofoneargument\gobbleoneargument}
290\unexpanded\def\doifnotallmodes {\syst_modes_check_all_lr\gobbleoneargument\firstofoneargument}
291\unexpanded\def\startallmodes   {\syst_modes_check_all_ss\donothing\syst_modes_stop_all_yes}
292\unexpanded\def\startnotallmodes{\syst_modes_check_all_ss\syst_modes_stop_all_nop\donothing}
293
294\let\doifmodeelse     \doifelsemode
295\let\doifallmodeselse \doifelseallmodes
296
297\unexpanded\def\stopmode         {} % no relax
298\unexpanded\def\stopnotmode      {} % no relax
299\unexpanded\def\stopallmodes     {} % no relax
300\unexpanded\def\stopnotallmodes  {} % no relax
301
302\def\syst_modes_stop_yes    #1\stopmode       {}
303\def\syst_modes_stop_nop    #1\stopnotmode    {}
304\def\syst_modes_stop_all_yes#1\stopallmodes   {}
305\def\syst_modes_stop_all_nop#1\stopnotallmodes{}
306
307%D Pushing/popping:
308
309\unexpanded\def\pushmode[#1]%
310  {\ifcsname\??mode#1\endcsname\else\syst_modes_new{#1}\fi
311   \expandafter\edef\csname\??modestack#1\expandafter\endcsname\expandafter{\number\lastnamedcs}%
312   \expandafter\pushmacro\lastnamedcs}
313
314\unexpanded\def\popmode[#1]%
315  {\ifcsname\??modestack#1\endcsname
316     \expandafter\popmacro\lastnamedcs
317     \csname\??mode#1\endcsname\csname\??modestack#1\endcsname\relax
318   \fi}
319
320\def\pushsystemmode#1%
321  {\ifcsname\??mode\systemmodeprefix#1\endcsname\else\syst_modes_new{\systemmodeprefix#1}\fi
322   \expandafter\edef\csname\??modestack\systemmodeprefix#1\expandafter\endcsname\expandafter{\number\lastnamedcs}%
323   \expandafter\pushmacro\lastnamedcs}
324
325\def\popsystemmode#1%
326  {\ifcsname\??modestack\systemmodeprefix#1\endcsname
327     \expandafter\popmacro\lastnamedcs
328     \csname\??mode\systemmodeprefix#1\endcsname\csname\??modestack\systemmodeprefix#1\endcsname\relax
329   \fi}
330
331%D Here is a relatively new variant of mode checking:
332%D
333%D \starttyping
334%D \enablemode[two]
335%D
336%D \startmodeset
337%D     [one]     {1}
338%D     [two]     {2}
339%D     [two]     {2}
340%D     [three]   {3}
341%D     [default] {?}
342%D \stopmodeset
343%D
344%D \startmodeset
345%D     [one]     {1}
346%D     [three]   {3}
347%D     [default] {?}
348%D \stopmodeset
349%D
350%D \startmodeset
351%D     [one] {
352%D         \input tufte
353%D     }
354%D     [two] {
355%D         \startmodes
356%D             [one]     {1}
357%D             [two]     {2}
358%D             [two]     {2}
359%D             [three]   {3}
360%D             [default] {?}
361%D         \stopmodes
362%D     }
363%D     [three] {
364%D         \input zapf
365%D     }
366%D     [default] {
367%D         \input ward
368%D     }
369%D \stopmodeset
370%D \stoptyping
371
372\newconditional\c_syst_modes_set_done % conditionals can be pushed/popped
373
374\unexpanded\def\startmodeset
375  {\pushmacro\c_syst_modes_set_done
376   \setfalse\c_syst_modes_set_done
377   \doifelsenextoptionalcs\syst_modes_set_start\syst_modes_set_quit}
378
379\def\syst_modes_set_start[#1]%
380  {\edef\m_mode_case{#1}%
381   \ifx\m_mode_case\s!default
382     \ifconditional\c_syst_modes_set_done
383       \doubleexpandafter\syst_modes_set_quit
384     \else
385       \doubleexpandafter\syst_modes_set_yes
386     \fi
387   \else
388     \singleexpandafter\syst_modes_set_check
389   \fi}
390
391\def\syst_modes_set_check
392  {\syst_modes_check_lr\syst_modes_set_yes\syst_modes_set_nop\m_mode_case}
393
394\def\syst_modes_set_yes#1%
395  {\settrue\c_syst_modes_set_done
396   #1%
397   \doifelsenextoptionalcs\syst_modes_set_start\syst_modes_set_quit}
398
399\def\syst_modes_set_nop#1%
400  {\doifelsenextoptionalcs\syst_modes_set_start\syst_modes_set_quit}
401
402\def\syst_modes_set_quit#1\stopmodeset
403  {\popmacro\c_syst_modes_set_done}
404
405\let\stopmodeset\relax
406
407%D Lets now set a mode:
408
409\enablemode[mkiv] \newsystemmode{mkiv} \setsystemmode{mkiv}
410
411%D Setups:
412
413\installcorenamespace{setup} % we can probably get rid of some :'s later on
414
415\unexpanded\def\startsetups{} % to please dep checker
416\unexpanded\def\stopsetups {} % to please dep checker
417
418\unexpanded\def\setups{\doifelsenextbgroup\syst_setups_a\syst_setups_b} % {..} or [..]
419\unexpanded\def\setup {\doifelsenextbgroup\syst_setups  \syst_setups_c} % {..} or [..]
420
421\def\syst_setups_a  #1{\processcommacommand[#1]\syst_setups} % {..}
422\def\syst_setups_b[#1]{\processcommacommand[#1]\syst_setups} % [..]
423\def\syst_setups_c[#1]{\syst_setups{#1}} % [..]
424
425\letvalue{\??setup:\??empty}\gobbleoneargument
426
427\def\syst_setups#1% the grid option will be extended to other main modes
428  {\csname\??setup
429     \ifgridsnapping
430       \ifcsname\??setup\v!grid:#1\endcsname\v!grid:#1\else:\ifcsname\??setup:#1\endcsname#1\else\??empty\fi\fi
431     \else
432                                                           :\ifcsname\??setup:#1\endcsname#1\else\??empty\fi
433     \fi
434   \endcsname\empty} % takes one argument
435
436% no checking and we assume it being defined:
437
438\def\fastsetup                     #1{\csname\??setup:#1\endcsname\empty}
439\def\fastsetupwithargument         #1{\csname\??setup:#1\endcsname}    % swapped per 2015-08-30
440\def\fastsetupwithargumentswapped#1#2{\csname\??setup:#2\endcsname{#1}}% swapped per 2015-09-05
441
442% the next one is meant for \c!setups situations, hence the check for
443% a shortcut
444
445\let\m_syst_setups_asked\empty
446
447\def\doprocesslocalsetups#1% sort of public, fast local variant
448  {\edef\m_syst_setups_asked{#1}%
449   \ifx\m_syst_setups_asked\empty\else
450     \expandafter\syst_setups_process_local
451   \fi}
452
453\unexpanded\def\usesetupsparameter#1%
454  {\edef\m_syst_setups_asked{#1\c!setups}%
455   \ifx\m_syst_setups_asked\empty\else
456     \expandafter\syst_setups_process_local
457   \fi}
458
459% setups=S1
460% setups=lua(S2)
461% setups=S3
462% setups={S1,lua(S2),xml(test{123}),S3}
463
464\def\syst_setups_process_local
465  {\clf_autosetups{\m_syst_setups_asked}%
466   \relax} % let's prevent lookahead
467
468\def\autosetups#1%
469  {\clf_autosetups{#1}}
470
471\edef\setupwithargument#1% saves a few expansions
472  {\noexpand\csname\??setup:\noexpand\ifcsname\??setup:#1\endcsname#1\noexpand\else\??empty\noexpand\fi\endcsname}
473
474\edef\setupwithargumentswapped#1#2% saves a few expansions (can be \let)
475  {\noexpand\csname\??setup:\noexpand\ifcsname\??setup:#2\endcsname#2\noexpand\else\??empty\noexpand\fi\endcsname{#1}}
476
477\let\directsetup\syst_setups
478\let\texsetup   \syst_setups % nicer than \directsetup and more en par with xmlsetup and luasetup
479
480\unexpanded\def\doifelsesetups#1% to be done: grid
481  {\ifcsname\??setup:#1\endcsname
482     \expandafter\firstoftwoarguments
483   \else
484     \expandafter\secondoftwoarguments
485   \fi}
486
487\let\doifsetupselse\doifelsesetups
488
489\unexpanded\def\doifsetups#1% to be done: grid
490  {\ifcsname\??setup:#1\endcsname
491     \expandafter\firstofoneargument
492   \else
493     \expandafter\gobbleoneargument
494   \fi}
495
496\unexpanded\def\doifnotsetups#1% to be done: grid
497  {\ifcsname\??setup:#1\endcsname
498     \expandafter\gobbleoneargument
499   \else
500     \expandafter\firstofoneargument
501   \fi}
502
503% maybe some day:
504%
505% \unexpanded\def\fastsetupfallback#1#2%
506%   {\ifcsname\??setup:#1\endcsname
507%      \expandafter\lastnamedcs
508%    \else
509%      \csname\??setup:#2\expandafter\endcsname
510%    \fi}
511%
512% or
513%
514% \unexpanded\def\fastsetupfallback#1#2#3% prefix preferred fallback
515%   {\ifcsname\??setup:#1#2\endcsname
516%      \expandafter\lastnamedcs
517%    \else
518%      \csname\??setup:#1#3\expandafter\endcsname
519%    \fi}
520
521% \startluasetups oeps
522%     context("DONE")
523%     a = 1
524%     b = 1
525% \stopluasetups
526%
527% \luasetup{oeps}
528%
529% \startsetups xxx
530%     ziezo
531% \stopsetups
532%
533% \directsetup{xxx}
534%
535% \startxmlsetups zzz
536%     [[#1]]
537% \stopxmlsetups
538%
539% \xmlsetup{123}{zzz}
540%
541% \startbuffer[what]
542%     context("DONE")
543% \stopbuffer
544%
545% \startbuffer
546%     context("MORE")
547% \stopbuffer
548%
549% \ctxluabuffer[what]
550%
551% \ctxluabuffer
552
553\newtoks\t_syst_setups_tex \appendtoks
554    \catcode\endoflineasciicode \ignorecatcode
555\to \t_syst_setups_tex
556
557\newtoks\t_syst_setups_loc \appendtoks
558    \catcode\endoflineasciicode \ignorecatcode
559\to \t_syst_setups_loc
560
561\newtoks\t_syst_setups_raw \appendtoks
562    % nothing
563\to \t_syst_setups_raw
564
565\newtoks\t_syst_setups_xml \appendtoks
566    \catcode\endoflineasciicode\ignorecatcode
567    \catcode\barasciicode      \othercatcode
568\to \t_syst_setups_xml
569
570\newtoks\t_syst_setups_lua \appendtoks
571    \obeylualines
572    \obeyluatokens
573\to \t_syst_setups_lua
574
575% Is doglobal still relevant? Maybe always global? Or never? Anyway, it will become obsolete.
576
577\let\syst_setups_def\def
578
579\unexpanded\def\pushglobalsetups{\let\syst_setups_def\gdef}
580\unexpanded\def\popglobalsetups {\let\syst_setups_def\def }
581
582\unexpanded\def\startluasetups  {\begingroup\doifelsenextoptionalcs\syst_setups_start_lua_a\syst_setups_start_lua_b} \let\stopluasetups              \relax
583\unexpanded\def\startxmlsetups  {\begingroup\doifelsenextoptionalcs\syst_setups_start_xml_a\syst_setups_start_xml_b} \let\stopxmlsetups              \relax
584\unexpanded\def\startrawsetups  {\begingroup\doifelsenextoptionalcs\syst_setups_start_raw_a\syst_setups_start_raw_b} \let\stoprawsetups              \relax
585\unexpanded\def\startlocalsetups{\begingroup\doifelsenextoptionalcs\syst_setups_start_loc_a\syst_setups_start_loc_b} \let\stoplocalsetups            \relax
586\unexpanded\def\startsetups     {\begingroup\doifelsenextoptionalcs\syst_setups_start_tex_a\syst_setups_start_tex_b} \let\stopsetups                 \relax
587
588\def\syst_setups_start_lua_indeed#1#2#3\stopluasetups  {\endgroup\dodoglobal\expandafter\syst_setups_def\csname\??setup#1:#2\expandafter\endcsname\expandafter##\expandafter1\expandafter{#3}}
589\def\syst_setups_start_xml_indeed#1#2#3\stopxmlsetups  {\endgroup\dodoglobal\expandafter\syst_setups_def\csname\??setup#1:#2\expandafter\endcsname\expandafter##\expandafter1\expandafter{#3}}
590\def\syst_setups_start_raw_indeed#1#2#3\stoprawsetups  {\endgroup\dodoglobal\expandafter\syst_setups_def\csname\??setup#1:#2\expandafter\endcsname\expandafter##\expandafter1\expandafter{#3}}
591\def\syst_setups_start_loc_indeed#1#2#3\stoplocalsetups{\endgroup\dodoglobal\expandafter\syst_setups_def\csname\??setup#1:#2\expandafter\endcsname\expandafter##\expandafter1\expandafter{#3}}
592\def\syst_setups_start_tex_indeed#1#2#3\stopsetups     {\endgroup\dodoglobal\expandafter\syst_setups_def\csname\??setup#1:#2\expandafter\endcsname\expandafter##\expandafter1\expandafter{#3}}
593
594\def\syst_setups_start_lua{\ifsecondargument\expandafter\syst_setups_start_lua_c\else\expandafter\syst_setups_start_lua_d\fi}
595\def\syst_setups_start_xml{\ifsecondargument\expandafter\syst_setups_start_xml_c\else\expandafter\syst_setups_start_xml_d\fi}
596\def\syst_setups_start_raw{\ifsecondargument\expandafter\syst_setups_start_raw_c\else\expandafter\syst_setups_start_raw_d\fi}
597\def\syst_setups_start_loc{\ifsecondargument\expandafter\syst_setups_start_loc_c\else\expandafter\syst_setups_start_loc_d\fi}
598\def\syst_setups_start_tex{\ifsecondargument\expandafter\syst_setups_start_tex_c\else\expandafter\syst_setups_start_tex_d\fi}
599
600% no need for \the\t_syst_setups_lua in the next, now too often
601
602\def\syst_setups_start_lua_a{\the\t_syst_setups_lua\dodoubleempty\syst_setups_start_lua} % [ ] delimited
603\def\syst_setups_start_xml_a{\the\t_syst_setups_xml\dodoubleempty\syst_setups_start_xml} % [ ] delimited
604\def\syst_setups_start_raw_a{\the\t_syst_setups_raw\dodoubleempty\syst_setups_start_raw} % [ ] delimited
605\def\syst_setups_start_loc_a{\the\t_syst_setups_loc\dodoubleempty\syst_setups_start_loc} % [ ] delimited
606\def\syst_setups_start_tex_a{\the\t_syst_setups_tex\dodoubleempty\syst_setups_start_tex} % [ ] delimited
607
608% empty preserves inner {} (is removed by the \expandafter{#3}) .. hm, looks old
609
610\def\syst_setups_start_lua_b#1 {\the\t_syst_setups_lua\syst_setups_start_lua_indeed\empty{#1}\empty} % space delimited
611\def\syst_setups_start_xml_b#1 {\the\t_syst_setups_xml\syst_setups_start_xml_indeed\empty{#1}\empty} % space delimited
612\def\syst_setups_start_raw_b#1 {\the\t_syst_setups_raw\syst_setups_start_raw_indeed\empty{#1}\empty} % space delimited
613\def\syst_setups_start_loc_b#1 {\the\t_syst_setups_loc\syst_setups_start_loc_indeed\empty{#1}\empty} % space delimited
614\def\syst_setups_start_tex_b#1 {\the\t_syst_setups_tex\syst_setups_start_tex_indeed\empty{#1}\empty} % space delimited
615
616\def\syst_setups_start_lua_c[#1][#2]{\the\t_syst_setups_lua\syst_setups_start_lua_indeed{#1}{#2}\empty} % [..] [..]
617\def\syst_setups_start_xml_c[#1][#2]{\the\t_syst_setups_xml\syst_setups_start_xml_indeed{#1}{#2}\empty} % [..] [..]
618\def\syst_setups_start_raw_c[#1][#2]{\the\t_syst_setups_raw\syst_setups_start_raw_indeed{#1}{#2}\empty} % [..] [..]
619\def\syst_setups_start_loc_c[#1][#2]{\the\t_syst_setups_loc\syst_setups_start_loc_indeed{#1}{#2}\empty} % [..] [..]
620\def\syst_setups_start_tex_c[#1][#2]{\the\t_syst_setups_tex\syst_setups_start_tex_indeed{#1}{#2}\empty} % [..] [..]
621
622\def\syst_setups_start_lua_d[#1][#2]{\the\t_syst_setups_lua\syst_setups_start_lua_indeed\empty{#1}\empty} % [..]
623\def\syst_setups_start_xml_d[#1][#2]{\the\t_syst_setups_xml\syst_setups_start_xml_indeed\empty{#1}\empty} % [..]
624\def\syst_setups_start_raw_d[#1][#2]{\the\t_syst_setups_raw\syst_setups_start_raw_indeed\empty{#1}\empty} % [..]
625\def\syst_setups_start_loc_d[#1][#2]{\the\t_syst_setups_loc\syst_setups_start_loc_indeed\empty{#1}\empty} % [..]
626\def\syst_setups_start_tex_d[#1][#2]{\the\t_syst_setups_tex\syst_setups_start_tex_indeed\empty{#1}\empty} % [..]
627
628\def\luasetup#1{\ctxlua{\syst_setups{#1}}}
629
630%D System setups:
631
632\let\systemsetupsprefix\wildcardsymbol
633
634\def\systemsetups#1{\syst_setups{\systemsetupsprefix#1}}
635
636\unexpanded\def\resetsetups[#1]% see x-fo for usage
637  {\ifcsname\??setup\ifgridsnapping\v!grid\fi:#1\endcsname
638     \dodoglobal\undefinevalue{\??setup\ifgridsnapping\v!grid\fi:#1}%
639   \else
640     \dodoglobal\undefinevalue{\??setup:#1}%
641   \fi}
642
643\unexpanded\def\copysetups
644  {\dodoubleargument\syst_setups_copy}
645
646\def\syst_setups_copy[#1][#2]%
647  {\ifcsname\??setup:#2\endcsname
648      \expandafter\let\csname\??setup:#1\expandafter\endcsname\lastnamedcs
649   \fi}
650
651\unexpanded\def\showsetupsdefinition[#1]%
652  {\showvalue{\??setup:#1}} % temp hack for debugging
653
654%D \macros
655%D   {setvariables,getvariable,getvariabledefault}
656%D
657%D \starttyping
658%D \setvariables[xx][title=]
659%D \setvariables[xx][title=test test]
660%D \setvariables[xx][title=test $x=1$ test]   % fatal error reported
661%D \setvariables[xx][title=test {$x=1$} test]
662%D \setvariables[xx][title]                   % fatal error reported
663%D \setvariables[xx][titletitel=e]
664%D \stoptyping
665
666\installcorenamespace{variables}
667
668\unexpanded\def\setvariables {\dotripleargument\syst_variables_set[\getrawparameters ]}
669\unexpanded\def\setevariables{\dotripleargument\syst_variables_set[\getraweparameters]}
670\unexpanded\def\setgvariables{\dotripleargument\syst_variables_set[\getrawgparameters]}
671\unexpanded\def\setxvariables{\dotripleargument\syst_variables_set[\getrawxparameters]}
672
673\unexpanded\def\globalsetvariables % obsolete
674  {\dotripleargument\syst_variables_set[\globalgetrawparameters]}
675
676\def\syst_variables_set[#1][#2][#3]% tricky, test on s-pre-60
677  {\doifelse{#2}\currentvariableclass
678     {#1[\??variables#2:][#3]}%
679     {\pushmacro\currentvariableclass
680      \def\currentvariableclass{#2}%
681      \getvariable{#2}\s!reset
682      #1[\??variables#2:][#3]%
683      \getvariable{#2}\s!set
684      \popmacro\currentvariableclass}}
685
686\unexpanded\def\setvariable #1#2#3{\expandafter\def \csname\??variables#1:#2\endcsname{#3}}
687\unexpanded\def\setevariable#1#2#3{\expandafter\edef\csname\??variables#1:#2\endcsname{#3}}
688\unexpanded\def\setgvariable#1#2#3{\expandafter\gdef\csname\??variables#1:#2\endcsname{#3}}
689\unexpanded\def\setxvariable#1#2#3{\expandafter\xdef\csname\??variables#1:#2\endcsname{#3}}
690
691\def\getvariable#1#2%
692  {\begincsname\??variables#1:#2\endcsname}
693
694\def\showvariable#1#2%
695  {\showvalue{\begincsname\??variables#1:#2\endcsname}}
696
697\let\currentvariableclass\empty
698
699%D \macros
700%D   {checkvariables}
701%D
702%D I'll probably forget that this on exists.
703
704\let\m_syst_variables_temp\empty
705
706\def\checkvariables
707  {\dodoubleargument\syst_variables_check}
708
709\def\syst_variables_check
710  {\dogetparameters\syst_variables_check_value}
711
712\def\syst_variables_check_value#1#2#3%
713  {\ifcsname\??variables#1:#2\endcsname
714     \edef\m_syst_variables_temp{\lastnamedcs}%
715     \ifx\m_syst_variables_temp\empty
716       \expandafter\def\csname\??variables#1:#2\endcsname{#3}%
717     \fi
718   \else
719     \expandafter\def\csname\??variables#1:#2\endcsname{#3}%
720   \fi}
721
722%D \macros
723%D   {doifelsevariable,doifvariable,doifnotvariable}
724%D
725%D A few trivial macros:
726
727\unexpanded\def\doifelsevariable#1#2%
728  {\ifcsname\??variables#1:#2\endcsname
729     \expandafter\firstoftwoarguments
730   \else
731     \expandafter\secondoftwoarguments
732   \fi}
733
734\let\doifvariableelse\doifelsevariable
735
736\unexpanded\def\doifvariable#1#2%
737  {\ifcsname\??variables#1:#2\endcsname
738     \expandafter\firstofoneargument
739   \else
740     \expandafter\gobbleoneargument
741   \fi}
742
743\unexpanded\def\doifnotvariable#1#2%
744  {\ifcsname\??variables#1:#2\endcsname
745     \expandafter\gobbleoneargument
746   \else
747     \expandafter\firstofoneargument
748   \fi}
749
750%D A few more (we could use a public test variable so that we only need to expand
751%D once, assuming expandable variables):
752
753\letvalue{\??variables:}\empty
754
755\unexpanded\def\doifelseemptyvariable#1#2%
756  {\edef\m_syst_string_one{\begincsname\??variables#1:#2\endcsname}%
757   \ifx\m_syst_string_one\empty
758     \expandafter\firstoftwoarguments
759   \else
760     \expandafter\secondoftwoarguments
761   \fi}
762
763\let\doifemptyvariableelse\doifelseemptyvariable
764
765\unexpanded\def\doifemptyvariable#1#2%
766  {\edef\m_syst_string_one{\begincsname\??variables#1:#2\endcsname}%
767   \ifx\m_syst_string_one\empty
768     \expandafter\firstofoneargument
769   \else
770     \expandafter\gobbleoneargument
771   \fi}
772
773\unexpanded\def\doifnotemptyvariable#1#2%
774  {\edef\m_syst_string_one{\begincsname\??variables#1:#2\endcsname}%
775   \ifx\m_syst_string_one\empty
776     \expandafter\gobbleoneargument
777   \else
778     \expandafter\firstofoneargument
779   \fi}
780
781\def\getvariabledefault#1#2% #3% can be command
782  {\ifcsname\??variables#1:#2\endcsname
783     \expandafter\expandafter\expandafter\lastnamedcs\expandafter\gobbleoneargument
784   \else
785     \expandafter\firstofoneargument
786   \fi}
787
788\unexpanded\def\setupenv
789  {\dotripleargument\syst_variables_set[\getrawparameters][\s!environment]}
790
791\unexpanded\def\doifelseenv{\doifelsevariable  \s!environment}
792\unexpanded\def\doifenv    {\doifvariable      \s!environment}
793\unexpanded\def\doifnotenv {\doifnotvariable   \s!environment}
794\def\env                   {\getvariable       \s!environment}
795\def\envvar                {\getvariabledefault\s!environment}
796
797\let\doifenvelse\doifelseenv
798
799%D \macros
800%D   {defineselector,setupselector,select,directselect}
801%D
802%D \starttyping
803%D \defineselector[caption][max=2,n=2]
804%D
805%D \start
806%D     \setupselector[caption][n=1]
807%D     \placelist[figure][criterium=all]
808%D \stop
809%D
810%D \starttext
811%D     \placefigure
812%D       {\select{caption}{zapf}{\input zapf \relax}}
813%D       {}
814%D \stoptext
815%D \stoptyping
816
817\installcorenamespace{selector}
818
819\unexpanded\def\defineselector{\dodoubleargument\syst_selectors_define}
820\unexpanded\def\setupselector {\dodoubleargument\syst_selectors_setup}
821
822% \def\syst_selectors_define[#1][#2]{\getparameters[\??selector#1][\c!max=\plusone,\c!n=\plusone,#2]}
823% \def\syst_selectors_setup [#1][#2]{\getparameters[\??selector#1][#2]}
824
825\def\syst_selectors_define[#1][{\getparameters[\??selector#1][\c!max=\plustwo,\c!n=\plusone,}
826\def\syst_selectors_setup [#1][{\getparameters[\??selector#1][}
827
828\unexpanded\def\select % unexpandable
829  {\directselect}
830
831% \def\directselect#1% expandable
832%   {\filterfromnext % maybe add an \expanded
833%      {\csname\??selector\ifcsname\??selector#1\c!max\endcsname#1\fi\c!max\endcsname}%
834%      {\csname\??selector\ifcsname\??selector#1\c!n  \endcsname#1\fi\c!n  \endcsname}}
835%
836% this is more efficient when the arguments are used a few times (or passed along):
837
838\def\directselect#1% expandable
839  {\expandafter\filterfromnext
840     \csname\??selector\ifcsname\??selector#1\c!max\endcsname#1\fi\c!max\expandafter\endcsname
841     \csname\??selector\ifcsname\??selector#1\c!n  \endcsname#1\fi\c!n  \endcsname}
842
843\letvalue{\??selector\c!max}\plusone
844\letvalue{\??selector\c!n  }\plusone
845
846\protect \endinput
847