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