% \iffalse meta-comment
%
%% regulatory-struct.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 is the only file that names the work. The sources and the manual carry a
% notice pointing here; the test files carry none, since a listing of one in the
% manual would open with seventeen lines of licence.
%
% This work consists of the files regulatory.ins,
% regulatory-struct.dtx, regulatory-ref.dtx,
% regulatory-defs.dtx, regulatory-attachments.dtx,
% regulatory-md.dtx, regulatory-sign.dtx,
% regulatory-sources.dtx,
% regulatory-html.dtx,
% regulatory-english.def, regulatory-dutch.def,
% regulatory-german.def, regulatory-french.def,
% regulatory-syntax.lua,
% regulatory.tex, regulatory-preamble.tex,
% regulatory-nl.tex, regulatory-en.tex,
% regulatory-syntax.c2t.tex,
% example1.tex, example2.tex,
% example1.bib, example2.bib, sources.bib,
% example1-nl.tex, example2-nl.tex,
% example1-en.tex, example2-en.tex,
% md-example.tex, example.md, de-example.tex,
% date-example.tex, nolang-example.tex,
% index-example.tex, index-defs.tex,
% sign-example.tex, source-example.tex,
% attach-example.tex,
% badsource.tex, badsource.bib,
% badsyntax.tex, badsyntax.bib,
% conformance.sh, conformance.tex, latexmkrc,
% and the derived files regulatory.sty, regulatory-struct.sty,
% regulatory-defs.sty, regulatory-ref.sty,
% regulatory-attachments.sty, regulatory-md.sty,
% regulatory-sign.sty, regulatory-sources.sty
% and regulatory.4ht.
%
% \fi
%
% \iffalse
%<*driver>
\ProvidesFile{regulatory-struct.dtx}
%</driver>
%<wrapper>\NeedsTeXFormat{LaTeX2e}
%<wrapper>\ProvidesPackage{regulatory}
%<wrapper>    [2026/09/10 1.0.0 Xerdi's Regulatory Package]
%<package>\NeedsTeXFormat{LaTeX2e}
%<package>\ProvidesPackage{regulatory-struct}
%<package>    [2026/09/10 1.0.0 Xerdi's Regulatory Package (Structures)]
%
%<*driver>
% The manuals in the doc directory are the actual drivers of this
% bundle. This driver typesets this single module and is meant to be
% run from within the doc directory.
\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-struct.dtx}
\end{document}
%</driver>
% \fi
%
% \subsection{\texorpdfstring{\package{regulatory-struct}}{regulatory-struct}}
% \setcounter{CodelineNo}{0}
%
% \subsubsection{The bundle}
%
% The \package{regulatory} package itself is nothing more than a wrapper around the six modules that are
% always loaded. \package{regulatory-sign} is among them: it defines two commands and emits nothing until
% one of them is used, and a document that needs a signature field is exactly the kind this bundle is for.
% \package{regulatory-md} is the seventh and is not loaded here; a hook pulls it in as soon as
% \package{markdown} is. Every option is handed over to \package{regulatory-struct}, which administers the
% options for the whole bundle. Every other module requests its own prerequisites, so the order below
% merely documents the dependency chain.
% \iffalse
%<*wrapper>
% \fi
%    \begin{macrocode}
\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{regulatory-struct}}
\ProcessOptions\relax
\RequirePackage{regulatory-struct}
\RequirePackage{regulatory-defs}
\RequirePackage{regulatory-ref}
\RequirePackage{regulatory-attachments}
\RequirePackage{regulatory-sign}
\RequirePackage{regulatory-sources}
%    \end{macrocode}
% \iffalse
%</wrapper>
% \fi
%
% \subsubsection{\translation{Package options}{Pakketopties}}
%
% Everything from here on belongs to \package{regulatory-struct}. The options are keys of the
% \texttt{regulatory} family of \pkg{l3keys}, which the kernel offers and which this bundle uses for every
% key it reads: the options here, the argument of \cmd{\srcref}, and the fields of an attachment. The
% registers of \zcref{sec:sources} are the one thing that is not keys but a store, and those are property
% lists.
% \iffalse
%<*package>
% \fi
% \package{ifthen} rather than \package{xifthen}: measured, nothing here uses a command of the second that
% the first does not have, and \package{xifthen} drags in \package{calc}, which changes how every
% \cmd{\setlength} in the document is parsed. \package{xspace} stood here as well and is gone; it was
% called nowhere.
%    \begin{macrocode}
\RequirePackage{ifthen}
%    \end{macrocode}
%
% \begin{macro}{\ifregulatory@markdown}
% \begin{macro}{\ifregulatory@bibtogls}
% \begin{macro}{\ifregulatory@legacy}
% \begin{macro}{\ifregulatory@alldefs}
% \begin{macro}{\ifregulatory@nameinlink}
% Each switch option is stored in a \cmd{\newif} switch, which \texttt{.legacy\_if\_set:n} sets. The
% switches are shared by every module, which is the reason for keeping them in this base module. The
% \texttt{nameinlink} switch is declared with \cmd{\newboolean}, because it is queried with
% \cmd{\ifthenelse} in \package{regulatory-ref} as well; \cmd{\newboolean} builds a \cmd{\newif} switch,
% so the same property reaches it.
%    \begin{macrocode}
\newif\ifregulatory@markdown
\newif\ifregulatory@bibtogls
\newif\ifregulatory@legacy
\newif\ifregulatory@alldefs
\newboolean{regulatory@nameinlink}
\ExplSyntaxOn
\tl_new:N \regulatory@defstyle
\tl_new:N \regulatory@sourcestyle
\tl_new:N \regulatory@attachkind
\keys_define:nn { regulatory }
  {
    md          .legacy_if_set:n = regulatory@markdown ,
    md          .default:n       = true ,
    md          .initial:n       = false ,
    bib2gls     .legacy_if_set:n = regulatory@bibtogls ,
    bib2gls     .default:n       = true ,
    bib2gls     .initial:n       = true ,
    legacy      .legacy_if_set:n = regulatory@legacy ,
    legacy      .default:n       = true ,
    legacy      .initial:n       = false ,
    alldefs     .legacy_if_set:n = regulatory@alldefs ,
    alldefs     .default:n       = true ,
    alldefs     .initial:n       = false ,
    nameinlink  .legacy_if_set:n = regulatory@nameinlink ,
    nameinlink  .default:n       = true ,
    nameinlink  .initial:n       = true ,
    defstyle    .tl_set:N        = \regulatory@defstyle ,
    defstyle    .initial:n       = alttree ,
%    \end{macrocode}
% The style a citation of an external source is written in is a choice and not a string, so that a value
% this bundle does not know is refused where it is given. It used to be stored as given, and a misspelling
% then reached every register lookup as a path that holds nothing: a citation came out with its numbers and
% without a single word, and nothing said so.
%    \begin{macrocode}
    sourcestyle .choice: ,
    sourcestyle / full    .code:n = \tl_set:Nn \regulatory@sourcestyle { full } ,
    sourcestyle / short   .code:n = \tl_set:Nn \regulatory@sourcestyle { short } ,
    sourcestyle / voluit  .code:n = \tl_set:Nn \regulatory@sourcestyle { full } ,
    sourcestyle / verkort .code:n = \tl_set:Nn \regulatory@sourcestyle { short } ,
    sourcestyle .initial:n = full ,
%    \end{macrocode}
% How a link to an attachment is made is a choice for the same reason, and the two values are not a
% matter of taste. \texttt{goto} is the default and the semantically right one: an embedded go-to
% action names the file inside this document. It is also the one \package{poppler} does not
% implement, and that is the engine under most viewers on a free desktop, so there the link does
% nothing at all. \texttt{annotation} places a file attachment annotation over the same text
% instead, which both Acrobat and \package{poppler} do implement, at the price of an annotation that
% the A-standards want an appearance for. Measured, not read out of a manual: the shared library of
% \package{poppler} names \texttt{GoTo}, \texttt{GoToR}, \texttt{Launch} and \texttt{Named} among
% its actions and \texttt{GoToE} nowhere, and \texttt{FileAttachment} among its annotations.
%    \begin{macrocode}
    attachmentlink .choice: ,
    attachmentlink / goto       .code:n =
      \tl_set:Nn \regulatory@attachkind { goto } ,
    attachmentlink / annotation .code:n =
      \tl_set:Nn \regulatory@attachkind { annotation } ,
    attachmentlink .initial:n = goto ,
    bronstijl   .meta:n    = { sourcestyle = {#1} } ,
  }
\ExplSyntaxOff
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\regulatory@defstyle}
% \begin{macro}{\regulatory@sourcestyle}
% The two options that carry a value rather than a switch. \option{defstyle} holds the name of the style
% \cmd{\printdefs} reaches for when it is given no style of its own; \option{sourcestyle} holds
% \texttt{full} or \texttt{short}, which is the arrangement \cmd{\srcref} writes a citation in.
% \end{macro}
% \end{macro}
%
% \begin{macro}{\regulatorysetup}
% Sets the same keys after the package is loaded, and is what a \file{regulatory.cfg} writes. A local
% configuration file is read before the options given to the package are processed, so a document always
% wins from the directory it stands in.
%    \begin{macrocode}
\ExplSyntaxOn
\NewDocumentCommand \regulatorysetup { m }
  { \keys_set:nn { regulatory } { #1 } }
\ExplSyntaxOff

\InputIfFileExists{regulatory.cfg}{%
    \PackageInfo{regulatory}{Using local configuration file}%
}{%
    \PackageInfo{regulatory}{No local configuration file}%
}

\ProcessKeyOptions[regulatory]
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{\translation{Prerequisites}{Vereisten}}
%
% Whenever \package{markdown} is loaded, the renderers of \package{regulatory-md} translate its constructs
% into the structures of this module. The hook fires whatever the order of both packages is, since it is
% executed right away for a \package{markdown} that is loaded already.
%
% It cannot fire in the middle of this module, though, and the \option{md} option below makes it try:
% \package{regulatory-md} needs \package{regulatory-defs}, which loads \package{glossaries}, and
% \package{glossaries} decides whether its entries become hyperlinks by looking for \package{hyperref},
% which this module only loads a few lines further down. A document with the \option{md} option therefore
% used to get definitions without a single link, and nothing said so. The load is postponed to the end of
% this file instead, where every prerequisite is in place.
%    \begin{macrocode}
\newif\ifregulatory@md@pending
\newif\ifregulatory@ready
\AddToHook{package/markdown/after}{%
    \ifregulatory@ready
        \RequirePackage{regulatory-md}%
    \else
        \regulatory@md@pendingtrue
    \fi
}
%    \end{macrocode}
%
% The \option{md} option comes down to loading \package{markdown} itself. This has to happen before
% \package{enumitem} is loaded, otherwise \package{markdown} breaks the list definitions further down,
% which is the reason for loading it here rather than leaving it to the document. The options
% \package{markdown} is to be given are not stated here but in \package{regulatory-md}, which sets them
% with \cmd{\markdownSetup}: a document that loads \package{markdown} by itself then gets the same
% conversion as one that used the \option{md} option.
%    \begin{macrocode}
\ifregulatory@markdown
\RequirePackage{markdown}
\fi
%    \end{macrocode}
%
% The remaining prerequisites of the whole bundle are loaded here, in this exact order. The \texttt{xr}
% option of \package{zref} is only used by \package{regulatory-attachments}, but has to be loaded before
% \package{hyperref}, which is loaded by this module. \package{glossaries} is not among them: it belongs to
% \package{regulatory-defs}, so a document that only wants the structures does not carry it.
%
% \package{xr-hyper} used to stand beside it and is gone. Nothing in this bundle calls
% \cmd{\externaldocument}; the references to another document are \cmd{\zexternaldocument} of
% \package{zref-xr}, and the links they produce come from \package{zref-hyperref}. Measured on the same
% example built both ways: eleven \texttt{/GoToR} actions, eighteen link annotations and two file
% specifications, with the package and without it. A document that wants \cmd{\externaldocument} loads
% \package{xr-hyper} itself, which is where that choice belongs.
%    \begin{macrocode}
\RequirePackage{xcolor}
\RequirePackage{enumitem}
\RequirePackage{fmtcount}
\RequirePackage{scrextend}
\RequirePackage[user,counter,hyperref,xr]{zref}
\RequirePackage{zref-xr,zref-user,zref-clever,zref-hyperref}
\RequirePackage{hyperref}
\RequirePackage{translations}
%    \end{macrocode}
%
% \begin{macro}{\regulatory@ifmodule}
% The language definition files of \package{regulatory-ref} configure whatever module happens to be loaded.
% This test tells them which parts to skip. Its first argument is the module name without the
% \texttt{regulatory-} prefix.
%    \begin{macrocode}
\newcommand\regulatory@ifmodule[3]{%
    \@ifundefined{ver@regulatory-#1.sty}{#3}{#2}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\GetTranslation}
% English is the fallback of every translation used by this bundle. The languages themselves are declared
% in the language definition files of \package{regulatory-ref}.
%    \begin{macrocode}
\DeclareTranslationFallback{article}{article}
\DeclareTranslationFallback{Article}{Article}
\DeclareTranslationFallback{articles}{articles}
\DeclareTranslationFallback{Articles}{Articles}
\DeclareTranslationFallback{paragraph}{paragraph}
\DeclareTranslationFallback{Paragraph}{Paragraph}
\DeclareTranslationFallback{paragraphs}{paragraphs}
\DeclareTranslationFallback{Paragraphs}{Paragraphs}
\DeclareTranslationFallback{point}{point}
\DeclareTranslationFallback{Point}{Point}
\DeclareTranslationFallback{points}{points}
\DeclareTranslationFallback{Points}{Points}
\DeclareTranslationFallback{Definitions}{Definitions}
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{\translation{Colors}{Kleuren}}
%
% All colors default to black, so they only have to be redefined, e.g.\ with \cmd{\colorlet}, whenever
% headings should stand out.
%    \begin{macrocode}
\providecolor{artlabel}{rgb}{0,0,0}
\providecolor{arttitle}{rgb}{0,0,0}
\providecolor{paralabel}{rgb}{0,0,0}
\providecolor{paratitle}{rgb}{0,0,0}
\providecolor{sublabel}{rgb}{0,0,0}
\providecolor{subtitle}{rgb}{0,0,0}
%    \end{macrocode}
%
% \subsubsection{\translation{Headings}{Koppen}}
%
% \begin{macro}{\article}
% \begin{macro}{\para}
% Articles and paragraphs are ordinary counters, where the paragraph counter is reset by the article
% counter.
%    \begin{macrocode}
\newcounter{article}
\newcounter{para}
\counterwithin{para}{article}

\renewcommand{\thearticle}{\arabic{article}}
\renewcommand{\thepara}{\arabic{para}}
%    \end{macrocode}
% The headings themselves are provided by \package{titlesec}. As soon as the new \LaTeX{} heading interface
% is available, \cmd{\ParseLaTeXeHeading} is defined and both headings are declared as \texttt{heading}
% instances instead, since \package{titlesec} and the new interface exclude each other.
%    \begin{macrocode}
\@ifundefined{ParseLaTeXeHeading}{%
    \RequirePackage{titlesec}%
    \titleclass{\article}[0]{straight}%
    \titleformat{\article}{\normalfont\color{arttitle}}
        {\bfseries\color{artlabel}\GetTranslation{Article} \thearticle.\quad}{1em}{}%
    \titlespacing*{\article}{0pt}{3.5ex plus 1ex minus .2ex}{5pt}%
    \titleclass{\para}{straight}[\article]%
    \titleformat{\para}{\normalfont\color{paratitle}}
        {\normalfont\color{paralabel}\thearticle.\thepara.\quad}{1em}{}%
    \titlespacing*{\para}{0pt}{3.5ex plus 1ex minus .2ex}{5pt}%
}{%
    \DeclareInstance{heading}{regulatory-article}{display}{
        name                = article,
        level               = 1,
        heading-decls       = \normalfont\color{arttitle},
        prefix              = \GetTranslation{Article},
        prefix-decls        = \bfseries\color{artlabel},
        number-decls        = \bfseries\color{artlabel},
        number-format       = \thearticle.,
        headformat-instance = regulatory-article,
        before-vspace       = 3.5ex plus 1ex minus .2ex,
        after-vspace        = 5pt,
    }%
    \DeclareInstance{headformat}{regulatory-article}{hang}{
        heading-indent   = 0pt,
        number-title-sep = 2em,
    }%
    \DeclareInstance{heading}{regulatory-para}{display}{
        name                = para,
        parent-name         = article,
        level               = 2,
        heading-decls       = \normalfont\color{paratitle},
        number-decls        = \normalfont\color{paralabel},
        number-format       = \thearticle.\thepara.,
        headformat-instance = regulatory-para,
        before-vspace       = 3.5ex plus 1ex minus .2ex,
        after-vspace        = 5pt,
    }%
    \DeclareInstance{headformat}{regulatory-para}{hang}{
        heading-indent   = 0pt,
        number-title-sep = 2em,
    }%
    \DeclareDocumentCommand\article{som}{%
        \ParseLaTeXeHeading{regulatory-article}{#1}{#2}{#3}%
    }%
    \DeclareDocumentCommand\para{som}{%
        \ParseLaTeXeHeading{regulatory-para}{#1}{#2}{#3}%
    }%
}
%    \end{macrocode}
% Both headings take part in the table of contents at the level of subsections and subsubsections.
%    \begin{macrocode}
\newcommand{\l@article}{\@dottedtocline{1}{1.5em}{2.3em}}
\def\toclevel@article{2}
\newcommand{\l@para}{\@dottedtocline{1}{3.8em}{2.3em}}
\def\toclevel@para{3}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \subsubsection{\translation{Lists}{Lijsten}}
%
% \begin{environment}{provisions}
% \begin{environment}{paras}
% Provisions are a flat enumeration within a section, whereas paragraphs and points are the two
% levels of the \texttt{paras} environment. The label of the first level repeats the article number, and the
% second level is enumerated alphabetically with \cmd{\abalphnum} of \package{fmtcount}, so it isn't limited
% to 26 points.
%    \begin{macrocode}
\newcounter{provisions}
\newlist{provisions}{enumerate}{1}
\setlist[provisions,1]{label=\arabic*.,align=left,itemsep=0pt}
\counterwithin{provisions}{section}

\newlist{paras}{enumerate}{2}
\@ifpackageloaded{latex-lab-enumitem}{%
    \setlist[paras,1]{label=\thearticle.\arabic*.,align=left,itemsep=0pt}%
    \setlist[paras,2]{label=\abalphnum{\arabic*}),itemsep=0pt}%
}{%
    \setlist[paras,1]{label=\thearticle.\arabic*.,ref=\arabic*,align=left,itemsep=0pt}%
    \setlist[paras,2]{label=\abalphnum{\arabic*}),ref=\arabic*,itemsep=0pt}%
}
\counterwithin{parasi}{article}
\counterwithin{parasii}{parasi}
%    \end{macrocode}
% The list counters of \package{enumitem} are numbered per list, while references have to address them as
% part of the document structure. Therefore both representations are rewritten right before every item.
%    \begin{macrocode}
\AddToHook{cmd/item/before}{%
    \@ifundefined{c@parasi}{}{%
        \renewcommand\theparasi{\thearticle.\arabic{parasi}}%
        \renewcommand\theparasii{\theparasi\abalphnum{\arabic{parasii}}}%
    }%
}
%    \end{macrocode}
% \end{environment}
% \end{environment}
%
% \subsubsection{\translation{Reference properties}{Verwijseigenschappen}}
%
% Every label records the article, paragraph and point it appears in, which is what
% \package{regulatory-ref} builds its references upon. A paragraph is either a \cmd{\para} heading or the
% first level of the \texttt{paras} environment, so both are stored in the same property.
%    \begin{macrocode}
\zref@newprop{article}[-1]{\number\value{article}}
\zref@newprop{para}[-1]{\ifnum\value{para}>0\number\value{para}\else\number\value{parasi}\fi}
\zref@newprop{sub}[-1]{\number\value{parasii}}
\zref@addprops{main}{article,para,sub}
%    \end{macrocode}
%
% Every \cmd{\label} records them without anything further being asked of it: \cmd{\zref@addprops} puts
% the properties on the \texttt{main} list, and \package{zref-clever} labels with that list from the
% \texttt{label} hook, which it installs itself unless its \option{labelhook} option says otherwise.
%
% This package used to hook \cmd{\zlabel} onto \cmd{\label} once more, through
% \cmd{\RegisterPostLabelHook} of \package{xassoccnt}. That wrote a second and identical
% \cmd{\zref@newlabel} for every label, which the next run reads back as a label that is defined twice:
% every document built with this package carried a dozen or more `multiply defined' warnings and
% nothing else went wrong, which is exactly why it took this long to notice.
%
% References made with \cmd{\zcref} of \package{zref-clever} get the designations of these structures, so
% that both ways of referring stay consistent. The counters \texttt{parasi} and \texttt{parasii} are the
% list variants of a paragraph and a point.
%    \begin{macrocode}
\zcRefTypeSetup{article}{%
    Name-sg = \GetTranslation{Article},
    name-sg = \GetTranslation{article},
    Name-pl = \GetTranslation{Articles},
    name-pl = \GetTranslation{articles}
}
\zcRefTypeSetup{para}{%
    Name-sg = \GetTranslation{Paragraph},
    name-sg = \GetTranslation{paragraph},
    Name-pl = \GetTranslation{Paragraphs},
    name-pl = \GetTranslation{paragraphs}
}
\zcRefTypeSetup{parasi}{%
    Name-sg = \GetTranslation{Paragraph},
    name-sg = \GetTranslation{paragraph},
    Name-pl = \GetTranslation{Paragraphs},
    name-pl = \GetTranslation{paragraphs}
}
\zcRefTypeSetup{parasii}{%
    Name-sg = \GetTranslation{Point},
    name-sg = \GetTranslation{point},
    Name-pl = \GetTranslation{Points},
    name-pl = \GetTranslation{points}
}
%    \end{macrocode}
%
% \subsubsection{\translation{Language files}{Taalbestanden}}
%
% Every language supported by this bundle has its own definition file \texttt{regulatory-\meta{language}.def},
% comparable to the \texttt{fc-\meta{language}.def} files of \package{fmtcount}. Such a file declares the
% translations of the bundle and, whenever \package{regulatory-ref} is loaded, the reference formats of that
% language. The loading mechanism lives in this module, so a document that only loads
% \package{regulatory-struct} is translated as well.
%
% \begin{macro}{\ProvidesRegulatoryLanguage}
% Every language file identifies itself with this macro, just like \cmd{\ProvidesFile} does.
%    \begin{macrocode}
\newcommand\ProvidesRegulatoryLanguage[1]{%
    \ProvidesFile{regulatory-#1.def}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\RegulatoryLoadLanguage}
% Loads the definition file of \meta{language}, unless it is already loaded. A language without a definition
% file is silently accepted, since \cmd{\regulatory@load@languages} offers every language known to
% \package{babel}, most of which this bundle does not support. Definition files are read at the end of the
% preamble, where the at sign is no letter, so its category code is set and restored around them. The
% tilde as well: \LaTeX{} makes it an ordinary space while it reads a package file, and a language file is
% largely a set of decisions about spacing. That is not a detail\,---\,measured, a tilde that quietly
% became a space took every non-breaking space in a citation register with it.
%    \begin{macrocode}
\newcommand\RegulatoryLoadLanguage[1]{%
    \@ifundefined{ver@regulatory-#1.def}{%
        \edef\regulatory@restoreat{%
            \catcode`\noexpand\@=\the\catcode`\@\relax
            \catcode`\noexpand\~=\the\catcode`\~\relax}%
        \makeatletter
        \catcode`\~=13\relax
        \InputIfFileExists{regulatory-#1.def}{%
            \PackageInfo{regulatory}{Loaded language definitions for `#1'}%
        }{%
            \PackageInfo{regulatory}{No language definitions for `#1'}%
        }%
        \regulatory@restoreat
    }{}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\regulatory@load@languages}
% English is always loaded, as it holds the defaults every other language builds upon. The languages of the
% document itself are only known once \package{babel} or \package{polyglossia} is loaded, which is why this
% runs at the very end of the preamble. Documents using another language selection mechanism can call
% \cmd{\RegulatoryLoadLanguage} in their preamble instead.
%
% Every language this bundle ships is read whatever the document says, and not only the ones it speaks.
% A language file holds two things: how that language words a reference, and how a legal order writing in
% it words a citation. The second is a property of the source and not of the document\,---\,a Dutch
% contract cites a German regulation in German\,---\,so a register that were only read when the document
% spoke its language would be missing exactly where it is needed. Reading a language a document does not
% speak costs nothing that shows: everything in such a file is keyed by the name of its language, so it
% defines what nobody asks for.
%
% Three places are asked, because no single one of them is right. \cmd{\bbl@loaded} is the list
% \package{babel} keeps, and it is empty under the \texttt{ini} based loading that \texttt{provide=*}
% selects; \cmd{\xpg@loaded} is the same list for \package{polyglossia}; and \cmd{\languagename} is the one
% language that is current, which is correct in every case but names only one. Measured on the same
% document with only the \package{babel} line differing: the classic form gave \enquote{Artikel 1, eerste
% lid} and the \texttt{ini} form gave \enquote{Article 1(1)}, because the list was empty and Dutch was
% therefore never loaded. Nothing failed, and the reference was simply worded in another language than the
% document.
%    \begin{macrocode}
\ExplSyntaxOn
\clist_new:N \g_regulatory_languages_clist

\cs_new_protected:Npn \regulatory@collect@languages
  {
    \clist_gset:Nx \g_regulatory_languages_clist
      {
        \cs_if_exist_use:cF { bbl@loaded } { } ,
        \cs_if_exist_use:cF { xpg@loaded } { } ,
        \cs_if_exist_use:cF { languagename } { }
      }
    \clist_gremove_duplicates:N \g_regulatory_languages_clist
  }

\clist_const:Nn \c_regulatory_shipped_clist { english , dutch , german , french }

\cs_new_protected:Npn \regulatory@load@languages
  {
    \regulatory@collect@languages
    \clist_map_inline:Nn \c_regulatory_shipped_clist
      { \RegulatoryLoadLanguage { ##1 } }
    \clist_map_inline:Nn \g_regulatory_languages_clist
      { \RegulatoryLoadLanguage { ##1 } }
  }
\ExplSyntaxOff
\AddToHook{begindocument/before}{\regulatory@load@languages}
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{\translation{What the run cannot fix}{Wat de run niet kan verhelpen}}
%
% \begin{macro}{\regulatory@checkenvironment}
% Three things this bundle cannot do anything about, and which show up in the result rather than in the
% log. Each of them was found the hard way, by reading an output that looked finished, so each is said out
% loud once at the beginning of the document.
%
% A language without a definition file is accepted where it is loaded, since \package{babel} may well be
% asked for a language that is only used for a quotation. What it costs is only visible in a reference: the
% wording falls back on English, so a Dutch document that never declared Dutch reads
% \enquote{Article 1(1)} in the middle of its own sentences. The languages are listed rather than counted,
% since the one that is missing is the point. They are the same three sources the loader reads, which
% matters more than it looks: a check that asked \cmd{\bbl@loaded} alone would share the blind spot of the
% thing it is meant to watch, and stay silent in exactly the case it exists for.
%
% Under \package{tex4ht}, the configuration of this bundle is what turns an article into a section with a
% heading. Without it the conversion still succeeds and produces neither: a heading becomes a paragraph of
% text and nothing says so. The test is for the configuration itself, not for the file, so a copy that
% shadows the one of the package fails it just as loudly as a missing one.
%
% Also under \package{tex4ht}: PDF management pulls in the list code of latex-lab, which leaves
% \package{tex4ht} nothing to turn a \texttt{paras} item into, and the items come out as running text.
% A document that is converted as well as typeset declares its \cmd{\DocumentMetadata} conditionally, which
% is what the examples of this bundle do.
%    \begin{macrocode}
\ExplSyntaxOn
\cs_new:Npn \regulatory@languages { \clist_use:Nn \g_regulatory_languages_clist { , } }
\ExplSyntaxOff

\newcommand\regulatory@checkenvironment{%
    \def\regulatory@missinglangs{}%
    \@for\regulatory@lang:=\regulatory@languages\do{%
        \@ifundefined{ver@regulatory-\regulatory@lang.def}{%
            \edef\regulatory@missinglangs{%
                \regulatory@missinglangs
                \ifx\regulatory@missinglangs\@empty\else, \fi
                \regulatory@lang}%
        }{}%
    }%
    \ifx\regulatory@missinglangs\@empty\else%
        \PackageWarning{regulatory}{%
            No definitions for the language(s) \regulatory@missinglangs;\MessageBreak
            references in them are worded in English. Reported}%
    \fi%
    \ifdefined\HCode%
        \@ifundefined{a:regarticle}{%
            \PackageWarning{regulatory}{%
                regulatory.4ht was not found, so an article and a\MessageBreak
                paragraph convert to running text without a heading.\MessageBreak
                Reported}%
        }{}%
        \IfDocumentMetadataTF{%
            \PackageWarning{regulatory}{%
                PDF management is active under tex4ht, which leaves it\MessageBreak
                nothing to turn a paras item into. Declare\MessageBreak
                \string\DocumentMetadata\space only when \string\HCode\space is undefined.\MessageBreak
                Reported}%
        }{}%
    \fi%
}
\AddToHook{begindocument/end}{\regulatory@checkenvironment}
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{\translation{Postponed modules}{Uitgestelde modules}}
%
% Everything this module provides is now in place, so \package{regulatory-md} can be loaded for the
% \package{markdown} that was loaded above, or for one the document loaded before this module.
%    \begin{macrocode}
\regulatory@readytrue
\ifregulatory@md@pending
\RequirePackage{regulatory-md}
\fi
%    \end{macrocode}
% \iffalse
%</package>
% \fi
%
% \Finale
%
