%D \module
%D   [       file=core-reg,
%D        version=1999.12.27,
%D          title=\CONTEXT\ Core Macros,
%D       subtitle=Register Management,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%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 Core Macros / Register Management}

\newif \ifautoregisterhack % for the moment a private hack

% new: eigennummer=ja => eerste {} ipv pag nummer

\unprotect

%D Isolated but still indocumented.

%  Formaat tex-utility-input-file <jobname.tui>:
%
%    i e {tag} {loc} {pure} {entry+..} {p:c:p:sp:ssp=>page} {realpage}
%    i s {tag} {loc} {pure} {entry+..} {other entry}
%
%  In plaats van + kan een & worden gebruikt. Ook kan als
%  eerste karakter worden opgegeven wat de scheider is.
%
%  \index                {entry}
%  \index[key]           {entry}
%  \index[pageclass::]   {entry}
%  \index[pageclass::key]{entry}
%  \index                {textclass::entry}
%  \index[key]           {textclass::entry}
%  \index[pageclass::]   {textclass::entry}
%  \index[pageclass::key]{textclass::entry}
%
%  Deze file wordt met het Perl script TeXUtil omgezet in
%  een in te lezen file met de commando's:
%
%    \registerentrya {tag} {ingang}
%    \registerentryb {tag} {subingang}
%    \registerentryc {tag} {subsubingang}
%
%    \registerpage   {tag} {pag,txt} {volgnummer} {paginanummer} {volgnummer}
%
%    \registersee    {tag} {pag,txt} {andere ingang}
%
%    \registerentry  {tag} {letter}

\def\dostelregisterin[#1][#2][#3]%
  {\ifthirdargument
     \def\dodostelregisterin##1%
       {\getparameters[\??id##1#2][#3]%
        \preparepaginaprefix{\??id##1}}%
   \else
     \def\dodostelregisterin##1%
       {\getparameters[\??id##1][#2]%
        \doifvalue{\??id##1\c!koppeling}\v!ja
          {\appendtoks\koppelregister[##1][#2]\to\everystarttext}%
        \preparepaginaprefix{\??id##1}}%
   \fi
   \processcommalist[#1]\dodostelregisterin}

\def\stelregisterin
  {\dotripleempty\dostelregisterin}

\def\getlastregisterentry#1%
  {\def\docommando##1%
     {\def\!!stringa{##1}}%
   \processseparatedlist[#1][+]\docommando
   \!!stringa}

\def\doprocesspageregister[#1]#2#3% key altnum entry
  {\begingroup
   \thisisnextinternal\s!ind
   \ifduplicate\getlastregisterentry{#3}\fi
   \convertexpanded{\??id\currentregister}{#3}\asciiregisterentry
   \makesectionformat
   \doifelsevalue{\??id\currentregister\c!eigennummer}\v!ja
     \donetrue\donefalse
   % the spaces between } { are essential for texutil's split
   \edef\schrijfwegnaarregister%
     {\writeutility%
        {r \ifcase\registerpagestatus\space\or e \or f \or t \fi
         {\currentregister} %
         {\nextinternalreference} %
         {#1} %
         {\asciiregisterentry} %
         {\sectionformat\sectionseparator\sectionseparator
          \ifdone#2\else\noexpand\pagenumber\fi} %
         {\noexpand\realfolio}}}%
   \schrijfwegnaarregister
   \getfirstcharacter\currentregister
   \registerinfo{> \firstcharacter}{#3}%
   \endgroup}

\def\doregister#1%
  {\chardef\registerpagestatus\plusone
   \def\currentregister{#1}%
   \doifelsevalue{\??id\currentregister\c!eigennummer}\v!ja
     {\dosingleempty\dodoregister}
     {\dosingleempty\donoregister}}

\def\donoregister[#1]%
  {\dodoregister[#1]{}}

% \def\dodoregister[#1]#2#3%
%   {\doprocesspageregister[#1]{#2}{#3}%
%    \ifvmode\nobreak\fi
%    \GotoPar}

\def\dodoregister[#1]#2#3%
  {\dogotopar{\doprocesspageregister[#1]{#2}{#3}}}

\def\writetoregister[#1]% to be documented
  {\doregister{#1}}

\def\startregister
  {\dodoubleargument\dostartregister}

%\def\dostartregister[#1][#2]#3%
%  {\chardef\registerpagestatus=2
%   \def\currentregister{#1}%
%   \setgvalue{\??id#1\??id#2}{\dodostopregister[#1][#2]{#3}}%
%   \complexdoregister[#2]{#3}}

\def\dostartregister[#1][#2]#3%
  {\chardef\registerpagestatus2
   \def\currentregister{#1}%
   \setgvalue{\??id#1\??id#2}{\dodostopregister[#1][#2]{#3}}%
   \donoregister[#2]{#3}}

\def\stopregister
  {\dodoubleargument\dostopregister}

\def\dostopregister[#1][#2]%
  {\getvalue{\??id#1\??id#2}\setgvalue{\??id#1\??id#2}{}}

%\def\dodostopregister[#1][#2]%
%  {\chardef\registerpagestatus=3
%   \def\currentregister{#1}%
%   \complexdoregister[#2]}

\def\dodostopregister[#1][#2]%
  {\chardef\registerpagestatus3
   \def\currentregister{#1}%
   \donoregister[#2]}

\def\complexdozieregister[#1]#2#3%
  {\begingroup
     \thisisnextinternal\s!ind
     \ifduplicate\getlastregisterentry{#2}\fi
     \convertexpanded{\??id\currentregister}{#2}\asciiregisterentry
     \makesectionformat
     \edef\schrijfwegnaarregister%
       {\writeutility%
          {r s %
           {\currentregister} %
           {\nextinternalreference} %
           {#1} %
           {\asciiregisterentry} %
           {#3} %
           {\sectionformat}}}%
     \schrijfwegnaarregister
   \endgroup
   \registerinfo{> zie}{#2}%
   \GotoPar}

\def\dozieregister#1%
  {\def\currentregister{#1}%
   \complexorsimpleempty\dozieregister}

%\def\doschrijfnaarregister[#1]%  % de twee-traps-aanroep is nodig
%  {\edef\currentregister{#1}%    % om gebruik van \ExpandBothAfter
%   \doprocesspageregister}       % mogelijk te maken

\def\doschrijfnaarregister[#1]%  % de twee-traps-aanroep is nodig
  {\edef\currentregister{#1}%    % om gebruik van \ExpandBothAfter
   \doprocesspageregister{}}     % mogelijk te maken

\def\schrijfnaarregister
  {\dodoubleempty\doschrijfnaarregister}

\def\ifregistergeplaatst{\ifutilitydone}

\newif\iffirstregisterpage
\newif\iffirstregisterentry

\let\c!entrya\empty
\let\c!entryb\empty
\let\c!entryc\empty

\def\nextregisterpage
  {\iffirstregisterpage
     \doglobal\newcounter\registerpagenumber
   \fi
   \doglobal\increment\registerpagenumber}

\def\doregisterpagelocation#1#2%
  {\nextregisterpage
   \hbox to 1em{\hss\doregisterpagehowto{#1}{#2}\hss}}

\def\setregisterpage#1%
  {\let\registerpageseparator\empty
   \processaction
     [\getvalue{\??id#1\c!symbool}]
     [      \c!n=>{\def\doregisterpage##1[##2]%
                     {\doregisterpagelocation{#1}{\registerpagenumber}\/}},
            \c!a=>{\def\doregisterpage##1[##2]%
                     {\doregisterpagelocation{#1}{\character{\registerpagenumber}\/}}},
               1=>{\def\doregisterpage##1[##2]%
                     {\doregisterpagelocation{#1}{$\bullet$}}},
               2=>{\def\doregisterpage##1[##2]%
                     {\doregisterpagelocation{#1}{\vrule\!!width1em\!!height1ex\!!depth\!!zeropoint}}},
         \v!geen=>{\def\doregisterpage##1[##2]{}},%
      \s!unknown=>{\def\registerpagesymbol{\getvalue{\??id#1\c!symbool}}%
                   \def\doregisterpage##1[##2]%
                     {\doregisterpagelocation{#1}{\registerpagesymbol}}},
      \s!default=>{\def\registerpageseparator%
                     {,}%
                   \def\doregisterpage##1[##2]%
                     {\doregisterpagehowto{##1}
                        {\strut
                         \paginaprefix{\??id##1}[##2]%
                         \translatednumber[##2]}}}]}

\let\registerpagehowto\empty
\let\registertexthowto\empty

\def\setregisterhowto[#1,#2]%
  {\def\registerpagehowto{#1}%
   \def\registertexthowto{#2}}%

\def\doregistertexthowto#1#2%
  {\dostartattributes{\??id#1\registertexthowto}\c!tekstletter\c!tekstkleur{}%
   \getvalue{\??id#1\c!tekstcommando}{#2}%
   \dostopattributes}

\def\doregisterpagehowto#1#2%
  {\dostartattributes{\??id#1\registerpagehowto}\c!paginaletter\c!paginakleur{}%
   \getvalue{\??id#1\c!paginacommando}{#2}%
   \dostopattributes}

\def\registerentry #1{\executeifdefined{#1\s!entry }\gobbleoneargument  }
\def\registerentrya#1{\executeifdefined{#1\s!entrya}\gobbleoneargument  }
\def\registerentryb#1{\executeifdefined{#1\s!entryb}\gobbleoneargument  }
\def\registerentryc#1{\executeifdefined{#1\s!entryc}\gobbleoneargument  }
\def\registersee   #1{\executeifdefined{#1\s!see   }\gobblethrearguments}
\def\registerpage  #1{\executeifdefined{#1\s!page  }\gobblefourarguments}
\def\registerfrom  #1{\executeifdefined{#1\s!from  }\gobblefourarguments}
\def\registerto    #1{\executeifdefined{#1\s!to    }\gobblefourarguments}

\def\doresetregister#1%
  {\letvalue{#1\s!entrya}\gobbleoneargument
   \letvalue{#1\s!entryb}\gobbleoneargument
   \letvalue{#1\s!entryc}\gobbleoneargument
   \letvalue{#1\s!see   }\gobblethreearguments
   \letvalue{#1\s!page  }\gobblefourarguments
   \letvalue{#1\s!from  }\gobblefourarguments
   \letvalue{#1\s!to    }\gobblefourarguments
   \letvalue{#1\s!entry }\gobbleoneargument}

\newif\iffirstsubentry
\newif\iffirstsubsubentry

\newcounter\currententrylevel

\let\c!entryletter   =\empty
\let\c!entryreference=\empty
\let\c!entrya        =\relax
\let\c!entryb        =\relax
\let\c!entryc        =\relax

\chardef\lastregisterpagestatus=0

\def\limitedregisterentry#1#2%
  {\getvalue{\??id#1\c!tekstcommando}%
     {\doifelsenothing{\??id#1\c!maxbreedte}
        {#2}
        {\limitatetext{#2}{\getvalue{\??id#1\c!maxbreedte}}{\unknown}}}}

\def\dosetpageregisterpage#1#2#3#4#5#6%
  {\doifreglevelelse[#5]{\dodosetpageregisterpage{#1}{#2}{#3}{#4}{#5}{#6}}{}}

\def\dodosetpageregisterpage#1#2#3#4#5#6%
   {\global\utilitydonetrue
    \c!entryletter
    \setregisterhowto[#3]%
    \def\dohandleregisterentry##1%
      {\bgroup
       \if!!donea % \strut nieuw
         \setbox0\hbox{\showlocation{\doregistertexthowto{#2}
           {\strut\limitedregisterentry{#2}{##1}}}}%
         \gotonextinternal{\s!ind}{#4}{#6}{\box0}%
       \else
         \doregistertexthowto{#2}{##1}%
       \fi
       \egroup
       \!!doneafalse}%
    \!!doneafalse
    \doifelsevalue{\??id#2\c!interactie}\v!tekst
      {\ifcase\currententrylevel                 \or
         \!!doneatrue\c!entrya\c!entryb\c!entryc \or
         \c!entrya\!!doneatrue\c!entryb\c!entryc \or
         \c!entrya\c!entryb\!!doneatrue\c!entryc \fi}
      {\c!entrya\c!entryb\c!entryc}%
    \global\let\c!entrya\relax
    \global\let\c!entryb\relax
    \global\let\c!entryc\relax
    \global\let\c!entryletter\relax
    \global\let\c!entryreference\relax
   % \global\firstregisterentrytrue
    \iffirstregisterpage
      \global\chardef\lastregisterpagestatus\zerocount
      \expandafter\hskip\getvalue{\??id#2\c!afstand}\relax
      \donetrue
    \else\ifnum#1=3
      |--|\relax % -- !
      \donetrue
    \else\ifnum\lastregisterpagestatus=2
      \donefalse % waiting for "to" pagenumber
    \else
      \registerpageseparator
      |\spatie|\relax % \relax needed because | looks ahead
      \donetrue
    \fi\fi\fi
    \ifdone
      \doifelsevalue{\??id#2\c!interactie}\v!paginanummer
        {\bgroup
         \setbox0\hbox
           {\showlocation{\doregisterpage{#2}[#5]\ifnum#1=2\/\fi}}%
         \gotonextinternal{\s!ind}{#4}{#6}{\box0}%{\copy0}%
         \egroup}
        {\hbox{\doregisterpage{#2}[#5]\ifnum#1=2\/\fi}}%
      \ignorespaces
      \global\chardef\lastregisterpagestatus#1\relax
    \fi
    \global\firstregisterpagefalse}

\def\dosetpageregistersee#1#2#3#4% ugly separator hack
  {\expanded{\doifreglevelelse[#4\sectionseparator\sectionseparator0]}%
     {{\global\utilitydonetrue
       \setregisterhowto[#2]%
       \def\dohandleregisterentry##1% dubbelop | \strut nieuw
         {\doregistertexthowto{#1}{\strut\limitedregisterentry{#1}{##1}}}%
       \getvalue
         {#1\ifcase\currententrylevel\s!entrya\or\s!entryb\else\s!entryc\fi}%
         {\doregisterpagehowto{#1}{\labeltexts{\v!zie}{#3}}}%
       \c!entryletter\c!entrya\c!entryb\c!entryc
       \global\let\c!entrya\relax
       \global\let\c!entryb\relax
       \global\let\c!entryc\relax
       \global\let\c!entryletter\relax
       \global\let\c!entryreference\relax
       \global\chardef\lastregisterpagestatus\zerocount
    %   \global\firstregisterentrytrue
       \global\firstregisterpagefalse}}
     {}}

%D Extended with variant:

\def\doregistercharacter[#1]#2%
  {\global\firstregisterentrytrue
   \doifelsevalue{\??id#1\c!aanduiding}\v!ja
     {\executeifdefined
        {\strippedcsname\doregistercharacter\getvalue{\??id#1\c!variant}}%
        \doregistercharactera
        [#1]{#2}}
     {\noregistercharacter[#1]{#2}}}

\def\noregistercharacter[#1]#2%
  {\getvalue{\??id#1\c!voor}%
   \goodbreak}

% a = <before> <goodbreak> <character> <par> <after> <nobreak>

\def\doregistercharactera[#1]#2%
  {\getvalue{\??id#1\c!voor}%
   \vskip\lineheight\goodbreak\vskip-\lineheight
   \ifhmode\unskip\else\noindent\fi % brrr
   \getvalue{\??id#1\c!commando}%
     {\doattributes{\??id#1}\c!letter\c!kleur{\strut\ignorespaces#2}}%
   \getvalue{\??id#1\c!na}%
   \par\nobreak}

% b = <goodbreak> <before> <character> <after> <nobreak>

\def\doregistercharacterb[#1]#2% here no lineheight hackery ! ! !
  {\getvalue{\??id#1\c!voor}%
   \ifhmode\unskip\else\noindent\fi % brrr
   \getvalue{\??id#1\c!commando}%
     {\doattributes{\??id#1}\c!letter\c!kleur{\strut\ignorespaces#2}}%
   \getvalue{\??id#1\c!na}%
   \nobreak}

%D Don't use \type{\string#2}; another hack isneeded, since
%D \type {#2} can be \type {\string} itself.

\def\doregisterreference[#1]#2%
  {\doifvalue{\??id#1\c!refereren}\v!aan
     {\pagereference[#1:#2]}}

\def\dosetpageregisterletter#1#2%
  {\gdef\c!entryreference
     {\global\let\c!entryreference\relax
      \doregisterreference[#1]{#2}}%
   \gdef\c!entryletter
     {\global\utilitydonetrue
      \global\let\c!entryletter\relax
      \doregistercharacter[#1]{#2}}}

\def\dosetpageregisterentrya#1#2%
  {\edef\currententrylevel{1}%
   \global\let\c!entryb\relax
   \global\let\c!entryc\relax
   \gdef\c!entrya
     {\iffirstregisterentry\else\endgraf\fi % new
      \global\firstregisterpagetrue
      \hangindent1em\noindent\c!entryreference
      \dohandleregisterentry{#2}%
      \global\firstregisterentryfalse
      \global\firstsubentrytrue
      \global\firstsubsubentrytrue}}

\def\dosetpageregisterentryb#1#2%
  {\edef\currententrylevel{2}%
   \global\let\c!entryc\relax
   \global\def\c!entryb
     {\iffirstregisterentry\else\endgraf\fi % new
      \global\firstregisterpagetrue
      \global\let\c!entrya\relax
      \iffirstsubentry\nobreak\fi
      \hangindent2em\noindent\c!entryreference\hskip1em\relax
      \dohandleregisterentry{#2}%
      \global\firstregisterentryfalse
      \global\firstsubentryfalse
      \global\firstsubsubentrytrue}}

\def\dosetpageregisterentryc#1#2%
  {\edef\currententrylevel{3}%
   \gdef\c!entryc
     {\iffirstregisterentry\else\endgraf\fi % new
      \global\firstregisterpagetrue
      \global\let\c!entrya\relax
      \global\let\c!entryb\relax
      \iffirstsubsubentry\nobreak\fi
      \hangindent3em\noindent\c!entryreference\hskip2em\relax
      \dohandleregisterentry{#2}%
      \global\firstregisterentryfalse
      \global\firstsubsubentryfalse}}

\def\dosetpageregister#1% \currentregister gebruiken
  {\dosetreglevel{#1}%
   \global\let\currentregisterentry\empty
   \global\firstsubentrytrue
   \global\firstsubsubentrytrue
   \setregisterpage{#1}%
   \chardef\lastregisterpagestatus\zerocount
   \setvalue{#1\s!entrya}{\dosetpageregisterentrya {#1}}%
   \setvalue{#1\s!entryb}{\dosetpageregisterentryb {#1}}%
   \setvalue{#1\s!entryc}{\dosetpageregisterentryc {#1}}%
   \setvalue{#1\s!page  }{\dosetpageregisterpage{1}{#1}}%
   \setvalue{#1\s!from  }{\dosetpageregisterpage{2}{#1}}%
   \setvalue{#1\s!to    }{\dosetpageregisterpage{3}{#1}}%
   \setvalue{#1\s!see   }{\dosetpageregistersee    {#1}}%
   \setvalue{#1\s!entry }{\dosetpageregisterletter {#1}}}

\def\dosetreglevel#1%
  {\dosetfilterlevel{\getvalue{\??id#1\c!criterium}}\empty}

\def\getalllistreferences#1#2%
  {\doglobal\convertexpanded{\??id#1}{#2}\currentregisterentry
   \doifdefinedelse{\??id#1\??id\currentregisterentry}
     {\edef\alllistreferences%
        {\getvalue{\??id#1\??id\currentregisterentry}}%
      \beforesplitstring\alllistreferences\at::\to\internallistreference
      \aftersplitstring \alllistreferences\at::\to\alllistreferences}
     {\let\alllistreferences\empty
      \def\internallistreference{0}}}

\def\dosetlinkregister#1% is die page reference echt nodig?
  {\dosetreglevel{#1}%
   \setregisterpage{#1}%
   \global\let\currentregisterentry\empty
   \global\firstsubentrytrue % not needed
   \global\firstsubsubentrytrue % not needed too
   \setvalue{#1\s!entrya}##1{\dosetlinkregisterentrya{#1}{##1}}%
   \setvalue{#1\s!entry }##1{\dosetpageregisterletter{#1}{##1}}}

\def\dosetlinkregisterentrya#1#2%
   {\global\utilitydonetrue
    \c!entryletter
    \iflocation
      \getalllistreferences{#1}{#2}%
      \endgraf\hangindent1em\noindent\c!entryreference
      %
      %\thisissomeinternal{\s!lin}{\internallistreference}%
      %
      \pagereference[-:\s!lin:\internallistreference]% -: added
      %
      \getcommacommandsize[\alllistreferences]%
      \getfromcommacommand[\alllistreferences][1]%
      \ifnum\commalistsize=1
        \let\firstlistreference\empty
        \let\midlistreference\commalistelement
        \let\lastlistreference\empty
      \else
        \let\firstlistreference\commalistelement
        \getfromcommacommand[\alllistreferences][\commalistsize]%
        \let\lastlistreference\commalistelement
        \ifnum\commalistsize=2
          \let\midlistreference\empty
        \else
          \!!counta\commalistsize
          \divide\!!counta 2
          \getfromcommacommand[\alllistreferences][\!!counta]%
          \let\midlistreference\commalistelement
        \fi
      \fi
      % aangepast
      \def\dodocommando[##1-##2]%
        {\gotonextinternal{\s!ind}{##1}{##2}{\box0}}%
      \doifelsevalue{\??id#1\c!interactie}\v!paginanummer
        {\limitedregisterentry{#1}{#2}} % paginanummer
        {{\setbox0\hbox{\limitedregisterentry{#1}{\begstrut#2}}%
          \ifx\firstlistreference\empty  % tekst,alles
            \ifx\midlistreference\empty
              \box0
            \else
              \expandafter\dodocommando\expandafter[\midlistreference]%
            \fi
          \else
            \expandafter\dodocommando\expandafter[\firstlistreference]%
          \fi}}%
      \doifvalue{\??id#1\c!nummer}\v!ja
        {\hskip\getvalue{\??id#1\c!afstand}(\commalistsize)}%
      \doifnotvalue{\??id#1\c!interactie}{\v!tekst} % paginanummer,alles
        {\def\docommando##1##2%
           {{\setbox0\hbox{\showlocation{\hbox to 1em{\hss\symbol[##2]\hss}}}%
             \ifx##1\empty
               % \hskip\wd0 % (optioneel maken)
             \else
               \expandafter\dodocommando\expandafter[##1]%
             \fi}}%
         \hskip\getvalue{\??id#1\c!afstand}%
         \docommando\firstlistreference\v!vorige
         \docommando\midlistreference\v!ergens
         \docommando\lastlistreference\v!volgende}%
      % tot hier
    \else
      \endgraf\noindent\c!entryreference
      \limitedregisterentry{#1}{#2}%
    \fi}

\def\dosetregister#1%
  {\doifelsevalue{\??id#1\c!koppeling}\v!ja
     {\ifautoregisterhack
        \dosetautoregister{#1}%
      \else
        \dosetlinkregister{#1}%
      \fi}
     {\dosetpageregister{#1}}}

\newcounter\internallistreference

\def\doloadregisterlinks#1%
  {\dosetreglevel{#1}%
   \setregisterpage{#1}%
   \global\let\currentregisterentry\empty
   \global\firstregisterpagetrue
   \setvalue{#1\s!entrya}##1%
     {\global\firstregisterpagetrue
      \doglobal\convertargument##1\to\currentregisterentry % \doglobal nodig?
      \doglobal\increment\internallistreference}%
   \setvalue{#1\s!from}%
     {\getvalue{#1\s!page}}%
\ifautoregisterhack
   \setvalue{#1\s!page}##1##2##3##4%
     {\doifreglevelelse[##3]
        {\global\utilitydonetrue
         \iffirstregisterpage
           \@EA\xdef\csname\??id#1\??id\currentregisterentry\endcsname
             {\internallistreference::##4}%
         \else % catches errors in index
           \ifcsname\??id#1\??id\currentregisterentry\endcsname
             \@EA\xdef\csname\??id#1\??id\currentregisterentry\endcsname
               {\csname\??id#1\??id\currentregisterentry\endcsname,##4}%
           \fi
         \fi}
        {}}%
\else
   \setvalue{#1\s!page}##1##2##3##4%
     {\doifreglevelelse[##3]
        {\global\utilitydonetrue
         \iffirstregisterpage
           \global\firstregisterpagefalse
           \@EA\xdef\csname\??id#1\??id\currentregisterentry\endcsname
             {\internallistreference::##2-##4}%
         \else % catches errors in index
           \ifcsname\??id#1\??id\currentregisterentry\endcsname
             \@EA\xdef\csname\??id#1\??id\currentregisterentry\endcsname
               {\csname\??id#1\??id\currentregisterentry\endcsname,##2-##4}%
           \fi
         \fi}
        {}}%
\fi}

\def\dokoppelregister[#1][#2]%
  {\iflocation
     \ifcase0\countervalue{autolink:#1}\relax % only once
       \begingroup
       \let\dosetregister\doloadregisterlinks
       \stelregisterin[#1][#2]%
       \doutilities{#1}\jobname{#1}\relax\relax
       \endgroup
       \ifautoregisterhack
         \doinitializeautoregister{#1}%
       \else
         \doinitializelinkregister{#1}%
       \fi
     \fi
   \fi}

\def\koppelregister
  {\dodoubleempty\dokoppelregister}

\def\dodocommandoprolinrefAA[#1-#2]%
  {\def\lastlistreference{#1-#2}}

\def\dodocommandoprolinrefA[#1-#2]%
  {\def\lastlistreference{#1-#2}%
   \ifx\firstlistreference\empty
     \let\firstlistreference\lastlistreference
   \fi
   \ifnum#1<\nextinternalreference\relax
     \let\prevlistreference\lastlistreference
   \else\ifnum#1>\nextinternalreference\relax
     \let\nextlistreference\lastlistreference
     \let\dodocommandoprolinrefA\dodocommandoprolinrefAA
   \else
     \let\selflistreference\lastlistreference
   \fi\fi}

\def\docommandoprolinrefA#1%
  {\dodocommandoprolinrefA[#1]}

\def\dodocommandoprolinrefB[#1-#2]%
  {\gotonextinternal{\s!ind}{#1}{#2}{\box0}}

\def\docommandoprolinrefB#1#2#3%
  {\bgroup
   \ifx#2\empty
     \doifvalue{\??id#1\c!onbekendeverwijzing}\v!leeg{\hskip1em}%
   \else
     \setbox0\hbox to 1em{\hss\showlocation{\symbol[#3]}\hss}%
     \expandafter\dodocommandoprolinrefB\expandafter[#2]%
   \fi
   \egroup}

\def\doprocesslinkregister[#1][#2]#3%
  {\hbox
     {\doprocesspageregister[#2]{}{#3}%
      \let\firstlistreference\empty
      \let\lastlistreference\empty
      \let\selflistreference\empty
      \let\prevlistreference\empty
      \let\nextlistreference\empty
      \getalllistreferences{#1}{#3}%
      \ifx\alllistreferences\empty \else
        \expanded{\rawprocesscommalist[\alllistreferences]}\docommandoprolinrefA
      \fi
       \ifx\prevlistreference\empty
         \let\prevlistreference\lastlistreference
       \fi
       \ifx\nextlistreference\empty
         \let\nextlistreference\firstlistreference
       \fi
       \ifx\prevlistreference\selflistreference
         \let\prevlistreference\empty
         \let\nextlistreference\empty
       \fi
       \setalignmentswitch{\getvalue{\??id#1\c!plaats}}%
       \ifcase\alignmentswitch
         % links
         \docommandoprolinrefB{#1}\prevlistreference\v!vorige
         \docommandoprolinrefB{#1}\nextlistreference\v!volgende
       \or
         % midden
         \docommandoprolinrefB{#1}\prevlistreference\v!vorige
       \or
         % rechts
       \fi
       \doifreferencefoundelse{\s!lin:\internallistreference}
         {\gotosomeinternal
            \s!lin \internallistreference \currentrealreference
            {\showlocation{\limitedregisterentry{#1}{#3}}}}
         {\hbox{\limitedregisterentry{#1}{#3}}}%
       \ifcase\alignmentswitch
         % links
       \or
         % midden
         \docommandoprolinrefB{#1}\nextlistreference\v!volgende
       \or
         % rechts
         \docommandoprolinrefB{#1}\prevlistreference\v!vorige
         \docommandoprolinrefB{#1}\nextlistreference\v!volgende
       \fi}}

\def\dodolinkedregister[#1][#2]#3% page auto link
  {\bgroup
   \chardef\registerpagestatus\plusone
   \def\currentregister{#1}%
   \iflocation
     \ifautoregisterhack
       \def\next{\doprocessautoregister[#1][#2]}%
     \else
       \def\next{\doprocesslinkregister[#1][#2]}%
     \fi
   \else
     \def\next{\doprocesspageregister[#2]{}}%
   \fi
   \next{#3}%
   \egroup
   \ifvmode\nobreak\fi
   \GotoPar}

\def\dolinkedregister#1%
  {\dodoubleempty\dodolinkedregister[#1]}

\def\dosetautoregister#1%
  {\makecounter{autolink:#1}%
   \dosetreglevel{#1}%
   \setregisterpage{#1}%
   \global\let\currentregisterentry\empty
   \global\firstsubentrytrue % not needed
   \global\firstsubsubentrytrue % not needed too
   \setvalue{#1\s!entrya}##1%
     {\dosetautoregisterentrya{#1}{##1}}%
   \setvalue{#1\s!entry}##1%
     {\dosetpageregisterletter{#1}{##1}}}

\def\dosetautoregisterentrya#1#2%
  {\global\utilitydonetrue
   \c!entryletter
   \iflocation
     \getalllistreferences{#1}{#2}%
     \endgraf\hangindent1em\noindent\c!entryreference
     \pagereference[-:\s!lin:\internallistreference]%
     \pluscounter{autolink:#1}%
     \bgroup
    %\setupinteraction[\c!kleur=,\c!contrastkleur=,\c!letter=]% kan sneller
     \resetinteractionparameter\c!kleur
     \resetinteractionparameter\c!contrastkleur
     \resetinteractionparameter\c!letter
     \naarbox
       {\limitedregisterentry{#1}{\begstrut#2}}%
       [JS(SetRegisterEntry{\v!register,\countervalue{autolink:#1},#2,{\alllistreferences}})]%
     \egroup
   \else
     \endgraf\noindent\c!entryreference
     \limitedregisterentry{#1}{#2}%
   \fi}

\def\doprocessautoregister[#1][#2]#3%
  {\hbox
     {\doprocesspageregister[#2]{}{#3}%
      \doifreferencefoundelse{\s!lin:\internallistreference}
        {\gotosomeinternal \s!lin
           {\internallistreference}{\currentrealreference}
           {\showlocation{\limitedregisterentry{#1}{#3}}}}
        {\hbox{\limitedregisterentry{#1}{#3}}}}}

% \appendmacro aan openpaginaactie (in shipout)

%D The first implementation used one main field with clones.
%D In a 2500 page document this resulted in a rather (anoying)
%D long start||up time. This \citeer {every page its own field}
%D solution, combined with a \citeer {page open action}, works
%D much faster, but is conceptually pretty weak.

\def\complexregisterfield[#1]%
  {\definefield[#1:\realfolio][line][\v!register]%
   \field[#1:\realfolio]}

\def\simpleregisterfield
  {\complexregisterfield[\v!register]}

\definecomplexorsimple\registerfield

\setupfield
  [\v!register]
  [\c!breedte=10em,
   \c!hoogte=3ex,
   \c!uitlijnen=\v!midden,
   \c!optie=\v!alleenleesbaar,
   \c!plaats=\v!laag]

\def\doinitializeautoregister#1%
  {\useJSscripts[reg]%
   \useJSpreamblenow{LinkedRegisters}%
   \setupinteraction[\c!openpaginaactie=JS(UpdateRegisterField{\v!register})]%
   \definereference[\v!reset   \v!register][JS(ResetRegisterEntry{\v!register})]%
   \definereference[\v!eerste  \v!register][JS(GotoFirstRegisterEntry{\v!register})]%
   \definereference[\v!vorige  \v!register][JS(GotoPreviousRegisterEntry{\v!register})]%
   \definereference[\v!volgende\v!register][JS(GotoNextRegisterEntry{\v!register})]%
   \definereference[\v!laatste \v!register][JS(GotoLastRegisterEntry{\v!register})]}

\def\doinitializelinkregister#1%
  {}

% todo ruwe register

\def\plaatsregister
  {\dosingleargument\doplaatsregister}

\def\doplaatsregister[#1]%
  {\def\currentregister{#1}%
   \complexorsimpleempty\doplaatsregister}

\def\complexdoplaatsregister[#1]%
  {\begingroup
   \stelregisterin[\currentregister][#1]%
   \raggedright
   \startkolommen
     [\c!n=\getvalue{\??id\currentregister\c!n},
      \c!balanceren=\getvalue{\??id\currentregister\c!balanceren},
      \c!uitlijnen=\getvalue{\??id\currentregister\c!uitlijnen}]%
   \mindermeldingen
   \startopelkaar[\v!blanko]%
   \doutilities\currentregister\jobname\currentregister\relax\par
   \stopopelkaar
   \stopkolommen
   \endgroup}

% \def\complexdovolledigregister[#1]% \@EA's kunnen weg
%   {\@EA\plaatsvolledig\@EA{\@EA\systemsuppliedchapter\@EA}%
%      \@EA{\@EA\currentregister\@EA}%
%      \@EA{\@EA\headtext\@EA{\currentregister}}%
%      {\complexdoplaatsregister[#1]}}

\def\complexdovolledigregister[#1]% the expansion is needed because we don't want
   {\expanded                     % \v!'s in the tuo file (french)
      {\plaatsvolledig
         {\noexpand\systemsuppliedchapter}%
         {\currentregister}%
         {\noexpand\headtext{\currentregister}}%
         {\noexpand\complexdoplaatsregister[#1]}}}

\def\dovolledigregister[#1]%
  {\def\currentregister{#1}%
   \complexorsimpleempty\dovolledigregister}

\def\volledigregister
  {\dosingleargument\doplaatsregister}

\def\dodefinieerregister[#1][#2]%
  {\stelregisterin[#1]%
     [\c!n=2,
      \c!balanceren=\v!ja,  % \v!nee komt niet zo vaak voor
      \c!uitlijnen=\v!nee,
      \c!voor=\blanko,      % binnen kolommen: \blanko[\v!regel]
      \c!na=,
      \c!symbool=,
      \c!interactie=\v!paginanummer,
      \c!variant=\v!a,
      \c!afstand=1em,
      \c!letter=\v!vet,
      \c!paginaletter=\v!schuin,
      \c!aanduiding=\v!ja,
      \v!deel\v!nummer=\v!ja, % v
      \v!hoofdstuk\c!nummer=\v!nee,
      \c!criterium=\v!alles,
      \c!commando=,
      \c!refereren=\v!aan,
      \c!plaats=\v!midden,
      \c!maxbreedte=,
      \c!nummer=\v!nee,
      \c!onbekendeverwijzing=\v!leeg,
      \c!expansie=]%
   \presetheadtext[#1=\Word{#1}]%
   \setvalue{#1}%
     {\doregister{#1}}%
   \setvalue{\e!gekoppelde#1}%
     {\dolinkedregister{#1}}%
   \setvalue{\s!set#1}%
     {\dosetregister{#1}}%
   \setvalue{\s!reset#1}%
     {\doresetregister{#1}}%
   \addutilityreset{#1}%
   \setvalue{\e!zie#1}%
     {\dozieregister{#1}}%
   \setvalue{\e!plaats#1}%
     {\doplaatsregister[#1]}%
   \setvalue{\e!volledige#1}%
     {\dovolledigregister[#1]}%
   \setvalue{\e!stel#1\e!in}[##1]%
     {\getparameters[\??id#1][##1]}}

\def\definieerregister%
  {\dodoubleargument\dodefinieerregister}

\def\registerlengte{\utilityregisterlength}

\def\utilityregisterlength{0}

\def\dobepaalregisterkenmerken[#1][#2]%
  {\begingroup
   \stelregisterin[#1][#2]%
   \dosetreglevel{#1}%
   \setvalue{#1\s!from}%
     {\getvalue{#1\s!page}}%
   \setvalue{#1\s!page}##1##2##3##4%
     {\doifreglevelelse[##3]
        {\doglobal\increment\utilitylistlength
         \global\utilitydonetrue}
        {}}%
   \doglobal\newcounter\utilityregisterlength
   \setbox0\vbox
     {\doutilities{#1}\jobname{#1}\relax\relax}%
   \endgroup
   \ifregistergeplaatst
     \setsystemmode  \v!register
   \else
     \resetsystemmode\v!register
   \fi}

\def\bepaalregisterkenmerken
  {\dodoubleempty\dobepaalregisterkenmerken}

\definieerregister
  [\v!index]
  [\v!indices]

% \stelregisterin[index][koppeling=ja]
%
% \stelveldenin
%   [register][achtergrond=raster,kader=uit]
%
% \stelvoettekstenin
%   [{\field[index]}]
%
% \stelhoofdtekstenin
%   [{\naar   {first}[eersteindex]\quad
%     \naar{previous}[vorigeindex]\quad
%     \naar    {next}[volgendeindex]\quad
%     \naar    {last}[laatsteindex]\quad\quad
%     \naar   {index}[index]}]
%
% \starttekst
%
% oeps~~~\gekoppeldeindex{oeps} \blanko
% flop~~~\gekoppeldeindex{flop} \blanko
% test~~~\gekoppeldeindex{test} \pagina
% flop~~~\gekoppeldeindex{flop} \blanko
% test~~~\gekoppeldeindex{test} \pagina
% oeps~~~\gekoppeldeindex{oeps} \blanko
% test~~~\gekoppeldeindex{test} \pagina
% flop~~~\gekoppeldeindex{flop} \blanko
% oeps~~~\gekoppeldeindex{oeps} \pagina
%
% \volledigeindex

\protect \endinput
