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