strc-sec.mkiv /size: 49 Kb    last modification: 2021-10-28 13:50
1%D \module
2%D   [       file=strc-sec,
3%D        version=2008.10.20,
4%D          title=\CONTEXT\ Structure Macros,
5%D       subtitle=Sectioning,
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%D In retrospect I should have gone futher and move more to the
15%D \LUA\ end but here we are now. Maybe some day.
16
17\writestatus{loading}{ConTeXt Structure Macros / Sectioning}
18
19\unprotect
20
21\startcontextdefinitioncode
22
23\installcorenamespace{structure}
24
25\installdirectcommandhandler \??structure {structure} % unchecked, so we need to initialize used parameters
26
27\setupstructure % not a user command so we might need to change the name
28  [\c!number=,
29   \c!level=,
30   \c!name=,
31   \c!title=,
32   \c!bookmark=,
33   \c!marking=,
34   \c!list=,
35   \c!label=,
36   \c!coupling=,
37   \c!ownnumber=,
38 % \c!interaction=\v!list,
39   \c!sectionseparatorset=\s!default,
40   \c!sectionconversionset=\s!default,
41   \c!sectionstopper=,
42   \c!sectionstarter=,
43   \c!sectionsegments=,
44   \c!sectionresetset=,
45   \c!reference=,
46   \c!backreference=,
47   \c!expansion=\v!no,
48   \c!xmlsetup=,
49   \s!catcodes=,
50   \c!saveinlist=\v!yes]
51
52% maybe flags for list, bm, mark
53
54\def\m_strc_references_prefix_yes{+}
55\def\m_strc_references_prefix_nop{-}
56
57\let\currentstructurereferenceprefix\empty
58
59\installglobalmacrostack\currentstructurereferenceprefix
60
61\def\strc_sectioning_set_reference_prefix
62  {\ifx\currentstructurereferenceprefix\empty
63     % nothing
64   \else\ifx\currentstructurereferenceprefix\m_strc_references_prefix_yes
65     \global\advance\prefixcounter \plusone % temp here
66     \setupglobalreferenceprefix[\the\prefixcounter]%
67   \else\ifx\currentstructurereferenceprefix\m_strc_references_prefix_nop
68     \setupglobalreferenceprefix[]%
69   \else
70     \setupglobalreferenceprefix[\currentstructurereferenceprefix]%
71   \fi\fi\fi
72   \glet\currentstructurereferenceprefix\referenceprefix}
73
74% why xdef ?
75
76\setupstructure
77  [\c!label={\headparameter{\currentsectionblock\c!label}},
78   \c!incrementnumber=\ifconditional\c_strc_sectioning_increment\v!yes\else\v!no\fi, % not that needed
79   \c!saveinlist=\ifconditional\c_strc_sectioning_to_list\v!yes\else\v!no\fi,
80   \c!level=\currentheadlevel,
81   \c!number=\ifconditional\c_strc_sectioning_increment\ifconditional\headshownumber\v!yes\else\v!no\fi\else\v!no\fi,
82   \c!expansion=\headparameter\c!expansion,
83   \c!xmlsetup=\headparameter\c!xmlsetup,
84   \s!catcodes=\headparameter\s!catcodes,
85   \c!sectionresetset=\headparameter\c!sectionresetset,
86   \c!sectionseparatorset=\headparameter\c!sectionseparatorset,
87   \c!sectionconversionset=\headparameter\c!sectionconversionset,
88   \c!sectionconversion=\headparameter\c!conversion, % just for compatibility
89   \c!sectionstarter=\headparameter\c!sectionstarter,
90   \c!sectionstopper=\headparameter\c!sectionstopper,
91   \c!sectionset=\headparameter\c!sectionset,
92   \c!sectionsegments=\headparameter\c!sectionsegments,
93   \c!reference=\headparameter\c!reference,
94   \c!referenceprefix=\headparameter\c!referenceprefix,
95   \c!criterium=\headparameter\c!criterium]
96
97% see lists/neat-001.tex for usage of:
98
99\def\namedstructureheadlocation#1% expandable, maybe [#1]
100  {\csname\??savedinternalreference\ifcsname\??savedinternalreference#1\endcsname#1\else\s!default\fi\endcsname}
101
102% The next directive only makes sense when we have sort of garanteed outcome (math is not so
103% nice for instance).
104%
105% \enabledirectives[references.bookmarks.preroll]
106
107\newconditional\c_strc_bookmarks_preroll
108
109\installtexdirective
110  {references.bookmarks.preroll}
111  {\settrue \c_strc_bookmarks_preroll}
112  {\setfalse\c_strc_bookmarks_preroll}
113
114\def\strc_sectioning_autobookmark#1%
115  {\begingroup
116 % \settrialtypesetting
117   \the\everypreroll
118   \nodestostring\tempstring{#1}%
119   \glet\currentstructurebookmark\tempstring
120   \endgroup}
121
122% zeros:
123%
124% \setuphead[subsection][criterium=all]
125%
126% \dorecurse{3} {
127%     \chapter{Blabla}                 \subsection{bla 1 1} \subsection{bla 1 2}
128%                      \section{bla 2} \subsection{bla 2 1} \subsection{bla 2 2}
129% }
130
131\unexpanded\def\strc_sectioning_register#1#2#3% #1=interfaced-settings, #2=optional user data (not yet supported)
132  {\begingroup
133   \setupstructure[\c!name={#1},#2]%
134   \xdef\currentstructurename           {\structureparameter\c!name}%
135   \xdef\currentstructurecoupling       {\structureparameter\c!coupling}%
136   \xdef\currentstructureownnumber      {\structureparameter\c!ownnumber}% optional own number
137   \xdef\currentstructurelevel          {\structureparameter\c!level}%
138   \edef\currentstructureexpansion      {\structureparameter\c!expansion}%
139   \xdef\currentstructurexmlsetup       {\structureparameter\c!xmlsetup}%
140   \xdef\currentstructurecatcodes       {\structureparameter\s!catcodes}%
141   \xdef\currentstructurelabel          {\structureparameter\c!label}%
142   \xdef\currentstructurereference      {\structureparameter\c!reference}%
143   \xdef\currentstructurereferenceprefix{\structureparameter\c!referenceprefix}%
144   \xdef\currentstructurebackreference  {\structureparameter\c!backreference}%
145   \xdef\currentstructureshownumber     {\structureparameter\c!number}%
146   \xdef\currentstructuresaveinlist     {\structureparameter\c!saveinlist}%
147   \xdef\currentstructureincrementnumber{\structureparameter\c!incrementnumber}%
148   \xdef\currentstructureplaceholder    {\structureparameter\c!placeholder}%
149   \ifx\currentstructureexpansion\s!xml
150     \xmlstartraw
151       \xdef\currentstructuretitle   {\structureparameter\c!title}%
152       \xdef\currentstructurebookmark{\structureparameter\c!bookmark}%
153       \xdef\currentstructuremarking {\structureparameter\c!marking}%
154       \xdef\currentstructurelist    {\structureparameter\c!list}%
155     \xmlstopraw
156     \iflocation \ifx\currentstructurebookmark\empty \ifconditional\c_strc_bookmarks_preroll
157       \strc_sectioning_autobookmark\currentstructuretitle
158     \fi \fi \fi
159     \ifx\currentstructurelist\empty
160       \glet\currentstructurelist\currentstructuretitle
161     \fi
162     \glet\currentstructurecoding\s!xml
163   \else
164     \ifx\currentstructureexpansion\v!yes
165       \xdef\currentstructuretitle   {\structureparameter\c!title}%
166       \xdef\currentstructurebookmark{\structureparameter\c!bookmark}%
167       \xdef\currentstructuremarking {\structureparameter\c!marking}%
168       \xdef\currentstructurelist    {\structureparameter\c!list}%
169       \iflocation \ifx\currentstructurebookmark\empty \ifconditional\c_strc_bookmarks_preroll
170         \strc_sectioning_autobookmark\currentstructuretitle
171       \fi \fi \fi
172     \else
173       \xdef\currentstructuretitle   {\detokenizedstructureparameter\c!title}%
174       \xdef\currentstructurebookmark{\detokenizedstructureparameter\c!bookmark}%
175       \xdef\currentstructuremarking {\detokenizedstructureparameter\c!marking}%
176       \xdef\currentstructurelist    {\detokenizedstructureparameter\c!list}%
177       \iflocation \ifx\currentstructurebookmark\empty
178         \ifconditional\c_strc_bookmarks_preroll
179           \strc_sectioning_autobookmark{\structureparameter\c!title}%
180         \else
181           \begingroup
182           \simplifycommands
183           \xdef\currentstructurebookmark{\detokenize\expandafter{\normalexpanded{\structureparameter\c!title}}}%
184           \endgroup
185         \fi
186       \fi \fi
187     \fi
188     \ifx\currentstructurelist\empty
189       \glet\currentstructurelist\currentstructuretitle
190     \fi
191     \glet\currentstructurecoding\s!tex
192   \fi
193   \setnextinternalreference
194   \storeinternalreference\currentstructurename{\the\locationcount}%
195   \strc_sectioning_set_reference_prefix
196   \clf_setsectionentry
197        references {
198            internal      \locationcount
199          % block         {\currentsectionblock}
200            prefix        {\currentstructurereferenceprefix}
201            reference     {\currentstructurereference}
202            backreference {\currentstructurebackreference}
203        }
204        directives {
205            resetset {\structureparameter\c!sectionresetset}
206        }
207        metadata {
208            kind      {section}
209            name      {\currentstructurename}
210            catcodes  \ifx\currentstructurecatcodes\empty\catcodetable\else\csname\currentstructurecatcodes\endcsname\fi\space
211            coding    {\currentstructurecoding}
212        \ifx\currentstructurecoding\s!xml
213            xmlroot   {\xmldocument}
214        \fi
215        \ifx\currentstructurexmlsetup\empty \else
216            xmlsetup  {\currentstructurexmlsetup}
217        \fi
218        \ifx\currentstructuresaveinlist\v!no
219            nolist \space true\space
220        \fi
221        \ifx\currentstructureincrementnumber\v!yes
222            increment {\currentstructureincrementnumber}
223        \fi
224        }
225        titledata {
226            label    {\detokenize\expandafter{\currentstructurelabel}}
227            title    {\detokenize\expandafter{\currentstructuretitle}}
228        \ifx\currentstructurebookmark\currentstructuretitle \else
229            bookmark {\detokenize\expandafter{\currentstructurebookmark}}
230        \fi
231        \ifx\currentstructuremarking\currentstructuretitle \else
232            marking  {\detokenize\expandafter{\currentstructuremarking}}
233        \fi
234        \ifx\currentstructuresaveinlist\v!no \else
235          \ifx\currentstructurelist\currentstructuretitle \else
236            list     {\detokenize\expandafter{\currentstructurelist}}
237          \fi
238        \fi
239        }
240        numberdata {
241          % block         {\currentsectionblock}
242        \ifx\currentstructureshownumber\v!no
243            hidenumber    \space true\space % space needed for parser
244        \fi
245            separatorset  {\structureparameter\c!sectionseparatorset}
246            conversionset {\structureparameter\c!sectionconversionset}
247            conversion    {\structureparameter\c!sectionconversion}
248            starter       {\structureparameter\c!sectionstarter}
249            stopper       {\structureparameter\c!sectionstopper}
250            set           {\structureparameter\c!sectionset}
251            segments      {\structureparameter\c!sectionsegments}
252            ownnumber     {\currentstructureownnumber}
253            language      {\currentlanguage}% for the moment, needed for bookmarks conversion
254            criterium     {\structureparameter\c!criterium}
255        }
256        userdata {\detokenize{#3}}% will be converted to table at the lua end
257   \relax
258   \xdef\currentstructurelistnumber{\clf_currentsectiontolist}%
259 % \currentstructuresynchronize has to be called someplace, since it introduces a node
260   \setstructuresynchronization\currentstructurelistnumber
261   \endgroup}
262
263\let\currentsectioncountervalue \!!zerocount % redefined later
264\let\previoussectioncountervalue\!!zerocount % redefined later
265
266% We can access the (stored) data with the following macros.
267%
268% \def\MyHeadCommand  #1#2{\framed{#1}\framed{#2 / \structureuservariable{subtitle}}}
269% \def\MyListCommand#1#2#3{\externalfigure[\structurelistuservariable{figure}][height=5mm]#2}
270%
271% \setuphead[chapter][command=\MyHeadCommand]
272% \setuplist[chapter][alternative=command,command=\MyListCommand]
273%
274% \starttext
275%     \setupheadertexts[chapter]
276%     \setupinteraction[state=start]
277%     \placebookmarks[chapter]
278%     \placelist[chapter]
279%     \startchapter[ownnumber=10,title=Ton,list=Hans,marking=Kees,bookmark=Bram][figure=cow.pdf,subtitle=oeps]
280%     \stopchapter
281% \stoptext
282
283% todo: #1 => "#1" ... adapt lua code for name and number
284
285\def\structurenumber               {\clf_structurenumber}
286\def\structuretitle                {\clf_structuretitle}
287\def\structurevariable           #1{\clf_structurevariable         {#1}}
288\def\structureuservariable       #1{\clf_structureuservariable     {#1}}
289\def\structurecatcodedget        #1{\clf_structurecatcodedget      {#1}}    % bad name
290\def\structuregivencatcodedget #1#2{\clf_structuregivencatcodedget {#1}#2 } % bad name
291\def\structureautocatcodedget  #1#2{\clf_structureautocatcodedget  {#1}{#2}}
292\def\namedstructurevariable    #1#2{\clf_namedstructurevariable    {#1}{#2}}
293\def\namedstructureuservariable#1#2{\clf_namedstructureuservariable{#1}{#2}}
294
295% compatibility issue:
296%
297% \def\setfullsectionnumber #1{}
298% \def\preparefullnumber    #1{}
299% \def\fullsectionnumber    {1--1--1}
300% \def\makesectionnumber    [#1]{}
301% \def\makesectionformat    {}
302% \def\sectionformat        {1--1-1-1-1-1-1}
303% \def\composedsectionnumber{}
304% \def\@@kolist{}
305
306% \setuphead[section]   [separator=\separatorlist{?,!,*}]
307% \setuphead[subsection][separator=\separatorlist{??,!!,**}]
308%
309% \let\spr\separatorlist % this will enable this feature
310%
311% \setuphead[section]   [separator={?,!,*}]
312% \setuphead[subsection][separator={??,!!,**}]
313%
314% \setupheads[separator={A,B,C,D,E,F}]
315% \chapter{test}
316% \section{test} \subsection{test} \subsection{test}
317% \section{test} \subsection{test} \subsection{test}
318
319% lua interface / names and interface might change
320
321% \newconditional\c_strc_rendering_continuous % not used (mkii ?)
322
323\def\setstructurelevel         #1#2{\clf_setstructurelevel         {#1}{#2}}         % name, level|parent
324\def\getstructurelevel           #1{\clf_getstructurelevel         {#1}}             % name
325\def\setstructurenumber        #1#2{\clf_setstructurenumber         #1{#2}}          % level, number (+/-)
326\def\getstructurenumber          #1{\clf_getstructurenumber         \numexpr#1\relax} % level
327\def\getsomestructurenumber    #1#2{\clf_getsomestructurenumber     #1{#2}}           % level, what
328\def\getfullstructurenumber      #1{\clf_getfullstructurenumber     \numexpr#1\relax} % level
329\def\getsomefullstructurenumber#1#2{\clf_getsomefullstructurenumber #1{#2}}           % level, what
330\def\getspecificstructuretitle   #1{\clf_getspecificstructuretitle {#1}{\headparameter\s!catcodes}}
331
332% structure heads (like \startchapter)
333
334% \c!deeptextcommand, \c!deepnumbercommand: undefined !
335% \c!before \c!after \c!distance
336% \c!page \c!header  \c!text \c!footer=,
337% \c!numbercommand \c!textcommand \c!ownnumber \c!number
338% \c!file \c!grid \c!margintext
339% \c!expansion \c!xmlsetup \s!catcode
340
341\installcorenamespace{head}
342\installcorenamespace{headlevel}
343\installcorenamespace{headincrement}
344\installcorenamespace{headplace}
345\installcorenamespace{headmarkyes}
346\installcorenamespace{headmarknop}
347
348\installcommandhandler \??head {head} \??head
349
350\installmacrostack\currenthead
351\installmacrostack\currentheadparent
352
353\setuphead [%
354    %\c!after=,
355    %\c!align=,
356    %\c!aligntitle=,
357    \c!alternative=\v!normal,
358    %\c!before=,
359    %\c!color=,
360    %\c!command=,
361    \c!continue=\v!yes,
362    %\c!coupling=,
363    %\c!deepnumbercommand=,
364    %\c!deeptextcommand=,
365    %\c!default=,
366    \c!distance=\zeropoint,
367    \c!textdistance=\zeropoint,
368    \c!textwidth=\zeropoint,   % signal too
369    \c!numberwidth=\zeropoint, % signal too
370    \c!width=\zeropoint,       % signal too
371    \c!expansion=\v!no,
372    %\c!file=,
373    %\c!footer=,
374    %\c!grid=,
375    \c!hang=\v!none,
376    %\c!header=,
377    \c!incrementnumber=\v!yes,
378    \c!indentnext=\v!no,
379    %\c!label=,
380    %\c!limittext=\languageparameter\c!limittext,
381    \c!margin=\zeropoint,
382    %\c!margintext=,
383    \c!number=\v!yes,
384    \c!numbercolor=\headparameter\c!color,
385    \c!textcolor=\headparameter\c!color,
386    \c!numberstyle=\headparameter\c!style,
387    \c!textstyle=\headparameter\c!style,
388    %\c!numbercommand=,
389    %\c!textcommand=,
390    \c!ownnumber=\v!no,
391    %\c!page=,
392    \c!placehead=\v!yes,
393    \c!sectionconversionset=\s!default,
394    \c!sectionnumber=\v!yes,
395    %\c!sectionsegments=,
396    \c!sectionseparatorset=\s!default,
397    \c!sectionset=\v!all,
398    \c!interlinespace=,
399    %\c!sectionstopper=,
400    %\c!sectionstarter=,
401    %\c!strut=,
402    %\c!style=,
403    %\c!text=,
404    %\c!tolerance=,
405    %\c!beforesection=\directsetup{document:\currenthead:start},  % these might become defaults i.e. acpect document: namespace
406    %\c!insidesection=\directsetup{document:\currenthead:inside}, % these might become defaults i.e. acpect document: namespace
407    %\c!aftersection=\directsetup{document:\currenthead:stop},    % these might become defaults i.e. acpect document: namespace
408   ]
409
410\let\setupheads\setuphead % will go
411
412\appendtoks
413    \ifx\currentheadparent\empty
414        \edef\currentheaddefault{\headparameter\c!default}%
415        \edef\currentheadsection{\headparameter\c!section}%
416        \ifx\currenthead\currentheaddefault
417          \let\currentheadparent\currentheadsection
418        \else\ifx\currentheaddefault\empty
419          \let\currentheadparent\currentheadsection
420        \else
421          \let\currentheadparent\currentheaddefault
422        \fi\fi
423        \normalexpanded {%
424            \setheadparameter{\c!label}{\currenthead}%
425            \setheadparameter{\c!coupling}{\currenthead}%
426            \setheadparameter{\s!parent}{\??head\currentheadparent}%
427            \definemarking[\currenthead]         [\currentheadsection]%
428            \definemarking[\currenthead\v!number][\currentheadsection]%
429            \setupmarking [\currenthead]         [\c!filtercommand=\noexpand\sectionheadmarkingtitle {\currenthead}]%
430            \setupmarking [\currenthead\v!number][\c!filtercommand=\noexpand\sectionheadmarkingnumber{\currenthead}]%
431        }%
432        \doifelselist\currenthead\donothing
433          {\definelist[\currenthead][\c!prefix=\v!no]}%
434        % we can't do this now for backward compatibility reasons
435      % \doifelselist\currenthead\donothing
436      %   {\normalexpanded{\definelist[\currenthead][\currentheadparent][\c!prefix=\v!no]}}%
437    \else
438        \normalexpanded {%
439            \setheadparameter{\c!label}{\currenthead}%
440            \setheadparameter{\c!coupling}{\currentheadparent}%
441            \definemarking[\currenthead]         [\currentheadparent]%
442            \definemarking[\currenthead\v!number][\currentheadparent\c!number]%
443        }%
444        \doifelselist\currenthead\donothing
445          {\normalexpanded{\definelist[\currenthead][\currentheadparent][\c!prefix=\v!no]}}%
446    \fi
447    \presetlabeltext[\currenthead=]%
448    \the\everysetuphead
449\to \everydefinehead
450
451\newtoks\everyredefinehead
452
453\appendtoks
454    \the\everyredefinehead
455\to \everydefinehead
456
457\appendtoks
458   \setstructurelevel\currenthead{\thenamedheadlevel\currenthead}%
459\to \everyredefinehead
460
461\appendtoks
462    % beware, this is a global register
463    \begingroup
464    \edef\currentsectionheadcoupling{\sectionheadcoupling\currenthead}%
465    \edef\currentsectionheadsection {\sectionheadsection \currentsectionheadcoupling}%
466    \edef\currentsectionlevel       {\sectionlevel       \currentsectionheadsection}%
467    \clf_registersection {\currenthead} {
468        coupling {\currentsectionheadcoupling}
469        section  {\currentsectionheadsection}
470        level    \space \currentsectionlevel \space % space needed for parser
471        parent   {\currentheadparent}
472    }%
473    \endgroup
474\to \everyredefinehead
475
476\appendtoks
477 % \setevalue{\e!next \currenthead}{\donexthead [\currenthead]}%
478   \setuevalue{\e!start\currenthead}{\strc_sectioning_start[\currenthead]}%
479   \setuevalue{\e!stop \currenthead}{\strc_sectioning_stop [\currenthead]}%
480\to \everydefinehead
481
482% so \subject as well as \section will need two commands when ownnumber
483% is used (one can disable it anyway for subject) .. this is not downward
484% compatible but better
485
486\appendtoks
487    \ifx\currenthead\empty \else
488      \doifelse{\headparameter\c!ownnumber}\v!yes
489        {\setuevalue\currenthead{\strc_sectioning_handle_own[\currenthead]}}
490        {\setuevalue\currenthead{\strc_sectioning_handle_nop[\currenthead]}}%
491    \fi
492\to \everysetuphead
493
494\unexpanded\def\doredefinehead#1#2% called at lua end
495  {\push_macro_currenthead
496   \push_macro_currentheadparent
497   \edef\currenthead{#1}%
498   \edef\currentheadparent{#2}%
499   \the\everyredefinehead\relax
500   \pop_macro_currentheadparent
501   \pop_macro_currenthead}
502
503\let\currentnamedsection\empty
504
505\installmacrostack\currentnamedsection
506
507\unexpanded\def\startnamedsection
508  {\dotripleempty\strc_sectioning_start_named_section}
509
510% todo: add grouping but where: before/after trickery .. probably inside because one can always add
511% grouping to the before/after settings
512
513\unexpanded\def\stopnamedsection
514  {\normalexpanded{\strc_sectioning_stop[\currentnamedsection]}}
515
516% structure sections (the parents of chapter etc)
517
518\let\firstsectionname\empty
519\let\lastsectionname \empty
520
521\let\resetallstructuremarks            \relax
522\let\resetcurrentstructuremarks        \relax
523\let\resetcurrentstructuremarkswithpage\relax
524
525\def\resetallstructuremarks            {\resetmarking[\firstsectionname]} % will become option (was \v!section-1)
526\def\resetcurrentstructuremarks        {\resetmarking[\lastsectionname]}  % will become option
527%def\resetcurrentstructuremarkswithpage{\resetmarking[\lastsectionname]}  % will become option
528
529% We could use a commandhandler here but sections are somewhat special in the
530% sense that we have two ways of chaining: the main section (levels) as well
531% as rendering (head).
532
533% -2 = text
534% -1 = manual
535%  0 = block
536% +1 = structurelevel 1 .. n
537
538\newcount\maxstructuredepth
539
540\def\sectionlevel#1%
541  {\csname\??headlevel\ifcsname\??headlevel#1\endcsname#1\else\v!none\fi\endcsname}
542
543\def\namedsectionlevel#1#2% direct indirect
544  {\csname\??headlevel
545     \ifcsname\??headlevel#1\endcsname
546       #1%
547     \else\ifcsname\??headlevel#2\endcsname
548       #2%
549     \else
550       \v!none
551     \fi\fi
552   \endcsname}
553
554\def\xthenamedheadlevel#1%
555  {\namedsectionlevel{#1}{\sectionheadsection{\sectionheadcoupling{#1}}}}
556
557\setvalue{\??headlevel\v!block}{0}
558\setvalue{\??headlevel\v!none }{-1}
559\setvalue{\??headlevel\v!text }{-2}
560\setvalue{\??headlevel\v!head }{-3}
561
562\newtoks\everydefinesection
563
564\unexpanded\def\definesection[#1]%
565  {\ifcsname\??headlevel#1\endcsname \else
566     \edef\currentsection{#1}% not used, will go
567     \edef\currenthead{#1}%
568     \global\advance\maxstructuredepth\plusone
569     \setevalue{\??headlevel#1}{\the\maxstructuredepth}%
570     \setstructurelevel{#1}{\sectionlevel{#1}}%
571     \normalexpanded{\setheadparameter{\s!parent}{\??head\lastsectionname}}% TO BE CHECKED, WE HAVE A HELPER
572     \the\everydefinesection
573     % so far for these default inheritances
574     \definemarking[#1]%
575     \ifnum\maxstructuredepth>\plusone
576       \normalexpanded{\relatemarking[#1][\lastsectionname]}% so, the parent will reset the child
577     \fi
578     \xdef\lastsectionname{#1}%
579     \ifx\firstsectionname\empty
580        \glet\firstsectionname\lastsectionname
581     \fi
582   \fi}
583
584\unexpanded\def\setupsection
585  {\dotripleempty\strc_sectioning_setup}
586
587\def\strc_sectioning_setup[#1][#2][#3]%
588  {\ifcsname\??headlevel#1\endcsname
589     \strc_sectioning_setup_indeed[#1][#2][#3]%
590   \else
591     \strc_sectioning_setup_indeed[\sectionheadsection{#1}][#2][#3]%
592   \fi}
593
594\def\strc_sectioning_setup_indeed[#1][#2][#3]%
595  {\push_macro_currenthead
596   \ifthirdargument
597     \edef\currenthead{#1#2}%     % not used at any more in mkiv (sets now)
598     \setupcurrenthead[#3]%
599   \else
600     \edef\currenthead{#1}%
601     \setupcurrenthead[#2]%
602   \fi
603   \pop_macro_currenthead}
604
605% we share the parameters as sections are roots of heads so eventually we can
606% consider \definesection -> \definehead with one argument
607
608\appendtoks
609    % This is a rather practical default that we don't want to
610    % be part of the parent chain lookup mechanism; it's also
611    % mkii compatible. Somewhat weird that it's part of the
612    % top level structure but it will be flattened anyway.
613    \let\currenthead\currentsection %
614    \setheadparameter\c!textstyle  {\directheadparameter\c!style}%
615    \setheadparameter\c!textcolor  {\directheadparameter\c!color}%
616    \setheadparameter\c!numberstyle{\directheadparameter\c!style}%
617    \setheadparameter\c!numbercolor{\directheadparameter\c!color}%
618\to \everydefinesection
619
620% head -> head
621
622\def\sectionheadmarkingtitle #1#2{\clf_markingtitle {#1}{#2}}
623\def\sectionheadmarkingnumber#1#2{\clf_markingnumber{#1}{#2}}
624
625\def\sectionheadcoupling#1{\namedheadparameter{#1}\c!coupling}
626\def\sectionheadsection #1{\namedheadparameter{#1}\c!section}
627
628% head construction
629
630\unexpanded\def\strc_sectioning_handle_own{\dodoubleempty\strc_sectioning_handle_own_indeed}   % [ref] {nr} {title}
631\unexpanded\def\strc_sectioning_handle_nop{\dodoubleempty\strc_sectioning_handle_nop_indeed}   % [ref] {title}
632\unexpanded\def\strc_sectioning_start     {\dotripleempty\strc_sectioning_start_named_section} % [settings] [userdata] !!! also used at lua end
633
634\newconditional\currentstructureown
635
636\newtoks\everybeforehead % hook, todo: before/after keys
637\newtoks\everyafterhead  % hook, todo: before/after keys
638
639\unexpanded\def\strc_sectioning_handle_own_indeed[#1][#2]#3#4%
640  {\settrue\currentstructureown
641   \triggerautostructurelevel
642   \strc_sectioning_handle{#1}{\c!reference={#2},\c!ownnumber={#3},\c!title={#4}}{}} % name ref nr title --
643
644% \unexpanded\def\strc_sectioning_handle_nop_indeed[#1][#2]% for taco: [key=value] variant
645%   {\setfalse\currentstructureown
646%    \triggerautostructurelevel
647%    \doifelseassignment{#2}\strc_sectioning_handle_nop_indeed_yes\strc_sectioning_handle_nop_indeed_nop{#1}{#2}}
648
649\unexpanded\def\strc_sectioning_handle_nop_indeed[#1][#2]% for taco: [key=value] variant
650  {\setfalse\currentstructureown
651   \triggerautostructurelevel
652   \ifcondition\validassignment{#2}%
653     \expandafter\strc_sectioning_handle_nop_indeed_yes
654   \else
655     \expandafter\strc_sectioning_handle_nop_indeed_nop
656   \fi
657   {#1}{#2}}
658
659\unexpanded\def\strc_sectioning_handle_nop_indeed_yes#1#2%
660  {\strc_sectioning_handle{#1}{#2}{}}
661
662\unexpanded\def\strc_sectioning_handle_nop_indeed_nop#1#2#3%
663  {\strc_sectioning_handle{#1}{\c!reference={#2},\c!title={#3}}{}} % name ref nr title --
664
665\unexpanded\def\strc_sectioning_start_named_section[#1][#2][#3]% for the moment no grouping, too annoying with page breaks
666  {\push_macro_currentnamedsection
667   \push_macro_currentstructurereferenceprefix
668   \edef\currentnamedsection{#1}%
669   \setfalse\currentstructureown
670  %\globalpushmacro\currenthead % this does not work out well
671   \xdef\currenthead{#1}%
672   \setsystemmode\currenthead % new, also here now
673   \headparameter\c!beforesection % beware, no users vars set yet
674   \the\everybeforehead
675   \strc_sectioning_handle{#1}{#2}{#3}% name -- -- -- userdata (we might move the tagged to here)
676   % potential: \bgroup (can be optional: grouped = yes)
677   \headparameter\c!insidesection}
678
679\unexpanded\def\strc_sectioning_stop[#1]% !!! also used at lua end
680  {\dostoptagged
681   \dostoptagged
682   % potential: \egroup
683  %\globalpopmacro\currenthead % so we do a hard recover
684   \xdef\currenthead{#1}% recover
685   \headparameter\c!aftersection
686   \the\everyafterhead
687   \resetsystemmode\currenthead
688   \pop_macro_currentstructurereferenceprefix
689   \pop_macro_currentnamedsection} % new, also here now
690
691\let\dostarthead\strc_sectioning_start % used at lua end
692\let\dostophead \strc_sectioning_stop  % used at lua end
693
694% \newconditional\structurereversesectionnumbers  % todo: key/val
695
696\newconditional\c_strc_sectioning_to_list
697\newconditional\c_strc_sectioning_increment
698\newconditional\c_strc_sectioning_place
699\newconditional\c_strc_sectioning_empty
700\newconditional\c_strc_sectioning_hidden
701\newconditional\c_strc_sectioning_section
702
703\newconditional\headshownumber  % public
704\newconditional\headisdisplay   % public
705\newconditional\headissomewhere % public
706
707\setvalue{\??headincrement\v!yes  }{\settrue \c_strc_sectioning_increment\settrue \c_strc_sectioning_to_list}
708\setvalue{\??headincrement\v!no   }{\setfalse\c_strc_sectioning_increment\setfalse\c_strc_sectioning_to_list}
709\setvalue{\??headincrement\v!list }{\setfalse\c_strc_sectioning_increment\settrue \c_strc_sectioning_to_list}
710\setvalue{\??headincrement\s!empty}{\settrue \c_strc_sectioning_increment\settrue \c_strc_sectioning_to_list}
711
712\unexpanded\def\strc_sectioning_initialize_increment
713  {\edef\currentheadincrement{\headparameter\c!incrementnumber}%
714   \ifcsname\??headincrement\currentheadincrement\endcsname
715     \lastnamedcs
716   \else
717     \settrue \c_strc_sectioning_increment\settrue \c_strc_sectioning_to_list
718     % \filterheadnumber
719   \fi}
720
721\def\filterheadnumber
722  {\settrue\c_strc_sectioning_increment
723   \settrue\c_strc_sectioning_to_list
724   \ifx\currentproduct\empty
725     % todo : filter from other toc (number, file, title)
726     % use  : \currentheadincrement as spec
727   \fi}
728
729\setvalue{\??headplace\v!yes}%
730  {\setfalse\c_strc_sectioning_empty
731   \settrue \c_strc_sectioning_place
732   \setfalse\c_strc_sectioning_hidden
733   \setfalse\c_strc_sectioning_section}
734
735\setvalue{\??headplace\v!empty}%
736  {\settrue \c_strc_sectioning_empty
737   \settrue \c_strc_sectioning_place
738   \setfalse\c_strc_sectioning_hidden
739   \setfalse\c_strc_sectioning_section}
740
741\setvalue{\??headplace\v!no}%
742  {\settrue \c_strc_sectioning_empty
743   \setfalse\c_strc_sectioning_place
744   \setfalse\c_strc_sectioning_hidden
745   \setfalse\c_strc_sectioning_section}
746
747\setvalue{\??headplace\v!hidden}%
748  {\settrue \c_strc_sectioning_empty
749   \setfalse\c_strc_sectioning_place
750   \settrue \c_strc_sectioning_hidden
751   \setfalse\c_strc_sectioning_section}
752
753\setvalue{\??headplace\v!section}%
754  {\settrue \c_strc_sectioning_empty
755   \setfalse\c_strc_sectioning_place
756   \settrue \c_strc_sectioning_hidden
757   \settrue \c_strc_sectioning_section}
758
759\unexpanded\def\strc_sectioning_initialize_placement
760  {\expandnamespaceparameter\??headplace\headparameter\c!placehead\v!yes}
761
762\newmode\v!sectionnumber
763
764\def\dosetstructureheadnumbercontent
765  {\setsystemmode\v!sectionnumber
766   \settrue\headshownumber} % why ?
767
768\def\doresetstructureheadnumbercontent
769  {\resetsystemmode\v!sectionnumber
770   \setfalse\headshownumber} % why ?
771
772\unexpanded\def\strc_sectioning_initialize_number
773  {\edef\p_number{\sectionblockparameter\c!number}%
774   \ifx\p_number\v!yes
775      \edef\p_number{\headparameter\c!number}%
776      \ifx\p_number\v!yes
777        \settrue\headshownumber
778      \else
779        \setfalse\headshownumber
780      \fi
781   \else
782     \setfalse\headshownumber
783   \fi}
784
785% Beware, we do need some node for anchoring marks and normally a zwnj will
786% do but it interferes so we deal with it at the \LUA\ end.
787
788\newtoks\everyheadsynchronization
789
790% \appendtoks
791%     \currentstructuresynchronize
792% \to \everyheadsynchronization
793
794\let\currentstructuresynchronize\donothing
795
796\appendtoks
797    \currentstructuresynchronize
798    \glet\currentstructuresynchronize\donothing
799\to \everyheadsynchronization
800
801\unexpanded\def\theheadsynchronization
802  {% no, interferes: \signalcharacter
803   \the\everyheadsynchronization}
804
805% BEWARE: \marking[section]{my text} does not work as we use list indices instead
806% so we need a 'keep track of raw set option' (or maybe a funny internal prefix)
807
808\unexpanded\def\setheadmarking % li:: so that we can use \marking[section]{Taco needed this}
809  {\strc_sectioning_delayed_flush
810   \normalexpanded{\setmarking[\currenthead]{li::\currentstructurelistnumber}}}
811
812\let\deepstructurenumbercommand\relax
813\let\deepstructuretitlecommand \relax
814
815\unexpanded\def\fullheadnumber
816  {\edef\currentheadlabeltag{\currentsectionblock\c!label}%
817   \dostarttagged\t!sectionnumber\empty
818   \labeltexts
819     {\headparameter\currentheadlabeltag}
820     {\ifx\deepstructurenumbercommand\relax
821        \structurenumber
822      \else
823        \normalexpanded{\noexpand\deepstructurenumbercommand{\structurenumber}}%
824      \fi}%
825   \dostoptagged}
826
827\unexpanded\def\fullheadtitle
828  {\dostarttagged\t!sectiontitle\empty
829   \ifx\deepstructuretitlecommand\relax
830     \structuretitle
831   \else
832     \normalexpanded{\noexpand\deepstructuretitlecommand{\structuretitle}}%
833   \fi
834   \dostoptagged}
835
836\let\currenthead        \empty
837\let\currentheadcoupling\empty
838\let\currentheadsection \empty
839\let\currentheadlevel   \!!zerocount
840\let\currentheadcounter \!!zerocount
841
842\let\strc_show_used\relax
843
844\installtextracker
845  {structures.showused}
846  {\let\strc_show_used\clf_showstructure}
847  {\let\strc_show_used\relax}
848
849\appendtoks
850    \strc_show_used
851\to \everystoptext
852
853\unexpanded\def\placeheadtext  {\dosingleempty\strc_sectioning_place_head_text  } % use with care
854\unexpanded\def\placeheadnumber{\dosingleempty\strc_sectioning_place_head_number} % use with care
855
856\unexpanded\def\strc_sectioning_report{\clf_reportstructure}
857
858\ifdefined\strc_rendering_initialize_style_and_color \else
859
860    \unexpanded\def\strc_rendering_initialize_style_and_color#1#2%
861      {\dontconvertfont
862       \useheadstyleandcolor\c!style\c!color
863       \useheadstyleandcolor#1#2%
864       \setupinterlinespace}
865
866\fi
867
868\def\strc_sectioning_place_head_text[#1]%
869  {\dontleavehmode
870   \begingroup
871   \unexpanded\def\\{\space}% messy here, but the default (and needs to be grouped)
872   \global\settrue\headisdisplay % triggers interlinespace checking
873   \edef\currenthead{#1}%
874   \strc_rendering_initialize_style_and_color\c!textstyle\c!textcolor
875   \relax
876   \getspecificstructuretitle{\thenamedheadlevel{#1}}%
877   \endgraf
878   \endgroup}
879
880\def\strc_sectioning_place_head_number[#1]%
881  {\dontleavehmode
882   \begingroup
883   \global\settrue\headisdisplay % triggers interlinespace checking
884   \edef\currenthead{#1}%
885   \strc_rendering_initialize_style_and_color\c!numberstyle\c!numbercolor
886   \relax
887   \getfullstructurenumber{\thenamedheadlevel{#1}}%
888   \endgraf
889   \endgroup}
890
891\ifdefined\triggerautostructurelevel \else \let\triggerautostructurelevel\relax \fi
892
893\newtoks\everybeforesectionheadhandle
894\newtoks\everyaftersectionheadhandle
895
896\def\strc_sectioning_handle#1#2#3% name data userdata (we can move #1 to the caller)
897  {\xdef\currenthead        {#1}%
898   \xdef\currentheadcoupling{\sectionheadcoupling\currenthead}%
899   \xdef\currentheadsection {\sectionheadsection \currentheadcoupling}%
900   \xdef\currentheadlevel   {\sectionlevel       \currentheadsection}%
901   %
902   %\writestatus\m!system{setup: \currenthead,\currentheadcoupling,\currentheadsection,\currentheadlevel}%
903   %
904   \strc_sectioning_initialize_autolevel
905   \strc_sectioning_initialize_increment
906   \strc_sectioning_initialize_placement
907   \strc_sectioning_initialize_number
908   %
909   \the\everybeforesectionheadhandle
910   %
911   % todo: also mark (for header)
912   %
913   % we might remove the lower level
914   %
915   % not here, after optional \page: \strc_sectioning_register{#1}{#2}{#3}%
916   %
917%    \xdef\currentheadcounter{\currentsectioncountervalue}% lua call
918   %
919   % \currentstructuresynchronize % will move
920   %
921   \let\getheadnumber\empty
922   \let\getheadtitle \empty
923   \let\getheadsyncs \empty
924   \ifconditional\c_strc_sectioning_increment
925     \ifconditional\c_strc_sectioning_place
926       \strc_sectioning_before_yes
927       \strc_sectioning_register{#1}{#2}{#3}% after optional \page
928       \strc_sectioning_report
929       \dostarttagged\t!sectioncaption\empty
930       \let\getheadsyncs\theheadsynchronization
931       \let\getheadtitle\fullheadtitle
932       \ifconditional\headshownumber
933         \let\getheadnumber\fullheadnumber
934         \strc_rendering_place_head_number_and_text
935       \else
936         \strc_rendering_place_head_text
937       \fi
938       \dostoptagged
939       \strc_sectioning_after_yes
940     \else\ifconditional\c_strc_sectioning_hidden
941       \strc_sectioning_register{#1}{#2}{#3}% after optional \page
942       \strc_sectioning_report
943       \dostarttagged\t!sectioncaption\empty
944       \let\getheadsyncs\theheadsynchronization
945       \ifconditional\c_strc_sectioning_section
946         \strc_rendering_place_head_section
947       \else
948         \strc_rendering_place_head_hidden % only something when tracing
949       \fi
950       \dostoptagged
951     \else
952       \strc_sectioning_before_nop % toegevoegd ivm subpaginanr / tug sheets
953       \strc_sectioning_register{#1}{#2}{#3}% after optional \page
954       \strc_sectioning_report
955       \dostarttagged\t!sectioncaption\empty
956       \let\getheadsyncs\theheadsynchronization
957       \strc_rendering_place_head_empty % just flush 'm
958       \dostoptagged
959       \strc_sectioning_after_nop
960     \fi\fi
961   \else
962     \ifconditional\c_strc_sectioning_place
963       \strc_sectioning_before_yes
964       \strc_sectioning_register{#1}{#2}{#3}% after optional \page
965       \strc_sectioning_report
966       \dostarttagged\t!sectioncaption\empty
967       \let\getheadsyncs\theheadsynchronization
968       \let\getheadtitle\fullheadtitle
969       \strc_rendering_place_head_text
970       \dostoptagged
971       \strc_sectioning_after_yes
972     \else\ifconditional\c_strc_sectioning_hidden
973       \strc_sectioning_register{#1}{#2}{#3}% after optional \page
974       \strc_sectioning_report
975       \let\getheadsyncs\theheadsynchronization
976       \dostarttagged\t!sectioncaption\empty
977       \ifconditional\c_strc_sectioning_section
978         \strc_rendering_place_head_section
979       \else
980         \strc_rendering_place_head_hidden % only something when tracing
981       \fi
982       \dostoptagged
983     \else
984       % do nothing / should be vbox to 0pt
985       \strc_sectioning_before_nop
986       \strc_sectioning_register{#1}{#2}{#3}% after optional \page
987       \strc_sectioning_report
988       \dostarttagged\t!sectioncaption\empty
989       \let\getheadsyncs\theheadsynchronization
990       \strc_rendering_place_head_empty % just flush 'm
991       \dostoptagged
992       \strc_sectioning_after_nop
993     \fi\fi
994   \fi
995   %
996   \the\everyaftersectionheadhandle
997   %
998   \setfalse\c_strc_sectioning_ignore_page
999   % ignorespaces prevents spaces creeping in when after=\dontleavehmode
1000   \dostarttagged\t!sectioncontent\empty
1001   \ifx\currentstructureplaceholder\empty
1002      \ifconditional\headisdisplay
1003        \doubleexpandafter\ignorespaces
1004      \else
1005        \doubleexpandafter\ignorepars
1006      \fi
1007   \else
1008      \expandafter\strc_sectioning_placeholder
1009   \fi}
1010
1011%D \starttyping
1012%D \startsubject[placeholder=todo,title=one]
1013%D     whatever one
1014%D \stopsubject
1015%D \stoptyping
1016
1017\def\strc_sectioning_placeholder
1018  {\placeholder[\currentstructureplaceholder]%
1019   \gobblenested{\e!start\currenthead}{\e!stop\currenthead}{\e!stop\currenthead}}
1020
1021% typesetting (the getters are public)
1022
1023\unexpanded\def\strc_rendering_place_head_number_and_text
1024  {\setheadmarking
1025   \getheadnumber/\getheadtitle
1026   \getheadsyncs}
1027
1028\unexpanded\def\strc_rendering_place_head_text
1029  {\setheadmarking
1030   \getheadtitle
1031   \getheadsyncs}
1032
1033\unexpanded\def\strc_rendering_place_head_empty
1034  {\setheadmarking
1035   \getheadsyncs}
1036
1037\installcorenamespace{hiddenheadattr}
1038\installcorenamespace{hiddenheadsync}
1039
1040% todo: when in the page builder we need to resolve the marking immediately
1041% because otherwise we have an async
1042
1043\newbox\b_sectioning_delayed
1044
1045\def\strc_sectioning_delayed_flush
1046  {\ifvoid\b_sectioning_delayed\else
1047     \smashedbox\b_sectioning_delayed
1048   \fi}
1049
1050\unexpanded\def\strc_rendering_place_head_section % see hidden below
1051  {\global\setbox\b_sectioning_delayed\hpack\bgroup
1052     \setmarking[\currentheadcoupling]{li::\currentstructurelistnumber}%
1053     \hpack\headreferenceattributes{}% also does the mark
1054     \theheadsynchronization
1055   \egroup}
1056
1057\unexpanded\def\strc_rendering_place_head_hidden % maybe trialtypesetting check
1058  {\setxvalue{\??hiddenheadattr\currenthead}%
1059     {\headreferenceattributes}% can be used when making a box
1060   \setxvalue{\??hiddenheadsync\currenthead}%
1061     {\noexpand\letgvalue{\??hiddenheadsync\currenthead}\relax
1062      \noexpand\setmarking[\currentheadcoupling]{li::\currentstructurelistnumber}%
1063      \hpack\headreferenceattributes{}% otherwise no destination ... maybe tag ref as hidden and fall back on page reference
1064      \theheadsynchronization}} % and it's a node anyway
1065
1066\def\synchronizehead           #1{\csname\??hiddenheadsync#1\endcsname}
1067\def\theheadreferenceattributes#1{\csname\??hiddenheadattr#1\endcsname}
1068
1069\unexpanded\def\placerawheaddata  [#1]{\synchronizehead{#1}}
1070\unexpanded\def\placerawheadtext  [#1]{\getspecificstructuretitle{\thenamedheadlevel{#1}}}
1071\unexpanded\def\placerawheadnumber[#1]{\getfullstructurenumber{\thenamedheadlevel{#1}}}
1072
1073\unexpanded\def\repeathead[#1]%
1074  {\begingroup
1075   \setupinteraction[\c!state=\v!stop]%
1076   \def\currenthead{#1}
1077   \strc_sectioning_initialize_placement
1078   \strc_sectioning_initialize_number
1079   \dostarttagged\t!sectioncaption\empty
1080   \let\getheadsyncs \relax
1081   \def\getheadtitle {\getmarking[#1]}
1082   \def\getheadnumber{\getmarking[#1\v!number]}
1083   \strc_sectioning_before_yes
1084   \ifconditional\headshownumber
1085      \strc_rendering_place_head_number_and_text
1086   \else
1087      \strc_rendering_place_head_text
1088   \fi
1089   \dostoptagged
1090   \strc_sectioning_after_yes
1091   \endgroup}
1092
1093% \setuphead[chapter][placehead=hidden]
1094% \chapter {test}
1095%
1096% %(\synchronizehead{chapter}) % \getheadsyncs
1097% %(\getfullstructurenumber{\thenamedheadlevel{chapter}})
1098% %(\getspecificstructuretitle{\thenamedheadlevel{chapter}})
1099%
1100% (\placerawheaddata  [chapter])
1101% (\placerawheadnumber[chapter])
1102% (\placerawheadtext  [chapter])
1103
1104% pagebreaks
1105
1106\letvalue{\??headmarknop\v!page   }\donothing
1107\setvalue{\??headmarknop\v!reset  }{\resetcurrentstructuremarks}
1108\letvalue{\??headmarknop\s!unknown}\donothing
1109
1110\letvalue{\??headmarkyes\v!page   }\donothing  % to be checked: {\resetcurrentstructuremarks}
1111\setvalue{\??headmarkyes\v!reset  }{\resetcurrentstructuremarks}
1112\letvalue{\??headmarkyes\s!unknown}\donothing
1113
1114\def\strc_sectioning_check_layout
1115  {\edef\p_page{\headparameter\c!page}%
1116   \ifx\p_page\empty
1117     \strc_sectioning_check_layout_nop
1118   \else
1119     \strc_sectioning_check_layout_yes
1120   \fi}
1121
1122\def\strc_sectioning_check_layout_nop
1123  {\expandnamespaceparameter\??headmarknop\headparameter\c!marking\s!unknown}
1124
1125\def\strc_sectioning_check_layout_yes
1126  {\page[\p_page]%
1127   \expandnamespaceparameter\??headmarkyes\headparameter\c!marking\s!unknown
1128   \edef\p_header{\headparameter\c!header}%
1129   \ifx\p_header\empty \else
1130     \doifelselayouttextline\v!header{\normalexpanded{\setuplayouttext[\v!header][\c!state=\p_header]}}\donothing
1131   \fi
1132   \edef\p_text{\headparameter\c!text}%
1133   \ifx\p_text\empty \else
1134     \doifelselayouttextline\v!text  {\normalexpanded{\setuplayouttext[\v!text  ][\c!state=\p_text  ]}}\donothing
1135   \fi
1136   \edef\p_footer{\headparameter\c!footer}%
1137   \ifx\p_footer\empty \else
1138     \doifelselayouttextline\v!footer{\normalexpanded{\setuplayouttext[\v!footer][\c!state=\p_footer]}}\donothing
1139   \fi}
1140
1141\newcount      \c_strc_sectioning_preceding_level     \c_strc_sectioning_preceding_level\plusone
1142\newconditional\c_strc_sectioning_auto_break          \settrue\c_strc_sectioning_auto_break
1143\newconditional\c_strc_sectioning_ignore_page
1144\newsignal     \s_strc_sectioning_continuous_signal
1145
1146\unexpanded\def\strc_sectioning_inject_continuous_signal
1147  {\ifhmode
1148     \hskip\s_strc_sectioning_continuous_signal\relax
1149   \fi}
1150
1151% \let\dotagsectionlevel\relax
1152
1153\def\strc_sectioning_before_yes
1154  {\strc_sectioning_check_before\strc_sectioning_handle_page_yes
1155   \headparameter\c!inbetween
1156   \dostarttaggedchained\t!section\currenthead\??head
1157%    \dotagsectionlevel
1158   }
1159
1160\def\strc_sectioning_before_nop
1161  {\strc_sectioning_check_before\strc_sectioning_handle_page_nop
1162   \headparameter\c!inbetween
1163   \dostarttagged\currenthead\empty} % this is a weird one .. needs checking
1164
1165\def\strc_sectioning_empty_correction
1166  {\ifconditional\c_strc_sectioning_empty
1167     % this needs checking
1168     \penalty\plustenthousand
1169     \vskip-\lineheight
1170     \kern\zeropoint
1171     \prevdepth\strutdepth
1172   \fi}
1173
1174\def\strc_sectioning_after_nop
1175  {}
1176
1177\def\strc_sectioning_check_before#1%
1178  {\ifhmode
1179     \scratchcounter\lastpenalty
1180     \unpenalty % no beauty in this
1181     \ifdim\lastskip=\s_strc_sectioning_continuous_signal
1182       % no page break
1183       \ifconditional\c_strc_sectioning_ignore_page
1184         \setfalse\c_strc_sectioning_ignore_page
1185       \else
1186         \global\c_strc_sectioning_preceding_level\currentheadlevel
1187         \nobreak
1188       \fi
1189     % \global\settrue\c_strc_rendering_continuous
1190     \else
1191       \penalty\scratchcounter
1192     % \global\setfalse\c_strc_rendering_continuous
1193       #1%
1194     \fi
1195   \else
1196   % \global\setfalse\c_strc_rendering_continuous
1197     #1%
1198   \fi}
1199
1200\def\currentsectioncountervalue {\clf_depthnumber\numexpr\thenamedheadlevel\currenthead\relax}
1201\def\previoussectioncountervalue{\clf_depthnumber\numexpr\thenamedheadlevel\currenthead+\minusone\relax}
1202
1203% \def\strc_sectioning_handle_page_nop
1204%   {\edef\p_continue{\headparameter\c!continue}%
1205%    \ifx\p_continue\v!yes
1206%      \ifnum\previoussectioncountervalue=\zerocount
1207%        \strc_sectioning_check_layout
1208%      \else\ifnum\currentsectioncountervalue>\zerocount
1209%        \strc_sectioning_check_layout
1210%      \fi\fi
1211%    \else
1212%      \strc_sectioning_check_layout
1213%    \fi}
1214
1215\def\currentsectioncountervalue {\clf_depthnumber\numexpr\thenamedheadlevel\currenthead\relax}
1216%def\previoussectioncountervalue{\clf_depthnumber\numexpr\thenamedheadlevel\currenthead+\minusone\relax}
1217\def\previoussectioncountervalue{\clf_depthnumber\numexpr\thenamedheadlevel\previoushead\relax}
1218
1219\let\previoushead\empty
1220
1221\def\strc_sectioning_handle_page_nop
1222  {\edef\p_continue{\headparameter\c!continue}%
1223   \ifx\p_continue\v!yes
1224     \ifx\currenthead\previoushead % not really needed
1225        \strc_sectioning_check_layout
1226     \else\ifnum\previoussectioncountervalue=\zerocount
1227        \strc_sectioning_check_layout
1228     \else\ifnum\currentsectioncountervalue>\zerocount
1229        \strc_sectioning_check_layout
1230     \fi\fi\fi
1231   \else
1232     \strc_sectioning_check_layout
1233   \fi
1234   \glet\previoushead\currenthead}
1235
1236% \def\strc_sectioning_handle_page_yes
1237%   {\ifconditional\c_strc_sectioning_ignore_page
1238%      \setfalse\c_strc_sectioning_ignore_page
1239%    \else
1240%      % beware, these numbers are not yet know here
1241%      \strc_sectioning_handle_page_nop
1242%      \edef\p_aligntitle{\headparameter\c!aligntitle}%
1243%      \ifx\p_aligntitle\v!float
1244%          \ifconditional\c_strc_sectioning_auto_break
1245%            \vspacing[\v!samepage-\currentheadlevel]%
1246%          \fi
1247%          \headparameter\c!before\relax
1248%          \indent
1249%      \else
1250%          \page_otr_command_flush_side_floats
1251%          \ifconditional\c_strc_sectioning_auto_break
1252%            \vspacing[\v!samepage-\currentheadlevel]%
1253%          \fi
1254%          \headparameter\c!before\relax
1255%      \fi
1256%      \global\c_strc_sectioning_preceding_level\currentheadlevel
1257%    \fi
1258%    \glet\previoushead\currenthead}
1259%
1260% \unexpanded\def\strc_sectioning_prevent_page_break% see strc-con
1261%   {\ifconditional\c_strc_sectioning_auto_break
1262%       \vspacing[\v!samepage-\the\numexpr\currentheadlevel+\plusone\relax]%
1263%    \fi}
1264%
1265% \def\strc_sectioning_after_yes
1266%   {\ifconditional\headisdisplay
1267%      \ifconditional\c_strc_sectioning_auto_break
1268%      % \vspacing[\v!samepage-\currentheadlevel]%
1269%        \vspacing[\v!samepage]%
1270%      \fi
1271%      \strc_sectioning_empty_correction
1272%      \headparameter\c!after
1273%    \fi}
1274
1275% This works better in columns ... but also elsewhere?
1276
1277\def\strc_sectioning_handle_page_yes
1278  {\ifconditional\c_strc_sectioning_ignore_page
1279     \setfalse\c_strc_sectioning_ignore_page
1280   \else
1281     % beware, these numbers are not yet know here
1282     \strc_sectioning_handle_page_nop
1283     \edef\p_aligntitle{\headparameter\c!aligntitle}%
1284     \ifx\p_aligntitle\v!float
1285         \ifconditional\c_strc_sectioning_auto_break
1286           \spac_vspacing_same_page\currentheadlevel\zerocount
1287         \fi
1288         \headparameter\c!before\relax
1289         \indent
1290     \else
1291         \page_otr_command_flush_side_floats
1292         \ifconditional\c_strc_sectioning_auto_break
1293           \spac_vspacing_same_page\currentheadlevel\zerocount
1294         \fi
1295         \headparameter\c!before\relax
1296     \fi
1297     \global\c_strc_sectioning_preceding_level\currentheadlevel
1298   \fi
1299   \glet\previoushead\currenthead}
1300
1301\def\strc_sectioning_depth_correction
1302  {\ifvmode
1303     \edef\p_depthcorrection{\headparameter\c!depthcorrection}%
1304     \ifx\p_depthcorrection\v!strut
1305       \prevdepth\strutdepth
1306     \fi
1307   \fi}
1308
1309\def\strc_sectioning_after_yes
1310  {\ifconditional\headisdisplay
1311     \ifconditional\c_strc_sectioning_auto_break
1312       \spac_vspacing_same_page\currentheadlevel\plusone
1313     \fi
1314     \strc_sectioning_empty_correction
1315     \headparameter\c!after
1316     \strc_sectioning_depth_correction
1317   \fi}
1318
1319\unexpanded\def\strc_sectioning_prevent_page_break % see strc-con
1320  {\ifconditional\c_strc_sectioning_auto_break
1321     \spac_vspacing_same_page\currentheadlevel\plustwo
1322   \fi}
1323
1324
1325% We do support negative numbers but it can have side effects that we won't catch:
1326%
1327% \chapter{some} \setupheadnumber[chapter][3] \chapter{more}
1328% \setupheadnumber[section][8] \section{b} \section{c} \setupheadnumber[section][-1] \section{d}
1329
1330\def\thenamedheadlevel#1%
1331  {\sectionlevel{\sectionheadsection{\sectionheadcoupling{#1}}}}
1332
1333\unexpanded\def\setupheadnumber
1334  {\dodoubleargument\strc_sectioning_setup_number}
1335
1336\def\strc_sectioning_setup_number[#1][#2]% todo: reset if at other level
1337  {\setstructurenumber{\thenamedheadlevel{#1}}{\number#2}}
1338
1339\def\currentheadnumber{0} % ==> \currentheadnumber
1340
1341\unexpanded\def\determineheadnumber[#1]%
1342  {\xdef\currentheadnumber{\getstructurenumber{\thenamedheadlevel{#1}}}}
1343
1344% The previous macro is been replaced by the expandable:
1345
1346\def\namedheadnumber      #1{\getstructurenumber    {\thenamedheadlevel{#1}}}
1347\def\somenamedheadnumber#1#2{\getsomestructurenumber{\thenamedheadlevel{#1}}{#2}}
1348
1349\unexpanded\def\headnumber
1350  {\dodoubleempty\strc_sectioning_number}
1351
1352\def\strc_sectioning_number[#1][#2]% simple case is just a number
1353  {\getsomefullstructurenumber{\iffirstargument\thenamedheadlevel{#1}\fi}{#2}}
1354
1355\unexpanded\def\someheadnumber
1356  {\dodoubleempty\strc_sectioning_number_some}
1357
1358\def\strc_sectioning_number_some[#1][#2]%
1359  {\dontleavehmode
1360   \begingroup
1361   \edef\currenthead{#1}%
1362   \getsomefullstructurenumber{\thenamedheadlevel{#1}}{#2}%
1363   \endgroup}
1364
1365\let\sectioncountervalue\structurevalue
1366
1367\def\currentheadtext{obsolete,\space use marks}
1368
1369% list references, will be redone in lua when we need it
1370
1371\let\startlistreferences\relax
1372\let\stoplistreferences \relax
1373
1374% experimental
1375
1376\newconditional\c_strc_sectioning_auto_levels
1377
1378\appendtoks
1379    \settrue\c_strc_sectioning_auto_levels
1380\to \everyenableelements
1381
1382\unexpanded\def\strc_sectioning_initialize_autolevel
1383  {\ifconditional\c_strc_sectioning_auto_levels
1384     \clf_autonextstructurelevel\currentheadlevel\relax
1385     \global\setfalse\c_strc_sectioning_auto_levels
1386   \fi}
1387
1388\unexpanded\def\triggerautostructurelevel
1389  {\global\settrue\c_strc_sectioning_auto_levels}
1390
1391\unexpanded\def\finalizeautostructurelevels
1392  {\clf_autofinishstructurelevels}
1393
1394\unexpanded\def\finalizeautostructurelevel
1395  {\dostoptagged
1396   \dostoptagged}
1397
1398\appendtoks
1399    \finalizeautostructurelevels
1400\to \everystoptext
1401
1402\stopcontextdefinitioncode
1403
1404\protect \endinput
1405