%D \module
%D   [       file=strc-con,
%D        version=2008.10.20,
%D          title=\CONTEXT\ Structure Macros,
%D       subtitle=Constructions,
%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.

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

\registerctxluafile{strc-con}{}

% todo: check why \copy .. probably mkii leftover
%
% todo: check if commands similar to lists
% todo: \strc_constructions_setup_counter\strc_constructions_setup_counter{#1} in setup ... synchronization
%
% ? : \def\showdnlisttext{\constructionparameter\c!listtext}   % space in default
%
% maybe: pickup text and store in buffer ...
%
% \@@notemakeconstruction[##1]{}{##2}%
% \expandafter\endgroup\noteparameter\c!next}}
%
% todo: \currentconstructionattribute : can be a counter instead

%D Constructions are just descriptions but a bit more abstract so that we can
%D conveniently build upon them. They are not really meant for users but module
%D writers might find them useful. We mention a couple of parameters but these are
%D only mentioned because in the shared code we map all resolvers to constructions.
%D
%D On top of constructions we build descriptions, enumerations, notes, labels and
%D maybe some day more.

\unprotect

%D Todo:

\installcorenamespace{construction}

\installcommandhandler \??construction {construction} \??construction

\aliased\let\setupconstructions\setupconstruction

\setupconstructions[%
    %c!title=,
    %c!text=,
    %
    %c!style=,
    %c!color=,
    %c!command=,
    %c!align=,
    %
    %c!headstyle=,
    %c!headcolor=,
    %c!headalign=,
    %
    %c!titlestyle=,
    %c!titlecolor=,
    %c!titlecommand=,
    %c!titleleft=,
    %c!titleright=,
    %
    %c!closesymbol=,
    %c!closecommand=,
    %
    \c!alternative=\v!left,
    \c!display=\v!yes,
    \c!width=7\emwidth,
    \c!distance=\emwidth,
    \c!stretch=.50,
    \c!shrink=.25,
    \c!titledistance=.5\emwidth,
    %c!hang=,
    %c!sample=,
    \c!margin=\v!no,
    \c!before=\blank,
    \c!inbetween=\blank,
    \c!after=\blank,
    %c!indentnext=,
    %c!indenting=,
    %
    \c!expansion=\v!no,
    %c!xmlsetup=,
    %s!catcodes=,
]

%D Constructions and alike uses similar structures. In order to prevent issues
%D we freeze some states. There is some overhead in the intermediate define
%D step (as we could set them directly) but this is more flexible (and looks
%D nicer). Keep in mind that descriptions, enumeration and notations are all
%D independent and that we just remap the resolvers.

% \defineconstruction[test][handler=description,level=1]
% \defineconstruction[test][parent][handler=description,level=3]

\installcorenamespace{constructionmain}  % frozen after definition
\installcorenamespace{constructionlevel} % frozen after definition
\installcorenamespace{constructionclass} % frozen after definition

%aliased\let\currentconstructionhash           \??construction

\mutable\lettonothing\currentconstructionmain
\mutable\lettonothing\currentconstructionlevel
\mutable\lettonothing\currentconstructionhandler
\mutable\lettonothing\currentconstructionattribute
\mutable\lettonothing\currentconstructionbookmark
\mutable\lettonothing\currentconstructioncatcodes
\mutable\lettonothing\currentconstructioncoding
\mutable\lettonothing\currentconstructionexpansion
\mutable\lettonothing\currentconstructionincrementnumber
\mutable\lettonothing\currentconstructionlabel
\mutable\lettonothing\currentconstructionlist
\mutable\lettonothing\currentconstructionlistentry
\mutable\lettonothing\currentconstructionlistnumber
\mutable\lettonothing\currentconstructionmarking
\mutable\lettonothing\currentconstructionnumber
\mutable\lettonothing\currentconstructionreference
\mutable\lettonothing\currentconstructionreferencetext
\mutable\lettonothing\currentconstructionreferenceprefix
\mutable\lettonothing\currentconstructionsynchronize
\mutable\lettonothing\currentconstructiontitle
\mutable\lettonothing\currentconstructionxmlsetup

\newconditional\c_strc_constructions_define_commands \c_strc_constructions_define_commands\conditionaltrue % use with care, might become a proper key

\appendtoks
    \ifempty\currentconstructionparent
        \letcsname\??constructionmain\currentconstruction\endcsname\currentconstruction
        \definelist[\currentconstruction]% goodie
    \else
        \letcsname\??constructionmain\currentconstruction\endcsname\currentconstructionparent
        \definelist[\currentconstruction][\currentconstructionparent]% goodie
    \fi
    \edefcsname\??constructionlevel\currentconstruction\endcsname{\number\constructionparameter\c!level}%
    \edefcsname\??constructionclass\currentconstruction\endcsname{\constructionparameter\s!handler}%
    \expandafter\newconditional\csname\??constructionclosesymbol\currentconstruction\endcsname
\to \everydefineconstruction

% todo: inhibit this when we have a different handle .. current we cannot do \frozen

\appendtoks
    \ifconditional\c_strc_constructions_define_commands
        \protected\instance\edefcsname\e!start\currentconstruction\endcsname{\startnamedconstruction[\currentconstruction]}%
        \protected\instance \defcsname\e!stop \currentconstruction\endcsname{\stopnamedconstruction}%
    \fi
\to \everydefineconstruction

%D Just a basic environment (mostly for testing). We will provide a 'setup' based
%D plugin once the rest is sorted out.

\tolerant\permanent\protected\def\startnamedconstruction[#1]#*[#S#2]#*[#3]%
  {\begingroup
   \strc_constructions_initialize{#1}%
   \strc_constructions_register[#3][\c!reference=,\c!title=,\c!bookmark=,\c!list=,\c!referencetext=,#2]%
   \csname\??constructionstarthandler\currentconstructionhandler\endcsname}

\permanent\protected\def\stopnamedconstruction
  {\csname\??constructionstophandler\currentconstructionhandler\endcsname
   \endgroup}

%D As we will build on top of the generic construction mechanism we have handlers
%D as a sort of plug in mechanism. In order to have some consistency we share
%D some namespaces.

\installcorenamespace{constructioninitializer}
\installcorenamespace{constructionfinalizer}

\installcorenamespace{constructionmainhandler}
\installcorenamespace{constructioncommandhandler}
\installcorenamespace{constructionstarthandler}
\installcorenamespace{constructionstophandler}

\installcorenamespace{constructiontexthandler}
\installcorenamespace{constructionnotehandler}

\protected\def\strc_constructions_initialize#1% class instance
  {\cdef\currentconstruction{#1}%
   \enforced\let\currentconstructionhash\??construction
   \let\currentconstructionlistentry\!!zerocount
   \enforced\expandafter\let\expandafter\currentconstructionmain   \csname\??constructionmain \currentconstruction\endcsname
   \enforced\expandafter\let\expandafter\currentconstructionlevel  \csname\??constructionlevel\currentconstruction\endcsname
   \enforced\expandafter\let\expandafter\currentconstructionhandler\csname\??constructionclass\currentconstruction\endcsname
   \csname\??constructioninitializer\currentconstructionhandler\endcsname}

\protected\def\strc_constructions_finalize
  {\csname\??constructionfinalizer\currentconstructionhandler\endcsname
   \strc_constructions_discard}

\newconditional\c_strc_constructions_number_state
\newconditional\c_strc_constructions_title_state

\protected\defcsname\??constructioninitializer\v!construction\endcsname
  {\c_strc_constructions_number_state\conditionalfalse
   \c_strc_constructions_title_state\conditionalfalse}

\protected\defcsname\??constructionfinalizer\v!construction\endcsname
  {}

%D We keep the command variant around but rather would move to the start-stop one.
%D Also, passing the title as argument has some history so we need to keep that as
%D well.

% \ifdefined\dotagsetconstruction \else \aliased\let\dotagsetconstruction\relax \fi

% \startuseMPgraphic{MyFrame}
%     picture p ; numeric o ; path a, b ; pair c ;
%     p := textext.rt("\FunnyFramed{\currentconstructiontext}") ;
%   % p := textext.rt("\wrappedconstruction{\FunnyFramed{\currentconstructiontext}}") ;
%   % p := textext.rt("\FunnyFramed{\wrappedconstruction{\currentconstructiontext}}") ;
%   % p := textext.rt("\FunnyFramed{\wrappedcurrentconstruction}") ;
%     ...
% \stopuseMPgraphic
%
% \defineoverlay[MyFrame][\useMPgraphic{MyFrame}]
%
% \defineframedtext
%   [MyText]
%   [frame=off,
%    background=MyFrame]
%
% \defineenumeration[Theorem]
%   [alternative=empty,
%    before=\startMyText,
%    after=\stopMyText]

\newtoks\everyconstruction

\permanent\protected\def\currentconstructiontext
  {\begstrut
   \csname\??constructiontexthandler\currentconstructionhandler\endcsname
   \endstrut}

\permanent\protected\def\currentconstructionsample
  {\begstrut
   \constructionparameter\c!text
   \p_strc_constructions_sample
   \endstrut}

\permanent\protected\def\wrappedconstruction#1%
  {\begingroup
     \iftrialtypesetting \else
       \currentconstructionsynchronize
       \c_attr_destination\currentconstructionattribute\relax
     \fi
     #1%
   \endgroup}

\permanent\protected\def\wrappedcurrentconstruction
  {\begingroup
     \iftrialtypesetting \else
       \currentconstructionsynchronize
       \c_attr_destination\currentconstructionattribute\relax
     \fi
     \currentconstructiontext
   \endgroup}

\protected\defcsname\??constructionmainhandler\v!construction\endcsname#1%
  {\iftrialtypesetting \else
     \begingroup
     \currentconstructionsynchronize % reinstated
     \c_attr_destination\currentconstructionattribute\relax % todo, whole text
     \signalcharacter
     \endgroup
   \fi#1}

\protected\defcsname\??constructiontexthandler\v!construction\endcsname
  {\begingroup
   \useconstructionstyleandcolor\c!headstyle\c!headcolor % move to \currentconstructiontext
   \expand\everyconstruction
   \constructionparameter\c!headcommand
     {\strut
      \constructionparameter\c!text
      \clf_savedlisttitle{\currentconstructionmain}\currentconstructionlistentry\relax}%
   \endgroup}

\protected\def\strc_constructions_stored_start
  {\begingroup % brrr \endgroup elsewhere ... will be sorted out
   \csname\??constructionstarthandler\currentconstructionhandler\endcsname}

\protected\def\strc_constructions_stored_stop
  {\csname\??constructionstophandler\currentconstructionhandler\endcsname}

\newconstant\c_strc_constructions_nested_state % to be redone

% not used any more
%
% \def\resetconstructions % to be used in e.g. footnotes
%   {\c_strc_constructions_nested_state\zerocount}

\protected\defcsname\??constructioncommandhandler\v!construction\endcsname
  {\endgroup}

\lettonothing\p_strc_constructions_align
\lettonothing\p_strc_constructions_aligntitle
\lettonothing\p_strc_constructions_closesymbol
\lettonothing\p_strc_constructions_distance
\lettonothing\p_strc_constructions_hang
\lettonothing\p_strc_constructions_headalign
\lettonothing\p_strc_constructions_inbetween
\lettonothing\p_strc_constructions_indenting
\lettonothing\p_strc_constructions_number
\lettonothing\p_strc_constructions_renderingsetup
\lettonothing\p_strc_constructions_sample
\lettonothing\p_strc_constructions_title
\lettonothing\p_strc_constructions_width

\newconditional\c_strc_constructions_distance_none

\def\strc_constructions_set_width_and_distance
  {\assignwidth
     \p_strc_constructions_width
     \constructionsheadwidth
     {\unhcopy\constructionheadbox}
     \constructionsheaddistance}

\def\strc_constructions_preroll_head#content%
  {\setbox\constructionheadbox\hbox
     {\forgetall
      \dontcomplain
      \settrialtypesetting
      \csname\??constructionmainhandler\currentconstructionhandler\endcsname#content}}

\def\strc_constructions_ignore_head
  {\constructionsheaddistance\zeropoint
   \constructionsheadwidth   \zeropoint
   % we also need to make sure that no stretch creeps in (new per 2015-02-02, for Alan)
   \c_strc_constructions_distance_none\conditionaltrue}

\protected\defcsname\??constructionstarthandler\v!construction\endcsname % this will be redone (reorganized) .. too much boxing
  {\dostarttaggedchained\t!construction\currentconstruction\currentconstruction\currentconstructionhash
%    \dotagsetconstruction
   \constructionparameter\c!before
   \begingroup
   \edef\currentconstructionalternative{\constructionparameter\c!alternative}%
   \edef\p_strc_constructions_renderingsetup{\constructionalternativeparameter\c!renderingsetup}%
   % catch fuzzyness
   \ifempty\p_strc_constructions_renderingsetup
      \letconstructionparameter\c!alternative\v!left
      \let\currentconstructionalternative\v!left
      \edef\p_strc_constructions_renderingsetup{\constructionalternativeparameter\c!renderingsetup}%
   \else
     \doifnotsetups\p_strc_constructions_renderingsetup
       {\letconstructionparameter\c!alternative\v!left
        \let\currentconstructionalternative\v!left
        \edef\p_strc_constructions_renderingsetup{\constructionalternativeparameter\c!renderingsetup}}%
   \fi
   %
   \doadaptleftskip{\constructionparameter\c!margin}%
   \setlocalhsize % so we can use \localhsize in width assignments
   \edef\p_strc_constructions_distance{\constructionalternativeparameter\c!distance}%
   \edef\p_strc_constructions_width{\constructionalternativeparameter\c!width}%
   \ifx\p_strc_constructions_distance\v!none
     \c_strc_constructions_distance_none\conditionaltrue
     \constructionsheaddistance\zeropoint
   \else
     \c_strc_constructions_distance_none\conditionalfalse
     \constructionsheaddistance\p_strc_constructions_distance\relax
     \ifdim\constructionsheaddistance=\zeropoint
       \ifx\p_strc_constructions_width\v!broad
         \constructionsheaddistance\emwidth
       \orelse\ifx\p_strc_constructions_width\v!line
         \constructionsheaddistance\emwidth
       \fi
     \fi
   \fi
   % inefficient and not always needed, for instance not with margins so we will make checkers
   % per alternative some day (especially in labels this is unwanted overhead)
   %
   % maybe we should have an option as i cannot oversee the consequences now
   %
   % \edef\p_strc_constructions_sample{\constructionparameter\c!sample}%
   % \ifempty\p_strc_constructions_sample
   %   \strc_constructions_preroll_head\currentconstructiontext
   % \else
   %   \strc_constructions_preroll_head\currentconstructiontextsample
   % \fi
   % \strc_constructions_set_width_and_distance
   %
   \strc_constructions_preroll_head\currentconstructiontext
   \ifzeropt\wd\constructionheadbox
     \strc_constructions_ignore_head
   \else
     \edef\p_strc_constructions_sample{\constructionparameter\c!sample}%
     \ifempty\p_strc_constructions_sample
       \strc_constructions_set_width_and_distance
     \else
       \strc_constructions_preroll_head\currentconstructionsample
       \ifzeropt\wd\constructionheadbox
         \strc_constructions_ignore_head
       \else
         \strc_constructions_set_width_and_distance
       \fi
     \fi
   \fi
   %
   \dostarttaggednodetail\t!constructiontag % todo
   \setbox\constructionheadbox\hbox
     {\scratchskip\parindent
      \forgetall
      \dontcomplain
      % new and under testing
      \ifcstok{\constructionparameter\c!headindenting}\v!yes
        \hskip\scratchskip
      \fi
      %
      \ifx\currentconstructionalternative\v!serried % brrr, hack, will change
        \csname\??constructionmainhandler\currentconstructionhandler\endcsname\currentconstructiontext
      \else
        \csname\??constructionmainhandler\currentconstructionhandler\endcsname{\boxedconstructionhead\currentconstructiontext}%
      \fi}%
   \dostoptagged % tag
   \edef\p_strc_constructions_aligntitle{\constructionparameter\c!aligntitle}%
   \ifx\p_strc_constructions_aligntitle\v!no
     \leftconstructionskip \leftskip
     \rightconstructionskip\rightskip
   \orelse\ifcase\c_strc_constructions_nested_state
     \leftconstructionskip \leftskip
     \rightconstructionskip\rightskip
   \fi
   \edef\p_strc_constructions_align{\constructionparameter\c!align}%
   \ifempty\p_strc_constructions_align \else
     \setupalign[\p_strc_constructions_align]% \use...
   \fi
   \ifcase\c_strc_constructions_nested_state
     \c_strc_constructions_nested_state\plusone
   \or
     \c_strc_constructions_nested_state\plustwo
   \fi
   \strc_constructions_close_symbol_reset
   %
   \edef\p_strc_constructions_headalign{\constructionparameter\c!headalign}%
   %
   \directsetup\p_strc_constructions_renderingsetup\relax
   % moved to here 2014-07-03
   % we'd like to use \useindentingparameter\constructionparameter but ...
   \edef\p_strc_constructions_indenting{\constructionparameter\c!indenting}%
   \ifempty\p_strc_constructions_indenting \else
     \c_spac_indentation_indent_first\conditionaltrue % recently added, better no v!reset
     \indenting[\v!first,\p_strc_constructions_indenting]% Wolfgang needs to check this
   \fi
   %
   \dostarttaggednodetail\t!constructioncontent
  %\freezeparagraphproperties
   \updateparagraphshapes
   \ignorespaces} % args not needed

% This is why we need the \v!first in indentation above
%
% \defineenumeration
%   [foo]
%   [alternative=serried,
%    indenting={yes,medium}]
%
% \startitemize
%     \startitem
%         \startfoo
%             AAA\par
%             BBB\par
%             CCC\par
%             DDD\par
%         \stopfoo
%     \stopitem
% \stopitemize

\protected\defcsname\??constructionstophandler\v!construction\endcsname
  {\strc_constructions_close_symbol_place
   \ifcstok{\constructionparameter\c!display}\v!no\else
     \par
   \fi
   \dostoptagged % content
   \dostoptagged % construction
   \endgroup
   \constructionparameter\c!after
   \useindentnextparameter\constructionparameter
   \strc_constructions_finalize
%   \endgroup
   \dorechecknextindentation}

\permanent\protected\def\boxedconstructionhead#1%
  {\ifcstok{\constructionalternativeparameter\c!alignbottom}\v!yes \vbox \else \vtop \fi
     \bgroup
       \hsize\constructionsheadwidth
       \edef\p_strc_constructions_headalign{\constructionparameter\c!headalign}%
       \ifempty\p_strc_constructions_headalign \else
         \setupalign[\p_strc_constructions_headalign]% \use...
       \fi
       #1%
     \egroup}

\installcorenamespace{constructionalternative}
\installcorenamespace{constructionrenderings}

% see lists: alternativemethods ... todo
%
% there will be a proper interface to variables

\installcommandhandler \??constructionalternative {constructionalternative} \??constructionalternative

\setupconstructionalternative
  [%c!left=, % no inheritance
   %c!right=,% no inheritance
   \c!width=\constructionparameter\c!width,
   \c!distance=\constructionparameter\c!distance,
   \c!stretch=\constructionparameter\c!stretch,
   \c!shrink=\constructionparameter\c!shrink]

\defineconstructionalternative
  [\v!left]
  [%\c!width=7em,
   %\c!distance=1em,
   \c!renderingsetup=\??constructionrenderings:\v!left]

\defineconstructionalternative
  [\v!right]
  [%\c!width=7em,
   %\c!distance=1em,
   \c!renderingsetup=\??constructionrenderings:\v!right]

\defineconstructionalternative
  [\v!inmargin]
  [\c!renderingsetup=\??constructionrenderings:\v!inmargin]

\defineconstructionalternative
  [\v!inleft]
  [\c!renderingsetup=\??constructionrenderings:\v!inleft]

\defineconstructionalternative
  [\v!inright]
  [\c!renderingsetup=\??constructionrenderings:\v!inright]

\defineconstructionalternative
  [\v!margin]
  [\c!renderingsetup=\??constructionrenderings:\v!margin]

\defineconstructionalternative
  [\v!leftmargin]
  [\c!renderingsetup=\??constructionrenderings:\v!leftmargin]

\defineconstructionalternative
  [\v!rightmargin]
  [\c!renderingsetup=\??constructionrenderings:\v!rightmargin]

\defineconstructionalternative
  [\v!innermargin]
  [\c!renderingsetup=\??constructionrenderings:\v!innermargin]

\defineconstructionalternative
  [\v!outermargin]
  [\c!renderingsetup=\??constructionrenderings:\v!outermargin]

\defineconstructionalternative
  [\v!serried]
  [\c!renderingsetup=\??constructionrenderings:\v!serried]

\defineconstructionalternative
  [\v!hanging]
  [%\c!width=.75\emwidth
   \c!renderingsetup=\??constructionrenderings:\v!hanging]

\defineconstructionalternative
  [\v!top]
  [\c!renderingsetup=\??constructionrenderings:\v!top,
   \c!width=\localhsize]

\defineconstructionalternative
  [\v!command]
  [\c!renderingsetup=\??constructionrenderings:\v!command]

\defineconstructionalternative
  [\v!empty]
  [\c!renderingsetup=\??constructionrenderings:\v!empty]

\defineconstructionalternative
  [\v!label]
  [\c!renderingsetup=\??constructionrenderings:\v!label,
   \c!width=]

\newbox      \constructionheadbox
\newgluespec \leftconstructionskip
\newgluespec \rightconstructionskip
\newdimension\constructionsheadwidth
\newdimension\constructionsheaddistance

\def\strc_constructions_set_hang_box#1% messy left/rightskip
  {\setbox\constructionheadbox\vtop   % \vbox gaat fout in hang
     {\forgetall
      \dontcomplain
      \hsize\constructionsheadwidth\relax
      \ifempty\p_strc_constructions_headalign
        \setupalign[#1]% use fast one
      \else
        \setupalign[\p_strc_constructions_headalign]% use fast one
      \fi
      \ifconditional\c_strc_constructions_distance_none \else
        \advanceby\ifx#1\v!flushleft\rightskip\else\leftskip\fi\constructionsheaddistance % only difference and wrong anyway
      \fi
      \flushconstructionheadbox}%
   \setbox\constructionheadbox\hpack{\box\constructionheadbox}% needed in case of e.g. a real big head font, see descriptions-006.tex
   \ht\constructionheadbox\strutht
   \dp\constructionheadbox\strutdp}

\def\strc_constructions_set_pure_box#1% default ... better set up differently
  {\setbox\constructionheadbox\vtop
     {\forgetall
      \dontcomplain
      \hsize\constructionsheadwidth\relax
      \ifempty\p_strc_constructions_headalign
        \setupalign[#1]% use fast one
      \else
        \setupalign[\p_strc_constructions_headalign]% use fast one
      \fi
      \flushconstructionheadbox}%
   \setbox\constructionheadbox\hpack{\box\constructionheadbox}% needed in case of e.g. a real big head font, see descriptions-006.tex
   \ht\constructionheadbox\strutht
   \dp\constructionheadbox\strutdp}

\def\strc_constructions_set_hang#1%
  {\ifempty\p_strc_constructions_hang
     % nothing
   \orelse\ifx\p_strc_constructions_hang\v!fit
     \scratchdimen\htdp\constructionheadbox
     \getnoflines\scratchdimen
     \hangafter-\noflines
   \orelse\ifx\p_strc_constructions_hang\v!broad
     \scratchdimen{\htdp\constructionheadbox+.5\strutht}%
     \getnoflines\scratchdimen
     \hangafter-\noflines
   \else
     \hangafter-\p_strc_constructions_hang
   \fi
   \relax
   \hangindent\ifx#1\v!right-\fi\constructionsheadwidth}

\permanent\protected\def\flushconstructionheadbox
  {\ifhbox\constructionheadbox\unhbox\else\box\fi\constructionheadbox}

% The setups. These only deal with placement of the descriptor and initializing the
% environment. The wrapping happens elsewhere.

% todo: optimize the setups with
%
% \ifconditional\c_strc_constructions_distance_none : no need for skip
% \ifzeropt\wd\constructionheadbox : no need for box and skips

\startsetups[\??constructionrenderings:\v!left]
    \edef\p_strc_constructions_hang{\constructionparameter\c!hang}%
    \doifelsesetups{\??constructionrenderings:\v!left:\p_strc_constructions_hang} {
        \directsetup{\??constructionrenderings:\v!left:\p_strc_constructions_hang}
    } {
        \directsetup{\??constructionrenderings:\v!left:\v!hanging}
    }
\stopsetups

\startsetups[\??constructionrenderings:\v!right]
    \edef\p_strc_constructions_hang{\constructionparameter\c!hang}
    \doifelsesetups{\??constructionrenderings:\v!right:\p_strc_constructions_hang} {
        \directsetup{\??constructionrenderings:\v!right:\p_strc_constructions_hang}
    } {
        \directsetup{\??constructionrenderings:\v!right:\v!hanging}
    }
\stopsetups

\startsetups[\??constructionrenderings:\v!left:\v!none]
    \enforced\let\\\crlf
    \noindent
    \strc_constructions_set_pure_box\v!flushleft
    \leftskip{\leftconstructionskip+\constructionsheadwidth+\constructionsheaddistance}%
    \rightskip\rightconstructionskip\relax
    \llap {
        \hpack to \leftskip {
            \hskip\leftconstructionskip
            \box\constructionheadbox % was copy
            \hss
        }
    }
    \nobreak
    \useconstructionstyleandcolor\c!style\c!color
    \ignorespaces
\stopsetups

\startsetups[\??constructionrenderings:\v!left:0]
    \directsetup{\??constructionrenderings:\v!left:\v!none}
\stopsetups

\startsetups[\??constructionrenderings:\v!left:]
    \directsetup{\??constructionrenderings:\v!left:\v!none}
\stopsetups

\startsetups[\??constructionrenderings:\v!right:\v!none]
    \enforced\let\\\crlf
    \noindent
    \leftskip\leftconstructionskip
    \rightskip{\rightconstructionskip+\constructionsheadwidth}%
   %\strc_constructions_pure_hang_box\raggedleft
    \strc_constructions_set_pure_box\v!flushright
    \rlap {
        \hskip{\hsize-\leftskip-\rightskip}%
        \copy\constructionheadbox
        \hskip\rightconstructionskip
    }
    \nobreak
    \advanceby\rightskip \constructionsheaddistance
    \useconstructionstyleandcolor\c!style\c!color
    \ignorespaces
\stopsetups

\startsetups[\??constructionrenderings:\v!right:0]
    \directsetup{\??constructionrenderings:\v!right:\v!none}
\stopsetups

\startsetups[\??constructionrenderings:\v!right:]
    \directsetup{\??constructionrenderings:\v!right:\v!none}
\stopsetups

\startsetups[\??constructionrenderings:\v!left:\v!margin]%
    \enforced\let\\\crlf
    \noindent
    \strc_constructions_set_pure_box\v!flushleft
    \llap {
        \hpack to \constructionsheadwidth {
            \box\constructionheadbox % was copy
            \hss
        }
        \hskip\constructionsheaddistance
    }
    \useconstructionstyleandcolor\c!style\c!color
    \ignorespaces
\stopsetups

\startsetups[\??constructionrenderings:\v!right:\v!margin]%
    \enforced\let\\\crlf
    \noindent
    \strc_constructions_set_pure_box\v!flushright
    \rlap {
        \hskip\constructionsheaddistance
        \hpack to \constructionsheadwidth {
            \box\constructionheadbox % was copy
            \hss
        }
    }
    \useconstructionstyleandcolor\c!style\c!color
    \ignorespaces
\stopsetups

\startsetups[\??constructionrenderings:\v!left:\v!hanging]%
    \enforced\let\\\crlf
    \dontcomplain
    \advanceby\constructionsheadwidth \constructionsheaddistance
    \strc_constructions_set_hang_box\v!flushleft
    \strc_constructions_set_hang\v!left
    \noindent
    \llap {
        \tpack to \zeropoint {
            \box\constructionheadbox
        }
    }
    \nobreak
    \useconstructionstyleandcolor\c!style\c!color
    \ignorespaces
\stopsetups

\startsetups[\??constructionrenderings:\v!right:\v!hanging]%
    \enforced\let\\\crlf
    \dontcomplain
    \advanceby\constructionsheadwidth \constructionsheaddistance
    \strc_constructions_set_hang_box\v!flushright
    \strc_constructions_set_hang\v!right
    \noindent
    \rlap {
        \hpack to {\hsize-\leftskip-\rightskip} {
            \hss
            \tpack to \zeropoint {
                \box\constructionheadbox
            }
        }
    }
    \nobreak
    \useconstructionstyleandcolor\c!style\c!color
    \ignorespaces
\stopsetups

\startsetups[\??constructionrenderings:\v!top]
  % \strc_sectioning_prevent_page_break % commented per 31/5/2019
    \enforced\let\\\space
    \noindent
    \copy\constructionheadbox % why copy ?
    \par
    \nobreak
    \edef\p_strc_constructions_inbetween{\constructionparameter\c!inbetween}%
    \ifempty\p_strc_constructions_inbetween \else
      \p_strc_constructions_inbetween
      % shouldn't this move to after the fi?
      \directcheckedvspacing\v!samepage
    \fi
    \useconstructionstyleandcolor\c!style\c!color
    \ignorespaces
\stopsetups

% why copy? historic reason?

\startsetups[\??constructionrenderings:\v!margin]
    \enforced\let\\\crlf
    \noindent
    \inmargin[\c!scope=\v!local]{\flushconstructionheadbox}%
    \useconstructionstyleandcolor\c!style\c!color
    \ignorespaces
\stopsetups

\startsetups[\??constructionrenderings:\v!leftmargin]
    \enforced\let\\\crlf
    \noindent
    \inleft[\c!scope=\v!local]{\flushconstructionheadbox}%
    \useconstructionstyleandcolor\c!style\c!color
    \ignorespaces
\stopsetups

\startsetups[\??constructionrenderings:\v!rightmargin]
    \enforced\let\\\crlf
    \noindent
    \inright[\c!scope=\v!local]{\flushconstructionheadbox}%
    \useconstructionstyleandcolor\c!style\c!color
    \ignorespaces
\stopsetups

\startsetups[\??constructionrenderings:\v!innermargin]
    \enforced\let\\\crlf
    \noindent
    \ininner[\c!scope=\v!local]{\flushconstructionheadbox}%
    \useconstructionstyleandcolor\c!style\c!color
    \ignorespaces
\stopsetups

\startsetups[\??constructionrenderings:\v!outermargin]
    \enforced\let\\\crlf
    \noindent
    \inouter[\c!scope=\v!local]{\flushconstructionheadbox}%
    \useconstructionstyleandcolor\c!style\c!color
    \ignorespaces
\stopsetups

\startsetups[\??constructionrenderings:\v!inmargin]
    \directsetup{\??constructionrenderings:\v!margin}
\stopsetups

\startsetups[\??constructionrenderings:\v!inleft]
    \directsetup{\??constructionrenderings:\v!leftmargin}
\stopsetups

\startsetups[\??constructionrenderings:\v!inright]
    \directsetup{\??constructionrenderings:\v!rightmargin}
\stopsetups

\startsetups[\??constructionrenderings:\v!serried]
    % already set?
    \edef\p_strc_constructions_width{\constructionparameter\c!width}% CHECK ! ! ! wrong parameter namespace
    \doifelsesetups{\??constructionrenderings:\v!serried:\p_strc_constructions_width} {
        \directsetup{\??constructionrenderings:\v!serried:\p_strc_constructions_width}
    } {
        \directsetup{\??constructionrenderings:\v!serried:\v!wide}
    }
\stopsetups

\startsetups[\??constructionrenderings:\v!serried:\v!fit]
    \enforced\let\\\crlf
    \noindent
    \flushconstructionheadbox
    \nobreak
    \hskip\constructionsheaddistance\relax
    \useconstructionstyleandcolor\c!style\c!color
    \ignorespaces
\stopsetups

\startsetups[\??constructionrenderings:\v!serried:\v!broad]
    \enforced\let\\\crlf
    \noindent
    \flushconstructionheadbox
    \ifconditional\c_strc_constructions_distance_none \else
        \nobreak
        \hskip\constructionsheaddistance
          \s!plus \constructionalternativeparameter\c!stretch\constructionsheaddistance
          \s!minus\constructionalternativeparameter\c!shrink \constructionsheaddistance
        \relax
    \fi
    \useconstructionstyleandcolor\c!style\c!color
    \ignorespaces
\stopsetups

\startsetups[\??constructionrenderings:\v!serried:]
    \directsetup{\??constructionrenderings:\v!serried:\v!broad}
\stopsetups

\startsetups[\??constructionrenderings:\v!serried:\v!wide]
    \enforced\let\\\crlf
    \noindent
    \hbox to \constructionsheadwidth {
        \flushconstructionheadbox
        \hss
    }
    \nobreak
    \hskip\constructionsheaddistance\relax
    \useconstructionstyleandcolor\c!style\c!color
    \ignorespaces
\stopsetups

\startsetups[\??constructionrenderings:\v!hanging]
    % tricky: leftskipadaption is somewhat unpredictable
    \enforced\let\\\crlf
    \noindent
    \advanceby\leftskip-\leftskipadaption\relax
    \ifdim\leftskipadaption=\zeropoint
        \leftskipadaption1.5\emwidth\relax % just some default
        \ifnum\c_strc_constructions_nested_state=\plusone
            \ifdim\leftskip>\zeropoint \relax
                \leftskipadaption\leftskip
            \fi
        \fi
    \fi
    \ifnum\c_strc_constructions_nested_state>\zerocount % was \ifnum\c_strc_constructions_nested_state=\plusone
        \advanceby\leftskip\leftskipadaption % but we're already further on
    \fi
    \hskip-\leftskipadaption\relax
    \ifhbox\constructionheadbox \unhbox\else\box\fi\constructionheadbox
    \ifconditional\c_strc_constructions_distance_none \else
      % we used to have just a kern, but long lines look bad then
      \scratchdistance\ifdim\constructionsheaddistance=\zeropoint .75\emwidth\else\constructionsheaddistance\fi
      \hskip \scratchdistance
        \s!plus \constructionalternativeparameter\c!stretch\scratchdistance
        \s!minus\constructionalternativeparameter\c!shrink \scratchdistance
    \fi
    \ifhmode
        \ifx\p_strc_constructions_width\v!line
            \hfill\break
        \else
            \allowbreak
        \fi
    \fi
    \useconstructionstyleandcolor\c!style\c!color
    \ignorespaces
\stopsetups

%D \starttyping
%D \setupfootnotation[location=command,headcommand=\llap]
%D \stoptyping

\startsetups[\??constructionrenderings:\v!command]
    \noindent
    \constructionparameter\c!headcommand{\flushconstructionheadbox}
    \useconstructionstyleandcolor\c!style\c!color
    \ignorespaces
\stopsetups

\startsetups[\??constructionrenderings:\v!empty]
    \noindent
    \useconstructionstyleandcolor\c!style\c!color
    \ignorespaces
\stopsetups

\startsetups[\??constructionrenderings:\v!label]
    \dontleavehmode
    \begingroup
    \constructionparameter\c!headcommand{\flushconstructionheadbox}
    \endgroup
\stopsetups

% \definedescription[whatever][alternative=right:bottom]
%
% \startwhatever{just a small\\example}
%     \input ward
% \stopwhatever

\defineconstructionalternative
  [\v!right:\v!bottom]
  [%\c!width=7em,
   %\c!distance=1em,
   \c!alignbottom=\v!yes,
   \c!renderingsetup=\??constructionrenderings:\v!right:\v!bottom]

\startsetups[\??constructionrenderings:\v!right:\v!bottom]
    \enforced\let\\\crlf
    \noindent
    \leftskip\leftconstructionskip
    \rightskip{\rightconstructionskip+\constructionsheadwidth+\constructionsheaddistance}%
    \parfillskip\zeroskip
    \strc_constructions_set_pure_box\v!flushright
    \directparwrapper \relax {%
      \hfilll
      \rlap
        {\kern\constructionsheaddistance
         \copy\constructionheadbox}%
    }%
    \useconstructionstyleandcolor\c!style\c!color
    \ignorespaces
\stopsetups

%D This next feature will get an lmtx implementation (probably by using a new generic
%D close mechanism).

% you can use \placeclosesymbol or \qed to place a symbol at the end of a
% construction

\installcorenamespace{constructionclosesymbol}

\mutable\let\placeclosesymbol\donothing
\mutable\let\qed             \donothing

\def\strc_constructions_close_symbol_reset % no need for global
  {\global\csname\??constructionclosesymbol\currentconstruction\endcsname\conditionaltrue
   \let\placeclosesymbol\strc_constructions_close_symbol_place
   \let\qed             \strc_constructions_close_symbol_place}

\protected\def\strc_constructions_close_symbol_place
  {\ifconditional\csname\??constructionclosesymbol\currentconstruction\endcsname
     \global\csname\??constructionclosesymbol\currentconstruction\endcsname\conditionalfalse
     \edef\p_strc_constructions_closesymbol{\constructionparameter\c!closesymbol}%
     \ifempty\p_strc_constructions_closesymbol \else
       \constructionparameter\c!closecommand{\p_strc_constructions_closesymbol}% hm why {} maybe because box expected
     \fi
   \fi}

\newif\ifnoconstructioncaption

%D The storage macros:

\mutable\let\currentconstructionlistentry\!!zerocount

\protected\def\strc_constructions_register
  {\clf_doifelselisthasentry{\currentconstructionlistentry}%
     \strc_constructions_register_nop
     \strc_constructions_register_yes}

% \def\strc_constructions_register{\strc_constructions_register_yes}

\def\strc_constructions_register_nop[#S#1][#S#2]% #1=optional user data #2=interfaced-settings
 %{\writestatus{constructions}{reusing \currentconstruction: \number\currentconstructionlistentry}}
  {}

\def\strc_constructions_discard
  {\iftrialtypesetting
   % \writestatus{constructions}{discarding \currentconstruction: \number\currentconstructionlistentry}%
     \clf_discardfromlist\currentconstructionlistentry\relax
   \fi}

\let\currentconstructionlistnumber \!!zerocount
\let\currentconstructionsynchronize\relax
\let\currentconstructionattribute  \attributeunsetvalue

\def\strc_constructions_register_yes[#S#1][#S#2]% #1=optional user data #2=interfaced-settings
  {\begingroup                              % similar to structure so we might generalize this
   \setupcurrentconstruction[#2]%           % xdef's will become edef's
   \xdef\currentconstructionexpansion      {\constructionparameter\c!expansion}%
   \xdef\currentconstructionxmlsetup       {\constructionparameter\c!xmlsetup}%
   \xdef\currentconstructioncatcodes       {\constructionparameter\s!catcodes}%
   \xdef\currentconstructionlabel          {\constructionparameter\c!label}%
   \xdef\currentconstructionreference      {\constructionparameter\c!reference}%
   \xdef\currentconstructionreferencetext  {\constructionparameter\c!referencetext}%
   \xdef\currentconstructionreferenceprefix{\constructionparameter\c!referenceprefix}%
   %xdef\currentconstructionshownumber     {\constructionparameter\c!number}%
   \xdef\currentconstructionincrementnumber{\constructionparameter\c!incrementnumber}%
   %
   \ifempty\currentconstructionexpansion
     \glet\currentconstructionexpansion\v!no
   \fi
   %
   \ifempty\currentconstructionreferenceprefix
     \glet\currentconstructionreferenceprefix\referenceprefix
   \fi
   \ifx\currentconstructionexpansion\s!xml
     \xmlstartraw
       \xdef\currentconstructiontitle        {\constructionparameter\c!title}%
       \xdef\currentconstructionbookmark     {\constructionparameter\c!bookmark}%
       \xdef\currentconstructionmarking      {\constructionparameter\c!marking}%
       \xdef\currentconstructionlist         {\constructionparameter\c!list}%
       \xdef\currentconstructionreferencetext{\constructionparameter\c!referencetext}%
     \xmlstopraw
     \ifempty\currentconstructionlist
       \glet\currentconstructionlist\currentconstructiontitle
     \fi
     \glet\currentconstructioncoding\s!xml
   \else
     \ifx\currentconstructionexpansion\v!yes
       \xdef\currentconstructiontitle        {\constructionparameter\c!title}%
       \xdef\currentconstructionbookmark     {\constructionparameter\c!bookmark}%
       \xdef\currentconstructionmarking      {\constructionparameter\c!marking}%
       \xdef\currentconstructionlist         {\constructionparameter\c!list}%
       \xdef\currentconstructionreferencetext{\constructionparameter\c!referencetext}%
     \else
       \xdef\currentconstructiontitle        {\detokenizedconstructionparameter\c!title}%
       \xdef\currentconstructionbookmark     {\detokenizedconstructionparameter\c!bookmark}%
       \xdef\currentconstructionmarking      {\detokenizedconstructionparameter\c!marking}%
       \xdef\currentconstructionlist         {\detokenizedconstructionparameter\c!list}%
       \xdef\currentconstructionreferencetext{\detokenizedconstructionparameter\c!referencetext}%
       \iflocation \ifempty\currentconstructionbookmark
         \begingroup
         \simplifycommands
         \xdef\currentconstructionbookmark{\detokenize\expandafter{\expanded{\constructionparameter\c!title}}}%
         \endgroup
       \fi \fi
     \fi
     \ifempty\currentconstructionlist
       \glet\currentconstructionlist\currentconstructiontitle
     \fi
     \glet\currentconstructioncoding\s!tex
   \fi
   %
   \ifx\currentconstructiontitle\v!none % will become obsolete
     \global\noconstructioncaptiontrue
   \fi
   %
   \ifnoconstructioncaption % then why analyze anyway?
     \endgroup
     \let\currentconstructionlistnumber \relax
     \let\currentconstructionsynchronize\relax
     \let\currentconstructionattribute  \relax
   \else
     \setnextinternalreferences{construction}\currentconstructionmain % plural
     \relax
     \scratchcounter\clf_addtolist
        metadata {
            kind     {construction}
            name     {\currentconstructionmain}
          % level    structures.sections.currentlevel()
            catcodes \catcodetable
        }
        references {
            internal  \locationcount
            order     \locationorder
            reference {\currentconstructionreference}
            prefix    {\currentconstructionreferenceprefix}
          % block     {\currentsectionblock}
          % section   structures.sections.currentid(),
        }
        titledata  {
            label     {\detokenize\expandafter{\currentconstructionlabel}}
            title     {\detokenize\expandafter{\currentconstructiontitle}}
        \ifx\currentconstructionbookmark\currentconstructiontitle \else
            bookmark  {\detokenize\expandafter{\currentconstructionbookmark}}
        \fi
        \ifx\currentconstructionreferencetext\currentconstructiontitle \else
            reference {\detokenize\expandafter{\currentconstructionreferencetext}}
        \fi
        \ifx\currentconstructionlist\currentconstructiontitle \else
            list      {\detokenize\expandafter{\currentconstructionlist}}
        \fi
        }
    \ifconditional\c_strc_constructions_number_state
        prefixdata {
            prefix        {\constructionparameter\c!prefix}
            separatorset  {\constructionparameter\c!prefixseparatorset}
            conversion    {\constructionparameter\c!prefixconversion}
            conversionset {\constructionparameter\c!prefixconversionset}
            set           {\constructionparameter\c!prefixset}
            segments      {\constructionparameter\c!prefixsegments}
            connector     {\constructionparameter\c!prefixconnector}
        }
        numberdata {
            numbers       {\currentconstructionnumber}
            separatorset  {\constructionparameter\c!numberseparatorset}
            conversion    {\constructionparameter\c!numberconversion}
            conversionset {\constructionparameter\c!numberconversionset}
            starter       {\constructionparameter\c!numberstarter}
            stopper       {\constructionparameter\c!numberstopper}
            segments      {\constructionparameter\c!numbersegments}
        }
    \else
       % symbol
    \fi
        userdata {\detokenize{#1}}
     \relax
   % \writestatus{constructions}{registering \currentconstruction: \number\scratchcounter}%
     \clf_setinternalreference
       prefix    {\currentconstructionreferenceprefix}%
       reference {\currentconstructionreference}%
       internal  \locationcount
       view      {\interactionparameter\c!focus}%
     \relax
     \expanded {%
       \endgroup
       \edef\noexpand\currentconstructionlistentry  {\the\scratchcounter}%
       \edef\noexpand\currentconstructionattribute  {\the\lastdestinationattribute}%
       \edef\noexpand\currentconstructionsynchronize{\clf_deferredenhancelist\the\scratchcounter}%
     }%
   \fi}

% This is not so nice, some day I'll just store the number with the entry
% and deal with all at the Lua end, but first we need to be able to set
% macros.

\permanent\protected\def\reinstateconstructionnumberentry#1% was xdef
  {\edef\currentconstructionattribute  {\clf_getinternallistreference#1}%
   \edef\currentconstructionsynchronize{\clf_deferredenhancelist\number#1}}

\permanent\protected\def\reinstatecachedconstructionnumberentry#1% was xdef | #1 = cached index can be different from real
  {\edef\currentconstructionattribute  {\clf_getinternalcachedlistreference#1}% destination
   \edef\currentconstructionsynchronize{\clf_deferredenhancelist\number#1}}

\installstructurelistprocessor{construction}{\usestructurelistprocessor{number+title}}

% Helpers:

\def\currentconstructionnumber{\constructionparameter\s!counter}

\protected\def\strc_constructions_next_indeed #get#tag#level{\strc_counters_increment_sub{#get{#tag}\s!counter}{#level}}
\protected\def\strc_constructions_reset_indeed#get#tag#level{\strc_counters_reset_sub    {#get{#tag}\s!counter}{#level}}

\protect \endinput