% \iffalse meta-comment
%
%% regulatory-ref.dtx
%% Copyright 2024-2026 E. Nijenhuis
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3c
% of this license or (at your option) any later version.
% The latest version of this license is in
% http://www.latex-project.org/lppl.txt
% and version 1.3c or later is part of all distributions of LaTeX
% version 2005/12/01 or later.
%
% This work has the LPPL maintenance status ‘maintained’.
%
% The Current Maintainer of this work is E. Nijenhuis.
%
% This work consists of the files listed in the meta-comment of
% regulatory-struct.dtx.
%
% \fi
%
% \iffalse
%<*driver>
\ProvidesFile{regulatory-ref.dtx}
%</driver>
%<package>\NeedsTeXFormat{LaTeX2e}
%<package>\ProvidesPackage{regulatory-ref}
%<package>    [2026/09/10 1.0.0 Xerdi's Regulatory Package (References)]
%
%<*driver>
\documentclass[10pt,english]{ltxdoc}
%! suppress = InclusionLoop
\usepackage{regulatory}
\usepackage{tabularx}
\usepackage[english,dutch]{babel}
\input{regulatory-preamble}
\newcommand\translation[2]{#1}
\begin{document}
    \selectlanguage{english}
    \DocInput{regulatory-ref.dtx}
\end{document}
%</driver>
% \fi
%
% \subsection{\texorpdfstring{\package{regulatory-ref}}{regulatory-ref}}
% \setcounter{CodelineNo}{0}
%
% \subsubsection{\translation{Prerequisites}{Vereisten}}
%
% The structures of \package{regulatory-struct} hold the counters and the reference properties every
% reference is built upon, so this module loads it first. \package{xstring} is used to take apart the
% comma separated label lists of \cmd{\aref}.
%
% Options are administered by \package{regulatory-struct} for the whole bundle, so they are handed over,
% just like \package{regulatory} does. Whenever that module is loaded already, its options are settled and
% there is nothing left to hand over.
% \iffalse
%<*package>
% \fi
%    \begin{macrocode}
\@ifpackageloaded{regulatory-struct}{}{%
    \DeclareOption*{\PassOptionsToPackage{\CurrentOption}{regulatory-struct}}%
    \ProcessOptions\relax
}
\RequirePackage{regulatory-struct}
\RequirePackage{xstring}
%    \end{macrocode}
%
% The range conjunction and the conjunction of an enumeration are looked up with
% \package{translations} as well, so that they follow the language selected at that very spot in the
% document.
%    \begin{macrocode}
\DeclareTranslationFallback{and}{and}
\DeclareTranslationFallback{to}{to}
%    \end{macrocode}
%
% \subsubsection{\translation{Switches}{Schakelaars}}
%
% \begin{macro}{\hashchar}
% Hyperlinks to another document are composed by hand, for which the hash character is needed with its
% ordinary category code.
%    \begin{macrocode}
{\catcode`\#=12 \gdef\hashchar{#}}
\def\rref@linkpr{\href{\rref@current@fullurl}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@ifrrefcap}
% A capitalized reference is requested by the \cmd{\Rref}, \cmd{\Nref} and \cmd{\Aref} variants. Only the
% first designation printed may be capitalized, hence the switch resets itself as soon as it produced
% something.
%    \begin{macrocode}
\newboolean{rref@cap}
%    \end{macrocode}
%
% A designation that is not built from a language file never passes through here\,---\,an article is
% referred to by its number alone\,---\,so the request would otherwise survive the reference that made it
% and capitalize the next one instead. Every reference ends by withdrawing it.
%    \begin{macrocode}
\newcommand\rref@capreset{\setboolean{rref@cap}{false}}
\def\@ifrrefcap#1#2{%
    \ifthenelse{\boolean{rref@cap}}{%
        #1%
        \ifthenelse{\equal{#1}{}}{}{%
            \setboolean{rref@cap}{false}%
        }%
    }{%
        #2%
    }%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@ifnameinlink}
% Reads the \option{nameinlink} option of \package{regulatory-struct}, which decides whether the designation
% is part of the hyperlink or only the number is.
%    \begin{macrocode}
\def\@ifnameinlink#1#2{%
    \ifthenelse{\boolean{regulatory@nameinlink}}{#1}{#2}%
}
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{\translation{Conjunction}{Conjunctie}}
%
% \begin{macro}{\setmiddleconjunction}
% \begin{macro}{\setlastconjunction}
% \begin{macro}{\setrangeconjunction}
% \begin{macro}{\setconjunction}
% The conjunctions join the labels of an enumeration, of which the last one is joined differently, and a
% range of three or more consecutive labels is joined with the range conjunction instead.
%    \begin{macrocode}
\newcommand\rref@middleconjunction{, }
\newcommand\rref@lastconjunction{ \GetTranslation{and} }
\newcommand\rref@rangeconjunction{ \GetTranslation{to} }

\newcommand\setmiddleconjunction[1]{\renewcommand\rref@middleconjunction{#1}}
\newcommand\setlastconjunction[1]{\renewcommand\rref@lastconjunction{#1}}
\newcommand\setrangeconjunction[1]{\renewcommand\rref@rangeconjunction{#1}}

\newcommand\setconjunction[3]{%
    \setmiddleconjunction{#1}%
    \setlastconjunction{#2}%
    \setrangeconjunction{#3}%
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\setjuncto}
% \begin{macro}{\unsetjuncto}
% Legacy documents join the last label with `junctis', which the \option{legacy} option switches on right
% away.
%    \begin{macrocode}
\newcommand\setjuncto{%
\setlastconjunction{ jo.\ }%
}

\newcommand\unsetjuncto{%
\setlastconjunction{ \GetTranslation{and} }%
}

\ifregulatory@legacy
\setjuncto
\fi
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \subsubsection{\translation{Reference formats}{Verwijsformaten}}
%
% These are the formats the language definition files pick from. A \texttt{ref format} turns the number of a
% reference into its representation, a \texttt{label format} decides on the order of the designation and the
% number, and a \texttt{group format} wraps the parent parts of a reference. A point is lettered and
% put in brackets, \texttt{(a)}, which is the form the European style guides write it in and the one the
% English configuration reaches for.
%    \begin{macrocode}
\newcommand\rref@refformat@noop[1]{#1}
\newcommand\rref@refformat@parenthesis[1]{(#1)}
\newcommand\rref@refformat@ordinal[1]{\@ifrrefcap{\Ordinalstringnum{#1}}{\ordinalstringnum{#1}}}
\newcommand\rref@refformat@alpha[1]{\@ifrrefcap{\ABAlphnum{#1}}{\abalphnum{#1}}}
\newcommand\rref@refformat@alphaparen[1]{(\abalphnum{#1})}
\newcommand\rref@label@prefix[2]{#1 #2}
\newcommand\rref@label@postfix[2]{#2 #1}
\newcommand\rref@label@refonly[2]{\@gobble{#1}#2}
\newcommand\rref@group@braced[1]{{[}#1{]~}}
%    \end{macrocode}
%
% \subsubsection{\translation{Language configuration}{Taalconfiguratie}}
%
% Every language gets its own designations per type of reference, of which the initial values are the
% English ones, so a language definition file only has to state the differences. They are kept in one
% property list, keyed by language, type and key; the keys a definition file may set are listed, so that a
% misspelling is refused where it is written rather than read back as nothing wherever it is used.
%    \begin{macrocode}
\ExplSyntaxOn
\prop_new:N \g__regulatory_rref_prop
\cs_generate_variant:Nn \prop_item:Nn  { Ne }
\cs_generate_variant:Nn \prop_gput:Nnn { Nen }
\cs_generate_variant:Nn \prop_get:NnNF { NeNF }

\clist_const:Nn \c__regulatory_rref_keys_clist
  {
    name , Name , names , Names ,
    ref~format , label~format , group~conjunction , group~format
  }

\cs_new_protected:Npn \__regulatory_rref_put:nnnn #1#2#3#4
  { \prop_gput:Nen \g__regulatory_rref_prop { #1 / #2 / #3 } { #4 } }

\cs_new_protected:Npn \__regulatory_rref_set:nnnn #1#2#3#4
  {
    \clist_if_in:NnTF \c__regulatory_rref_keys_clist { #3 }
      { \__regulatory_rref_put:nnnn { #1 } { #2 } { #3 } { #4 } }
      { \msg_error:nnnnn { regulatory-ref } { unknown-key } { #1 } { #2 } { #3 } }
  }

\cs_new_protected:Npn \__regulatory_rref_bare:nnn #1#2#3
  { \msg_error:nnnnn { regulatory-ref } { key-without-value } { #1 } { #2 } { #3 } }

\msg_new:nnn { regulatory-ref } { unknown-key }
  {
    The~#2~designations~of~`#1'~were~given~a~key~`#3',~which~this~package~
    does~not~know.~\\
    The~keys~are:~\clist_use:Nn \c__regulatory_rref_keys_clist { ,~ }.
  }

\msg_new:nnn { regulatory-ref } { key-without-value }
  { The~key~`#3'~of~the~#2~designations~of~`#1'~was~given~no~value. }

\cs_new_protected:Npn \rref@setup@lang #1#2#3
  {
    \keyval_parse:nnn
      { \__regulatory_rref_bare:nnn { #1 } { #2 } }
      { \__regulatory_rref_set:nnnn { #1 } { #2 } }
      { #3 }
  }
\ExplSyntaxOff

%    \end{macrocode}
% \begin{macro}{\rref@init@lang@article}
% \begin{macro}{\rref@init@lang@para}
% \begin{macro}{\rref@init@lang@sub}
%    \begin{macrocode}
\newcommand\rref@init@lang@article[1]{%
    \rref@setup@lang{#1}{article}{%
        name=\GetTranslation{article},
        Name=\GetTranslation{Article},
        names=\GetTranslation{articles},
        Names=\GetTranslation{Articles},
        ref format=\rref@refformat@noop,
        label format=\rref@label@prefix,
        group conjunction={},
        group format=\rref@refformat@noop
    }%
}
\newcommand\rref@init@lang@para[1]{%
    \rref@setup@lang{#1}{para}{%
        name=\GetTranslation{paragraph},
        Name=\GetTranslation{Paragraph},
        names=\GetTranslation{paragraphs},
        Names=\GetTranslation{Paragraphs},
        ref format=\rref@refformat@parenthesis,
        label format=\rref@label@refonly,
        group conjunction={,},
        group format=\rref@refformat@noop
    }%
}
\newcommand\rref@init@lang@sub[1]{%
    \rref@setup@lang{#1}{sub}{%
        name=\GetTranslation{point},
        Name=\GetTranslation{Point},
        names=\GetTranslation{points},
        Names=\GetTranslation{Points},
        ref format=\rref@refformat@ordinal,
        label format=\rref@label@postfix,
        group conjunction={,},
        group format=\rref@group@braced
    }%
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\rref@setup}
% Declares \meta{language} and configures its three types at once. The declaration itself is recorded, so
% that \cmd{\rref@lang} can tell a supported language from an unsupported one.
%
% This is extension API and not an internal: it is what a language definition file calls, and it is
% supported as it stands for the whole of 1.x. The at sign is deliberate. A definition file is read with
% the at sign made a letter\,---\,\cmd{\RegulatoryLoadLanguage} sets the category code and restores it
% afterwards\,---\,which is the convention the kernel's own \file{.def} files and the
% \file{fc-\meta{language}.def} files of \package{fmtcount} are written under, and inside such a file the
% name asks for nothing. A document that declares a language in its own preamble puts the call between
% \cmd{\makeatletter} and \cmd{\makeatother}. The format commands it is given\,---\,\cmd{\rref@refformat@}
% and \cmd{\rref@label@} below, and \cmd{\rref@group@braced}\,---\,are part of the same interface.
%    \begin{macrocode}
\newcommand\rref@setup[4]{%
    \expandafter\gdef\csname rref@declared@#1\endcsname{}%
    \rref@init@lang@article{#1}
    \rref@init@lang@para{#1}
    \rref@init@lang@sub{#1}
    \rref@setup@lang{#1}{article}{#2}
    \rref@setup@lang{#1}{para}{#3}
    \rref@setup@lang{#1}{sub}{#4}
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\rref@lang}
% The language a reference is formatted in. Whenever the current language has no configuration of its own,
% the English one is used, which is always loaded. Note that this expands within \cmd{\csname}, so it must
% not produce a single space.
%    \begin{macrocode}
\def\rref@lang{%
    \ifcsname languagename\endcsname%
        \ifcsname rref@declared@\languagename\endcsname\languagename\else english\fi%
    \else english\fi%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\rref@get}
% \begin{macro}{\rref@set}
% Reading a single key of the current, or of an explicitly given, language. Where \cmd{\rref@get} prints the
% value, \cmd{\rref@set} stores it in the macro of its last argument.
%
% A designation that stands in front of more than one number is written in the plural: the Leidraad voor
% juridische auteurs writes \enquote{de artikelen 162 tot en met 164} and \enquote{onderdelen c en d}. The
% plural is a key of its own per type and per language, since it is not the language that decides it but
% the position: Dutch keeps \enquote{lid} singular where the designation follows the ordinals, and says so
% in its own definition file rather than here.
%    \begin{macrocode}
\ExplSyntaxOn
\NewDocumentCommand \rref@set { O{\rref@lang} m m m }
  {
    \prop_get:NeNF \g__regulatory_rref_prop { #1 / #2 / #3 } #4
      { \cs_set_eq:NN #4 \relax }
  }

\NewExpandableDocumentCommand \rref@get { O{\rref@lang} m m }
  { \prop_item:Ne \g__regulatory_rref_prop { #1 / #2 / #3 } }
\ExplSyntaxOff

\newif\ifrref@plural
\newcommand\rref@name[2][\rref@lang]{%
    \ifrref@plural%
        \@ifrrefcap{\rref@get[#1]{#2}{Names}}{\rref@get[#1]{#2}{names}}%
    \else%
        \@ifrrefcap{\rref@get[#1]{#2}{Name}}{\rref@get[#1]{#2}{name}}%
    \fi%
}
\def\rref@article@name{\rref@name{article}}
\def\rref@para@name{\rref@name{para}}
\def\rref@sub@name{\rref@name{sub}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% The formats of the current type applied to a number. A link format is a label format of which either the
% whole label or only the number is a hyperlink, depending on the \option{nameinlink} option.
%    \begin{macrocode}
\newcommand\rref@refformat[2][\rref@current@type]{\rref@set{#1}{ref format}{\@@rrefformat}\@@rrefformat{#2}}
\newcommand\rref@labelformat[2][\rref@current@type]{\rref@set{#1}{label format}{\@@labelformat}\@@labelformat{\rref@name{#1}}{#2}}
\newcommand\rref@linkformat[2][\rref@current@type]{%
    \@ifnameinlink{%
        \rref@linkpr{\rref@labelformat[#1]{\rref@refformat[#1]{#2}}}%
    }{%
        \rref@labelformat[#1]{\rref@linkpr{\rref@refformat[#1]{#2}}}%
    }%
}
\newcommand\rref@reflink[2][\rref@current@type]{%
    \rref@linkpr{\rref@refformat[#1]{#2}}%
}
\newcommand\rref@groupformat[2][\rref@current@type]{%
    \rref@set{#1}{group format}{\@@groupformat}\@@groupformat{#2}%
}
%    \end{macrocode}
%
% \subsubsection{\translation{Reference macros}{Verwijsmacro's}}
%
% \begin{macro}{\rref}
% \begin{macro}{\Rref}
% Refers with the number only. Whenever the label is not one of the structures of this bundle, the
% reference is handed over to \package{zref}, which knows how to refer to sections and the like.
%    \begin{macrocode}
\def\rref{\@ifstar\rref@star\rref@nostar}
\def\rref@star#1{%
    \rref@setcurrent{#1}%
    \ifnum\rref@current@value>0%
        \rref@refformat{\rref@current@value}%
    \else%
        \zref{#1}%
    \fi%
    \rref@capreset%
}
\def\rref@nostar#1{%
    \rref@setcurrent{#1}%
    \ifnum\rref@current@value>0%
        \rref@linkpr{\rref@refformat{\rref@current@value}}%
    \else%
        \zcref[noname]{#1}%
    \fi%
    \rref@capreset%
}
\def\Rref{\@ifstar\Rref@star\Rref@nostar}
\def\Rref@star#1{%
    \setboolean{rref@cap}{true}%
    \rref*{#1}%
}
\def\Rref@nostar#1{%
    \setboolean{rref@cap}{true}%
    \rref{#1}%
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\nref}
% \begin{macro}{\Nref}
% Refers with the designation and the number, in the order the language prescribes.
%    \begin{macrocode}
\def\nref{\@ifstar\nref@star\nref@nostar}
\def\nref@star#1{%
    \rref@setcurrent{#1}%
    \ifnum\rref@current@value>0%
        \rref@labelformat{\rref@refformat{\rref@current@value}}%
    \else%
        \zcref*{#1}%
    \fi%
    \rref@capreset%
}
\def\nref@nostar#1{%
    \rref@setcurrent{#1}%
    \ifnum\rref@current@value>0%
        \rref@linkformat{\rref@current@value}%
    \else%
        \zcref{#1}%
    \fi%
    \rref@capreset%
}
\def\Nref{\@ifstar\Nref@star\Nref@nostar}
\def\Nref@star#1{%
    \setboolean{rref@cap}{true}%
    \nref*{#1}%
}
\def\Nref@nostar#1{%
    \setboolean{rref@cap}{true}%
    \nref{#1}%
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \subsubsection{\translation{The current reference}{De huidige verwijzing}}
%
% \begin{macro}{\rref@setcurrent}
% Reads all properties of \meta{label} recorded by \package{regulatory-struct} and works out which type of
% reference it is.
%    \begin{macrocode}
\def\rref@setcurrent#1{%
    \def\rref@current{#1}%
    \def\rref@current@counter{\zref@extract{#1}{counter}}%
    \def\rref@current@article{\zref@extract{#1}{article}}%
    \def\rref@current@para{\zref@extract{#1}{para}}%
    \def\rref@current@sub{\zref@extract{#1}{sub}}%
    \rref@settype%
    \rref@setlink%
}
%    \end{macrocode}
% \end{macro}
%
% The counter of a label tells the type. Both the \cmd{\para} heading and the first level of the
% \texttt{paras} environment count as a paragraph, and anything else is left to \package{zref}, which is
% what the value of $-1$ stands for.
%    \begin{macrocode}
\def\rref@settype{%
    \ifthenelse{\equal{article}{\rref@current@counter}}{%
        \def\rref@current@type{article}%
        \def\rref@current@value{\rref@current@article}%
        \def\rref@current@fullformat{}%
    }{%
        \ifthenelse{\equal{para}{\rref@current@counter}\or\equal{parasi}{\rref@current@counter}}{%
            \def\rref@current@type{para}%
            \def\rref@current@value{\rref@current@para}%
        }{%
            \ifthenelse{\equal{parasii}{\rref@current@counter}}{%
                \def\rref@current@type{sub}%
                \def\rref@current@value{\rref@current@sub}%
            }{%
                \def\rref@current@type{}%
                \def\rref@current@value{-1}%
            }%
        }%
    }%
}
%    \end{macrocode}
%
% The anchor of a label within the current document, or the anchor within the URL of another document,
% which \package{regulatory-attachments} records with \cmd{\refdocument} and \cmd{\masterdocument}.
%    \begin{macrocode}
\def\rref@setlink{%
    \def\rref@current@anchor{\zref@extract{\rref@current}{anchor}}%
    \def\rref@current@url{\zref@extractdefault{\rref@current}{url}{}}%
    \def\rref@current@fullurl{\rref@current@url\hashchar\rref@current@anchor}%
}
%    \end{macrocode}
%
% \begin{macro}{\rref@number}
% The number of another label, of the type of the current reference. The sorting and the compaction of an
% enumeration compare labels with it.
%    \begin{macrocode}
\newcommand\rref@number[1]{%
    \zref@extractdefault{#1}{\rref@current@type}{-1}%
}
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{\translation{Complete references}{Volledige verwijzingen}}
%
% \begin{macro}{\aref@postlink@setup}
% Whatever follows a complete reference, which is nothing as long as the label belongs to this document.
% \package{regulatory-attachments} redefines this to mention the document a label of another document
% belongs to.
%    \begin{macrocode}
\newcommand\aref@postlink@setup[1]{%
    \def\@aref@postlink{}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\aref@setcurrent}
% A complete reference states all parent parts of the label as well, so a paragraph is prefixed with its
% article, and a point with both its article and its paragraph. Each of them is joined with the
% group conjunction of its own type.
%    \begin{macrocode}
\newcommand\aref@setcurrent[1]{%
    \def\aref@current@reflink{\rref@reflink[\rref@current@type]{\rref@current@value}}%
    \aref@postlink@setup{#1}%
    \ifthenelse{\equal{\rref@current@type}{article}}{%
        \def\@aref@prefix{}%
        \def\@aref@postfix{}%
    }{%
        \ifthenelse{\equal{\rref@current@type}{para}}{%
            \def\@aref@prefix{%
                \rref@labelformat[article]{\rref@current@article}\rref@get{article}{group conjunction}%
            }%
            \def\@aref@postfix{}%
        }{%
            \ifthenelse{\equal{\rref@current@type}{sub}}{%
                \def\@aref@prefix{%
                    \rref@labelformat[article]{\rref@refformat[article]{\rref@current@article}}\rref@get{article}{group conjunction}%
                    \rref@labelformat[para]{\rref@refformat[para]{\rref@current@para}}\rref@get{para}{group conjunction}%
                }%
                \def\@aref@postfix{}%
            }{%
                \def\@aref@prefix{}%
                \def\@aref@postfix{}%
            }%
        }%
    }%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\rref@labellist}
% Reads an enumeration of labels into \cmd{\rref@labels}. A space is what a writer naturally puts after a
% comma, and it used to be fatal in a way that said nothing: the number of a label with a leading space
% cannot be extracted, the default of that extraction is $-1$, and $-1$ is the terminator of the
% enumeration, so the list ended silently at the first space and every label behind it was dropped.
%
% The list is therefore split on the commas and each label is trimmed on its own. Taking every space out
% of the whole list would be shorter and wrong: a label may perfectly well have a space inside it, and a
% document that writes \verb|\aref{lid:meerwerk niet akkoord}| would then be looking for a label nobody
% ever declared, which is exactly the kind of silent miss this is meant to end.
%    \begin{macrocode}
\ExplSyntaxOn
\tl_new:N \rref@labels
\seq_new:N \l__regulatory_ref_labels_seq

\cs_new_protected:Npn \__regulatory_ref_append:n #1
{
    \tl_put_right:Nn \rref@labels { #1 }
}

\cs_new_protected:Npn \rref@labellist #1
{
    \seq_set_split:Nnn \l__regulatory_ref_labels_seq { , } { #1 }
    \tl_clear:N \rref@labels
    \seq_map_inline:Nn \l__regulatory_ref_labels_seq
    {
        \tl_if_empty:NF \rref@labels { \tl_put_right:Nn \rref@labels { , } }
        \tl_trim_spaces_apply:nN { ##1 } \__regulatory_ref_append:n
    }
}
\ExplSyntaxOff
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\aref}
% \begin{macro}{\Aref}
% A complete reference of one or more labels. All labels of an enumeration are of the same type, so the
% first one determines the prefix and the designation of the whole group.
%    \begin{macrocode}
\newcommand{\aref}[1]{%
    \rref@labellist{#1}%
    \def\@@arefsetup##1##2{%
        \rref@setcurrent{##1}%
        \aref@setcurrent{##1}%
        \rref@groupformat{\@aref@prefix}%
        ##2%
        \@aref@postfix\@aref@postlink%
    }%
    \expandafter\aref@dispatch\expandafter{\rref@labels}%
    \rref@capreset%
}

\newcommand\aref@dispatch[1]{%
    \IfSubStr{#1}{,}{%
        \StrBefore[1]{#1}{,}[\firstarg]%
        \@@arefsetup{\firstarg}{%
            \rref@pluraltrue\rref@labelformat{\aref@group{#1}}\rref@pluralfalse%
        }%
    }{%
        \@@arefsetup{#1}{\nref{#1}}%
    }%
}

\newcommand{\Aref}[1]{%
    \setboolean{rref@cap}{true}%
    \aref{#1}%
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \subsubsection{\translation{Enumerations}{Opsommingen}}
%
% An enumeration of labels is first sorted and then compacted, so that three or more consecutive numbers
% become a range. Both walk the comma separated list with a terminator at the end.
%    \begin{macrocode}
\def\listterminator{-1}

\newcommand\aref@group[1]{%
    \bubblesort{#1}%
    \expandafter\begincompaction\sortedlist,\listterminator,\relax%
}
%    \end{macrocode}
%
% \begin{macro}{\begincompaction}
% \begin{macro}{\findendlist}
% The compaction keeps track of the first label of the current run and of the last consecutive one found so
% far. As soon as the run is broken, it is printed as a single reference, as a pair joined with a
% conjunction, or as a range, after which the remainder of the list is compacted the same way.
%    \begin{macrocode}
\def\begincompaction#1,#2\relax{%
    \def\startlist{#1}%
    \def\currentendlist{#1}%
    \findendlist#2\relax%
}
\def\findendlist#1,#2\relax{%
    \ifnum\numexpr\rref@number{\currentendlist}+1\relax=\rref@number{#1}\relax%
        \def\currentendlist{#1}%
        \findendlist#2\relax%
    \else%
        \ifnum\rref@number{\startlist}=\rref@number{\currentendlist}\relax%
            \ignorespaces\rref{\startlist}\unskip%
        \else%
            \ifnum\numexpr\rref@number{\startlist}+1\relax=\rref@number{\currentendlist}\relax%
                \ignorespaces\rref{\startlist}\unskip%
                \ifnum\rref@number{#1}=\listterminator\relax%
                    \rref@lastconjunction%
                \else%
                    \rref@middleconjunction%
                \fi\ignorespaces%
                \rref{\currentendlist}\unskip%
            \else%
                \ignorespaces\rref{\startlist}\unskip\rref@rangeconjunction\ignorespaces%
                \rref{\currentendlist}\unskip%
            \fi%
        \fi%
        \ifnum\rref@number{#1}=\listterminator\else%
            \IfStrEq{#2}{\listterminator,}{\rref@lastconjunction}{\rref@middleconjunction}\begincompaction#1,#2\relax%
        \fi%
    \fi%
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\bubblesort}
% Sorting is done on the number of the type of the current reference, by swapping the first two labels that
% are out of order and starting over with the result.
%    \begin{macrocode}
\newcommand\bubblesort[1]{\def\sortedlist{}\sortlist#1,\listterminator,\relax}
\def\sortlist#1,#2,#3\relax{%
    \rref@setcurrent{#1}%
    \aref@setcurrent{#1}%
    \ifnum\rref@number{#2}=\listterminator\relax%
        \edef\sortedlist{\sortedlist#1}%
    \else%
        \ifnum\rref@number{#1}<\rref@number{#2}\relax%
            \edef\sortedlist{\sortedlist#1,}%
            \sortlist#2,#3\relax%
        \else%
            \let\tmp\sortedlist%
            \def\sortedlist{}%
            \expandafter\sortlist\tmp#2,#1,#3\relax%
        \fi%
    \fi%
}
%    \end{macrocode}
% \iffalse
%</package>
% \fi
% \end{macro}
%
% \Finale
%
