strc-lst.mkii / last modification: 2020-01-30 14:15
%D \module
%D   [       file=strc-lst,
%D        version=1997.03.31,
%D          title=\CONTEXT\ Structure Macros,
%D       subtitle=Lists,
%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 / Lists}

\unprotect

% \getlistlevel[hoofdstuk]\test{0} \test

% can be made faster if needed

\def\getlistlevel[#1]#2#3% [list] \variable \default
  {\doifdefinedelse{\??ko#1\c!section}
     {\edef#2{\getvalue{\??ko#1\c!section}}%
      \doifdefinedelse{\??se#2\c!level}
        {\edef#2{\getvalue{\??se#2\c!level}}}
        {\edef#2{#3}}}
     {\edef#2{#3}}}

% Auto cross document links work by either using logical or
% page references, depending on the general settings. The
% locations are stored in global references where the auto tag
% number uses the text container. We use reference mapping
% (define reference) to keep track of the current ref.

% \@@sectie == current level

\def\dowritetolist#1%
  {\doifelsevalue{\??li#1\c!state}\v!start
     \dodowritetolist\gobblefourarguments{#1}}

\long\def\dodowritetolist#1#2#3#4%
  {\begingroup
   \expanded{\everylistentry\emptytoks\the\everylistentry}% \emptytoks, else loop
   \def\currentlist{#1}% evt naar dowritetolist
   \defconvertexpanded\asciilistentry{\getvalue{\??li\currentlist\c!expansion}}{#3}%
   \makesectionformat
   \doifelse\@@nmstate\v!start
     {\def\dopagenummer{\noexpand\pagenumber}}
     {\let\dopagenummer\!!zerocount}%
   % niet waterdicht, wat te doen met figuren en zo
   % first hack: scheelt rommel, second hack: alleen koppen
   \doifelsevalue{\??rf\currentlist\c!state}\v!start
     {\doif{\@@sectionlevel\@@sectie}{0}\autocrossdocumentfalse}
     {\autocrossdocumentfalse}%
   % weak and inefficient
   \ifautocrossdocument
     \bgroup
     \thisisnextinternal\currentlist
    %\thisisdestination{\currentlist::\sectionformat}%
     \expanded{\setsectieenkoppeling{\currentlist}}%
     \edef\currentlevel{\@@sectionlevel\@@sectie}%
     \processcommacommand[\crossdocumentreferences]\dododowritetolist
     \egroup
   \else
     \thisisnextinternal\currentlist
   \fi
   \expanded
     {\writeutilitycommand % todo: also an immediate option
        {\noexpand\listentry
           {\currentlist}%
           {\nextinternalreference}%
           {#2}%
           {\asciilistentry}%
           {\sectionformat\sectionseparator\sectionseparator\dopagenummer}%
           {\noexpand\realfolio}}}%
   \endgroup}

\def\dododowritetolist#1%
  {\def\docommand##1%
     {\doifvalue{\??rf##1\c!state}\v!start
        {\setsectieenkoppeling{##1}%
         \def\level{\@@sectionlevel\@@sectie}%
         \ifnum\level>\currentlevel
           \expanded{\definereference[#1::##1][\v!none]}%
         \else\ifnum\level=\currentlevel
           \expanded{\definereference[#1::##1][#1::{##1::\sectionformat}]}%
         \fi\fi}}%
   \processcommacommand[\crossdocumentelements]\docommand}

% so far

\def\dowritebetweenlist#1#2%
  {\doifvalue{\??li#1\c!state}\v!start
     {\begingroup
      \defconvertedargument\ascii{#2}%
      \makesectionformat
      \doifelse{\@@nmstate}\v!start
        {\def\dopagenummer{\noexpand\pagenumber}}
        {\let\dopagenummer\!!zerocount}%
      \expanded
        {\writeutilitycommand
           {\noexpand\listbetween
              {#1}%
              {\ascii}%
              {\sectionformat\sectionseparator\sectionseparator\dopagenummer}%
              {\noexpand\realfolio}}}%
      \endgroup}}

% experimental (no nodes in mvl), needed for naw

\def\immediatetolist[#1]#2#3#4%
  {\begingroup
   \defconvertexpanded\asciilistentry{\getvalue{\??li#1\c!expansion}}{#3}%
   \makesectionformat
   \immediatewriteutilitycommand
     {\listentry
        {#1}{}{#2}{\asciilistentry}%
        {\sectionformat\sectionseparator\sectionseparator\number#4}%
        {\realfolio}}%
   \endgroup}

\def\immediatebetweenlist[#1]#2%
  {\begingroup
   \defconvertedargument\asciilistentry{#2}%
   \makesectionformat
   \immediatewriteutilitycommand
     {\listbetween
        {#1}{\asciilistentry}%
        {\sectionformat\sectionseparator\sectionseparator0}%
        {\realfolio}}%
   \endgroup}

\def\setlistentries
  {\def\listentry  ##1{\executeifdefined{##1\c!list     }\gobblefivearguments }%
   \def\listbetween##1{\executeifdefined{##1\c!inbetween}\gobblethreearguments}}

\def\resetlistentries
  {\let\listentry  \gobblesixarguments
   \let\listbetween\gobblefourarguments}

\resetlistentries

\addutilityreset{listentries}

% old values:
%
% a: \def\listfill {\hskip 1.75em}
% b: \def\listfill {\hskip.5em\hfill}
% c: \def\listfill {\hskip.5em\listdots\hskip.5em}

% todo: interface them

% \setvalue{\??li\c!alternative a}% nr - tit - pag
%   {\def\listfill   {\hskip.25em\relax}%
%    \def\listskip   {0pt}%
%    \def\listwidth  {2em}%
%    \def\liststretch{10em}}

% \setvalue{\??li\c!alternative b}% nr - tit - fill - pag
%   {\def\listfill   {\hfill}%
%    \def\listskip   {5em}%
%    \def\listwidth  {2em}%
%    \def\liststretch{10em}}

% \setvalue{\??li\c!alternative c}% nr - tit - dots - pag
%   {\def\listfill   {\hskip.5em\listdots\hskip.5em\relax}%
%    \def\listskip   {5em}%
%    \def\listwidth  {0pt}%
%    \def\liststretch{10em}}

\def\listalternativeparameter#1%
  {\csname\??li\??li\listparameter\c!alternative#1\endcsname}

\def\setuplistalternative[#1]%
  {\dodoubleargument\getparameters[\??li\??li#1]}

 % \listfill cum suis will be replaced by the direct call

\def\listfill   {\listalternativeparameter\c!command }
\def\listskip   {\listalternativeparameter\c!distance}
\def\listwidth  {\listalternativeparameter\c!width   }
\def\liststretch{\listalternativeparameter\c!stretch }

% a : nr - tit - pag
% b : nr - tit - fill - pag
% c : nr - tit - dots - pag

\setuplistalternative[a][\c!distance=0pt,\c!width=2em,\c!stretch=10em,\c!command=\hskip.25em\relax]
\setuplistalternative[b][\c!distance=5em,\c!width=2em,\c!stretch=10em,\c!command=\hfill]
\setuplistalternative[c][\c!distance=5em,\c!width=0pt,\c!stretch=10em,\c!command=\hskip.5em\listdots\hskip.5em\relax]

\def\listdots{\leaders\hbox to .5em{\hss.\hss}\hfill}

% \starttext
%     \placelist[section][alternative=c]
%     \setuplistalternative[c][distance=1em,stretch=0em]
%     \placelist[section][alternative=c]
%     \section{test}
%     \section{\readfile{tufte}{}{}}
% \stoptext

\setvalue{\??li\c!alternative}{\getvalue{\??li\c!alternative b}}

\getvalue{\??li\c!alternative}

\def\setlistparameter#1#2#3{\@EA\def\csname\??li#1#2\endcsname{#3}} % often
\def\listparameter       #1{\csname\??li\currentlist#1\endcsname}

\def\dosetuplist[#1][#2]% slow -)
  {\def\docommand##1%
     {\getparameters[\??li##1][#2]%
      \preparepageprefix{\??li##1}}%
   \processcommalist[#1]\docommand}

\def\setuplist
  {\dodoubleargument\dosetuplist}

\def\dodosetlist#1%
  {\def\nolist{\splitsequence{\getvalue{\??li#1\c!limittext}}}%
   \setvalue{#1\c!inbetween}{\dobetweenlist{#1}}%
   \setvalue{#1\c!list     }{\dolistelement{#1}}}

% \def\dodoresetlist#1%
%   {\let\nolist\empty
%    \setvalue{#1\c!inbetween}{\gobblefourarguments{#1}}%
%    \setvalue{#1\c!list     }{\gobblesixarguments {#1}}}

\def\dodoresetlist#1%
  {\let\nolist\empty
   \letvalue{#1\c!inbetween}\gobblethreearguments
   \letvalue{#1\c!list     }\gobblefivearguments}

\let\nolist\empty

\def\dodefinelist[#1][#2][#3]%
  {\presetlocalframed[\??li#1]%
   \getparameters
     [\??li#1]
     [\c!height=\v!broad,
      \c!depth=\v!broad,
      \c!offset=0.25em,
      \c!maxwidth=,
      \c!align=,
      \c!state=\v!start,
      \c!coupling=\v!off,
      \c!criterium=\v!local,
      \c!width=3em,
      \c!alternative=\c!b,
      \c!style=\v!normal,
      \c!textstyle=\listparameter\c!style,
      \c!numberstyle=\listparameter\c!style,
      \c!pagestyle=\listparameter\c!style,
      \c!color=,
      \c!textcolor=\listparameter\c!color,
      \c!numbercolor=\listparameter\c!color,
      \c!pagecolor=\listparameter\c!color,
      \c!numbercommand=\listnumbercommand,
      \c!textcommand=\listtextcommand,
      \c!pagecommand=\listpagecommand,
      \c!pagenumber=\v!yes,
      \c!headnumber=\v!yes,
      \c!pageboundaries=,
      \c!margin=\!!zeropoint,
      \c!aligntitle=,
      \c!before=,
      \c!after=,
      \c!inbetween=,
      \c!symbol=,
      \c!interaction=\v!sectionnumber,
      \v!part\v!number=\v!yes,  % nodig ? % v
      %\c!prefix=\v!no, % we need to initialize it
      \c!label=\v!no,
      \c!distance=\!!zeropoint,
      \c!separator=\@@koseparator,
      \c!limittext=\@@kolimittext,
      \c!stopper=,
      \c!expansion=]%
   \doifassignmentelse{#2}
     {\getparameters[\??li#1][#2]}
     {\ConvertToConstant\doifnot{#2}{} % not \doifsomething ivm Convert...
        {\copyparameters % interactie ?
           [\??li#1][\??li#2]
           [\c!state,\c!width,\c!alternative,\c!style,\c!color,
            \c!textstyle,\c!textcolor,\c!textcommand,
            \c!pagestyle,\c!pagecommand,\c!pagecolor,
            \c!numberstyle,\c!numbercolor,\c!numbercommand,
            \c!headnumber,
            \c!pagenumber,\c!pageboundaries,\c!margin,\c!symbol,\c!limittext,
            \c!aligntitle,\c!before,\c!after,\c!inbetween,\v!part\c!number,\c!label]%
         \getparameters[\??li#1][#3]}}%
    \addutilityreset{#1}%
    \setvalue{\s!set  #1}{\dodosetlist  {#1}}%
    \setvalue{\s!reset#1}{\dodoresetlist{#1}}}

\def\definelist
  {\dotripleempty\dodefinelist}

\def\iflijstgeplaatst{\ifutilitydone} % obsolete, is now a mode

\def\placelist
  {\dodoubleempty\doplacelist}

\def\placerawlist
  {\dodoubleempty\doplacerawlist}

\def\dobeginoflist
  {\begingroup
   \startpacked[\v!blank]}

\def\doendoflist
  {\stoppacked
   \endgroup}

\def\doplacelist[#1][#2]%
  {\dobeginoflist
   \doplacerawlist[#1][#2]%
   \doendoflist}

\def\doplacerawlist[#1][#2]%
  {\begingroup
   \dogetcommalistelement1\from#1\to\firstlistelement
   \dosetuplist[#1][#2]%
   \doifvalue{\??li\firstlistelement\c!coupling}\v!on
     {\startlistreferences{#1}}%
   \dosettoclevel\??li\firstlistelement
   \honorlocalfilterlevel
   \doutilities{listentries,#1}\jobname{#1}\relax\par
   \stoplistreferences
   \dosetlistmode
   \endgroup}

% the simple approach:
%
% \def\dosettoclevel#1#2%
%   {\dosetfilterlevel{\getvalue{#1#2\c!criterium}}\empty}
%
% but we want to to support selection by number:
%
% \starttypen
% \placelist[section][criterium=chapter,number=1] \blank
% \placelist[section][criterium=chapter,number=2] \blank
% \placelist[section][criterium=chapter,number=3] \blank
%
% \chapter{first}  \section{AA} \section{BB}
% \chapter{second} \section{CC} \section{DD}
% \chapter{third}  \section{EE} \section{FF}
% \stoptypen

\def\dosettoclevel#1#2% todo: check if criterium is headid, else error
  {\ifundefined{#1#2\c!number}%
     \dosetfilterlevel{\getvalue{#1#2\c!criterium}}\empty
   \else
     % \doifnot{#2}\v!local ...
     \doifelsevaluenothing{#1#2\c!number}%
       {\dosetfilterlevel{\getvalue{#1#2\c!criterium}}\empty}
       {\setsectieenkoppeling{\getvalue{#1#2\c!criterium}}%
        \dosetfilterlevel
          {\previoussection\@@sectie}%
          {\getvalue{#1#2\c!number}}}%
   \fi}

\def\dosetlistmode
  {\ifutilitydone
     \setsystemmode  \v!list
   \else
     \resetsystemmode\v!list
   \fi}

\def\dodocompletelist[#1][#2][#3]%  enkelvoud, meervoud, instellingen
  {\expanded{\systemsuppliedtitle[#2]{\noexpand\headtext{#2}}}% expansion needed for v! vs french !
   \doplacelist[#1][#3]}

\def\docompletelist[#1][#2]%
  {\dodocompletelist[#1][#1][#2]}

\def\completelist
  {\dodoubleempty\docompletelist}

\def\listelements        {}   % list of page breaks
\def\listnumbercommand #1{#1} % no strut due to interactive version
\def\listtextcommand   #1{\begstrut#1\endstrut}
\def\listpagecommand   #1{\strut#1}

\def\doassigndimen#1#2#3%
  {\doifinsetelse{#2}{\v!fit,\v!broad}{#1=#3}{#1=#2}\relax}

% \let\dohandlelistnumber\firstofoneargument
%
% can be anything, so no \expanded{\separatednumber{#1}} !

\def\dohandlelistnumber#1{\separatednumber{#1}}

\def\listsymbol[#1]#2%
  {\begingroup
   \def\currentlist{#1}%
   \def\currentlistnumber{#2}%
   \currentlistsymbol
   \endgroup}

% Beware, the list symbol macro gets an argument passed, i.e. when this
% argument is not picked up, the symbol becomes a kind of prefix.

% for historical reasons we're stuck to symbols, so in order to generalize,
% we have to hook it into the symbol handler; we need a beter clean up later
%
% < 2005
%
% \def\dosetlistsymbol % #1
%   {\executeifdefined{listsymbol@\listparameter\c!symbol}\listsymbol@default} % {#1}
%
% >= 2005
%
% at this symbol level, we have access to the raw 'number' in
% \currentlistnumber

\definesymbol[\v!list][\v!none   ][\listsymbol@none   ]
\definesymbol[\v!list][\v!one    ][\listsymbol@one    ]
\definesymbol[\v!list][\v!two    ][\listsymbol@two    ]
\definesymbol[\v!list][\v!three  ][\listsymbol@three  ]
\definesymbol[\v!list][\s!default][\listsymbol@default]
\definesymbol[\v!list][\s!unknown][\listsymbol@unknown]

\def\currentlistsymbol
  {\doifinsymbolsetelse\v!list{\listparameter\c!symbol}
     {\directsymbol\v!list{\listparameter\c!symbol}}
     {\directsymbol\v!list\s!default}}

\def\listsymbol@none
  {\doassigndimen\scratchdimen{\listparameter\c!width}{1.5em}%
   \hbox to \scratchdimen{}}

\def\listsymbol@one
  {\strut$\bullet$}

\def\listsymbol@two
  {\vrule\!!width1em\!!height1ex\!!depth\zeropoint}

\def\listsymbol@three
  {\begingroup
   \doassigndimen{\dimen0}{\listparameter\c!width }{1.5em}%
   \doassigndimen{\dimen2}{\listparameter\c!height}{1ex}%
   \doassigndimen{\dimen4}{\listparameter\c!depth }\zeropoint
   \vrule\!!width\dimen0\!!height\dimen2\!!depth\dimen4%
   \endgroup}

\def\listsymbol@default
  {\doifelse{\listparameter\c!prefix}\v!no % ook nog eerste
     {\edef\splitlistsymbol{\@EA\removefirstprefix\@EA{\currentlistnumber}}}% one level expansion
     {\doifelse{\listparameter\c!prefix}\v!none
        {\edef\splitlistsymbol{\@EA\removeallprefixes\@EA{\currentlistnumber}}}%
        {\let\splitlistsymbol\currentlistnumber}}% geen \edef ivm 8 bit enz
    \doif{\listparameter\c!label}\v!yes{\leftlabeltext\currentlist}%
    \strut
    \def\numberseparator{\listparameter\c!separator}% overloaded, todo
    \@EA\dohandlelistnumber\@EA{\splitlistsymbol}%
    \listparameter\c!stopper
    \doif{\listparameter\c!label}\v!yes{\rightlabeltext\currentlist}}

\def\listsymbol@unknown
  {\listparameter\c!symbol}

% so far for list symbols

\def\@@dodolistelement{dodolistelement}

\def\dosomelistelement#1#2#3{#1 #2 \translatednumber[#3]}

\setvalue{\@@dodolistelement a}{\let\dosomelistelement\dodofixdlistelementABC}
\setvalue{\@@dodolistelement b}{\let\dosomelistelement\dodofixdlistelementABC}
\setvalue{\@@dodolistelement c}{\let\dosomelistelement\dodofixdlistelementABC}
\setvalue{\@@dodolistelement d}{\let\dosomelistelement\dodofixdlistelementD}
\setvalue{\@@dodolistelement e}{\let\dosomelistelement\dodofixdlistelementE}
\setvalue{\@@dodolistelement f}{\let\dosomelistelement\dodofixdlistelementF}
\setvalue{\@@dodolistelement g}{\let\dosomelistelement\dodofixdlistelementG}

\setvalue{\@@dodolistelement\v!none      }{\def\dosomelistelement{\dodofreevlistelement}}
\setvalue{\@@dodolistelement\v!vertical  }{\def\dosomelistelement{\dodofreevlistelement}}
\setvalue{\@@dodolistelement\v!horizontal}{\def\dosomelistelement{\dodofreehlistelement}}
\setvalue{\@@dodolistelement\v!command   }{\let\dosomelistelement\dodocommandlistelement}

% \setuplist
%   [section]
%   [alternative=MyListItem,
%    after=\blank,
%    before=\blank]
%
% \definelistplacement[MyListItem][none]#1#2#3%
%   {(#1) (#2) (#3)}

\def\definelistplacement
  {\dodoubleempty\dodefinelistplacement}

\def\dodefinelistplacement[#1][#2]%
  {\setvalue{\@@dodolistelement#1}%
     {\doifelsenothing{#2}
        {\getvalue{\@@dodolistelement\v!command}}%
        {\executeifdefined{\@@dodolistelement#2}
           {\getvalue{\@@dodolistelement\v!command}}}%
      \setvalue{\??li\currentlist\c!command}{\getvalue{\@@dodolistelement::#1}}}%
   \setvalue{\@@dodolistelement::#1}}

% don't mess arround with endgraf/grouping else we loose leftskip

% \strippedcsname\dodolistelement

\def\newlineinlist{\space}

\let\currentlist\s!unknown

\def\dolistelement#1#2#3#4#5#6% pas op: wordt ook elders gedefinieerd
  {\doiftoclevelelse[#5]{\dodolistelement{#1}{#2}{#3}{#4}{#5}{#6}}{}}

\def\dodolistelement#1#2#3#4#5#6%
  {\def\currentlist{#1}%
   \def\currentlistnumber{#3}%
   \getvalue{\@@dodolistelement\listparameter\c!alternative}%
   %\showcomposition
   \let\@@iawidth\!!zeropoint  % moet boolean worden
   \bgroup
   \edef\listelements
     {\listparameter\c!pageboundaries}%
   \ExpandBothAfter\doifinset{#3}\listelements
     {\showmessage\m!systems{14}{#3}%
      \page}%
   \egroup
   \dontcomplain
   \setfullsectionnumber{\??li\currentlist}%
   \dosomelistelement{#1}{#2}{#3}{#4}{#5}{#6}%
   \global\utilitydonetrue}

\def\donestedlistattributes#1#2%
  {\doifvaluesomething{\??li\currentlist#2} % color
     {\resetinteractionparameter\c!color
      \resetinteractionparameter\c!contrastcolor}%
   \dolistattributes{#1}{#2}}

\def\dostartlistattributes{\dostartattributes{\??li\currentlist}}
\def\dostoplistattributes {\dostopattributes}
\def\dolistattributes     {\doattributes{\??li\currentlist}}

\def\dodocommandlistelement#1#2#3#4#5#6%
  {\doifdefinedelse{\??li#1\c!command}
     {\listparameter\c!command
        {#3}{#4}{\pageprefix\??li\currentlist[#5]\translatednumber[#5]}}
     {[\currentlist: #3 - #4 - \pageprefix\??li\currentlist[#5]\translatednumber[#5]]}}

\def\dodofreelistelement#1#2#3#4#5#6#7#8%
  {\def\makelistelement##1##2%
     {\noindent % new and needed
      \hbox
        {\doifelse{\listparameter\c!interaction}{##1} % \??li ipv \??ia
           {\setbox0\hbox{\showcontrastlocation{\??li\currentlist}{#6}{##2}}%
            \linklisttoelement{#2}{#5}{#6}{\box0}}%{\copy0}}%
           {##2}}}%
   \listparameter\c!before% can be \hskip
   \doifdefinedelse{\??li#1\c!command}
     {\makelistelement{\listparameter\c!interaction}% this forces all
        {\listparameter\c!command
           {#3}% geen conversies etc
           {#4}% geen conversies etc
           {\pageprefix\??li\currentlist[#5]%
            \translatednumber[#5]}}}
     {#7%
      \vbox
        {\forgetall
         \makelistelement\v!all
           {%
\doif{\listparameter\c!headnumber}\v!yes
              {\makelistelement\v!sectionnumber
                 {\donestedlistattributes\c!numberstyle\c!numbercolor
                    {\listparameter\c!numbercommand{\currentlistsymbol}}}%
}%
            \makelistelement\v!text
              {\donestedlistattributes\c!textstyle\c!textcolor
                 {\let\\=\newlineinlist
                  \dontconvertfont
                  \listparameter\c!textcommand{#4}}}%
            \doif{\listparameter\c!pagenumber}\v!yes
              {\doifsomething{#5}
                 {\makelistelement\v!pagenumber
                    {\donestedlistattributes\c!pagestyle\c!pagecolor
                       {\listparameter\c!pagecommand
                          {\pageprefix\??li\currentlist[#5]%
                           \translatednumber[#5]}}}}}}}%
      #8}%
   \listparameter\c!after}

\def\dodofreehlistelement#1#2#3#4#5#6%
  {\dodofreelistelement{#1}{#2}{#3}{#4}{#5}{#6}
     {\noindent}{}}

\def\dodofreevlistelement#1#2#3#4#5#6%          % \nointerlineskip needed,
  {\dodofreelistelement{#1}{#2}{#3}{#4}{#5}{#6} % otherwise wrong spacing
     {\ifvmode\nointerlineskip\fi}              % at multi-line lists
     {\ifvmode\nointerlineskip\fi\endgraf\allowbreak}} % test is saveguard

% to be documented: align, hang

% now also in abc

\def\limitatedlistentry#1%
  {\doifelsenothing{\listparameter\c!maxwidth}
     {\listparameter\c!textcommand{#1}}
     {\listparameter\c!textcommand
        {\limitatetext
           {#1}%
           {\listparameter\c!maxwidth}%
           {\splitsymbol{\listparameter\c!limittext}}}}}

\def\dodofixdlistelementABC#1#2#3#4#5#6% weeden
  {\endgraf
   \leftskip\listparameter\c!margin% na de \endgraf !
   \listparameter\c!before
   \!!widthc\listparameter\c!distance
   \doifelse{\listparameter\c!width}\v!fit
     {\!!widtha\zeropoint}
     {\doifelsenothing{#3}
        {\doifelse{\listparameter\c!aligntitle}\v!yes
           {\!!widtha\zeropoint
            \!!widthc\zeropoint}
           {\!!widtha\listparameter\c!width}}
        {\!!widtha\listparameter\c!width}}%
   \getvalue{\??li\c!alternative\listparameter\c!alternative}%
   \endgraf
   \def\makelistelement##1##2%
     {\doifelse{\listparameter\c!interaction}{##1}
        {\setbox0\hbox{\showcontrastlocation\??ia{#6}{##2}}%
         \linklisttoelement{#2}{#5}{#6}{\box0}}%{\copy0}}%
        {\hbox{##2}}}%
   \doif{\listparameter\c!interaction}\v!text % not supported ! ! ! ! ! ! text == all
     {\setlistparameter\currentlist\c!interaction\v!all}%
 % \dontleavehmode % new, else no margin, but wrong, better (else \indent as well):
   \noindent
   \makelistelement\v!all
     {\setlocalhsize
      \hsize\localhsize
      \hbox to \hsize
        {\forgetall
         \dostartlistattributes\c!style\c!color\empty
         \!!widthb\hsize
         \doifelse{\listparameter\c!headnumber}\v!yes
           {\setbox2\hbox \ifdim\!!widtha>\zeropoint to \!!widtha \fi
              {\makelistelement\v!sectionnumber
                 {\donestedlistattributes\c!numberstyle\c!numbercolor
                    {\listparameter\c!numbercommand{\currentlistsymbol}}%
               \hfill}}}
           {\!!widtha\zeropoint
            \!!widthc\zeropoint
            \setbox2\hbox{}}%
         \setbox4\hbox
           {\doif{\listparameter\c!pagenumber}\v!yes
              {\doifsomething{#5}    % \listwidth is new ; temp hack
                 {\hbox \ifdim\listwidth>\zeropoint to \listwidth\fi
                    {\hfill
                     \makelistelement\v!pagenumber
                       {\donestedlistattributes\c!pagestyle\c!pagecolor
                          {\listparameter\c!pagecommand
                             {\pageprefix\??li\currentlist[#5]%
                              \translatednumber[#5]}}}}}}}%
         \vbox
           {\hsize\!!widthb
            \setupalign[\listparameter\c!align]%
            \ifdim\!!widtha<\hsize
              \hangindent\wd2
              \dimen2=\!!widthc % \listparameter\c!distance
              \advance\hangindent \dimen2
              \hangafter\plusone
              \doif{\listparameter\c!hang}\v!no{\hangafter\zerocount}%
              \ifdim\wd4=\zeropoint % \ifvoid4
                % we kunnen gewoon afbreken aan het eind
              \else
                \ifdim\listskip>\zeropoint\relax
                  \rightskip\listskip\!!plus\liststretch\relax
                  \parfillskip-\rightskip
                \fi
              \fi
            \else
              \dimen2\zeropoint
            \fi
            \parindent\zeropoint\relax
            \leavevmode
            \box2\relax
            \hskip\dimen2
            \bgroup
            \donestedlistattributes\c!textstyle\c!textcolor
              {\let\\=\newlineinlist
               \dontconvertfont
              %\listparameter\c!textcommand{#4}}%
               \limitatedlistentry{#4}}%
              %\carryoverpar % new otherwise wrong linespacing
            \egroup
            \ifdim\wd4=\zeropoint\relax % \ifvoid4
              % \ifdim\!!widtha<\hsize \hfill\strut \fi % spoils align
            \else
              \nobreak\listfill
              \box4\relax
              \relax
            \fi}%
         \hss
         \dostoplistattributes}}% new
   \endgraf % new, else problems with nointerlinespace and prevdepth
   \nointerlineskip % anders verkeerde spatiering bij multi-line
   \endgraf
   \allowbreak
   \listparameter\c!after}

% % example from the context list
%
% \setuphead [part]    [page=right,placehead=yes]
% \setuplist [chapter] [alternative=d,before=\blank,after=\blank]
% \setuplist [part]    [before=\blank,after=\blank]
%
% \starttext
%   \startnarrower[2*right] \placecontent \stopnarrower
%   \blank[4*big]
%   \startsetups chapter
%     \blank \startnarrower[3*middle] \placecontent[criterium=local] \stopnarrower
%   \stopsetups
%   \placelist[part][criterium=text,after=\setups{chapter}]
%
%   \part{First part}       \chapter{Chapter one}  \chapter{Chapter two}
%   \chapter{Chapter three} \chapter{Chapter four} \chapter{Chapter five}
%   \part{Second part}      \chapter{Chapter one}  \chapter{Chapter two}
%   \chapter{Chapter three} \chapter{Chapter four} \chapter{Chapter five}
%   \part{Third part}       \chapter{Chapter one}  \chapter{Chapter two}
%   \chapter{Chapter three} \chapter{Chapter four} \chapter{Chapter five}
% \stoptext

% overrulen interactie kan sneller, bv door hulpconstanten
% te gebruiken en die te letten

\def\dodofixdlistelementD#1#2#3#4#5#6%
  {%\leftskip=\listparameter\c!margin
   \ifvmode
     \advance\leftskip\listparameter\c!margin%  AANGEPAST
   \fi
   \bgroup
   \ifvmode
     \noindent\leavevmode % leavevmode ? ? ?
   \fi
   \doif{\listparameter\c!interaction}\v!text % not supported
     {\setlistparameter\currentlist\c!interaction\v!sectionnumber}%
   \doif{\listparameter\c!interaction}\v!all % not supported
     {\setlistparameter\currentlist\c!interaction\v!sectionnumber}%
   \def\makelistelement##1##2%
     {\doifelse{\listparameter\c!interaction}{##1}
        {\setbox0\hbox{\showcontrastlocation\??ia{#6}{##2}}%
         \linklisttoelement{#2}{#5}{#6}{\box0}}%{\copy0}}%
        {\hbox{##2}}}%
   \setbox4\hbox
     {\doif{\listparameter\c!pagenumber}\v!yes
        {\doifsomething{#5}
           {\makelistelement\v!pagenumber
              {\donestedlistattributes\c!pagestyle\c!pagecolor
                 {\listparameter\c!pagecommand
                    {\pageprefix\??li\currentlist[#5]%
                     \translatednumber[#5]}}}}}}%
\doif{\listparameter\c!headnumber}\v!yes{%
   \donetrue
   \doifnothing{#3}{\doifnothing{\listparameter\c!symbol}\donefalse}%
   % == \doifnothing{#3\listparameter\c!symbol}\donefalse
   \ifdone
     \hbox
       {\listparameter\c!left
        \makelistelement\v!sectionnumber
          {\donestedlistattributes\c!numberstyle\c!numbercolor
             {\listparameter\c!numbercommand{\currentlistsymbol}}}%
          \listparameter\c!right
        \hskip.5em}%
     \nobreak
   \fi
}%
   \tolerance3500 % niet zomaar veranderen
   \donestedlistattributes\c!textstyle\c!textcolor
     {\let\\=\newlineinlist
      \dontconvertfont
     %\listparameter\c!textcommand{#4}}%
      \limitatedlistentry{#4}}%
   \ifvoid4\else
     \nobreak
     \hskip.75em\relax
     \nobreak
     \box4
   \fi
   \dimen0=\listparameter\c!distance\relax
   \ifdim\dimen0<1em\relax
     \hskip1em\!!plus1em\!!minus.25em\relax
   \else
     \hskip\dimen0\!!plus.5\dimen0\!!minus.25\dimen0\relax
   \fi
   \egroup}

\def\dodofixdlistelementE#1%
  {\dodofixdlistelementEFG
     {\setupinteraction[\c!strut=\v!no]}
     {\localframed[\??li\currentlist][\c!depth=\!!zeropoint,\c!color=]}
     {}}

\def\dodofixdlistelementF#1%
  {\dodofixdlistelementEFG
     {}
     {\dosetraggedhbox{\listparameter\c!align}\raggedbox}
     {}}

\def\dodofixdlistelementG#1%
  {\dodofixdlistelementEFG
     {}
     \midaligned
     {}}

\def\dodofixdlistelementEFG#1#2#3#4#5#6#7#8%
  {\noindent
   \bgroup
   \def\makelistelement##1##2% isolated by Wolfgang Schuster
     {\doifelse{\listparameter\c!interaction}{##1}
        {#2{##2}}
        {\setbox0\hbox{#2{\showcontrastlocation\??ia{#8}{##2}}}%
         \linklisttoelement{#4}{#7}{#8}{\box0}}}%
   \makelistelement\v!no
     {\let\\=\newlineinlist
      #1% in case E nils the strut (still needed?)
      \dostartlistattributes\c!style\c!color\empty
      \ignorespaces\dontconvertfont\setstrut
      \begstrut
      \limitatedlistentry{#6}%
      \endstrut
      \dostoplistattributes}%
   \egroup
   \par
   \listparameter\c!inbetween}

% better:
%
% \def\linklisttoelement#1#2#3#4% % list location format page data
%   {\ifautocrossdocument
%     \gotodestination{}{}{\currentlist::\@@filterblocknumberpart[#2]}{#3}{#4}%
%    \else
%      \gotonextinternal\currentlist{#1}{#3}{#4}%
%    \fi}
%
% but for the moment:

\def\linklisttoelement#1#2#3#4% % list location format page data
  {\gotonextinternal\currentlist{#1}{#3}{#4}}

\def\writetolist[#1]#2#3%
  {\doifsomething{#1}
     {\defconvertedargument\firstlistelement{#2}%
      \@EA\dowritetolist\@EA{#1}{\firstlistelement}{#3}{\v!head}}}

\def\dobetweenlist#1#2#3#4% pas op: wordt ook elders gedefinieerd
  {\doiftoclevelelse[#3]{#2}{}}

\def\writebetweenlist[#1]#2%
  {\@EA\dowritebetweenlist\@EA{#1}{#2}} % #2 weg en \expanded

% NOG ENGELS MAKEN

\def\listlength{\utilitylistlength}
\def\listwidth {\utilitylistwidth}
\def\listheight{\utilitylistheight}

\def\utilitylistlength {0}
\def\utilitylistwidth  {0pt}
\def\utilitylistheight {0pt}

\def\dolistelementX#1#2#3#4#5#6%
  {\doiftoclevelelse[#5]
     {\doglobal\increment\utilitylistlength
      \hbox
        {\dolistattributes\c!textstyle\c!textcolor
          {\let\\=\newlineinlist
           \dontconvertfont
           \listparameter\c!textcommand{#4}}}%
      \global\utilitydonetrue}
     {}}

\def\dodeterminelistcharacteristics[#1][#2]%
  {\begingroup
   \doglobal\newcounter\utilitylistlength
   \let\dolistelement\dolistelementX
   \dosetuplist[#1][#2]%
   \dogetcommalistelement1\from#1\to\commalistelement
   \dosettoclevel\??li\commalistelement
   \setbox0\vbox{\doutilities{listentries,#1}\jobname{#1}\relax\par}%
   \xdef\utilitylistheight{\the\ht0}%
   \xdef\utilitylistwidth {\the\wd0}%
   \endgroup
   \dosetlistmode}

\def\determinelistcharacteristics
  {\dodoubleempty\dodeterminelistcharacteristics}

% \definerreferencelist
%   [externalfigure]
%   [command=\showbigfigure,
%    before=\page,
%    after=\page]
%
% \definereferencelist
%   [externaltable]
%   [command=\showbigtable,
%    before=\page,
%    after=\page]
%
% \def\showbigfigure#1%
%   {\externalfigure[#1][frame=on,factor=max]}
%
% \def\showbigtable#1%
%   {\switchtobodyfont[12pt]\getbuffer[#1]}
%
% \writetoreferencelist[externalfigure]{koe}  {\externalfigure[koe]  [width=3cm,frame=on]}
% \writetoreferencelist[externalfigure]{paard}{\externalfigure[paard][width=3cm,frame=on]}
%
% \startbuffer[kanweg]
% \starttable[|||]
% \HL
% \VL test \VL test \VL\SR
% \HL
% \VL test \VL test \VL\FR
% \VL test \VL test \VL\MR
% \VL test \VL test \VL\LR
% \HL
% \stoptable
% \stopbuffer
%
% \writetoreferencelist[externaltable]{kanweg}{\switchtbodyfont[5pt]\getbuffer[kanweg]}
%
% \placereferencelist[externalfigure,externaltable]

% algemeen

\def\referencebutton#1[#2]%
  {\hbox\bgroup               % the \hbox is needed to bypass
   \let\referenceprefix\empty % \dontleavehmode in \gotobox
   \setupinteraction[\c!color=,\c!contrastcolor=,\c!strut=]%
   \setupreferencing[\c!prefix=]%
   \gotobox{\hbox{\ignorespaces#1}}[#2]%
   \egroup}

\newcounter\referencecounter

\def\doreferencelistelement#1#2#3#4#5%
  {\doiftoclevelelse[#4]
     {\getvalue{\??rl#1\c!before}%
      \referencebutton
        {\getvalue{\??rl#1\c!command}{#3}\pagereference[\r!to#2]}%
        [\r!from#2]%
      \global\utilitydonetrue
      \getvalue{\??rl#1\c!after}}
     {}}

\def\doplacereferencelist[#1][#2]%
  {\begingroup
   \setupreferencelist[#1][#2,\c!state=\v!stop]%
   \dogetcommalistelement1\from#1\to\commalistelement
   \dosettoclevel\??rl\commalistelement
   \doutilities{listentries,#1}\jobname{#1}\relax\par
   \endgroup}

\def\placereferencelist
  {\dodoubleempty\doplacereferencelist}

\def\dowritetoreferencelist#1#2#3%
  {\doifvalue{\??rl#1\c!state}\v!start
     {\begingroup
      \makesectionformat
      \doifelse{\@@nmstate}\v!start
        {\def\dopagenummer{\noexpand\pagenumber}}
        {\let\dopagenummer\!!zerocount}%
      \expanded
        {\writeutilitycommand%
           {\noexpand\referencelistentry%
              {#1}%  tag
              {#2}%  number
              {#3}%  data
              {\sectionformat\sectionseparator\sectionseparator\dopagenummer}%
              {\noexpand\realfolio}}}%
      \endgroup}}

\def\writetoreferencelist[#1]#2% #1=class #2=data #3=visualization
  {\dowithnextbox
     {\doifelsevalue{\??rl#1\c!state}\v!start
        {\doglobal\increment\referencecounter % must be resolved due to #2
         \referencebutton
           {\flushnextbox
            \pagereference[\r!from\referencecounter]%
            \dowritetoreferencelist{#1}{\referencecounter}{#2}}%
           [\r!to\referencecounter]}
        {\flushnextbox}}
     \hbox} % \vbox ?

\def\referencelistentry#1%
  {\executeifdefined{#1\c!list}\gobblefourarguments}

\def\dodosetreferencelist#1%
  {\setvalue{#1\c!list}{\doreferencelistelement{#1}}}

\def\dodoresetreferencelist#1%
  {\setvalue{#1\c!list}{\gobblefourarguments}}

\def\dodefinereferencelist[#1][#2]%
  {\setupreferencelist[#1]
     [\c!command=,
      \c!state=\v!start,
      \c!criterium=\v!all,
      \c!before=,
      \c!after=,
      #2]%
   \resetcounter{#1}%
   \addutilityreset{#1}%
   \setvalue{\s!set  #1}{\dodosetreferencelist  {#1}}%
   \setvalue{\s!reset#1}{\dodoresetreferencelist{#1}}}

\def\definereferencelist
  {\dodoubleempty\dodefinereferencelist}

\def\dosetupreferencelist[#1][#2]%
  {\getparameters[\??rl#1][#2]}

\def\setupreferencelist
  {\dodoubleempty\dosetupreferencelist}

\def\dosetupcombinedlist[#1][#2]%
  {\getparameters[\??ih#1][#2]%
   \expanded{\setuplist[\getvalue{\??ih#1\c!list}]}[#2]}

\def\setupcombinedlist
  {\dodoubleargument\dosetupcombinedlist}

\def\doplacecombinedlist[#1][#2]%
  {\begingroup
   \getparameters[\??ih#1][#2]%
   \dosettoclevel\??ih{#1}%
   \edef\combinedlist{\getvalue{\??ih#1\c!list}}%
   \doifelsevalue{\??ih#1\c!level}\v!current %
     {\!!counta=0\@@kolevel} % hm: \@@kolevel
     {\fullexpandoneargafter\doifnumberelse{\getvalue{\??ih#1\c!level}}% in verband
        {\!!counta\getvalue{\??ih#1\c!level}% met de vorige implementatie
         \advance\!!counta \plusone % accepteren we ook nummers (0==deel)
         \getfromcommacommand[\combinedlist][\!!counta]%
         \edef\maximumlist{\commalistelement}}%
        {\edef\maximumlist{\getvalue{\??ih#1\c!level}}}%
      \doifdefinedelse{\??ko\maximumlist\c!section}
        {\!!counta\getvalue{\??se\getvalue{\??ko\maximumlist\c!section}\c!level}}%
        {\!!counta\zerocount}}
   \let\!!stringa\combinedlist
   \let\combinedlist\empty
   \def\docommand##1%
     {\doifdefinedelse{\??ko##1\c!section}
        {\ifnum\getvalue{\??se\getvalue{\??ko##1\c!section}\c!level}>\!!counta\else
           \addtocommalist{##1}\combinedlist
         \fi}%
        {\addtocommalist{##1}\combinedlist}}%
   \processcommacommand[\!!stringa]\docommand
   \doifvalue{\??ih#1\c!coupling}\v!on
     {\startlistreferences{#1}}%
   \ExpandFirstAfter\dodoplacecombinedlist[\combinedlist][#2]%
   \stoplistreferences
   \endgroup
   \dosetlistmode}

\def\dodoplacecombinedlist[#1][#2]%
  {\dobeginoflist
   \dosetuplist[#1][#2]%
   \doutilities{listentries,#1}\jobname{#1}\relax\par
   \doendoflist}

\def\docompletecombinedlist[#1][#2]%
  {\expanded{\systemsuppliedtitle[#1]{\noexpand\headtext{#1}}}% expansion due to v! vs french !
   \doplacecombinedlist[#1][#2]}

\def\dodefinecombinedlist[#1][#2][#3]%
  {\makerawcommalist[#2]\combinedlist % for fast processing
   \letvalue{\??ih#1\c!list}\combinedlist
   \getcommalistsize[#2]%
   \getfromcommalist[#2][\commalistsize]%
   \doeassign[\??ih#1][\c!level=\commalistelement]%
   \getparameters
     [\??ih#1]
     [\c!criterium=\v!local,#3]%
   \setvalue{\e!setup#1\e!endsetup}%
     {\dodoubleempty\dosetupcombinedlist[#1]}%
   \setvalue{\e!place#1}%
     {\dodoubleempty\doplacecombinedlist[#1]}%
   \setvalue{\e!complete#1}%
     {\dodoubleempty\docompletecombinedlist[#1]}}

\def\definecombinedlist
  {\dotripleempty\dodefinecombinedlist}

\def\placecombinedlist
  {\dodoubleempty\doplacecombinedlist}

% new and yet undocumented (used in cocoa qa)
%
% \setupremaininglistlength
%   [left=\hss nog~,right=~ingangen]
%
% \resetremaininglistlength
%   [section][settings]
%
% \placelist
%   [section]
%   [before=\showremaininglistlength]
%
% \dorecurse{100}{\section{hans}}

\definesystemvariable {ll} % ListLength

\def\setupremaininglistlength[#1]%
  {\getparameters[\??ll][#1]%
   \globallet\listlengthcounter\!!zerocount}

\setupremaininglistlength
  [\c!left=\hss,\c!right=,\c!number=\v!yes,
   \c!before=\blank,\c!after=\page,
   \c!style=\v!smallnormal,\c!color=]

\def\resetremaininglistlength
  {\dodoubleempty\doresetremaininglistlength}

\def\doresetremaininglistlength[#1][#2]%
  {\determinelistcharacteristics[#1][#2]% \determinelistcharacteristics[#1][#2]%
   \xdef\listlengthcounter{\number\utilitylistlength}}

\def\showremaininglistlength
  {\bgroup
   \ifnum\listlengthcounter>\plusone
     \setbox\scratchbox\vbox
       {\@@llbefore\par\horizontalstrut\par\horizontalstrut\par\@@llafter}%
     \scratchdimen\pagetotal
     \advance\scratchdimen \ht\scratchbox
     \advance\scratchdimen \dp\scratchbox
     \ifdim\scratchdimen>\pagegoal
       \@@llbefore
       \nobreak\hbox to \hsize
         {\doifnot\@@llnumber\v!yes{\let\listlengthcounter\empty}%
          \doattributes\??ll\c!style\c!color{\@@llleft\listlengthcounter\@@llright}}
       \@@llafter
     \fi
   \fi
   \doglobal\decrement\listlengthcounter\relax
   \egroup}

\setupreferencelist
  [\c!style=\v!normal]

\protect \endinput