strc-num.mkiv /size: 35 Kb    last modification: 2020-07-01 14:35
1%D \module
2%D   [       file=strc-num,
3%D        version=2008.10.20,
4%D          title=\CONTEXT\ Structure Macros,
5%D       subtitle=Basic Numbering,
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 Structure Macros / Basic Numbering}
15
16\registerctxluafile{strc-num}{}
17
18\unprotect
19
20\startcontextdefinitioncode
21
22% work in progress
23% to be checked: can we use the command handler code here?
24% all settings will move to lua
25
26\installcorenamespace{counter}
27
28\installcommandhandler \??counter {counter} \??counter
29
30\let\setupcounters\setupcounter
31
32\let\setupstructurecounting\setupcounter % will disappear
33
34\setupcounter
35  [\c!way=\v!by\v!chapter,
36%  \c!blockway=,
37%  \c!prefixstarter=,
38%  \c!prefixstopper=,
39   \c!prefixconnector=.,
40   \c!prefixsegments=\autostructureprefixsegments\rootcounterparameter,
41   \c!start=\zerocount,
42   \c!prefix=\v!yes,
43   \c!state=\v!start]
44
45\def\autostructureprefixsegments#1% todo: \c!prefixsegments=\v!auto
46  {2:\thenamedheadlevel{\clf_way{#1\c!way}}}
47
48\appendtoks
49    \resetcounterparameter\s!counter
50\to \everypresetcounter
51
52\appendtoks
53    \ifx\currentcounterparent\empty
54        \edef\p_start{\counterparameter\c!start}%
55        \clf_definecounter
56           name    {\currentcounter}%
57           start   \ifx\p_start\empty\zerocount\else\numexpr\p_start\relax\fi
58           counter {\counterparameter\s!counter}%
59           method  {\counterparameter\c!method}%
60        \relax
61        \letcounterparameter\s!name\currentcounter
62    \else
63      % \letcounterparameter\s!name\currentcounterparent % we need a chained clone
64        \setexpandedcounterparameter\s!name{\namedcounterparameter\currentcounterparent\s!name}%
65    \fi
66    \strc_counters_check_setup
67\to \everydefinecounter
68
69\appendtoks
70    \ifx\currentcounter\empty \else
71        \edef\p_number{\counterparameter\c!number}%
72        \ifx\p_number\empty \else
73          \clf_setcounter{\counterparameter\s!name}\numexpr\p_number\relax
74          \letcounterparameter\c!number\empty
75        \fi
76        \edef\p_start{\counterparameter\c!start}%
77        \setexpandedcounterparameter\c!start{\ifx\p_start\empty0\else\number\p_start\fi}%
78        \strc_counters_check_setup
79    \fi
80\to \everysetupcounter
81
82% % % %
83
84\def\strc_counters_way#1{\clf_way{\namedcounterparameter{#1}\c!way}}
85
86\def\thenamedcounterlevel#1%
87  {\xthenamedheadlevel{\clf_way{\namedcounterparameter{#1}\c!way}}}
88
89\unexpanded\def\strc_counters_check_setup
90  {\edef\p_name{\directcounterparameter\s!name}%
91   \ifx\currentcounter\p_name
92     \edef\currentcounterlevel{\thenamedcounterlevel\currentcounter}%
93     \edef\p_start{\counterparameter\c!start}%
94     \clf_checkcountersetup
95       {\currentcounter}%
96       \numexpr\currentcounterlevel\relax
97       \numexpr\ifx\p_start\empty\zerocount\else\p_start\fi\relax % bug in scanner
98       {\counterparameter\c!state}%
99   \fi}
100
101\unexpanded\def\doifelsecounter #1{\clf_doifelsecounter{\namedcounterparameter{#1}\s!name}}
102\unexpanded\def\doifcounter     #1{\clf_doifcounter    {\namedcounterparameter{#1}\s!name}}
103\unexpanded\def\doifnotcounter  #1{\clf_doifnotcounter {\namedcounterparameter{#1}\s!name}}
104
105\let\doifcounterelse\doifelsecounter
106
107\unexpanded\def\setcounter        {\dotripleempty   \strc_counters_set_interfaced}
108\unexpanded\def\setcounterown     {\dotripleempty   \strc_counters_setown_interfaced}
109\unexpanded\def\restartcounter    {\dotripleempty   \strc_counters_restart_interfaced}
110\unexpanded\def\resetcounter      {\dodoubleempty   \strc_counters_reset_interfaced}
111\unexpanded\def\incrementcounter  {\dodoubleempty   \strc_counters_increment_interfaced}
112\unexpanded\def\decrementcounter  {\dodoubleempty   \strc_counters_decrement_interfaced}
113
114\unexpanded\def\rawcounter        {\dodoubleargument\strc_counters_raw_interfaced}
115\unexpanded\def\lastcounter       {\dodoubleargument\strc_counters_last_interfaced}
116\unexpanded\def\firstcounter      {\dodoubleargument\strc_counters_first_interfaced}
117\unexpanded\def\nextcounter       {\dodoubleargument\strc_counters_next_interfaced}
118\unexpanded\def\prevcounter       {\dodoubleargument\strc_counters_prev_interfaced}
119\unexpanded\def\countersubs       {\dodoubleargument\strc_counters_subs_interfaced}
120
121\unexpanded\def\savecounter       {\dosingleempty   \strc_counters_save_interfaced}
122\unexpanded\def\restorecounter    {\dosingleempty   \strc_counters_restore_interfaced}
123
124\def\strc_counters_set_interfaced
125  {\ifthirdargument
126     \singleexpandafter\strc_counters_set_two
127   \else\ifsecondargument
128     \doubleexpandafter\strc_counters_set_one
129   \else
130     \doubleexpandafter\gobblethreeoptionals
131   \fi\fi}
132
133\def\strc_counters_setown_interfaced
134  {\ifthirdargument
135     \singleexpandafter\strc_counters_setown_two
136   \else\ifsecondargument
137     \doubleexpandafter\strc_counters_setown_one
138   \else
139     \doubleexpandafter\gobblethreeoptionals
140   \fi\fi}
141
142\def\strc_counters_restart_interfaced
143  {\ifthirdargument
144     \singleexpandafter\strc_counters_restart_two
145   \else\ifsecondargument
146     \doubleexpandafter\strc_counters_restart_one
147   \else
148     \doubleexpandafter\gobblethreeoptionals
149   \fi\fi}
150
151\def\strc_counters_reset_interfaced
152  {\ifsecondargument
153     \singleexpandafter\strc_counters_reset_two
154   \else\iffirstargument
155     \doubleexpandafter\strc_counters_reset_one
156   \else
157     \doubleexpandafter\gobbletwooptionals
158   \fi\fi}
159
160\def\strc_counters_increment_interfaced
161  {\ifsecondargument
162     \singleexpandafter\strc_counters_increment_two
163   \else\iffirstargument
164     \doubleexpandafter\strc_counters_increment_one
165   \else
166     \doubleexpandafter\gobbletwooptionals
167   \fi\fi}
168
169\def\strc_counters_decrement_interfaced
170  {\ifsecondargument
171     \singleexpandafter\strc_counters_decrement_two
172   \else\iffirstargument
173     \doubleexpandafter\strc_counters_decrement_one
174   \else
175     \doubleexpandafter\gobbletwooptionals
176   \fi\fi}
177
178\def\strc_counters_raw_interfaced
179  {\ifsecondargument
180     \singleexpandafter\strc_counters_raw_two
181   \else\iffirstargument
182     \doubleexpandafter\strc_counters_raw_one
183   \else
184     \doubleexpandafter\gobbletwooptionals
185   \fi\fi}
186
187\def\strc_counters_last_interfaced
188  {\ifsecondargument
189     \singleexpandafter\strc_counters_last_two
190   \else\iffirstargument
191     \doubleexpandafter\strc_counters_last_one
192   \else
193     \doubleexpandafter\gobbletwooptionals
194   \fi\fi}
195
196\def\strc_counters_first_interfaced
197  {\ifsecondargument
198     \singleexpandafter\strc_counters_first_two
199   \else\iffirstargument
200     \doubleexpandafter\strc_counters_first_one
201   \else
202     \doubleexpandafter\gobbletwooptionals
203   \fi\fi}
204
205\def\strc_counters_prev_interfaced
206  {\ifsecondargument
207     \singleexpandafter\strc_counters_prev_two
208   \else\iffirstargument
209     \doubleexpandafter\strc_counters_prev_one
210   \else
211     \doubleexpandafter\gobbletwooptionals
212   \fi\fi}
213
214\def\strc_counters_next_interfaced
215  {\ifsecondargument
216     \singleexpandafter\strc_counters_next_two
217   \else\iffirstargument
218     \doubleexpandafter\strc_counters_next_one
219   \else
220     \doubleexpandafter\gobbletwooptionals
221   \fi\fi}
222
223\def\strc_counters_subs_interfaced
224  {\ifsecondargument
225     \singleexpandafter\strc_counters_subs_two
226   \else\iffirstargument
227     \doubleexpandafter\strc_counters_subs_one
228   \else
229     \doubleexpandafter\gobbletwooptionals
230   \fi\fi}
231
232\def\strc_counters_save_interfaced
233  {\iffirstargument
234     \expandafter\strc_counters_save_one
235   \else
236     \expandafter\gobbleoneoptional
237   \fi}
238
239\def\strc_counters_restore_interfaced
240  {\iffirstargument
241     \expandafter\strc_counters_restore_one
242   \else
243     \expandafter\gobbleoneoptional
244   \fi}
245
246\def\strc_counters_set_two           [#1][#2][#3]{\clf_setsubcounter          {\namedcounterparameter{#1}\s!name}\numexpr#2\relax\numexpr#3\relax}
247\def\strc_counters_setown_two        [#1][#2][#3]{\clf_setownsubcounter       {\namedcounterparameter{#1}\s!name}\numexpr#2\relax{#3}}
248\def\strc_counters_restart_two       [#1][#2][#3]{\clf_restartsubcounter      {\namedcounterparameter{#1}\s!name}\numexpr#2\relax\numexpr#3\relax}
249\def\strc_counters_reset_two             [#1][#2]{\clf_resetsubcounter        {\namedcounterparameter{#1}\s!name}\numexpr#2\relax}
250%def\strc_counters_increment_two         [#1][#2]{\clf_incrementsubcounter    {\namedcounterparameter{#1}\s!name}\numexpr#2\relax}
251\def\strc_counters_decrement_two         [#1][#2]{\clf_decrementsubcounter    {\namedcounterparameter{#1}\s!name}\numexpr#2\relax}
252
253\def\strc_counters_raw_two               [#1][#2]{\clf_subcountervalue        {\namedcounterparameter{#1}\s!name}\numexpr#2\relax}
254\def\strc_counters_last_two              [#1][#2]{\clf_lastsubcountervalue    {\namedcounterparameter{#1}\s!name}\numexpr#2\relax}
255\def\strc_counters_first_two             [#1][#2]{\clf_firstsubcountervalue   {\namedcounterparameter{#1}\s!name}\numexpr#2\relax}
256\def\strc_counters_next_two              [#1][#2]{\clf_nextsubcountervalue    {\namedcounterparameter{#1}\s!name}\numexpr#2\relax}
257\def\strc_counters_prev_two              [#1][#2]{\clf_previoussubcountervalue{\namedcounterparameter{#1}\s!name}\numexpr#2\relax}
258\def\strc_counters_subs_two              [#1][#2]{\clf_subsubcountervalues    {\namedcounterparameter{#1}\s!name}\numexpr#2\relax}
259
260\def\strc_counters_set_one           [#1][#2][#3]{\clf_setcounter             {\namedcounterparameter{#1}\s!name}\numexpr#2\relax}
261\def\strc_counters_setown_one        [#1][#2][#3]{\clf_setowncounter          {\namedcounterparameter{#1}\s!name}{#2}}
262\def\strc_counters_restart_one       [#1][#2][#3]{\clf_restartcounter         {\namedcounterparameter{#1}\s!name}\numexpr#2\relax}
263\def\strc_counters_reset_one             [#1][#2]{\clf_resetcounter           {\namedcounterparameter{#1}\s!name}}
264%def\strc_counters_increment_one         [#1][#2]{\clf_incrementcounter       {\namedcounterparameter{#1}\s!name}}
265\def\strc_counters_decrement_one         [#1][#2]{\clf_decrementcounter       {\namedcounterparameter{#1}\s!name}}
266
267\def\strc_counters_raw_one               [#1][#2]{\clf_countervalue           {\namedcounterparameter{#1}\s!name}}
268\def\strc_counters_last_one              [#1][#2]{\clf_lastcountervalue       {\namedcounterparameter{#1}\s!name}}
269\def\strc_counters_first_one             [#1][#2]{\clf_firstcountervalue      {\namedcounterparameter{#1}\s!name}}
270\def\strc_counters_next_one              [#1][#2]{\clf_nextcountervalue       {\namedcounterparameter{#1}\s!name}}
271\def\strc_counters_prev_one              [#1][#2]{\clf_previouscountervalue   {\namedcounterparameter{#1}\s!name}}
272\def\strc_counters_subs_one              [#1][#2]{\clf_subcountervalues       {\namedcounterparameter{#1}\s!name}}
273
274\def\strc_counters_save_one                  [#1]{\clf_savecounter            {\namedcounterparameter{#1}\s!name}}
275\def\strc_counters_restore_one               [#1]{\clf_restorecounter         {\namedcounterparameter{#1}\s!name}}
276
277\unexpanded\def\strc_counters_set            #1#2{\clf_setcounter             {\namedcounterparameter{#1}\s!name}\numexpr#2\relax}
278\unexpanded\def\strc_counters_setown         #1#2{\clf_setowncounter          {\namedcounterparameter{#1}\s!name}{#2}}
279\unexpanded\def\strc_counters_restart        #1#2{\clf_restartcounter         {\namedcounterparameter{#1}\s!name}\numexpr#2\relax}
280\unexpanded\def\strc_counters_reset            #1{\clf_resetcounter           {\namedcounterparameter{#1}\s!name}}
281%unexpanded\def\strc_counters_increment        #1{\clf_incrementcounter       {\namedcounterparameter{#1}\s!name}}
282\unexpanded\def\strc_counters_decrement        #1{\clf_decrementcounter       {\namedcounterparameter{#1}\s!name}}
283
284           \def\strc_counters_raw              #1{\clf_countervalue           {\namedcounterparameter{#1}\s!name}}
285           \def\strc_counters_last             #1{\clf_lastcountervalue       {\namedcounterparameter{#1}\s!name}}
286           \def\strc_counters_first            #1{\clf_firstcountervalue      {\namedcounterparameter{#1}\s!name}}
287           \def\strc_counters_next             #1{\clf_nextcountervalue       {\namedcounterparameter{#1}\s!name}}
288           \def\strc_counters_prev             #1{\clf_previouscountervalue   {\namedcounterparameter{#1}\s!name}}
289           \def\strc_counters_subs             #1{\clf_subcountervalues       {\namedcounterparameter{#1}\s!name}}
290
291\unexpanded\def\strc_counters_set_sub      #1#2#3{\clf_setsubcounter          {\namedcounterparameter{#1}\s!name}\numexpr#2\relax\numexpr#3\relax}
292\unexpanded\def\strc_counters_setown_sub   #1#2#3{\clf_setownsubcounter       {\namedcounterparameter{#1}\s!name}\numexpr#2\relax{#3}}
293\unexpanded\def\strc_counters_restart_sub  #1#2#3{\clf_restartsubcounter      {\namedcounterparameter{#1}\s!name}\numexpr#2\relax\numexpr#3\relax}
294\unexpanded\def\strc_counters_reset_sub      #1#2{\clf_resetsubcounter        {\namedcounterparameter{#1}\s!name}\numexpr#2\relax}
295%unexpanded\def\strc_counters_increment_sub  #1#2{\clf_incrementsubcounter    {\namedcounterparameter{#1}\s!name}\numexpr#2\relax}
296\unexpanded\def\strc_counters_decrement_sub  #1#2{\clf_decrementsubcounter    {\namedcounterparameter{#1}\s!name}\numexpr#2\relax}
297
298           \def\strc_counters_raw_sub        #1#2{\clf_subcountervalue        {\namedcounterparameter{#1}\s!name}\numexpr#2\relax} % maybe raw
299           \def\strc_counters_last_sub       #1#2{\clf_lastsubcountervalue    {\namedcounterparameter{#1}\s!name}\numexpr#2\relax}
300           \def\strc_counters_first_sub      #1#2{\clf_firstsubcountervalue   {\namedcounterparameter{#1}\s!name}\numexpr#2\relax}
301           \def\strc_counters_next_sub       #1#2{\clf_nextsubcountervalue    {\namedcounterparameter{#1}\s!name}\numexpr#2\relax}
302           \def\strc_counters_prev_sub       #1#2{\clf_previoussubcountervalue{\namedcounterparameter{#1}\s!name}\numexpr#2\relax}
303           \def\strc_counters_subs_sub       #1#2{\clf_subsubcountervalues    {\namedcounterparameter{#1}\s!name}\numexpr#2\relax}
304
305\unexpanded\def\strc_counters_save             #1{\clf_savecounter            {\namedcounterparameter{#1}\s!name}}
306\unexpanded\def\strc_counters_restore          #1{\clf_restorecounter         {\namedcounterparameter{#1}\s!name}}
307
308\unexpanded\def\strc_counters_incremented      #1{\clf_incrementedcounter     {\namedcounterparameter{#1}\s!name}}
309\unexpanded\def\strc_counters_decremented      #1{\clf_decrementedcounter     {\namedcounterparameter{#1}\s!name}}
310
311\unexpanded\def\showcounter                  [#1]{\clf_showcounter            {\namedcounterparameter{#1}\s!name}}
312
313\unexpanded\def\incrementedcounter           [#1]{\clf_incrementedcounter     {\namedcounterparameter{#1}\s!name}} % no \dosingleargument
314\unexpanded\def\decrementedcounter           [#1]{\clf_decrementedcounter     {\namedcounterparameter{#1}\s!name}} % no \dosingleargument
315
316% public variants ... beware, for old cases, from now on the value variants are the
317% ones that are expandable
318
319\def\rawcountervalue     [#1]{\clf_countervalue        {\namedcounterparameter{#1}\s!name}}
320\def\lastcountervalue    [#1]{\clf_lastcountervalue    {\namedcounterparameter{#1}\s!name}}
321\def\firstcountervalue   [#1]{\clf_firstcountervalue   {\namedcounterparameter{#1}\s!name}}
322\def\nextcountervalue    [#1]{\clf_nextcountervalue    {\namedcounterparameter{#1}\s!name}}
323\def\prevcountervalue    [#1]{\clf_previouscountervalue{\namedcounterparameter{#1}\s!name}}
324
325\def\rawsubcountervalue  [#1]#2[#3]{\clf_subcountervalue        {\namedcounterparameter{#1}\s!name}\numexpr#3\relax}
326\def\lastsubcountervalue [#1]#2[#3]{\clf_lastsubcountervalue    {\namedcounterparameter{#1}\s!name}\numexpr#3\relax}
327\def\firstsubcountervalue[#1]#2[#3]{\clf_firstsubcountervalue   {\namedcounterparameter{#1}\s!name}\numexpr#3\relax}
328\def\nextsubcountervalue [#1]#2[#3]{\clf_nextsubcountervalue    {\namedcounterparameter{#1}\s!name}\numexpr#3\relax}
329\def\prevsubcountervalue [#1]#2[#3]{\clf_previoussubcountervalue{\namedcounterparameter{#1}\s!name}\numexpr#3\relax}
330
331% The bypage check needs a multipass reference and therefore we only check for it when we increment
332% and know that some content will be placed. We could also check for spreads.
333
334\unexpanded\def\strc_counters_increment_sub#1#2%
335  {% this will be combined into one lua call
336   \edef\m_strc_counters_way{\strc_counters_way{#1}}%
337   \ifx\m_strc_counters_way\v!page
338     \checkpagechange{#1}%
339     \ifpagechanged
340       \strc_counters_reset{#1}%
341     \fi
342   \fi
343   \clf_incrementsubcounter{\namedcounterparameter{#1}\s!name}\numexpr#2\relax}
344
345% We also need to redefine these because of the page check:
346
347           \def\strc_counters_increment_two [#1][#2]{\strc_counters_increment_sub{#1}{#2}}
348           \def\strc_counters_increment_one [#1][#2]{\strc_counters_increment_sub{#1}\plusone}
349\unexpanded\def\strc_counters_increment           #1{\strc_counters_increment_sub{#1}\plusone}
350
351% so far for the hack
352
353\unexpanded\def\convertedcounter
354  {\dodoubleempty\strc_counters_converted}
355
356\def\strc_counters_converted[#1][#2]%
357  {\begingroup
358   \edef\currentcounter{#1}%
359   \ifsecondargument\setupcurrentcounter[#2]\fi
360   \clf_prefixedconverted
361     {\counterparameter\s!name}
362     {
363       prefix        {\counterparameter\c!prefix}
364       separatorset  {\counterparameter\c!prefixseparatorset}
365       conversion    {\counterparameter\c!prefixconversion}
366       conversionset {\counterparameter\c!prefixconversionset}
367       starter       {\counterparameter\c!prefixstarter}
368       stopper       {\counterparameter\c!prefixstopper}
369       set           {\counterparameter\c!prefixset}
370       segments      {\counterparameter\c!prefixsegments}
371       connector     {\counterparameter\c!prefixconnector}
372     }
373     {
374       order         {\counterparameter\c!numberorder}
375       separatorset  {\counterparameter\c!numberseparatorset}
376       conversion    {\counterparameter\c!numberconversion}
377       conversionset {\counterparameter\c!numberconversionset}
378       starter       {\counterparameter\c!numberstarter}
379       stopper       {\counterparameter\c!numberstopper}
380       segments      {\counterparameter\c!numbersegments}
381       type          {\counterparameter\c!type}
382       criterium     {\counterparameter\c!criterium}
383     }
384   \relax
385   \endgroup}
386
387\def\directconvertedcounter#1#2% name, type
388  {\clf_prefixedconverted
389     {\namedcounterparameter{#1}\s!name}
390     {
391       prefix        {\namedcounterparameter{#1}\c!prefix}
392       separatorset  {\namedcounterparameter{#1}\c!prefixseparatorset}
393       conversion    {\namedcounterparameter{#1}\c!prefixconversion}
394       conversionset {\namedcounterparameter{#1}\c!prefixconversionset}
395    %  starter       {\namedcounterparameter{#1}\c!prefixstarter}
396    %  stopper       {\namedcounterparameter{#1}\c!prefixstopper}
397       set           {\namedcounterparameter{#1}\c!prefixset}
398       segments      {\namedcounterparameter{#1}\c!prefixsegments}
399       connector     {\namedcounterparameter{#1}\c!prefixconnector}
400     }
401     {
402       order         {\namedcounterparameter{#1}\c!numberorder}
403       separatorset  {\namedcounterparameter{#1}\c!numberseparatorset}
404       conversion    {\namedcounterparameter{#1}\c!numberconversion}
405       conversionset {\namedcounterparameter{#1}\c!numberconversionset}
406       starter       {\namedcounterparameter{#1}\c!numberstarter}
407       stopper       {\namedcounterparameter{#1}\c!numberstopper}
408       segments      {\namedcounterparameter{#1}\c!numbersegments}
409       type          {#2}
410     }
411   \relax}
412
413\unexpanded\def\convertedsubcounter
414  {\dotripleempty\strc_counters_converted_sub}
415
416\def\strc_counters_converted_sub[#1][#2][#3]% #2 can be n or n:m
417  {\ifsecondargument
418     \strc_counters_converted[#1][\c!numbersegments=#2,#3]%
419   \else
420     \secondargumentfalse\strc_counters_converted[#1][]%
421   \fi}
422
423% \unexpanded\def\doifdefinedcounter#1%
424%   {\ifcsname\namedcounterhash{#1}\s!name\endcsname
425%      \expandafter\firstofoneargument
426%    \else
427%      \expandafter\gobbleoneargument
428%    \fi}
429%
430% \unexpanded\def\doifundefinedcounter#1%
431%   {\ifcsname\namedcounterhash{#1}\s!name\endcsname
432%      \expandafter\gobbleoneargument
433%    \else
434%      \expandafter\firstofoneargument
435%    \fi}
436%
437% \unexpanded\def\doifdefinedcounterelse#1%
438%   {\ifcsname\namedcounterhash{#1}\s!name\endcsname
439%      \expandafter\firstoftwoarguments
440%    \else
441%      \expandafter\secondoftwoarguments
442%    \fi}
443
444\unexpanded\def\doifdefinedcounter    {\doifcommandhandler    \??counter}
445\unexpanded\def\doifundefinedcounter  {\doifnotcommandhandler \??counter}
446\unexpanded\def\doifelsedefinedcounter{\doifelsecommandhandler\??counter}
447
448\let\doifdefinedcounterelse\doifelsedefinedcounter
449
450%D What follows is a compatibility layer.
451
452\let \numberparameter       \namedcounterparameter  % {name}\c!key
453
454\let \definenumber          \definecounter          % [name]
455\let \setupnumber           \setupcounter           % [name][setups]
456
457\let \setnumber             \setcounter             % [name]{value}
458\let \resetnumber           \resetcounter           % [name]
459\let \savenumber            \savecounter            % [name]
460\let \restorenumber         \restorecounter         % [name]
461\let \incrementnumber       \incrementcounter       % [name]
462\let \decrementnumber       \decrementcounter       % [name]
463\let \rawnumber             \rawcounter             % [name]
464\let \getnumber             \convertedcounter       % [name]
465\let \convertednumber       \convertedcounter       % [name]
466
467\let \doifdefinednumber     \doifdefinedcounter     % {number}{true}
468\let \doifundefinednumber   \doifnotdefinedcounter  % {number}{true}
469\let \doifelsedefinednumber \doifelsedefinedcounter % {number}{true}{false}
470\let \doifdefinednumberelse \doifelsedefinedcounter % {number}{true}{false}
471
472\let \setupnumbering        \setupcounter
473
474%D Helpers:
475
476% call:
477%
478% \strc_counters_register_component
479%   \currentfloat
480%   \getfloatparameters \floatparameter \detokenizedfloatparameter
481%   \hascaption \hastitle \hasnumber
482%   [settings][userdata]
483%
484% sets:
485%
486% \m_strc_counters_last_registered_index
487% \m_strc_counters_last_registered_attribute
488% \m_strc_counters_last_registered_synchronize
489
490% currentstructurecomponent => \strc_current_ or just \m_strc_
491
492\unexpanded\def\strc_counters_register_component#1#2#3#4#5#6#7[#8][#9]% maybe also nolist
493  {\begingroup
494   %
495   #2[\s!haslevel=1,#8]%
496   \edef\p_haslevel  {#3\s!haslevel}%
497   \edef\p_hascaption{#3\s!hascaption}%
498   \edef\p_hastitle  {#3\s!hastitle}%
499   \edef\p_hasnumber {#3\s!hasnumber}%
500   %
501   \edef\p_prefixsegments{#3\c!prefixsegments}%
502   \ifx\p_prefixsegments\v!auto
503     \edef\p_prefixsegments{\autostructureprefixsegments#3}%
504   \fi
505   %
506   \edef\currentname{#3\s!name}%
507   \ifx\currentname\empty
508     \edef\currentname{#1}%
509   \fi
510   \edef\currentcounter{#3\s!counter}%
511   \ifx\currentcounter\empty
512     \let\currentcounter\currentname
513   \fi
514   %
515   \ifx\p_hascaption\v!yes
516     \strc_counters_register_component_list{#1}{#3}{#4}{#9}%
517   \else\ifx\currentstructurecomponentreference\empty
518     \strc_counters_register_component_none
519   \else
520     \strc_counters_register_component_page{#3}%
521   \fi\fi
522   \endgroup}
523
524\def\strc_counters_register_component_none
525  {\glet\m_strc_counters_last_registered_index      \relax
526   \glet\m_strc_counters_last_registered_attribute  \attributeunsetvalue
527   \glet\m_strc_counters_last_registered_synchronize\relax}
528
529\def\strc_counters_register_component_check_prefix
530  {\ifx\currentstructurecomponentreferenceprefix\empty
531     \let\currentstructurecomponentreferenceprefix\currentstructurereferenceprefix
532   \fi
533   \ifx\currentstructurecomponentreferenceprefix\empty
534     \let\currentstructurecomponentreferenceprefix\referenceprefix
535   \fi
536   \ifdefined\currentstructurecomponentreferenceprefix\else
537     \let\currentstructurecomponentreferenceprefix\empty
538   \fi}
539
540\def\strc_counters_register_component_page#1%
541  {\xdef\currentstructurecomponentreference      {#1\c!reference}%
542   \xdef\currentstructurecomponentreferenceprefix{#1\c!referenceprefix}%
543   \strc_counters_register_component_check_prefix
544   \setnextinternalreference
545   \clf_setdestinationattribute
546        {%
547            references {%
548                  internal  \locationcount
549                % block     {\currentsectionblock}% move to lua
550                  view      {\interactionparameter\c!focus}%
551                  prefix    {\currentstructurecomponentreferenceprefix}%
552                  reference {\currentstructurecomponentreference}%
553            }%
554            metadata {%
555                kind {\s!page}%
556            }%
557        }%
558   \relax
559   \xdef\m_strc_counters_last_registered_attribute  {\the\lastdestinationattribute}%
560   \glet\m_strc_counters_last_registered_index      \relax
561   \glet\m_strc_counters_last_registered_synchronize\relax}
562
563\def\strc_counters_register_component_list#1#2#3#4%
564  {\xdef\currentstructurecomponentname           {#2\s!name}%
565   \xdef\currentstructurecomponentlevel          {#2\c!level}%
566   \edef\currentstructurecomponentexpansion      {#2\c!expansion}%
567   \xdef\currentstructurecomponentxmlsetup       {#2\c!xmlsetup}%
568   \xdef\currentstructurecomponentcatcodes       {#2\s!catcodes}%
569   \xdef\currentstructurecomponentlabel          {#2\c!label}%
570   \xdef\currentstructurecomponentreference      {#2\c!reference}%
571   \xdef\currentstructurecomponentreferenceprefix{#2\c!referenceprefix}%
572   \strc_counters_register_component_check_prefix
573   \ifx\currentstructurecomponentexpansion\s!xml
574     \xmlstartraw
575       \xdef\currentstructurecomponenttitle   {#2\c!title}%
576       \xdef\currentstructurecomponentbookmark{#2\c!bookmark}%
577       \xdef\currentstructurecomponentmarking {#2\c!marking}%
578       \xdef\currentstructurecomponentlist    {#2\c!list}%
579     \xmlstopraw
580     \ifx\currentstructurecomponentlist\empty
581       \glet\currentstructurecomponentlist\currentstructurecomponenttitle
582     \fi
583     \glet\currentstructurecomponentcoding\s!xml
584   \else
585     \ifx\currentstructurecomponentexpansion\v!yes
586       \xdef\currentstructurecomponenttitle   {#2\c!title}%
587       \xdef\currentstructurecomponentbookmark{#2\c!bookmark}%
588       \xdef\currentstructurecomponentmarking {#2\c!marking}%
589       \xdef\currentstructurecomponentlist    {#2\c!list}%
590     \else
591       \xdef\currentstructurecomponenttitle   {#3\c!title}%
592       \xdef\currentstructurecomponentbookmark{#3\c!bookmark}%
593       \xdef\currentstructurecomponentmarking {#3\c!marking}%
594       \xdef\currentstructurecomponentlist    {#3\c!list}%
595       \iflocation \ifx\currentstructurecomponentbookmark\empty
596         \begingroup
597         \simplifycommands
598         \xdef\currentstructurecomponentbookmark{\detokenize\expandafter{\normalexpanded{#2\c!title}}}%
599        \endgroup
600       \fi \fi
601     \fi
602     \ifx\currentstructurecomponentlist\empty
603       \glet\currentstructurecomponentlist\currentstructurecomponenttitle
604     \fi
605     \glet\currentstructurecomponentcoding\s!tex
606   \fi
607   %
608   \setnextinternalreference
609   \scratchcounter\clf_addtolist %{
610      metadata {
611          kind     {#1}
612          name     {\currentname}
613        % level    structures.sections.currentlevel()
614          catcodes \ifx\currentstructurecomponentcatcodes\empty\catcodetable\else\csname\currentstructurecomponentcatcodes\endcsname\fi
615          coding   {\currentstructurecomponentcoding}
616      \ifx\currentstructurecomponentcoding\s!xml
617          xmlroot  {\xmldocument}
618      \fi
619      \ifx\currentstructurecomponentxmlsetup\empty \else
620          xmlsetup {\currentstructurexmlsetup}
621      \fi
622      }
623      references {
624          internal  \locationcount
625        % block     {\currentsectionblock}
626          reference {\currentstructurecomponentreference}
627          prefix    {\currentstructurecomponentreferenceprefix}
628        % section   structures.sections.currentid()
629          view      {\interactionparameter\c!focus}%
630      }
631      titledata {
632          label    {\detokenize\expandafter{\currentstructurecomponentlabel}}
633          title    {\detokenize\expandafter{\currentstructurecomponenttitle}}
634      \ifx\currentstructurecomponentbookmark\currentstructurecomponenttitle \else
635          bookmark {\detokenize\expandafter{\currentstructurecomponentbookmark}}
636      \fi
637      \ifx\currentstructurecomponentmarking\currentstructurecomponenttitle \else
638          marking  {\detokenize\expandafter{\currentstructurecomponentmarking}}
639      \fi
640      \ifx\currentstructurecomponentlist\currentstructurecomponenttitle \else
641          list     {\detokenize\expandafter{\currentstructurecomponentlist}}
642      \fi
643      }
644  \ifx\p_hasnumber\v!yes
645      prefixdata {
646          prefix        {#2\c!prefix}
647          separatorset  {#2\c!prefixseparatorset}
648          conversion    {#2\c!prefixconversion}
649          conversionset {#2\c!prefixconversionset}
650          set           {#2\c!prefixset}
651       %  segments      {#2\c!prefixsegments}
652          segments      {\p_prefixsegments}
653          connector     {#2\c!prefixconnector}
654      }
655      numberdata { % more helpers here, like compact elsewhere
656          numbers       {\currentcounter}
657          group         {#2\c!group}
658          groupsuffix   {#2\c!groupsuffix}
659          counter       {\currentcounter}
660          separatorset  {#2\c!numberseparatorset}
661          conversion    {#2\c!numberconversion}
662          conversionset {#2\c!numberconversionset}
663          starter       {#2\c!numberstarter}
664          stopper       {#2\c!numberstopper}
665          segments      {#2\c!numbersegments}
666      }
667  \fi
668      userdata {\detokenize{#4}}
669   %}
670   \relax
671   \xdef\m_strc_counters_last_registered_index{\the\scratchcounter}%
672   \setstructurecomponentsynchronization\m_strc_counters_last_registered_index
673   \glet\m_strc_counters_last_registered_attribute  \currentstructurecomponentattribute
674   \glet\m_strc_counters_last_registered_synchronize\currentstructurecomponentsynchronize}
675
676\let\m_strc_counters_last_registered_index      \relax
677\let\m_strc_counters_last_registered_attribute  \relax
678\let\m_strc_counters_last_registered_synchronize\relax
679
680% This can be improved as we don't need to pas all these variables
681% each time (we can set them up once).
682
683\unexpanded\def\strc_counter_preset_using_parameter#1#2% \setupcommand \someparameter
684  {#1%
685    [\c!way                =#2\c!way,
686     \c!prefix             =#2\c!prefix,
687     \c!prefixseparatorset =#2\c!prefixseparatorset,
688     \c!prefixconversion   =#2\c!prefixconversion,
689     \c!prefixconversionset=#2\c!prefixconversionset,
690     \c!prefixstarter      =#2\c!prefixstarter,
691     \c!prefixstopper      =#2\c!prefixstopper,
692     \c!prefixsegments     =#2\c!prefixsegments,
693     \c!prefixset          =#2\c!prefixset,
694     \c!prefixconnector    =#2\c!prefixconnector,
695     \c!numberseparatorset =#2\c!numberseparatorset,
696     \c!numberconversion   =#2\c!numberconversion,
697     \c!numberconversionset=#2\c!numberconversionset,
698     \c!numberstarter      =#2\c!numberstarter,
699     \c!numberstopper      =#2\c!numberstopper,
700     \c!numbersegments     =#2\c!numbersegments]}
701
702% \unexpanded\def\strc_counter_setup_using_parameter#1#2% name \someparameter
703%   {\setupcounter
704%      [#1]
705%      [              \c!start=#2\c!start,
706%                     \c!state=#2\c!state, % beware, "" == start
707%                       \c!way=#2\c!way,
708%                             %
709%                    \c!prefix=#2\c!prefix,
710%        \c!prefixseparatorset=#2\c!prefixseparatorset,
711%          \c!prefixconversion=#2\c!prefixconversion,
712%       \c!prefixconversionset=#2\c!prefixconversionset,
713%             \c!prefixstarter=#2\c!prefixstarter,
714%             \c!prefixstopper=#2\c!prefixstopper,
715%                 \c!prefixset=#2\c!prefixset,
716%            \c!prefixsegments=#2\c!prefixsegments,
717%                 \c!prefixset=#2\c!prefixset,
718%           \c!prefixconnector=#2\c!prefixconnector,
719%                             %
720%        \c!numberseparatorset=#2\c!numberseparatorset,
721%          \c!numberconversion=#2\c!numberconversion,
722%       \c!numberconversionset=#2\c!numberconversionset,
723%             \c!numberstarter=#2\c!numberstarter,
724%             \c!numberstopper=#2\c!numberstopper,
725%            \c!numbersegments=#2\c!numbersegments]}
726
727\unexpanded\def\strc_counter_setup_using_parameter#1#2% name \someparameter
728  {\edef\currentcounter{#1}%
729   %
730   \setcounterparameter              \c!start{#2\c!start}%
731   \setcounterparameter              \c!state{#2\c!state}% % beware, "" == start
732   \setcounterparameter                \c!way{#2\c!way}%
733   %
734   \setcounterparameter             \c!prefix{#2\c!prefix}%
735   \setcounterparameter \c!prefixseparatorset{#2\c!prefixseparatorset}%
736   \setcounterparameter   \c!prefixconversion{#2\c!prefixconversion}%
737   \setcounterparameter\c!prefixconversionset{#2\c!prefixconversionset}%
738   \setcounterparameter      \c!prefixstarter{#2\c!prefixstarter}%
739   \setcounterparameter      \c!prefixstopper{#2\c!prefixstopper}%
740   \setcounterparameter          \c!prefixset{#2\c!prefixset}%
741   \setcounterparameter     \c!prefixsegments{#2\c!prefixsegments}%
742   \setcounterparameter          \c!prefixset{#2\c!prefixset}%
743   \setcounterparameter    \c!prefixconnector{#2\c!prefixconnector}%
744   %
745   \setcounterparameter \c!numberseparatorset{#2\c!numberseparatorset}%
746   \setcounterparameter   \c!numberconversion{#2\c!numberconversion}%
747   \setcounterparameter\c!numberconversionset{#2\c!numberconversionset}%
748   \setcounterparameter      \c!numberstarter{#2\c!numberstarter}%
749   \setcounterparameter      \c!numberstopper{#2\c!numberstopper}%
750   \setcounterparameter     \c!numbersegments{#2\c!numbersegments}%
751   %
752   \the\everysetupcounter}
753
754\unexpanded\def\mult_interfaces_counter_association#1#2#3#4#5#6#7% tag current setup parameter list sync register
755  {\strc_counter_preset_using_parameter#3\rootcounterparameter
756   \newtoks#5%
757   \unexpanded\def   #6{\ifx#2\empty\the#5\else\strc_counter_setup_using_parameter#2#4\fi}% sync
758   \unexpanded\def#7##1{\normalexpanded{#5{\the#5\strc_counter_setup_using_parameter{##1}\noexpand#4}}}} % register
759
760\unexpanded\def\installcounterassociation#1% => synchronize#1counters register#1counter
761  {\normalexpanded
762     {\mult_interfaces_counter_association
763        {#1}% not \??xx but xx
764        \expandafter\noexpand\csname current#1\endcsname
765        \expandafter\noexpand\csname setup#1\endcsname
766        \expandafter\noexpand\csname #1parameter\endcsname
767        \expandafter\noexpand\csname counter_association_list_#1\endcsname
768        \expandafter\noexpand\csname synchronize#1counters\endcsname
769        \expandafter\noexpand\csname register#1counter\endcsname}}
770
771% needs testing:
772%
773% \unexpanded\def\strc_counter_setup_push#1#2#3% \someparameter \directsomeparameter \setexpandedsomeparameter
774%   {\let\savedcounterparameter           \counterparameter
775%    \let\saveddirectcounterparameter     \directcounterparameter
776%    \let\savedsetexpandedcounterparameter\setexpandedcounterparameter
777%    % remap
778%    \let\counterparameter                #1%
779%    \let\directcounterparameter          #2%
780%    \let\setexpandedcounterparameter     #3}
781%
782% \unexpanded\def\strc_counter_setup_pop
783%   {\let\counterparameter                \savedcounterparameter
784%    \let\directcounterparameter          \saveddirectcounterparameter
785%    \let\setexpandedcounterparameter     \savedsetexpandedcounterparameter}
786%
787% \unexpanded\def\mult_interfaces_counter_association#1#2#3#4#5#6#7% tag current setup parameter list sync register
788%   {\strc_counter_preset_using_parameter#3\rootcounterparameter
789%    \newtoks#5%
790%    \unexpanded\def#6% sync
791%      {\strc_counter_setup_push
792%       \ifx#2\empty
793%         \the#5%
794%       \else
795%         \let\currentcounter\empty
796%         \the\everysetupcounter
797%       \fi
798%       \strc_counter_setup_pop}%
799%    \unexpanded\def#7##1% register
800%       {\normalexpanded{#5{\the#5\edef\noexpand\currentcounter{##1}\noexpand\the\everysetupcounter}}}}
801
802%D For good old times (easier to explain in manuals):
803%D
804%D \starttyping
805%D \setcounter[userpage][9]
806%D \setupcounter[userpage][number=9]
807%D \setupuserpagenumber[number=9]
808%D \stoptyping
809
810% needs testing: we might have conflicts with mixins
811%
812% \appendtoks
813%     \ifx\currentcounter\empty \else
814%         \edef\p_number{\counterparameter\c!number}%
815%         \ifx\p_number\empty \else
816%             \strc_counters_set\currentcounter\p_number
817%             \letcounterparameter\c!number\empty
818%         \fi
819%     \fi
820% \to \everysetupcounter
821
822\stopcontextdefinitioncode
823
824\protect \endinput
825