%D \module
%D   [       file=strc-sec,
%D        version=2008.10.20,
%D          title=\CONTEXT\ Structure Macros,
%D       subtitle=Sectioning,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

%D In retrospect I should have gone futher and move more to the
%D \LUA\ end but here we are now. Maybe some day.

\writestatus{loading}{ConTeXt Structure Macros / Sectioning}

\unprotect

\startcontextdefinitioncode

\installcorenamespace{structure}

\installdirectcommandhandler \??structure {structure} % unchecked, so we need to initialize used parameters

\setupstructure % not a user command so we might need to change the name
  [\c!number=,
   \c!level=,
   \c!name=,
   \c!title=,
   \c!bookmark=,      % no real need, default to empty anyway
   \c!marking=,       % no real need, default to empty anyway
   \c!list=,          % no real need, default to empty anyway
   \c!referencetext=, % no real need, default to empty anyway
   \c!label=,         % no real need, default to empty anyway
   \c!coupling=,
   \c!ownnumber=,
 % \c!interaction=\v!list,
   \c!sectionseparatorset=\s!default,
   \c!sectionconversionset=\s!default,
   \c!sectionstopper=,
   \c!sectionstarter=,
   \c!sectionsegments=,
   \c!sectionresetset=,
   \c!reference=,
   \c!backreference=,
   \c!expansion=\v!no,
   \c!xmlsetup=,
   \s!catcodes=,
   \c!saveinlist=\v!yes]

% maybe flags for list, bm, mark

\def\m_strc_references_prefix_yes{+}
\def\m_strc_references_prefix_nop{-}

\mutable\lettonothing\currentstructurereferenceprefix
\mutable\lettonothing\currentstructurereferencetext

\installglobalmacrostack\currentstructurereferenceprefix

\def\strc_sectioning_set_reference_prefix
  {\ifempty\currentstructurereferenceprefix
     % nothing
   \orelse\ifx\currentstructurereferenceprefix\m_strc_references_prefix_yes
     \ifempty\currentstructurereference
       \global\advanceby\prefixcounter \plusone % temp here
       \setupglobalreferenceprefix[\the\prefixcounter]%
     \else
       \setupglobalreferenceprefix[\currentstructurereference]%
     \fi
   \orelse\ifx\currentstructurereferenceprefix\m_strc_references_prefix_nop
     \setupglobalreferenceprefix[]%
   \else
     \setupglobalreferenceprefix[\currentstructurereferenceprefix]%
   \fi
   \glet\currentstructurereferenceprefix\referenceprefix}

% why xdef ?

\setupstructure
  [\c!label={\headparameter{\currentsectionblock\c!label}},
   \c!incrementnumber=\ifconditional\c_strc_sectioning_increment\v!yes\else\v!no\fi, % not that needed
   \c!saveinlist=\ifconditional\c_strc_sectioning_to_list\v!yes\else\v!no\fi,
   \c!level=\currentheadlevel,
   \c!number=\ifconditional\c_strc_sectioning_increment\ifconditional\headshownumber\v!yes\else\v!no\fi\else\v!no\fi,
   \c!expansion=\headparameter\c!expansion,
   \c!xmlsetup=\headparameter\c!xmlsetup,
   \s!catcodes=\headparameter\s!catcodes,
   \c!sectionresetset=\headparameter\c!sectionresetset,
   \c!sectionseparatorset=\headparameter\c!sectionseparatorset,
   \c!sectionconversionset=\headparameter\c!sectionconversionset,
   \c!sectionconversion=\headparameter\c!conversion, % just for compatibility
   \c!sectionstarter=\headparameter\c!sectionstarter,
   \c!sectionstopper=\headparameter\c!sectionstopper,
   \c!sectionset=\headparameter\c!sectionset,
   \c!sectionsegments=\headparameter\c!sectionsegments,
   \c!reference=\headparameter\c!reference,
   \c!referenceprefix=\headparameter\c!referenceprefix,
   \c!criterium=\headparameter\c!criterium]

% see lists/neat-001.tex for usage of:

\permanent\def\namedstructureheadlocation#1% expandable, maybe [#1]
  {\csname\??savedinternalreference\ifcsname\??savedinternalreference#1\endcsname#1\else\s!default\fi\endcsname}

\mutable\lettonothing\currentheadbackreference
\mutable\lettonothing\currentheaddefault
\mutable\lettonothing\currentheadincrement
\mutable\lettonothing\currentheadinteraction
\mutable\lettonothing\currentheadlabeltag
\mutable\lettonothing\currentheadrenderingalternative
\mutable\lettonothing\currentheadrenderingsetup
\mutable\lettonothing\currentheadtext

\mutable\let\currentheadnumber\!!zerocount

% zeros:
%
% \setuphead[subsection][criterium=all]
%
% \dorecurse{3} {
%     \chapter{Blabla}                 \subsection{bla 1 1} \subsection{bla 1 2}
%                      \section{bla 2} \subsection{bla 2 1} \subsection{bla 2 2}
% }

\mutable\lettonothing\currentstructureextradata

% all these globals ...

\protected\def\strc_sectioning_register#1#2#3% #1=interfaced-settings, #2=optional user data (not yet supported)
  {\begingroup
   \setupstructure[\c!name={#1},#2]%
   \xdef\currentstructurename           {\structureparameter\c!name}%
   \xdef\currentstructurecoupling       {\structureparameter\c!coupling}%
   \xdef\currentstructureownnumber      {\structureparameter\c!ownnumber}% optional own number
   \xdef\currentstructurelevel          {\structureparameter\c!level}%
   \edef\currentstructureexpansion      {\structureparameter\c!expansion}%
   \xdef\currentstructurexmlsetup       {\structureparameter\c!xmlsetup}%
   \xdef\currentstructurecatcodes       {\structureparameter\s!catcodes}%
   \xdef\currentstructurelabel          {\structureparameter\c!label}%
   \xdef\currentstructurereference      {\structureparameter\c!reference}%
   \xdef\currentstructurereferenceprefix{\structureparameter\c!referenceprefix}%
   \xdef\currentstructurebackreference  {\structureparameter\c!backreference}%
   \xdef\currentstructureshownumber     {\structureparameter\c!number}%
   \xdef\currentstructuresaveinlist     {\structureparameter\c!saveinlist}%
   \xdef\currentstructureincrementnumber{\structureparameter\c!incrementnumber}%
   \xdef\currentstructureplaceholder    {\structureparameter\c!placeholder}%
   \xdef\currentstructureextradata      {\structureparameter\c!extradata}%
   \ifx\currentstructureexpansion\s!xml
     \xmlstartraw
       \xdef\currentstructuretitle        {\structureparameter\c!title}%
       \xdef\currentstructurebookmark     {\structureparameter\c!bookmark}%
       \xdef\currentstructuremarking      {\structureparameter\c!marking}%
       \xdef\currentstructurelist         {\structureparameter\c!list}%
       \xdef\currentstructurereferencetext{\structureparameter\c!referencetext}%
     \xmlstopraw
     \iflocation \ifempty\currentstructurebookmark
       \xdef\currentstructurebookmark{\prerolltostring{\currentstructuretitle}}%
     \fi \fi
     \ifempty\currentstructurelist
       \glet\currentstructurelist\currentstructuretitle
     \fi
     \glet\currentstructurecoding\s!xml
   \else
     \ifx\currentstructureexpansion\v!yes
       \xdef\currentstructuretitle        {\structureparameter\c!title}%
       \xdef\currentstructurebookmark     {\structureparameter\c!bookmark}%
       \xdef\currentstructuremarking      {\structureparameter\c!marking}%
       \xdef\currentstructurelist         {\structureparameter\c!list}%
       \xdef\currentstructurereferencetext{\structureparameter\c!referencetext}%
       \iflocation \ifempty\currentstructurebookmark
        \xdef\currentstructurebookmark{\prerolltostring{\currentstructuretitle}}%
       \fi \fi
     \else
       \xdef\currentstructuretitle        {\detokenizedstructureparameter\c!title}%
       \xdef\currentstructurebookmark     {\detokenizedstructureparameter\c!bookmark}%
       \xdef\currentstructuremarking      {\detokenizedstructureparameter\c!marking}%
       \xdef\currentstructurelist         {\detokenizedstructureparameter\c!list}%
       \xdef\currentstructurereferencetext{\detokenizedstructureparameter\c!referencetext}%
       \iflocation \ifempty\currentstructurebookmark
         \xdef\currentstructurebookmark{\prerolltostring{\structureparameter\c!title}}%
       \fi \fi
     \fi
     \ifempty\currentstructurelist
       \glet\currentstructurelist\currentstructuretitle
     \fi
     \glet\currentstructurecoding\s!tex
   \fi
   \iflocation \ifempty\currentstructurebookmark \orelse \ifx\currentstructurebookmark\currentstructuretitle \else
    %\showmessage\m!structures3{{\currentstructurebookmark}}% comma interference
     \writestatus{\m!structures}{bookmark:\space\currentstructurebookmark}%
   \fi \fi
   \setnextinternalreference
   \storeinternalreference\currentstructurename{\the\locationcount}%
   \strc_sectioning_set_reference_prefix
   \clf_setsectionentry
        references {
            internal      \locationcount
          % block         {\currentsectionblock}
            prefix        {\currentstructurereferenceprefix}
            reference     {\currentstructurereference}
            backreference {\currentstructurebackreference}
        }
        directives {
            resetset {\structureparameter\c!sectionresetset}
        }
        metadata {
            kind      \s!section
            name      \currentstructurename
            catcodes  \ifempty\currentstructurecatcodes\catcodetable\else\csname\currentstructurecatcodes\endcsname\fi\relaxedspace
            coding    {\currentstructurecoding}
        \ifx\currentstructurecoding\s!xml
            xmlroot   {\xmldocument}
        \fi
        \ifempty\currentstructurexmlsetup \else
            xmlsetup  {\currentstructurexmlsetup}
        \fi
        \ifx\currentstructuresaveinlist\v!no
            nolist true\relaxedspace
        \fi
        \ifx\currentstructureincrementnumber\v!yes
            increment {\currentstructureincrementnumber}
        \fi
        }
        titledata {
            label     {\detokenize\expandafter{\currentstructurelabel}}
            title     {\detokenize\expandafter{\currentstructuretitle}}
% alternative 1:
%             label     {\detokened\currentstructurelabel}
%             title     {\detokened\currentstructuretitle}
% alternative 2, detokened scanner:
%             label     \currentstructurelabel
%             title     \currentstructuretitle
        \ifx\currentstructurebookmark\currentstructuretitle \else
            bookmark  {\detokenize\expandafter{\currentstructurebookmark}}
        \fi
        \ifx\currentstructuremarking\currentstructuretitle \else
            marking   {\detokenize\expandafter{\currentstructuremarking}}
        \fi
        \ifx\currentstructuresaveinlist\v!no \else
          \ifx\currentstructurelist\currentstructuretitle \else
            list      {\detokenize\expandafter{\currentstructurelist}}
          \fi
        \fi
        \ifx\currentstructurereferencetext\currentstructuretitle \else
            reference {\detokenize\expandafter{\currentstructurereferencetext}}
        \fi
        }
        numberdata {
          % block         {\currentsectionblock}
        \ifx\currentstructureshownumber\v!no
            hidenumber true\relaxedspace % space needed for parser
        \fi
            separatorset  {\structureparameter\c!sectionseparatorset}
            conversionset {\structureparameter\c!sectionconversionset}
            conversion    {\structureparameter\c!sectionconversion}
            starter       {\structureparameter\c!sectionstarter}
            stopper       {\structureparameter\c!sectionstopper}
            set           {\structureparameter\c!sectionset}
            segments      {\structureparameter\c!sectionsegments}
            ownnumber     {\currentstructureownnumber}
            language      {\currentlanguage}% for the moment, needed for bookmarks conversion
            criterium     {\structureparameter\c!criterium}
        }
        userdata {\detokenize{#3}}% will be converted to table at the lua end
   \relax
   \xdef\currentstructurelistnumber{\clf_currentsectiontolist}%
 % \currentstructuresynchronize has to be called someplace, since it introduces a node
   \setstructuresynchronization\currentstructurelistnumber
   \endgroup}

\mutable\let\currentsectioncountervalue \!!zerocount % redefined later
\mutable\let\previoussectioncountervalue\!!zerocount % redefined later

% We can access the (stored) data with the following macros.
%
% \def\MyHeadCommand  #1#2{\framed{#1}\framed{#2 / \structureuservariable{subtitle}}}
% \def\MyListCommand#1#2#3{\externalfigure[\structurelistuservariable{figure}][height=5mm]#2}
%
% \setuphead[chapter][command=\MyHeadCommand]
% \setuplist[chapter][alternative=command,command=\MyListCommand]
%
% \starttext
%     \setupheadertexts[chapter]
%     \setupinteraction[state=start]
%     \placebookmarks[chapter]
%     \placelist[chapter]
%     \startchapter[ownnumber=10,title=Ton,list=Hans,marking=Kees,bookmark=Bram][figure=cow.pdf,subtitle=oeps]
%     \stopchapter
% \stoptext

% defined at the lua end:

%permanent\def\structurenumber               {\clf_structurenumber}
%permanent\def\structuretitle                {\clf_structuretitle}
%permanent\def\structurevariable           #1{\clf_structurevariable         {#1}}
%permanent\def\structureuservariable       #1{\clf_structureuservariable     {#1}}
%permanent\def\structurecatcodedget        #1{\clf_structurecatcodedget      {#1}}    % bad name
%permanent\def\structuregivencatcodedget #1#2{\clf_structuregivencatcodedget {#1}#2 } % bad name
%permanent\def\structureautocatcodedget  #1#2{\clf_structureautocatcodedget  {#1}{#2}}
%permanent\def\namedstructurevariable    #1#2{\clf_namedstructurevariable    {#1}{#2}}
%permanent\def\namedstructureuservariable#1#2{\clf_namedstructureuservariable{#1}{#2}}

% compatibility issue:
%
% \def\setfullsectionnumber #1{}
% \def\preparefullnumber    #1{}
% \def\fullsectionnumber    {1--1--1}
% \def\makesectionnumber    [#1]{}
% \def\makesectionformat    {}
% \def\sectionformat        {1--1-1-1-1-1-1}
% \def\composedsectionnumber{}
% \def\@@kolist{}

% \setuphead[section]   [separator=\separatorlist{?,!,*}]
% \setuphead[subsection][separator=\separatorlist{??,!!,**}]
%
% \let\spr\separatorlist % this will enable this feature
%
% \setuphead[section]   [separator={?,!,*}]
% \setuphead[subsection][separator={??,!!,**}]
%
% \setupheads[separator={A,B,C,D,E,F}]
% \chapter{test}
% \section{test} \subsection{test} \subsection{test}
% \section{test} \subsection{test} \subsection{test}

% lua interface / names and interface might change

% \newconditional\c_strc_rendering_continuous % not used (mkii ?)

% defined at the lua end:
%
%permanent\def\setstructurelevel         #1#2{\clf_setstructurelevel         {#1}{#2}} % name, level|parent
%permanent\def\getstructurelevel           #1{\clf_getstructurelevel         {#1}}     % name
%permanent\def\setstructurenumber        #1#2{\clf_setstructurenumber         #1{#2}}  % level, number (+/-)
%permanent\def\getstructurenumber          #1{\clf_getstructurenumber         {#1}}    % level
%permanent\def\getsomestructurenumber    #1#2{\clf_getsomestructurenumber     #1{#2}}  % level, what
%permanent\def\getfullstructurenumber      #1{\clf_getfullstructurenumber     {#1}}    % level
%permanent\def\getsomefullstructurenumber#1#2{\clf_getsomefullstructurenumber #1{#2}}  % level, what

\permanent\def\getspecificstructuretitle   #1{\clf_getspecificstructuretitle {#1}{\headparameter\s!catcodes}}

% structure heads (like \startchapter)

% \c!deeptextcommand, \c!deepnumbercommand: undefined !
% \c!before \c!after \c!distance
% \c!page \c!header  \c!text \c!footer=,
% \c!numbercommand \c!textcommand \c!ownnumber \c!number
% \c!file \c!grid \c!margintext
% \c!expansion \c!xmlsetup \s!catcode

\installcorenamespace{head}
\installcorenamespace{headlevel}
\installcorenamespace{headincrement}
\installcorenamespace{headplace}
\installcorenamespace{headmarkyes}
\installcorenamespace{headmarknop}

\installcommandhandler \??head {head} \??head

\installmacrostack\currenthead
\installmacrostack\currentheadparent

\setuphead [%
    %\c!after=,
    %\c!align=,
    %\c!aligntitle=,
    \c!alternative=\v!normal,
    %\c!before=,
    %\c!color=,
    %\c!command=,
    \c!continue=\v!yes,
    %\c!coupling=,
    %\c!deepnumbercommand=,
    %\c!deeptextcommand=,
    %\c!default=,
    \c!distance=\zeropoint,
    \c!textdistance=\zeropoint,
    \c!textwidth=\zeropoint,   % signal too
    \c!numberwidth=\zeropoint, % signal too
    \c!width=\zeropoint,       % signal too
    \c!expansion=\v!no,
    %\c!file=,
    %\c!footer=,
    %\c!grid=,
    \c!hang=\v!none,
    %\c!header=,
    \c!incrementnumber=\v!yes,
    \c!indentnext=\v!no,
    %\c!label=,
    %\c!limittext=\languageparameter\c!limittext,
    \c!margin=\zeropoint,
    %\c!margintext=,
    \c!number=\v!yes,
    \c!numbercolor=\headparameter\c!color,
    \c!textcolor=\headparameter\c!color,
    \c!numberstyle=\headparameter\c!style,
    \c!textstyle=\headparameter\c!style,
    %\c!numbercommand=,
    %\c!textcommand=,
    \c!ownnumber=\v!no,
    %\c!page=,
    \c!placehead=\v!yes,
    \c!sectionconversionset=\s!default,
    \c!sectionnumber=\v!yes,
    %\c!sectionsegments=,
    \c!sectionseparatorset=\s!default,
    \c!sectionset=\v!all,
    \c!interlinespace=,
    %\c!sectionstopper=,
    %\c!sectionstarter=,
    %\c!strut=,
    %\c!style=,
    %\c!text=,
    %\c!tolerance=,
    %\c!beforesection=\directsetup{document:\currenthead:start},  % these might become defaults i.e. acpect document: namespace
    %\c!insidesection=\directsetup{document:\currenthead:inside}, % these might become defaults i.e. acpect document: namespace
    %\c!aftersection=\directsetup{document:\currenthead:stop},    % these might become defaults i.e. acpect document: namespace
    %\c!beforehead=, % here userdata is known
    %\c!afterhead=,
   ]

\aliased\let\setupheads\setuphead % will go

\appendtoks
    \ifempty\currentheadparent
        \edef\currentheaddefault{\headparameter\c!default}%
        \edef\currentheadsection{\headparameter\c!section}%
        \ifx\currenthead\currentheaddefault
          \let\currentheadparent\currentheadsection
        \orelse\ifempty\currentheaddefault
          \let\currentheadparent\currentheadsection
        \else
          \let\currentheadparent\currentheaddefault
        \fi
        \expanded {%
            \setheadparameter{\c!label}{\currenthead}%
            \setheadparameter{\c!coupling}{\currenthead}%
            \setheadparameter{\s!parent}{\??head\currentheadparent}%
            \definemarking[\currenthead]         [\currentheadsection]%
            \definemarking[\currenthead\v!number][\currentheadsection]%
            \setupmarking [\currenthead]         [\c!filtercommand=\noexpand\sectionheadmarkingtitle {\currenthead}]%
            \setupmarking [\currenthead\v!number][\c!filtercommand=\noexpand\sectionheadmarkingnumber{\currenthead}]%
        }%
        \doifelselist\currenthead\donothing
          {\definelist[\currenthead][\c!prefix=\v!no]}%
        % we can't do this now for backward compatibility reasons
      % \doifelselist\currenthead\donothing
      %   {\expanded{\definelist[\currenthead][\currentheadparent][\c!prefix=\v!no]}}%
    \else
        \expanded {%
            \setheadparameter{\c!label}{\currenthead}%
            \setheadparameter{\c!coupling}{\currentheadparent}%
        }%
        \ifcstok{\headparameter\c!marking}\v!new % WS: so its own class
          \expanded {%
              \definemarking[\currenthead]
              \definemarking[\currenthead\v!number]
              \setupmarking [\currenthead]         [\c!filtercommand=\noexpand\sectionheadmarkingtitle {\currenthead}]%
              \setupmarking [\currenthead\v!number][\c!filtercommand=\noexpand\sectionheadmarkingnumber{\currenthead}]%
          }%
          \letheadparameter\c!marking\empty
        \else
          \expanded {%
              \definemarking[\currenthead]         [\currentheadparent]%
              \definemarking[\currenthead\v!number][\currentheadparent\c!number]%
          }%
        \fi
        \doifelselist\currenthead\donothing
          {\expanded{\definelist[\currenthead][\currentheadparent][\c!prefix=\v!no]}}%
    \fi
    \presetlabeltext[\currenthead=]%
    \expand\everysetuphead
\to \everydefinehead

\newtoks\everyredefinehead

\appendtoks
    \expand\everyredefinehead
\to \everydefinehead

\appendtoks
   \setstructurelevel\currenthead{\thenamedheadlevel\currenthead}%
\to \everyredefinehead

\mutable\lettonothing\currentsectionheadcoupling
\mutable\lettonothing\currentsectionheadsection
\mutable\lettonothing\currentsectionlevel

\appendtoks
    % beware, this is a global register
    \begingroup
    \edef\currentsectionheadcoupling{\sectionheadcoupling\currenthead}%
    \edef\currentsectionheadsection {\sectionheadsection \currentsectionheadcoupling}%
    \edef\currentsectionlevel       {\sectionlevel       \currentsectionheadsection}%
    \clf_registersection {\currenthead} {
        coupling {\currentsectionheadcoupling}
        section  {\currentsectionheadsection}
        level    \currentsectionlevel \relaxedspace % space needed for parser
        parent   {\currentheadparent}
    }%
    \endgroup
\to \everyredefinehead

\appendtoks
   \protected\frozen\instance\edefcsname\e!start\currenthead\endcsname{\strc_sectioning_start[\currenthead]}%
   \protected\frozen\instance\edefcsname\e!stop \currenthead\endcsname{\strc_sectioning_stop [\currenthead]}%
\to \everydefinehead

% so \subject as well as \section will need two commands when ownnumber
% is used (one can disable it anyway for subject) .. this is not downward
% compatible but better

\appendtoks
    \ifempty\currenthead
      % top level
    \orelse\ifcstok{\headparameter\c!ownnumber}\v!yes
      \protected\instance\edefcsname\currenthead\endcsname{\strc_sectioning_handle_own[\currenthead]}
    \else
      \protected\instance\edefcsname\currenthead\endcsname{\strc_sectioning_handle_nop[\currenthead]}%
    \fi
\to \everysetuphead

\permanent\protected\def\doredefinehead#1#2% called at lua end
  {\push_macro_currenthead
   \push_macro_currentheadparent
   \cdef\currenthead{#1}%
   \edef\currentheadparent{#2}%
   \expand\everyredefinehead\relax
   \pop_macro_currentheadparent
   \pop_macro_currenthead}

\mutable\lettonothing\currentnamedsection

\installmacrostack\currentnamedsection

% structure sections (the parents of chapter etc)

\mutable\lettonothing\firstsectionname
\mutable\lettonothing\lastsectionname

%aliased\let\resetallstructuremarks            \relax
%aliased\let\resetcurrentstructuremarks        \relax
\aliased\let\resetcurrentstructuremarkswithpage\relax

\permanent\protected\def\resetallstructuremarks            {\clearmarking[\firstsectionname]} % will become option (was \v!section-1)
\permanent\protected\def\resetcurrentstructuremarks        {\clearmarking[\lastsectionname]}  % will become option
%permanent\protected\def\resetcurrentstructuremarkswithpage{\clearmarking[\lastsectionname]}  % will become option

% We could use a commandhandler here but sections are somewhat special in the
% sense that we have two ways of chaining: the main section (levels) as well
% as rendering (head).

% -2 = text
% -1 = manual
%  0 = block
% +1 = structurelevel 1 .. n

\newinteger\maxstructuredepth

\permanent\def\sectionlevel#1%
  {\csname\??headlevel\ifcsname\??headlevel#1\endcsname#1\else\v!none\fi\endcsname}

\permanent\def\namedsectionlevel#1#2% direct indirect
  {\csname\??headlevel
     \ifcsname\??headlevel#1\endcsname
       #1%
     \orelse\ifcsname\??headlevel#2\endcsname
       #2%
     \else
       \v!none
     \fi
   \endcsname}

\permanent\def\xthenamedheadlevel#1%
  {\namedsectionlevel{#1}{\sectionheadsection{\sectionheadcoupling{#1}}}}

\defcsname\??headlevel\v!block\endcsname{0}
\defcsname\??headlevel\v!none \endcsname{-1}
\defcsname\??headlevel\v!text \endcsname{-2}
\defcsname\??headlevel\v!head \endcsname{-3}

\newtoks\everydefinesection

\mutable\lettonothing\currentsection % historic alias

\permanent\protected\def\definesection[#1]%
  {\ifcsname\??headlevel#1\endcsname \else
     \cdef\currenthead{#1}%
     \let\currentsection\currenthead % just an alias
     \global\advanceby\maxstructuredepth\plusone
     \edefcsname\??headlevel#1\endcsname{\the\maxstructuredepth}%
     \setstructurelevel{#1}{\sectionlevel{#1}}%
     \expanded{\setheadparameter{\s!parent}{\??head\lastsectionname}}% TO BE CHECKED, WE HAVE A HELPER
     \expand\everydefinesection
     % so far for these default inheritances
     \definemarking[#1]%
     \ifnum\maxstructuredepth>\plusone
       \expanded{\relatemarking[#1][\lastsectionname]}% so, the parent will reset the child
     \fi
     \enforced\permanent\xdef\lastsectionname{#1}%
     \ifempty\firstsectionname
        \enforced\glet\firstsectionname\lastsectionname
     \fi
   \fi}

\permanent\tolerant\protected\def\setupsection[#1]#*[#S#2]#*[#S#3]%
  {\ifparameter#1\else
     \push_macro_currenthead
     \cdef\currenthead{\ifcsname\??headlevel#1\endcsname#1\else\sectionheadsection{#1}\fi}%
     \ifparameter#3\or
       \cdef\currenthead{\currenthead#2}% not used at any more in mkiv (sets now)
       \setupcurrenthead[#3]%
     \else
       \setupcurrenthead[#2]%
     \fi
     \pop_macro_currenthead
   \fi}

% we share the parameters as sections are roots of heads so eventually we can
% consider \definesection -> \definehead with one argument

\appendtoks
    % This is a rather practical default that we don't want to
    % be part of the parent chain lookup mechanism; it's also
    % mkii compatible. Somewhat weird that it's part of the
    % top level structure but it will be flattened anyway.
  % \let\currenthead\currentsection % hm
    \setheadparameter\c!textstyle  {\directheadparameter\c!style}%
    \setheadparameter\c!textcolor  {\directheadparameter\c!color}%
    \setheadparameter\c!numberstyle{\directheadparameter\c!style}%
    \setheadparameter\c!numbercolor{\directheadparameter\c!color}%
\to \everydefinesection

% head -> head

\permanent\def\sectionheadmarkingtitle #1#2{\clf_markingtitle {#1}{#2}} % can be done at lua end
\permanent\def\sectionheadmarkingnumber#1#2{\clf_markingnumber{#1}{#2}} % can be done at lua end

\permanent\def\sectionheadcoupling#1{\namedheadparameter{#1}\c!coupling}
\permanent\def\sectionheadsection #1{\namedheadparameter{#1}\c!section}

% head construction

\newconditional\currentstructureown

\newtoks\everybeforehead % hook, todo: before/after keys
\newtoks\everyafterhead  % hook, todo: before/after keys

\permanent\tolerant\protected\def\strc_sectioning_handle_own[#1]#*[#2]#:#*#=#*#=% [ref] {nr} {title}
  {\currentstructureown\conditionaltrue
   \triggerautostructurelevel
   \strc_sectioning_handle{#1}{\c!reference={#2},\c!ownnumber={#3},\c!title={#4}}{}} % name ref nr title --

\permanent\tolerant\protected\def\strc_sectioning_handle_nop[#1]#*[#2]%  [ref] {title} / for taco: [key=value] variant
  {\currentstructureown\conditionalfalse
   \triggerautostructurelevel
   \ifhastok={#2}%
     \expandafter\strc_sectioning_handle_nop_indeed_yes
   \else
     \expandafter\strc_sectioning_handle_nop_indeed_nop
   \fi
   {#1}{#2}}

\def\strc_sectioning_handle_nop_indeed_yes#1#2%
  {\strc_sectioning_handle{#1}{#2}{}}

\def\strc_sectioning_handle_nop_indeed_nop#1#2#3%
  {\strc_sectioning_handle{#1}{\c!reference={#2},\c!title={#3}}{}} % name ref nr title --

\permanent\tolerant\protected\def\strc_sectioning_start[#1]#*[#S#2]#*[#S#3]% for the moment no grouping, too annoying with page breaks
  {\push_macro_currentnamedsection
   \push_macro_currentstructurereferenceprefix
   \edef\currentnamedsection{#1}%
   \currentstructureown\conditionalfalse
  %\globalpushmacro\currenthead % this does not work out well
   \xdef\currenthead{#1}%
   \setsystemmode\currenthead % new, also here now
   \headparameter\c!beforesection % beware, no users vars set yet
   \expand\everybeforehead
   \strc_sectioning_handle{#1}{#2}{#3}% name -- -- -- userdata (we might move the tagged to here)
   % potential: \bgroup (can be optional: grouped = yes)
   \headparameter\c!insidesection}

\permanent\protected\def\strc_sectioning_stop[#1]% !!! also used at lua end
  {\dostoptagged
   \dostoptagged
   % potential: \egroup
  %\globalpopmacro\currenthead % so we do a hard recover
   \xdef\currenthead{#1}% recover
   \ifconditional\c_strc_sectioning_place
     \ifx\currentheadrenderingalternative\v!horizontal\else
       \par
     \fi
   \fi
   \headparameter\c!aftersection
   \expand\everyafterhead
   \resetsystemmode\currenthead
   \pop_macro_currentstructurereferenceprefix
   \pop_macro_currentnamedsection} % new, also here now

\aliased\let\dostarthead\strc_sectioning_start % used at lua end
\aliased\let\dostophead \strc_sectioning_stop  % used at lua end

% todo: add grouping but where: before/after trickery .. probably inside because one can always add
% grouping to the before/after settings

\aliased\let\namedsection\strc_sectioning_handle_nop

\aliased\let\startnamedsection\strc_sectioning_start

\permanent\protected\def\stopnamedsection
  {\expanded{\strc_sectioning_stop[\currentnamedsection]}}

% \newconditional\structurereversesectionnumbers  % todo: key/val

\newconditional\c_strc_sectioning_to_list
\newconditional\c_strc_sectioning_increment
\newconditional\c_strc_sectioning_place
\newconditional\c_strc_sectioning_empty
\newconditional\c_strc_sectioning_hidden
\newconditional\c_strc_sectioning_section

\newconditional\headshownumber  % public
\newconditional\headisdisplay   % public
\newconditional\headissomewhere % public

\defcsname\??headincrement\v!yes  \endcsname{\c_strc_sectioning_increment\conditionaltrue\c_strc_sectioning_to_list\conditionaltrue}
\defcsname\??headincrement\v!no   \endcsname{\c_strc_sectioning_increment\conditionalfalse\c_strc_sectioning_to_list\conditionalfalse}
\defcsname\??headincrement\v!list \endcsname{\c_strc_sectioning_increment\conditionalfalse\c_strc_sectioning_to_list\conditionaltrue}
\defcsname\??headincrement\s!empty\endcsname{\c_strc_sectioning_increment\conditionaltrue\c_strc_sectioning_to_list\conditionaltrue}

\protected\def\strc_sectioning_initialize_increment
  {\edef\currentheadincrement{\headparameter\c!incrementnumber}%
   \ifcsname\??headincrement\currentheadincrement\endcsname
     \lastnamedcs
   \else
     \c_strc_sectioning_increment\conditionaltrue
     \c_strc_sectioning_to_list\conditionaltrue
     % \filterheadnumber
   \fi}

\permanent\protected\def\filterheadnumber
  {\c_strc_sectioning_increment\conditionaltrue
   \c_strc_sectioning_to_list\conditionaltrue
   \ifempty\currentproduct
     % todo : filter from other toc (number, file, title)
     % use  : \currentheadincrement as spec
   \fi}

\defcsname\??headplace\v!yes\endcsname
  {\c_strc_sectioning_empty\conditionalfalse
   \c_strc_sectioning_place\conditionaltrue
   \c_strc_sectioning_hidden\conditionalfalse
   \c_strc_sectioning_section\conditionalfalse}

\defcsname\??headplace\v!empty\endcsname
  {\c_strc_sectioning_empty\conditionaltrue
   \c_strc_sectioning_place\conditionaltrue
   \c_strc_sectioning_hidden\conditionalfalse
   \c_strc_sectioning_section\conditionalfalse}

\defcsname\??headplace\v!no\endcsname
  {\c_strc_sectioning_empty\conditionaltrue
   \c_strc_sectioning_place\conditionalfalse
   \c_strc_sectioning_hidden\conditionalfalse
   \c_strc_sectioning_section\conditionalfalse}

\defcsname\??headplace\v!hidden\endcsname
  {\c_strc_sectioning_empty\conditionaltrue
   \c_strc_sectioning_place\conditionalfalse
   \c_strc_sectioning_hidden\conditionaltrue
   \c_strc_sectioning_section\conditionalfalse}

\defcsname\??headplace\v!section\endcsname       % we need to explain the difference with hidden
  {\c_strc_sectioning_empty\conditionaltrue
   \c_strc_sectioning_place\conditionalfalse
   \c_strc_sectioning_hidden\conditionaltrue
   \c_strc_sectioning_section\conditionaltrue}

\protected\def\strc_sectioning_initialize_placement
  {\expandnamespaceparameter\??headplace\headparameter\c!placehead\v!yes}

\newmode\v!sectionnumber

\def\strc_sectioning_set_head_number_content   % was: \dosetstructureheadnumbercontent
  {\setsystemmode\v!sectionnumber
   \headshownumber\conditionaltrue} % why ?

\def\strc_sectioning_reset_head_number_content % was: \doresetstructureheadnumbercontent
  {\resetsystemmode\v!sectionnumber
   \headshownumber\conditionalfalse} % why ?

\protected\def\strc_sectioning_initialize_number
  {\ifcstok{\sectionblockparameter\c!number}\v!yes
      \ifcstok{\headparameter\c!number}\v!yes
        \headshownumber\conditionaltrue
      \else
        \headshownumber\conditionalfalse
      \fi
   \else
     \headshownumber\conditionalfalse
   \fi}

% Beware, we do need some node for anchoring marks and normally a zwnj will
% do but it interferes so we deal with it at the \LUA\ end.

\newtoks\everyheadsynchronization

\aliased\let\currentstructuresynchronize\donothing

\appendtoks
    \currentstructuresynchronize
    \enforced\glet\currentstructuresynchronize\donothing
\to \everyheadsynchronization

\permanent\protected\def\theheadsynchronization % public
  {% no, interferes: \signalcharacter
   \expand\everyheadsynchronization
   % new, this might move to a better place, e.g. first in the box
   \currentstructureextradata
   \glettonothing\currentstructureextradata
   % done (can be used for e.g. index entries)
  }

% BEWARE: \marking[section]{my text} does not work as we use list indices instead
% so we need a 'keep track of raw set option' (or maybe a funny internal prefix)

\permanent\protected\def\setheadmarking % li:: so that we can use \marking[section]{Taco needed this}
  {\strc_sectioning_delayed_flush
   \expanded{\setmarking[\currenthead]{li::\currentstructurelistnumber}}}

\mutable\let\deepstructurenumbercommand\relax
\mutable\let\deepstructuretitlecommand \relax

\permanent\protected\def\fullheadnumber
  {\edef\currentheadlabeltag{\currentsectionblock\c!label}%
   \dostarttaggednodetail\t!sectionnumber
   \labeltexts
     {\headparameter\currentheadlabeltag}
     {\ifrelax\deepstructurenumbercommand
        \structurenumber
      \else
        \expanded{\noexpand\deepstructurenumbercommand{\structurenumber}}%
      \fi}%
   \dostoptagged}

\permanent\protected\def\fullheadtitle
  {\dostarttaggednodetail\t!sectiontitle
   \ifrelax\deepstructuretitlecommand
     \structuretitle
   \else
     \expanded{\noexpand\deepstructuretitlecommand{\structuretitle}}%
   \fi
   \dostoptagged}

\mutable\lettonothing\currenthead
\mutable\lettonothing\currentheadcoupling
\mutable\lettonothing\currentheadsection

\mutable\let\currentheadlevel   \!!zerocount
\mutable\let\currentheadcounter \!!zerocount

\let\strc_show_used\relax

\installtextracker
  {structures.showused}
  {\let\strc_show_used\clf_showstructure}
  {\let\strc_show_used\relax}

\appendtoks
    \strc_show_used
\to \everystoptext

\protected\def\strc_sectioning_report{\clf_reportstructure}

\ifdefined\strc_rendering_initialize_style_and_color \else

    \protected\def\strc_rendering_initialize_style_and_color#1#2%
      {\dontconvertfont
       \useheadstyleandcolor\c!style\c!color
       \useheadstyleandcolor#1#2%
       \setupinterlinespace}

\fi

\permanent\tolerant\protected\def\placeheadtext[#1]%
  {\dontleavehmode
   \begingroup
   \enforced\permanent\protected\def\\{\space}% messy here, but the default (and needs to be grouped)
   \global\headisdisplay\conditionaltrue % triggers interlinespace checking
   \cdef\currenthead{#1}% maybe only when #1 is given
   \strc_rendering_initialize_style_and_color\c!textstyle\c!textcolor
   \relax
   \getspecificstructuretitle{\thenamedheadlevel{#1}}%
   \endgraf
   \endgroup}

\permanent\tolerant\protected\def\placeheadnumber[#1]%
  {\dontleavehmode
   \begingroup
   \global\headisdisplay\conditionaltrue % triggers interlinespace checking
   \cdef\currenthead{#1}% maybe only when #1 is given
   \strc_rendering_initialize_style_and_color\c!numberstyle\c!numbercolor
   \relax
   \getfullstructurenumber{\thenamedheadlevel{#1}}%
   \endgraf
   \endgroup}

\ifdefined\triggerautostructurelevel \else \let\triggerautostructurelevel\relax \fi

\newtoks\everybeforesectionheadhandle
\newtoks\everyaftersectionheadhandle

\mutable\lettonothing\getheadnumber
\mutable\lettonothing\getheadtitle
\mutable\lettonothing\getheadsyncs

\def\strc_sectioning_handle#1#2#3% name data userdata (we can move #1 to the caller)
  {\xdef\currenthead        {#1}%
   \xdef\currentheadcoupling{\sectionheadcoupling\currenthead}%
   \xdef\currentheadsection {\sectionheadsection \currentheadcoupling}%
   \xdef\currentheadlevel   {\sectionlevel       \currentheadsection}%
   %
   %\writestatus\m!system{setup: \currenthead,\currentheadcoupling,\currentheadsection,\currentheadlevel}%
   %
   \strc_sectioning_initialize_autolevel
   \strc_sectioning_initialize_increment
   \strc_sectioning_initialize_placement
   \strc_sectioning_initialize_number
   %
   \expand\everybeforesectionheadhandle
   %
   % todo: also mark (for header)
   %
   % we might remove the lower level
   %
   % not here, after optional \page: \strc_sectioning_register{#1}{#2}{#3}%
   %
%    \xdef\currentheadcounter{\currentsectioncountervalue}% lua call
   %
   % \currentstructuresynchronize % will move
   %
   \lettonothing\getheadnumber
   \lettonothing\getheadtitle
   \lettonothing\getheadsyncs
   \ifconditional\c_strc_sectioning_increment
     \ifconditional\c_strc_sectioning_place
       \strc_sectioning_before_yes
       \strc_sectioning_register{#1}{#2}{#3}% after optional \page
       \strc_sectioning_report
       \dostarttaggednodetail\t!sectioncaption
       \let\getheadsyncs\theheadsynchronization
       \let\getheadtitle\fullheadtitle
       \ifconditional\headshownumber
         \let\getheadnumber\fullheadnumber
         \strc_rendering_place_head_number_and_text
       \else
         \strc_rendering_place_head_text
       \fi
       \dostoptagged
       \strc_sectioning_after_yes
     \orelse\ifconditional\c_strc_sectioning_hidden
       \strc_sectioning_register{#1}{#2}{#3}% after optional \page
       \strc_sectioning_report
       \dostarttaggednodetail\t!sectioncaption
       \let\getheadsyncs\theheadsynchronization
       \ifconditional\c_strc_sectioning_section
         \strc_rendering_place_head_section
       \else
         \strc_rendering_place_head_hidden % only something when tracing
       \fi
       \dostoptagged
     \else
       \strc_sectioning_before_nop % toegevoegd ivm subpaginanr / tug sheets
       \strc_sectioning_register{#1}{#2}{#3}% after optional \page
       \strc_sectioning_report
       \dostarttaggednodetail\t!sectioncaption
       \let\getheadsyncs\theheadsynchronization
       \strc_rendering_place_head_empty % just flush 'm
       \dostoptagged
       \strc_sectioning_after_nop
     \fi
   \else
     \ifconditional\c_strc_sectioning_place
       \strc_sectioning_before_yes
       \strc_sectioning_register{#1}{#2}{#3}% after optional \page
       \strc_sectioning_report
       \dostarttaggednodetail\t!sectioncaption
       \let\getheadsyncs\theheadsynchronization
       \let\getheadtitle\fullheadtitle
       \strc_rendering_place_head_text
       \dostoptagged
       \strc_sectioning_after_yes
     \orelse\ifconditional\c_strc_sectioning_hidden
       \strc_sectioning_register{#1}{#2}{#3}% after optional \page
       \strc_sectioning_report
       \let\getheadsyncs\theheadsynchronization
       \dostarttaggednodetail\t!sectioncaption
       \ifconditional\c_strc_sectioning_section
         \strc_rendering_place_head_section
       \else
         \strc_rendering_place_head_hidden % only something when tracing
       \fi
       \dostoptagged
     \else
       % do nothing / should be vbox to 0pt
       \strc_sectioning_before_nop
       \strc_sectioning_register{#1}{#2}{#3}% after optional \page
       \strc_sectioning_report
       \dostarttaggednodetail\t!sectioncaption
       \let\getheadsyncs\theheadsynchronization
       \strc_rendering_place_head_empty % just flush 'm
       \dostoptagged
       \strc_sectioning_after_nop
     \fi
   \fi
   %
   \expand\everyaftersectionheadhandle
   %
   \c_strc_sectioning_ignore_page\conditionalfalse
   % ignorespaces prevents spaces creeping in when after=\dontleavehmode
   \dostarttaggednodetail\t!sectioncontent
   \unless\ifempty\currentstructureplaceholder
     \expandafter\strc_sectioning_placeholder
   \orelse\ifconditional\headisdisplay
     \expandafter\ignorespaces
   \else
     \expandafter\ignorepars
   \fi}

%D \starttyping
%D \startsubject[placeholder=todo,title=one]
%D     whatever one
%D \stopsubject
%D \stoptyping

\def\strc_sectioning_placeholder
  {\placeholder[\currentstructureplaceholder]%
   \gobblenested{\e!start\currenthead}{\e!stop\currenthead}{\e!stop\currenthead}}

% typesetting (the getters are public)

\protected\def\strc_rendering_place_head_number_and_text
  {\setheadmarking
   \getheadnumber/\getheadtitle
   \getheadsyncs}

\protected\def\strc_rendering_place_head_text
  {\setheadmarking
   \getheadtitle
   \getheadsyncs}

\protected\def\strc_rendering_place_head_empty
  {\setheadmarking
   \getheadsyncs}

\installcorenamespace{hiddenheadattr}
\installcorenamespace{hiddenheadsync}

% todo: when in the page builder we need to resolve the marking immediately
% because otherwise we have an async

\newbox\b_sectioning_delayed

\def\strc_sectioning_delayed_flush
  {\ifvoid\b_sectioning_delayed\else
     \smashedbox\b_sectioning_delayed
   \fi}

\ifdefined\??markingclass % uses a node, so we need to embed / bind

    \protected\def\strc_rendering_place_head_section % see hidden below
      {\global\setbox\b_sectioning_delayed\hpack\bgroup
         \hpack\headreferenceattributes\bgroup
            \setmarking[\currentheadcoupling]{li::\currentstructurelistnumber}% also does the mark
         \egroup
         \theheadsynchronization
       \egroup}

    \protected\def\strc_rendering_place_head_hidden % maybe trialtypesetting check
      {\xdefcsname\??hiddenheadattr\currenthead\endcsname
         {\headreferenceattributes}% can be used when making a box
       \xdefcsname\??hiddenheadsync\currenthead\endcsname
         {\noexpand\gletcsname\??hiddenheadsync\currenthead\endcsname\relax
       % {\noexpand\gletcsname\??hiddenheadsync\currenthead\endcsname\relax
          \hpack\headreferenceattributes\bgroup
            \noexpand\setmarking[\currentheadcoupling]{li::\currentstructurelistnumber}% otherwise no destination ... maybe tag ref as hidden and fall back on page reference
          \egroup
          \theheadsynchronization}} % and it's a node anyway

\else % uses attributes so no interference

    \protected\def\strc_rendering_place_head_section % see hidden below
      {\global\setbox\b_sectioning_delayed\hpack\bgroup
         \setmarking[\currentheadcoupling]{li::\currentstructurelistnumber}%
         \hpack\headreferenceattributes{}% also does the mark
         \theheadsynchronization
       \egroup}

    \protected\def\strc_rendering_place_head_hidden % maybe trialtypesetting check
      {\xdefcsname\??hiddenheadattr\currenthead\endcsname
         {\headreferenceattributes}% can be used when making a box
       \xdefcsname\??hiddenheadsync\currenthead\endcsname
         {\noexpand\gletcsname\??hiddenheadsync\currenthead\endcsname\relax
          \noexpand\setmarking[\currentheadcoupling]{li::\currentstructurelistnumber}%
          \hpack\headreferenceattributes{}% otherwise no destination ... maybe tag ref as hidden and fall back on page reference
          \theheadsynchronization}} % and it's a node anyway

\fi

\permanent\def\synchronizehead           #1{\begincsname\??hiddenheadsync#1\endcsname}
\permanent\def\theheadreferenceattributes#1{\begincsname\??hiddenheadattr#1\endcsname}

\permanent\protected\def\placerawheaddata  [#1]{\synchronizehead{#1}}
\permanent\protected\def\placerawheadtext  [#1]{\getspecificstructuretitle{\thenamedheadlevel{#1}}}
\permanent\protected\def\placerawheadnumber[#1]{\getfullstructurenumber{\thenamedheadlevel{#1}}}

\permanent\protected\def\repeathead[#1]%
  {\begingroup
   \setupinteraction[\c!state=\v!stop]%
   \cdef\currenthead{#1}
   \strc_sectioning_initialize_placement
   \strc_sectioning_initialize_number
   \dostarttaggednodetail\t!sectioncaption
   \let\getheadsyncs \relax
   \def\getheadtitle {\getmarking[#1]}
   \def\getheadnumber{\getmarking[#1\v!number]}
   \strc_sectioning_before_yes
   \ifconditional\headshownumber
      \strc_rendering_place_head_number_and_text
   \else
      \strc_rendering_place_head_text
   \fi
   \dostoptagged
   \strc_sectioning_after_yes
   \endgroup}

% \setuphead[chapter][placehead=hidden]
% \chapter {test}
%
% %(\synchronizehead{chapter}) % \getheadsyncs
% %(\getfullstructurenumber{\thenamedheadlevel{chapter}})
% %(\getspecificstructuretitle{\thenamedheadlevel{chapter}})
%
% (\placerawheaddata  [chapter])
% (\placerawheadnumber[chapter])
% (\placerawheadtext  [chapter])

% pagebreaks

\letcsname\??headmarknop\v!page   \endcsname\donothing
\defcsname\??headmarknop\v!reset  \endcsname{\resetcurrentstructuremarks}
\letcsname\??headmarknop\s!unknown\endcsname\donothing

\letcsname\??headmarkyes\v!page   \endcsname\donothing  % to be checked: {\resetcurrentstructuremarks}
\defcsname\??headmarkyes\v!reset  \endcsname{\resetcurrentstructuremarks}
\letcsname\??headmarkyes\s!unknown\endcsname\donothing

\def\strc_sectioning_check_layout
  {\edef\p_page{\headparameter\c!page}%
   \ifempty\p_page
     \strc_sectioning_check_layout_nop
   \else
     \strc_sectioning_check_layout_yes
   \fi}

\def\strc_sectioning_check_layout_nop
  {\expandnamespaceparameter\??headmarknop\headparameter\c!marking\s!unknown}

\def\strc_sectioning_check_layout_yes
  {\page[\p_page]%
   \expandnamespaceparameter\??headmarkyes\headparameter\c!marking\s!unknown
   \edef\p_header{\headparameter\c!header}%
   \ifempty\p_header \else
     \doifelselayouttextline\v!header{\expanded{\setuplayouttext[\v!header][\c!state=\p_header]}}\donothing
   \fi
   \edef\p_text{\headparameter\c!text}%
   \ifempty\p_text \else
     \doifelselayouttextline\v!text  {\expanded{\setuplayouttext[\v!text  ][\c!state=\p_text  ]}}\donothing
   \fi
   \edef\p_footer{\headparameter\c!footer}%
   \ifempty\p_footer \else
     \doifelselayouttextline\v!footer{\expanded{\setuplayouttext[\v!footer][\c!state=\p_footer]}}\donothing
   \fi}

\newinteger    \c_strc_sectioning_preceding_level     \c_strc_sectioning_preceding_level\plusone
\newconditional\c_strc_sectioning_auto_break          \c_strc_sectioning_auto_break\conditionaltrue
\newconditional\c_strc_sectioning_ignore_page
\newboundary   \c_strc_sectioning_boundary

\protected\def\strc_sectioning_inject_continuous_signal
  {\ifhmode
     \boundary\c_strc_sectioning_boundary
   \fi}

% \let\dotagsectionlevel\relax

\def\strc_sectioning_before_yes
  {\strc_sectioning_check_before\strc_sectioning_handle_page_yes
   \headparameter\c!inbetween
   \dostarttaggedchained\t!section\currenthead\currenthead\??head
%    \dotagsectionlevel
   }

\def\strc_sectioning_before_nop
  {\strc_sectioning_check_before\strc_sectioning_handle_page_nop
   \headparameter\c!inbetween
%  \dostarttaggednodetail\currenthead} % this is a weird one .. needs checking
   \dostarttaggedchained\t!section\currenthead\currenthead\??head}

\def\strc_sectioning_empty_correction
  {\ifconditional\c_strc_sectioning_empty
     % this needs checking
     \penalty\plustenthousand
     \vskip-\lineheight
     \kern\zeropoint
     \prevdepth\strutdepth
   \fi}

\def\strc_sectioning_after_nop
  {}

\def\strc_sectioning_check_before#1%
  {\ifhmode
     \scratchcounter\lastpenalty
     \unpenalty % no beauty in this
     \ifnum\lastboundary=\c_strc_sectioning_boundary
       % no page break
       \ifconditional\c_strc_sectioning_ignore_page
         \c_strc_sectioning_ignore_page\conditionalfalse
       \else
         \global\c_strc_sectioning_preceding_level\currentheadlevel
         \nobreak
       \fi
     % \global\c_strc_rendering_continuous\conditionaltrue
     \else
       \penalty\scratchcounter
     % \global\c_strc_rendering_continuous\conditionalfalse
       #1%
     \fi
   \else
   % \global\c_strc_rendering_continuous\conditionalfalse
     #1%
   \fi}

\permanent\def\currentsectioncountervalue {\clf_depthnumber{\thenamedheadlevel\currenthead}}
%permanent\def\previoussectioncountervalue{\clf_depthnumber{\thenamedheadlevel\currenthead+\minusone}}
\permanent\def\previoussectioncountervalue{\clf_depthnumber{\thenamedheadlevel\previoushead}}

\mutable\lettonothing\previoushead

\def\strc_sectioning_handle_page_nop
  {\unless\ifcstok{\headparameter\c!continue}\v!yes
     \strc_sectioning_check_layout
   \orelse\ifx\currenthead\previoushead % not really needed
     \strc_sectioning_check_layout
   \orelse\ifnum\previoussectioncountervalue=\zerocount
     \strc_sectioning_check_layout
   \orelse\ifnum\currentsectioncountervalue>\zerocount
     \strc_sectioning_check_layout
   \fi
   \glet\previoushead\currenthead}

\def\strc_sectioning_handle_page_yes
  {\ifconditional\c_strc_sectioning_ignore_page
     \c_strc_sectioning_ignore_page\conditionalfalse
   \else
     % beware, these numbers are not yet know here
     \strc_sectioning_handle_page_nop
     \ifcstok{\headparameter\c!aligntitle}\v!float
       \ifconditional\c_strc_sectioning_auto_break
         \spac_vspacing_same_page\currentheadlevel\zerocount
       \fi
       \headparameter\c!before\relax
       \indent % hm, not a clever one?
     \else
       \page_otr_command_flush_side_floats
       \ifconditional\c_strc_sectioning_auto_break
         \spac_vspacing_same_page\currentheadlevel\zerocount
       \fi
       \headparameter\c!before\relax
     \fi
     \global\c_strc_sectioning_preceding_level\currentheadlevel
   \fi
   \glet\previoushead\currenthead}

\def\strc_sectioning_depth_correction
  {\ifvmode
     \ifcstok{\headparameter\c!depthcorrection}\v!strut
       \prevdepth\strutdepth
     \fi
   \fi}

\def\strc_sectioning_after_yes
  {\ifconditional\headisdisplay
     \ifconditional\c_strc_sectioning_auto_break
       \spac_vspacing_same_page\currentheadlevel\plusone
     \fi
     \strc_sectioning_empty_correction
     \headparameter\c!after
     \strc_sectioning_depth_correction
   \fi}

\protected\def\strc_sectioning_prevent_page_break % see strc-con
  {\ifconditional\c_strc_sectioning_auto_break
     \spac_vspacing_same_page\currentheadlevel\plustwo
   \fi}

% We do support negative numbers but it can have side effects that we won't catch:
%
% \chapter{some} \setupheadnumber[chapter][3] \chapter{more}
% \setupheadnumber[section][8] \section{b} \section{c} \setupheadnumber[section][-1] \section{d}

\permanent\def\thenamedheadlevel#1%
  {\sectionlevel{\sectionheadsection{\sectionheadcoupling{#1}}}}

\permanent\tolerant\protected\def\setupheadnumber[#1]#*[#2]% todo: reset if at other level
  {\setstructurenumber{\thenamedheadlevel{#1}}{#2}} % #2 should be a string as it intercepts + -

\permanent\protected\def\determineheadnumber[#1]%
  {\xdef\currentheadnumber{\getstructurenumber{\thenamedheadlevel{#1}}}}

% The previous macro is been replaced by the expandable:

\permanent\def\namedheadnumber      #1{\getstructurenumber    {\thenamedheadlevel{#1}}}
\permanent\def\somenamedheadnumber#1#2{\getsomestructurenumber{\thenamedheadlevel{#1}}{#2}}

\permanent\tolerant\protected\def\headnumber[#1]#*[#2]%
  {\getsomefullstructurenumber{\thenamedheadlevel{#1}}{#2}}

\permanent\tolerant\protected\def\someheadnumber[#1]#*[#2]%
  {\dontleavehmode
   \begingroup
   \cdef\currenthead{#1}%
   \getsomefullstructurenumber{\thenamedheadlevel{#1}}{#2}%
   \endgroup}

% \mutable\def\currentheadtext{obsolete,\space use marks}

% list references, will be redone in lua when we need it

% \let\startlistreferences\relax
% \let\stoplistreferences \relax

% experimental

\newconditional\c_strc_sectioning_auto_levels

\appendtoks
    \c_strc_sectioning_auto_levels\conditionaltrue
\to \everyenableelements

\protected\def\strc_sectioning_initialize_autolevel
  {\ifconditional\c_strc_sectioning_auto_levels
     \clf_autonextstructurelevel\currentheadlevel\relax
     \global\c_strc_sectioning_auto_levels\conditionalfalse
   \fi}

\permanent\protected\def\triggerautostructurelevel
  {\global\c_strc_sectioning_auto_levels\conditionaltrue}

\permanent\protected\def\finalizeautostructurelevels
  {\clf_autofinishstructurelevels}

\permanent\protected\def\finalizeautostructurelevel
  {\dostoptagged
   \dostoptagged}

\appendtoks
    \finalizeautostructurelevels
\to \everystoptext

%D Defined at the \LUA\ end:

% \doifelsefirstsectionpage{chapter}{do this}{or that} % in pagebody building

\stopcontextdefinitioncode

\protect \endinput
