strc-sec.mkxl /size: 50 Kb    last modification: 2023-12-21 09:44
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\space
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 \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% 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    \space true\space % 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         \numexpr#1\relax} % level
336\permanent\def\getsomestructurenumber    #1#2{\clf_getsomestructurenumber     #1{#2}}           % level, what
337\permanent\def\getfullstructurenumber      #1{\clf_getfullstructurenumber     \numexpr#1\relax} % 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   ]
418
419\aliased\let\setupheads\setuphead % will go
420
421\appendtoks
422    \ifempty\currentheadparent
423        \edef\currentheaddefault{\headparameter\c!default}%
424        \edef\currentheadsection{\headparameter\c!section}%
425        \ifx\currenthead\currentheaddefault
426          \let\currentheadparent\currentheadsection
427        \orelse\ifempty\currentheaddefault
428          \let\currentheadparent\currentheadsection
429        \else
430          \let\currentheadparent\currentheaddefault
431        \fi
432        \normalexpanded {%
433            \setheadparameter{\c!label}{\currenthead}%
434            \setheadparameter{\c!coupling}{\currenthead}%
435            \setheadparameter{\s!parent}{\??head\currentheadparent}%
436            \definemarking[\currenthead]         [\currentheadsection]%
437            \definemarking[\currenthead\v!number][\currentheadsection]%
438            \setupmarking [\currenthead]         [\c!filtercommand=\noexpand\sectionheadmarkingtitle {\currenthead}]%
439            \setupmarking [\currenthead\v!number][\c!filtercommand=\noexpand\sectionheadmarkingnumber{\currenthead}]%
440        }%
441        \doifelselist\currenthead\donothing
442          {\definelist[\currenthead][\c!prefix=\v!no]}%
443        % we can't do this now for backward compatibility reasons
444      % \doifelselist\currenthead\donothing
445      %   {\normalexpanded{\definelist[\currenthead][\currentheadparent][\c!prefix=\v!no]}}%
446    \else
447        \normalexpanded {%
448            \setheadparameter{\c!label}{\currenthead}%
449            \setheadparameter{\c!coupling}{\currentheadparent}%
450            \definemarking[\currenthead]         [\currentheadparent]%
451            \definemarking[\currenthead\v!number][\currentheadparent\c!number]%
452        }%
453        \doifelselist\currenthead\donothing
454          {\normalexpanded{\definelist[\currenthead][\currentheadparent][\c!prefix=\v!no]}}%
455    \fi
456    \presetlabeltext[\currenthead=]%
457    \expand\everysetuphead
458\to \everydefinehead
459
460\newtoks\everyredefinehead
461
462\appendtoks
463    \expand\everyredefinehead
464\to \everydefinehead
465
466\appendtoks
467   \setstructurelevel\currenthead{\thenamedheadlevel\currenthead}%
468\to \everyredefinehead
469
470\mutable\lettonothing\currentsectionheadcoupling
471\mutable\lettonothing\currentsectionheadsection
472\mutable\lettonothing\currentsectionlevel
473
474\appendtoks
475    % beware, this is a global register
476    \begingroup
477    \edef\currentsectionheadcoupling{\sectionheadcoupling\currenthead}%
478    \edef\currentsectionheadsection {\sectionheadsection \currentsectionheadcoupling}%
479    \edef\currentsectionlevel       {\sectionlevel       \currentsectionheadsection}%
480    \clf_registersection {\currenthead} {
481        coupling {\currentsectionheadcoupling}
482        section  {\currentsectionheadsection}
483        level    \space \currentsectionlevel \space % space needed for parser
484        parent   {\currentheadparent}
485    }%
486    \endgroup
487\to \everyredefinehead
488
489\appendtoks
490   \frozen\instance\protected\edefcsname\e!start\currenthead\endcsname{\strc_sectioning_start[\currenthead]}%
491   \frozen\instance\protected\edefcsname\e!stop \currenthead\endcsname{\strc_sectioning_stop [\currenthead]}%
492\to \everydefinehead
493
494% so \subject as well as \section will need two commands when ownnumber
495% is used (one can disable it anyway for subject) .. this is not downward
496% compatible but better
497
498\appendtoks
499    \ifempty\currenthead
500      % top level
501    \orelse\ifcstok{\headparameter\c!ownnumber}\v!yes
502      \instance\protected\edefcsname\currenthead\endcsname{\strc_sectioning_handle_own[\currenthead]}
503    \else
504      \instance\protected\edefcsname\currenthead\endcsname{\strc_sectioning_handle_nop[\currenthead]}%
505    \fi
506\to \everysetuphead
507
508\permanent\protected\def\doredefinehead#1#2% called at lua end
509  {\push_macro_currenthead
510   \push_macro_currentheadparent
511   \cdef\currenthead{#1}%
512   \edef\currentheadparent{#2}%
513   \expand\everyredefinehead\relax
514   \pop_macro_currentheadparent
515   \pop_macro_currenthead}
516
517\mutable\lettonothing\currentnamedsection
518
519\installmacrostack\currentnamedsection
520
521% structure sections (the parents of chapter etc)
522
523\mutable\lettonothing\firstsectionname
524\mutable\lettonothing\lastsectionname
525
526%aliased\let\resetallstructuremarks            \relax
527%aliased\let\resetcurrentstructuremarks        \relax
528\aliased\let\resetcurrentstructuremarkswithpage\relax
529
530\permanent\protected\def\resetallstructuremarks            {\clearmarking[\firstsectionname]} % will become option (was \v!section-1)
531\permanent\protected\def\resetcurrentstructuremarks        {\clearmarking[\lastsectionname]}  % will become option
532%permanent\protected\def\resetcurrentstructuremarkswithpage{\clearmarking[\lastsectionname]}  % will become option
533
534% We could use a commandhandler here but sections are somewhat special in the
535% sense that we have two ways of chaining: the main section (levels) as well
536% as rendering (head).
537
538% -2 = text
539% -1 = manual
540%  0 = block
541% +1 = structurelevel 1 .. n
542
543\newinteger\maxstructuredepth
544
545\permanent\def\sectionlevel#1%
546  {\csname\??headlevel\ifcsname\??headlevel#1\endcsname#1\else\v!none\fi\endcsname}
547
548\permanent\def\namedsectionlevel#1#2% direct indirect
549  {\csname\??headlevel
550     \ifcsname\??headlevel#1\endcsname
551       #1%
552     \orelse\ifcsname\??headlevel#2\endcsname
553       #2%
554     \else
555       \v!none
556     \fi
557   \endcsname}
558
559\permanent\def\xthenamedheadlevel#1%
560  {\namedsectionlevel{#1}{\sectionheadsection{\sectionheadcoupling{#1}}}}
561
562\defcsname\??headlevel\v!block\endcsname{0}
563\defcsname\??headlevel\v!none \endcsname{-1}
564\defcsname\??headlevel\v!text \endcsname{-2}
565\defcsname\??headlevel\v!head \endcsname{-3}
566
567\newtoks\everydefinesection
568
569\mutable\lettonothing\currentsection % historic alias
570
571\permanent\protected\def\definesection[#1]%
572  {\ifcsname\??headlevel#1\endcsname \else
573     \cdef\currenthead{#1}%
574     \let\currentsection\currenthead % just an alias
575     \global\advanceby\maxstructuredepth\plusone
576     \edefcsname\??headlevel#1\endcsname{\the\maxstructuredepth}%
577     \setstructurelevel{#1}{\sectionlevel{#1}}%
578     \normalexpanded{\setheadparameter{\s!parent}{\??head\lastsectionname}}% TO BE CHECKED, WE HAVE A HELPER
579     \expand\everydefinesection
580     % so far for these default inheritances
581     \definemarking[#1]%
582     \ifnum\maxstructuredepth>\plusone
583       \normalexpanded{\relatemarking[#1][\lastsectionname]}% so, the parent will reset the child
584     \fi
585     \enforced\permanent\xdef\lastsectionname{#1}%
586     \ifempty\firstsectionname
587        \enforced\glet\firstsectionname\lastsectionname
588     \fi
589   \fi}
590
591\permanent\tolerant\protected\def\setupsection[#1]#*[#S#2]#*[#S#3]%
592  {\ifparameter#1\else
593     \push_macro_currenthead
594     \cdef\currenthead{\ifcsname\??headlevel#1\endcsname#1\else\sectionheadsection{#1}\fi}%
595     \ifparameter#3\or
596       \cdef\currenthead{\currenthead#2}% not used at any more in mkiv (sets now)
597       \setupcurrenthead[#3]%
598     \else
599       \setupcurrenthead[#2]%
600     \fi
601     \pop_macro_currenthead
602   \fi}
603
604% we share the parameters as sections are roots of heads so eventually we can
605% consider \definesection -> \definehead with one argument
606
607\appendtoks
608    % This is a rather practical default that we don't want to
609    % be part of the parent chain lookup mechanism; it's also
610    % mkii compatible. Somewhat weird that it's part of the
611    % top level structure but it will be flattened anyway.
612  % \let\currenthead\currentsection % hm
613    \setheadparameter\c!textstyle  {\directheadparameter\c!style}%
614    \setheadparameter\c!textcolor  {\directheadparameter\c!color}%
615    \setheadparameter\c!numberstyle{\directheadparameter\c!style}%
616    \setheadparameter\c!numbercolor{\directheadparameter\c!color}%
617\to \everydefinesection
618
619% head -> head
620
621\permanent\def\sectionheadmarkingtitle #1#2{\clf_markingtitle {#1}{#2}} % can be done at lua end
622\permanent\def\sectionheadmarkingnumber#1#2{\clf_markingnumber{#1}{#2}} % can be done at lua end
623
624\permanent\def\sectionheadcoupling#1{\namedheadparameter{#1}\c!coupling}
625\permanent\def\sectionheadsection #1{\namedheadparameter{#1}\c!section}
626
627% head construction
628
629\newconditional\currentstructureown
630
631\newtoks\everybeforehead % hook, todo: before/after keys
632\newtoks\everyafterhead  % hook, todo: before/after keys
633
634\permanent\tolerant\protected\def\strc_sectioning_handle_own[#1]#*[#2]#:#*#=#*#=% [ref] {nr} {title}
635  {\currentstructureown\conditionaltrue
636   \triggerautostructurelevel
637   \strc_sectioning_handle{#1}{\c!reference={#2},\c!ownnumber={#3},\c!title={#4}}{}} % name ref nr title --
638
639\permanent\tolerant\protected\def\strc_sectioning_handle_nop[#1]#*[#2]%  [ref] {title} / for taco: [key=value] variant
640  {\currentstructureown\conditionalfalse
641   \triggerautostructurelevel
642   \ifhastok={#2}%
643     \expandafter\strc_sectioning_handle_nop_indeed_yes
644   \else
645     \expandafter\strc_sectioning_handle_nop_indeed_nop
646   \fi
647   {#1}{#2}}
648
649\def\strc_sectioning_handle_nop_indeed_yes#1#2%
650  {\strc_sectioning_handle{#1}{#2}{}}
651
652\def\strc_sectioning_handle_nop_indeed_nop#1#2#3%
653  {\strc_sectioning_handle{#1}{\c!reference={#2},\c!title={#3}}{}} % name ref nr title --
654
655\permanent\tolerant\protected\def\strc_sectioning_start[#1]#*[#S#2]#*[#S#3]% for the moment no grouping, too annoying with page breaks
656  {\push_macro_currentnamedsection
657   \push_macro_currentstructurereferenceprefix
658   \edef\currentnamedsection{#1}%
659   \currentstructureown\conditionalfalse
660  %\globalpushmacro\currenthead % this does not work out well
661   \xdef\currenthead{#1}%
662   \setsystemmode\currenthead % new, also here now
663   \headparameter\c!beforesection % beware, no users vars set yet
664   \expand\everybeforehead
665   \strc_sectioning_handle{#1}{#2}{#3}% name -- -- -- userdata (we might move the tagged to here)
666   % potential: \bgroup (can be optional: grouped = yes)
667   \headparameter\c!insidesection}
668
669\permanent\protected\def\strc_sectioning_stop[#1]% !!! also used at lua end
670  {\dostoptagged
671   \dostoptagged
672   % potential: \egroup
673  %\globalpopmacro\currenthead % so we do a hard recover
674   \xdef\currenthead{#1}% recover
675   \headparameter\c!aftersection
676   \expand\everyafterhead
677   \resetsystemmode\currenthead
678   \pop_macro_currentstructurereferenceprefix
679   \pop_macro_currentnamedsection} % new, also here now
680
681\aliased\let\dostarthead\strc_sectioning_start % used at lua end
682\aliased\let\dostophead \strc_sectioning_stop  % used at lua end
683
684% todo: add grouping but where: before/after trickery .. probably inside because one can always add
685% grouping to the before/after settings
686
687\aliased\let\startnamedsection\strc_sectioning_start
688
689\permanent\protected\def\stopnamedsection
690  {\normalexpanded{\strc_sectioning_stop[\currentnamedsection]}}
691
692% \newconditional\structurereversesectionnumbers  % todo: key/val
693
694\newconditional\c_strc_sectioning_to_list
695\newconditional\c_strc_sectioning_increment
696\newconditional\c_strc_sectioning_place
697\newconditional\c_strc_sectioning_empty
698\newconditional\c_strc_sectioning_hidden
699\newconditional\c_strc_sectioning_section
700
701\newconditional\headshownumber  % public
702\newconditional\headisdisplay   % public
703\newconditional\headissomewhere % public
704
705\defcsname\??headincrement\v!yes  \endcsname{\c_strc_sectioning_increment\conditionaltrue\c_strc_sectioning_to_list\conditionaltrue}
706\defcsname\??headincrement\v!no   \endcsname{\c_strc_sectioning_increment\conditionalfalse\c_strc_sectioning_to_list\conditionalfalse}
707\defcsname\??headincrement\v!list \endcsname{\c_strc_sectioning_increment\conditionalfalse\c_strc_sectioning_to_list\conditionaltrue}
708\defcsname\??headincrement\s!empty\endcsname{\c_strc_sectioning_increment\conditionaltrue\c_strc_sectioning_to_list\conditionaltrue}
709
710\protected\def\strc_sectioning_initialize_increment
711  {\edef\currentheadincrement{\headparameter\c!incrementnumber}%
712   \ifcsname\??headincrement\currentheadincrement\endcsname
713     \lastnamedcs
714   \else
715     \c_strc_sectioning_increment\conditionaltrue
716     \c_strc_sectioning_to_list\conditionaltrue
717     % \filterheadnumber
718   \fi}
719
720\permanent\protected\def\filterheadnumber
721  {\c_strc_sectioning_increment\conditionaltrue
722   \c_strc_sectioning_to_list\conditionaltrue
723   \ifempty\currentproduct
724     % todo : filter from other toc (number, file, title)
725     % use  : \currentheadincrement as spec
726   \fi}
727
728\defcsname\??headplace\v!yes\endcsname
729  {\c_strc_sectioning_empty\conditionalfalse
730   \c_strc_sectioning_place\conditionaltrue
731   \c_strc_sectioning_hidden\conditionalfalse
732   \c_strc_sectioning_section\conditionalfalse}
733
734\defcsname\??headplace\v!empty\endcsname
735  {\c_strc_sectioning_empty\conditionaltrue
736   \c_strc_sectioning_place\conditionaltrue
737   \c_strc_sectioning_hidden\conditionalfalse
738   \c_strc_sectioning_section\conditionalfalse}
739
740\defcsname\??headplace\v!no\endcsname
741  {\c_strc_sectioning_empty\conditionaltrue
742   \c_strc_sectioning_place\conditionalfalse
743   \c_strc_sectioning_hidden\conditionalfalse
744   \c_strc_sectioning_section\conditionalfalse}
745
746\defcsname\??headplace\v!hidden\endcsname
747  {\c_strc_sectioning_empty\conditionaltrue
748   \c_strc_sectioning_place\conditionalfalse
749   \c_strc_sectioning_hidden\conditionaltrue
750   \c_strc_sectioning_section\conditionalfalse}
751
752\defcsname\??headplace\v!section\endcsname
753  {\c_strc_sectioning_empty\conditionaltrue
754   \c_strc_sectioning_place\conditionalfalse
755   \c_strc_sectioning_hidden\conditionaltrue
756   \c_strc_sectioning_section\conditionaltrue}
757
758\protected\def\strc_sectioning_initialize_placement
759  {\expandnamespaceparameter\??headplace\headparameter\c!placehead\v!yes}
760
761\newmode\v!sectionnumber
762
763\def\strc_sectioning_set_head_number_content   % was: \dosetstructureheadnumbercontent
764  {\setsystemmode\v!sectionnumber
765   \headshownumber\conditionaltrue} % why ?
766
767\def\strc_sectioning_reset_head_number_content % was: \doresetstructureheadnumbercontent
768  {\resetsystemmode\v!sectionnumber
769   \headshownumber\conditionalfalse} % why ?
770
771\protected\def\strc_sectioning_initialize_number
772  {\ifcstok{\sectionblockparameter\c!number}\v!yes
773      \ifcstok{\headparameter\c!number}\v!yes
774        \headshownumber\conditionaltrue
775      \else
776        \headshownumber\conditionalfalse
777      \fi
778   \else
779     \headshownumber\conditionalfalse
780   \fi}
781
782% Beware, we do need some node for anchoring marks and normally a zwnj will
783% do but it interferes so we deal with it at the \LUA\ end.
784
785\newtoks\everyheadsynchronization
786
787\aliased\let\currentstructuresynchronize\donothing
788
789\appendtoks
790    \currentstructuresynchronize
791    \enforced\glet\currentstructuresynchronize\donothing
792\to \everyheadsynchronization
793
794
795\permanent\protected\def\theheadsynchronization % public
796  {% no, interferes: \signalcharacter
797   \expand\everyheadsynchronization
798   % new, this might move to a better place, e.g. first in the box
799   \currentstructureextradata
800   \lettonothing\currentstructureextradata
801   % done (can be used for e.g. index entries)
802  }
803
804% BEWARE: \marking[section]{my text} does not work as we use list indices instead
805% so we need a 'keep track of raw set option' (or maybe a funny internal prefix)
806
807\permanent\protected\def\setheadmarking % li:: so that we can use \marking[section]{Taco needed this}
808  {\strc_sectioning_delayed_flush
809   \normalexpanded{\setmarking[\currenthead]{li::\currentstructurelistnumber}}}
810
811\mutable\let\deepstructurenumbercommand\relax
812\mutable\let\deepstructuretitlecommand \relax
813
814\permanent\protected\def\fullheadnumber
815  {\edef\currentheadlabeltag{\currentsectionblock\c!label}%
816   \dostarttagged\t!sectionnumber\empty
817   \labeltexts
818     {\headparameter\currentheadlabeltag}
819     {\ifrelax\deepstructurenumbercommand
820        \structurenumber
821      \else
822        \normalexpanded{\noexpand\deepstructurenumbercommand{\structurenumber}}%
823      \fi}%
824   \dostoptagged}
825
826\permanent\protected\def\fullheadtitle
827  {\dostarttagged\t!sectiontitle\empty
828   \ifrelax\deepstructuretitlecommand
829     \structuretitle
830   \else
831     \normalexpanded{\noexpand\deepstructuretitlecommand{\structuretitle}}%
832   \fi
833   \dostoptagged}
834
835\mutable\lettonothing\currenthead
836\mutable\lettonothing\currentheadcoupling
837\mutable\lettonothing\currentheadsection
838
839\mutable\let\currentheadlevel   \!!zerocount
840\mutable\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\protected\def\strc_sectioning_report{\clf_reportstructure}
854
855\ifdefined\strc_rendering_initialize_style_and_color \else
856
857    \protected\def\strc_rendering_initialize_style_and_color#1#2%
858      {\dontconvertfont
859       \useheadstyleandcolor\c!style\c!color
860       \useheadstyleandcolor#1#2%
861       \setupinterlinespace}
862
863\fi
864
865\permanent\tolerant\protected\def\placeheadtext[#1]%
866  {\dontleavehmode
867   \begingroup
868   \enforced\permanent\protected\def\\{\space}% messy here, but the default (and needs to be grouped)
869   \global\headisdisplay\conditionaltrue % triggers interlinespace checking
870   \cdef\currenthead{#1}% maybe only when #1 is given
871   \strc_rendering_initialize_style_and_color\c!textstyle\c!textcolor
872   \relax
873   \getspecificstructuretitle{\thenamedheadlevel{#1}}%
874   \endgraf
875   \endgroup}
876
877\permanent\tolerant\protected\def\placeheadnumber[#1]%
878  {\dontleavehmode
879   \begingroup
880   \global\headisdisplay\conditionaltrue % triggers interlinespace checking
881   \cdef\currenthead{#1}% maybe only when #1 is given
882   \strc_rendering_initialize_style_and_color\c!numberstyle\c!numbercolor
883   \relax
884   \getfullstructurenumber{\thenamedheadlevel{#1}}%
885   \endgraf
886   \endgroup}
887
888\ifdefined\triggerautostructurelevel \else \let\triggerautostructurelevel\relax \fi
889
890\newtoks\everybeforesectionheadhandle
891\newtoks\everyaftersectionheadhandle
892
893\mutable\lettonothing\getheadnumber
894\mutable\lettonothing\getheadtitle
895\mutable\lettonothing\getheadsyncs
896
897\def\strc_sectioning_handle#1#2#3% name data userdata (we can move #1 to the caller)
898  {\xdef\currenthead        {#1}%
899   \xdef\currentheadcoupling{\sectionheadcoupling\currenthead}%
900   \xdef\currentheadsection {\sectionheadsection \currentheadcoupling}%
901   \xdef\currentheadlevel   {\sectionlevel       \currentheadsection}%
902   %
903   %\writestatus\m!system{setup: \currenthead,\currentheadcoupling,\currentheadsection,\currentheadlevel}%
904   %
905   \strc_sectioning_initialize_autolevel
906   \strc_sectioning_initialize_increment
907   \strc_sectioning_initialize_placement
908   \strc_sectioning_initialize_number
909   %
910   \expand\everybeforesectionheadhandle
911   %
912   % todo: also mark (for header)
913   %
914   % we might remove the lower level
915   %
916   % not here, after optional \page: \strc_sectioning_register{#1}{#2}{#3}%
917   %
918%    \xdef\currentheadcounter{\currentsectioncountervalue}% lua call
919   %
920   % \currentstructuresynchronize % will move
921   %
922   \lettonothing\getheadnumber
923   \lettonothing\getheadtitle
924   \lettonothing\getheadsyncs
925   \ifconditional\c_strc_sectioning_increment
926     \ifconditional\c_strc_sectioning_place
927       \strc_sectioning_before_yes
928       \strc_sectioning_register{#1}{#2}{#3}% after optional \page
929       \strc_sectioning_report
930       \dostarttagged\t!sectioncaption\empty
931       \let\getheadsyncs\theheadsynchronization
932       \let\getheadtitle\fullheadtitle
933       \ifconditional\headshownumber
934         \let\getheadnumber\fullheadnumber
935         \strc_rendering_place_head_number_and_text
936       \else
937         \strc_rendering_place_head_text
938       \fi
939       \dostoptagged
940       \strc_sectioning_after_yes
941     \orelse\ifconditional\c_strc_sectioning_hidden
942       \strc_sectioning_register{#1}{#2}{#3}% after optional \page
943       \strc_sectioning_report
944       \dostarttagged\t!sectioncaption\empty
945       \let\getheadsyncs\theheadsynchronization
946       \ifconditional\c_strc_sectioning_section
947         \strc_rendering_place_head_section
948       \else
949         \strc_rendering_place_head_hidden % only something when tracing
950       \fi
951       \dostoptagged
952     \else
953       \strc_sectioning_before_nop % toegevoegd ivm subpaginanr / tug sheets
954       \strc_sectioning_register{#1}{#2}{#3}% after optional \page
955       \strc_sectioning_report
956       \dostarttagged\t!sectioncaption\empty
957       \let\getheadsyncs\theheadsynchronization
958       \strc_rendering_place_head_empty % just flush 'm
959       \dostoptagged
960       \strc_sectioning_after_nop
961     \fi
962   \else
963     \ifconditional\c_strc_sectioning_place
964       \strc_sectioning_before_yes
965       \strc_sectioning_register{#1}{#2}{#3}% after optional \page
966       \strc_sectioning_report
967       \dostarttagged\t!sectioncaption\empty
968       \let\getheadsyncs\theheadsynchronization
969       \let\getheadtitle\fullheadtitle
970       \strc_rendering_place_head_text
971       \dostoptagged
972       \strc_sectioning_after_yes
973     \orelse\ifconditional\c_strc_sectioning_hidden
974       \strc_sectioning_register{#1}{#2}{#3}% after optional \page
975       \strc_sectioning_report
976       \let\getheadsyncs\theheadsynchronization
977       \dostarttagged\t!sectioncaption\empty
978       \ifconditional\c_strc_sectioning_section
979         \strc_rendering_place_head_section
980       \else
981         \strc_rendering_place_head_hidden % only something when tracing
982       \fi
983       \dostoptagged
984     \else
985       % do nothing / should be vbox to 0pt
986       \strc_sectioning_before_nop
987       \strc_sectioning_register{#1}{#2}{#3}% after optional \page
988       \strc_sectioning_report
989       \dostarttagged\t!sectioncaption\empty
990       \let\getheadsyncs\theheadsynchronization
991       \strc_rendering_place_head_empty % just flush 'm
992       \dostoptagged
993       \strc_sectioning_after_nop
994     \fi
995   \fi
996   %
997   \expand\everyaftersectionheadhandle
998   %
999   \c_strc_sectioning_ignore_page\conditionalfalse
1000   % ignorespaces prevents spaces creeping in when after=\dontleavehmode
1001   \dostarttagged\t!sectioncontent\empty
1002   \unless\ifempty\currentstructureplaceholder
1003     \expandafter\strc_sectioning_placeholder
1004   \orelse\ifconditional\headisdisplay
1005     \expandafter\ignorespaces
1006   \else
1007     \expandafter\ignorepars
1008   \fi}
1009
1010%D \starttyping
1011%D \startsubject[placeholder=todo,title=one]
1012%D     whatever one
1013%D \stopsubject
1014%D \stoptyping
1015
1016\def\strc_sectioning_placeholder
1017  {\placeholder[\currentstructureplaceholder]%
1018   \gobblenested{\e!start\currenthead}{\e!stop\currenthead}{\e!stop\currenthead}}
1019
1020% typesetting (the getters are public)
1021
1022\protected\def\strc_rendering_place_head_number_and_text
1023  {\setheadmarking
1024   \getheadnumber/\getheadtitle
1025   \getheadsyncs}
1026
1027\protected\def\strc_rendering_place_head_text
1028  {\setheadmarking
1029   \getheadtitle
1030   \getheadsyncs}
1031
1032\protected\def\strc_rendering_place_head_empty
1033  {\setheadmarking
1034   \getheadsyncs}
1035
1036\installcorenamespace{hiddenheadattr}
1037\installcorenamespace{hiddenheadsync}
1038
1039% todo: when in the page builder we need to resolve the marking immediately
1040% because otherwise we have an async
1041
1042\newbox\b_sectioning_delayed
1043
1044\def\strc_sectioning_delayed_flush
1045  {\ifvoid\b_sectioning_delayed\else
1046     \smashedbox\b_sectioning_delayed
1047   \fi}
1048
1049\ifdefined\??markingclass % uses a node, so we need to embed / bind
1050
1051    \protected\def\strc_rendering_place_head_section % see hidden below
1052      {\global\setbox\b_sectioning_delayed\hpack\bgroup
1053         \hpack\headreferenceattributes\bgroup
1054            \setmarking[\currentheadcoupling]{li::\currentstructurelistnumber}% also does the mark
1055         \egroup
1056         \theheadsynchronization
1057       \egroup}
1058
1059    \protected\def\strc_rendering_place_head_hidden % maybe trialtypesetting check
1060      {\xdefcsname\??hiddenheadattr\currenthead\endcsname
1061         {\headreferenceattributes}% can be used when making a box
1062       \xdefcsname\??hiddenheadsync\currenthead\endcsname
1063         {\noexpand\gletcsname\??hiddenheadsync\currenthead\endcsname\relax
1064       % {\noexpand\gletcsname\??hiddenheadsync\currenthead\endcsname\relax
1065          \hpack\headreferenceattributes\bgroup
1066            \noexpand\setmarking[\currentheadcoupling]{li::\currentstructurelistnumber}% otherwise no destination ... maybe tag ref as hidden and fall back on page reference
1067          \egroup
1068          \theheadsynchronization}} % and it's a node anyway
1069
1070\else % uses attributes so no interference
1071
1072    \protected\def\strc_rendering_place_head_section % see hidden below
1073      {\global\setbox\b_sectioning_delayed\hpack\bgroup
1074         \setmarking[\currentheadcoupling]{li::\currentstructurelistnumber}%
1075         \hpack\headreferenceattributes{}% also does the mark
1076         \theheadsynchronization
1077       \egroup}
1078
1079    \protected\def\strc_rendering_place_head_hidden % maybe trialtypesetting check
1080      {\xdefcsname\??hiddenheadattr\currenthead\endcsname
1081         {\headreferenceattributes}% can be used when making a box
1082       \xdefcsname\??hiddenheadsync\currenthead\endcsname
1083         {\noexpand\gletcsname\??hiddenheadsync\currenthead\endcsname\relax
1084          \noexpand\setmarking[\currentheadcoupling]{li::\currentstructurelistnumber}%
1085          \hpack\headreferenceattributes{}% otherwise no destination ... maybe tag ref as hidden and fall back on page reference
1086          \theheadsynchronization}} % and it's a node anyway
1087
1088\fi
1089
1090\permanent\def\synchronizehead           #1{\begincsname\??hiddenheadsync#1\endcsname}
1091\permanent\def\theheadreferenceattributes#1{\begincsname\??hiddenheadattr#1\endcsname}
1092
1093\permanent\protected\def\placerawheaddata  [#1]{\synchronizehead{#1}}
1094\permanent\protected\def\placerawheadtext  [#1]{\getspecificstructuretitle{\thenamedheadlevel{#1}}}
1095\permanent\protected\def\placerawheadnumber[#1]{\getfullstructurenumber{\thenamedheadlevel{#1}}}
1096
1097\permanent\protected\def\repeathead[#1]%
1098  {\begingroup
1099   \setupinteraction[\c!state=\v!stop]%
1100   \cdef\currenthead{#1}
1101   \strc_sectioning_initialize_placement
1102   \strc_sectioning_initialize_number
1103   \dostarttagged\t!sectioncaption\empty
1104   \let\getheadsyncs \relax
1105   \def\getheadtitle {\getmarking[#1]}
1106   \def\getheadnumber{\getmarking[#1\v!number]}
1107   \strc_sectioning_before_yes
1108   \ifconditional\headshownumber
1109      \strc_rendering_place_head_number_and_text
1110   \else
1111      \strc_rendering_place_head_text
1112   \fi
1113   \dostoptagged
1114   \strc_sectioning_after_yes
1115   \endgroup}
1116
1117% \setuphead[chapter][placehead=hidden]
1118% \chapter {test}
1119%
1120% %(\synchronizehead{chapter}) % \getheadsyncs
1121% %(\getfullstructurenumber{\thenamedheadlevel{chapter}})
1122% %(\getspecificstructuretitle{\thenamedheadlevel{chapter}})
1123%
1124% (\placerawheaddata  [chapter])
1125% (\placerawheadnumber[chapter])
1126% (\placerawheadtext  [chapter])
1127
1128% pagebreaks
1129
1130\letcsname\??headmarknop\v!page   \endcsname\donothing
1131\defcsname\??headmarknop\v!reset  \endcsname{\resetcurrentstructuremarks}
1132\letcsname\??headmarknop\s!unknown\endcsname\donothing
1133
1134\letcsname\??headmarkyes\v!page   \endcsname\donothing  % to be checked: {\resetcurrentstructuremarks}
1135\defcsname\??headmarkyes\v!reset  \endcsname{\resetcurrentstructuremarks}
1136\letcsname\??headmarkyes\s!unknown\endcsname\donothing
1137
1138\def\strc_sectioning_check_layout
1139  {\edef\p_page{\headparameter\c!page}%
1140   \ifempty\p_page
1141     \strc_sectioning_check_layout_nop
1142   \else
1143     \strc_sectioning_check_layout_yes
1144   \fi}
1145
1146\def\strc_sectioning_check_layout_nop
1147  {\expandnamespaceparameter\??headmarknop\headparameter\c!marking\s!unknown}
1148
1149\def\strc_sectioning_check_layout_yes
1150  {\page[\p_page]%
1151   \expandnamespaceparameter\??headmarkyes\headparameter\c!marking\s!unknown
1152   \edef\p_header{\headparameter\c!header}%
1153   \ifempty\p_header \else
1154     \doifelselayouttextline\v!header{\normalexpanded{\setuplayouttext[\v!header][\c!state=\p_header]}}\donothing
1155   \fi
1156   \edef\p_text{\headparameter\c!text}%
1157   \ifempty\p_text \else
1158     \doifelselayouttextline\v!text  {\normalexpanded{\setuplayouttext[\v!text  ][\c!state=\p_text  ]}}\donothing
1159   \fi
1160   \edef\p_footer{\headparameter\c!footer}%
1161   \ifempty\p_footer \else
1162     \doifelselayouttextline\v!footer{\normalexpanded{\setuplayouttext[\v!footer][\c!state=\p_footer]}}\donothing
1163   \fi}
1164
1165\newinteger    \c_strc_sectioning_preceding_level     \c_strc_sectioning_preceding_level\plusone
1166\newconditional\c_strc_sectioning_auto_break          \c_strc_sectioning_auto_break\conditionaltrue
1167\newconditional\c_strc_sectioning_ignore_page
1168\newboundary   \c_strc_sectioning_boundary
1169
1170\protected\def\strc_sectioning_inject_continuous_signal
1171  {\ifhmode
1172     \boundary\c_strc_sectioning_boundary
1173   \fi}
1174
1175% \let\dotagsectionlevel\relax
1176
1177\def\strc_sectioning_before_yes
1178  {\strc_sectioning_check_before\strc_sectioning_handle_page_yes
1179   \headparameter\c!inbetween
1180   \dostarttaggedchained\t!section\currenthead\??head
1181%    \dotagsectionlevel
1182   }
1183
1184\def\strc_sectioning_before_nop
1185  {\strc_sectioning_check_before\strc_sectioning_handle_page_nop
1186   \headparameter\c!inbetween
1187   \dostarttagged\currenthead\empty} % this is a weird one .. needs checking
1188
1189\def\strc_sectioning_empty_correction
1190  {\ifconditional\c_strc_sectioning_empty
1191     % this needs checking
1192     \penalty\plustenthousand
1193     \vskip-\lineheight
1194     \kern\zeropoint
1195     \prevdepth\strutdepth
1196   \fi}
1197
1198\def\strc_sectioning_after_nop
1199  {}
1200
1201\def\strc_sectioning_check_before#1%
1202  {\ifhmode
1203     \scratchcounter\lastpenalty
1204     \unpenalty % no beauty in this
1205     \ifnum\lastboundary=\c_strc_sectioning_boundary
1206       % no page break
1207       \ifconditional\c_strc_sectioning_ignore_page
1208         \c_strc_sectioning_ignore_page\conditionalfalse
1209       \else
1210         \global\c_strc_sectioning_preceding_level\currentheadlevel
1211         \nobreak
1212       \fi
1213     % \global\c_strc_rendering_continuous\conditionaltrue
1214     \else
1215       \penalty\scratchcounter
1216     % \global\c_strc_rendering_continuous\conditionalfalse
1217       #1%
1218     \fi
1219   \else
1220   % \global\c_strc_rendering_continuous\conditionalfalse
1221     #1%
1222   \fi}
1223
1224%permanent\def\currentsectioncountervalue {\clf_depthnumber\numexpr\thenamedheadlevel\currenthead\relax}
1225%permanent\def\previoussectioncountervalue{\clf_depthnumber\numexpr\thenamedheadlevel\currenthead+\minusone\relax}
1226
1227\permanent\def\currentsectioncountervalue {\clf_depthnumber\numexpr\thenamedheadlevel\currenthead\relax}
1228%permanent\def\previoussectioncountervalue{\clf_depthnumber\numexpr\thenamedheadlevel\currenthead+\minusone\relax}
1229\permanent\def\previoussectioncountervalue{\clf_depthnumber\numexpr\thenamedheadlevel\previoushead\relax}
1230
1231\mutable\lettonothing\previoushead
1232
1233\def\strc_sectioning_handle_page_nop
1234  {\unless\ifcstok{\headparameter\c!continue}\v!yes
1235     \strc_sectioning_check_layout
1236   \orelse\ifx\currenthead\previoushead % not really needed
1237     \strc_sectioning_check_layout
1238   \orelse\ifnum\previoussectioncountervalue=\zerocount
1239     \strc_sectioning_check_layout
1240   \orelse\ifnum\currentsectioncountervalue>\zerocount
1241     \strc_sectioning_check_layout
1242   \fi
1243   \glet\previoushead\currenthead}
1244
1245
1246\def\strc_sectioning_handle_page_yes
1247  {\ifconditional\c_strc_sectioning_ignore_page
1248     \c_strc_sectioning_ignore_page\conditionalfalse
1249   \else
1250     % beware, these numbers are not yet know here
1251     \strc_sectioning_handle_page_nop
1252     \ifcstok{\headparameter\c!aligntitle}\v!float
1253       \ifconditional\c_strc_sectioning_auto_break
1254         \spac_vspacing_same_page\currentheadlevel\zerocount
1255       \fi
1256       \headparameter\c!before\relax
1257       \indent % hm, not a clever one?
1258     \else
1259       \page_otr_command_flush_side_floats
1260       \ifconditional\c_strc_sectioning_auto_break
1261         \spac_vspacing_same_page\currentheadlevel\zerocount
1262       \fi
1263       \headparameter\c!before\relax
1264     \fi
1265     \global\c_strc_sectioning_preceding_level\currentheadlevel
1266   \fi
1267   \glet\previoushead\currenthead}
1268
1269\def\strc_sectioning_depth_correction
1270  {\ifvmode
1271     \ifcstok{\headparameter\c!depthcorrection}\v!strut
1272       \prevdepth\strutdepth
1273     \fi
1274   \fi}
1275
1276\def\strc_sectioning_after_yes
1277  {\ifconditional\headisdisplay
1278     \ifconditional\c_strc_sectioning_auto_break
1279       \spac_vspacing_same_page\currentheadlevel\plusone
1280     \fi
1281     \strc_sectioning_empty_correction
1282     \headparameter\c!after
1283     \strc_sectioning_depth_correction
1284   \fi}
1285
1286\protected\def\strc_sectioning_prevent_page_break % see strc-con
1287  {\ifconditional\c_strc_sectioning_auto_break
1288     \spac_vspacing_same_page\currentheadlevel\plustwo
1289   \fi}
1290
1291% We do support negative numbers but it can have side effects that we won't catch:
1292%
1293% \chapter{some} \setupheadnumber[chapter][3] \chapter{more}
1294% \setupheadnumber[section][8] \section{b} \section{c} \setupheadnumber[section][-1] \section{d}
1295
1296\permanent\def\thenamedheadlevel#1%
1297  {\sectionlevel{\sectionheadsection{\sectionheadcoupling{#1}}}}
1298
1299\permanent\tolerant\protected\def\setupheadnumber[#1]#*[#2]% todo: reset if at other level
1300  {\setstructurenumber{\thenamedheadlevel{#1}}{\number#2}}
1301
1302\permanent\protected\def\determineheadnumber[#1]%
1303  {\xdef\currentheadnumber{\getstructurenumber{\thenamedheadlevel{#1}}}}
1304
1305% The previous macro is been replaced by the expandable:
1306
1307\permanent\def\namedheadnumber      #1{\getstructurenumber    {\thenamedheadlevel{#1}}}
1308\permanent\def\somenamedheadnumber#1#2{\getsomestructurenumber{\thenamedheadlevel{#1}}{#2}}
1309
1310\permanent\tolerant\protected\def\headnumber[#1]#*[#2]%
1311  {\getsomefullstructurenumber{\thenamedheadlevel{#1}}{#2}}
1312
1313\permanent\tolerant\protected\def\someheadnumber[#1]#*[#2]%
1314  {\dontleavehmode
1315   \begingroup
1316   \cdef\currenthead{#1}%
1317   \getsomefullstructurenumber{\thenamedheadlevel{#1}}{#2}%
1318   \endgroup}
1319
1320% \mutable\def\currentheadtext{obsolete,\space use marks}
1321
1322% list references, will be redone in lua when we need it
1323
1324% \let\startlistreferences\relax
1325% \let\stoplistreferences \relax
1326
1327% experimental
1328
1329\newconditional\c_strc_sectioning_auto_levels
1330
1331\appendtoks
1332    \c_strc_sectioning_auto_levels\conditionaltrue
1333\to \everyenableelements
1334
1335\protected\def\strc_sectioning_initialize_autolevel
1336  {\ifconditional\c_strc_sectioning_auto_levels
1337     \clf_autonextstructurelevel\currentheadlevel\relax
1338     \global\c_strc_sectioning_auto_levels\conditionalfalse
1339   \fi}
1340
1341\permanent\protected\def\triggerautostructurelevel
1342  {\global\c_strc_sectioning_auto_levels\conditionaltrue}
1343
1344\permanent\protected\def\finalizeautostructurelevels
1345  {\clf_autofinishstructurelevels}
1346
1347\permanent\protected\def\finalizeautostructurelevel
1348  {\dostoptagged
1349   \dostoptagged}
1350
1351\appendtoks
1352    \finalizeautostructurelevels
1353\to \everystoptext
1354
1355%D Defined at the \LUA\ end:
1356
1357% \doifelsefirstsectionpage{chapter}{do this}{or that} % in pagebody building
1358
1359\stopcontextdefinitioncode
1360
1361\protect \endinput
1362