core-env.mkiv /size: 28 Kb    last modification: 2021-10-28 13:50
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\unexpanded\def\startluasetups  {\begingroup\doifelsenextoptionalcs\syst_setups_start_lua_a\syst_setups_start_lua_b} \let\stopluasetups              \relax
578\unexpanded\def\startxmlsetups  {\begingroup\doifelsenextoptionalcs\syst_setups_start_xml_a\syst_setups_start_xml_b} \let\stopxmlsetups              \relax
579\unexpanded\def\startrawsetups  {\begingroup\doifelsenextoptionalcs\syst_setups_start_raw_a\syst_setups_start_raw_b} \let\stoprawsetups              \relax
580\unexpanded\def\startlocalsetups{\begingroup\doifelsenextoptionalcs\syst_setups_start_loc_a\syst_setups_start_loc_b} \let\stoplocalsetups            \relax
581\unexpanded\def\startsetups     {\begingroup\doifelsenextoptionalcs\syst_setups_start_tex_a\syst_setups_start_tex_b} \let\stopsetups                 \relax
582
583\def\syst_setups_start_lua_indeed#1#2#3\stopluasetups  {\endgroup\dodoglobal\expandafter\def\csname\??setup#1:#2\expandafter\endcsname\expandafter##\expandafter1\expandafter{#3}}
584\def\syst_setups_start_xml_indeed#1#2#3\stopxmlsetups  {\endgroup\dodoglobal\expandafter\def\csname\??setup#1:#2\expandafter\endcsname\expandafter##\expandafter1\expandafter{#3}}
585\def\syst_setups_start_raw_indeed#1#2#3\stoprawsetups  {\endgroup\dodoglobal\expandafter\def\csname\??setup#1:#2\expandafter\endcsname\expandafter##\expandafter1\expandafter{#3}}
586\def\syst_setups_start_loc_indeed#1#2#3\stoplocalsetups{\endgroup\dodoglobal\expandafter\def\csname\??setup#1:#2\expandafter\endcsname\expandafter##\expandafter1\expandafter{#3}}
587\def\syst_setups_start_tex_indeed#1#2#3\stopsetups     {\endgroup\dodoglobal\expandafter\def\csname\??setup#1:#2\expandafter\endcsname\expandafter##\expandafter1\expandafter{#3}}
588
589\def\syst_setups_start_lua{\ifsecondargument\expandafter\syst_setups_start_lua_c\else\expandafter\syst_setups_start_lua_d\fi}
590\def\syst_setups_start_xml{\ifsecondargument\expandafter\syst_setups_start_xml_c\else\expandafter\syst_setups_start_xml_d\fi}
591\def\syst_setups_start_raw{\ifsecondargument\expandafter\syst_setups_start_raw_c\else\expandafter\syst_setups_start_raw_d\fi}
592\def\syst_setups_start_loc{\ifsecondargument\expandafter\syst_setups_start_loc_c\else\expandafter\syst_setups_start_loc_d\fi}
593\def\syst_setups_start_tex{\ifsecondargument\expandafter\syst_setups_start_tex_c\else\expandafter\syst_setups_start_tex_d\fi}
594
595% no need for \the\t_syst_setups_lua in the next, now too often
596
597\def\syst_setups_start_lua_a{\the\t_syst_setups_lua\dodoubleempty\syst_setups_start_lua} % [ ] delimited
598\def\syst_setups_start_xml_a{\the\t_syst_setups_xml\dodoubleempty\syst_setups_start_xml} % [ ] delimited
599\def\syst_setups_start_raw_a{\the\t_syst_setups_raw\dodoubleempty\syst_setups_start_raw} % [ ] delimited
600\def\syst_setups_start_loc_a{\the\t_syst_setups_loc\dodoubleempty\syst_setups_start_loc} % [ ] delimited
601\def\syst_setups_start_tex_a{\the\t_syst_setups_tex\dodoubleempty\syst_setups_start_tex} % [ ] delimited
602
603% empty preserves inner {} (is removed by the \expandafter{#3}) .. hm, looks old
604
605\def\syst_setups_start_lua_b#1 {\the\t_syst_setups_lua\syst_setups_start_lua_indeed\empty{#1}\empty} % space delimited
606\def\syst_setups_start_xml_b#1 {\the\t_syst_setups_xml\syst_setups_start_xml_indeed\empty{#1}\empty} % space delimited
607\def\syst_setups_start_raw_b#1 {\the\t_syst_setups_raw\syst_setups_start_raw_indeed\empty{#1}\empty} % space delimited
608\def\syst_setups_start_loc_b#1 {\the\t_syst_setups_loc\syst_setups_start_loc_indeed\empty{#1}\empty} % space delimited
609\def\syst_setups_start_tex_b#1 {\the\t_syst_setups_tex\syst_setups_start_tex_indeed\empty{#1}\empty} % space delimited
610
611\def\syst_setups_start_lua_c[#1][#2]{\the\t_syst_setups_lua\syst_setups_start_lua_indeed{#1}{#2}\empty} % [..] [..]
612\def\syst_setups_start_xml_c[#1][#2]{\the\t_syst_setups_xml\syst_setups_start_xml_indeed{#1}{#2}\empty} % [..] [..]
613\def\syst_setups_start_raw_c[#1][#2]{\the\t_syst_setups_raw\syst_setups_start_raw_indeed{#1}{#2}\empty} % [..] [..]
614\def\syst_setups_start_loc_c[#1][#2]{\the\t_syst_setups_loc\syst_setups_start_loc_indeed{#1}{#2}\empty} % [..] [..]
615\def\syst_setups_start_tex_c[#1][#2]{\the\t_syst_setups_tex\syst_setups_start_tex_indeed{#1}{#2}\empty} % [..] [..]
616
617\def\syst_setups_start_lua_d[#1][#2]{\the\t_syst_setups_lua\syst_setups_start_lua_indeed\empty{#1}\empty} % [..]
618\def\syst_setups_start_xml_d[#1][#2]{\the\t_syst_setups_xml\syst_setups_start_xml_indeed\empty{#1}\empty} % [..]
619\def\syst_setups_start_raw_d[#1][#2]{\the\t_syst_setups_raw\syst_setups_start_raw_indeed\empty{#1}\empty} % [..]
620\def\syst_setups_start_loc_d[#1][#2]{\the\t_syst_setups_loc\syst_setups_start_loc_indeed\empty{#1}\empty} % [..]
621\def\syst_setups_start_tex_d[#1][#2]{\the\t_syst_setups_tex\syst_setups_start_tex_indeed\empty{#1}\empty} % [..]
622
623\def\luasetup#1{\ctxlua{\syst_setups{#1}}}
624
625%D System setups:
626
627\let\systemsetupsprefix\wildcardsymbol
628
629\def\systemsetups#1{\syst_setups{\systemsetupsprefix#1}}
630
631\unexpanded\def\resetsetups[#1]% see x-fo for usage
632  {\ifcsname\??setup\ifgridsnapping\v!grid\fi:#1\endcsname
633     \dodoglobal\undefinevalue{\??setup\ifgridsnapping\v!grid\fi:#1}%
634   \else
635     \dodoglobal\undefinevalue{\??setup:#1}%
636   \fi}
637
638\unexpanded\def\copysetups
639  {\dodoubleargument\syst_setups_copy}
640
641\def\syst_setups_copy[#1][#2]%
642  {\ifcsname\??setup:#2\endcsname
643      \expandafter\let\csname\??setup:#1\expandafter\endcsname\lastnamedcs
644   \fi}
645
646\unexpanded\def\showsetupsdefinition[#1]%
647  {\showvalue{\??setup:#1}} % temp hack for debugging
648
649%D \macros
650%D   {setvariables,getvariable,getvariabledefault}
651%D
652%D \starttyping
653%D \setvariables[xx][title=]
654%D \setvariables[xx][title=test test]
655%D \setvariables[xx][title=test $x=1$ test]   % fatal error reported
656%D \setvariables[xx][title=test {$x=1$} test]
657%D \setvariables[xx][title]                   % fatal error reported
658%D \setvariables[xx][titletitel=e]
659%D \stoptyping
660
661\installcorenamespace{variables}
662
663\unexpanded\def\setvariables {\dotripleargument\syst_variables_set[\getrawparameters ]}
664\unexpanded\def\setevariables{\dotripleargument\syst_variables_set[\getraweparameters]}
665\unexpanded\def\setgvariables{\dotripleargument\syst_variables_set[\getrawgparameters]}
666\unexpanded\def\setxvariables{\dotripleargument\syst_variables_set[\getrawxparameters]}
667
668\unexpanded\def\globalsetvariables % obsolete
669  {\dotripleargument\syst_variables_set[\globalgetrawparameters]}
670
671\def\syst_variables_set[#1][#2][#3]% tricky, test on s-pre-60
672  {\doifelse{#2}\currentvariableclass
673     {#1[\??variables#2:][#3]}%
674     {\pushmacro\currentvariableclass
675      \def\currentvariableclass{#2}%
676      \getvariable{#2}\s!reset
677      #1[\??variables#2:][#3]%
678      \getvariable{#2}\s!set
679      \popmacro\currentvariableclass}}
680
681\unexpanded\def\setvariable #1#2#3{\expandafter\def \csname\??variables#1:#2\endcsname{#3}}
682\unexpanded\def\setevariable#1#2#3{\expandafter\edef\csname\??variables#1:#2\endcsname{#3}}
683\unexpanded\def\setgvariable#1#2#3{\expandafter\gdef\csname\??variables#1:#2\endcsname{#3}}
684\unexpanded\def\setxvariable#1#2#3{\expandafter\xdef\csname\??variables#1:#2\endcsname{#3}}
685
686\def\getvariable#1#2%
687  {\begincsname\??variables#1:#2\endcsname}
688
689\def\showvariable#1#2%
690  {\showvalue{\begincsname\??variables#1:#2\endcsname}}
691
692\let\currentvariableclass\empty
693
694%D \macros
695%D   {checkvariables}
696%D
697%D I'll probably forget that this on exists.
698
699\let\m_syst_variables_temp\empty
700
701\def\checkvariables
702  {\dodoubleargument\syst_variables_check}
703
704\def\syst_variables_check
705  {\dogetparameters\syst_variables_check_value}
706
707\def\syst_variables_check_value#1#2#3%
708  {\ifcsname\??variables#1:#2\endcsname
709     \edef\m_syst_variables_temp{\lastnamedcs}%
710     \ifx\m_syst_variables_temp\empty
711       \expandafter\def\csname\??variables#1:#2\endcsname{#3}%
712     \fi
713   \else
714     \expandafter\def\csname\??variables#1:#2\endcsname{#3}%
715   \fi}
716
717%D \macros
718%D   {doifelsevariable,doifvariable,doifnotvariable}
719%D
720%D A few trivial macros:
721
722\unexpanded\def\doifelsevariable#1#2%
723  {\ifcsname\??variables#1:#2\endcsname
724     \expandafter\firstoftwoarguments
725   \else
726     \expandafter\secondoftwoarguments
727   \fi}
728
729\let\doifvariableelse\doifelsevariable
730
731\unexpanded\def\doifvariable#1#2%
732  {\ifcsname\??variables#1:#2\endcsname
733     \expandafter\firstofoneargument
734   \else
735     \expandafter\gobbleoneargument
736   \fi}
737
738\unexpanded\def\doifnotvariable#1#2%
739  {\ifcsname\??variables#1:#2\endcsname
740     \expandafter\gobbleoneargument
741   \else
742     \expandafter\firstofoneargument
743   \fi}
744
745%D A few more (we could use a public test variable so that we only need to expand
746%D once, assuming expandable variables):
747
748\letvalue{\??variables:}\empty
749
750\unexpanded\def\doifelseemptyvariable#1#2%
751  {\edef\m_syst_string_one{\begincsname\??variables#1:#2\endcsname}%
752   \ifx\m_syst_string_one\empty
753     \expandafter\firstoftwoarguments
754   \else
755     \expandafter\secondoftwoarguments
756   \fi}
757
758\let\doifemptyvariableelse\doifelseemptyvariable
759
760\unexpanded\def\doifemptyvariable#1#2%
761  {\edef\m_syst_string_one{\begincsname\??variables#1:#2\endcsname}%
762   \ifx\m_syst_string_one\empty
763     \expandafter\firstofoneargument
764   \else
765     \expandafter\gobbleoneargument
766   \fi}
767
768\unexpanded\def\doifnotemptyvariable#1#2%
769  {\edef\m_syst_string_one{\begincsname\??variables#1:#2\endcsname}%
770   \ifx\m_syst_string_one\empty
771     \expandafter\gobbleoneargument
772   \else
773     \expandafter\firstofoneargument
774   \fi}
775
776\def\getvariabledefault#1#2% #3% can be command
777  {\ifcsname\??variables#1:#2\endcsname
778     \expandafter\expandafter\expandafter\lastnamedcs\expandafter\gobbleoneargument
779   \else
780     \expandafter\firstofoneargument
781   \fi}
782
783\unexpanded\def\setupenv
784  {\dotripleargument\syst_variables_set[\getrawparameters][\s!environment]}
785
786\unexpanded\def\doifelseenv{\doifelsevariable  \s!environment}
787\unexpanded\def\doifenv    {\doifvariable      \s!environment}
788\unexpanded\def\doifnotenv {\doifnotvariable   \s!environment}
789\def\env                   {\getvariable       \s!environment}
790\def\envvar                {\getvariabledefault\s!environment}
791
792\let\doifenvelse\doifelseenv
793
794%D \macros
795%D   {defineselector,setupselector,select,directselect}
796%D
797%D \starttyping
798%D \defineselector[caption][max=2,n=2]
799%D
800%D \start
801%D     \setupselector[caption][n=1]
802%D     \placelist[figure][criterium=all]
803%D \stop
804%D
805%D \starttext
806%D     \placefigure
807%D       {\select{caption}{zapf}{\input zapf \relax}}
808%D       {}
809%D \stoptext
810%D \stoptyping
811
812\installcorenamespace{selector}
813
814\unexpanded\def\defineselector{\dodoubleargument\syst_selectors_define}
815\unexpanded\def\setupselector {\dodoubleargument\syst_selectors_setup}
816
817% \def\syst_selectors_define[#1][#2]{\getparameters[\??selector#1][\c!max=\plusone,\c!n=\plusone,#2]}
818% \def\syst_selectors_setup [#1][#2]{\getparameters[\??selector#1][#2]}
819
820\def\syst_selectors_define[#1][{\getparameters[\??selector#1][\c!max=\plustwo,\c!n=\plusone,}
821\def\syst_selectors_setup [#1][{\getparameters[\??selector#1][}
822
823\unexpanded\def\select % unexpandable
824  {\directselect}
825
826% \def\directselect#1% expandable
827%   {\filterfromnext % maybe add an \expanded
828%      {\csname\??selector\ifcsname\??selector#1\c!max\endcsname#1\fi\c!max\endcsname}%
829%      {\csname\??selector\ifcsname\??selector#1\c!n  \endcsname#1\fi\c!n  \endcsname}}
830%
831% this is more efficient when the arguments are used a few times (or passed along):
832
833\def\directselect#1% expandable
834  {\expandafter\filterfromnext
835     \csname\??selector\ifcsname\??selector#1\c!max\endcsname#1\fi\c!max\expandafter\endcsname
836     \csname\??selector\ifcsname\??selector#1\c!n  \endcsname#1\fi\c!n  \endcsname}
837
838\letvalue{\??selector\c!max}\plusone
839\letvalue{\??selector\c!n  }\plusone
840
841\protect \endinput
842