strc-lst.mklx /size: 55 Kb    last modification: 2021-10-28 13:51
1%D \module
2%D   [       file=strc-lst,
3%D        version=2008.10.20,
4%D          title=\CONTEXT\ Structure Macros,
5%D       subtitle=Lists,
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 / Lists}
15
16\registerctxluafile{strc-lst}{}
17
18% clean up in progress ...
19%
20% also (long term) todo:
21%
22% autocrossdocument
23% auto refs to lists (chain)
24%
25% TODO: strut=yes|no
26%
27% \lists -> strc_lists
28
29\unprotect
30
31%D Lists are mostly used for tables of contents but are in fact a rather generic
32%D feature of \CONTEXT. We seperate between storage and rendering and the current
33%D implementation is a reworked version of all that was added in steps. As lists
34%D are used frequently compatibility is an important aspect. A couple of rendering
35%D alternatives are provided here but more are possible.
36
37\installcorenamespace{list}
38
39\installframedcommandhandler \??list {list} \??list
40
41\aliased\let\setuplists\setuplist % yes or no
42
43\setuplist
44  [\c!height=\v!broad,
45   \c!depth=\v!broad,
46   \c!offset=.25\emwidth,
47   \c!state=\v!start,
48   \c!coupling=\v!off,
49   \c!criterium=\v!local,
50   \c!reference=,% was number which was sort of obsolete
51   \c!width=3\emwidth,
52  %\c!maxwidth=,
53   \c!distance=\zeropoint,
54   \c!margin=\zeropoint,
55   \c!alternative=\c!b,
56   \c!style=\v!normal,
57  %\c!color=,
58   \c!textstyle=\listparameter\c!style,   % \currentliststyleparameter (but then we need to set it in every ...)
59   \c!numberstyle=\listparameter\c!style, % \currentliststyleparameter
60   \c!pagestyle=\listparameter\c!style,   % \currentliststyleparameter
61   \c!textcolor=\listparameter\c!color,   % \currentlistcolorparameter (but then we need to set it in every ...)
62   \c!numbercolor=\listparameter\c!color, % \currentlistcolorparameter
63   \c!pagecolor=\listparameter\c!color,   % \currentlistcolorparameter
64   \c!numbercommand=\firstofoneargument,
65   \c!textcommand=\firstofoneargument,
66   \c!pagecommand=\firstofoneargument,
67   \c!pagenumber=\v!yes, % better: 'first'
68   \c!headnumber=\v!yes, % better: 'second'
69%  \c!sectionnumber=\listparameter\c!headnumber, % use this instead
70   \c!interaction=\v!all, % was \v!sectionnumber, % or make this headnumber (or accept both)
71   \c!label=\v!no,
72  %\c!extras=,
73  %\c!aligntitle=,
74  %\c!before=,
75  %\c!after=,
76  %\c!inbetween=,
77  %\c!symbol=,
78  %\c!expansion=,
79   \c!limittext=\languageparameter\c!limittext] % not used currently
80
81%D Helpers:
82
83\permanent\protected\def\usenestedliststyleandcolor#style#color% will change
84  {\useliststyleandcolor#style#color%
85   % how about style
86   \ifempty\currentcolorparameter \else
87     \resetinteractionparameter\c!color
88     \resetinteractionparameter\c!contrastcolor
89   \fi}
90
91\permanent\protected\def\doifelselist#tag% can also move to \installcommandhandler
92  {\ifcsname\namedlisthash{#tag}\s!parent\endcsname
93     \expandafter\firstoftwoarguments
94   \else
95     \expandafter\secondoftwoarguments
96   \fi}
97
98\aliased\let\doiflistelse\doifelselist
99
100%D Regular list entries are bound to a specific location in order to get the right
101%D pagenumber etc.\ associated. When pushing something inbetween (in mkiv) it ends
102%D up directtly in the list. This is the default because otherwise users will wonder
103%D why spacing might get messed up (due to an unseen but present node). It is
104%D possible to force a location by explicitly setting \type {location} to \type
105%D {here}.
106%D
107%D Another way to force a certain order is to set the \type {order} variable when
108%D placing a list. The \type {command} option only pushes commands into the right
109%D order, and \type {all} orders all entries (which might be too much). In this case
110%D no specific location is needed with the inbetween method. Maybe additional
111%D mechanisms show up some day. See \type {inbetween-001.tex} for an example.
112
113% command  : location=none
114% userdata : location=none
115% simple   : location=here
116
117\installcorenamespace {listlocations}
118
119\permanent\protected\def\doifelseinlistentry#1%
120  {\unless\ifcsname\??listlocations#1\endcsname
121     \expandafter\secondoftwoarguments
122   \orelse\ifnum\lastnamedcs=\structurelistlocation\relax
123     \expandafter\firstoftwoarguments
124   \else
125     \expandafter\secondoftwoarguments
126   \fi}
127
128\permanent\protected\def\doifelseincurrentlistentry
129  {\doifelseinlistentry\currentlist}
130
131\permanent\protected\def\structurelistinject[#tag]%
132  {\begingroup
133   \edef\currentlist{#tag}%
134   \doifelse{\listparameter\c!state}\v!start\strc_lists_inject_yes\strc_lists_inject_nop}
135
136\tolerant\protected\def\strc_lists_inject_nop[#settings]#spacer[#userdata]%
137  {\endgroup}
138
139\def\strc_lists_inject_enhance#listindex%
140  {\expandafter\clf_deferredenhancelist\number#listindex\relax}
141
142\tolerant\protected\def\strc_lists_inject_yes[#settings]#spacer[#userdata]% can be used directly
143  {\setupcurrentlist[\c!type=userdata,\c!location=\v!none,#settings]% grouped (use \let...
144   \edef\p_location{\listparameter\c!location}%
145   \setnextinternalreference
146   \scratchcounter\clf_addtolist
147        references {
148            internal \locationcount
149          % block    {\currentsectionblock}
150          % section  structures.sections.currentid()
151          % location {\p_location}
152        }
153        metadata {
154            kind     {\listparameter\c!type}
155            name     {\currentlist}
156          % level    structures.sections.currentlevel()
157            catcodes \catcodetable
158        }
159        userdata {\detokenize\expandafter{\normalexpanded{#userdata}}}
160   \relax
161   \edef\currentlistnumber{\the\scratchcounter}%
162   \setxvalue{\??listlocations\currentlist}{\the\locationcount}%
163   \ifx\p_location\v!here
164     % this branch injects nodes !
165     \strc_lists_inject_enhance{\currentlistnumber}%
166     \clf_setinternalreference
167        internal \locationcount
168        view     {\interactionparameter\c!focus}%
169     \relax % this will change
170     \xdef\currentstructurelistattribute{\the\lastdestinationattribute}%
171     \dontleavehmode\hpack attr \destinationattribute \lastdestinationattribute{}% todo
172   \else
173     % and this one doesn't
174     \clf_enhancelist\currentlistnumber\relax
175   \fi
176   \endgroup}
177
178% todo: make like \strc_references_direct_full_user ... with {}{}{}
179
180\protected\def\strc_lists_inject_direct[#tag]% [#settings][#userdata]
181  {\begingroup
182   \edef\currentlist{#tag}%
183   \strc_lists_inject_yes} % [#settings][#userdata]
184
185\permanent\protected\def\writebetweenlist[#tag]%
186  {\begingroup
187   \edef\currentlist{#tag}%
188   \doifelse{\namedlistparameter{#tag}\c!state}\v!start
189     \strc_lists_write_between_yes
190     \strc_lists_write_between_nop}
191
192\tolerant\def\strc_lists_write_between_yes[#settings]#:#command%
193  {\strc_lists_inject_yes[#settings,\c!type=\s!command][command={#command}]}
194
195\tolerant\def\strc_lists_write_between_nop[#settings]#:#command%
196  {\endgroup}
197
198\permanent\protected\def\writedatatolist[#tag]%
199  {\begingroup
200   \edef\currentlist{#tag}%
201   \doifelse{\namedlistparameter{#tag}\c!state}\v!start
202     \strc_lists_write_data_to_yes
203     \strc_lists_write_data_to_nop}
204
205\tolerant\def\strc_lists_write_data_to_yes[#settings]#spacer[#userdata]%
206  {\ifparameter#userdata\or % no need to have an extra step ... used seldom
207     \strc_lists_inject_yes[#settings,\c!type=\s!userdata][#userdata]%
208   \else
209     \strc_lists_inject_yes[\c!type=\s!userdata][#settings]%
210   \fi}
211
212\tolerant\def\strc_lists_write_data_to_nop[#settings]#spacer[#userdata]%
213  {\endgroup}
214
215\permanent\protected\def\writetolist[#tag]%
216  {\begingroup
217   \edef\currentlist{#tag}%
218   \doifelse{\namedlistparameter{#tag}\c!state}\v!start
219     \strc_lists_write_to_yes
220     \strc_lists_write_to_nop}
221
222\tolerant\def\strc_lists_write_to_yes[#settings]#:#first#second% no \s!first because we don't expand user settings
223  {\strc_lists_inject_yes[\c!location=\v!here,#settings,\c!type=\s!simple][first={#first},second={#second}]}
224
225\tolerant\def\strc_lists_write_to_nop[#settings]#:#first#second%
226  {\endgroup} % \strc_lists_inject_nop[][]
227
228% \starttyping
229% \installstructurelistprocessor{chapter:userdata}
230%   {\startlinecorrection[blank]
231%    \hfill \inframed{you really need to look at \structurelistuservariable{pagenumber}}%
232%    \stoplinecorrection}
233%
234% \starttext
235%   \placelist[chapter]
236%   \chapter{one}
237%   \writebetweenlist[chapter][location=here]{\blank page 4\blank}
238%   \writedatatolist[chapter][location=here][pagenumber=4]
239%   \writetolist[chapter]{}{It's a test}
240%   \chapter{two}
241% \stoptext
242% \stoptyping
243
244%D When placing a list either one or a set can be giving. This makes it possible to
245%D flush for instance an nested (or merged) table of contents. Keep in mind that
246%D placing a list is what we do most (think of tables of contents, figures, etc.\
247%D but other usage is also possible in which case low level commands have to be
248%D used.
249
250\newtoks\everystructurelist
251
252\permanent\tolerant\protected\def\placelist[#taglist]#spacer[#settings]%
253  {\begingroup
254   \startpacked[\v!blank]%
255   \edef\m_list {#taglist}%
256   \edef\m_first{\firststructureelementinlist{#taglist}}%
257   \ifx\m_list\m_first
258      % use settings of first
259   \else
260      % use settings of root
261      \let\m_first\empty
262   \fi
263   \strc_lists_place_indeed\m_first\m_list{#settings}%
264   \stoppacked
265   \endgroup}
266
267\permanent\tolerant\protected\def\placerawlist[#tag]#spacer[#settings]% just one list
268  {\strc_lists_place_indeed\empty{#tag}{#settings}}
269
270\aliased\let\strc_lists_place\placelist % used in strc-flt
271
272\def\strc_lists_place_indeed#tag#list#settings%
273  {\begingroup
274   \the\t_lists_every_renderingcleanup % \let\currentlistentrylocation\empty
275   \edef\currentlist{#tag}%
276   \setupcurrentlist[#settings]%
277   \the\everystructurelist
278 % \doif{\listparameter\c!coupling}\v!on{\startlistreferences{#tag}}%
279   \strc_lists_place_current % maybe inline
280     {#list}%
281     {\listparameter\c!criterium}%
282     {\listparameter\c!reference}%
283     {\listparameter\c!extras}%
284     {\listparameter\c!order}%
285 % \stoplistreferences
286   \par % todo: only when vertical list mode
287   \endgroup
288   \strc_lists_set_mode}
289
290\def\strc_lists_set_mode
291  {\ifcase\structurelistsize\relax
292     \resetsystemmode\v!list
293   \else
294     \setsystemmode  \v!list
295   \fi}
296
297%D Complete lists are just lists but with a title. They were originally introduced
298%D to minimize the number for commands in a document source but nowadays that is
299%D less an issue in the sense that the extra few lines are neglectable to the rest.
300
301\ifdefined\startnamedsection \else \let\startnamedsection\relax \fi
302\ifdefined\stopnamedsection  \else \let\stopnamedsection \relax \fi
303\ifdefined\headtext          \else \let\headtext         \relax \fi
304
305\permanent\tolerant\protected\def\completelist[#tag]#spacer[#settings]%
306  {\normalexpanded{\startnamedsection[\v!title][\c!title=\headtext{#tag},\c!reference=#tag]}% {} around ref ?
307   \strc_lists_place[#tag][#settings]%
308   \stopnamedsection}
309
310\permanent\tolerant\protected\def\strc_lists_complete[#singular]#spacer[#plural]#spacer[#settings]% used in strc-flt
311  {\normalexpanded{\startnamedsection[\v!title][\c!title=\headtext{#plural},\c!reference=#singular]}% {} around ref ?
312   \strc_lists_place[#singular][#settings]%
313   \stopnamedsection}
314
315\permanent\tolerant\def\strc_lists_combined_complete[#tag]#spacer[#settings]%
316  {\normalexpanded{\startnamedsection[\v!title][\c!title={\headtext{#tag}},\c!reference=#tag]}%
317   \placecombinedlist[#tag][#settings]%
318   \stopnamedsection}
319
320%D Combined list provide a nice level of abstraction.
321%D
322%D \starttyping
323%D \definecombinedlist[whatever][a,b,c][settings]
324%D \stoptyping
325
326\permanent\tolerant\protected\def\definecombinedlist[#tag]#spacer[#list]#spacer[#settings]%
327  {\definelist[#tag][\c!criterium=\v!local,\c!reference=,\c!alternative=,\c!list={#list},#settings]% inherits from root
328   \frozen\instance\defcsname\e!setup#tag\e!endsetup\endcsname{\setupcombinedlist[#tag]}%
329   \frozen\instance\defcsname\e!place#tag\endcsname{\placecombinedlist[#tag]}%
330   \frozen\instance\defcsname\e!complete#tag\endcsname{\strc_lists_combined_complete[#tag]}}
331
332\permanent\tolerant\protected\def\setupcombinedlist[#tag]#spacer[#settings]%
333  {\ifarguments\or\or
334     \setuplist[#tag][#settings]% we don't want to mess up the parent
335   \fi}
336
337\permanent\tolerant\protected\def\placecombinedlist[#tag]#spacer[#settings]% i.e. no list set in settings
338  {\begingroup
339   \edef\currentlist{#tag}%
340   \setupcurrentlist[#settings]%
341   \edef\m_strc_list_alternative{\listparameter\c!alternative}% we only inherit alternative
342   \strc_lists_place_indeed{#tag}{\listparameter\c!list}{#settings}%
343   \endgroup}
344
345%D Given that some variables are set, we can ask for some properties of
346%D an entry.
347
348\mutable\def\currentstructurelistnumber{0}     % injection
349\mutable\def\currentlistmethod         {entry} % typesetting
350\mutable\def\currentlistindex          {0}     % typesetting (maybe also a real counter)
351
352\permanent\protected\def\savedlistnumber        #1#2{\clf_savedlistnumber        {#1}\numexpr#2\relax}
353\permanent\protected\def\savedlisttitle         #1#2{\clf_savedlisttitle         {#1}\numexpr#2\relax}
354\permanent\protected\def\savedlistprefixednumber#1#2{\clf_savedlistprefixednumber{#1}\numexpr#2\relax}
355
356\newconditional\c_lists_show_realpage
357
358\installcorenamespace {listpagenumber}
359
360\defcsname\??listpagenumber\v!always  \endcsname{\settrue\c_lists_show_page\settrue\c_lists_has_page}
361\defcsname\??listpagenumber\v!yes     \endcsname{\settrue\c_lists_show_page}
362\defcsname\??listpagenumber\s!realpage\endcsname{\settrue\c_lists_show_page\settrue\c_lists_show_realpage}
363
364\def\strc_lists_process_pagenumber#1%
365  {\begincsname\??listpagenumber#1\endcsname}
366
367\permanent\def\structurelistlocation
368  {\clf_listlocation\numexpr\currentlistindex\relax}
369
370\permanent\def\structurelistrealpagenumber
371  {\clf_listrealpage{\currentlist}\numexpr\currentlistindex\relax}
372
373\permanent\protected\def\structurelistpagenumber
374  {\dostarttagged\t!listpage\empty
375   \ifconditional\c_lists_show_realpage
376     \clf_listrealpage{\currentlist}\numexpr\currentlistindex\relax
377   \else
378     \clf_listprefixedpage
379       {\currentlist}%
380       \currentlistindex
381       {%
382         separatorset  {\listparameter\c!pageprefixseparatorset}%
383         conversionset {\listparameter\c!pageprefixconversionset}%
384         set           {\listparameter\c!pageprefixset}%
385         segments      {\listparameter\c!pageprefixsegments}%
386         connector     {\listparameter\c!pageprefixconnector}%
387       }%
388       {%
389         prefix        {\listparameter\c!pageprefix}%
390         conversionset {\listparameter\c!pageconversionset}%
391         starter       {\listparameter\c!pagestarter}%
392         stopper       {\listparameter\c!pagestopper}%
393       }%
394     \relax
395   \fi
396   \dostoptagged}
397
398\permanent\protected\def\structurelistuservariable#name%
399  {\dostarttagged\t!listdata{#name}%
400   \clf_listuserdata{\currentlist}\currentlistindex{#name}%
401   \dostoptagged}
402
403\permanent\def\rawstructurelistuservariable#name%
404  {\clf_listuserdata{\currentlist}\currentlistindex{#name}}
405
406\permanent\protected\def\structurelistfirst {\structurelistuservariable\s!first } % s!
407\permanent\protected\def\structurelistsecond{\structurelistuservariable\s!second} % s!
408
409\permanent\def\rawstructurelistfirst {\rawstructurelistuservariable\s!first } % s! % was \protected
410\permanent\def\rawstructurelistsecond{\rawstructurelistuservariable\s!second} % s! % was \protected
411
412\permanent\protected\def\doifelsestructurelisthaspage
413  {\clf_doifelselisthaspage{\currentlist}\numexpr\currentlistindex\relax}
414
415\permanent\protected\def\doifelsestructurelisthasnumber
416  {\clf_doifelselisthasnumber{\currentlist}\numexpr\currentlistindex\relax}
417
418\aliased\let\doifstructurelisthaspageelse  \doifelsestructurelisthaspage
419\aliased\let\doifstructurelisthasnumberelse\doifelsestructurelisthasnumber
420
421\permanent\protected\def\structurelistgenerictitle
422  {\dostarttagged\t!listcontent\empty
423   \clf_listtitle{\currentlist}\currentlistindex\relax
424   \dostoptagged}
425
426\permanent\protected\def\structurelistgenericnumber % tricky, we need to delay tagging as we have nested lua calls
427  {\dostarttagged\t!listtag\empty
428   \clf_listprefixednumber
429     {\currentlist}%
430     \currentlistindex
431     {%
432         prefix        {\listparameter\c!prefix}%
433         separatorset  {\listparameter\c!prefixseparatorset}%
434         conversionset {\listparameter\c!prefixconversionset}%
435         starter       {\listparameter\c!prefixstarter}%
436         stopper       {\listparameter\c!prefixstopper}%
437         set           {\listparameter\c!prefixset}%
438         segments      {\listparameter\c!prefixsegments}%
439         connector     {\listparameter\c!prefixconnector}%
440     }%
441     {%
442         separatorset  {\listparameter\c!numberseparatorset}%
443         conversionset {\listparameter\c!numberconversionset}%
444         starter       {\listparameter\c!numberstarter}%
445         stopper       {\listparameter\c!numberstopper}%
446         segments      {\listparameter\c!numbersegments}%
447     }%
448   \relax
449   \dostoptagged}
450
451% TODO: pass extra tag name (contents, figures, bibliography ...)
452
453\protected\def\strc_lists_place_current#list#criterium#reference#extras#order% beware, not a user command
454  {\dostarttaggedchained\t!list\empty\??list
455   \clf_processlist
456        names     {#list}
457        criterium {#criterium}
458        reference {#reference}
459        extras    {#extras}
460        order     {#order}
461   \relax
462   \dostoptagged}
463
464\protected\def\strc_lists_analyze#list#criterium#reference%
465  {\clf_analyzelist
466        names     {#list}
467        criterium {#criterium}
468        reference {#reference}
469   \relax}
470
471\permanent\def\firststructureelementinlist#list% expandable
472  {\firstinset{#list}}
473
474\permanent\def\structurelistsize
475  {\clf_listsize}
476
477%D Depending on what kind of list we have (e.g.\ a section related one) processors
478%D can be defined.
479
480% push pop test:
481%
482% \starttext
483%   \placelist[chapter] [after={\placelist[section][criterium=local]}]
484%   \chapter{One} \section{Alpha} \section{Beta}
485%   \chapter{Two} \section{First} \section{Second}
486% \stoptext
487
488\installcorenamespace{structurelistprocessor} % the topmost list handler
489\installcorenamespace{listextra}              % control of that handler
490
491\installcommandhandler \??listextra {listextra} \??listextra
492
493\definelistextra % example
494  [\v!page]
495  [\c!before={\showmessage\m!system{14}{\currentlist/\currentlistindex}\page}]
496
497\permanent\protected\def\installstructurelistprocessor#tag#meaning%
498  {\expandafter\normaldef\csname\??structurelistprocessor#tag\endcsname{#meaning}}
499
500\permanent\def\usestructurelistprocessor#tag%
501  {\begincsname\??structurelistprocessor#tag\endcsname}
502
503\aliased\let\dotaglistlocation\relax
504
505\def\strc_lists_entry_process_default
506  {no list method}
507
508\def\strc_lists_entry_process % assume things to be set up
509  {\listextraparameter\c!before
510   \dostarttagged\t!listitem\currentlist
511   \dotaglistlocation
512   \ifcsname\??structurelistprocessor\currentlist:\currentlistmethod\endcsname\lastnamedcs\orelse
513   \ifcsname\??structurelistprocessor\currentlistmethod             \endcsname\lastnamedcs\orelse
514   \ifcsname\??structurelistprocessor\currentlist                   \endcsname\lastnamedcs\else
515                                                         \strc_lists_entry_process_default\fi
516   \dostoptagged
517   \listextraparameter\c!after}
518
519\permanent\protected\def\strclistsentryprocess#tag#method#index#extra% This one is called at the lua end!
520  {\clf_pushlist#index\relax
521  %\let\currentlistentrylocation\empty
522   \edef\currentlist      {#tag}%
523   \edef\currentlistmethod{#method}%
524   \edef\currentlistindex {#index}%
525   \edef\currentlistextra {#extra}%
526   \strc_lists_entry_process
527   \clf_poplist}
528
529% lists that have a number/title are kind of generic and can share code
530
531\installstructurelistprocessor\s!default
532  {\strc_lists_entry_process_default}
533
534\installstructurelistprocessor\s!simple
535  {\let\currentlistentrynumber    \structurelistfirst
536   \let\currentlistentrytitle     \structurelistsecond
537   \let\currentlistentrypagenumber\structurelistpagenumber
538   \strc_lists_apply_renderingsetup}
539
540\installstructurelistprocessor\s!command
541  {\clf_listuserdata{\currentlist}\currentlistindex{\s!command}}
542
543\installstructurelistprocessor{section}
544  {\let\currentlistentrynumber    \structurelistgenericnumber
545   \let\currentlistentrytitle     \structurelistgenerictitle
546   \let\currentlistentrypagenumber\structurelistpagenumber
547   \strc_lists_apply_renderingsetup}
548
549\installstructurelistprocessor{number+title}
550  {\let\currentlistentrynumber    \structurelistgenericnumber
551   \let\currentlistentrytitle     \structurelistgenerictitle
552   \let\currentlistentrypagenumber\structurelistpagenumber
553   \strc_lists_apply_renderingsetup}
554
555% example of usage elsewhere:
556%
557% \installstructurelistprocessor{pubs:userdata}
558%   {\clf_listuserdata{\currentlist}\currentlistindex{bibref}}
559
560%D List symbols are used in interactive documents where no numbers are used but
561%D nevertheless structure is present. Beware, the list symbol macro gets an argument
562%D passed, i.e. when this argument is not picked up, the symbol becomes a kind of
563%D prefix. It's not really a user command (and might even get protected).
564
565\permanent\protected\def\listsymbol[#tag]#number%
566  {\begingroup
567   \edef\currentlist{#tag}%
568   \def\currentlistentrynumber{#number}% no edef else tag problems
569   \currentlistsymbol
570   \endgroup}
571
572%D For historical reasons we're stuck to symbols, so in order to generalize, we have
573%D to hook it into the symbol handle. One way to deal with this is to use a
574%D different key and as it makes sense to use setups instead of def's we use a new
575%D key \quote {renderingsetup} which is the name of a setup.
576
577\def\strc_lists_assign_dimen#dimension#key#default%
578  {\edef\m_strc_list_dimen{\listparameter#key}%
579   \doifelseinset\m_strc_list_dimen{\v!fit,\v!broad}{#dimension#default}{#dimension\m_strc_list_dimen}\relax}
580
581\definesymbol[\v!list][\v!none   ][\strc_lists_symbol_none]
582\definesymbol[\v!list][\v!one    ][\strc_lists_symbol_one]
583\definesymbol[\v!list][\v!two    ][\strc_lists_symbol_two]
584\definesymbol[\v!list][\v!three  ][\strc_lists_symbol_three]
585\definesymbol[\v!list][\s!default][\strc_lists_symbol_default]
586\definesymbol[\v!list][\s!unknown][\strc_lists_symbol_unknown]
587
588\permanent\protected\def\currentlistsymbol
589  {\edef\p_symbol{\listparameter\c!symbol}%
590   \doifelseinsymbolset\v!list\p_symbol
591     {\directsymbol\v!list\p_symbol}
592     {\directsymbol\v!list\s!default}}
593
594\protected\def\strc_lists_symbol_none
595  {\strc_lists_assign_dimen\scratchwidth\c!width{1.5\emwidth}%
596   \hpack to \scratchwidth{}}
597
598\protected\def\strc_lists_symbol_one
599  {\strut\symbol[bullet]}
600
601\protected\def\strc_lists_symbol_two
602  {\vrule\s!width\emwidth\s!height\exheight\s!depth\zeropoint\relax}
603
604\protected\def\strc_lists_symbol_three
605  {\begingroup
606   \strc_lists_assign_dimen\scratchwidth \c!width {1.5\emwidth}%
607   \strc_lists_assign_dimen\scratchheight\c!height\exheight
608   \strc_lists_assign_dimen\scratchdepth \c!depth \zeropoint
609   \vrule\s!width\scratchwidth\s!height\scratchheight\s!depth\scratchdepth
610   \endgroup}
611
612\protected\def\strc_lists_symbol_unknown
613  {\listparameter\c!symbol}
614
615\installcorenamespace{listsymbollabels}
616
617\def\strc_lists_symbol_label_unknown
618  {\leftlabeltext\currentlistlabel
619   \listparameter\c!starter
620   \currentlistentrynumber
621   \listparameter\c!stopper
622   \rightlabeltext\currentlistlabel}
623
624\mutable\let\currentlistnumber\!!zerocount
625\mutable\let\currentlistlabel \empty
626
627\protected\def\strc_lists_symbol_default
628  {\dontleavehmode
629   \strut
630   \begingroup
631   \edef\currentlistlabel{\listparameter\c!label}% can be used in label
632   \ifcsname\??listsymbollabels\currentlistlabel\endcsname
633      \lastnamedcs
634   \else
635     \strc_lists_symbol_label_unknown
636   \fi
637   \endgroup}
638
639\letcsname\??listsymbollabels\s!unknown\endcsname\strc_lists_symbol_default
640
641\defcsname\??listsymbollabels\endcsname % default (empty)
642  {\listparameter\c!starter
643   \currentlistentrynumber
644   \listparameter\c!stopper}
645
646\defcsname\??listsymbollabels\v!no\endcsname % also default
647  {\listparameter\c!starter
648   \currentlistentrynumber
649   \listparameter\c!stopper}
650
651\defcsname\??listsymbollabels\v!none\endcsname % real minimal (as suggested by WS)
652  {\currentlistentrynumber}
653
654\defcsname\??listsymbollabels\v!yes\endcsname % auto (use value stored in tuc file)
655  {\edef\currentlistlabel{\clf_listlabel\currentlistindex{\currentlistlabel}}%
656   \leftlabeltext\currentlistlabel
657   \listparameter\c!starter
658   \currentlistentrynumber
659   \listparameter\c!stopper
660   \rightlabeltext\currentlistlabel}
661
662% a : nr - tit - pag
663% b : nr - tit - fill - pag
664% c : nr - tit - dots - pag
665% d : inline
666% e : interaction
667% f : interaction
668% g : interaction
669
670\installcorenamespace{listalternative} % specific ways of rendering a list
671\installcorenamespace{listrenderings}  % a namespace for setups (rather local)
672
673\installcommandhandler \??listalternative {listalternative} \??listalternative
674
675% Commands are bound to specific list instances as often these are quite special
676% and don't apply to multiple. So, being strict saves us resets.
677
678% \installcorenamespace{listfiller}
679%
680% \protected\def\installlistfiller#1#2%
681%   {\setuvalue{\??listfiller#1}{#2}}
682%
683% \protected\def\listfiller#1%
684%   {\begincsname\??listfiller#1\endcsname}
685%
686% \protected\def\currentlistfiller
687%   {\begingroup
688%    \edef\p_filler{\listalternativeparameter\c!filler}%
689%    \ifcsname\??listfiller\p_filler\endcsname
690%      \lastnamedcs
691%    \else
692%      \p_filler
693%    \fi
694%    \endgroup}
695%
696% \installlistfiller\v!sym % original one
697%   {\begingroup
698%    \scratchdimen.5\emwidth
699%    \hskip\scratchdimen
700%    \gleaders
701%      \hbox to \scratchdimen
702%        {\hss
703%         \uselistalternativestyleandcolor\c!symstyle\c!symcolor
704%         \listalternativeparameter\c!symbol
705%         \hss}%
706%      \hfill
707%    \hskip\scratchdimen
708%    \endgroup}
709%
710% \installlistfiller\v!symbol % new one (make that default?)
711%   {\begingroup
712%    \scratchdimen.5\emwidth
713%    \hskip\scratchdimen
714%    \gleaders
715%      \hbox spread .5\scratchdimen
716%        {\hss
717%         \uselistalternativestyleandcolor\c!symstyle\c!symcolor
718%         \listalternativeparameter\c!symbol
719%         \hss}%
720%      \hfill
721%    \hskip\scratchdimen
722%    \endgroup}
723%
724% \installlistfiller\v!width
725%   {\hfill}
726%
727% \installlistfiller\v!space
728%   {\hskip.25\emwidth\relax}
729
730\setuplistalternative
731  [\c!command=\directlistparameter\c!command,
732   \c!symbol=.]
733
734\permanent\protected\def\currentlistfiller
735  {\checkedfiller{\listalternativeparameter\c!filler}}
736
737\definelistalternative
738  [a]
739  [\c!distance=0pt,
740   \c!width=2em,
741   \c!stretch=10em,
742   \c!filler=\hskip.25em\relax,
743   \c!renderingsetup=\??listrenderings:abc]
744
745\definelistalternative
746  [b]
747  [\c!distance=5em,
748   \c!width=2em,
749   \c!stretch=10em,
750   \c!filler=\hfill,
751   \c!renderingsetup=\??listrenderings:abc]
752
753\definelistalternative
754  [c]
755  [\c!distance=5em,
756   \c!width=0pt,
757   \c!stretch=10em,
758   \c!filler=\hskip.5em\gleaders\hbox to .5\emwidth{\hss.\hss}\hfill\hskip.5em\relax,
759   \c!renderingsetup=\??listrenderings:abc]
760
761\definelistalternative
762  [d]
763  [\c!renderingsetup=\??listrenderings:d]
764
765\definelistalternative
766  [e]
767  [\c!renderingsetup=\??listrenderings:e]
768
769\definelistalternative
770  [f]
771  [\c!renderingsetup=\??listrenderings:f]
772
773\definelistalternative
774  [g]
775  [\c!renderingsetup=\??listrenderings:g]
776
777\definelistalternative
778  [\v!command]
779  [\c!renderingsetup=\??listrenderings:command]
780
781\definelistalternative
782  [\v!none]
783  [\c!renderingsetup=\??listrenderings:none]
784
785\definelistalternative
786  [\v!vertical]
787  [\c!before=\ifvmode\nointerlineskip\fi,
788   \c!after=\ifvmode\nointerlineskip\fi\endgraf\allowbreak,
789   \c!renderingsetup=\??listrenderings:generic]
790
791\definelistalternative
792  [\v!horizontal]
793  [\c!before=\noindent,
794   \c!after=,
795   \c!renderingsetup=\??listrenderings:generic]
796
797% \setuplist
798%   [section]
799%   [alternative=MyListItem,
800%    after=\blank,
801%    before=\blank]
802%
803% \definelistplacement[MyListItem][command]#1#2#3{(#1) (#2) (#3)}
804% \definelistplacement[MyListItem][command]{\whatever}
805%
806% this is a compatibility command, best use the regular defined with command=
807% either set in the alternative or in the list
808
809\installcorenamespace{listelementcommand} % the old plugin model
810
811\permanent\tolerant\protected\def\definelistplacement[#tag]#spacer[#method]%
812  {\edef\p_method{#method}%
813   \ifempty\p_method
814     \let\p_method\v!command
815   \fi
816   \normalexpanded{\definelistalternative[#tag][\p_method]}[\c!command=\strc_lists_placement_command]%
817   \doifelsenextbgroup
818     {\strc_lists_define_placement_yes{#tag}}
819     {\strc_lists_define_placement_nop{#tag}}}
820
821% indirect definition: <three ignore arguments>: {\bla}
822
823\def\strc_lists_define_placement_yes#tag%
824  {\protected\defcsname\??listelementcommand#tag\endcsname##1##2##3}
825
826% direct definition: <three arguments>{\bla}
827
828\def\strc_lists_define_placement_nop#tag%
829  {\protected\defcsname\??listelementcommand#tag\endcsname}
830
831\def\strc_lists_placement_command
832  {\csname\??listelementcommand\currentlistalternative\endcsname}
833
834%D The rendering macros.
835
836\newbox  \b_strc_lists_number
837\newbox  \b_strc_lists_text
838\newbox  \b_strc_lists_page
839
840\newtoks \t_lists_every_renderingsetup
841\newtoks \t_lists_every_renderingtext
842\newtoks \t_lists_every_renderingsynchronize
843\newtoks \t_lists_every_renderingcleanup
844
845\newconditional\c_lists_has_number
846\newconditional\c_lists_has_page
847\newconditional\c_lists_show_number
848\newconditional\c_lists_show_page
849
850\mutable\let\currentlistentrylocation  \empty % watch the 'entry' in the name
851\mutable\let\currentlistentrynumber    \empty % watch the 'entry' in the name
852\mutable\let\currentlistentrytitle     \empty % watch the 'entry' in the name
853\mutable\let\currentlistentrypagenumber\empty % watch the 'entry' in the name
854
855\appendtoks
856    \dontcomplain
857  % \letinteractionparameter\c!width\zeropoint % a weird one
858\to \t_lists_every_renderingsetup
859
860\appendtoks
861    % better is to use a special list entry but we keep this for compatibility
862    \enforced\let\\\space
863    % so expanding this token register has to come *after* the font switch
864    \dontconvertfont % (**) this has to become an option (see publ)
865\to \t_lists_every_renderingtext
866
867\appendtoks
868    % because we want to avoid redundant lua calls we expand the
869    % location beforehand
870    \ifempty\currentlistentrylocation
871        \enforced\edef\currentlistentrylocation{\structurelistlocation}% needs attention
872    \fi
873    % because these tests happen often and because we're dealing with
874    % rather complex composed data we have special conditionals; keep
875    % in mind that testing for empty fails do to tagging being applied
876%   \edef\p_pagenumber{\listparameter\c!pagenumber}%
877%   \ifx\p_pagenumber\v!always
878%     \settrue\c_lists_has_page
879%     \settrue\c_lists_show_page
880%   \else
881%     \doifelsestructurelisthaspage\settrue\setfalse\c_lists_has_page
882%     \ifx\p_pagenumber\v!yes
883%       \settrue\c_lists_show_page
884%     \else
885%       \setfalse\c_lists_show_page
886%     \fi
887%   \fi
888    \setfalse\c_lists_show_page % necessary?
889    \processcommacommand[\listparameter\c!pagenumber]\strc_lists_process_pagenumber
890    \ifconditional\c_lists_has_page \else
891      \doifelsestructurelisthaspage\settrue\setfalse\c_lists_has_page
892    \fi
893    % always forces number placement (in bib we use a forced number)
894    \edef\p_headnumber{\listparameter\c!headnumber}%
895    \ifx\p_headnumber\v!always
896      \settrue\c_lists_has_number
897      \settrue\c_lists_show_number
898    \else
899      \doifelsestructurelisthasnumber\settrue\setfalse\c_lists_has_number
900      \ifx\p_headnumber\v!yes
901        \settrue\c_lists_show_number
902      \else
903        \setfalse\c_lists_show_number
904      \fi
905    \fi
906    \strc_lists_interaction_check
907\to \t_lists_every_renderingsetup
908
909\appendtoks
910    \strc_references_flush_destination_nodes
911\to \t_lists_every_renderingsynchronize
912
913\appendtoks
914   % as we don't want any interference we clear some variables
915   % afterwards
916   \let\currentlistentrylocation  \empty
917   \let\currentlistentrynumber    \empty
918   \let\currentlistentrytitle     \empty
919   \let\currentlistentrypagenumber\empty
920   \setfalse\c_lists_has_page
921   \setfalse\c_lists_has_number
922   \setfalse\c_lists_show_page
923   \setfalse\c_lists_show_realpage
924   \setfalse\c_lists_show_number
925\to \t_lists_every_renderingcleanup
926
927\let\m_strc_list_alternative\empty % combined
928
929\protected\def\strc_lists_apply_renderingsetup
930  {\the\t_lists_every_renderingsetup
931   % now we group
932   \begingroup
933   \ifempty\m_strc_list_alternative
934     \edef\currentlistalternative{\listparameter\c!alternative}%
935   \else
936     \let\currentlistalternative\m_strc_list_alternative
937   \fi
938   \directsetup{\listalternativeparameter\c!renderingsetup}\relax
939   \endgroup
940   % till here, where we reset locals
941   \the\t_lists_every_renderingcleanup}
942
943% todo: provide packager via attributes
944
945\doinstallinjector\s!list
946
947\installcorenamespace{listalternativemethods} % the general wrapper of a rendering
948
949\startsetups[\??listrenderings:none]
950    % nothing, nb we use the [] syntax here because we end with a \cs
951\stopsetups
952
953\permanent\protected\def\currentlistentrytitlesynchronize
954  {\the\t_lists_every_renderingsynchronize}
955
956\permanent\protected\def\currentlistentrytitlerendered
957  {\currentlistentrytitlesynchronize\currentlistentrytitle}
958
959\startsetups[\??listrenderings:command]
960    \edef\p_command{\listalternativeparameter\c!command}%
961    \ifempty\p_command
962        [\currentlist: \currentlistentrynumber\space -- \currentlistentrytitle\space -- \currentlistentrypagenumber]%
963    \else
964        \p_command
965          \currentlistentrynumber
966          \currentlistentrytitlerendered % {\currentlistentrytitlesynchronize\currentlistentrytitle}
967          \currentlistentrypagenumber
968    \fi
969\stopsetups
970
971% \startsetups[\??listrenderings:\v!vertical]
972%     \directsetup{\??listrenderings:generic}
973% \stopsetups
974
975% \startsetups[\??listrenderings:\v!horizontal]
976%     \directsetup{\??listrenderings:generic}
977% \stopsetups
978
979\startsetups[\??listrenderings:generic]
980    \typo_injectors_check_list
981    \listparameter\c!before % can be \hskip
982    \edef\p_command{\listalternativeparameter\c!command}
983    \ifempty\p_command
984        \listalternativeparameter\c!before
985        \vbox {
986            \forgetall
987            \noindent % otherwise annotations are mirrored up
988            \typo_injectors_mark_list
989            \hbox \strc_lists_get_reference_attribute\v!all {
990                \ifconditional\c_lists_show_number
991                  % \ifconditional\c_lists_has_page
992                        \hbox \strc_lists_get_reference_attribute\v!number {
993                            \strc_lists_set_style_color\c!numberstyle\c!numbercolor\v!number
994                            \listparameter\c!numbercommand\currentlistsymbol
995                        }
996                  % \fi
997                \fi
998                \hbox \strc_lists_get_reference_attribute\v!text {
999                    \strc_lists_set_style_color\c!textstyle\c!textcolor\v!text
1000                    \the\t_lists_every_renderingtext
1001                    \the\t_lists_every_renderingsynchronize
1002                    \listparameter\c!textcommand\currentlistentrytitle
1003                }
1004                \ifconditional\c_lists_show_page
1005                    \ifconditional\c_lists_has_page
1006                        \hbox \strc_lists_get_reference_attribute\v!pagenumber {
1007                            \strc_lists_set_style_color\c!pagestyle\c!pagecolor\v!pagenumber
1008                            \listparameter\c!pagecommand\currentlistentrypagenumber
1009                        }
1010                    \fi
1011                \fi
1012            }
1013        }
1014        \listalternativeparameter\c!after
1015   \else
1016        \noindent % otherwise annotations are mirrored up
1017        \typo_injectors_mark_list
1018        \hbox \strc_lists_get_reference_attribute\v!all \strc_lists_get_destination_attribute {
1019            \p_command\currentlistentrynumber\currentlistentrytitle\currentlistentrypagenumber
1020        }
1021   \fi
1022   \listparameter\c!after
1023\stopsetups
1024
1025% to be documented: align, hang
1026
1027\startsetups[\??listrenderings:abc]
1028    \endgraf % are we grouped?
1029    \typo_injectors_check_list
1030  % \advance % yes or no ... \rightskip is also honored
1031    \leftskip\listparameter\c!margin % after \endgraf !
1032    \listparameter\c!before
1033    \endgraf
1034    \edef\p_width{\listparameter\c!width}
1035    \scratchdistance\listparameter\c!distance\relax
1036    \ifx\p_width\v!fit
1037        \scratchwidth\zeropoint
1038    \orelse\ifconditional\c_lists_has_number
1039        \scratchwidth\p_width
1040    \else
1041        \edef\p_aligntitle{\listparameter\c!aligntitle}
1042        \ifx\p_aligntitle\v!yes
1043            \scratchwidth\zeropoint
1044            \scratchdistance\zeropoint
1045        \else
1046            \scratchwidth\p_width
1047        \fi
1048    \fi
1049    \noindent % otherwise annotations are mirrored up
1050    \typo_injectors_mark_list
1051    \hbox \strc_lists_get_reference_attribute\v!all \strc_lists_get_destination_attribute {
1052        \setlocalhsize
1053        \hsize\localhsize
1054        \hbox to \hsize {
1055            \forgetall
1056            \strc_lists_set_style_color\c!style\c!color\v!all
1057            \scratchhsize\hsize
1058            \ifconditional\c_lists_has_number
1059                \ifconditional\c_lists_show_number
1060                  \setbox\b_strc_lists_number
1061%                    \hbox
1062%                      \strc_lists_get_reference_attribute\v!number
1063%                      \ifdim\scratchwidth>\zeropoint to \scratchwidth \fi
1064                    \simplealignedboxplus
1065                        \scratchwidth
1066                        {\listparameter\c!numberalign}
1067                        {\strc_lists_get_reference_attribute\v!number}
1068                        {
1069                            \strc_lists_set_style_color\c!numberstyle\c!numbercolor\v!number
1070                            \listparameter\c!numbercommand\currentlistsymbol
1071%                             \hfill
1072                        }
1073                \else
1074                    \setbox\b_strc_lists_number\emptyhbox
1075                \fi
1076            \else
1077                \scratchwidth\zeropoint
1078                \scratchdistance\zeropoint
1079                \setbox\b_strc_lists_number\emptyhbox
1080            \fi
1081            \ifconditional\c_lists_has_page
1082                \ifconditional\c_lists_show_page
1083                    \setbox\b_strc_lists_page\hpack {
1084                        \scratchdimen\listalternativeparameter\c!width
1085                        \hbox \strc_lists_get_reference_attribute\v!pagenumber \ifdim\scratchdimen>\zeropoint to \scratchdimen\fi {
1086                            \hfill
1087                            \strc_lists_set_style_color\c!pagestyle\c!pagecolor\v!pagenumber
1088                            \strut
1089                            \listparameter\c!pagecommand\currentlistentrypagenumber
1090                        }
1091                    }
1092                \else
1093                    \setbox\b_strc_lists_page\emptyhbox
1094                \fi
1095            \else
1096                \setbox\b_strc_lists_page\emptyhbox
1097            \fi
1098            \vbox {
1099                \hsize\scratchhsize
1100                \usealignparameter\listparameter
1101                \ifdim\scratchwidth<\hsize
1102                    % we have leftskip so we'd better just skip back instead of messing
1103                    % with hang*
1104                    \edef\p_hang{\listparameter\c!hang}
1105                    \hangindent\dimexpr\wd\b_strc_lists_number+\scratchdistance\relax
1106                    \hangafter\ifx\p_hang\v!no\zerocount\else\plusone\fi
1107                    \scratchdimen\listalternativeparameter\c!distance\relax
1108                    \ifzeropt\wd\b_strc_lists_page\orelse\ifdim\scratchdimen>\zeropoint\relax
1109                        \rightskip\scratchdimen\s!plus\listalternativeparameter\c!stretch\relax
1110                        \parfillskip-\rightskip
1111                    \fi
1112                \else
1113                    \scratchdistance\zeropoint
1114                \fi
1115                \parindent\zeropoint
1116                \dontleavehmode % this nils hang: i need to figure out why
1117                % % topaligned
1118                %
1119                % \scratchdimen\wd\b_strc_lists_number
1120                % \setbox\b_strc_lists_number\hbox to \hsize{\box\b_strc_lists_number\hss\box\b_strc_lists_page}%
1121                % \wd\b_strc_lists_number\scratchdimen
1122                %
1123                \box\b_strc_lists_number
1124                \hskip\scratchdistance\relax
1125                \begingroup
1126                \strc_lists_set_reference_attribute\v!text
1127                \strc_lists_set_style_color\c!textstyle\c!textcolor\v!text
1128                \the\t_lists_every_renderingtext
1129                \the\t_lists_every_renderingsynchronize
1130                \setstrut % needs checking, new here
1131                \begstrut
1132                \strc_lists_limitated_text\currentlistentrytitle
1133                \endstrut
1134                \endgroup
1135                \ifzeropt\wd\b_strc_lists_page\else
1136                    \nobreak
1137                    \currentlistfiller
1138                    \box\b_strc_lists_page
1139                \fi
1140            }
1141            \hss
1142        }
1143    }% new
1144    \endgraf % new, else problems with nointerlinespace and prevdepth
1145    \nointerlineskip % anders verkeerde spatiering bij multi-line
1146    \endgraf
1147    \allowbreak
1148    \listparameter\c!after
1149\stopsetups
1150
1151% % example from the context list
1152%
1153% \setuphead [part]    [page=right,placehead=yes]
1154% \setuplist [chapter] [alternative=d,before=\blank,after=\blank]
1155% \setuplist [part]    [before=\blank,after=\blank]
1156%
1157% \starttext
1158%   \startnarrower[2*right] \placecontent \stopnarrower
1159%   \blank[4*big]
1160%   \startsetups chapter
1161%     \blank \startnarrower[3*middle] \placecontent[criterium=local] \stopnarrower
1162%   \stopsetups
1163%   \placelist[part][criterium=text,after=\setups{chapter}]
1164%
1165%   \part{First part}       \chapter{Chapter one}  \chapter{Chapter two}
1166%   \chapter{Chapter three} \chapter{Chapter four} \chapter{Chapter five}
1167%   \part{Second part}      \chapter{Chapter one}  \chapter{Chapter two}
1168%   \chapter{Chapter three} \chapter{Chapter four} \chapter{Chapter five}
1169%   \part{Third part}       \chapter{Chapter one}  \chapter{Chapter two}
1170%   \chapter{Chapter three} \chapter{Chapter four} \chapter{Chapter five}
1171% \stoptext
1172
1173\startsetups[\??listrenderings:d]
1174    \ifvmode
1175        \advance\leftskip\listparameter\c!margin
1176    \fi
1177    \begingroup
1178    \ifvmode
1179        \noindent
1180    \fi
1181    \begingroup
1182    \strc_lists_set_reference_attribute\v!all
1183    \strc_lists_set_style_color\c!style\c!color\v!all
1184    \strc_lists_get_destination_attribute
1185    \begingroup
1186    \ifconditional\c_lists_show_number
1187        \donetrue
1188        \ifconditional\c_lists_has_number \else
1189            \edef\p_symbol{\listparameter\c!symbol}
1190            \ifempty\p_symbol
1191                \donefalse
1192            \fi
1193        \fi
1194        \ifdone
1195            \begingroup
1196            \strc_lists_set_reference_attribute\v!number
1197            \strc_lists_set_style_color\c!numberstyle\c!numbercolor\v!number
1198            \listparameter\c!left
1199            \listparameter\c!numbercommand\currentlistsymbol
1200            \listparameter\c!right
1201            \endgroup
1202            \kern.5\emwidth\relax
1203            \nobreak
1204        \fi
1205    \fi
1206    \endgroup
1207    \begingroup
1208    \strc_lists_set_reference_attribute\v!text
1209    \strc_lists_set_style_color\c!textstyle\c!textcolor\v!text
1210    \the\t_lists_every_renderingtext
1211    \the\t_lists_every_renderingsynchronize
1212    \setstrut % needs checking, new here
1213    \begstrut
1214    \strc_lists_limitated_text\currentlistentrytitle
1215    \endstrut
1216    \endgroup
1217    \begingroup
1218    \ifconditional\c_lists_has_page
1219        \ifconditional\c_lists_show_page
1220            \nobreak
1221            \hskip.75\emwidth\relax
1222            \nobreak
1223            \strc_lists_set_reference_attribute\v!pagenumber
1224            \strc_lists_set_style_color\c!pagestyle\c!pagecolor\v!pagenumber
1225            \strut
1226            \listparameter\c!pagecommand\currentlistentrypagenumber
1227        \fi
1228    \fi
1229    \endgroup
1230    \scratchdistance\listparameter\c!distance\relax
1231    \ifdim\scratchdistance<\emwidth
1232        \hskip\emwidth\s!plus\emwidth\s!minus.25\emwidth\relax
1233    \else
1234        \hskip\scratchdistance\s!plus.5\scratchdistance\s!minus.25\scratchdistance\relax
1235    \fi
1236    \endgroup
1237    \endgroup
1238\stopsetups
1239
1240\startsetups[\??listrenderings:e]
1241    \typo_injectors_check_list
1242    \noindent % otherwise annotations are mirrored up
1243    \typo_injectors_mark_list
1244    \hbox \strc_lists_get_reference_attribute\v!all \strc_lists_get_destination_attribute {
1245        \letlistparameter\c!depth\zeropoint
1246        \letlistparameter\c!color\empty
1247        \inheritedlistframed {
1248            \letinteractionparameter\c!strut\v!no % still needed?
1249            \strc_lists_set_style_color\c!style\c!color\v!all
1250            \the\t_lists_every_renderingtext
1251            \the\t_lists_every_renderingsynchronize
1252            \setstrut
1253            \begstrut
1254            \strc_lists_limitated_text\currentlistentrytitle
1255            \endstrut
1256        }
1257    }
1258    \par
1259    \listparameter\c!inbetween
1260\stopsetups
1261
1262\startsetups[\??listrenderings:f]
1263    \typo_injectors_check_list
1264    \noindent % otherwise annotations are mirrored up
1265    \typo_injectors_mark_list
1266    \hbox \strc_lists_get_reference_attribute\v!all \strc_lists_get_destination_attribute {
1267        \dosetraggedhbox{\listparameter\c!align}%
1268        \raggedbox {
1269            \strc_lists_set_style_color\c!style\c!color\v!all
1270            \the\t_lists_every_renderingtext
1271            \the\t_lists_every_renderingsynchronize
1272            \setstrut
1273            \begstrut
1274            \strc_lists_limitated_text\currentlistentrytitle
1275            \endstrut
1276        }
1277    }
1278    \par
1279    \listparameter\c!inbetween
1280\stopsetups
1281
1282\startsetups[\??listrenderings:g]
1283    \typo_injectors_check_list
1284    \noindent % otherwise annotations are mirrored up
1285    \typo_injectors_mark_list
1286    \hbox \strc_lists_get_reference_attribute\v!all \strc_lists_get_destination_attribute {
1287        \midaligned {
1288            \strc_lists_set_style_color\c!style\c!color\v!all
1289            \the\t_lists_every_renderingtext
1290            \the\t_lists_every_renderingsynchronize
1291            \setstrut
1292            \begstrut
1293            \strc_lists_limitated_text\currentlistentrytitle
1294            \endstrut
1295        }
1296    }
1297    \par
1298    \listparameter\c!inbetween
1299\stopsetups
1300
1301%D This is a new one, similar to vertical and horizontal but better suited when
1302%D no command is set (WS):
1303
1304\definelistalternative
1305  [\v!interactive]
1306  [\c!renderingsetup=\??listrenderings:interactive,
1307   \c!before=\endgraf, % new per 2014-11-08
1308   \c!after=\endgraf]  % new per 2014-11-08
1309
1310\startsetups[\??listrenderings:interactive]
1311    \edef\p_command{\listalternativeparameter\c!command}%
1312    \typo_injectors_check_list
1313    \listparameter\c!before
1314    \noindent % otherwise annotations are mirrored up
1315    \typo_injectors_mark_list
1316    \hbox \strc_lists_get_reference_attribute\v!all \strc_lists_get_destination_attribute {
1317        \ifempty\p_command
1318            [
1319                \currentlist:\space
1320                \currentlistentrynumber
1321                \space\emdash\space
1322                \currentlistentrytitle
1323                \space\emdash\space
1324                \currentlistentrypagenumber
1325            ]
1326        \else
1327            \p_command\currentlistentrynumber\currentlistentrytitle\currentlistentrypagenumber
1328        \fi
1329   }
1330   \listparameter\c!after
1331\stopsetups
1332
1333%D One special for publications (as Alan loves to hangindent). No fonts and such
1334%D (for now). No interaction either as that is dealt with elsewhere.
1335%D
1336%D \currentlistsymbol
1337%D \currentlistentrynumber
1338%D \currentlistentrytitle
1339%D \currentlistentrypagenumber % not really used
1340
1341\definelistalternative
1342  [\v!paragraph]
1343  [\c!filler=\v!space,
1344   \c!renderingsetup=\??listrenderings:\v!paragraph]
1345
1346\startsetups[\??listrenderings:\v!paragraph]
1347    \endgraf % are we grouped?
1348    \typo_injectors_check_list % ?
1349    \listparameter\c!before
1350    \endgraf
1351    \begingroup
1352    \forgetall
1353    \noindent
1354    \parindent\zeropoint
1355    \edef\p_width{\listparameter\c!width}%
1356    \edef\p_distance{\listparameter\c!distance}% we are nice for bib users
1357    \edef\p_margin{\listparameter\c!margin}% we are nice for bib users
1358    \ifx\p_distance\v!none
1359        \scratchdistance\zeropoint
1360    \else
1361        \scratchdistance\p_distance
1362    \fi
1363    \ifx\p_margin\v!none
1364        \scratchoffset\zeropoint
1365    \else
1366        \scratchoffset\p_margin
1367    \fi
1368    \ifx\p_width\v!fit
1369        \scratchwidth\zeropoint
1370        \leftskip\scratchoffset
1371    \else
1372        \scratchwidth\p_width
1373        \ifzeropt\scratchoffset
1374            \leftskip\dimexpr\scratchwidth+\scratchdistance\relax
1375        \else
1376            \leftskip\scratchoffset
1377        \fi
1378    \fi
1379    \usealignparameter\listparameter
1380    \hskip-\leftskip
1381    \ifconditional\c_lists_has_number
1382        \ifconditional\c_lists_show_number
1383            \setbox\scratchbox
1384                \simplealignedbox\scratchwidth{\listparameter\c!numberalign}
1385                \bgroup
1386                    \useliststyleandcolor\c!numberstyle\c!numbercolor
1387                    \currentlistsymbol
1388                \egroup
1389            \ifdim\wd\scratchbox>\zeropoint
1390                \box\scratchbox
1391                \hskip\scratchdistance\relax
1392            \fi
1393        \fi
1394    \fi
1395    \begingroup
1396        \useliststyleandcolor\c!textstyle\c!textcolor
1397        \setstrut
1398        \begstrut
1399        \currentlistentrytitle
1400        \endstrut
1401    \endgroup
1402    \ifconditional\c_lists_has_page
1403        \ifconditional\c_lists_show_page
1404            \nobreak
1405            \currentlistfiller
1406            \begingroup
1407                \useliststyleandcolor\c!pagestyle\c!pagecolor
1408                \currentlistentrypagenumber
1409            \endgroup
1410        \fi
1411    \fi
1412    \endgraf
1413    \endgroup
1414    \allowbreak
1415    \listparameter\c!after
1416\stopsetups
1417
1418%D List elements are packaged in such a way that we can click on them in an
1419%D interactive document. Here are a few helpers.
1420
1421\newconstant\a_strc_lists_reference
1422\newconstant\a_strc_lists_destination
1423
1424\installcorenamespace{listinteractions}
1425
1426\letcsname\??listinteractions\v!number       \endcsname\v!number
1427\letcsname\??listinteractions\v!sectionnumber\endcsname\v!number
1428\letcsname\??listinteractions\v!text         \endcsname\v!text
1429\letcsname\??listinteractions\v!title        \endcsname\v!text
1430\letcsname\??listinteractions\v!page         \endcsname\v!pagenumber
1431\letcsname\??listinteractions\v!pagenumber   \endcsname\v!pagenumber
1432\letcsname\??listinteractions\v!all          \endcsname\v!all
1433\letcsname\??listinteractions\v!yes          \endcsname\v!all
1434
1435\permanent\def\listboxproperties       {\strc_lists_get_reference_attribute}
1436\permanent\def\listrenderingsetup      {\the\t_lists_every_renderingtext}
1437\permanent\def\listrenderingsynchronize{\the\t_lists_every_renderingsynchronize}
1438
1439\protected\def\strc_lists_interaction_check
1440  {\iflocation
1441     \strc_lists_interaction_check_yes
1442   \else
1443     \strc_lists_interaction_check_nop
1444   \fi}
1445
1446\def\strc_lists_interaction_check_yes_yes
1447  {\edef\p_interaction_forward{\listparameter\c!interaction}%
1448   \ifcsname\??listinteractions\p_interaction_forward\endcsname
1449    %\expandafter\let\expandafter\p_interaction_forward\csname\??listinteractions\p_interaction_forward\endcsname
1450     \expandafter\let\expandafter\p_interaction_forward\lastnamedcs
1451     \strc_references_get_simple_reference{internal(\currentlistentrylocation)}%
1452     \a_strc_lists_reference\currentreferenceattribute
1453   \else
1454     \a_strc_lists_reference\attributeunsetvalue
1455   \fi
1456   \ifnum\a_strc_lists_reference=\attributeunsetvalue
1457     \let\strc_lists_get_reference_attribute\gobbleoneargument
1458     \let\strc_lists_set_reference_attribute\gobbleoneargument
1459     \let\strc_lists_set_style_color        \strc_lists_set_style_color_normal
1460   \else
1461     \let\strc_lists_get_reference_attribute\strc_lists_get_reference_attribute_indeed
1462     \let\strc_lists_set_reference_attribute\strc_lists_set_reference_attribute_indeed
1463     \let\strc_lists_set_style_color        \strc_lists_set_style_color_special
1464   \fi
1465   \edef\p_interaction_backward{\namedheadparameter\currentlist\c!interaction}% \namedheadparameter !
1466   \ifx\p_interaction_backward\v!list
1467     \strc_references_set_simple_reference{*\currentlistentrylocation}%
1468     \a_strc_lists_destination\currentdestinationattribute
1469   \else
1470     \a_strc_lists_destination\attributeunsetvalue
1471   \fi
1472   \ifnum\a_strc_lists_destination=\attributeunsetvalue
1473     \let\strc_lists_get_destination_attribute\empty
1474     \let\strc_lists_set_destination_attribute\empty
1475   \else
1476     \let\strc_lists_get_destination_attribute\strc_lists_get_destination_attribute_indeed
1477     \let\strc_lists_set_destination_attribute\strc_lists_set_destination_attribute_indeed
1478   \fi}
1479
1480\def\strc_lists_interaction_check_yes_nop
1481  {\a_strc_lists_reference  \attributeunsetvalue
1482   \a_strc_lists_destination\attributeunsetvalue
1483   \let\strc_lists_get_reference_attribute\gobbleoneargument
1484   \let\strc_lists_set_reference_attribute\gobbleoneargument
1485   \let\strc_lists_get_destination_attribute\empty
1486   \let\strc_lists_set_destination_attribute\empty
1487   \let\strc_lists_set_style_color\strc_lists_set_style_color_normal}
1488
1489\def\strc_lists_interaction_check_yes
1490  {\ifempty\currentlistentrylocation
1491     \strc_lists_interaction_check_yes_nop
1492   \orelse\ifnum\currentlistentrylocation=\zerocount
1493     \strc_lists_interaction_check_yes_nop
1494   \else
1495     \strc_lists_interaction_check_yes_yes
1496   \fi}
1497
1498\def\strc_lists_interaction_check_nop
1499  {\let\strc_lists_get_reference_attribute  \gobbleoneargument
1500   \let\strc_lists_set_reference_attribute  \gobbleoneargument
1501   \let\strc_lists_get_destination_attribute\empty
1502   \let\strc_lists_set_destination_attribute\empty
1503   \let\strc_lists_set_style_color          \strc_lists_set_style_color_normal}
1504
1505\strc_lists_interaction_check_nop
1506
1507\def\strc_lists_get_reference_attribute_indeed#element%
1508  {\ifx#element\p_interaction_forward
1509     attr \referenceattribute\a_strc_lists_reference
1510   \fi}
1511
1512\def\strc_lists_set_reference_attribute_indeed#element%
1513  {\ifx#element\p_interaction_forward
1514     \c_attr_reference\a_strc_lists_reference
1515   \fi}
1516
1517\def\strc_lists_get_destination_attribute_indeed
1518  {attr \destinationattribute\number\a_strc_lists_destination}
1519
1520\def\strc_lists_set_destination_attribute_indeed
1521  {\c_attr_destination\a_strc_lists_destination}
1522
1523\protected\def\strc_lists_set_style_color_normal#style#color#element%
1524  {\useliststyleandcolor#style#color}
1525
1526\protected\def\strc_lists_set_style_color_special#style#color#element%
1527  {\useliststyleandcolor#style#color%
1528   \ifempty\currentcolorparameter
1529     \ifx#element\p_interaction_forward
1530       \setlocationcolor
1531     \fi
1532 % \else
1533 %   \resetinteractionparameter\c!color
1534 %   \resetinteractionparameter\c!contrastcolor
1535   \fi}
1536
1537\let\strc_lists_set_style_color\strc_lists_set_style_color_normal
1538
1539%D A helper:
1540
1541\protected\def\strc_lists_limitated_text#text%
1542  {\edef\p_maxwidth{\listparameter\c!maxwidth}%
1543   \ifempty\p_maxwidth
1544     \listparameter\c!textcommand{#text}%
1545   \else
1546     \listparameter\c!textcommand{\limitatetext{#text}\p_maxwidth{\splitsymbol{\listparameter\c!limittext}}}%
1547   \fi}
1548
1549% public helpers
1550
1551\permanent\protected\def\startcurrentlistentrywrapper
1552  {\hbox \strc_lists_get_reference_attribute\v!all \strc_lists_get_destination_attribute\bgroup}
1553
1554\aliased\let\stopcurrentlistentrywrapper\egroup
1555
1556\permanent\def\currentlistentryreferenceattribute  {\strc_lists_get_reference_attribute}   % this definition can change
1557\permanent\def\currentlistentrydestinationattribute{\strc_lists_get_destination_attribute} % this definition can change
1558\permanent\def\currentlistentrylimitedtext         {\strc_lists_limitated_text}            % this definition can change
1559
1560% todo:
1561
1562\permanent\def\utilitylistlength{\listlength} % also in strc-reg (downward compatible name)
1563
1564\mutable\let\listlength\!!zerocount           % also in strc-reg
1565
1566\permanent\tolerant\protected\def\determinelistcharacteristics[#list]#spacer[#settings]%
1567  {\begingroup
1568   \edef\currentlist{\firststructureelementinlist{#list}}%
1569   \ifempty\currentlist
1570     \endgroup
1571     \let\listlength\!!zerocount
1572   \else
1573     \setupcurrentlist[#settings]%
1574     \strc_lists_analyze{#list}{\listparameter\c!criterium}{\listparameter\c!reference}%
1575     \normalexpanded{\endgroup\noexpand\edef\noexpand\listlength{\structurelistsize}}%
1576   \fi
1577   \strc_lists_set_mode}
1578
1579\protect \endinput
1580