% \iffalse meta-comment % %% regulatory-sources.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-sources.dtx} % %\NeedsTeXFormat{LaTeX2e} %\ProvidesPackage{regulatory-sources} % [2026/09/10 1.0.0 Xerdi's Regulatory Package (External sources)] % %<*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-sources.dtx} \end{document} % % \fi % % \subsection{\texorpdfstring{\package{regulatory-sources}}{regulatory-sources}} % \setcounter{CodelineNo}{0} % % A regulatory document cites instruments that are not this document: a statute, a regulation of the % Union. This module holds the ones a document cites, so that the wording of a citation is a property of % the document rather than of the sentence it happens to stand in. What it does \emph{not} do is decide the % wording; that is the next module. This one reads and holds. % % \subsubsection{\translation{Prerequisites}{Vereisten}} % % \iffalse %<*package> % \fi % \begin{macrocode} \RequirePackage{regulatory-struct} % \end{macrocode} % % \subsubsection{\translation{Sources of a source}{Bronnen van een bron}} % % Sources are declared in a \file{bib} file, which is the format such records are already kept in, and % read by this module rather than by \package{biblatex} or \package{bib2gls}. Neither would be wrong; both % would put an external program between a document and a handful of records. The test suite of this bundle % promises a \TeX{} installation and nothing else, the conversion to HTML runs the same documents, and a % document rarely cites more than a few instruments. So the reading is done here, and the price of that is % that this module owns a parser. % % A parser that is owned has to say what it accepts. This one accepts the shape a \file{bib} file is % written in when a person writes it, and nothing further: % % \begin{labeling}{\quad} % \item[] an entry opens with \texttt{@}\meta{type}\texttt{\{}\meta{key}\texttt{,} on a line of its own; % \item[] a field is \meta{name}~\texttt{= \{}\meta{value}\texttt{\},} on a line of its own; % \item[] the entry closes with \texttt{\}} on a line of its own; % \item[] a line that is empty, or that starts with \texttt{\%}, is a comment. % \end{labeling} % % A line that is none of these is an error naming the file and the line, rather than a line that is % skipped. That is the whole reason a parser may be owned at all: the failure of a reader has to be loud, % since a record that was not read is a citation that comes out empty and a document that looks finished. % \begin{macrocode} \ExplSyntaxOn \prop_new:N \g__regulatory_src_required_prop \prop_new:N \g__regulatory_src_type_prop \prop_new:N \g__regulatory_src_register_prop \prop_new:N \g__regulatory_src_typealias_prop \prop_new:N \g__regulatory_src_fieldalias_prop \seq_new:N \g__regulatory_src_keys_seq \ior_new:N \g__regulatory_src_ior \str_new:N \l__regulatory_src_key_str \str_new:N \l__regulatory_src_type_str \str_new:N \l__regulatory_src_file_str \str_new:N \l__regulatory_src_query_str \int_new:N \l__regulatory_src_line_int \bool_new:N \l__regulatory_src_open_bool \seq_new:N \l__regulatory_src_parts_seq \tl_new:N \l__regulatory_src_required_tl \clist_new:N \l__regulatory_src_required_clist \tl_new:N \l__regulatory_src_one_tl \tl_new:N \l__regulatory_src_two_tl % \end{macrocode} % % \begin{macro}{\newsourcetype} % Declares an entry type, the fields an entry of it cannot do without, and the register its citations are % worded in. The required fields are what the wording needs in every register: a Dutch regulation is named % by its citeertitel, an act of the Union by what kind of act it is and by its number. % % The register belongs to the type and not to the document, because it is the legal order of the instrument % that decides how a citation of it reads. A Dutch contract that cites the \textsc{gdpr} words that % citation the way the regulation itself does. An entry may override it with a \texttt{register} field. % \begin{macrocode} \NewDocumentCommand \newsourcetype { m m m } { \prop_gput:Nnn \g__regulatory_src_required_prop { #1 } { #2 } \prop_gput:Nnn \g__regulatory_src_register_prop { #1 } { #3 } } \NewDocumentCommand \newsourcetypealias { m m } { \prop_gput:Nnn \g__regulatory_src_typealias_prop { #1 } { #2 } } \NewDocumentCommand \newsourcefieldalias { m m } { \prop_gput:Nnn \g__regulatory_src_fieldalias_prop { #1 } { #2 } } \cs_new:Npn \__regulatory_src_alias:Nn #1#2 { \tl_if_blank:eTF { \prop_item:Nn #1 { #2 } } { #2 } { \prop_item:Nn #1 { #2 } } } \cs_generate_variant:Nn \__regulatory_src_alias:Nn { Ne } \cs_new:Npn \regulatory@src@type@of #1 { \__regulatory_src_alias:Ne \g__regulatory_src_typealias_prop { #1 } } \cs_new:Npn \regulatory@src@field@of #1 { \__regulatory_src_alias:Ne \g__regulatory_src_fieldalias_prop { #1 } } \ExplSyntaxOff \newsourcetype{regulation}{citetitle}{dutch} \newsourcetype{euact}{kind,number}{dutch_eu} % \end{macrocode} % % The names above are English, as the rest of this bundle is, and every one of them answers to a Dutch name % as well. A bib file is written by the person who keeps the records, and that person writes % \texttt{citetitle} because that is what the field is called in the law that defines it. Neither name is % a translation of the other in the reader: the Dutch one resolves to the English one before anything is % stored, so a file may use either and a document may read back either. % \begin{macrocode} \newsourcetypealias{regeling}{regulation} \newsourcetypealias{euhandeling}{euact} \newsourcefieldalias{citeertitel}{citetitle} \newsourcefieldalias{afkorting}{abbreviation} \newsourcefieldalias{boek}{book} \newsourcefieldalias{geldig}{valid} \newsourcefieldalias{soort}{kind} \newsourcefieldalias{nummer}{number} \newsourcefieldalias{roepnaam}{shortname} \newsourcefieldalias{titel}{title} \newsourcefieldalias{pb}{oj} \newsourcefieldalias{lidwoord}{determiner} % \end{macrocode} % \end{macro} % % \begin{macro}{\newsource} % Declares one source in the document itself, which is the route that needs no file at all. It ends in the % same store as a line read from a \file{bib} file, so nothing downstream can tell the two apart. % \begin{macrocode} \ExplSyntaxOn \NewDocumentCommand \newsource { m m m } { \__regulatory_src_begin:nn { #2 } { #1 } \keyval_parse:nnn { \__regulatory_src_novalue:n } { \__regulatory_src_field:nn } { #3 } \__regulatory_src_end: } \cs_new_protected:Npn \__regulatory_src_novalue:n #1 { \msg_error:nnn { regulatory-sources } { no-value } { #1 } } % \end{macrocode} % \end{macro} % % \subsubsection*{Opening an entry} % % \verb|\__regulatory_src_begin:nn| % Opens an entry of \meta{type} under \meta{key}. An undeclared type and a key that is already taken are % both errors: the first is a record nothing can word, the second is a record that would quietly replace % one the document already relies on. % \begin{macrocode} \cs_new_protected:Npn \__regulatory_src_begin:nn #1#2 { \str_set:Nx \l__regulatory_src_type_str { \regulatory@src@type@of { #1 } } \str_set:Nn \l__regulatory_src_key_str { #2 } \prop_if_in:NVF \g__regulatory_src_required_prop \l__regulatory_src_type_str { \msg_error:nnxx { regulatory-sources } { unknown-type } { \l__regulatory_src_type_str } { \l__regulatory_src_key_str } } \seq_if_in:NVT \g__regulatory_src_keys_seq \l__regulatory_src_key_str { \msg_error:nnx { regulatory-sources } { duplicate-key } { \l__regulatory_src_key_str } } \prop_new:c { g__regulatory_src_e_ \l__regulatory_src_key_str _prop } \bool_set_true:N \l__regulatory_src_open_bool } % \end{macrocode} % % \subsubsection*{Storing a field} % % \verb|\__regulatory_src_field:nn| % Stores one field of the entry that is open. The name of the field is lowered and expanded into the key % it is stored under, while the value is not expanded at all: a value is data, and a document that writes % a macro in a bib file gets that macro back rather than what it produced at reading time. % \begin{macrocode} \cs_new_protected:Npn \__regulatory_src_field:nn #1#2 { \bool_if:NTF \l__regulatory_src_open_bool { \use:x { \prop_gput:cnn { g__regulatory_src_e_ \l__regulatory_src_key_str _prop } { \regulatory@src@field@of { \str_lowercase:n { #1 } } } { \exp_not:n { #2 } } } } { \msg_error:nnn { regulatory-sources } { stray-field } { #1 } } } % \end{macrocode} % % \subsubsection*{Closing an entry} % % \verb|\__regulatory_src_end:| % Closes the entry and holds it against the fields its type requires. This is the moment the guarantee is % made: from here on a source may be read without asking whether it is complete, which is what lets the % commands that word a citation be expandable and silent. % \begin{macrocode} \cs_new_protected:Npn \__regulatory_src_end: { \prop_get:NVN \g__regulatory_src_required_prop \l__regulatory_src_type_str \l__regulatory_src_required_tl \quark_if_no_value:NF \l__regulatory_src_required_tl { \clist_set:NV \l__regulatory_src_required_clist \l__regulatory_src_required_tl \clist_map_inline:Nn \l__regulatory_src_required_clist { \prop_if_in:cnF { g__regulatory_src_e_ \l__regulatory_src_key_str _prop } { ##1 } { \msg_error:nnxxx { regulatory-sources } { missing-field } { ##1 } { \l__regulatory_src_key_str } { \l__regulatory_src_type_str } } } } \__regulatory_src_checkvalid: \prop_gput:NVV \g__regulatory_src_type_prop \l__regulatory_src_key_str \l__regulatory_src_type_str \seq_gput_right:NV \g__regulatory_src_keys_seq \l__regulatory_src_key_str \bool_set_false:N \l__regulatory_src_open_bool } % \end{macrocode} % % \verb|\__regulatory_src_checkvalid:| % Every entry says when it was last held against the text it describes. The date it gives is what % \cmd{\sourcedate} is compared with, so an entry without one is never reported stale: \enquote{not looked % at yet} and \enquote{looked at and current} would come out as the same silence. A guard whose off switch % is an absent field is switched off by accident rather than by decision, so the absence is said out loud % and the decision is given a word of its own\,---\,\texttt{valid = unverified}, which is silent, because % the author has then said it. Anything else that is not a date is said as well, since a date in another % shape compares wrongly rather than not at all. % % Asked for by the sibling session that keeps the sources this reader is written for, on the argument this % whole bundle is built on. % % There is deliberately no fourth state for \enquote{checked and known to have changed}. Such an entry % already warns: it keeps its last good date, the document speaks later, and the source is named. A word in % place of that date would fire the same warning while throwing the date away, and the date is the one thing % that says how far behind the entry is and whether the citation in front of the reader predates the change. % A note that an entry is known to be wrong is for a person reading the file, not a state this guard reads. % \begin{macrocode} \cs_new_protected:Npn \__regulatory_src_checkvalid: { \prop_get:cnNTF { g__regulatory_src_e_ \l__regulatory_src_key_str _prop } { valid } \l__regulatory_src_valid_tl { \str_if_eq:VnF \l__regulatory_src_valid_tl { unverified } { \regex_match:NVF \c__regulatory_src_date_regex \l__regulatory_src_valid_tl { \msg_warning:nnxx { regulatory-sources } { valid-not-iso } { \l__regulatory_src_key_str } { \l__regulatory_src_valid_tl } } } } { \msg_warning:nnx { regulatory-sources } { no-valid } { \l__regulatory_src_key_str } } } \cs_generate_variant:Nn \regex_match:NnF { NVF } \msg_new:nnn { regulatory-sources } { no-valid } { The~source~`#1'~does~not~say~when~it~was~last~held~against~the~text~it~ describes,~\\ so~it~can~never~be~reported~out~of~date.~Give~it~valid~=~YYYY-MM-DD,~or~ valid~=~unverified~to~say~so~on~purpose.~Reported } \msg_new:nnn { regulatory-sources } { valid-not-iso } { The~source~`#1'~gives~valid~=~`#2',~which~is~neither~YYYY-MM-DD~nor~ unverified.~\\ Dates~are~compared~as~they~are~written,~so~this~one~compares~wrongly~rather~ than~not~at~all.~Reported } % \end{macrocode} % % \begin{macro}{\loadsources} % Reads \meta{file}\texttt{.bib}. The file is looked up the way \TeX{} looks up a file it is given, so it % is found next to the document or anywhere on the input path; a file that is not there is an error and % not an empty list of sources. % \begin{macrocode} \NewDocumentCommand \loadsources { m } { \file_get_full_name:nNTF { #1 .bib } \l__regulatory_src_file_str { \__regulatory_src_read:V \l__regulatory_src_file_str } { \msg_error:nnn { regulatory-sources } { file-not-found } { #1 .bib } } } \cs_new_protected:Npn \__regulatory_src_read:n #1 { \int_zero:N \l__regulatory_src_line_int \bool_set_false:N \l__regulatory_src_open_bool \ior_open:Nn \g__regulatory_src_ior { #1 } \ior_str_map_inline:Nn \g__regulatory_src_ior { \__regulatory_src_line:nn { #1 } { ##1 } } \ior_close:N \g__regulatory_src_ior \bool_if:NT \l__regulatory_src_open_bool { \msg_error:nnxx { regulatory-sources } { unclosed } { \l__regulatory_src_key_str } { #1 } } } \cs_generate_variant:Nn \__regulatory_src_read:n { V } % \end{macrocode} % \end{macro} % % \subsubsection*{Reading one line} % % \verb|\__regulatory_src_line:nn| % One line of the file, tried against the four shapes the subset knows. The order is the order they occur % in: a comment or a blank line first, since a file holds more of those than anything else. % \begin{macrocode} \regex_const:Nn \c__regulatory_src_blank_regex { \A \s* (\%.*)? \Z } \regex_const:Nn \c__regulatory_src_open_regex { \A \s* \@ (\w+) \s* \{ \s* ([^,\s\{\}]+) \s* ,? \s* \Z } \regex_const:Nn \c__regulatory_src_field_regex { \A \s* (\w+) \s* = \s* \{ (.*) \} \s* ,? \s* \Z } \regex_const:Nn \c__regulatory_src_close_regex { \A \s* \} \s* ,? \s* \Z } \cs_new_protected:Npn \__regulatory_src_pair:N #1 { \tl_set:Nx \l__regulatory_src_one_tl { \seq_item:Nn \l__regulatory_src_parts_seq { 2 } } \tl_set:Nx \l__regulatory_src_two_tl { \seq_item:Nn \l__regulatory_src_parts_seq { 3 } } \exp_args:NVV #1 \l__regulatory_src_one_tl \l__regulatory_src_two_tl } \cs_new_protected:Npn \__regulatory_src_line:nn #1#2 { \int_incr:N \l__regulatory_src_line_int \regex_match:NnTF \c__regulatory_src_blank_regex { #2 } { } { \regex_extract_once:NnNTF \c__regulatory_src_open_regex { #2 } \l__regulatory_src_parts_seq { \__regulatory_src_pair:N \__regulatory_src_begin:nn } { \regex_extract_once:NnNTF \c__regulatory_src_field_regex { #2 } \l__regulatory_src_parts_seq { \__regulatory_src_pair:N \__regulatory_src_field:nn } { \regex_match:NnTF \c__regulatory_src_close_regex { #2 } { \__regulatory_src_end: } { \msg_error:nnxxx { regulatory-sources } { unreadable } { \int_use:N \l__regulatory_src_line_int } { #1 } { #2 } } } } } } % \end{macrocode} % % \begin{macro}{\srcfield} % \begin{macro}{\srctype} % Reads one field of a source. Both are expandable and both give nothing for a field that is not there, % which is safe precisely because a source cannot be declared without the fields its type requires: what % is absent here is optional by construction. % \begin{macrocode} \cs_new:Npn \__regulatory_src_read:nn #1#2 { \prop_item:cn { g__regulatory_src_e_ #1 _prop } { #2 } } \cs_generate_variant:Nn \__regulatory_src_read:nn { ee } \cs_new:Npn \srcfield #1#2 { \__regulatory_src_read:ee { #1 } { \regulatory@src@field@of { #2 } } } \cs_new:Npn \srctype #1 { \prop_item:Nn \g__regulatory_src_type_prop { #1 } } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\srcregister} % The register a source is worded in: the one its type declares, unless the entry says otherwise. % \begin{macrocode} \cs_new:Npn \srcregister #1 { \tl_if_blank:eTF { \srcfield { #1 } { register } } { \prop_item:Ne \g__regulatory_src_register_prop { \prop_item:Nn \g__regulatory_src_type_prop { #1 } } } { \srcfield { #1 } { register } } } % \end{macrocode} % \end{macro} % % \begin{macro}{\ifsourceexists} % Whether \meta{key} was declared at all. The key is made into a string before it is looked for: the keys % of a file were read as text, and a sequence compares what it holds character by character, category code % and all\,---\,so a key typed in the document would never equal the same key read from a file. % \begin{macrocode} \NewDocumentCommand \ifsourceexists { m m m } { \str_set:Nn \l__regulatory_src_query_str { #1 } \seq_if_in:NVTF \g__regulatory_src_keys_seq \l__regulatory_src_query_str { #2 } { #3 } } % \end{macrocode} % \end{macro} % % \subsubsection{\translation{Registers}{Registers}} % % A citation is worded in the register of the instrument it points at, and every register has two systems: % one written out in full and one shortened. Which of the two applies is a property of the place the % citation stands in\,---\,the Leidraad has it in full in the running text and shortened in a footnote, and % shortened as well when it stands between brackets in the running text\,---\,so the call decides and the % document sets the default. % % Seven keys are enough to word a citation. Five of them are macros, and each of them is handed the macro % to put its result in rather than expanding to it: writing an ordinal in words is work that % \package{fmtcount} does with a command that cannot be expanded, and a citation is assembled before it is % typeset so that it can be read back. % % \begin{labeling}{\texttt{separator}} % \item[\texttt{article}] the word before the number of an article. % \item[\texttt{number}] the number itself, which is where the colon notation of the civil code lives. % \item[\texttt{paragraph}] the paragraph, which Dutch calls a lid. % \item[\texttt{point}] the lettered point, which Dutch calls an onderdeel. % \item[\texttt{subpoint}] the level below that, which the standards call a subonderdeel. % \item[\texttt{separator}] what stands between the parts: a comma in full, a space when shortened. % \item[\texttt{determiner}] the article a name takes when neither the entry nor the kind of the % instrument says, which is a genitive in the registers of the Union: \enquote{der Verordnung}, % \enquote{du règlement}. % \item[\texttt{connective}] what stands between the last part and the instrument: \enquote{connective} when written % out in full, nothing when shortened. % \item[\texttt{assemble}] how the parts are arranged: from the outside in, which is what a register % that leaves this out gets, or the other way round, which is what English does. % \item[\texttt{attachnum}] the shape the number of a paragraph takes when it hangs on its article % rather than standing on its own. Brackets in English, and around each of them where there is more % than one: \enquote{Article 6(1), (2) and (3)}, measured, against \enquote{paragraphs 1 and 2} % where the same paragraphs stand by themselves. % \item[\texttt{attach}] how that number is bound to the article, which in English is simply against % it. Only a register arranged the other way round needs either of these two. % \item[\texttt{source}] the instrument itself, named from the fields of its entry. % \end{labeling} % \begin{macrocode} \ExplSyntaxOff \newcommand\regulatory@src@ordinal[1]{\ordinalstringnum{#1}} \ExplSyntaxOn \prop_new:N \g__regulatory_src_register_store_prop \cs_generate_variant:Nn \prop_item:Nn { Ne } % \end{macrocode} % Which registers were declared, in the order they were, so that the set of them can be read back. The % store above is keyed by register, system and key at once, so it answers what a register says and not % which registers there are, and the manual names them one by one. This is what lets the suite hold that % list against the code rather than against the last time somebody looked. % \begin{macrocode} \seq_new:N \g__regulatory_src_registers_seq \cs_new_protected:Npn \__regulatory_src_register_put:nnnn #1#2#3#4 { \prop_gput:Nnn \g__regulatory_src_register_store_prop { #1 / #2 / #3 } { #4 } } \cs_new_protected:Npn \__regulatory_src_register_bare:nnn #1#2#3 { \msg_error:nnnnn { regulatory-sources } { register-key-without-value } { #1 } { #2 } { #3 } } \msg_new:nnn { regulatory-sources } { register-key-without-value } { The~key~`#3'~of~register~`#1'~(#2)~was~given~no~value.~\\ Every~key~of~a~register~carries~one:~a~word,~a~number~format~or~an~arrangement. } \NewDocumentCommand \newsourceregister { m m m } { \seq_if_in:NnF \g__regulatory_src_registers_seq { #1 } { \seq_gput_right:Nn \g__regulatory_src_registers_seq { #1 } } \keyval_parse:nnn { \__regulatory_src_register_bare:nnn { #1 } { full } } { \__regulatory_src_register_put:nnnn { #1 } { full } } { #2 } \keyval_parse:nnn { \__regulatory_src_register_bare:nnn { #1 } { short } } { \__regulatory_src_register_put:nnnn { #1 } { short } } { #3 } } \cs_new:Npn \regsrc@get #1#2#3 { \prop_item:Ne \g__regulatory_src_register_store_prop { #1 / #2 / #3 } } \cs_new_protected:Npn \regsrc@set #1#2#3#4 { \prop_get:NeNF \g__regulatory_src_register_store_prop { #1 / #2 / #3 } #4 { \cs_set_eq:NN #4 \relax } } \cs_generate_variant:Nn \prop_get:NnNF { NeNF } \ExplSyntaxOff % \end{macrocode} % % The register of the Dutch legislator, which is also the one a Dutch author writes in. In full it is the % form the Aanwijzingen voor de regelgeving prescribe for regulations themselves\,---\,a model rather than % a rule for a document that is not a regulation, since those instructions bind ministries and not % contracts. Shortened it is the form of the Leidraad: no commas, the designation before the number, and % the colon notation for the civil code. % \begin{macrocode} % Where the designation stands: before its numbers in nearly every register, after % them where a paragraph is written as an ordinal. \newcommand\regulatory@src@before[3]{\def#1{#3~#2}} \newcommand\regulatory@src@after[3]{\def#1{#2\space#3}} % One number, in the shape its level takes. \newcommand\regulatory@src@num@plain[2]{\def#1{#2}} \newcommand\regulatory@src@num@paren[2]{\def#1{#2)}} \newcommand\regulatory@src@num@degree[2]{\def#1{#2\textdegree}} \newcommand\regulatory@src@num@parens[2]{\def#1{(#2)}} % A paragraph written into the article it belongs to, which is the English form. \newcommand\regulatory@src@attach@plain[3]{\def#1{#2#3}} \newcommand\regulatory@src@num@ordinal[2]{% \storeordinalstringnum{regsrc}{#2}% \expandafter\let\expandafter\regulatory@src@ord\csname @fcs@regsrc\endcsname \let#1\regulatory@src@ord } \newcommand\regulatory@src@num@unmeasured[2]{% \PackageWarning{regulatory-sources}{% This register has no measured form for the level below a point,\MessageBreak so the number is written on its own. Reported}% \def#1{#2}% } \newcommand\regulatory@src@paragraph@absatz[2]{\def#1{Absatz~#2}} \newcommand\regulatory@src@paragraph@paragraphe[2]{\def#1{paragraphe~#2}} \newcommand\regulatory@src@point@buchstabe[2]{\def#1{Buchstabe~#2}} \newcommand\regulatory@src@point@point[2]{\def#1{point~#2)}} % \end{macrocode} % % Which article a name takes is not a property of the register but of the instrument, and the entry % already says which instrument it is. Counted in the same regulation: \enquote{de la directive} sixteen % times against \enquote{du règlement} seven, so a single default for French is wrong more often than it % is right, and \enquote{du directive} is not a matter of style but of grammar. German is the same story % one step further: \enquote{der} carries Verordnung and Richtlinie but not Beschluss or Vertrag, which % take \enquote{des}. % % So the determiner is looked up by the kind of the instrument, and the \texttt{determiner} field of an % entry overrides that for the case no table can know. % \begin{macrocode} % \end{macrocode} % % The pieces the registers above are built from. A number carries the book of the civil code in the % shortened form and leaves it to the name of the instrument in the full one, which is what % \enquote{artikel 96 \dots{} van Boek 6 van het Burgerlijk Wetboek} against \enquote{art. 6:96 BW} comes % down to. % \begin{macrocode} \newcommand\regulatory@src@number@plain[3]{\def#1{#3}} \newcommand\regulatory@src@number@colon[3]{% \ifthenelse{\equal{#2}{}}{\def#1{#3}}{\def#1{#2:#3}}% } % \end{macrocode} % % The ordinal keeps an ordinary space between the number and the word it belongs to. The regulation binds % a label to its number with a space that does not break, but it writes its numbers after the label, % \texttt{lid 6}, and never as an ordinal: \emph{zesde lid} does not occur in it once. What binds % \emph{zesde} to \emph{lid} in the national register is therefore not measured, and this bundle does not % decide it. % \begin{macrocode} \newcommand\regulatory@src@source@full@store[2]{% \protected@edef#1{\regulatory@src@source@full{#2}}% } \newcommand\regulatory@src@source@short@store[2]{% \protected@edef#1{\regulatory@src@source@short{#2}}% } \ExplSyntaxOn \prop_new:N \g__regulatory_src_determiner_prop \tl_new:N \l__regulatory_src_det_tl \tl_new:N \l__regulatory_src_kind_tl \cs_generate_variant:Nn \str_lowercase:n { V } \NewDocumentCommand \newsourcedeterminer { m m m } { \tl_set:Nx \l__regulatory_src_kind_tl { #1 / \str_lowercase:n { #2 } } \prop_gput:NVn \g__regulatory_src_determiner_prop \l__regulatory_src_kind_tl { #3 } } % \end{macrocode} % % Worked out before the citation is built rather than while it is: the entry decides first, then the kind % of the instrument, then the default of the register. Doing it here rather than in an expandable macro % keeps the lookup a plain lookup. % \begin{macrocode} \cs_new_protected:Npn \regulatory@src@setdet #1 { \tl_set:Nx \l__regulatory_src_det_tl { \srcfield { #1 } { determiner } } \tl_if_blank:VT \l__regulatory_src_det_tl { \tl_set:Nx \l__regulatory_src_kind_tl { \srcfield { #1 } { kind } } \tl_set:Nx \l__regulatory_src_kind_tl { \regulatory@src@reg / \str_lowercase:V \l__regulatory_src_kind_tl } \tl_set:Nx \l__regulatory_src_det_tl { \exp_args:NNV \prop_item:Nn \g__regulatory_src_determiner_prop \l__regulatory_src_kind_tl } } \tl_if_blank:VT \l__regulatory_src_det_tl { \tl_set:Nx \l__regulatory_src_det_tl { \regulatory@src@defdet } } \tl_set_eq:NN \regulatory@src@thisdet \l__regulatory_src_det_tl } \cs_new:Npn \regulatory@src@determiner #1 { \regulatory@src@thisdet } \ExplSyntaxOff \ExplSyntaxOn \cs_new:Npn \regulatory@src@naam #1 { \tl_if_blank:eTF { \srcfield { #1 } { shortname } } { \srcfield { #1 } { citetitle } } { \srcfield { #1 } { shortname } } } \cs_new:Npn \regulatory@src@source@full #1 { \tl_if_blank:eF { \srcfield { #1 } { book } } { Boek~ \srcfield { #1 } { book } \c_space_tl van~ } \tl_if_blank:eF { \regulatory@src@determiner { #1 } } { \regulatory@src@determiner { #1 } ~ } \regulatory@src@naam { #1 } } \cs_new:Npn \regulatory@src@source@short #1 { \tl_if_blank:eTF { \srcfield { #1 } { abbreviation } } { \regulatory@src@naam { #1 } } { \srcfield { #1 } { abbreviation } } } \ExplSyntaxOff \ExplSyntaxOn % \end{macrocode} % % \subsubsection{\translation{Where a register lives}{Waar een register staat}} % % Not here. A register is written in the language definition file of its language, % \file{regulatory-\meta{language}.def}, next to the words that language calls a provision by. Those two % are one measurement: what says that German writes \enquote{Artikel 6 Absatz 1 Buchstabe a} in a citation % is the same reading of the same text that says it calls a paragraph an \emph{Absatz}. Keeping them apart % would mean one measurement landing in two files, where it can drift. % % It also spares whoever writes one a second set of names. The language is \texttt{dutch} to % \package{babel} and the register is \texttt{dutch} here, and \texttt{dutch\_eu} is that same language % writing in the legal order of the Union. % % Those files are read for every language this bundle ships, whatever language the document is in, because % a register belongs to the source and not to the document: a Dutch contract cites a German regulation in % German. \zcref{sec:lang} has the loading rule. % % \subsubsection{\translation{Naming more than one}{Meer dan één noemen}} % % A citation may name a list of provisions or a run of them, which the source writes as % \enquote{artikelen 101 en 102} and \enquote{artikelen 12 tot en met 15}. Both are written by the author % rather than worked out here: \texttt{point=\{c,d\}} is a list and \texttt{point=\{a--c\}} is a % run, and the register decides how either reads. % % The far end of a range does not always read like the near one: the civil code is cited as % \enquote{art. 6:162-164}, where the book is named once and the second number stands on its own. A run % therefore formats its two ends separately, and every other level hands the same format twice. % % Three things are counted apart because the register words them apart: the numbers, which each go through % the format of their level; the words that join them; and the designation, which takes its plural as soon % as there is more than one. Measured in the same regulation, with the non-breaking space where the source % puts it: \enquote{artikelen~101 en~102}, \enquote{artikelen~12 tot en met~15}, \enquote{punten~c) en~e)}, % \enquote{Buchstaben~c und e}, \enquote{Absätze~1, 2 und~3}, \enquote{paragraphes~1 et 4}. % \begin{macrocode} \ExplSyntaxOn \seq_new:N \l__regulatory_src_items_seq \tl_new:N \l__regulatory_src_joined_tl \int_new:N \l__regulatory_src_count_int \cs_new_protected:Npn \regulatory@src@join #1#2#3#4#5#6 { \tl_clear:N \l__regulatory_src_joined_tl \tl_if_in:nnTF { #2 } { -- } { \__regulatory_src_range:nnnn { #2 } { #3 } { #6 } { #5 } } { \__regulatory_src_list:nnn { #2 } { #3 } { #4 } } \tl_set_eq:NN #1 \l__regulatory_src_joined_tl } \cs_new_protected:Npn \__regulatory_src_range:nnnn #1#2#3#4 { \seq_set_split:Nnn \l__regulatory_src_items_seq { -- } { #1 } \int_set:Nn \l__regulatory_src_count_int { 2 } \seq_pop_left:NN \l__regulatory_src_items_seq \l_tmpa_tl \exp_args:NNV #2 \l__regulatory_src_piece_tl \l_tmpa_tl \tl_put_right:NV \l__regulatory_src_joined_tl \l__regulatory_src_piece_tl \tl_put_right:Nn \l__regulatory_src_joined_tl { #4 } \seq_pop_left:NN \l__regulatory_src_items_seq \l_tmpa_tl \exp_args:NNV #3 \l__regulatory_src_piece_tl \l_tmpa_tl \tl_put_right:NV \l__regulatory_src_joined_tl \l__regulatory_src_piece_tl } \cs_new_protected:Npn \__regulatory_src_list:nnn #1#2#3 { \seq_set_split:Nnn \l__regulatory_src_items_seq { , } { #1 } \seq_set_map_x:NNn \l__regulatory_src_items_seq \l__regulatory_src_items_seq { \tl_trim_spaces:n { ##1 } } \int_set:Nn \l__regulatory_src_count_int { \seq_count:N \l__regulatory_src_items_seq } \int_step_inline:nnn { 1 } { \l__regulatory_src_count_int } { \int_compare:nNnT { ##1 } > { 1 } { \int_compare:nNnTF { ##1 } = { \l__regulatory_src_count_int } { \tl_put_right:Nn \l__regulatory_src_joined_tl { #3 } } { \tl_put_right:Nn \l__regulatory_src_joined_tl { ,~ } } } \tl_set:Nx \l_tmpa_tl { \seq_item:Nn \l__regulatory_src_items_seq { ##1 } } \exp_args:NNV #2 \l__regulatory_src_piece_tl \l_tmpa_tl \tl_put_right:NV \l__regulatory_src_joined_tl \l__regulatory_src_piece_tl } } \tl_new:N \l__regulatory_src_piece_tl \cs_new:Npn \regulatory@src@items { \int_use:N \l__regulatory_src_count_int } \ExplSyntaxOff % \end{macrocode} % % \subsubsection{\translation{Citing a source}{Een bron aanhalen}} % % \begin{macro}{\srcref} % Cites \meta{key}, either as a whole or down to one of its provisions. The optional argument holds the % provision\,---\,\texttt{article}, \texttt{paragraph}, \texttt{point} and \texttt{subpoint}\,---\,and stands % before the key, as it does in \cmd{\cite}, so that a bracket in the sentence after the citation is not % mistaken for it. % % The star asks for the system that is not the default of the document, which is what a citation between % brackets or in a footnote wants. It may also be named outright with \texttt{system}. The default of the % document is the \option{sourcestyle} option, and it is \texttt{full}, since that is what the running text % of a document is. % % What it comes to is built up in \cmd{\regulatory@src@last} before it is typeset, so that the wording of a % citation can be read back rather than only looked at. That is what the test suite asserts on: a citation % in the wrong register fails nowhere, it simply stands there wrong. % \begin{macrocode} \ExplSyntaxOff \newcommand\regulatory@src@system{\regulatory@sourcestyle} % \end{macrocode} % The Dutch names are meta keys, and the value of a meta key is braced on the way through: a meta key sets % its target by running the key parser again, so \texttt{onderdeel=\{c,d\}} would arrive as two keys, of % which the second is a key named \texttt{d} that does not exist. Measured: without the braces the list and % range citations lost their second item and \LaTeX{} said only that a key was unknown, naming a letter. % \begin{macrocode} \ExplSyntaxOn \keys_define:nn { regulatory / srcref } { article .code:n = \def \regulatory@src@article { #1 } , paragraph .code:n = \def \regulatory@src@paragraph { #1 } , point .code:n = \def \regulatory@src@point { #1 } , subpoint .code:n = \def \regulatory@src@subpoint { #1 } , system .code:n = \def \regulatory@src@thissystem { #1 } , date .code:n = \tl_set:Nn \l__regulatory_src_thisdate_tl { #1 } , datum .meta:n = { date = {#1} } , artikel .meta:n = { article = {#1} } , lid .meta:n = { paragraph = {#1} } , onderdeel .meta:n = { point = {#1} } , onder .meta:n = { subpoint = {#1} } , } \cs_new_protected:Npn \regulatory@src@setkeys #1 { \keys_set:nn { regulatory / srcref } { #1 } } \ExplSyntaxOff % \end{macrocode} % % \begin{macro}{\sourcedate} % The date a citation speaks as of. A reference to legislation is a reference to a \emph{version} of it: % the same article read a year apart is not necessarily the same article, and the Juriconnect standard says % so by carrying the date in the reference itself. This bundle does not print the date and does not build % the link yet, but it refuses to let a document leave it unsaid, because the alternative is a citation % that silently means \enquote{whenever this was last typeset}. % % It is a warning and not an error on purpose: a document that cites without a date is defective, but it is % not broken, and a package that cannot be added to an existing document without stopping it is a package % that does not get added. The warning is said once, and names the command that answers it. % % An entry may carry a \texttt{valid} field, which is the date the data of that entry was last checked. % When the document speaks as of a later date than that, the entry cannot vouch for itself and says so, % once per source. That is what makes a shared file of sources safe to use at all, wherever it is kept: the % identifiers in it never age, the dates do, and a document that outruns the data it was handed is told % rather than quietly given whatever the last update to that file happened to contain. This bundle ships % no legislation itself and is not the place for it\,---\,a citeertitel changes on its own clock and a % package on CTAN does not\,---\,but it is the place for the machinery that says when the two have come % apart. % \begin{macrocode} \ExplSyntaxOn \tl_new:N \g__regulatory_src_date_tl \tl_new:N \l__regulatory_src_thisdate_tl \seq_new:N \g__regulatory_src_dated_seq \bool_new:N \g__regulatory_src_nodate_bool \regex_const:Nn \c__regulatory_src_date_regex { \A \d{4}-\d{2}-\d{2} \Z } \msg_new:nnn { regulatory-sources } { date-not-iso } { The~date~`#1'~is~not~of~the~form~YYYY-MM-DD.~\\ Dates~are~compared~as~they~are~written,~so~another~form~would~compare~wrongly~ rather~than~not~at~all. } \NewDocumentCommand \sourcedate { m } { \regex_match:NnTF \c__regulatory_src_date_regex { #1 } { \tl_gset:Nn \g__regulatory_src_date_tl { #1 } } { \msg_error:nnn { regulatory-sources } { date-not-iso } { #1 } } } \cs_new_protected:Npn \__regulatory_src_checkdate:n #1 { \tl_if_empty:NT \l__regulatory_src_thisdate_tl { \tl_set_eq:NN \l__regulatory_src_thisdate_tl \g__regulatory_src_date_tl } \tl_if_empty:NTF \l__regulatory_src_thisdate_tl { \bool_if:NF \g__regulatory_src_nodate_bool { \bool_gset_true:N \g__regulatory_src_nodate_bool \msg_warning:nn { regulatory-sources } { no-date } } } { \__regulatory_src_checkstale:n { #1 } } } \cs_new_protected:Npn \__regulatory_src_checkstale:n #1 { \tl_set:Nx \l__regulatory_src_valid_tl { \srcfield { #1 } { valid } } \tl_if_empty:NF \l__regulatory_src_valid_tl { \str_compare:eNeT \l__regulatory_src_thisdate_tl > \l__regulatory_src_valid_tl { \seq_if_in:NnF \g__regulatory_src_dated_seq { #1 } { \seq_gput_right:Nn \g__regulatory_src_dated_seq { #1 } \msg_warning:nnxxx { regulatory-sources } { stale-source } { #1 } { \l__regulatory_src_valid_tl } { \l__regulatory_src_thisdate_tl } } } } } \cs_generate_variant:Nn \str_compare:nNnT { eNeT } \msg_new:nnn { regulatory-sources } { no-date } { This~document~cites~legislation~without~saying~as~of~when.~\\ Put~\iow_char:N\\sourcedate\{YYYY-MM-DD\}~in~the~preamble,~or~give~one~ citation~its~own~with~date=YYYY-MM-DD.~Reported } \msg_new:nnn { regulatory-sources } { stale-source } { The~source~`#1'~was~last~checked~on~#2,~and~this~document~speaks~as~of~#3.~\\ Whatever~changed~in~between~is~not~in~this~citation.~Reported } \cs_new_protected:Npn \regulatory@src@checkdate #1 { \__regulatory_src_checkdate:n { #1 } } \cs_new_protected:Npn \regulatory@src@cleardate { \tl_clear:N \l__regulatory_src_thisdate_tl } \ExplSyntaxOff % \end{macrocode} % \end{macro} % % \begin{macrocode} \newcommand\regulatory@src@thislabel{} \newcommand\regulatory@src@label[2]{% \ifnum\regulatory@src@items>1 \edef\regulatory@src@thislabel{% \regsrc@get{\regulatory@src@reg}{\regulatory@src@thissystem}{#2}}% \else \edef\regulatory@src@thislabel{% \regsrc@get{\regulatory@src@reg}{\regulatory@src@thissystem}{#1}}% \fi } \newcommand\regulatory@src@last{} \newcommand\regulatory@src@part[1]{% \ifx\regulatory@src@parts\@empty\else \protected@xdef\regulatory@src@last{\regulatory@src@last\regulatory@src@sep}% \fi \protected@xdef\regulatory@src@last{\regulatory@src@last#1}% \let\regulatory@src@parts\relax } % \end{macrocode} % % Every level puts what it comes to in a macro of its own, worked out to the last token there and then, % rather than straight into the citation. Worked out, because the designation of a level lives in one macro % that every level writes to in turn, and a part that kept the macro rather than its text would read the % word of whatever level came after it. Its own macro, because % where the parts stand with respect to one another is a decision of the register and not of this module. % Nearly every register names them from the outside in\,---\,the article, then the paragraph, then the % point\,---\,and joins them with its separator. English does the reverse, and measured in the English text % of the same regulation it is not close: \enquote{point (a) of Article 6(1)} twenty-eight times against % nothing at all for either of the two arrangements the other registers use. So the deepest level comes % first, each level is joined to the next with \enquote{of}, and the paragraph is not named but written % into the article between brackets. % % Two arrangements are therefore offered and the \texttt{assemble} key of a register picks one. A register % that says nothing is arranged from the outside in, which is what all four of the others do. % \begin{macrocode} \newcommand\regulatory@src@p@article{} \newcommand\regulatory@src@p@paragraph{} \newcommand\regulatory@src@p@paragraphnum{} \newcommand\regulatory@src@p@point{} \newcommand\regulatory@src@p@subpoint{} \newcommand\regulatory@src@p@source{} \newcommand\regulatory@src@add[1]{% \ifx#1\@empty\else\expandafter\regulatory@src@part\expandafter{#1}\fi } \newcommand\regulatory@src@assemble@forward{% \regulatory@src@add\regulatory@src@p@article \regulatory@src@add\regulatory@src@p@paragraph \regulatory@src@add\regulatory@src@p@point \regulatory@src@add\regulatory@src@p@subpoint \ifx\regulatory@src@parts\@empty\else \protected@edef\regulatory@src@p@source{% \regulatory@src@connective\regulatory@src@p@source}% \fi \regulatory@src@add\regulatory@src@p@source } % \end{macrocode} % % The other way round, with one thing more to do than turning the order about: a paragraph that hangs on an % article is written \texttt{(1)} and takes no word, while one that stands on its own keeps its word, % \enquote{point (a) of paragraph 1}. Both occur in the same regulation, so the register hands over the % shape of the attached one in \texttt{attach} and the level keeps its own wording for the other case. % \begin{macrocode} \newcommand\regulatory@src@assemble@backward{% \ifx\regulatory@src@p@article\@empty\else \ifx\regulatory@src@p@paragraphnum\@empty\else \ifx\regulatory@src@attach\relax\else \protected@edef\@@attachnow{% \noexpand\regulatory@src@attach \noexpand\regulatory@src@p@article {\regulatory@src@p@article}{\regulatory@src@p@paragraphnum}}% \@@attachnow \let\regulatory@src@p@paragraph\@empty \fi \fi \fi \regulatory@src@add\regulatory@src@p@subpoint \regulatory@src@add\regulatory@src@p@point \regulatory@src@add\regulatory@src@p@paragraph \regulatory@src@add\regulatory@src@p@article \regulatory@src@add\regulatory@src@p@source } \NewDocumentCommand \srcref { s O{} m }{% \begingroup \def\regulatory@src@article{}% \def\regulatory@src@paragraph{}% \def\regulatory@src@point{}% \def\regulatory@src@subpoint{}% \IfBooleanTF{#1}{% \ifthenelse{\equal{\regulatory@sourcestyle}{full}}{% \def\regulatory@src@thissystem{short}% }{% \def\regulatory@src@thissystem{full}% }% }{% \edef\regulatory@src@thissystem{\regulatory@sourcestyle}% }% \regulatory@src@cleardate \regulatory@src@setkeys{#2}% \regulatory@src@checkdate{#3}% \edef\regulatory@src@reg{\srcregister{#3}}% \regsrc@set{\regulatory@src@reg}{\regulatory@src@thissystem}{separator}% {\regulatory@src@sep}% \edef\regulatory@src@defdet{% \regsrc@get{\regulatory@src@reg}{\regulatory@src@thissystem}{determiner}}% \regulatory@src@setdet{#3}% \let\regulatory@src@parts\@empty \gdef\regulatory@src@last{}% \let\regulatory@src@p@article\@empty \let\regulatory@src@p@paragraph\@empty \let\regulatory@src@p@paragraphnum\@empty \let\regulatory@src@p@point\@empty \let\regulatory@src@p@subpoint\@empty \regsrc@set{\regulatory@src@reg}{\regulatory@src@thissystem}{and}% {\regulatory@src@and}% \regsrc@set{\regulatory@src@reg}{\regulatory@src@thissystem}{to}% {\regulatory@src@to}% \regsrc@set{\regulatory@src@reg}{\regulatory@src@thissystem}{connective}% {\regulatory@src@connective}% \regsrc@set{\regulatory@src@reg}{\regulatory@src@thissystem}{attach}% {\regulatory@src@attach}% \ifx\regulatory@src@article\@empty\else \regsrc@set{\regulatory@src@reg}{\regulatory@src@thissystem}{articlenum}{\@@fmt}% \def\@@numfmt##1##2{\@@fmt##1{\srcfield{#3}{book}}{##2}}% \def\@@numrest##1##2{\@@fmt##1{}{##2}}% \expandafter\regulatory@src@join\expandafter\regulatory@src@piece \expandafter{\regulatory@src@article}{\@@numfmt}% {\regulatory@src@and}{\regulatory@src@to}{\@@numrest}% \regulatory@src@label{articleone}{articlemany}% \protected@edef\regulatory@src@p@article{% \regulatory@src@thislabel~\regulatory@src@piece}% \fi \ifx\regulatory@src@paragraph\@empty\else \regsrc@set{\regulatory@src@reg}{\regulatory@src@thissystem}{paragraphnum}{\@@fmt}% \expandafter\regulatory@src@join\expandafter\regulatory@src@piece \expandafter{\regulatory@src@paragraph}{\@@fmt}% {\regulatory@src@and}{\regulatory@src@to}{\@@fmt}% \regulatory@src@label{paragraphone}{paragraphmany}% \regsrc@set{\regulatory@src@reg}{\regulatory@src@thissystem}{paragraph}{\@@compose}% \expandafter\@@compose\expandafter\regulatory@src@p@paragraph \expandafter{\regulatory@src@piece}{\regulatory@src@thislabel}% \protected@edef\regulatory@src@p@paragraph{\regulatory@src@p@paragraph}% \regsrc@set{\regulatory@src@reg}{\regulatory@src@thissystem}{attachnum}{\@@afmt}% \ifx\@@afmt\relax \let\regulatory@src@p@paragraphnum\regulatory@src@piece \else \expandafter\regulatory@src@join\expandafter\regulatory@src@p@paragraphnum \expandafter{\regulatory@src@paragraph}{\@@afmt}% {\regulatory@src@and}{\regulatory@src@to}{\@@afmt}% \fi \fi \ifx\regulatory@src@point\@empty\else \regsrc@set{\regulatory@src@reg}{\regulatory@src@thissystem}{pointnum}{\@@fmt}% \expandafter\regulatory@src@join\expandafter\regulatory@src@piece \expandafter{\regulatory@src@point}{\@@fmt}% {\regulatory@src@and}{\regulatory@src@to}{\@@fmt}% \regulatory@src@label{pointone}{pointmany}% \regsrc@set{\regulatory@src@reg}{\regulatory@src@thissystem}{point}{\@@compose}% \expandafter\@@compose\expandafter\regulatory@src@p@point \expandafter{\regulatory@src@piece}{\regulatory@src@thislabel}% \protected@edef\regulatory@src@p@point{\regulatory@src@p@point}% \fi \ifx\regulatory@src@subpoint\@empty\else \regsrc@set{\regulatory@src@reg}{\regulatory@src@thissystem}{subpointnum}{\@@fmt}% \expandafter\regulatory@src@join\expandafter\regulatory@src@piece \expandafter{\regulatory@src@subpoint}{\@@fmt}% {\regulatory@src@and}{\regulatory@src@to}{\@@fmt}% \regulatory@src@label{subpointone}{subpointmany}% \regsrc@set{\regulatory@src@reg}{\regulatory@src@thissystem}{subpoint}{\@@compose}% \expandafter\@@compose\expandafter\regulatory@src@p@subpoint \expandafter{\regulatory@src@piece}{\regulatory@src@thislabel}% \protected@edef\regulatory@src@p@subpoint{\regulatory@src@p@subpoint}% \fi \regsrc@set{\regulatory@src@reg}{\regulatory@src@thissystem}{source}{\@@fmt}% \@@fmt\regulatory@src@p@source{#3}% \regsrc@set{\regulatory@src@reg}{\regulatory@src@thissystem}{assemble}% {\regulatory@src@assembler}% \ifx\regulatory@src@assembler\relax \let\regulatory@src@assembler\regulatory@src@assemble@forward \fi \regulatory@src@assembler \endgroup \regulatory@src@last } \ExplSyntaxOn % \end{macrocode} % \end{macro} % % \begin{macro}{\regulatory@src@messages} % What the module says when it stops. Every one of these names the record it was reading, since a bib file % that is wrong is wrong in one entry and the rest of it is fine. % \begin{macrocode} \msg_new:nnn { regulatory-sources } { unknown-type } { Source~'#2'~is~of~type~'#1',~which~no~one~declared.~Declare~it~with~ \iow_char:N\\newsourcetype,~or~use~one~of:~ \prop_map_function:NN \g__regulatory_src_required_prop \__regulatory_src_type_name:nn } \cs_new:Npn \__regulatory_src_type_name:nn #1#2 { ~#1 } \msg_new:nnn { regulatory-sources } { missing-field } { Source~'#2'~of~type~'#3'~has~no~'#1'.~A~source~of~that~type~cannot~be~ written~out~without~it. } \msg_new:nnn { regulatory-sources } { duplicate-key } { Source~'#1'~was~already~declared.~The~second~one~would~replace~it. } \msg_new:nnn { regulatory-sources } { stray-field } { Field~'#1'~stands~outside~any~entry. } \msg_new:nnn { regulatory-sources } { no-value } { Field~'#1'~was~given~no~value. } \msg_new:nnn { regulatory-sources } { file-not-found } { There~is~no~file~'#1'~to~read~sources~from. } \msg_new:nnn { regulatory-sources } { unclosed } { Source~'#1'~is~still~open~at~the~end~of~'#2'.~A~closing~brace~is~missing. } \msg_new:nnn { regulatory-sources } { unreadable } { Line~#1~of~'#2'~is~none~of~the~four~shapes~this~reader~knows:\\ ~~#3\\ An~entry~opens~with~an~at~sign,~the~type~and~the~key;~a~field~reads~ name~=~{value};~an~entry~closes~with~a~brace~of~its~own.~Each~of~the~three~ stands~on~a~line~of~its~own,~and~a~value~is~in~braces~and~not~in~quotes:~ this~is~a~restricted~syntax~and~not~a~BibTeX~parser. } \ExplSyntaxOff % \end{macrocode} % \end{macro} % \iffalse % % \fi % % \Finale %