strc-itm.mklx /size: 82 Kb    last modification: 2025-02-21 11:03
1%D \module
2%D   [       file=strc-itm,
3%D        version=2008.10.20,
4%D          title=\CONTEXT\ Structure Macros,
5%D       subtitle=Itemgroups,
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 / Itemgroups}
15
16\unprotect
17
18\newdimension\d_strc_itemgroups_max_width
19\newinteger  \c_strc_itemgroups_max_items
20
21\registerctxluafile{strc-itm}{autosuffix}
22
23%D As we analyze/register widths and such we could as well push and pop the numbers
24%D at the \LUA\ end (which saves a few calls).
25%D
26%D Cleaning up this module happened around the time when Kate Bush came up with the
27%D nicest numbered list of words: 50 Words For Snow. It's therefore no surprise that
28%D I had that cd running several times when updating this code. One of the
29%D highlights of 2011.
30%D
31%D This module needs to be rewritten but that is tricky with respect to
32%D compatibilitity. Basically each major variant (regular, text, columns,
33%D horizontal, etc) needs to be on its own.
34
35% todo: check breaks
36% todo: check grouping
37% todo: fixedconversion
38
39% \startitemize[n,packed]
40% \item test \item test \item test
41% \stopitemize
42%
43% \startitemize[n,packed,reverse]
44% \item test \item test \item test
45% \stopitemize
46%
47% \startitemize[n,packed,reverse] \item test \item test \stopitemize
48% \startitemize[continue]
49% \item test \startitemize[n,packed] \item test \item test \stopitemize
50% \item test
51% \item test
52% \stopitemize
53% \startitemize[continue] \item test \stopitemize
54%
55% \startitemize[n,packed] \item test \item test \stopitemize
56% \startitemize[continue] \item test            \stopitemize
57% \startitemize[continue] \item test            \stopitemize
58%
59% \setupwhitespace[big]
60% \starttext
61%     test \startitemize[joinedup]                \item test \item test \stopitemize test \par
62%     test \startitemize[joinedup,nowhite]        \item test \item test \stopitemize test \par
63%     test \startitemize[joinedup,nowhite,before] \item test \item test \stopitemize test \par
64%     test \startitemize[joinedup,nowhite,after]  \item test \item test \stopitemize test \par
65% \stoptext
66%
67% test / example
68%
69% \startnarrower[left] \startcolumns[n=3] \startitemize
70% \item \input ward \item \input ward \item \input ward
71% \stopitemize \stopcolumns\stopnarrower \blank
72%
73% \startnarrower[left] \startitemize[columns,three]
74% \item \input ward \item \input ward \item \input ward
75% \stopitemize \stopnarrower \blank
76%
77% \setupitemize[leftmargin=1.5em] \startitemize[columns,three]
78% \item \input ward \item \input ward \item \input ward
79% \stopitemize \blank
80%
81% beware, we don't group (yet) as we want to keep the left/right skip
82%
83% \startitemize
84% \startitem \stopitem
85% some intermediate text that will properly indent
86% \startitem \stopitem
87% \stopitem
88%
89% so we need to keep that property
90%
91% \startitemize
92%   \starthead {xx} test \stophead
93%   \startitem test \stopitem
94%   \startitem test \stopitem
95% \stopitemize
96%
97% Sometimes the user demands get pretty weird:
98%
99% \startitemize
100%   \item test
101%   \item test
102%   \headsym{xx} test \par test
103% \stopitemize
104%
105% aligned items
106%
107% \startitemize[n,fit,broad][itemalign=flushright]
108%      \dorecurse{100}{\item The first item.}
109% \stopitemize
110%
111% \setupitemgroup[itemize][each][fit]
112% \setupitemgroup[itemize][each][distance=.5em,factor=1,itemalign=flushright]
113%
114% \startitemize[n]
115%      \dorecurse{100}{\item The first item.}
116% \stopitemize
117%
118% \defineitemgroup[gbitemize]
119% \setupitemgroup[gbitemize][each][headstyle=bold]
120%
121% \startgbitemize
122% \txt{italian} some italians like this kind of cross||breed between
123%   an itemize and a description
124% \txt{sicilians} i wonder how many sicilian mathematicians do a thesis
125%   on the math involved in predicting the next big bang of the vulcano
126% \stopgbitemize
127%
128% \startitemize[n,repeat]
129%     \noitem \startitemize[a] \item Item 1.a. \item Item 1.b. \stopitemize
130%     \noitem \startitemize[a] \item Item 2.a. \item Item 2.b. \stopitemize
131% \stopitemize
132%
133% \startitemize[n,repeat][width=0pt]
134%   \noitem \startitemize[a][width=2em] \item Item 1.a. \item Item 1.b. \stopitemize
135%   \noitem \startitemize[a][width=2em] \item Item 2.a. \item Item 2.b. \stopitemize
136% \stopitemize
137%
138% \startbuffer
139% \item
140%   \startitemize[n]
141%   \item item 1.1
142%   \item item 1.2
143%   \startitemize[n] \item item 1.2.1 \item item 1.2.2 \stopitemize
144%   \item item 1.3
145%   \stopitemize
146% \item
147%   \startitemize[n] \item item 2.1 \item item 2.2 \stopitemize
148% \item item 3
149%   \startitemize[n] \item item 3.1 \item item 3.2 \stopitemize
150% \item
151%   \startitemize[n] \item item 4.1 \item item 4.2 \stopitemize
152% \stopbuffer
153%
154% \startitemize[n,repeat,6*broad,packed] \getbuffer \stopitemize \blank[3*big]
155% \startitemize[n,repeat,packed]         \getbuffer \stopitemize \blank[3*big]
156% \setupitemize[each][atmargin][width=3em]
157% \startitemize[n,repeat,packed]         \getbuffer \stopitemize
158%
159% todo: assume startitem ... stopitem and do an autostopitem .. cleaner for
160% elements
161%
162% \startitemize[text][space=medium]
163% \item one \item two \item three
164% \stopitemize
165%
166% For Giuseppe "Oblomov" Bilotta, inspired on a suggestion by Taco
167% Hoekwater.
168%
169% \def\MyItemCommand#1{{\bf#1}\quad}
170% \setupitemgroup[itemize][command=\MyItemCommand]
171%
172% \startitemize
173% \item {test} is this okay?
174% \item {test} is this okay?
175% \item {test} is this okay?
176% \stopitemize
177
178\newconditional\c_strc_itemgroups_sub
179\newconditional\c_strc_itemgroups_head
180\newconditional\c_strc_itemgroups_intro
181\newconditional\c_strc_itemgroups_randomize
182\newconditional\c_strc_itemgroups_horizontal
183\newconditional\c_strc_itemgroups_collecting
184\newconditional\c_strc_itemgroups_auto_intro
185\newconditional\c_strc_itemgroups_pack
186\newconditional\c_strc_itemgroups_paragraph
187\newconditional\c_strc_itemgroups_text
188\newconditional\c_strc_itemgroups_no_par
189\newconditional\c_strc_itemgroups_text_saved
190\newconditional\c_strc_itemgroups_first
191\newconditional\c_strc_itemgroups_before
192\newconditional\c_strc_itemgroups_after
193\newconditional\c_strc_itemgroups_nowhite
194\newconditional\c_strc_itemgroups_joined
195\newconditional\c_strc_itemgroups_reverse
196\newconditional\c_strc_itemgroups_continue
197\newconditional\c_strc_itemgroups_fitting
198\newconditional\c_strc_itemgroups_indented_first
199\newconditional\c_strc_itemgroups_inline
200\newconditional\c_strc_itemgroups_columns
201\newconditional\c_strc_itemgroups_concat
202\newconditional\c_strc_itemgroups_txt
203\newconditional\c_strc_itemgroups_extra
204\newconditional\c_strc_itemgroups_repeat
205\newconditional\c_strc_itemgroups_inline_head
206\newconditional\c_strc_itemgroups_symbol
207\newconditional\c_strc_itemgroups_overlay
208
209% 0=before/after 1=auto 2=inbetween (default)
210
211\newconstant   \c_strc_itemgroups_spacing_mode   \c_strc_itemgroups_spacing_mode\plustwo
212\newconditional\c_strc_itemgroups_auto_concat    \c_strc_itemgroups_auto_concat \conditionaltrue
213
214% 0=loose 1=tight 2=verytight
215
216\newinteger    \c_strc_itemgroups_optimize       \c_strc_itemgroups_optimize\plusone % tight
217
218\newboundary   \c_strc_itemgroups_boundary
219\newbox        \b_strc_itemgroups
220
221\newdimension  \d_strc_itemgroups_list_width
222\newdimension  \d_strc_itemgroups_asked_width
223
224%newdimension  \d_strc_itemgroups_max_width % defined already, used at the Lua end
225%newinteger    \c_strc_itemgroups_max_items % idem
226
227\def\d_strc_itemgroups_max_width_reference{\d_strc_itemgroups_max_width} % no alias!
228
229\newinteger    \c_strc_itemgroups_n_of_items
230\newinteger    \c_strc_itemgroups_nesting
231\newinteger    \c_strc_itemgroups_column_depth
232
233\def           \v_strc_itemgroups_counter        {itemgroup:\currentparentitemgroup}
234\lettonothing  \m_strc_itemgroups_repeat_start
235\def           \v_strc_itemgroups_unknown_symbol {?}
236\lettonothing  \m_strc_itemgroups_indenting
237\lettonothing  \m_strc_itemgroups_destination
238
239\mutable\let   \currentitemlevel                 \!!zerocount % public
240\mutable\def   \currentnofitems                  {\the\c_strc_itemgroups_max_items}
241\mutable\def   \currentitemindex                 {\the\c_strc_itemgroups_n_of_items}
242\mutable\def   \currentitemnumber                {\strc_counters_raw_sub\v_strc_itemgroups_counter\currentitemlevel} % public
243
244\newtoks       \itemgroupcommands                % maybe public
245
246\mutable\def          \currentitemgroupsymbol        {n} % here we cannot use a _ in the name
247\mutable\lettonothing \currentitemgroupconversionset     % here we cannot use a _ in the name
248\mutable\lettonothing \currentitemgroupsegments
249
250\def\strc_itemgroups_register_status
251  {\clf_registeritemgroup{\currentparentitemgroup}\c_strc_itemgroups_nesting\c_strc_itemgroups_n_of_items{\itemgroupparameter\c!maxwidth}}
252
253\def\strc_itemgroups_check_n_of_items % we could do this at the lua end and save a call (i.e. will be dimen and counter)
254  {\clf_analyzeitemgroup{\currentparentitemgroup}\c_strc_itemgroups_nesting\relax
255   \edef\currentnofitems{\the\c_strc_itemgroups_max_items}}
256
257\permanent\protected\def\upcomingnofitems#1%
258  {\the\numexpr
259     \clf_analyzeupcomingitemgroup{#1}{\c_strc_itemgroups_nesting+\plusone}%
260     \c_strc_itemgroups_max_items
261   \relax}
262
263% todo: \dodosetreference -> \strc_counters_register_component (to be checked)
264
265\def\strc_itemgroups_insert_reference % we will make a decent number helper
266  {\iftrialtypesetting \orelse \ifempty\currentitemreference \else
267     \strc_itemgroups_insert_reference_indeed
268   \fi}
269
270\def\strc_itemgroups_insert_extra_reference
271  {\iftrialtypesetting \orelse \ifempty\currentitemreference \else
272     \normalexpanded{\textreference[\currentitemreference]{\strc_itemgroups_extra_symbol}}%
273   \fi}
274
275\def\strc_itemgroups_insert_reference_indeed % maybe we need a 'frozen counter' numberdata blob / quick hack .. .mive this to strc-ref
276  {% needs testing, gave problems:
277   \setnextinternalreference
278   % no need to collect nodes in \b_strc_destination_nodes here ... maybe at some point
279   \strc_references_start_destination_nodes
280   % this is somewhat over the top ... we should use the counter's reference
281   \clf_setdestinationattribute
282     {%
283         metadata {%
284             kind            {item}% was item, why?
285         \ifx\currentreferencecoding\s!xml
286             xmlroot         {\xmldocument}% only useful when text
287         \fi
288             catcodes        \catcodetable
289         }%
290         references {%
291             internal        \locationcount % no: this spoils references
292           % block           {\currentsectionblock}%
293             view            {\interactionparameter\c!focus}%
294             prefix          {\referenceprefix}%
295             reference       {\currentitemreference}%
296         }%
297         prefixdata {%
298             prefix          {\namedcounterparameter\v_strc_itemgroups_counter\c!prefix}%
299             separatorset    {\namedcounterparameter\v_strc_itemgroups_counter\c!prefixseparatorset}%
300             conversion      {\namedcounterparameter\v_strc_itemgroups_counter\c!prefixconversion}%
301             conversionset   {\namedcounterparameter\v_strc_itemgroups_counter\c!prefixconversionset}%
302             set             {\namedcounterparameter\v_strc_itemgroups_counter\c!prefixset}%
303             segments        {\namedcounterparameter\v_strc_itemgroups_counter\c!prefixsegments}%
304           % segments        {\askedprefixsegments}%
305             connector       {\namedcounterparameter\v_strc_itemgroups_counter\c!prefixconnector}%
306         }%
307         numberdata {%
308             numbers         {\v_strc_itemgroups_counter}%
309             separatorset    {\namedcounterparameter\v_strc_itemgroups_counter\c!numberseparatorset}%
310           % conversion      {\namedcounterparameter\v_strc_itemgroups_counter\c!numberconversion}%
311           % conversionset   {\namedcounterparameter\v_strc_itemgroups_counter\c!numberconversionset}%
312           % fixedconversion {\currentitemgroupconversionset}%
313             conversionset   {fixed::\currentitemgroupconversionset}% temp hack
314           %
315           % for the moment no stopper, we need to make references configurable first
316           % stopper         {\namedcounterparameter\v_strc_itemgroups_counter\c!numberstopper}%
317             segments        {\namedcounterparameter\v_strc_itemgroups_counter\c!numbersegments}%
318         }%
319     }%
320   \relax
321   \strc_references_stop_destination_nodes
322   \xdef\currentdestinationattribute{\number\lastdestinationattribute}%
323   % will become an option:
324   \ifnum\lastdestinationattribute>\zerocount
325     \dontleavehmode\hbox attr \destinationattribute\lastdestinationattribute\bgroup
326       \strc_references_flush_destination_nodes
327     \egroup
328   \fi}
329
330%D Defining and setup:
331
332\installcorenamespace{itemgroup}
333\installcorenamespace{itemgroupoption}
334\installcorenamespace{itemgroupsetting}
335\installcorenamespace{itemgroupkeyword}
336\installcorenamespace{itemgroupalign}
337\installcorenamespace{itemgrouplocal}
338\installcorenamespace{itemgroupglobal}
339\installcorenamespace{itemgroupdistance}
340\installcorenamespace{itemgroupstack}
341\installcorenamespace{itemgroupfirst}
342\installcorenamespace{itemgroupstart}
343
344\installcommandhandler \??itemgroup {itemgroup} \??itemgroup
345
346\aliased\let\setupitemgroups\setupitemgroup
347
348\appendtoks
349    \frozen\instance\protected\edefcsname\e!start\currentitemgroup           \endcsname{\startitemgroup[\currentitemgroup]}%
350    \frozen\instance\protected\edefcsname\e!stop \currentitemgroup           \endcsname{\stopitemgroup}%
351    \frozen\instance\protected\edefcsname\e!setup\currentitemgroup\e!endsetup\endcsname{\setupitemgroup[\currentitemgroup]}% obsolete
352    \let\currentparentitemgroup\currentitemgroup
353    \definecounter[\v_strc_itemgroups_counter]%
354\to \everydefineitemgroup
355
356%D Global states
357
358\def\strc_itemgroups_store_continue_state#options#settings%
359   {\xdefcsname\??itemgroupoption \currentitemgroup\endcsname{\strc_itemgroups_process_options{#options}}%
360    \gdefcsname\??itemgroupsetting\currentitemgroup\endcsname{\setupcurrentitemgroup[#settings]}}
361
362\def\strc_itemgroups_fetch_continue_state
363  {\csname\??itemgroupoption \currentitemgroup\endcsname
364   \csname\??itemgroupsetting\currentitemgroup\endcsname}
365
366\def\strc_itemgroups_reset_continue_state
367  {\gletcsname\??itemgroupoption \currentitemgroup\endcsname\relax
368   \gletcsname\??itemgroupsetting\currentitemgroup\endcsname\relax}
369
370% These will become keywords. We will also add a feature to keep the while set
371% together.
372
373\definevspacing[\v!item @\v!no]        [penalty:0]     % allow
374\definevspacing[\v!item @\v!yes]       [penalty:10000] % never
375\definevspacing[\v!item @\v!tight]     [penalty:500]   % discourage
376\definevspacing[\v!item @\v!verytight] [penalty:5000]  % discourage more
377
378\definevspacing[\v!item @-5] [penalty:-5]
379\definevspacing[\v!item @5]  [penalty:5]
380
381\def\strc_itemgroups_insert_break_when_needed#break%
382  {\ifcase\c_strc_itemgroups_optimize
383     % loose
384   \orelse\ifconditional\c_strc_itemgroups_text
385     % horizontal
386   \else
387     #break\relax
388   \fi}
389
390\def\strc_itemgroups_insert_breakallow{\strc_itemgroups_insert_break_when_needed\strc_itemgroups_insert_breakallow_indeed}
391\def\strc_itemgroups_insert_breakno   {\strc_itemgroups_insert_break_when_needed\strc_itemgroups_insert_breakno_indeed   }
392\def\strc_itemgroups_insert_break     {\strc_itemgroups_insert_break_when_needed\strc_itemgroups_insert_break_indeed     }
393\def\strc_itemgroups_insert_nobreak   {\strc_itemgroups_insert_break_when_needed\strc_itemgroups_insert_nobreak_indeed   }
394
395\def\strc_itemgroups_insert_breakallow_indeed
396  {\vspacing[\v!item @\v!no]}
397
398\def\strc_itemgroups_insert_breakno_indeed
399  {\vspacing[\v!item @\v!yes]}
400
401\def\strc_itemgroups_insert_break_indeed
402  {\flushnotes
403   \vspacing[\v!item @-5]}
404
405\def\strc_itemgroups_insert_nobreak_indeed
406  {\flushnotes
407   \ifinsidecolumns % todo
408     \vspacing[\v!item @5]%
409   \orelse\ifcase\c_strc_itemgroups_optimize
410   \or
411     % tight
412     \vspacing[\v!item @\v!tight]%
413   \else
414     % verytight
415     \vspacing[\v!item @\v!verytight]%
416   \fi}
417
418\protected\def\strc_itemgroups_process_options#options%
419  {\processcommacommand[#options]\strc_itemgroups_process_option} % expansion of options is handy for xml
420
421% \installcommalistprocessorcommand \strc_itemgroups_process_option_list \strc_itemgroups_process_option
422%
423% \protected\def\strc_itemgroups_process_options#options%
424%   {\normalexpanded{\strc_itemgroups_process_option_list[#options]}} % expansion of options is handy for xml
425
426\mutable\lettonothing\itemgroupfirst
427\mutable\lettonothing\itemgroupsecond
428
429\def\strc_itemgroups_process_option#option%
430  {\edef\scratchstringone{#option}%
431   \ifempty\scratchstringone\else
432     \splitatasterisk\scratchstringone\itemgroupfirst\itemgroupsecond
433     \ifempty\itemgroupsecond
434        \let\itemgroupsecond\itemgroupfirst
435        \let\itemgroupfirst\!!plusone
436     \fi
437     \ifcsname\??itemgroupkeyword\itemgroupsecond\endcsname
438       \lastnamedcs
439     \else
440       \strc_itemgroups_set_symbol\scratchstringone
441     \fi
442   \fi}
443
444\def\strc_itemgroups_process_set_option_pack
445  {\ifcase\c_strc_itemgroups_nesting \else
446     \c_strc_itemgroups_pack\conditionaltrue
447   \fi}
448
449\def\strc_itemgroups_process_set_option_unpack
450  {\ifcase\c_strc_itemgroups_nesting\else
451     \c_strc_itemgroups_pack\conditionalfalse
452   \fi}
453
454\defcsname\??itemgroupkeyword\!!zerocount\endcsname
455  {} % ignore 0
456
457\defcsname\??itemgroupkeyword\v!packed\endcsname
458  {\strc_itemgroups_process_set_option_pack}
459
460\defcsname\??itemgroupkeyword\v!unpacked\endcsname
461  {\strc_itemgroups_process_set_option_unpack}
462
463\defcsname\??itemgroupkeyword\v!nointro\endcsname
464  {\c_strc_itemgroups_intro\conditionalfalse}
465
466\defcsname\??itemgroupkeyword\v!intro\endcsname
467  {\c_strc_itemgroups_intro\conditionaltrue}
468
469\defcsname\??itemgroupkeyword\v!autointro\endcsname
470  {\c_strc_itemgroups_auto_intro\conditionaltrue}
471
472\defcsname\??itemgroupkeyword\v!broad\endcsname
473  {\ifempty\itemgroupfirst
474     \let\itemgroupfirst\!!plusone
475   \fi
476   \letitemgroupparameter\c!factor\itemgroupfirst}
477
478\defcsname\??itemgroupkeyword\v!text\endcsname
479  {\c_strc_itemgroups_text\conditionaltrue
480   \c_strc_itemgroups_inline\conditionaltrue
481   \c_strc_itemgroups_joined\conditionaltrue
482   \strc_itemgroups_process_set_option_pack}
483
484\defcsname\??itemgroupkeyword\v!before\endcsname
485  {\c_strc_itemgroups_before\conditionaltrue}
486
487\defcsname\??itemgroupkeyword\v!after\endcsname
488  {\c_strc_itemgroups_after\conditionaltrue}
489
490\defcsname\??itemgroupkeyword\v!nowhite\endcsname
491  {\c_strc_itemgroups_nowhite\conditionaltrue}
492
493\defcsname\??itemgroupkeyword\v!margin\endcsname % signal
494  {\setitemgroupparameter\c!width{-2em}}
495
496\defcsname\??itemgroupkeyword\v!inmargin\endcsname % signal
497  {\setitemgroupparameter\c!width{-2em}}
498
499\defcsname\??itemgroupkeyword\v!atmargin\endcsname% signal
500  {\ifnum\c_strc_itemgroups_nesting>\plusone
501     \setitemgroupparameter\c!width{0em}%
502   \fi}
503
504\defcsname\??itemgroupkeyword\v!intext\endcsname
505  {\c_strc_itemgroups_inline\conditionaltrue}
506
507\defcsname\??itemgroupkeyword\v!headintext\endcsname
508  {\c_strc_itemgroups_inline_head\conditionaltrue}
509
510\defcsname\??itemgroupkeyword\v!loose\endcsname
511  {\c_strc_itemgroups_optimize\zerocount}
512
513\defcsname\??itemgroupkeyword\v!tight\endcsname % new per 2023-07-16
514  {\c_strc_itemgroups_optimize\plusone}
515
516\defcsname\??itemgroupkeyword\v!verytight\endcsname % new per 2023-07-16
517  {\c_strc_itemgroups_optimize\plustwo}
518
519\defcsname\??itemgroupkeyword\v!tight:\v!first\endcsname % new per 2023-07-16
520  {\c_strc_itemgroups_optimize\plusthree}
521
522\defcsname\??itemgroupkeyword\v!tight:\v!last\endcsname % new per 2023-07-16
523  {\c_strc_itemgroups_optimize\plusfour}
524
525\defcsname\??itemgroupkeyword\v!fit\endcsname
526  {\c_strc_itemgroups_fitting\conditionaltrue}
527
528\defcsname\??itemgroupkeyword\v!nofit\endcsname
529  {\c_strc_itemgroups_fitting\conditionalfalse}
530
531\defcsname\??itemgroupkeyword\v!paragraph\endcsname
532  {\c_strc_itemgroups_paragraph\conditionaltrue
533   \strc_itemgroups_process_set_option_pack}
534
535\defcsname\??itemgroupkeyword\v!joinedup\endcsname
536  {\c_strc_itemgroups_joined\conditionaltrue
537   \strc_itemgroups_process_set_option_pack}
538
539\defcsname\??itemgroupkeyword\v!notjoinedup\endcsname
540  {\c_strc_itemgroups_joined\conditionalfalse}
541
542\defcsname\??itemgroupkeyword\v!serried\endcsname
543  {\edef\itemgroupfirst{-\ifempty\itemgroupfirst1\else\itemgroupfirst\fi}%
544   \letitemgroupparameter\c!factor\itemgroupfirst}
545
546\defcsname\??itemgroupkeyword\v!stopper\endcsname
547  {\letitemgroupparameter\c!placestopper\v!yes} % keep {}
548
549\defcsname\??itemgroupkeyword\v!nostopper\endcsname
550  {\letitemgroupparameter\c!placestopper\v!no} % keep {}
551
552\defcsname\??itemgroupkeyword\v!repeat\endcsname
553  {\c_strc_itemgroups_repeat\conditionaltrue}
554
555\defcsname\??itemgroupkeyword\v!norepeat\endcsname
556  {\c_strc_itemgroups_repeat\conditionalfalse}
557
558\defcsname\??itemgroupkeyword\v!reverse\endcsname
559  {\c_strc_itemgroups_reverse\conditionaltrue}
560
561\defcsname\??itemgroupkeyword\v!columns\endcsname
562  {\c_strc_itemgroups_columns\conditionaltrue}
563
564\defcsname\??itemgroupkeyword\v!overlay\endcsname
565  {\c_strc_itemgroups_overlay\conditionaltrue}
566
567\defcsname\??itemgroupkeyword\v!one  \endcsname{\letitemgroupparameter\c!n\plusone}
568\defcsname\??itemgroupkeyword\v!two  \endcsname{\letitemgroupparameter\c!n\plustwo}
569\defcsname\??itemgroupkeyword\v!three\endcsname{\letitemgroupparameter\c!n\plusthree}
570\defcsname\??itemgroupkeyword\v!four \endcsname{\letitemgroupparameter\c!n\plusfour}
571\defcsname\??itemgroupkeyword\v!five \endcsname{\letitemgroupparameter\c!n\plusfive}
572\defcsname\??itemgroupkeyword\v!six  \endcsname{\letitemgroupparameter\c!n\plussix}
573\defcsname\??itemgroupkeyword\v!seven\endcsname{\letitemgroupparameter\c!n\plusseven}
574\defcsname\??itemgroupkeyword\v!eight\endcsname{\letitemgroupparameter\c!n\pluseight}
575\defcsname\??itemgroupkeyword\v!nine \endcsname{\letitemgroupparameter\c!n\plusnine}
576
577\defcsname\??itemgroupkeyword\v!standard\endcsname
578  {\setitemgroupparameter  \c!width        {1.5\emwidth}%
579   \setitemgroupparameter  \c!distance     {.5\emwidth}%
580  %\letitemgroupparameter  \c!factor       \!!zerocount
581   \letitemgroupparameter  \c!factor       {\zerocount}%
582   \setitemgroupparameter  \c!packcriterium{\zerocount}%
583   \resetitemgroupparameter\c!inner
584   \resetitemgroupparameter\c!beforehead
585   \letitemgroupparameter  \c!afterhead    \blank
586   \letitemgroupparameter  \c!before       \blank
587   \letitemgroupparameter  \c!inbetween    \blank
588   \letitemgroupparameter  \c!after        \blank}
589
590\def\strc_itemgroups_initialize_local
591  {\c_strc_itemgroups_inline\conditionalfalse
592   \c_strc_itemgroups_concat\conditionalfalse
593   \c_strc_itemgroups_txt\conditionalfalse
594   \c_strc_itemgroups_no_par\conditionalfalse
595   %
596   \c_strc_itemgroups_reverse\conditionalfalse
597   \c_strc_itemgroups_intro\conditionalfalse
598   \c_strc_itemgroups_auto_intro\conditionalfalse
599   \c_strc_itemgroups_before\conditionalfalse
600   \c_strc_itemgroups_after\conditionalfalse
601   \c_strc_itemgroups_nowhite\conditionalfalse
602   \c_strc_itemgroups_randomize\conditionalfalse
603   \c_strc_itemgroups_horizontal\conditionalfalse
604   \c_strc_itemgroups_collecting\conditionalfalse
605   \c_strc_itemgroups_intro\conditionalfalse
606   \c_strc_itemgroups_continue\conditionalfalse
607   % this will be a constant
608   \c_strc_itemgroups_head\conditionalfalse
609   \c_strc_itemgroups_sub\conditionalfalse
610   \c_strc_itemgroups_symbol\conditionalfalse
611   \c_strc_itemgroups_columns\conditionalfalse
612   \c_strc_itemgroups_overlay\conditionalfalse
613   % to be checked
614   \lettonothing\m_strc_itemgroups_destination
615   \lettonothing\strc_itemgroups_used_symbol   % ** start value
616   \lettonothing\strc_itemgroups_margin_symbol
617   \lettonothing\strc_itemgroups_extra_symbol
618   %
619   \global\letitemgroupparameter\c!maxwidth\!!zeropoint
620   }
621
622\defcsname\??itemgroupfirst\v!intro\endcsname
623  {\c_strc_itemgroups_intro\conditionaltrue}
624
625\defcsname\??itemgroupfirst\v!continue\endcsname
626  {\c_strc_itemgroups_continue\conditionaltrue}
627
628\defcsname\??itemgroupfirst\v!random\endcsname
629  {\c_strc_itemgroups_randomize\conditionaltrue
630   \c_strc_itemgroups_collecting\conditionaltrue}
631
632\defcsname\??itemgroupkeyword\v!horizontal\endcsname
633  {\c_strc_itemgroups_horizontal\conditionaltrue
634   \c_strc_itemgroups_collecting\conditionaltrue
635   \c_strc_itemgroups_inline\conditionaltrue
636   \c_strc_itemgroups_joined\conditionaltrue
637   \strc_itemgroups_process_set_option_pack}
638
639\def\strc_itemgroups_preset_stage_one#options%
640  {\processcommacommand[#options]\strc_itemgroups_preset_stage_one_indeed}
641
642% \installcommalistprocessorcommand \strc_itemgroups_preset_stage_one_list \strc_itemgroups_preset_stage_one_indeed
643%
644% \def\strc_itemgroups_preset_stage_one#options%
645%   {\normalexpanded{\strc_itemgroups_preset_stage_one_list[#options]}}
646
647\def\strc_itemgroups_preset_stage_one_indeed#option%
648  {\ifcsname\??itemgroupfirst#option\endcsname
649     \lastnamedcs
650   \fi}
651
652\ifdefined\dotagsetitemgroup \else \aliased\let\dotagsetitemgroup\relax             \fi
653\ifdefined\dotagsetitem      \else \aliased\let\dotagsetitem     \gobbleoneargument \fi
654
655\def\strc_itemgroups_tag_start_group
656  {\dostarttaggedchained\t!itemgroup\currentparentitemgroup\currentitemgroup\??itemgroup
657   \dotagsetitemgroup}
658
659\def\strc_itemgroups_tag_stop_group
660  {\dostoptagged}
661
662\def\strc_itemgroups_before_command
663  {\ifconditional\c_strc_itemgroups_nowhite
664     \ifconditional\c_strc_itemgroups_before
665       \ifcase\c_strc_itemgroups_nesting\or\itemgroupparameter\c!before\fi
666     \else
667       \nowhitespace
668     \fi
669   \orelse\ifconditional\c_strc_itemgroups_joined
670     % \empty
671   \else
672     \itemgroupparameter\c!before
673   \fi}
674
675\def\strc_itemgroups_after_command
676  {\ifconditional\c_strc_itemgroups_nowhite
677     \ifconditional\c_strc_itemgroups_after
678       \ifcase\c_strc_itemgroups_nesting\or\itemgroupparameter\c!after\fi
679     \else
680       \nowhitespace
681     \fi
682   \orelse\ifconditional\c_strc_itemgroups_joined
683     % \empty
684   \else
685     \itemgroupparameter\c!after
686   \fi}
687
688\def\strc_itemgroups_between_command
689  {\ifconditional\c_strc_itemgroups_nowhite
690     \nowhitespace
691   \orelse\ifconditional\c_strc_itemgroups_joined
692     % \empty
693   \else
694     \itemgroupparameter\c!inbetween
695   \fi}
696
697\def\strc_itemgroups_before_head_command
698  {\ifconditional\c_strc_itemgroups_nowhite
699     \nowhitespace
700   \orelse\ifconditional\c_strc_itemgroups_joined
701     % \empty
702   \else
703     \itemgroupparameter\c!beforehead
704   \fi}
705
706\def\strc_itemgroups_after_head_command
707  {\ifconditional\c_strc_itemgroups_nowhite
708     \nowhitespace
709   \orelse\ifconditional\c_strc_itemgroups_joined
710     % \empty
711   \else
712     \itemgroupparameter\c!afterhead
713   \fi}
714
715% compatible setup command:
716
717\let\strc_itemgroups_normal_setup\setupitemgroup
718
719\permanent\overloaded\tolerant\protected\def\setupitemgroup[#S#category]#spacer[#S#levels]#spacer[#S#options]#spacer[#S#settings]% category level|each options|settings settings|options
720  {\ifarguments
721     % nothing to set up
722   \or
723     \edef\strc_itemgroups_setup_what{#levels}%
724     \strc_itemgroups_normal_setup[#category]% == settings
725   \or
726     \edef\strc_itemgroups_setup_what{#levels}%
727     \strc_itemgroups_setup_each{#category}{#levels}%
728   \or
729     \edef\strc_itemgroups_setup_what{#levels}%
730     \ifx\strc_itemgroups_setup_what\v!each
731       \strc_itemgroups_setup_each{#category}{#options}%
732     \else
733       \strc_itemgroups_setup_list{#levels}{#category}{#options}%
734     \fi
735   \or
736     \edef\strc_itemgroups_setup_what{#levels}%
737     \ifx\strc_itemgroups_setup_what\v!each
738       \strc_itemgroups_setup_each{#category}{#options}%
739       \strc_itemgroups_setup_each{#category}{#settings}%
740     \else
741       \strc_itemgroups_setup_list{#levels}{#category}{#options}%
742       \strc_itemgroups_setup_list{#levels}{#category}{#settings}%
743     \fi
744   \fi}
745
746\def\strc_itemgroups_setup_each#category#whatever%
747  {\ifhastok={#whatever}%
748     \strc_itemgroups_normal_setup[#category][#whatever]%
749   \else
750     \strc_itemgroups_normal_setup[#category][\c!option={#whatever}]%
751   \fi}
752
753\def\strc_itemgroups_setup_list_level_a#category#whatever#level%
754  {\strc_itemgroups_normal_setup[#category:#level][#whatever]}
755
756\def\strc_itemgroups_setup_list_level_b#category#whatever#level%
757  {\strc_itemgroups_normal_setup[#category:#level][\c!option={#whatever}]}
758
759\def\strc_itemgroups_setup_list#subcategories#category#whatever%
760  {\ifhastok={#whatever}%
761     \processcommalist[#subcategories]{\strc_itemgroups_setup_list_level_a{#category}{#whatever}}%
762   \else
763     \processcommalist[#subcategories]{\strc_itemgroups_setup_list_level_b{#category}{#whatever}}%
764   \fi}
765
766\def\strc_itemgroups_increment_item_counter
767  {\ifconditional\c_strc_itemgroups_sub \else
768     \ifconditional\c_strc_itemgroups_symbol \else % \ifempty\strc_itemgroups_extra_symbol
769       \strc_counters_increment_sub\v_strc_itemgroups_counter\currentitemlevel
770     \fi
771   \fi}
772
773\protected\def\strc_itemgroups_insert_item_counter
774  {\ifconditional\c_strc_itemgroups_repeat
775     \ifcase\c_strc_itemgroups_nesting
776       % skip
777     \or
778       \strc_itemgroups_insert_item_counter_indeed % this could become an option
779     \else
780       \strc_itemgroups_insert_item_counter_indeed
781     \fi
782   \else
783     \strc_itemgroups_insert_item_counter_indeed
784   \fi}
785
786\installcorenamespace{itemstopper}
787
788\defcsname\??itemstopper\v!yes\endcsname
789  {\itemgroupparameter\c!stopper}
790
791\defcsname\??itemstopper\v!display\endcsname
792  {\ifconditional\c_strc_itemgroups_inline\else
793     \itemgroupparameter\c!stopper
794   \fi}
795
796\defcsname\??itemstopper\v!inline\endcsname
797  {\ifconditional\c_strc_itemgroups_inline
798     \itemgroupparameter\c!stopper
799   \fi}
800
801\def\strc_itemgroups_insert_item_counter_indeed % quite slow ... every time this setup .. but it
802  {\begingroup                                  % can be optimized ... best move some to strc-num
803   \setupcounter
804     [\v_strc_itemgroups_counter]%
805     [\c!prefix=\itemgroupparameter\c!prefix,
806      \c!prefixstopper=\itemgroupparameter\c!prefixstopper,
807      \c!prefixseparatorset=\itemgroupparameter\c!prefixseparatorset,
808      \c!prefixconversion=\itemgroupparameter\c!prefixconversion,
809      \c!prefixconversionset=\itemgroupparameter\c!prefixseparatorset,
810      \c!prefixset=\itemgroupparameter\c!prefixset,
811      \c!prefixsegments=\itemgroupparameter\c!prefixsegments,
812      \c!prefixconnector=\itemgroupparameter\c!prefixconnector,
813      \c!criterium=\itemgroupparameter\c!criterium,
814      \c!numberorder=\ifconditional\c_strc_itemgroups_reverse\v!reverse\else\v!normal\fi,
815      \c!numberstopper=\begincsname\??itemstopper\itemgroupparameter\c!placestopper\endcsname,
816      \c!numberconversionset=\v_strc_itemgroups_counter,
817      \c!numbersegments=\currentitemgroupsegments]%
818   % there will be a fixedconversion key
819   \normalexpanded{\defineconversionset[\v_strc_itemgroups_counter][\currentitemgroupconversionset][\currentitemgroupsymbol]}%
820  %\normalexpanded{\strc_sets_define_conversion_set[\v_strc_itemgroups_counter][\currentitemgroupconversionset][\currentitemgroupsymbol]}%
821   %
822   \convertedcounter[\v_strc_itemgroups_counter]% [\number\currentitemlevel]%
823   \strc_itemgroups_insert_reference
824   \endgroup}
825
826% needs testing (maybe it need to happen later)
827%
828% \appendtoks
829%    \setupcounter
830%      [\v_strc_itemgroups_counter]%
831%      [\c!prefix=\itemgroupparameter\c!prefix,
832%       \c!prefixstopper=\itemgroupparameter\c!prefixstopper,
833%       \c!prefixseparatorset=\itemgroupparameter\c!prefixseparatorset,
834%       \c!prefixconversion=\itemgroupparameter\c!prefixconversion,
835%       \c!prefixconversionset=\itemgroupparameter\c!prefixseparatorset,
836%       \c!prefixset=\itemgroupparameter\c!prefixset,
837%       \c!prefixsegments=\itemgroupparameter\c!prefixsegments,
838%       \c!prefixconnector=\itemgroupparameter\c!prefixconnector,
839%       \c!criterium=\itemgroupparameter\c!criterium,
840%       \c!numberorder=\ifconditional\c_strc_itemgroups_reverse\v!reverse\else\v!normal\fi,
841%       \c!numberstopper=\expdoif{\itemgroupparameter\c!placestopper}\v!yes{\itemgroupparameter\c!stopper},
842%       \c!numberconversionset=\v_strc_itemgroups_counter,
843%       \c!numbersegments=\currentitemgroupsegments]%
844% \to\itemgroupcommands
845%
846% \def\strc_itemgroups_insert_item_counter_indeed % quite slow ... every time this setup .. but it
847%   {\begingroup                                  % can be optimized ... best move some to strc-num
848%    % there will be a fixedconversion key
849%   %\normalexpanded{\defineconversionset[\v_strc_itemgroups_counter][\currentitemgroupconversionset][\currentitemgroupsymbol]}%
850%    \normalexpanded{\strc_sets_define_conversion_set[\v_strc_itemgroups_counter][\currentitemgroupconversionset][\currentitemgroupsymbol]}%
851%    %
852%    \convertedcounter[\v_strc_itemgroups_counter]% [\number\currentitemlevel]%
853%    \strc_itemgroups_insert_reference
854%    \endgroup}
855
856\lettonothing\strc_itemgroups_temp_symbol
857\lettonothing\strc_itemgroups_used_symbol
858\lettonothing\strc_itemgroups_asked_symbol
859\lettonothing\strc_itemgroups_margin_symbol
860\lettonothing\strc_itemgroups_extra_symbol
861
862\def\strc_itemgroups_set_symbol#symbol%
863  {\edef\strc_itemgroups_temp_symbol{#symbol}%
864   \ifempty\strc_itemgroups_temp_symbol \else
865     \doifelsesymboldefined\strc_itemgroups_temp_symbol
866        \strc_itemgroups_set_symbol_symbol
867        {\doifelseconversiondefined\strc_itemgroups_temp_symbol
868           \strc_itemgroups_set_symbol_conversion
869           \donothing}%
870   \fi}
871
872\def\strc_itemgroups_set_symbol_symbol
873  {\let\currentitemgroupsymbol\strc_itemgroups_temp_symbol
874   \strc_itemgroups_store_global_symbol\currentitemgroupsymbol
875   \strc_itemgroups_store_local_symbol\v_strc_itemgroups_unknown_symbol
876   \let\strc_itemgroups_used_symbol\strc_itemgroups_set_symbol_symbol_item
877   \lettonothing\strc_itemgroups_asked_symbol}
878
879\def\strc_itemgroups_set_symbol_conversion
880  {\let\currentitemgroupsymbol\strc_itemgroups_temp_symbol
881   \strc_itemgroups_store_global_symbol\currentitemgroupsymbol
882   \strc_itemgroups_store_local_symbol\strc_itemgroups_insert_item_counter
883   \let\strc_itemgroups_used_symbol\strc_itemgroups_set_symbol_conversion_item
884   \lettonothing\strc_itemgroups_asked_symbol}
885
886\def\strc_itemgroups_set_symbol_symbol_item
887  {\symbol[\currentitemgroupsymbol]}
888
889\def\strc_itemgroups_set_symbol_conversion_item
890  {\ifconditional\c_strc_itemgroups_text
891     % maybe block stopper here, but one can as well clone an itemgroup then
892     \itemgroupparameter\c!lefttext
893     \strc_itemgroups_fetch_local_symbol
894     \itemgroupparameter\c!righttext
895   \else
896     \itemgroupparameter\c!left
897     \strc_itemgroups_fetch_local_symbol
898     \itemgroupparameter\c!right
899   \fi}
900
901\def\strc_itemgroups_calculate_list_width#level%
902  {\let\m_strc_itemgroups_saved\currentitemgroup
903   \cdef\currentitemgroup{\currentparentitemgroup:\number#level}%
904   \ifdim\d_strc_itemgroups_max_width>\zeropoint
905     \d_strc_itemgroups_list_width\d_strc_itemgroups_max_width
906   \orelse\ifnum\itemgroupparameter\c!factor>\zerocount
907     \d_strc_itemgroups_list_width\itemgroupparameter\c!step\relax
908     \ifzeropt\d_strc_itemgroups_list_width \d_strc_itemgroups_list_width=.5em\fi
909     \multiplyby\d_strc_itemgroups_list_width \itemgroupparameter\c!factor
910     \advanceby\d_strc_itemgroups_list_width{\itemgroupparameter\c!width}%
911   \else
912     \d_strc_itemgroups_list_width{\itemgroupparameter\c!width}%
913   \fi
914   \advanceby\d_strc_itemgroups_list_width{\itemgroupparameter\c!distance}%
915   \let\currentitemgroup\m_strc_itemgroups_saved}
916
917\lettonothing\p_itemgroups_options
918\lettonothing\p_itemgroups_extra_options
919
920\permanent\tolerant\protected\def\startitemgroup[#S#category]#spacer[#S#options]#spacer[#S#settings]%
921  {\begingroup % (1)
922   \nofarguments\lastarguments
923   \cdef\currentitemgroup{#category}% no nested mixing of itemgroups
924   \let\currentparentitemgroup\currentitemgroup
925   \global\advanceby\c_strc_itemgroups_nesting\plusone
926   \def\currentitemlevel{\the\c_strc_itemgroups_nesting}%
927   \normalexpanded{\chaintocurrentitemgroup{\currentparentitemgroup:\currentitemlevel}}%
928   \cdef\currentitemgroup{\currentparentitemgroup:\currentitemlevel}%
929   %
930   \edef\p_itemgroups_options{\itemgroupparameter\c!option}%
931   \lettonothing\p_itemgroups_extra_options
932   \ifcase\nofarguments
933     \strc_itemgroups_start_indeed{}%
934   \or
935     \strc_itemgroups_start_indeed{}%
936   \or
937     \ifhastok={#options}%
938       \strc_itemgroups_start_indeed{#options}%
939     \else
940       \edef\p_itemgroups_extra_options{#options}%
941       \strc_itemgroups_start_indeed{}%
942     \fi
943   \or
944     \edef\p_itemgroups_extra_options{#options}%
945     \strc_itemgroups_start_indeed{#settings}%
946   \fi}
947
948\def\strc_itemgroups_start_indeed#settings%
949  {\ifempty\p_itemgroups_options
950     \let\p_itemgroups_options\p_itemgroups_extra_options
951   \orelse\ifempty\p_itemgroups_extra_options
952     % ok
953   \else
954     \edef\p_itemgroups_options{\p_itemgroups_options,\p_itemgroups_extra_options}%
955   \fi
956   \begingroup % (2)
957   \the\itemgroupcommands
958   \setconditional\c_strc_itemgroups_text_saved\c_strc_itemgroups_text
959   \strc_itemgroups_initialize_local
960   \strc_itemgroups_preset_stage_one\p_itemgroups_options
961   \iftrialtypesetting
962     \strc_counters_save\v_strc_itemgroups_counter
963   \fi
964\globalpushmacro\c_strc_itemgroups_n_of_items
965\global\c_strc_itemgroups_n_of_items\zerocount
966   \strc_itemgroups_check_n_of_items
967   \ifempty\p_itemgroups_options
968     \strc_itemgroups_setup_symbol_default
969     \strc_itemgroups_reset_continue_state
970     \setupcurrentitemgroup[#settings]%
971   \else
972     \strc_itemgroups_process_options\p_itemgroups_options
973     \setupcurrentitemgroup[#settings]%
974     \ifconditional\c_strc_itemgroups_continue
975       \strc_itemgroups_setup_symbol_continue
976       \strc_itemgroups_fetch_continue_state
977     \else
978       \strc_itemgroups_setup_symbol_asked
979       \strc_itemgroups_store_continue_state\p_itemgroups_options{#settings}%
980     \fi
981   \fi
982   %
983   \ifhmode
984     \ifconditional\c_strc_itemgroups_auto_concat
985       \ifnum\lastboundary=\c_strc_itemgroups_boundary
986         \c_strc_itemgroups_concat\conditionaltrue
987       \fi
988     \fi
989     \ifconditional\c_strc_itemgroups_text_saved
990     \orelse\ifconditional\c_strc_itemgroups_text
991     \orelse\ifconditional\c_strc_itemgroups_no_par
992     \else
993       \par
994     \fi
995   \fi
996   %
997   \ifconditional\c_strc_itemgroups_pack
998     \ifnum\currentnofitems>\itemgroupparameter\c!packcriterium\relax\else
999       \c_strc_itemgroups_pack\conditionalfalse
1000     \fi
1001   \fi
1002   %
1003   \ifconditional\c_strc_itemgroups_text % also does inline
1004     % ignore
1005   \orelse\ifnum\c_strc_itemgroups_nesting=\plusone % NIEUW
1006     \doadaptleftskip {\itemgroupparameter\c!margin}%
1007     \doadaptleftskip {\itemgroupparameter\c!leftmargin}%
1008     \doadaptrightskip{\itemgroupparameter\c!rightmargin}%
1009   \fi
1010   %
1011   \doadaptleftskip {\itemgroupparameter\c!leftmargindistance}%
1012   \doadaptrightskip{\itemgroupparameter\c!rightmargindistance}%
1013   %
1014   \edef\m_strc_itemgroups_spacing{\itemgroupparameter\c!spacing}%
1015   \ifx\m_strc_itemgroups_spacing\v!before
1016     \c_strc_itemgroups_spacing_mode\zerocount
1017   \orelse\ifx\m_strc_itemgroups_spacing\v!inbetween
1018     \c_strc_itemgroups_spacing_mode\plusone
1019   \orelse\ifx\m_strc_itemgroups_spacing\v!auto
1020     \c_strc_itemgroups_spacing_mode\plustwo
1021   \fi
1022   %
1023   \usealignparameter\itemgroupparameter
1024   \edef\m_strc_itemgroups_indenting{\itemgroupparameter\c!indenting}%
1025   \ifnum\c_strc_itemgroups_nesting>\zerocount
1026     \c_strc_itemgroups_first\conditionaltrue
1027     \ifconditional\c_strc_itemgroups_continue \else
1028       \strc_counters_restart_sub\v_strc_itemgroups_counter\currentitemlevel{(\itemgroupparameter\c!start)-\plusone}%
1029     \fi
1030   \fi
1031   \ifempty\strc_itemgroups_used_symbol
1032     \strc_itemgroups_set_symbol\strc_itemgroups_asked_symbol % ** default value
1033     \ifempty\strc_itemgroups_used_symbol
1034       \let\currentitemgroupsymbol\currentitemlevel % ** fall back
1035     \fi
1036   \fi
1037   \ifconditional\c_strc_itemgroups_auto_intro\ifnum\prevgraf<\plusthree
1038     \c_strc_itemgroups_intro\conditionaltrue
1039   \fi\fi
1040   \ifconditional\c_strc_itemgroups_paragraph
1041     \ifnum\c_strc_itemgroups_nesting>\plusone
1042       \resetitemgroupparameter\c!inbetween
1043     \fi
1044   \fi
1045   \ifconditional\c_strc_itemgroups_pack
1046     \resetitemgroupparameter\c!inbetween
1047   \fi
1048   \ifconditional\c_strc_itemgroups_columns
1049     \ifinsidecolumns\orelse\ifcase\c_strc_itemgroups_column_depth
1050       \global\c_strc_itemgroups_column_depth\c_strc_itemgroups_nesting % global ?
1051       \strc_itemgroups_before_command
1052       \strc_itemgroups_tag_start_group
1053       \strc_itemgroups_start_columns
1054     \fi
1055   \fi
1056   \ifconditional\c_strc_itemgroups_fitting
1057     \ifdim\d_strc_itemgroups_max_width>\zeropoint
1058       \letitemgroupparameter\c!width\d_strc_itemgroups_max_width_reference
1059     \fi
1060   \fi
1061   \strc_itemgroups_calculate_list_width\c_strc_itemgroups_nesting
1062   \ifdim\d_strc_itemgroups_list_width>\zeropoint\relax
1063     \ifconditional\c_strc_itemgroups_inline\else
1064       \frozen\advanceby\leftskip\d_strc_itemgroups_list_width\relax
1065     \fi
1066   \fi
1067   \ifempty\m_strc_itemgroups_repeat_start
1068     \let\currentitemgroupconversionset \currentitemgroupsymbol
1069     \edef\currentitemgroupsegments     {\currentitemlevel}%
1070   \else
1071     \edef\currentitemgroupconversionset{\currentitemgroupconversionset,\currentitemgroupsymbol}%
1072     \edef\currentitemgroupsegments     {\m_strc_itemgroups_repeat_start:\currentitemlevel}%
1073   \fi
1074   \d_strc_itemgroups_asked_width{\itemgroupparameter\c!width}%
1075   \startcollectitems}
1076
1077\let\startcollectitems\relax
1078\let\stopcollectitems \relax
1079
1080\letcsname\??itemgroupalign\v!flushleft \endcsname\relax
1081\letcsname\??itemgroupalign\v!right     \endcsname\relax
1082\letcsname\??itemgroupalign\v!flushright\endcsname\hfill
1083\letcsname\??itemgroupalign\v!left      \endcsname\hfill
1084\letcsname\??itemgroupalign\v!middle    \endcsname\hfil
1085\letcsname\??itemgroupalign\v!center    \endcsname\hfil
1086
1087\def\strc_itemgroups_left_sym_filler
1088  {\csname\??itemgroupalign\itemgroupparameter\c!symalign\endcsname}
1089
1090% symbols + states
1091
1092\def\strc_itemgroups_store_global_symbol#symbol%
1093  {\gletcsname\??itemgroupglobal\currentitemgroup:\currentitemlevel\endcsname#symbol}
1094
1095\def\strc_itemgroups_store_local_symbol#symbol%
1096  {\gletcsname\??itemgrouplocal\currentitemgroup:\currentitemlevel\endcsname#symbol}
1097
1098\def\strc_itemgroups_fetch_global_symbol
1099  {\csname\??itemgroupglobal\currentitemgroup:\currentitemlevel\endcsname}
1100
1101\def\strc_itemgroups_fetch_local_symbol
1102  {\csname\??itemgrouplocal\currentitemgroup:\currentitemlevel\endcsname}
1103
1104\def\strc_itemgroups_setup_symbol_default
1105  {\edef\strc_itemgroups_asked_symbol{\itemgroupparameter\c!symbol}%
1106   \strc_itemgroups_store_global_symbol\empty}
1107
1108\def\strc_itemgroups_setup_symbol_continue
1109  {\ifcsname\??itemgroupglobal\currentitemgroup:\currentitemlevel\endcsname
1110     \let\strc_itemgroups_asked_symbol\strc_itemgroups_fetch_global_symbol
1111   \else
1112     \let\strc_itemgroups_asked_symbol\currentitemlevel
1113   \fi}
1114
1115\def\strc_itemgroups_setup_symbol_asked
1116   {\edef\strc_itemgroups_asked_symbol{\itemgroupparameter\c!symbol}}
1117
1118\ifdefined\strc_itemgroups_start_columns
1119
1120    % already defined in page-mix
1121
1122\else
1123
1124    % will be redefined in page-mix
1125
1126    \ifdefined\startcolumns \else
1127        \protected\def\startcolumns[#S#settings]{}
1128        \protected\def\stopcolumns              {}
1129    \fi
1130
1131    \def\strc_itemgroups_start_columns
1132      {\startcolumns
1133         [\c!n=\itemgroupparameter\c!n,
1134          \c!height=,
1135          \c!rule=\v!off,
1136          \c!balance=\v!yes,
1137          \c!align=\v!no]}
1138
1139    \def\strc_itemgroups_stop_columns
1140      {\stopcolumns}
1141
1142\fi
1143
1144\permanent\protected\def\stopitemgroup
1145  {\stopcollectitems
1146   \ifconditional\c_strc_itemgroups_text
1147     \removeunwantedspaces
1148     \space
1149     \ignorepars % \ignorespaces
1150   \else
1151     \par
1152   \fi
1153   \strc_itemgroups_register_status
1154 % \ifconditional\c_strc_itemgroups_first \else
1155   \ifnum\c_strc_itemgroups_n_of_items>\zerocount % different criterium
1156     \dostoptagged
1157     \dostoptagged
1158   % \endgroup % (3)
1159   \fi
1160   \ifnum\c_strc_itemgroups_column_depth=\c_strc_itemgroups_nesting\relax
1161     \strc_itemgroups_stop_columns
1162     \global\c_strc_itemgroups_column_depth\zerocount % global ?
1163     \strc_itemgroups_tag_stop_group
1164     \strc_itemgroups_after_command
1165     \dontrechecknextindentation
1166   \orelse\ifnum\c_strc_itemgroups_nesting=\plusone
1167     \strc_itemgroups_insert_breakallow
1168     \strc_itemgroups_tag_stop_group
1169     \strc_itemgroups_after_command
1170     \useindentnextparameter\itemgroupparameter
1171   \else
1172     % nieuw, not yet nobreak handling
1173     \strc_itemgroups_tag_stop_group
1174     \ifcase\c_strc_itemgroups_spacing_mode
1175       \strc_itemgroups_after_command
1176     \or
1177       % was \strc_itemgroups_after_command
1178      %\ifempty\strc_itemgroups_after_command % here it's unset
1179       \ifempty{\directitemgroupparameter\c!after}%
1180         \strc_itemgroups_inbetween_command
1181       \else
1182         \strc_itemgroups_after_command
1183       \fi
1184     \else
1185       % was nothing
1186       \strc_itemgroups_inbetween_command
1187     \fi
1188     \dontrechecknextindentation
1189   \fi
1190   % new test, needed in sidefloats (surfaced in volker's proceedings)
1191   \iftrialtypesetting
1192     \strc_counters_restore\v_strc_itemgroups_counter % could happen in LUA
1193   \fi
1194   \globalpopmacro\c_strc_itemgroups_n_of_items
1195   \global\advanceby\c_strc_itemgroups_nesting\minusone
1196   \xdef\currentitemlevel{\the\c_strc_itemgroups_nesting}%
1197  %\ifconditional\c_strc_itemgroups_text
1198     \endgroup % (2)
1199     \endgroup % (1)
1200  %\else
1201  %  \endgroup % (2)
1202  %  \endgroup % (1)
1203  %  \par % hm, already done, and dangerous as \c_strc_itemgroups_text is already forgotten
1204  %\fi
1205   \dorechecknextindentation}
1206
1207% The items.
1208
1209\def\strc_itemgroups_start_item_first
1210  {\c_strc_itemgroups_first\conditionalfalse
1211 % \begingroup % (3)
1212   \ifcase\c_strc_itemgroups_nesting
1213                                           % 0
1214   \or
1215     \strc_itemgroups_start_item_first_one % 1
1216   \else
1217     \strc_itemgroups_start_item_first_two % 2+
1218   \fi}
1219
1220\def\strc_itemgroups_start_item_first_one
1221  {\ifcase\c_strc_itemgroups_column_depth
1222     \ifconditional\c_strc_itemgroups_intro\strc_itemgroups_insert_breakno\fi
1223     \strc_itemgroups_before_command
1224     \strc_itemgroups_tag_start_group
1225     \ifconditional\c_strc_itemgroups_intro\strc_itemgroups_insert_breakno\fi
1226   \fi}
1227
1228\newinteger\c_strc_itemgroups_prev_level
1229
1230\def\strc_itemgroups_inbetween_command
1231  {\nameditemgroupparameter{\currentparentitemgroup:\the\c_strc_itemgroups_prev_level}\c!inbetween}
1232
1233\def\strc_itemgroups_start_item_first_two
1234  {\ifconditional\c_strc_itemgroups_paragraph\else
1235     \c_strc_itemgroups_prev_level{\c_strc_itemgroups_nesting-\plusone}%
1236     \ifcase\c_strc_itemgroups_spacing_mode
1237       \strc_itemgroups_before_command
1238     \or
1239      %\ifempty\strc_itemgroups_before_command % should possibly expand to empty
1240      \ifempty{\directitemgroupparameter\c!before}%
1241         \strc_itemgroups_inbetween_command
1242       \else
1243         \strc_itemgroups_before_command
1244       \fi
1245     \else
1246       \strc_itemgroups_inbetween_command
1247     \fi
1248     \strc_itemgroups_tag_start_group
1249   \fi}
1250
1251\def\strc_itemgroups_start_item_next
1252  {%\dostoptagged % moved
1253   %\dostoptagged % moved
1254   \ifconditional\c_strc_itemgroups_text
1255     \ifhmode
1256       % WS: make the distance between items customizable, think about better default values -> see itemize-1.tex
1257       \strc_itemgroups_set_text_item_distance% HH: moved out and made configurable (sort of)
1258       \removeunwantedspaces
1259       \ifnum{\c_strc_itemgroups_n_of_items+\plusone}=\c_strc_itemgroups_max_items
1260         \itemgroupparameter\c!lasttextseparator
1261       \else
1262         \itemgroupparameter\c!textseparator
1263       \fi
1264       \ifempty\m_strc_itemgroups_text_distance
1265         % safeguard
1266       \else
1267         \hskip\m_strc_itemgroups_text_distance\relax
1268       \fi
1269     \fi
1270   \else
1271     \strc_itemgroups_between_command
1272   \fi}
1273
1274% c_strc_itemgroups_concat:
1275%
1276% the problem is that we use leftskip so concat cannot reliable take the height into
1277% account; it's .. rather tricky when white space in there anyway (due to \par) .. so
1278% we rely on a special blank method
1279%
1280% \startitemize[n]
1281%     \item bla
1282%     \item \startitemize[a]
1283%         \item bla $\displaystyle\int^{x^{y^4}}$ \item bla
1284%     \stopitemize
1285% \stopitemize
1286
1287\mutable\lettonothing\currentitemreference
1288
1289\noaligned\tolerant\permanent\protected\def\startitemgroupitem[#reference]% we can reuse more
1290  {\strc_itemgroups_begin
1291   \def\currentitemreference{#reference}%
1292   \ifconditional\c_strc_itemgroups_text
1293     % begin of item
1294   \orelse\ifconditional\c_strc_itemgroups_no_par
1295     % special
1296   \else
1297     \par
1298   \fi
1299   \ifconditional\c_strc_itemgroups_concat
1300     \strc_itemgroups_insert_breakno
1301   \fi
1302 % \ifconditional\c_strc_itemgroups_first
1303 %   \strc_itemgroups_start_item_first
1304 % \else
1305 %   \strc_itemgroups_start_item_next
1306 % \fi
1307 % now:
1308   \strc_itemgroups_increment_item_counter
1309   \ifnum\c_strc_itemgroups_n_of_items>\zerocount % different criterium
1310     \dostoptagged % moved here
1311     \dostoptagged % moved here
1312     \strc_itemgroups_start_item_next
1313   \else
1314     \strc_itemgroups_start_item_first
1315   \fi
1316   \ifconditional\c_strc_itemgroups_concat
1317     \spac_overlay_lines % see spac-ver.mkvi ... a typical potential problem
1318     \c_strc_itemgroups_concat\conditionalfalse
1319   \fi
1320   \dostarttaggednodetail\t!item
1321  % \dotagsetitem\empty
1322   \dostarttaggednodetail\t!itemtag
1323   \strc_itemgroups_insert_item
1324   \dostoptagged
1325   \ifconditional\c_strc_itemgroups_pack
1326     \setupwhitespace[\v!none]%
1327   \fi
1328   \itemgroupparameter\c!inner % will become obsolete (better use setups)
1329   \strc_itemgroups_margin_symbol
1330   \let\strc_itemgroups_margin_symbol\relax
1331   \dostarttaggednodetail\t!itemcontent
1332   \begstrut % \strut
1333   \nobreak                            % else problems with intext items
1334   \seteffectivehsize % NEW !
1335   \boundary\c_strc_itemgroups_boundary % was signal
1336   \itemgroupparameter\c!command}
1337
1338\noaligned\protected\permanent\def\stopitemgroupitem
1339  {\ifhmode
1340     \endstrut % new per 2017-12-15
1341   \fi
1342   \ifconditional\c_strc_itemgroups_text
1343     % nothing
1344   \else
1345     \endgraf
1346   \fi
1347   \strc_itemgroups_end}
1348
1349\lettonothing\strc_itemgroups_begin
1350\lettonothing\strc_itemgroups_end
1351
1352\tolerant\permanent\protected\def\startitemgrouphead[#reference]%
1353  {\ifconditional\c_strc_itemgroups_first \else
1354     \strc_itemgroups_insert_breakallow
1355   \fi
1356   \ifconditional\c_strc_itemgroups_pack \else
1357     \strc_itemgroups_before_head_command
1358   \fi
1359   \ifconditional\c_strc_itemgroups_first
1360     \ifconditional\c_strc_itemgroups_intro \else
1361       \ifcase\c_strc_itemgroups_nesting
1362         \strc_itemgroups_insert_breakallow
1363       \fi
1364     \fi
1365   \fi
1366  %\strc_itemgroups_start_item[#reference]%
1367   \startitemgroupitem[#reference]%
1368   \pickupgroupedcommand
1369     \strc_itemgroups_start_head_indeed
1370     \strc_itemgroups_stop_head_indeed
1371     \strc_itemgroups_head_body_indeed}
1372
1373\permanent\protected\def\stopitemgrouphead
1374  {\dostoptagged
1375   \stopitemgroupitem}
1376
1377\protected\def\strc_itemgroups_start_head_indeed
1378  {\c_strc_itemgroups_head\conditionaltrue
1379   \dotagsetitem\s!head% % weird place
1380   \dostarttaggednodetail\t!itemhead
1381   \useitemgroupstyleandcolor\c!headstyle\c!headcolor
1382   \ignorepars} % \ignorespaces
1383
1384\protected\def\strc_itemgroups_stop_head_indeed
1385  {\removeunwantedspaces
1386   \dostoptagged
1387   \ifconditional\c_strc_itemgroups_inline_head
1388       \space
1389       \ignorepars % \ignorespaces
1390   \else
1391     \ifconditional\c_strc_itemgroups_text
1392       \space
1393       \ignorepars % \ignorespaces
1394     \else
1395       \par
1396     \fi
1397     \strc_itemgroups_insert_breakno
1398     \ifconditional\c_strc_itemgroups_pack\else\strc_itemgroups_after_head_command\fi
1399     \strc_itemgroups_insert_breakno
1400  \fi}
1401
1402\protected\def\strc_itemgroups_head_body_indeed
1403  {\dostarttaggednodetail\t!itembody
1404   \noindentation
1405   \ignorepars} % \ignorespaces
1406
1407% Simple commands.
1408
1409\protected\def\strc_itemgroups_start_do_item
1410  {\startitemgroupitem}
1411
1412\protected\def\strc_itemgroups_start_no_item
1413  {\lettonothing\currentitemreference
1414   \strc_itemgroups_increment_item_counter
1415  %\advanceby\c_strc_itemgroups_n_of_items\plusone
1416   \setbox\b_strc_itemgroups\emptyhbox
1417   \strc_itemgroups_check_for_repeated
1418   \ignorepars} % \ignorespaces
1419
1420\protected\def\strc_itemgroups_start_button[#destination]%
1421  {\edef\m_strc_itemgroups_destination{#destination}%
1422   \startitemgroupitem}
1423
1424\protected\def\strc_itemgroups_start_symbol#text%
1425  {\def\strc_itemgroups_extra_symbol{#text}%
1426   \c_strc_itemgroups_symbol\conditionaltrue
1427   \startitemgroupitem
1428   \dotagsetitem\s!symbol}
1429
1430\protected\def\strc_itemgroups_start_dummy
1431  {\strc_itemgroups_start_symbol
1432  %\strut\strut} % two ?
1433   \begstrut}
1434
1435\protected\def\strc_itemgroups_start_subitem
1436  {\c_strc_itemgroups_sub\conditionaltrue
1437   \startitemgroupitem
1438   \dotagsetitem\s!sub}
1439
1440\protected\def\strc_itemgroups_start_edge#text%
1441  {\strc_itemgroups_start_symbol
1442     {\strc_itemgroups_calculate_list_width\c_strc_itemgroups_nesting
1443      \dostarttaggednodetail\t!ignore % for the moment, maybe an attribute
1444      \hbox to \d_strc_itemgroups_list_width
1445        {#text\hskip{\itemgroupparameter\c!distance}}%
1446      \dostoptagged}}
1447
1448\protected\def\strc_itemgroups_start_margin#text%
1449  {\def\strc_itemgroups_margin_symbol % brrr
1450     {\dostarttaggednodetail\t!ignore % for the moment, maybe an attribute
1451      \llap
1452        {\begingroup
1453         \useitemgroupstyleandcolor\c!marstyle\c!marcolor
1454         #text% keep em/ex local
1455         \endgroup
1456         \hskip{\leftskip+\leftmargindistance}}%
1457      \dostoptagged}%
1458   \startitemgroupitem
1459   \dotagsetitem\s!margin}
1460
1461\protected\def\strc_itemgroups_start_text#text%
1462  {\def\strc_itemgroups_extra_symbol{#text}%
1463   \c_strc_itemgroups_symbol\conditionaltrue
1464   \c_strc_itemgroups_txt\conditionaltrue
1465   \startitemgroupitem}
1466
1467\protected\tolerant\def\strc_itemgroups_start_items[#1]%
1468  {\strc_itemgroups_start_edge
1469     {\localcontrolledloop
1470        \plusone
1471        \ifchknumber#1\or\lastchknumber\else0\itemgroupparameter\c!items\fi
1472        \plusone
1473        {\strc_itemgroups_used_symbol\hss}%
1474      \unskip}}
1475
1476\protected\permanent\def\startspecialitemgroupitem[#name]% todo: frozen
1477  {\ifcsname\??itemgroupstart#name\endcsname
1478      \expandafter\lastnamedcs
1479    \else
1480      \expandafter\strc_itemgroups_start_do_item
1481    \fi}
1482
1483\protected\permanent\def\stopspecialitemgroupitem % todo: frozen
1484  {\stopitemgroupitem}
1485
1486\letcsname\??itemgroupstart\v!item\endcsname\strc_itemgroups_start_do_item
1487\letcsname\??itemgroupstart\v!sub \endcsname\strc_itemgroups_start_subitem
1488\letcsname\??itemgroupstart\v!sym \endcsname\strc_itemgroups_start_symbol
1489\letcsname\??itemgroupstart\v!ran \endcsname\strc_itemgroups_start_edge
1490\letcsname\??itemgroupstart\v!its \endcsname\strc_itemgroups_start_items
1491\letcsname\??itemgroupstart\v!mar \endcsname\strc_itemgroups_start_margin
1492\letcsname\??itemgroupstart\v!txt \endcsname\strc_itemgroups_start_text
1493\letcsname\??itemgroupstart\v!no  \endcsname\strc_itemgroups_start_no_item
1494
1495\def\strc_itemgroups_optimize_breaks_both
1496  {\ifcase\c_strc_itemgroups_max_items
1497   \orelse\ifnum\c_strc_itemgroups_max_items=\plusthree
1498     \ifnum\c_strc_itemgroups_n_of_items>\plusone
1499       \strc_itemgroups_insert_nobreak
1500     \fi
1501   \orelse\ifnum\c_strc_itemgroups_max_items>\plusthree
1502     \ifnum\c_strc_itemgroups_n_of_items=\plustwo
1503       \ifconditional\c_strc_itemgroups_intro
1504         \strc_itemgroups_insert_breakno
1505       \else
1506         \strc_itemgroups_insert_nobreak
1507       \fi
1508     \orelse\ifnum\c_strc_itemgroups_max_items=\c_strc_itemgroups_n_of_items\relax
1509       \strc_itemgroups_insert_nobreak
1510     \orelse\ifnum\c_strc_itemgroups_n_of_items>\plustwo
1511       \strc_itemgroups_insert_break
1512     \orelse\ifconditional\c_strc_itemgroups_intro
1513     \else
1514       \strc_itemgroups_insert_break
1515     \fi
1516   \fi}
1517
1518\def\strc_itemgroups_optimize_breaks_first
1519  {\ifcase\c_strc_itemgroups_max_items
1520   \orelse\ifnum\c_strc_itemgroups_max_items=\plusthree
1521     \ifnum\c_strc_itemgroups_n_of_items<\plusthree   % !
1522       \strc_itemgroups_insert_nobreak                % !
1523     \else                                            % !
1524       \strc_itemgroups_insert_break                  % !
1525     \fi                                              % !
1526   \orelse\ifnum\c_strc_itemgroups_max_items>\plusthree
1527     \ifnum\c_strc_itemgroups_n_of_items=\plustwo
1528       \ifconditional\c_strc_itemgroups_intro
1529         \strc_itemgroups_insert_breakno
1530       \else
1531         \strc_itemgroups_insert_nobreak
1532       \fi
1533     \orelse\ifnum\c_strc_itemgroups_max_items=\c_strc_itemgroups_n_of_items\relax
1534       \strc_itemgroups_insert_break                  % !
1535     \orelse\ifnum\c_strc_itemgroups_n_of_items>\plustwo
1536       \strc_itemgroups_insert_break
1537     \orelse\ifconditional\c_strc_itemgroups_intro
1538     \else
1539       \strc_itemgroups_insert_break
1540     \fi
1541   \fi}
1542
1543\def\strc_itemgroups_optimize_breaks_last
1544  {\ifcase\c_strc_itemgroups_max_items
1545   \orelse\ifnum\c_strc_itemgroups_max_items=\plusthree
1546     \ifnum\c_strc_itemgroups_n_of_items>\plustwo % !
1547       \strc_itemgroups_insert_nobreak            % !
1548     \else                                        % !
1549       \strc_itemgroups_insert_break              % !
1550     \fi                                          % !
1551   \orelse\ifnum\c_strc_itemgroups_max_items>\plusthree
1552     \ifnum\c_strc_itemgroups_n_of_items=\plustwo
1553      \ifconditional\c_strc_itemgroups_intro
1554        \strc_itemgroups_insert_breakno
1555      \else
1556        \strc_itemgroups_insert_break             % !
1557      \fi
1558     \orelse\ifnum\c_strc_itemgroups_max_items=\c_strc_itemgroups_n_of_items\relax
1559       \strc_itemgroups_insert_nobreak
1560     \orelse\ifnum\c_strc_itemgroups_n_of_items>\plustwo
1561       \strc_itemgroups_insert_break
1562     \orelse\ifconditional\c_strc_itemgroups_intro
1563     \else
1564       \strc_itemgroups_insert_break
1565     \fi
1566   \fi}
1567
1568\def\strc_itemgroups_optimize_breaks
1569  {\ifcase\c_strc_itemgroups_column_depth
1570     \ifcase\c_strc_itemgroups_optimize  % loose
1571     \or \strc_itemgroups_optimize_breaks_both  % tight
1572     \or \strc_itemgroups_optimize_breaks_both  % verytight
1573     \or \strc_itemgroups_optimize_breaks_first % tight:first
1574     \or \strc_itemgroups_optimize_breaks_last  % tight:last
1575     \fi
1576   \fi}
1577
1578\def\strc_itemgroups_handle_text_item
1579  {\scratchdimen\wd\b_strc_itemgroups
1580   \advanceby\scratchdimen{\itemgroupparameter\c!distance}%
1581   \ifdim\scratchdimen>\d_strc_itemgroups_list_width
1582     \advanceby\scratchdimen -\d_strc_itemgroups_list_width
1583   \else
1584     \scratchdimen\zeropoint
1585   \fi
1586   \llap{\hbox to \d_strc_itemgroups_list_width{\ifconditional\c_strc_itemgroups_sub\llap{+\enspace}\fi\box\b_strc_itemgroups\hss}}% was: \hfill
1587   \hskip\scratchdimen}
1588
1589\def\strc_itemgroups_handle_lapped_item_positive
1590  {\llap
1591     {\dontcomplain
1592      \hbox to \d_strc_itemgroups_list_width
1593        {\ifconditional\c_strc_itemgroups_sub
1594           \dostarttaggednodetail\t!ignore
1595           \llap{+\enspace}%
1596           \dostoptagged
1597         \fi
1598         \strc_itemgroups_left_sym_filler
1599         \box\b_strc_itemgroups % can already have a forced widt, only factor handled here
1600         \hfil
1601         \hskip{\itemgroupparameter\c!distance}}}}
1602
1603\def\strc_itemgroups_handle_lapped_item_negative
1604  {\llap
1605     {\ifconditional\c_strc_itemgroups_sub
1606        \dostarttaggednodetail\t!ignore
1607        \llap{+\enspace}%
1608        \dostoptagged
1609      \fi
1610      \box\b_strc_itemgroups
1611      \hskip\leftmargindistance}}
1612
1613\def\strc_itemgroups_handle_groups_text_item
1614  {\hbox
1615     {\ifconditional\c_strc_itemgroups_sub
1616        \dostarttaggednodetail\t!ignore
1617        +\enspace
1618        \dostoptagged
1619      \fi
1620      \scratchwidth\wd\b_strc_itemgroups
1621      \box\b_strc_itemgroups
1622      \ifzerodim\scratchwidth\else
1623        \hskip\interwordspace % not configureable (yet), could be \c!textdistance
1624      \fi}%
1625   \nobreak}
1626
1627\def\strc_itemgroups_handle_groups_inline_item
1628  {\hbox to \d_strc_itemgroups_list_width
1629     {\ifconditional\c_strc_itemgroups_sub
1630        \dostarttaggednodetail\t!ignore
1631        \llap{+\enspace}%
1632        \dostoptagged
1633      \fi
1634      \box\b_strc_itemgroups
1635      \hss}} % was: \hfill
1636
1637\protected\def\strc_itemgroups_start_head_sym#text%
1638  {\def\strc_itemgroups_extra_symbol{#text}%
1639   \c_strc_itemgroups_symbol\conditionaltrue
1640   \c_strc_itemgroups_head\conditionaltrue
1641  %\strc_itemgroups_start_head}
1642   \startitemgrouphead}
1643
1644\def\strc_itemgroups_make_symbol_box
1645  {\setbox\b_strc_itemgroups\autodirhbox
1646     {\ifconditional\c_strc_itemgroups_head
1647        \ifconditional\c_strc_itemgroups_symbol
1648          \strc_itemgroups_insert_extra_reference
1649          \useitemgroupstyleandcolor\c!symstyle\c!symcolor
1650          \strc_itemgroups_extra_symbol
1651        \else
1652          \useitemgroupstyleandcolor\c!headstyle\c!headcolor
1653          \strc_itemgroups_used_symbol
1654        \fi
1655      \else
1656        \ifconditional\c_strc_itemgroups_symbol
1657          \strc_itemgroups_insert_extra_reference
1658          \useitemgroupstyleandcolor\c!symstyle\c!symcolor
1659          \strc_itemgroups_extra_symbol
1660        \else
1661          \useitemgroupstyleandcolor\c!style\c!color
1662          \strc_itemgroups_used_symbol
1663        \fi
1664      \fi}%
1665   \lettonothing\strc_itemgroups_extra_symbol
1666   \c_strc_itemgroups_symbol\conditionalfalse}
1667
1668\def\strc_itemgroups_make_fitting_box
1669  {\ifdim\wd\b_strc_itemgroups>{\itemgroupparameter\c!maxwidth}%
1670     \normalexpanded{\global\setitemgroupparameter{\c!maxwidth}{\the\wd\b_strc_itemgroups}}%
1671   \fi
1672   \ifdim\d_strc_itemgroups_max_width>\zeropoint
1673     \setbox\b_strc_itemgroups\simplealignedbox
1674       {{\d_strc_itemgroups_max_width+(\itemgroupparameter\c!distance)}}%
1675       {\itemgroupparameter\c!itemalign}%
1676       {\box\b_strc_itemgroups\hskip{\itemgroupparameter\c!distance}}%
1677   \fi}
1678
1679\def\strc_itemgroups_make_aligned_box
1680  {\ifempty{\itemgroupparameter\c!itemalign}\else
1681     \setbox\b_strc_itemgroups\simplealignedbox
1682       {{\d_strc_itemgroups_asked_width+(\itemgroupparameter\c!distance)}}%
1683       {\itemgroupparameter\c!itemalign}%
1684       {\box\b_strc_itemgroups\hskip{\itemgroupparameter\c!distance}}%
1685   \fi}
1686
1687\def\strc_itemgroups_make_destination_box
1688  {\iftrialtypesetting \orelse \ifempty\m_strc_itemgroups_destination \else
1689     \setbox\b_strc_itemgroups\hbox{\directgotobox{\box\b_strc_itemgroups}[\m_strc_itemgroups_destination]}%
1690   \fi}
1691
1692\def\strc_itemgroups_check_indenting
1693  {\c_strc_itemgroups_indented_first\conditionalfalse
1694   \ifempty\m_strc_itemgroups_indenting \else
1695     % we'd like to use \useindentingparameter\itemgroupparameter but ...
1696     \normalexpanded{\setupindenting[\v!reset,\v!yes,\m_strc_itemgroups_indenting]}%
1697     \ifconditional\c_spac_indentation_indent_first % better is to have a mode
1698       \ifcstok{\itemgroupparameter\c!alignsymbol}\v!yes\else
1699         \c_strc_itemgroups_indented_first\conditionaltrue
1700       \fi
1701     \fi
1702   \fi}
1703
1704\def\strc_itemgroups_check_for_repeated
1705  {\ifconditional\c_strc_itemgroups_repeat
1706     \ifempty\m_strc_itemgroups_repeat_start
1707       \edef\m_strc_itemgroups_repeat_start{\currentitemlevel}%
1708     \fi
1709   \else
1710     \lettonothing\m_strc_itemgroups_repeat_start
1711   \fi}
1712
1713\newconditional\c_strc_itemgroups_ignore
1714
1715\noaligned\permanent\protected\def\startignoreditem % kind of private
1716  {\global\c_strc_itemgroups_ignore\conditionaltrue
1717   \startitem}
1718
1719\noaligned\permanent\protected\def\stopignoreditem % kind of private
1720  {\stopitem
1721   \global\c_strc_itemgroups_ignore\conditionalfalse}
1722
1723\def\strc_itemgroups_insert_item
1724  {\ifconditional\c_strc_itemgroups_text % again?
1725    % begin of item
1726   \orelse\ifconditional\c_strc_itemgroups_no_par % again?
1727    % begin of item
1728   \else
1729     \par % done twice?
1730   \fi
1731   \iftrialtypesetting\else
1732     \global\advanceby\c_strc_itemgroups_n_of_items\plusone
1733   \fi
1734   \ifconditional\c_strc_itemgroups_ignore\else
1735     \strc_itemgroups_optimize_breaks
1736     \strc_itemgroups_check_indenting
1737     \dontleavehmode
1738     \ifconditional\c_strc_itemgroups_indented_first
1739       \hskip-\parindent
1740     \fi
1741     \strc_itemgroups_make_symbol_box
1742     \strc_itemgroups_make_destination_box
1743     \ifconditional\c_strc_itemgroups_fitting
1744       \strc_itemgroups_make_fitting_box
1745     \orelse\ifdim\d_strc_itemgroups_asked_width>\zeropoint
1746       \strc_itemgroups_make_aligned_box
1747     \fi
1748     \lettonothing\m_strc_itemgroups_destination
1749     \ht\b_strc_itemgroups\strutheight % just in case a symbols is not yet available in
1750     \dp\b_strc_itemgroups\strutdepth  % the current run (more a mkii mp side artifact)
1751     \strc_itemgroups_check_for_repeated
1752     \ifdim\d_strc_itemgroups_asked_width<\zeropoint\relax
1753       \strc_itemgroups_handle_lapped_item_negative
1754     \else
1755       \ifzeropt\d_strc_itemgroups_asked_width
1756         \strc_itemgroups_calculate_list_width\plusone
1757       \else
1758         \strc_itemgroups_calculate_list_width\c_strc_itemgroups_nesting
1759       \fi
1760       \ifconditional\c_strc_itemgroups_text
1761         \strc_itemgroups_handle_groups_text_item
1762       \orelse\ifconditional\c_strc_itemgroups_inline
1763         \strc_itemgroups_handle_groups_inline_item
1764       \orelse\ifconditional\c_strc_itemgroups_txt
1765         \strc_itemgroups_handle_text_item
1766       \else
1767         \strc_itemgroups_handle_lapped_item_positive
1768       \fi
1769     \fi
1770     \c_strc_itemgroups_head\conditionalfalse
1771     \c_strc_itemgroups_sub\conditionalfalse
1772     \ifconditional\c_strc_itemgroups_indented_first
1773       \hskip\parindent
1774     \fi
1775   \fi
1776   \ignorepars} % \ignorespaces
1777
1778\def\strc_itemgroups_start_item_nop
1779  {\lettonothing\currentitemreference
1780   \strc_itemgroups_increment_item_counter
1781   \global\advanceby\c_strc_itemgroups_n_of_items\plusone
1782   \setbox\b_strc_itemgroups\hbox
1783     {\useitemgroupstyleandcolor\c!style\c!color
1784      \strc_itemgroups_used_symbol}%
1785   \strc_itemgroups_check_for_repeated
1786   \ignorepars} % \ignorespaces
1787
1788\defcsname\??itemgroupdistance\v!none\endcsname
1789  {\let\m_strc_itemgroups_text_distance\zeropoint}
1790
1791\defcsname\??itemgroupdistance\v!space\endcsname
1792  {\def\m_strc_itemgroups_text_distance{\interwordspace\s!plus\interwordstretch\s!minus\interwordshrink}}
1793
1794\defcsname\??itemgroupdistance\endcsname % catches empty value
1795  {\let\m_strc_itemgroups_text_distance\zeropoint}
1796
1797\protected\def\strc_itemgroups_set_text_item_distance
1798  {\edef\m_strc_itemgroups_text_distance{\itemgroupparameter\c!textdistance}%
1799   \ifempty\m_strc_itemgroups_text_distance
1800   % \let\m_strc_itemgroups_text_distance\zeropoint % safeguard elsewhere
1801   \orelse\ifcsname\??itemgroupdistance\m_strc_itemgroups_text_distance\endcsname
1802     \lastnamedcs
1803   \else
1804     \strc_itemgroups_set_text_item_distance_indeed
1805   \fi}
1806
1807\def\strc_itemgroups_set_text_item_distance_indeed
1808  {\assignvalue
1809     \m_strc_itemgroups_text_distance
1810     \m_strc_itemgroups_text_distance
1811     {.5\interwordspace\s!plus.5\emwidth}%
1812     {\interwordspace  \s!plus  \emwidth}%
1813     {\emwidth         \s!plus  \interwordstretch\s!minus\interwordshrink}}
1814
1815% \protected\def\strc_itemgroups_default_command
1816%   {\EveryPar{\ignorespaces}% needed ?
1817%    \ignorespaces}
1818
1819\protected\def\strc_itemgroups_default_command
1820  {\ignorepars} % \ignorespaces
1821
1822%D Special case:
1823
1824\protected\def\strc_itemgroups_head#text\par
1825  {\startitemgrouphead{#text}}
1826
1827%D The local commands:
1828
1829\ifdefined\item             \else         \let\item            \relax \fi % defined later
1830\ifdefined\sub              \else \aliased\let\sub             \relax \fi
1831\ifdefined\sym              \else \aliased\let\sym             \relax \fi
1832\ifdefined\ran              \else \aliased\let\ran             \relax \fi
1833\ifdefined\its              \else \aliased\let\its             \relax \fi
1834\ifdefined\mar              \else \aliased\let\mar             \relax \fi
1835\ifdefined\noitem           \else \aliased\let\noitem          \relax \fi
1836\ifdefined\itm              \else \aliased\let\itm             \relax \fi
1837\ifdefined\but              \else \aliased\let\but             \relax \fi
1838%ifdefined\nop              \else         \let\nop             \relax \fi % used often by myself
1839\ifdefined\txt              \else \aliased\let\txt             \relax \fi
1840\ifdefined\head             \else         \let\head            \relax \fi % defined later
1841\ifdefined\headsym          \else \aliased\let\headsym         \relax \fi
1842\ifdefined\startitem        \else         \let\startitem       \relax \fi % defined later
1843\ifdefined\stopitem         \else \aliased\let\stopitem        \relax \fi
1844\ifdefined\starthead        \else \aliased\let\starthead       \relax \fi
1845\ifdefined\stophead         \else \aliased\let\stophead        \relax \fi
1846\ifdefined\startspecialitem \else \aliased\let\startspecialitem\relax \fi
1847\ifdefined\stopspecialitem  \else \aliased\let\stopspecialitem \relax \fi
1848
1849\appendtoks
1850    \enforced\let\item            \strc_itemgroups_start_do_item
1851    \enforced\let\sub             \strc_itemgroups_start_subitem
1852    \enforced\let\sym             \strc_itemgroups_start_symbol
1853    \enforced\let\ran             \strc_itemgroups_start_edge
1854    \enforced\let\its             \strc_itemgroups_start_items
1855    \enforced\let\mar             \strc_itemgroups_start_margin
1856    \enforced\let\noitem          \strc_itemgroups_start_no_item
1857    \enforced\let\itm             \strc_itemgroups_start_do_item
1858    \enforced\let\but             \strc_itemgroups_start_button
1859    \enforced\let\nop             \strc_itemgroups_start_dummy
1860    \enforced\let\txt             \strc_itemgroups_start_text
1861    \enforced\let\head            \strc_itemgroups_head
1862    \enforced\let\headsym         \strc_itemgroups_start_head_sym
1863    \enforced\let\startitem       \startitemgroupitem
1864    \enforced\let\stopitem        \stopitemgroupitem
1865    \enforced\let\starthead       \startitemgrouphead
1866    \enforced\let\stophead        \stopitemgrouphead
1867    \enforced\let\startspecialitem\startspecialitemgroupitem
1868    \enforced\let\stopspecialitem \stopspecialitemgroupitem
1869\to \itemgroupcommands
1870
1871\ifx\currentinterface \s!english \else
1872
1873    \def\next#1#2{\ifcsname#1\endcsname\else\enforced\aliased\letcsname#1\endcsname#2\fi}
1874
1875    \etoksapp\itemgroupcommands{%
1876        \next{\v!item        }\strc_itemgroups_start_do_item
1877        \next{\v!sub         }\strc_itemgroups_start_subitem
1878        \next{\v!sym         }\strc_itemgroups_start_symbol
1879        \next{\v!ran         }\strc_itemgroups_start_edge
1880        \next{\v!head        }\strc_itemgroups_head
1881        \next{\v!its         }\strc_itemgroups_start_items
1882        \next{\v!mar         }\strc_itemgroups_start_margin
1883        \next{\v!txt         }\strc_itemgroups_start_text
1884        \next{\e!start\v!item}\startitemgroupitem
1885        \next{\e!stop \v!item}\stopitemgroupitem
1886        \next{\e!start\v!head}\startitemgrouphead
1887        \next{\e!stop \v!head}\stopitemgrouphead
1888    }
1889
1890  % \let\next\relax
1891
1892\fi
1893
1894\relaxvalueifundefined \v!item
1895\relaxvalueifundefined \v!sub
1896\relaxvalueifundefined \v!sym
1897\relaxvalueifundefined \v!ran
1898\relaxvalueifundefined \v!head
1899\relaxvalueifundefined \v!its
1900\relaxvalueifundefined \v!mar
1901\relaxvalueifundefined \v!txt
1902\relaxvalueifundefined {\e!start\v!item}
1903\relaxvalueifundefined {\e!stop \v!item}
1904\relaxvalueifundefined {\e!start\v!head}
1905\relaxvalueifundefined {\e!stop \v!head}
1906
1907%D A nice example of a plugin:
1908%D
1909%D \startbuffer
1910%D \startitemize[a,random,packed]
1911%D \startitem first  \stopitem \startitem second \stopitem
1912%D \startitem third  \stopitem \startitem fourth \stopitem
1913%D \stopitemize
1914%D
1915%D \startitemize[a,random,packed]
1916%D \startitem first  \stopitem \startitem second \stopitem
1917%D \startitem third  \stopitem \startitem fourth \stopitem
1918%D \stopitemize
1919%D
1920%D \startitemize[a,packed]
1921%D \startitem first  \stopitem \startitem second \stopitem
1922%D \startitem third  \stopitem \startitem fourth \stopitem
1923%D \stopitemize
1924%D \stopbuffer
1925%D
1926%D \typebuffer \getbuffer
1927
1928% better collectitems als conditional and a real plugin mechanism (some day)
1929
1930\newinteger\c_strc_itemgroups_collected_stored
1931\newinteger\c_strc_itemgroups_collected_done
1932\newinteger\c_strc_itemgroups_collected_current
1933
1934\let\strc_itemgroups_collected_store\relax
1935
1936\lettonothing\m_strc_itemgroups_collected
1937
1938\normalexpanded{\def\strc_itemgroups_collected_store#1\csname\e!stop\v!item\endcsname}%
1939  {\advanceby\c_strc_itemgroups_collected_stored\plusone
1940   \defcsname\??itemgroupstack\the\c_strc_itemgroups_collected_stored\endcsname
1941     {\startitemgroupitem#1\stopitemgroupitem}}
1942
1943\def\strc_itemgroups_collected_flush_randomize
1944  {\m_strc_itemgroups_collected}
1945
1946\def\strc_itemgroups_collected_flush_horizontal
1947  {\begingroup
1948   \scratchcounter\itemgroupparameter\c!n\relax
1949   \ifnum\c_strc_itemgroups_collected_done>\plusone
1950     \ifcase\modulonumber\scratchcounter\c_strc_itemgroups_collected_done\relax
1951       % compensate for rounding errors
1952       \hfill % \hskip\zeropoint plus \scaledpoint minus \scaledpoint
1953       \allowbreak
1954     \fi
1955   \fi
1956   \noindent % no \dontleavehmode
1957   \hbox to {\availablehsize/\scratchcounter}{\m_strc_itemgroups_collected\hss}%
1958   \endgroup}
1959
1960\def\strc_itemgroups_collected_flush_indeed
1961  {\m_strc_itemgroups_collected
1962   \letcsname\??itemgroupstack\the\c_strc_itemgroups_collected_current\endcsname\undefined}
1963
1964\def\strc_itemgroups_collected_flush
1965  {\ifconditional\c_strc_itemgroups_randomize
1966     \getrandomcount\c_strc_itemgroups_collected_current\plusone\c_strc_itemgroups_collected_stored
1967   \else
1968     \advanceby\c_strc_itemgroups_collected_current\plusone
1969   \fi
1970   \ifcsname\??itemgroupstack\the\c_strc_itemgroups_collected_current\endcsname
1971     \edef\m_strc_itemgroups_collected{\lastnamedcs}%
1972     \ifconditional\c_strc_itemgroups_horizontal
1973       \strc_itemgroups_collected_flush_horizontal
1974     \else
1975       \strc_itemgroups_collected_flush_indeed
1976     \fi
1977     \advanceby\c_strc_itemgroups_collected_done\plusone
1978   \fi
1979   \ifnum\c_strc_itemgroups_collected_done<\c_strc_itemgroups_collected_stored
1980     \expandafter\strc_itemgroups_collected_flush
1981   \fi}
1982
1983\protected\permanent\def\stopcollectitems % todo: frozen
1984  {\ifconditional\c_strc_itemgroups_collecting
1985     \c_strc_itemgroups_collected_done   \zerocount
1986     \c_strc_itemgroups_collected_current\zerocount
1987     \ifnum\c_strc_itemgroups_collected_stored>\zerocount
1988       \ifconditional\c_strc_itemgroups_horizontal
1989         \strc_itemgroups_before_command
1990         \c_strc_itemgroups_first\conditionalfalse
1991         \strc_itemgroups_collected_flush
1992        %\strc_itemgroups_after_command % triggered elsewhere
1993       \else
1994         \strc_itemgroups_collected_flush
1995       \fi
1996     \fi
1997   \fi}
1998
1999\protected\permanent\def\startcollectitems % todo: frozen
2000  {\ifconditional\c_strc_itemgroups_collecting
2001     \c_strc_itemgroups_collected_stored\zerocount
2002     \enforced\letcsname\e!start\v!item\endcsname\strc_itemgroups_collected_store
2003   \fi}
2004
2005%D Left-overs:
2006
2007\permanent\protected\def\item % todo: frozen
2008  {\strc_itemgroups_item_alone}
2009
2010\tolerant\def\strc_itemgroups_item_alone[#category]#:#text\par
2011  {\ifempty{#category}%
2012     \startitemgroup[\v!itemize]%
2013   \else
2014     \startitemgroup[#category]%
2015   \fi
2016   \startitem#text\stopitem
2017   \stopitemgroup}
2018
2019\permanent\protected\def\head % todo: frozen
2020  {\strc_itemgroups_head_alone}
2021
2022\def\strc_itemgroups_head_alone[#category]#head\par#body\par
2023  {\ifempty{#category}%
2024     \startitemgroup[\v!itemize]%
2025   \else
2026     \startitemgroup[#category]%
2027   \fi
2028   \starthead{#head}#body\stophead
2029   \stopitemgroup}
2030
2031\pushoverloadmode
2032
2033\permanent\protected\defcsname\e!start\v!item\endcsname
2034  {\startitemgroup[\v!itemize]%
2035   \startitemgroupitem
2036   \enforced\letcsname\e!stop\v!item\endcsname\strc_itemgroups_stop_item}
2037
2038\aliased\letcsname\e!stop\v!item\endcsname\relax
2039
2040\permanent\protected\def\strc_itemgroups_stop_item
2041  {\stopitemgroupitem
2042   \stopitemgroup}
2043
2044\popoverloadmode
2045
2046% \def\sym#text%
2047%   {\noindent
2048%    \begingroup
2049%    \setbox\scratchbox\hbox{\settrialtypesetting#text}%
2050%    \setbox\scratchbox\hbox\ifdim\wd\scratchbox<1em to 1.5\else spread 1\fi em{#text\hfil}%
2051%    \normalexpanded{\box\scratchbox\endgroup\hangindent\the\wd\scratchbox}%
2052%    \ignorepars} % \ignorespaces
2053
2054%D End of plugin.
2055
2056%D Something for tables:
2057
2058\permanent\tolerant\protected\def\itemtag[#reference]% we can reuse more
2059  {% what if empty
2060   \def\currentitemreference{#reference}%
2061   \iftrialtypesetting
2062     \strc_counters_save\v_strc_itemgroups_counter
2063     \strc_itemgroups_increment_item_counter
2064     \strc_itemgroups_insert_item_tag_indeed
2065     \strc_counters_restore\v_strc_itemgroups_counter
2066   \else
2067     \strc_itemgroups_increment_item_counter
2068     \strc_itemgroups_insert_item_tag_indeed
2069   \fi}
2070
2071\def\strc_itemgroups_insert_item_tag_indeed
2072  {\letitemgroupparameter\c!distance\zeropoint
2073   %letitemgroupparameter\c!width\zeropoint
2074   \strc_itemgroups_make_symbol_box
2075   \strc_itemgroups_make_destination_box
2076   \lettonothing\m_strc_itemgroups_destination
2077   \ht\b_strc_itemgroups\strutheight
2078   \dp\b_strc_itemgroups\strutdepth
2079   \box\b_strc_itemgroups
2080   \ignorepars} % \ignorespaces
2081
2082%D New per 2023-08-01
2083
2084\newdimension\d_strc_itemgroups_inbetween_table
2085\newdimension\d_strc_itemgroups_column_distance
2086\newdimension\d_strc_itemgroups_column_width
2087
2088\def\strc_itemgroups_table_begin
2089  {\NC}
2090
2091\def\strc_itemgroups_table_end_row
2092  {\NR
2093   \ifzerodim\d_strc_itemgroups_inbetween_table\orelse\ifnum % todo
2094     \numexpr\c_strc_itemgroups_n_of_items/\c_strc_itemgroups_columns\relax
2095    <\numexpr\c_strc_itemgroups_max_items /\c_strc_itemgroups_columns\relax
2096        \noalign{\m_strc_itemgroups_inbetween}%
2097      % \TB[\the\d_strc_itemgroups_inbetween_table]%
2098   \fi}
2099
2100\noaligned\def\strc_itemgroups_table_end
2101  {\ifcase{\c_strc_itemgroups_n_of_items mod \c_strc_itemgroups_columns}%
2102     \expandafter\strc_itemgroups_table_end_row
2103   \fi}
2104
2105\protected\def\strc_itemgroups_table_wrapup
2106  {\iftrialtypesetting\orelse\ifcase\c_tabl_tabulate_column\else
2107     \beginlocalcontrol % horrible hack to prevens crcr issues
2108     \expandafter\endlocalcontrol\expandedloop
2109       {\c_tabl_tabulate_column+\plusone}%
2110       \c_tabl_tabulate_nofcolumns
2111       \plusone
2112       {\startignoreditem\strut\stopignoreditem}%
2113   \fi}
2114
2115\let\strc_itemgroups_table_pickup\relax
2116
2117\setupitemgroup[\c!columndistance=\emwidth]
2118
2119\lettonothing\m_strc_itemgroups_after
2120\lettonothing\m_strc_itemgroups_inbetween
2121
2122\tolerant\permanent\protected\def\strc_itemgroups_start_table[#1]#*[#S#2]#*[#S#3]%
2123  {\ifcase\currentitemlevel\relax
2124     \startitemgroup[#1][#2][#3]%
2125     \itemgroupparameter\c!before
2126   \orelse\ifhmode
2127     \strut
2128     \startitemgroup[#1][#2][#3]%
2129     \ifconditional\c_strc_itemgroups_overlay
2130       \blank[\v!overlay]%
2131     \else
2132       \itemgroupparameter\c!before
2133     \fi
2134   \else
2135     \startitemgroup[#1][#2][#3]%
2136     \itemgroupparameter\c!before
2137   \fi
2138   \edef\m_strc_itemgroups_after    {\itemgroupparameter\c!after}%
2139   \edef\m_strc_itemgroups_inbetween{\itemgroupparameter\c!inbetween}%
2140   \setbox\scratchbox\vbox{\m_strc_itemgroups_inbetween}%
2141   \d_strc_itemgroups_inbetween_table\htdp\scratchbox
2142   \letitemgroupparameter\c!before\relax
2143   \letitemgroupparameter\c!after\relax
2144   \letitemgroupparameter\c!inbetween\relax
2145   \c_strc_itemgroups_columns\itemgroupparameter\c!n
2146   \let\strc_itemgroups_begin\strc_itemgroups_table_begin
2147   \let\strc_itemgroups_end  \strc_itemgroups_table_end
2148   %
2149   % horrible ... we have \dividebydsize\textwidth{1em}{3}
2150   %
2151   \scratchdistance{\itemgroupparameter\c!columndistance}%
2152   \d_strc_itemgroups_column_distance{\leftskip+\rightskip}%
2153   \d_strc_itemgroups_column_width\hsize
2154   \c_strc_itemgroups_no_par\conditionaltrue % blocks a par that interferes with tagging
2155   \advanceby\d_strc_itemgroups_column_width   -\c_strc_itemgroups_columns\d_strc_itemgroups_column_distance
2156   \divideby \d_strc_itemgroups_column_width    \c_strc_itemgroups_columns
2157   \advanceby\d_strc_itemgroups_column_distance \scratchdistance
2158   \advanceby\d_strc_itemgroups_column_width   -\scratchdistance
2159   \advanceby\d_strc_itemgroups_column_width    {\scratchdistance/\c_strc_itemgroups_columns}%
2160   %
2161   \c_strc_itemgroups_optimize\zerocount % otherwise we inject vertical breaks between struts
2162   % inlining confusses the verbose name parser
2163   \normalexpanded{\strc_itemgroups_table_bootstrap
2164     \csname\e!start#1\v!table\endcsname
2165     \csname\e!stop #1\v!table\endcsname % watch the 'l' specification below, maybe a format key
2166     {\expandedrepeat \c_strc_itemgroups_columns {|p(\the\d_strc_itemgroups_column_width)l}|}}}
2167
2168\protected\def\strc_itemgroups_table_bootstrap#1#2#3%
2169  {\protected\def\strc_itemgroups_table_pickup##L#1##R#2##1%
2170     {\tabl_tabulate_disable_tagging
2171      \starttabulate[#3][\c!before=,\c!after=,\c!split=\v!no,\c!unit=\the\d_strc_itemgroups_column_distance]%
2172        ##1\relax\strc_itemgroups_table_wrapup
2173      \stoptabulate
2174      \normalexpanded{\stopitemgroup\m_strc_itemgroups_after}}%
2175   \strc_itemgroups_table_pickup}
2176
2177\appendtoks
2178    \frozen\instance\protected\edefcsname\e!stop \currentitemgroup\v!table\endcsname
2179      {}% {\strc_itemgroups_stop_table}
2180    \frozen\instance\protected\edefcsname\e!start\currentitemgroup\v!table\endcsname
2181      {\strc_itemgroups_start_table[\currentitemgroup]}%
2182\to \everydefineitemgroup
2183
2184%D Done again.
2185
2186\setupitemgroup
2187  [\c!margin=\zeropoint,
2188   \c!leftmargin=\zeropoint,
2189   \c!rightmargin=\zeropoint,
2190   \c!leftmargindistance=\zeropoint,
2191   \c!rightmargindistance=\zeropoint,
2192   \c!indentnext=\v!yes,
2193   \c!width=1.5\emwidth,
2194   \c!factor=0,
2195  %\c!distance=.5em, % is now:
2196   \c!step=.5\emwidth, % deals with broad
2197   \c!distance=\zeropoint,
2198  %\c!align=\v!normal, % definitely not \v!normal !
2199  %\c!symalign=,
2200  %\c!color=,
2201  %\c!indenting=, % untouched if empty
2202  %\c!style=,
2203   \c!marstyle=\v!type,
2204  %\c!symstyle=,
2205  %\c!headstyle=,
2206  %\c!marcolor=,
2207  %\c!symcolor=,
2208  %\c!headcolor=,
2209  %\c!beforehead=,
2210   \c!symcolor=\itemgroupparameter\c!color, % new per 2012.01.17
2211   \c!symstyle=\itemgroupparameter\c!style, % new per 2012.01.17
2212   \c!afterhead=\blank,
2213   \c!before=\blank,
2214   \c!inbetween=\blank,
2215   \c!after=\blank,
2216  %\c!stopper=.,
2217   \c!placestopper=\v!yes,
2218   \c!stopper=.,
2219  %\c!inner=,
2220   \c!n=2,
2221   \c!items=4,
2222   \c!levels=10,
2223   \c!lefttext=(,
2224   \c!righttext=),
2225   \c!start=1,
2226   \c!packcriterium=\zerocount,
2227   \c!criterium=\v!all, % permits 0 and negative numbers
2228  %\c!option=,
2229   \c!textdistance=\v!space, % none big medium small <dimension>
2230   \c!lasttextseparator=\itemgroupparameter\c!textseparator,
2231  %\c!lasttextseparator=,
2232   \c!command=\strc_itemgroups_default_command,
2233   \c!indenting=\v!next,
2234  %\c!alignsymbol=v!no,
2235   \c!symbol=\currentitemlevel,
2236   \c!prefix=\v!no,
2237  %\c!prefixstopper=.,
2238  %\c!prefixseparatorset=,
2239  %\c!prefixconversion=,
2240  %\c!prefixconversionset=,
2241  %\c!prefixset=,
2242  %\c!prefixsegments=1:100,
2243   \c!prefixconnector=.,
2244   \c!numberseparatorset=,
2245   \c!numberconversionset=,
2246   \c!numberstopper=.,
2247   \c!numbersegments=1]
2248
2249\defineitemgroup
2250  [\v!itemize]
2251
2252%D This is really ugly I should get rid of the global mess, whuch is a side
2253%D effect of the simple \type {\item} interface that we're stuck with for
2254%D compatibility reasons. See footnotes for usage. It's probablynot robust
2255%D for mixed itemgroups so in the end I need to get rid of the globals. One
2256%D problem is that counters are set.
2257
2258\defineitemgroup
2259  [\v!itemize:\v!note]
2260
2261\def\strc_itemgroups_push
2262  {\edef\strc_itemgroups_pop
2263     {\xdef\noexpand\currentitemlevel{\currentitemlevel}%
2264      \global\c_strc_itemgroups_nesting     \the\c_strc_itemgroups_nesting     \relax
2265      \global\c_strc_itemgroups_column_depth\the\c_strc_itemgroups_column_depth\relax}%
2266   \global\c_strc_itemgroups_column_depth\zerocount
2267   \global\c_strc_itemgroups_nesting     \zerocount
2268   \glet\currentitemlevel\!!zerocount
2269   \enforced\permanent\protected\def\startitemize{\startitemgroup[\v!itemize:\v!note]}%
2270   \enforced\permanent\protected\def\stopitemize {\stopitemgroup}}
2271
2272\let\strc_itemgroups_pop\relax
2273
2274\protect \endinput
2275