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