texlive[60171] Master: zref-check (5aug21)

commits+karl at tug.org commits+karl at tug.org
Thu Aug 5 22:47:40 CEST 2021


Revision: 60171
          http://tug.org/svn/texlive?view=revision&revision=60171
Author:   karl
Date:     2021-08-05 22:47:40 +0200 (Thu, 05 Aug 2021)
Log Message:
-----------
zref-check (5aug21)

Modified Paths:
--------------
    trunk/Master/tlpkg/bin/tlpkg-ctan-check
    trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc

Added Paths:
-----------
    trunk/Master/texmf-dist/doc/latex/zref-check/
    trunk/Master/texmf-dist/doc/latex/zref-check/CHANGELOG.md
    trunk/Master/texmf-dist/doc/latex/zref-check/DEPENDS.txt
    trunk/Master/texmf-dist/doc/latex/zref-check/README.md
    trunk/Master/texmf-dist/doc/latex/zref-check/zref-check-code.pdf
    trunk/Master/texmf-dist/doc/latex/zref-check/zref-check-code.tex
    trunk/Master/texmf-dist/doc/latex/zref-check/zref-check.pdf
    trunk/Master/texmf-dist/doc/latex/zref-check/zref-check.tex
    trunk/Master/texmf-dist/source/latex/zref-check/
    trunk/Master/texmf-dist/source/latex/zref-check/zref-check.dtx
    trunk/Master/texmf-dist/source/latex/zref-check/zref-check.ins
    trunk/Master/texmf-dist/tex/latex/zref-check/
    trunk/Master/texmf-dist/tex/latex/zref-check/zref-check.sty
    trunk/Master/tlpkg/tlpsrc/zref-check.tlpsrc

Added: trunk/Master/texmf-dist/doc/latex/zref-check/CHANGELOG.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/zref-check/CHANGELOG.md	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/zref-check/CHANGELOG.md	2021-08-05 20:47:40 UTC (rev 60171)
@@ -0,0 +1,8 @@
+# Changelog
+
+## [Unreleased](https://github.com/gusbrs/zref-check/compare/v0.1.0...HEAD)
+
+## [v0.1.0](https://github.com/gusbrs/zref-check/releases/tag/v0.1.0) (2021-08-04)
+
+### Added
+- Initial release.


Property changes on: trunk/Master/texmf-dist/doc/latex/zref-check/CHANGELOG.md
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/zref-check/DEPENDS.txt
===================================================================
--- trunk/Master/texmf-dist/doc/latex/zref-check/DEPENDS.txt	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/zref-check/DEPENDS.txt	2021-08-05 20:47:40 UTC (rev 60171)
@@ -0,0 +1,3 @@
+hard zref
+hard oberdiek
+soft hyperref


Property changes on: trunk/Master/texmf-dist/doc/latex/zref-check/DEPENDS.txt
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/zref-check/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/zref-check/README.md	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/zref-check/README.md	2021-08-05 20:47:40 UTC (rev 60171)
@@ -0,0 +1,17 @@
+# zref-check
+
+**Flexible LaTeX cross-references with contextual checks based on zref**
+
+`zref-check` provides an user interface for making LaTeX cross-references
+flexibly, while allowing to have them checked for consistency with the
+document structure as typeset.  Statements such as “above”, “on the next
+page”, “previously”, “as will be discussed”, “on the previous chapter” and so
+on can be given to `\zcheck` in free-form, and a set of “checks” can be
+specified to be run against a given `label`, which will result in a warning at
+compilation time if any of these checks fail.  `\zctarget` and the `zcregion`
+environment are also defined as a means to easily set label targets to
+arbitrary places in the text which can be referred to by `\zcheck`.
+
+The released version of this package is available from CTAN.
+
+For more details, check the Documentation.


Property changes on: trunk/Master/texmf-dist/doc/latex/zref-check/README.md
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/zref-check/zref-check-code.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/latex/zref-check/zref-check-code.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/latex/zref-check/zref-check-code.pdf	2021-08-05 20:47:05 UTC (rev 60170)
+++ trunk/Master/texmf-dist/doc/latex/zref-check/zref-check-code.pdf	2021-08-05 20:47:40 UTC (rev 60171)

Property changes on: trunk/Master/texmf-dist/doc/latex/zref-check/zref-check-code.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/zref-check/zref-check-code.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/zref-check/zref-check-code.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/zref-check/zref-check-code.tex	2021-08-05 20:47:40 UTC (rev 60171)
@@ -0,0 +1,87 @@
+% \iffalse meta-comment
+%
+% File: zref-check-code.tex
+%
+% This file is part of the LaTeX package "zref-check".
+%
+% Copyright (C) 2021  Gustavo Barros
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version.  The latest version
+% of this license is in the file:
+%
+%    https://www.latex-project.org/lppl.txt
+%
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+%
+% This work is "maintained" (as per LPPL maintenance status) by
+% Gustavo Barros.
+%
+% This work consists of the files zref-check.dtx,
+%                                 zref-check.ins,
+%                                 zref-check.tex,
+%                                 zref-check-code.tex,
+%           and the derived files zref-check.sty and
+%                                 zref-check.pdf,
+%                                 zref-check-code.pdf.
+%
+% The released version of this package is available from CTAN.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the package can be found at
+%
+%    https://github.com/gusbrs/zref-check
+%
+% for those people who are interested.
+%
+% -----------------------------------------------------------------------
+%
+% \fi
+
+\documentclass{l3doc}
+
+% Have \GetFileInfo pick up date and version data
+\usepackage{zref-check}
+
+\NewDocumentCommand\opt{m}{\texttt{#1}}
+
+% Have the Index at 'section' level rather than 'part'.  Otherwise it is just
+% the same definition from 'l3doc.cls'.
+\IndexPrologue{%
+  \section*{Index}
+  \markboth{Index}{Index}
+  \addcontentsline{toc}{section}{Index}
+  The italic numbers denote the pages where the corresponding entry is
+  described, numbers underlined point to the definition, all others indicate
+  the places where it is used.%
+}
+
+\begin{document}
+
+\GetFileInfo{zref-check.sty}
+
+\title{%
+  The \pkg{zref-check} package implementation%
+  \thanks{This file describes \fileversion, last revised \filedate.}%
+}
+
+\author{%
+  Gustavo Barros%
+  \thanks{\url{https://github.com/gusbrs/zref-check}}%
+}
+
+\date{\filedate}
+
+\maketitle
+
+\tableofcontents
+
+\DisableDocumentation
+
+\DocInput{zref-check.dtx}
+
+\end{document}


Property changes on: trunk/Master/texmf-dist/doc/latex/zref-check/zref-check-code.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/zref-check/zref-check.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/latex/zref-check/zref-check.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/latex/zref-check/zref-check.pdf	2021-08-05 20:47:05 UTC (rev 60170)
+++ trunk/Master/texmf-dist/doc/latex/zref-check/zref-check.pdf	2021-08-05 20:47:40 UTC (rev 60171)

Property changes on: trunk/Master/texmf-dist/doc/latex/zref-check/zref-check.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/zref-check/zref-check.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/zref-check/zref-check.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/zref-check/zref-check.tex	2021-08-05 20:47:40 UTC (rev 60171)
@@ -0,0 +1,89 @@
+% \iffalse meta-comment
+%
+% File: zref-check.tex
+%
+% This file is part of the LaTeX package "zref-check".
+%
+% Copyright (C) 2021  Gustavo Barros
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version.  The latest version
+% of this license is in the file:
+%
+%    https://www.latex-project.org/lppl.txt
+%
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+%
+% This work is "maintained" (as per LPPL maintenance status) by
+% Gustavo Barros.
+%
+% This work consists of the files zref-check.dtx,
+%                                 zref-check.ins,
+%                                 zref-check.tex,
+%                                 zref-check-code.tex,
+%           and the derived files zref-check.sty and
+%                                 zref-check.pdf,
+%                                 zref-check-code.pdf.
+%
+% The released version of this package is available from CTAN.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the package can be found at
+%
+%    https://github.com/gusbrs/zref-check
+%
+% for those people who are interested.
+%
+% -----------------------------------------------------------------------
+%
+% \fi
+
+\documentclass{l3doc}
+
+% Have \GetFileInfo pick up date and version data
+\usepackage{zref-check}
+
+\NewDocumentCommand\opt{m}{\texttt{#1}}
+
+\begin{document}
+
+\GetFileInfo{zref-check.sty}
+
+\title{%
+  The \pkg{zref-check} package%
+  \thanks{This file describes \fileversion, last revised \filedate.}%
+}
+
+\author{%
+  Gustavo Barros%
+  \thanks{\url{https://github.com/gusbrs/zref-check}}%
+}
+
+\date{\filedate}
+
+\maketitle
+
+\begin{abstract}
+  \pkg{zref-check} provides an user interface for making \LaTeX{}
+  cross-references flexibly, while allowing to have them checked for
+  consistency with the document structure as typeset.  Statements such as
+  ``above'', ``on the next page'', ``previously'', ``as will be discussed'',
+  ``on the previous chapter'' and so on can be given to \cs{zcheck} in
+  free-form, and a set of ``checks'' can be specified to be run against a
+  given \texttt{label}, which will result in a warning at compilation time if
+  any of these checks fail.  \cs{zctarget} and the \texttt{zcregion}
+  environment are also defined as a means to easily set label targets to
+  arbitrary places in the text which can be referred to by \cs{zcheck}.
+\end{abstract}
+
+\tableofcontents
+
+\DisableImplementation
+
+\DocInput{zref-check.dtx}
+
+\end{document}


Property changes on: trunk/Master/texmf-dist/doc/latex/zref-check/zref-check.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/zref-check/zref-check.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/zref-check/zref-check.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/zref-check/zref-check.dtx	2021-08-05 20:47:40 UTC (rev 60171)
@@ -0,0 +1,2218 @@
+% \iffalse meta-comment
+%
+% File: zref-check.dtx
+%
+% This file is part of the LaTeX package "zref-check".
+%
+% Copyright (C) 2021  Gustavo Barros
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version.  The latest version
+% of this license is in the file:
+%
+%    https://www.latex-project.org/lppl.txt
+%
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+%
+% This work is "maintained" (as per LPPL maintenance status) by
+% Gustavo Barros.
+%
+% This work consists of the files zref-check.dtx,
+%                                 zref-check.ins,
+%                                 zref-check.tex,
+%                                 zref-check-code.tex,
+%           and the derived files zref-check.sty and
+%                                 zref-check.pdf,
+%                                 zref-check-code.pdf.
+%
+% The released version of this package is available from CTAN.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the package can be found at
+%
+%    https://github.com/gusbrs/zref-check
+%
+% for those people who are interested.
+%
+% -----------------------------------------------------------------------
+%
+% \fi
+%
+% \iffalse
+%<*driver>
+\documentclass{l3doc}
+% Have \GetFileInfo pick up date and version data
+\usepackage{zref-check}
+\NewDocumentCommand\opt{m}{\texttt{#1}}
+\MakeShortVerb{\|}
+\begin{document}
+  \DocInput{zref-check.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+%
+% \begin{documentation}
+%
+% \section{Introduction}
+%
+% The \pkg{zref-check} package provides an user interface for making \LaTeX{}
+% cross-references exploiting document contextual information to enrich the
+% way the reference can be rendered, but at the same time ensuring the means
+% that these cross-references can be done consistently with the document
+% structure.
+%
+% The usual \LaTeX{} cross-reference is done by referring to a \texttt{label},
+% associated with one or another document structural element, and this
+% reference will typeset for you some content based on the information which
+% is stored in that label.  \cs{zcheck}, the main user command of
+% \pkg{zref-check}, has a somewhat different concept.  Instead of trying to
+% provide the text to be typeset based on the contextual information,
+% \cs{zcheck} lets the user supply an arbitrary text and specify one or more
+% checks to be done on the label(s) being referred to.  If any of the checks
+% fail, a warning is issued upon compilation, so that the user can go back to
+% that cross-reference and correct it as needed, without having to rely on
+% burdensome and error prone manual proof-reading.
+%
+% This grants a much increased flexibility for the cross-reference text, which
+% means in practice that the writing style, the variety of expressions you may
+% use for similar situations, does not need to be sacrificed for the
+% convenience.  \cs{zcheck}'s cross-references do not need to ``feel''
+% automated to be consistently checked.  Localization is also not an issue,
+% since the cross-reference text is provided directly by the user.  Separating
+% ``typesetting'' from ``checking'' also means there is a lot of document
+% context we can leverage for this purpose (see Section~\ref{sec:checks}).
+%
+% A standard \LaTeX{} cross-reference is made to refer to specific numbered
+% document elements -- chapters, sections, figures, tables, equations, etc.
+% The cross-reference will normally produce that number (which is the
+% element's ``id'') and, eventually, its ``type'' (the counter).  We may also
+% refer to the page that element occurs and even its ``title'' (in which case,
+% atypically, we may even get to refer to an unnumbered section, provided we
+% also implicitly supply by some means the ``id'').
+%
+% For references to these usual specific document elements, \pkg{zref-check}
+% caters for a particular kind of cross-reference which is common:
+% \emph{relational} statements based on them.  \cs{zcheck} can typeset and
+% meaningfully check cross-references such as ``above'', ``on the next page'',
+% ``on the facing page'', ``on the previous section'', ``later on this
+% chapter'' and so on.  After all, if your reference is being made on page 2
+% and refers to something on the same page, ``on this page'' reads much better
+% than ``on page~2''.  If you are writing chapter~4, ``on the previous
+% chapter'' sounds nicer than ``on chapter~3''.
+%
+% However, there is yet another kind of ``looser'' cross-reference we
+% routinely do in our documents.  Expressions such as ``previously'', ``as
+% mentioned before'', ``as will be discussed'', and so on, are a powerful
+% discursive instrument, which enriches the text, by offering hints to the
+% arguments' threads, without necessarily pressing them too hard onto the
+% reader.  So, we might not want to say ``on footnote 57, pag.~34'', but
+% prefer ``previously'', not ``on Section 3.4'', but rather ``below'', or
+% ``later on''.  Besides, we also may refer to certain passages in the text in
+% this way, rather than to numbered document elements.  And this kind of
+% reference is not only hard to check and find, but also to fix.  After all,
+% if you are making one such reference, you are taking that statement as a
+% premisse at the current point in the text.  So, if that reference is
+% missing, or relocated, you may need to bring in the support to the premisse
+% for your argument to close, rather than just ``adjust the reference text''.
+% \pkg{zref-check} also provides support for this kind of cross-reference,
+% allowing for them to be consistently verified.
+%
+%
+%
+% \section{Loading the package}
+% \label{sec:loading-package}
+%
+% As usual:
+%
+% \begin{syntax}
+%   \cs{usepackage}\oarg{options}|{zref-check}|
+% \end{syntax}
+%
+%
+%
+% \section{Dependencies}
+%
+% \pkg{zref} is required, of course, but in particular, its modules
+% \pkg{zref-user} and \pkg{zref-abspage} are loaded by default.  \pkg{ifdraft}
+% (from the \pkg{oberdiek} bundle) is also loaded by default.  A \LaTeX{}
+% kernel later than 2021-06-01 is required, since we rely on the new hook
+% system from \pkg{ltcmdhooks} for the sectioning checks.  If \pkg{hyperref}
+% is loaded and option \pkg{hyperref} is given, \pkg{zref-check} makes use of
+% it, but it does not load the package for you.
+%
+%
+% \section{User interface}
+% \label{sec:user-interface}
+%
+% \begin{function}{\zcheck}
+%   \begin{syntax}
+%     \cs{zcheck}\oarg{options}\marg{labels}\oarg{checks}\marg{text}
+%   \end{syntax}
+%   Typesets \marg{text}, as given, while performing the comma separated list
+%   of \oarg{checks} on each of the comma separated list of \marg{labels}.
+%   When \pkg{hyperref} support is enabled, \marg{text} will be made a
+%   hyperlink to \emph{the first} label in \marg{labels}.  The starred version
+%   of the command does the same as the plain one, just does not form a link.
+%   The \oarg{options} are (mostly) the same as those of the package, and can
+%   be given to local effect.
+% \end{function}
+%
+% \begin{function}{\zctarget}
+%   \begin{syntax}
+%     \cs{zctarget}\marg{label}\marg{text}
+%   \end{syntax}
+%   Typesets \marg{text}, as given, and places a pair of \texttt{zlabel}s, one
+%   at the start of \marg{text}, using \marg{label} as label name, another one
+%   (internal) at the end of \marg{text}.
+% \end{function}
+%
+%
+% \begin{function}{zcregion}
+%   \begin{syntax}
+%     |\begin{zcregion}|\marg{label}
+%       |  ...|
+%     |\end{zcregion}|
+%   \end{syntax}
+%   An environment that does the same as \cs{zctarget}, for cases of longer
+%   stretches of text.
+% \end{function}
+%
+%
+% \begin{function}{\zrefchecksetup}
+%   \begin{syntax}
+%     \cs{zrefchecksetup}\marg{options}
+%   \end{syntax}
+%   Sets \pkg{zref-check}'s options (see Section~\ref{sec:options}).
+% \end{function}
+%
+%
+% \section{Checks}
+% \label{sec:checks}
+%
+% \pkg{zref-check} provides several ``checks'' to be used with \cs{zcheck}.
+% The checks may be combined in a \cs{zcheck} call, e.g.\ \opt{[close,
+% after]}, or \opt{[thischap, before]}.  In this case, each check in
+% \oarg{checks} is performed against each of the \marg{labels}.  This is done
+% independently for each check, which means, in practice, that the checks bear
+% a logical \texttt{AND} relation to the others.  Whether the combination is
+% meaningful, is up to the user.  As is the correspondence between the
+% \oarg{checks} and the \marg{text>} in \cs{zcheck}.
+%
+% The use of checks which perform ``within the page'' comparisons -- namely
+% \opt{above} and \opt{below} and, through them, \opt{before} and \opt{after}
+% -- comes with some caveats you should be acquainted with.
+% Section~\ref{sec:within-page-checks} discusses their limitations and expands
+% on the expected workflow for their use to ensure reliable results.
+%
+% Note that the naming convention of the checks adopts the perspective of
+% \cs{zcheck}.  That is, the name of the check describes the position of the
+% label being referred to, relative to the \cs{zcheck} call being made.  For
+% example, the \opt{before} check should issue no message if
+% \cs{ztarget}|{mylabel}{...}| occurs before
+% \cs{zcheck}|{mylabel}[before]{...}|.
+%
+% The available checks are the following:
+%
+% \begin{description}[leftmargin=0pt, itemindent=0pt, align=right,
+%   labelsep=1em, font=\MacroFont]
+%
+% \item[thispage] \meta{label} occurs on the same page as \cs{zcheck}.
+%
+% \item[prevpage] \meta{label} occurs on the previous page relative to
+%   \cs{zcheck}.
+%
+% \item[nextpage] \meta{label} occurs on the next page relative to
+%   \cs{zcheck}.
+%
+% \item[facing] On a \texttt{twoside} document, both \meta{label} and
+%   \cs{zcheck} fall onto a double spread, each on one of the two facing
+%   pages.
+%
+% \item[above] \meta{label} and \cs{zcheck} are both on the same page, and
+%   \meta{label} occurs ``above'' \cs{zcheck}.
+%
+% \item[below] \meta{label} and \cs{zcheck} are both on the same page, and
+%   \meta{label} occurs ``below'' \cs{zcheck}.
+%
+% \item[pagesbefore] \meta{label} occurs on any page before the one of
+%   \cs{zcheck}.
+%
+% \item[ppbefore] Convenience alias for \opt{pagesbefore}.
+%
+% \item[pagesafter] \meta{label} occurs on any page after the one of
+%   \cs{zcheck}.
+%
+% \item[ppafter] Convenience alias for \opt{pagesafter}.
+%
+% \item[before] Either \opt{above} or \opt{pagesbefore}.
+%
+% \item[after]  Either \opt{below} or \opt{pagesafter}.
+%
+% \item[thischap] \meta{label} occurs on the same chapter as \cs{zcheck}.
+%
+% \item[prevchap] \meta{label} occurs on the previous chapter relative to the
+%   one of \cs{zcheck}.
+%
+% \item[nextchap] \meta{label} occurs on the next chapter relative to the one
+%   of \cs{zcheck}.
+%
+% \item[chapsbefore] \meta{label} occurs on any chapter before the one of
+%   \cs{zcheck}.
+%
+% \item[chapsafter] \meta{label} occurs on any chapter after the one of
+%   \cs{zcheck}.
+%
+% \item[thissec] \meta{label} occurs on the same section as \cs{zcheck}.
+%
+% \item[prevsec] \meta{label} occurs on the previous section (of the same
+%   chapter) relative to the one of \cs{zcheck}.
+%
+% \item[nextsec] \meta{label} occurs on the next section (of the same chapter)
+%   relative to the one of \cs{zcheck}.
+%
+% \item[secsbefore] \meta{label} occurs on any section (of the same chapter)
+%   before the one of \cs{zcheck}.
+%
+% \item[secsafter] \meta{label} occurs on any section (of the same chapter)
+%   after the one of \cs{zcheck}.
+%
+% \item[close] \meta{label} occurs within a page range from \opt{closerange}
+%   pages before the one of \cs{zcheck} to \opt{closerange} pages after it
+%   (about the \opt{closerange} option, see Section~\ref{sec:options}).
+%
+% \item[far] Not \opt{close}.
+%
+% \end{description}
+%
+%
+%
+% \section{Options}
+% \label{sec:options}
+%
+% Options are a standard \texttt{key=value} comma separated list, and can be
+% set globally either as \cs{usepackage}\oarg{options} at load-time (see
+% Section~\ref{sec:loading-package}), or by means of \cs{zrefchecksetup} (see
+% Section~\ref{sec:user-interface}) in the preamble.  Most options can also be
+% used with local effects, through the optional argument \oarg{options} of
+% \cs{zcheck}.
+%
+% \DescribeOption{hyperref}
+% Controls the use of \pkg{hyperref} by \pkg{zref-check} and takes values
+% \opt{auto}, \opt{true}, \opt{false}.  The default value, \opt{auto}, makes
+% \pkg{zref-check} use \pkg{hyperref} if it is loaded, meaning \cs{zcheck} can
+% be hyperlinked to the \emph{first label} in \marg{labels}.  \opt{true} does
+% the same thing, but warns if \pkg{hyperref} is not loaded (\pkg{hyperref} is
+% never loaded for you).  In either of these cases, if \pkg{hyperref} is
+% loaded, module \pkg{zref-hyperref} is also loaded by \pkg{zref-check}.
+% \opt{false} means not to use \pkg{hyperref} regardless of its availability.
+% This is a preamble only option, but \cs{zcheck} provides granular control of
+% hyperlinking by means of its starred version.
+%
+%
+% \DescribeOption{msglevel}
+% Sets the level of messages issued by \cs{zcheck} failed checks and takes
+% values \opt{warn}, \opt{info}, \opt{none}, \opt{obeydraft}, \opt{obeyfinal}.
+% The default value, \opt{warn}, issues messages both to the terminal and to
+% the log file, \opt{info} issues messages to the log file only, \opt{none}
+% suppresses all messages.  \opt{obeydraft} corresponds to \opt{info} if
+% option \opt{draft} is passed to \cs{documentclass}, and to \opt{warn}
+% otherwise.  \opt{obeyfinal} corresponds to \opt{warn} if option \opt{final}
+% is (explicitly) passed to \cs{documentclass} and \opt{info} otherwise.
+% \opt{ignore} is provided as convenience alias for \opt{msglevel=none} for
+% local use only.  This option only affects the messages issued by the checks
+% in \cs{zcheck}, not other messages or warnings of the package.  In
+% particular, it does not affect warnings issued for undefined labels, which
+% just use \cs{zref at refused} and thus are the same as standard \LaTeX{} ones
+% for this purpose.
+%
+%
+% \DescribeOption{onpage}
+% Allows to control the messaging style for ``within page checks'', and takes
+% values \opt{labelseq}, \opt{msg}, \opt{obeydraft}, \opt{obeyfinal}.  The
+% default, \opt{labelseq}, uses the labels' shipout sequence, as retrieved
+% from the \file{.aux} file, to infer relative position within the page.
+% \opt{msg} also uses the same method for checking relative position, but
+% issues a (different) message \emph{even if the check passes}, to provide a
+% simple workflow for robust checking of ``false negatives'', considering the
+% label sequence is not fool proof (for details and workflow recommendations,
+% see Section~\ref{sec:within-page-checks}).  \opt{msg} also issues its
+% messages at the same level defined in \opt{msglevel}.  \opt{obeydraft}
+% corresponds to \opt{labelseq} if option \opt{draft} is passed to
+% \cs{documentclass} and to \opt{msg} otherwise.  \opt{obeyfinal} corresponds
+% to \opt{msg} if option \opt{final} is (explicitly) passed to
+% \cs{documentclass}, and to \opt{labelseq} otherwise.
+%
+%
+% \DescribeOption{closerange}
+% Defines the width of the range of pages, relative to the reference, that are
+% considered ``close'' by the \opt{close} check.  Takes a positive integer as
+% value, with default 5.
+%
+%
+% \DescribeOption{labelcmd}
+% Defines the command used to set the user labels in \cs{zctarget} and
+% \texttt{zcregion}.  Takes a control sequence \emph{name} as value, and the
+% default sets labels with the minimal required properties, those of the
+% \texttt{zrefcheck} property list.  This is a preamble only option.  The
+% specified control sequence must receive one mandatory argument (the
+% \marg{label}) and must generate a \texttt{zref label} with at least the
+% properties in the \texttt{zrefcheck} property list.  The intended use case
+% is that of the user creating a convenience macro which calls both \cs{label}
+% and \cs{zlabel}, as suggested in Section~\ref{sec:labels}, so that the same
+% labels are accessible either from the standard reference system or from
+% \pkg{zref}.  For example:
+%
+% \begin{verbatim}
+%     \NewDocumentCommand\mybothlabels{m}{\label{#1}\zlabel{#1}}
+%     \zrefchecksetup{labelcmd=mybothlabels}
+% \end{verbatim}
+%
+% Note that the value of the underlying counter used for labels in
+% \cs{zctarget} and \texttt{zcregion} -- what you'd get with a plain \cs{ref}
+% here -- is not really meaningful.  But you get to use
+% \cs{pageref}\marg{label}, or \pkg{hyperref}'s
+% \cs{hyperref}\oarg{label}\marg{text} on the labels used in \cs{zctarget} and
+% \texttt{zcregion} with this procedure.
+%
+%
+% \section{Labels}
+% \label{sec:labels}
+%
+% \pkg{zref-check} depends on \pkg{zref}, as the name entails, which means it
+% is able to work with \pkg{zref} labels, in general created by \cs{zlabel},
+% but also with \cs{zctarget} and the \texttt{zcregion} environment provided
+% by this package.  This has some advantages, particularly the data
+% flexibility of \pkg{zref}, and the absence of the ubiquitous ``load-order''
+% and compatibility problems which are well known to afflict \LaTeX{} packages
+% of this area of functionality.  On the other hand, the reliance on
+% \pkg{zref} labels may be seen as an inconvenience, since users of the
+% standard cross-reference infrastructure may need to add extra labels for
+% this.  That's true.  But \pkg{zref-check} is not meant to replace the
+% existing functionality of the kernel or of the traditional packages in this
+% area (to my knowledge, it only intersects directly with \pkg{varioref} and,
+% even so, it is quite different in scope).  Indeed, it is easy to see the use
+% in tandem with standard references, for example:
+%
+% \begin{verbatim}
+%     ... Figure~\ref{fig:figure-1}, \zcheck*{fig:figure-1}[nextpage]{on
+%     the next page}.
+% \end{verbatim}
+%
+% Besides, \pkg{zref} does not share the label name-space with the standard
+% labels, so that you can call both \cs{label} and \cs{zlabel} with the same
+% label name (manually, or through a convenience macro), to ease the label set
+% administration.  The example above presumes that was the case.
+%
+% All user commands of \pkg{zref-check} have their \marg{label} arguments
+% protected for \pkg{babel} active characters using \pkg{zref}'s
+% \cs{zref at wrapper@babel}, so that we should have equivalent support in that
+% regard, as \pkg{zref} itself does.  However, \pkg{zref-check} sets labels
+% which either start with \texttt{zrefcheck@} or end with \texttt{@zrefcheck},
+% for internal use.  Label names with either of those are considered reserved
+% by the package.
+%
+%
+% \section{Limitations}
+%
+% There are three qualitatively different kinds of checks being used by
+% \cs{zcheck}, according to the source and reliability of the information they
+% mobilize: page number checks, within page checks, and sectioning checks.
+%
+%
+% \subsection{Page number checks}
+%
+% Page number checks -- \opt{thispage}, \opt{prevpage}, \opt{nextpage},
+% \opt{pagesbefore}, \opt{pagesafter}, \opt{facing} -- use the
+% \texttt{abspage} property provided by the \pkg{zref-abspage} module.  This
+% is a solid piece of information, on which we can rely upon.  However,
+% despite that, page number checks may still become ill-defined, if the
+% \marg{text} argument in \cs{zcheck}, when typeset, crosses page boundaries,
+% starting in one page, and finishing in another.  The same can happen with
+% the text in \cs{zctarget} and the \texttt{zcregion} environment.
+%
+% This is why the user commands of this package set always a pair or labels
+% around \meta{text}.  So, when checking \cs{zcheck} against a regular
+% \texttt{zlabel} both the start and the end of the \meta{text} are checked
+% against the label, and the check fails if either of them fails.  When
+% checking \cs{zcheck} against a \cs{zctarget} or a \texttt{zcregion}, both
+% beginnings and ends are checked against each other two by two, and if any of
+% them fails, the check fails.  In other words, if a page number checks
+% passes, we know that the entire \meta{text} arguments pass it.
+%
+% This is a corner case (albeit relevant) which must be taken care of, and it
+% is possible to do so robustly.  Hence, we can expect reliable results in
+% these tests.
+%
+%
+% \subsection{Within page checks}
+% \label{sec:within-page-checks}
+%
+% When both label and reference fall on the same page things become much
+% trickier.  This is basically the case of the checks \opt{above} and
+% \opt{below} (and, through them, \opt{before} and \opt{after}).  There is no
+% equally reliable information (that I know of) as we have for the page number
+% checks for this, especially when floats come into play.  Which, of course,
+% is the interesting case to handle.
+%
+% To infer relative position of label and reference on the same page,
+% \pkg{zref-check} uses the labels' shipout sequence, which is retrieved at
+% load-time from the order in which the labels occur in the \file{.aux} file.
+% Indeed, \pkg{zref} writes labels to the \file{.aux} file at shipout (and,
+% hence, in shipout order), and needs to do so, because a number of its
+% properties are only available at that point.
+%
+% However, even if this method will buy us a correct check for a regular float
+% on a regular page (which, to be fair, is a good result), it is not difficult
+% do conceive situations in which this sequence may not be meaningful, or even
+% correct, for the case.  A number of cases which may do so are: two column
+% documents, text wrapping, scaling, overlays, etc.  (I don't know if those
+% make the method fail, I just don't know if they don't).  Therefore, the
+% \texttt{labelseq} should be taken as a \emph{proxy} and not fully reliable,
+% meaning that the user should be watchful of its results.
+%
+% For this reason, \pkg{zref-check} provides an easy way to do so, by allowing
+% specific control of the messaging style of the checks which do within page
+% comparisons though the option \opt{onpage}.  The concern is not really with
+% false positives (getting a warning when it was not due), but with false
+% negatives (not getting a warning when it was due).  Hence, setting
+% \opt{onpage} to \opt{msg} at a final typesetting stage (or just set it to
+% \opt{obeydraft} or \opt{obeyfinal} if that's part of your workflow) provides
+% a way to easily identify all cases of such checks (failing or passing), and
+% double-check them.  In case the test is passing though, the message is
+% different from that of a failing check, to quickly convey why you are
+% getting the message.  This option can also be set at the local level, if the
+% page in question is known to be problematic, or just atypical.
+%
+%
+% \subsection{Sectioning checks}
+%
+% The information used by sectioning checks is provided by means of dedicated
+% counters for chapters and sections, similarly as standard counters for them,
+% but which are stepped and reset regardless of whether these sectioning
+% commands are numbered or not (that is, starred or not).  And this for two
+% reasons.  First, we don't need the absolute counter value to be able to make
+% the kind of relative statement we want to do here.  Second, this allows us
+% to have these checks work for numbered and unnumbered sectioning commands
+% without having to worry about how those are used within the document.
+%
+% The caveat is that the package does this by hooking into \cs{chapter} and
+% \cs{section}, which poses two restrictions for the proper working of these
+% checks.  First, we are using the new hook system for this, as provided by
+% \pkg{ltcmdhooks}, which means a \LaTeX{} kernel later than 2021-06-01 is
+% required.  Second, since we are hooking into \cs{chapter} and \cs{section},
+% these checks presume these commands are being used by the document class for
+% this purpose (either directly, or internally as, for example, KOMA-Script's
+% \cs{addchap} and \cs{addsec} do).  If that's not the case, additional setup
+% may be needed for these checks to work as expected.
+%
+%
+% \end{documentation}
+%
+%
+% \begin{implementation}
+%
+% \section{Initial setup}
+%
+% Start the \pkg{DocStrip} guards.
+%    \begin{macrocode}
+%<*package>
+%    \end{macrocode}
+%
+% Identify the internal prefix (\LaTeX3 \pkg{DocStrip} convention).
+%    \begin{macrocode}
+%<@@=zrefcheck>
+%    \end{macrocode}
+%
+%
+% For the \texttt{chapter} and \texttt{section} checks, \pkg{zref-check} uses
+% the new hook system in \pkg{ltcmdhooks}, which was released with the
+% 2021/06/01 \LaTeX{} kernel.
+%    \begin{macrocode}
+\providecommand\IfFormatAtLeastTF{\@ifl at t@r\fmtversion}
+\IfFormatAtLeastTF{2021-06-01}
+  {}
+  {%
+    \PackageError{zref-check}{LaTeX kernel too old}
+      {%
+        'zref-check' requires a LaTeX kernel newer than 2021-06-01.%
+        \MessageBreak Loading will abort!%
+      }%
+    \endinput
+  }%
+%    \end{macrocode}
+%
+% Identify the package.
+%    \begin{macrocode}
+\ProvidesExplPackage {zref-check} {2021-08-04} {0.1.0}
+  {Flexible cross-references with contextual checks based on zref}
+%    \end{macrocode}
+%
+% \section{Dependencies}
+%
+%    \begin{macrocode}
+\RequirePackage { zref-user }
+\RequirePackage { zref-abspage }
+\RequirePackage { ifdraft }
+%    \end{macrocode}
+%
+%
+% \section{\pkg{zref} setup}
+%
+% \begin{variable}{\g_@@_abschap_int, \g_@@_abssec_int}
+%   Provide absolute counters for section and chapter, and respective
+%   \pkg{zref} properties, so that we can make checks about relation of
+%   chapters/sections regardless of internal counters, since we don't get
+%   those for the unnumbered (starred) ones.  About the proper place to make
+%   the hooks for this purpose, see
+%   \url{https://tex.stackexchange.com/q/605533/105447} (thanks Ulrike
+%   Fischer).
+%    \begin{macrocode}
+\int_new:N \g_@@_abschap_int
+\int_new:N \g_@@_abssec_int
+%    \end{macrocode}
+% \end{variable}
+%
+%
+% If the documentclass does not define \cs{chapter} the only thing that
+% happens is that the chapter counter is never incremented, and the section
+% one never reset.
+%    \begin{macrocode}
+\AddToHook { cmd / chapter / before }
+  {
+    \int_gincr:N \g_@@_abschap_int
+    \int_zero:N \g_@@_abssec_int
+  }
+\zref at newprop { abschap } [0] { \int_use:N \g_@@_abschap_int }
+\zref at addprop \ZREF at mainlist { abschap }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\AddToHook { cmd / section / before }
+  { \int_gincr:N \g_@@_abssec_int }
+\zref at newprop { abssec } [0] { \int_use:N \g_@@_abssec_int }
+\zref at addprop \ZREF at mainlist { abssec }
+%    \end{macrocode}
+%
+%
+% This is the list of properties to be used by \pkg{zref-check}, that is, the
+% list of properties the references and targets store.  This is the minimum
+% set required, more properties may be added according to options.
+%    \begin{macrocode}
+\zref at newlist { zrefcheck }
+\zref at addprops { zrefcheck }
+  {
+    abspage ,
+    abschap ,
+    abssec ,
+    page
+  }
+%    \end{macrocode}
+%
+%
+% \section{Plumbing}
+%
+% \subsection{Messages}
+%
+% \begin{macro}{\@@_message:nnnn, \@@_message:nnnx}
+%    \begin{macrocode}
+\cs_new:Npn \@@_message:nnnn #1#2#3#4
+  {
+    \use:c { msg_ \l_@@_msglevel_tl :nnnnn }
+      { zref-check } {#1} {#2} {#3} {#4}
+  }
+\cs_generate_variant:Nn \@@_message:nnnn { nnnx }
+%    \end{macrocode}
+% \end{macro}
+%
+%    \begin{macrocode}
+\msg_new:nnn { zref-check } { check-failed }
+  {
+    Failed~check~'#1'~for~label~'#2' \iow_newline:
+    on~page~#3~on~input~line~\msg_line_number:.
+  }
+\msg_new:nnn { zref-check } { double-check }
+  {
+    Double-check~'#1'~for~label~'#2' \iow_newline:
+    on~page~#3~on~input~line~\msg_line_number:.
+  }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\msg_new:nnn { zref-check } { check-missing }
+  { Check~'#1'~not~defined~on~input~line~\msg_line_number:. }
+\msg_new:nnn { zref-check } { property-undefined }
+  { Property~'#1'~not~defined~on~input~line~\msg_line_number:. }
+\msg_new:nnn { zref-check } { property-not-in-label }
+  { Label~'#1'~has~no~property~'#2'~on~input~line~\msg_line_number:. }
+\msg_new:nnn { zref-check } { property-not-integer }
+  {
+    Property~'#1'~for~label~'#2'~not~an~integer \iow_newline:
+    on~input~line~\msg_line_number:.
+  }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\msg_new:nnn { zref-check } { hyperref-preamble-only }
+  {
+    Option~'hyperref'~only~available~in~the~preamble. \iow_newline:
+    Use~the~starred~version~of~'\noexpand\zcheck'~instead.
+  }
+\msg_new:nnn { zref-check } { missing-hyperref }
+  { Missing~'hyperref'~package. \iow_newline: Setting~'hyperref=false'. }
+\msg_new:nnn { zref-check } { ignore-document-only }
+  {
+    Option~'ignore'~only~available~in~the~document. \iow_newline:
+    Use~option~'msglevel'~instead.
+  }
+\msg_new:nnn { zref-check } { option-preamble-only }
+  {
+    Option~'#1'~only~available~in~the~preamble \iow_newline:
+    on~input~line~\msg_line_number:.
+  }
+\msg_new:nnn { zref-check } { closerange-not-positive-integer }
+  {
+    Option~'closerange'~not~a~positive~integer \iow_newline:
+    on~input~line~\msg_line_number:.~Using~default~value.
+  }
+\msg_new:nnn { zref-check } { labelcmd-undefined }
+  {
+    Control~sequence~named~'#1'~used~in~option~'labelcmd'~is~not~defined.~
+    Using~default~value.
+  }
+%    \end{macrocode}
+%
+%
+% \subsection{Integer testing}
+%
+% \begin{macro}{\@@_is_integer:n, \@@_int_to_roman:w}
+%   From \url{https://tex.stackexchange.com/a/244405} (thanks Enrico Gregorio,
+%   aka `egreg'), also see \url{https://tex.stackexchange.com/a/19769}.
+%   Following the \texttt{l3styleguide}, I made a copy of
+%   \cs{__int_to_roman:w}, since it is an internal function from the
+%   \texttt{int} module, but we still get a warning from \texttt{l3build doc},
+%   complaining about it.  And we're using \cs{tl_if_empty:oTF} instead of
+%   \cs{tl_if_blank:oTF} as in egreg's answer, since \cs{romannumeral} is
+%   defined so that ``the expansion is empty if the number is zero or
+%   negative'', not ``blank''.  A couple of comments about this technique: the
+%   underlying \cs{romannumeral} ignores space tokens and explicit signs
+%   (\texttt{+} and \texttt{-}) in the expansion and hence it can only be used
+%   to test positive integers; also the technique cannot distinguish whether
+%   it received an empty argument or if ``the expansion was empty'' as a
+%   result of receiving number as argument, so this must also be controlled
+%   for since, in our use case, this may happen.
+%    \begin{macrocode}
+\cs_new_eq:NN \@@_int_to_roman:w \__int_to_roman:w
+\prg_new_conditional:Npnn \@@_is_integer:n #1 { p, T , F , TF }
+  {
+    \tl_if_empty:oTF {#1}
+      { \prg_return_false: }
+      {
+        \tl_if_empty:oTF { \@@_int_to_roman:w -0#1 }
+          { \prg_return_true:  }
+          { \prg_return_false: }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_is_integer_rgx:n}
+%   A possible alternative to \cs{@@_is_integer:n} is to use a straightforward
+%   regexp match (see \url{https://tex.stackexchange.com/a/427559}).  It does
+%   not suffer from the mentioned caveats from the \cs{__int_to_roman:w}
+%   technique, however, while \cs{@@_is_integer:n} is expandable,
+%   \cs{@@_is_integer_rgx:n} is not.  Also, \cs{@@_is_integer_rgx:n} is
+%   probably slower.
+%    \begin{macrocode}
+\prg_new_protected_conditional:Npnn \@@_is_integer_rgx:n #1 { TF }
+  {
+    \regex_match:nnTF { \A\d+\Z } {#1}
+      { \prg_return_true:  }
+      { \prg_return_false: }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsection{Options}
+%
+%
+% \subsubsection*{\opt{hyperref} option}
+%
+% \begin{variable}{\l_@@_use_hyperref_bool, \l_@@_warn_hyperref_bool}
+%    \begin{macrocode}
+\bool_new:N \l_@@_use_hyperref_bool
+\bool_new:N \l_@@_warn_hyperref_bool
+\keys_define:nn { zref-check }
+  {
+    hyperref .choice: ,
+    hyperref / auto .code:n =
+      {
+        \bool_set_true:N \l_@@_use_hyperref_bool
+        \bool_set_false:N \l_@@_warn_hyperref_bool
+      } ,
+    hyperref / true .code:n =
+      {
+        \bool_set_true:N \l_@@_use_hyperref_bool
+        \bool_set_true:N \l_@@_warn_hyperref_bool
+      } ,
+    hyperref / false .code:n =
+      {
+        \bool_set_false:N \l_@@_use_hyperref_bool
+        \bool_set_false:N \l_@@_warn_hyperref_bool
+      } ,
+    hyperref .initial:n = auto ,
+    hyperref .default:n = auto
+  }
+%    \end{macrocode}
+% \end{variable}
+%
+%    \begin{macrocode}
+\AtBeginDocument
+  {
+    \@ifpackageloaded { hyperref }
+      {
+        \bool_if:NT \l_@@_use_hyperref_bool
+          {
+            \RequirePackage { zref-hyperref }
+            \zref at addprop { zrefcheck } { anchor }
+          }
+      }
+      {
+        \bool_if:NT \l_@@_warn_hyperref_bool
+          { \msg_warning:nn { zref-check } { missing-hyperref } }
+        \bool_set_false:N \l_@@_use_hyperref_bool
+      }
+    \keys_define:nn { zref-check }
+      {
+        hyperref .code:n =
+          { \msg_warning:nn { zref-check } { hyperref-preamble-only } }
+      }
+  }
+%    \end{macrocode}
+%
+%
+% \subsubsection*{\opt{msglevel} option}
+%
+% \begin{variable}{\l_@@_msglevel_tl}
+%    \begin{macrocode}
+\tl_new:N \l_@@_msglevel_tl
+\keys_define:nn { zref-check }
+  {
+    msglevel .choice: ,
+    msglevel / warn .code:n =
+      { \tl_set:Nn \l_@@_msglevel_tl { warning } } ,
+    msglevel / info .code:n =
+      { \tl_set:Nn \l_@@_msglevel_tl { info } } ,
+    msglevel / none .code:n =
+      { \tl_set:Nn \l_@@_msglevel_tl { none } } ,
+    msglevel / obeydraft .code:n =
+      {
+        \ifdraft
+          { \tl_set:Nn \l_@@_msglevel_tl { info } }
+          { \tl_set:Nn \l_@@_msglevel_tl { warning } }
+      } ,
+    msglevel / obeyfinal .code:n =
+      {
+        \ifoptionfinal
+          { \tl_set:Nn \l_@@_msglevel_tl { warning } }
+          { \tl_set:Nn \l_@@_msglevel_tl { info } }
+      } ,
+    msglevel .value_required:n = true ,
+    msglevel .initial:n = warn ,
+%    \end{macrocode}
+% \opt{ignore} is a convenience alias for \opt{msglevel=none}, but only for
+% use in the document body.
+%    \begin{macrocode}
+    ignore .code:n =
+      { \msg_warning:nn { zref-check } { ignore-document-only } } ,
+    ignore .value_forbidden:n = true
+  }
+%    \end{macrocode}
+% \end{variable}
+%
+%    \begin{macrocode}
+\AtBeginDocument
+  {
+    \keys_define:nn { zref-check }
+      { ignore .meta:n = { msglevel = none } }
+  }
+%    \end{macrocode}
+%
+%
+% \subsubsection*{\opt{onpage} option}
+%
+% \begin{variable}{\l_@@_msgonpage_bool}
+%    \begin{macrocode}
+\bool_new:N \l_@@_msgonpage_bool
+\keys_define:nn { zref-check }
+  {
+    onpage .choice: ,
+    onpage / labelseq .code:n =
+      {
+        \bool_set_false:N \l_@@_msgonpage_bool
+      } ,
+    onpage / msg .code:n =
+      {
+        \bool_set_true:N \l_@@_msgonpage_bool
+      } ,
+    onpage / obeydraft .code:n =
+      {
+        \ifdraft
+          { \bool_set_false:N \l_@@_msgonpage_bool }
+          { \bool_set_true:N \l_@@_msgonpage_bool }
+      } ,
+    onpage / obeyfinal .code:n =
+      {
+        \ifoptionfinal
+          { \bool_set_true:N \l_@@_msgonpage_bool }
+          { \bool_set_false:N \l_@@_msgonpage_bool }
+      } ,
+    onpage .value_required:n = true ,
+    onpage .initial:n = labelseq
+  }
+%    \end{macrocode}
+% \end{variable}
+%
+%
+% \subsubsection*{\opt{closerange} option}
+%
+% \begin{variable}{\l_@@_close_range_int}
+%    \begin{macrocode}
+\int_new:N \l_@@_close_range_int
+\keys_define:nn { zref-check }
+  {
+    closerange .code:n =
+      {
+        \@@_is_integer_rgx:nTF {#1}
+          { \int_set:Nn \l_@@_close_range_int { \int_eval:n {#1} } }
+          {
+            \msg_warning:nn { zref-check } { closerange-not-positive-integer }
+            \int_set:Nn \l_@@_close_range_int { 5 }
+          }
+      } ,
+    closerange .value_required:n = true ,
+    closerange .initial:n = 5
+  }
+%    \end{macrocode}
+% \end{variable}
+%
+%
+% \subsubsection*{\opt{labelcmd} option}
+%
+% \begin{variable}{\l_@@_target_label_tl}
+%   I'd love to receive the macro itself rather than it's name, but this would
+%   bring unwarranted complications:
+%   \url{https://tex.stackexchange.com/a/489570}.
+%    \begin{macrocode}
+\tl_new:N \l_@@_target_label_tl
+\bool_new:N \l_@@_target_label_bool
+\keys_define:nn { zref-check }
+  {
+    labelcmd .code:n =
+      {
+        \tl_set:Nn \l_@@_target_label_tl {#1}
+        \bool_set_true:N \l_@@_target_label_bool
+      } ,
+    labelcmd .value_required:n = true ,
+  }
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_target_label:n}
+%   Default definition of the function for user label setting in \cs{zctarget}
+%   and \texttt{zcregion}.  It may be redefined at \texttt{begindocument}
+%   according to option \opt{labelcmd}.
+%    \begin{macrocode}
+\cs_new:Npn \@@_target_label:n #1
+  { \zref at labelbylist {#1} { zrefcheck } }
+%    \end{macrocode}
+% \end{macro}
+%
+%    \begin{macrocode}
+\AtBeginDocument
+  {
+    \bool_if:NT \l_@@_target_label_bool
+      {
+        \tl_if_blank:VT \l_@@_target_label_tl
+          { \tl_clear:N \l_@@_target_label_tl }
+        \cs_if_exist:cTF { \l_@@_target_label_tl }
+          {
+            \cs_set:Npx \@@_target_label:n #1
+              {
+                \exp_not:o
+                  { \cs:w \l_@@_target_label_tl \cs_end: }
+                  {#1}
+              }
+          }
+          {
+            \exp_args:NnnV \msg_warning:nnn { zref-check }
+              { labelcmd-undefined } { \l_@@_target_label_tl }
+          }
+      }
+    \keys_define:nn { zref-check }
+      {
+        labelcmd .code:n =
+          {
+            \msg_warning:nnn { zref-check }
+              { option-preamble-only } { labelcmd }
+          }
+      }
+  }
+%    \end{macrocode}
+%
+%
+% \subsubsection*{Package options}
+%
+% Process load-time package options
+% (\url{https://tex.stackexchange.com/a/15840}).
+%    \begin{macrocode}
+\RequirePackage { l3keys2e }
+\ProcessKeysOptions { zref-check }
+%    \end{macrocode}
+%
+%
+% \begin{macro}[int]{\zrefchecksetup}
+%   Provide \cs{zrefchecksetup}.
+%    \begin{macrocode}
+\NewDocumentCommand \zrefchecksetup { m }
+  { \keys_set:nn { zref-check } {#1} }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsection{Position on page}
+%
+% Method for determining relative position within the page: the sequence in
+% which the labels get shipped out, inferred from the sequence in which the
+% labels occur in the \file{.aux} file.
+%
+% Some relevant info about the sequence of things:
+% \url{https://tex.stackexchange.com/a/120978} and \texttt{texdoc lthooks},
+% section ``Hooks provided by |\begin{document}|''.
+%
+%
+% One first attempt at this was to use \cs{zref at newlabel}, which is the macro
+% in which \pkg{zref} stores the label information in the aux file.  When the
+% \file{.aux} file is read at the beginning of the compilation, this macro is
+% expanded for each of the labels.  So, by redefining this macro we can feed a
+% variable (a L3 sequence), and then do what it usually does, which is to
+% define each label with the internal macro \cs{@newl at bel}, when the
+% \file{.aux} file is read.
+%
+% Patching this macro for this is not possible.  First, \cs{zref at newlabel} is
+% one of those ``commands that look ahead'' mentioned in \pkg{ltcmdhooks}
+% documentation.  Indeed, \cs{@newl at bel} receives 3 arguments, and
+% \cs{zref at newlabel} just passes the first, the following two will be scanned
+% ahead.  Second, the \pkg{ltcmdhooks} hooks are not actually available when
+% the \file{.aux} file is read, they come only after |\begin{document}|.
+% Hence, redefinition would be the only alternative.  My attempts at this
+% ended up registered at \url{https://tex.stackexchange.com/a/604744}.  But
+% the best result in these lines was:
+%
+% \begin{verbatim}
+% \ZREF at Robust\edef\zref at newlabel#1{
+%   \noexpand\seq_gput_right:Nn \noexpand\g__zrefcheck_auxfile_lblseq_seq {#1}
+%   \noexpand\@newl at bel{\ZREF at RefPrefix}{#1}
+% }
+% \end{verbatim}
+%
+%
+% However, better than the above is to just read it from the \file{.aux} file
+% directly, which relieves us from hacking into any internals.  That's what
+% David Carlisle's answer at \url{https://tex.stackexchange.com/a/147705}
+% does.  This answer has actually been converted into the package
+% \pkg{listlbls} by Norbert Melzer, but it is made to work with regular
+% labels, not with \pkg{zref}'s.  And it also does not really expose the
+% information in a retrievable way (as far as I can tell).  So, the below is
+% adapted from Carlisle's answer's technique (a poor man's version of it...).
+%
+% There is some subtlety here as to whether this approach makes it safe for us
+% to read the labels at this point without \cs{zref at wrapper@babel}.  The
+% common wisdom is that babel's shorthands are only active after
+% |\begin{document}| (e.g., \url{https://tex.stackexchange.com/a/98897}).
+% Alas, it is more complicated than that.  Babel's documentation says (in
+% section 9.5 Shorthands): ``To prevent problems with the loading of other
+% packages after babel we reset the catcode of the character to the original
+% one at the end of the package and of each language file (except with
+% KeepShorthandsActive).  It is re-activate[d] again at |\begin{document}|.
+% We also need to make sure that the shorthands are active during the
+% processing of the \file{.aux} file.  Otherwise some citations may give
+% unexpected results in the printout when a shorthand was used in the optional
+% argument of |\bibitem| for example.''  This is done with
+% |\if at filesw \immediate\write\@mainaux{...}|.  In other words, the
+% catcode change is written in the \file{.aux} file itself!  Indeed, if you
+% inspect the file, you'll find them there.  Besides, there is still the
+% ominous ``except with KeepShorthandsActive''.
+%
+% However, the \emph{method} we're using here is not quite the same as the
+% usual run of the \file{.aux} file, because we're actively discarding the
+% lines for which the first token is not equal to \cs{zref at newlabel}.  I have
+% tested the famous sensitive case for this: \pkg{babel} \opt{french} and
+% labels with colons.  And things worked as expected.  Well, \emph{if}
+% \opt{KeepShorthandsActive} is enabled \emph{with \opt{french}} and we load
+% the package \emph{after babel} things do break, but not quite because of the
+% colons in the labels.  Even \pkg{siunitx} breaks in the same
+% conditions\dots{}
+%
+% For reference: About what are valid characters for use in labels:
+% \url{https://tex.stackexchange.com/a/18312}.  About some problems with
+% active colons: \url{https://tex.stackexchange.com/a/89470}.  About the
+% difference between L3 strings and token lists, see
+% \url{https://tex.stackexchange.com/a/446381}, in particular Joseph Wright's
+% comment: ``Strings are for data that will never be typeset, for example file
+% names, identifiers, etc.: if the material may be used in typesetting, it
+% should be a token list.''  See also moewe's (CW) answer in the same lines.
+% Which suggests using L3 strings for the reference labels might be a good
+% catch all approach, and possibly more robust.  David Carlisle's comment
+% about \pkg{inputenc} and how the strings work is a caveat (see
+% \url{https://tex.stackexchange.com/q/446123#comment1516961_446381}, thanks
+% David Carlisle).  Still\dots{} let's stick to tradition as long as it works,
+% \pkg{zref} already does a great job in this regard anyway.
+%
+%
+% \begin{variable}{\g_@@_auxfile_lblseq_prop}
+%    \begin{macrocode}
+\prop_new:N \g_@@_auxfile_lblseq_prop
+%    \end{macrocode}
+% \end{variable}
+%
+%    \begin{macrocode}
+\tl_set:Nn \g_tmpa_tl { \c_sys_jobname_str .aux }
+\file_if_exist:nT { \g_tmpa_tl }
+  {
+%    \end{macrocode}
+% Retrieve the information from the \file{.aux} file, and store it in a
+% property list, so that the sequence can be retrieved in key-value fashion.
+%    \begin{macrocode}
+    \ior_open:Nn \g_tmpa_ior { \g_tmpa_tl }
+    \group_begin:
+      \int_zero:N \l_tmpa_int
+      \tl_clear:N \l_tmpa_tl
+      \tl_clear:N \l_tmpb_tl
+      \bool_set_false:N \l_tmpa_bool
+      \ior_map_variable:NNn \g_tmpa_ior \l_tmpa_tl
+        {
+          \tl_map_variable:NNn \l_tmpa_tl \l_tmpb_tl
+            {
+              \tl_if_eq:NnTF \l_tmpb_tl { \zref at newlabel }
+                {
+%    \end{macrocode}
+% Found a \cs{zref at label}, signal it.
+%    \begin{macrocode}
+                  \bool_set_true:N \l_tmpa_bool
+                }
+                {
+                  \bool_if:NTF \l_tmpa_bool
+                    {
+                      \bool_set_false:N \l_tmpa_bool
+                      \int_incr:N \l_tmpa_int
+                      \prop_gput:Nxx \g_@@_auxfile_lblseq_prop
+                        { \l_tmpb_tl } { \int_use:N \l_tmpa_int }
+                    }
+                    {
+%    \end{macrocode}
+% If there is not a match of the first token with \cs{zref at newlabel}, break
+% the loop and discard the rest of the line, to ensure no babel calls to
+% \cs{catcode} in the \file{.aux} file get expanded.  This also breaks the
+% loop and discards the rest of the \cs{zref at newlabel} lines after we got the
+% label we wanted, since we reset \cs{l_tmpa_bool} in the \texttt{T} branch.
+%    \begin{macrocode}
+                      \tl_map_break:
+                    }
+                }
+            }
+        }
+    \group_end:
+    \ior_close:N \g_tmpa_ior
+  }
+%    \end{macrocode}
+%
+%
+%
+% The alternate method I had considered (more than that...) for this was using
+% yx coordinates supplied by \pkg{zref}'s \pkg{savepos} module.  However, this
+% approach brought in a number of complexities, including the need to patch
+% either \cs{zref at label} or \cs{ZREF at label}.  In addition, the technique was
+% at the bottom fundamentally flawed.  Ulrike Fischer was very much right when
+% she said that ``structure and position are two different beasts''
+% (\url{https://github.com/ho-tex/zref/issues/12#issuecomment-880022576}).  It
+% is true that the checks based on it behaved decently, in normal
+% circumstances, and except for outrageous label placement by the user, it
+% would return the expected results.  We don't really need exact coordinates
+% to decide ``above/below''.  Besides, it would do an exact job for the
+% dedicated target macros of this package.  However, I could not conceive a
+% situation where the \texttt{yx} criterion would perform clearly better than
+% the \texttt{labelseq} one.  And, if that's the case, and considering the
+% complications it brings, this check was a slippery slope.  All in all, I've
+% decided to drop it.
+%
+%
+%
+% \subsection{Counter}
+%
+% We need a dedicated counter for the labels generated by the checks and
+% targets.  The value of the counter is not relevant, we just need it to be
+% able to set proper anchors with \cs{refstepcounter}.  And, since I couldn't
+% find a \cs{refstepcounter} equivalent in L3, we use a standard 2e counter
+% here.  I'm also using the technique to ensure the counter is never reset
+% that is used by \file{zref-abspage.sty} and \cs{zref at require@unique}.
+% Indeed, the requirements are the same, we need numbers ensured to be
+% \emph{unique} in the counter.
+%
+%    \begin{macrocode}
+\begingroup
+  \let \@addtoreset \ltx at gobbletwo
+  \newcounter { zrefcheck }
+\endgroup
+\setcounter { zrefcheck } { 0 }
+%    \end{macrocode}
+%
+%
+%
+% \subsection{Label formats}
+%
+% \begin{macro}{\@@_check_lblfmt:n}
+%   \begin{syntax}
+%     \cs{@@_check_lblfmt:n} \Arg{check id int}
+%   \end{syntax}
+%    \begin{macrocode}
+\cs_new:Npn \@@_check_lblfmt:n #1 { zrefcheck@ \int_use:N #1 }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_end_lblfmt:n}
+%   \begin{syntax}
+%     \cs{@@_end_lblfmt:n} \Arg{label}
+%   \end{syntax}
+%    \begin{macrocode}
+\cs_new:Npn \@@_end_lblfmt:n #1 { #1 @zrefcheck }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsection{Property values}
+%
+%
+% \begin{macro}[int]{\zrefcheck_get_astl:nnn}
+%   A convenience function to retrieve property values from labels.  Uses
+%   \cs{g_@@_auxfile_lblseq_prop} for \texttt{lblseq}, and calls
+%   \cs{zref at extractdefault} for everything else.
+%
+%   We cannot use the ``return value'' of \cs{@@_get_astl:nnn} or
+%   \cs{@@_get_asint:nnn} directly, because we need to use the retrieved
+%   property values as arguments in the checks, however we use here a number
+%   of non-expandable operations.  Hence, we receive a local \texttt{tl/int}
+%   variable as third argument and set that, so that it is available (and
+%   expandable) at the place of use.  For this reason, we do not group here,
+%   because we are passing a local variable around, but it is expected this
+%   function will be called within a group.
+%
+%   We're returning \cs{c_empty_tl} in case of failure to find the intended
+%   property value (explicitly in \cs{zref at extractdefault}, but that is also
+%   what \cs{tl_clear:N} does).
+%
+%   \begin{syntax}
+%     \cs{zrefcheck_get_astl:nnn} \Arg{label} \Arg{prop} \Arg{tl var}
+%   \end{syntax}
+%    \begin{macrocode}
+\cs_new:Npn \zrefcheck_get_astl:nnn #1#2#3
+  {
+    \tl_clear:N #3
+    \tl_if_eq:nnTF {#2} { lblseq }
+      {
+        \prop_get:NnNF \g_@@_auxfile_lblseq_prop {#1} #3
+          {
+            \msg_warning:nnnn { zref-check }
+              { property-not-in-label } {#1} {#2}
+          }
+      }
+      {
+%    \end{macrocode}
+% There are three things we need to check to ensure the information we are
+% trying to retrieve here exists: the existence of \Arg{label}, the existence
+% of \Arg{prop}, and whether the particular label being queried actually
+% contains the property.  If that's all in place, the value is passed to the
+% checks, and it's their responsibility to verify the consistency of this
+% value.
+%
+% The existence of the label is an user facing issue, and a warning for this
+% is placed in \cs{@@_zcheck:nnnnn} (and done with \cs{zref at refused}).  We do
+% check here though for definition with \cs{zref at ifrefundefined} and silently
+% do nothing if it is undefined, to reduce irrelevant warnings in a fresh
+% compilation round.  The other two are more ``internal'' problems, either
+% some problem with the checks, or with the configuration of \pkg{zref} for
+% their consumption.
+%    \begin{macrocode}
+        \zref at ifrefundefined {#1}
+          {}
+          {
+            \zref at ifpropundefined {#2}
+              { \msg_warning:nnnn { zref-check } { property-undefined } {#2} }
+              {
+                \zref at ifrefcontainsprop {#1} {#2}
+                  {
+                    \tl_set:Nx #3
+                      { \zref at extractdefault {#1} {#2} { \c_empty_tl } }
+                  }
+                  {
+                    \msg_warning:nnnn
+                      { zref-check } { property-not-in-label } {#1} {#2}
+                  }
+              }
+          }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{variable}{\l_@@_integer_bool}
+%   \cs{zrefcheck_get_asint:nnn} is a very convenient wrapper around the more
+%   general \cs{zrefcheck_get_astl:nnn}, since almost always we'll be wanting
+%   to compare numbers in the checks.  However, it is quite hard for it to
+%   ensure an integer is \emph{always} returned in the case of errors.  And
+%   those do occur, even in a well structured document (e.g., in a first round
+%   of compilation).  To complicate things, the L3 integer predicates are
+%   \emph{very} sensitive to receiving any other kind of data, and they
+%   \emph{scream}.  To handle this \cs{zrefcheck_get_asint:nnn} uses
+%   \cs{l_@@_integer_bool} to signal if an integer could not be returned.  To
+%   use this function always set \cs{l_@@_integer_bool} to true first, then
+%   call it as much as you need.  If any of these calls got is returning
+%   anything which is not an integer, \cs{l_@@_integer_bool} will have been
+%   set to false, and you should check that this hasn't happened before
+%   actually comparing the integers (\cs{bool_lazy_and:nnTF} is your friend).
+%    \begin{macrocode}
+\bool_new:N \l_@@_integer_bool
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_propval_tl}
+%    \begin{macrocode}
+\tl_new:N \l_@@_propval_tl
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[int]{\zrefcheck_get_asint:nnn}
+%   \begin{syntax}
+%     \cs{zrefcheck_get_asint:nnn} \Arg{label} \Arg{prop} \Arg{int var}
+%   \end{syntax}
+%    \begin{macrocode}
+\cs_new:Npn \zrefcheck_get_asint:nnn #1#2#3
+  {
+    \zrefcheck_get_astl:nnn {#1} {#2} { \l_@@_propval_tl }
+    \@@_is_integer:nTF { \l_@@_propval_tl }
+      {
+%    \end{macrocode}
+% Make it an integer data type.
+%    \begin{macrocode}
+        \int_set:Nn #3 { \int_eval:n { \l_@@_propval_tl } }
+      }
+      {
+        \bool_set_false:N \l_@@_integer_bool
+        \zref at ifrefundefined {#1}
+%    \end{macrocode}
+% Keep silent if ref is undefined to reduce irrelevant warnings in a fresh
+% compilation round.  Again, this is also not the point to check for undefined
+% references, that's a task for \cs{@@_zcheck:nnnnn}.
+%    \begin{macrocode}
+          { }
+          {
+            \msg_warning:nnnn { zref-check }
+              { property-not-integer } {#2} {#1}
+          }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+% \section{User interface}
+%
+%
+% \subsection{\cs{zcheck}}
+%
+% \begin{macro}[int]{\zcheck}
+%   The \marg{text} argument of \cs{zcheck} should not be long, since
+%   \cs{hyperlink} cannot receive a long argument.  Besides, there is no
+%   reason for it to be.  Note, also, that hyperlinks crossing page boundaries
+%   have some known issues: \url{https://tex.stackexchange.com/a/182769},
+%   \url{https://tex.stackexchange.com/a/54607},
+%   \url{https://tex.stackexchange.com/a/179907}.
+%
+%   \begin{syntax}
+%     \cs{zcheck}\meta{*}\oarg{options}\marg{labels}\oarg{checks}\marg{text}
+%   \end{syntax}
+%
+%    \begin{macrocode}
+\NewDocumentCommand \zcheck
+  { s O { } > { \SplitList { , } } m > { \SplitList { , } } O { } m }
+  { \zref at wrapper@babel \@@_zcheck:nnnnn {#3} {#1} {#2} {#4} {#5} }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{variable}
+%   {
+%     \g_@@_id_int ,
+%     \l_@@_checkbeg_tl ,
+%     \l_@@_checkend_tl ,
+%     \l_@@_link_label_tl ,
+%     \l_@@_link_anchor_tl ,
+%     \l_@@_link_star_tl
+%   }
+%    \begin{macrocode}
+\int_new:N \g_@@_id_int
+\tl_new:N \l_@@_checkbeg_tl
+\tl_new:N \l_@@_checkend_tl
+\tl_new:N \l_@@_link_label_tl
+\tl_new:N \l_@@_link_anchor_tl
+\bool_new:N \l_@@_link_star_tl
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_zcheck:nnnnn}
+%   An intermediate internal function, which does the actual heavy lifting,
+%   and places \Arg{labels} as first argument, so that it can be protected by
+%   \cs{zref at wrapper@babel} in \cs{zcheck}.  This is the same procedure as the
+%   one used in the definition of \cs{zref} in \file{zref-user.sty} for
+%   protection of \pkg{babel} active characters.
+%
+%   \begin{syntax}
+%     \cs{@@_zcheck:nnnnn} \Arg{labels} \Arg{*} \Arg{options} \Arg{checks} \Arg{text}
+%   \end{syntax}
+%
+%    \begin{macrocode}
+\cs_new:Npn \@@_zcheck:nnnnn #1#2#3#4#5
+  {
+    \group_begin:
+%    \end{macrocode}
+% Process local options.
+%    \begin{macrocode}
+      \keys_set:nn { zref-check } {#3}
+%    \end{macrocode}
+% Names of the labels for this zrefcheck call.
+%    \begin{macrocode}
+      \int_gincr:N \g_@@_id_int
+      \tl_set:Nx \l_@@_checkbeg_tl
+        { \@@_check_lblfmt:n { \g_@@_id_int } }
+      \tl_set:Nx \l_@@_checkend_tl
+        { \@@_end_lblfmt:n { \l_@@_checkbeg_tl } }
+%    \end{macrocode}
+% Set checkbeg label.
+%    \begin{macrocode}
+      \zref at labelbylist { \l_@@_checkbeg_tl } { zrefcheck }
+%    \end{macrocode}
+% Typeset \marg{text}, with hyperlink when appropriate.  Even though the first
+% argument can receive a list of labels, there is no meaningful way to set
+% links to multiple targets.  Hence, only the first one is considered for
+% hyperlinking.
+%    \begin{macrocode}
+      \tl_set:Nn \l_@@_link_label_tl { \tl_head:n {#1} }
+      \bool_set:Nn \l_@@_link_star_tl {#2}
+      \zref at ifrefundefined { \l_@@_link_label_tl }
+%    \end{macrocode}
+% If the reference is undefined, just typeset.
+%    \begin{macrocode}
+        {#5}
+        {
+          \bool_if:nTF
+            {
+              \l_@@_use_hyperref_bool &&
+              ! \l_@@_link_star_tl
+            }
+            {
+              \exp_args:Nx \zrefcheck_get_astl:nnn
+                { \l_@@_link_label_tl }
+                { anchor } { \l_@@_link_anchor_tl }
+              \hyperlink { \l_@@_link_anchor_tl } {#5}
+            }
+            {#5}
+        }
+%    \end{macrocode}
+% Set checkend label.
+%    \begin{macrocode}
+      \zref at labelbylist { \l_@@_checkend_tl } { zrefcheck }
+%    \end{macrocode}
+% Check if \meta{labels} are defined.
+%    \begin{macrocode}
+      \tl_map_function:nN {#1} \zref at refused
+%    \end{macrocode}
+% Run the checks.
+%    \begin{macrocode}
+      \@@_run_checks:nnV {#4} {#1} { \l_@@_checkbeg_tl }
+    \group_end:
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Targets}
+%
+% \begin{macro}[int]{\zctarget}
+%   \begin{syntax}
+%     \cs{zctarget}\marg{label}\marg{text}
+%   \end{syntax}
+%    \begin{macrocode}
+\NewDocumentCommand \zctarget { m +m }
+  {
+%    \end{macrocode}
+% Group contents of \cs{zctarget} to avoid leaking the effects of
+% \cs{refstepcounter} over \cs{@currentlabel}.  The same care is not needed
+% for \texttt{zcregion}, since the environment is already grouped.
+%    \begin{macrocode}
+    \group_begin:
+    \refstepcounter { zrefcheck }
+    \zref at wrapper@babel \@@_target_label:n {#1}
+    #2
+    \zref at wrapper@babel
+      \zref at labelbylist { \@@_end_lblfmt:n {#1} } { zrefcheck }
+    \group_end:
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{zcregion}
+%   \begin{syntax}
+%     |\begin{zcregion}|\marg{label}
+%       |  ...|
+%     |\end{zcregion}|
+%   \end{syntax}
+%    \begin{macrocode}
+\NewDocumentEnvironment {zcregion} { m }
+  {
+    \refstepcounter { zrefcheck }
+    \zref at wrapper@babel \@@_target_label:n {#1}
+  }
+  {
+    \zref at wrapper@babel
+      \zref at labelbylist { \@@_end_lblfmt:n {#1} } { zrefcheck }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \section{Checks}
+%
+% What is needed define a \pkg{zref-check} check?
+%
+% First, a conditional function defined with:
+%
+% \cs{prg_new_conditional:Npnn} \cs{@@_check_\meta{check}:nn} |#1#2 { F }|
+%
+% \noindent where \meta{check} is the name of the check, the first argument is
+% the \Arg{label} and the second the \Arg{reference}.  The existence of the
+% check is verified by the existence of the function with this name-scheme
+% (and signatures).  As usual, this function must return either
+% \cs{prg_return_true:} or \cs{prg_return_false:}.  Of course, you can define
+% other variants if you need them internally, it is just that what the package
+% does expect and verifies is the existence of the \texttt{:nnF} variant.
+%
+% Note that the naming convention of the checks adopts the perspective of the
+% \meta{reference}.  That is, the ``before'' check should return true if the
+% \meta{label} occurs before the ``reference''.
+%
+% The check conditionals are expected to retrieve \pkg{zref}'s label
+% information with \cs{zrefcheck_get_astl:nnn} or
+% \cs{zrefcheck_get_asint:nnn}.  Also, technically speaking, the
+% \meta{reference} argument is also a label, actually a pair of them, as set
+% by \cs{zcheck}.  For the ``labels'', any \pkg{zref} property in \pkg{zref}'s
+% main list is available, the ``references'' store the properties in the
+% \texttt{zrefcheck} list.  Besides those, there is also the \texttt{lblseq}
+% (fake) property (for either ``labels'' or ``references''), stored in
+% \cs{g_@@_auxfile_lblseq_prop}.
+%
+% Second, the required properties of labels and references must be duly
+% registered for \pkg{zref}.  This can be done with \cs{zref at newprop},
+% \cs{zref at addprop} and friends, as usual.
+%
+%
+% \subsection{Running}
+%
+% \begin{macro}{\@@_run_checks:nnn, \@@_run_checks:nnV}
+%   \begin{syntax}
+%     \cs{@@_run_checks:nnn} \Arg{checks} \Arg{labels} \Arg{reference}
+%   \end{syntax}
+%    \begin{macrocode}
+\cs_new:Npn \@@_run_checks:nnn #1#2#3
+  {
+    \group_begin:
+      \tl_map_inline:nn {#2}
+        {
+          \tl_map_inline:nn {#1}
+            { \@@_do_check:nnn {####1} {##1} {#3} }
+        }
+    \group_end:
+  }
+\cs_generate_variant:Nn \@@_run_checks:nnn { nnV }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{variable}
+%   {
+%     \l_@@_passedcheck_bool ,
+%     \l_@@_onpage_bool ,
+%     \c_@@_onpage_checks_seq
+%   }
+%    \begin{macrocode}
+\bool_new:N \l_@@_passedcheck_bool
+\bool_new:N \l_@@_onpage_bool
+\seq_new:N \c_@@_onpage_checks_seq
+\seq_set_from_clist:Nn \c_@@_onpage_checks_seq
+  { above , below , before , after }
+%    \end{macrocode}
+% \end{variable}
+%
+%
+% Variant not provided by \pkg{expl3}.
+%    \begin{macrocode}
+\cs_generate_variant:Nn \exp_args:Nnno { Nnoo }
+%    \end{macrocode}
+%
+% \begin{macro}{\@@_do_check:nnn}
+%   \begin{syntax}
+%     \cs{@@_do_check:nnn} \Arg{check} \Arg{label beg} \Arg{reference beg}
+%   \end{syntax}
+%    \begin{macrocode}
+\cs_new:Npn \@@_do_check:nnn #1#2#3
+  {
+    \group_begin:
+%    \end{macrocode}
+% \meta{label beg} may be defined or not, it is arbitrary user input.  Whether
+% this is the case is checked in \cs{@@_zcheck:nnnnn}, and due warning already
+% ensues.  And there is no point in checking ``relative position'' of an
+% undefined label.  Hence, in the absence of |#2|, we do nothing at all here.
+%    \begin{macrocode}
+      \zref at ifrefundefined {#2}
+        {}
+        {
+          \tl_if_empty:nF {#1}
+            {
+              \bool_set_true:N \l_@@_passedcheck_bool
+              \bool_set_false:N \l_@@_onpage_bool
+              \cs_if_exist:cTF { @@_check_ #1 :nnF }
+                {
+%    \end{macrocode}
+% ``label beg'' vs ``reference beg''.
+%    \begin{macrocode}
+                  \use:c { @@_check_ #1 :nnF }
+                    {#2} {#3}
+                    { \bool_set_false:N \l_@@_passedcheck_bool }
+%    \end{macrocode}
+% ``label beg'' vs ``reference end''.
+%    \begin{macrocode}
+                  \exp_args:Nnno \use:c { @@_check_ #1 :nnF }
+                    {#2} { \@@_end_lblfmt:n {#3} }
+                    { \bool_set_false:N \l_@@_passedcheck_bool }
+%    \end{macrocode}
+% ``label end'' \emph{may} have been created by the target commands.
+%    \begin{macrocode}
+                  \zref at ifrefundefined { \@@_end_lblfmt:n {#2} }
+                    {}
+                    {
+%    \end{macrocode}
+% ``label end'' vs ``reference beg''.
+%    \begin{macrocode}
+                      \exp_args:Nno \use:c { @@_check_ #1 :nnF }
+                        { \@@_end_lblfmt:n {#2} } {#3}
+                        { \bool_set_false:N \l_@@_passedcheck_bool }
+%    \end{macrocode}
+% ``label end'' vs ``reference end''.
+%    \begin{macrocode}
+                      \exp_args:Nnoo \use:c { @@_check_ #1 :nnF }
+                        { \@@_end_lblfmt:n {#2} }
+                        { \@@_end_lblfmt:n {#3} }
+                        { \bool_set_false:N \l_@@_passedcheck_bool }
+                    }
+%    \end{macrocode}
+% Handle option \opt{onpage=msg}.  This is only granted for tests which
+% perform ``within this page'' checks (\opt{above}, \opt{below}, \opt{before},
+% \opt{after}) \emph{and} if any of the two by two checks uses a ``within this
+% page'' comparison.  If both conditions are met, signal.
+%    \begin{macrocode}
+                  \seq_if_in:NnT \c_@@_onpage_checks_seq {#1}
+                    {
+                      \@@_check_thispage:nnT
+                        {#2} {#3}
+                        { \bool_set_true:N \l_@@_onpage_bool }
+                      \@@_check_thispage:nnT
+                        {#2} { \@@_end_lblfmt:n {#3} }
+                        { \bool_set_true:N \l_@@_onpage_bool }
+                      \zref at ifrefundefined { \@@_end_lblfmt:n {#2} }
+                        {}
+                        {
+                          \@@_check_thispage:nnT
+                            { \@@_end_lblfmt:n {#2} } {#3}
+                            { \bool_set_true:N \l_@@_onpage_bool }
+                          \@@_check_thispage:nnT
+                            { \@@_end_lblfmt:n {#2} }
+                            { \@@_end_lblfmt:n {#3} }
+                            { \bool_set_true:N \l_@@_onpage_bool }
+                        }
+                    }
+                  \bool_if:NTF \l_@@_passedcheck_bool
+                    {
+                      \bool_if:nT
+                        {
+                          \l_@@_msgonpage_bool &&
+                          \l_@@_onpage_bool
+                        }
+                        {
+                          \@@_message:nnnx { double-check } {#1} {#2}
+                            { \zref at extractdefault {#3} {page} {'unknown'} }
+                        }
+                    }
+                    {
+                      \@@_message:nnnx { check-failed } {#1} {#2}
+                        { \zref at extractdefault {#3} {page} {'unknown'} }
+                    }
+                }
+                { \msg_warning:nnn { zref-check } { check-missing } {#1} }
+            }
+        }
+    \group_end:
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Conditionals}
+%
+% \begin{variable}
+%   {
+%     \l_@@_lbl_int ,
+%     \l_@@_ref_int ,
+%     \l_@@_lbl_b_int ,
+%     \l_@@_ref_b_int
+%   }
+%   More readable scratch variables for the tests.
+%    \begin{macrocode}
+\int_new:N \l_@@_lbl_int
+\int_new:N \l_@@_ref_int
+\int_new:N \l_@@_lbl_b_int
+\int_new:N \l_@@_ref_b_int
+%    \end{macrocode}
+% \end{variable}
+%
+%
+% \subsubsection{This page}
+%
+% \begin{macro}{\@@_check_thispage:nn}
+%    \begin{macrocode}
+\prg_new_conditional:Npnn \@@_check_thispage:nn #1#2 { T , F , TF }
+  {
+    \group_begin:
+      \bool_set_true:N \l_@@_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abspage } { \l_@@_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abspage } { \l_@@_ref_int }
+      \bool_lazy_and:nnTF
+        { \l_@@_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l_@@_lbl_int } = { \l_@@_ref_int } &&
+%    \end{macrocode}
+% `0' is the default value of \texttt{abspage}, but this value should not
+% happen normally for this property, since even the first page, after it gets
+% shipped out, will receive value `1'.  So, if we do find `0' here, better
+% signal something is wrong.  This comment extends to all page number checks.
+%    \begin{macrocode}
+            ! \int_compare_p:nNn { \l_@@_lbl_int } = { 0 } &&
+            ! \int_compare_p:nNn { \l_@@_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \subsubsection{On page}
+%
+% \begin{macro}{\@@_check_above:nn, \@@_check_below:nn}
+%    \begin{macrocode}
+\prg_new_conditional:Npnn \@@_check_above:nn #1#2 { F , TF }
+  {
+    \group_begin:
+      \@@_check_thispage:nnTF {#1} {#2}
+        {
+          \bool_set_true:N \l_@@_integer_bool
+          \zrefcheck_get_asint:nnn {#1} { lblseq } { \l_@@_lbl_int }
+          \zrefcheck_get_asint:nnn {#2} { lblseq } { \l_@@_ref_int }
+          \bool_lazy_and:nnTF
+            { \l_@@_integer_bool }
+            {
+              \int_compare_p:nNn
+                { \l_@@_lbl_int } < { \l_@@_ref_int } &&
+              ! \int_compare_p:nNn { \l_@@_lbl_int } = { 0 } &&
+              ! \int_compare_p:nNn { \l_@@_ref_int } = { 0 }
+            }
+            { \group_insert_after:N \prg_return_true:  }
+            { \group_insert_after:N \prg_return_false: }
+        }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \@@_check_below:nn #1#2 { F , TF }
+  {
+    \@@_check_thispage:nnTF {#1} {#2}
+      {
+        \@@_check_above:nnTF {#1} {#2}
+          { \prg_return_false: }
+          { \prg_return_true:  }
+      }
+      { \prg_return_false: }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \subsubsection{Before / After}
+%
+% \begin{macro}{\@@_check_before:nn, \@@_check_after:nn}
+%    \begin{macrocode}
+\prg_new_conditional:Npnn \@@_check_before:nn #1#2 { F }
+  {
+    \@@_check_pagesbefore:nnTF {#1} {#2}
+      { \prg_return_true: }
+      {
+        \@@_check_above:nnTF {#1} {#2}
+          { \prg_return_true:  }
+          { \prg_return_false: }
+      }
+  }
+\prg_new_conditional:Npnn \@@_check_after:nn #1#2 { F }
+  {
+    \@@_check_pagesafter:nnTF {#1} {#2}
+      { \prg_return_true: }
+      {
+        \@@_check_below:nnTF {#1} {#2}
+          { \prg_return_true:  }
+          { \prg_return_false: }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \subsubsection{Pages}
+%
+% \begin{macro}
+%   {
+%     \@@_check_nextpage:nn ,
+%     \@@_check_prevpage:nn ,
+%     \@@_check_pagesbefore:nn ,
+%     \@@_check_ppbefore:nn ,
+%     \@@_check_pagesafter:nn ,
+%     \@@_check_ppafter:nn ,
+%     \@@_check_facing:nn
+%   }
+%    \begin{macrocode}
+\prg_new_conditional:Npnn \@@_check_nextpage:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l_@@_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abspage } { \l_@@_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abspage } { \l_@@_ref_int }
+      \bool_lazy_and:nnTF
+        { \l_@@_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l_@@_lbl_int } = { \l_@@_ref_int + 1 } &&
+          ! \int_compare_p:nNn { \l_@@_lbl_int } = { 0 } &&
+          ! \int_compare_p:nNn { \l_@@_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \@@_check_prevpage:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l_@@_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abspage } { \l_@@_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abspage } { \l_@@_ref_int }
+      \bool_lazy_and:nnTF
+        { \l_@@_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l_@@_lbl_int } = { \l_@@_ref_int - 1 } &&
+          ! \int_compare_p:nNn { \l_@@_lbl_int } = { 0 } &&
+          ! \int_compare_p:nNn { \l_@@_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \@@_check_pagesbefore:nn #1#2 { F , TF }
+  {
+    \group_begin:
+      \bool_set_true:N \l_@@_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abspage } { \l_@@_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abspage } { \l_@@_ref_int }
+      \bool_lazy_and:nnTF
+        { \l_@@_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l_@@_lbl_int } < { \l_@@_ref_int } &&
+          ! \int_compare_p:nNn { \l_@@_lbl_int } = { 0 } &&
+          ! \int_compare_p:nNn { \l_@@_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\cs_new_eq:NN \@@_check_ppbefore:nnF \@@_check_pagesbefore:nnF
+\prg_new_conditional:Npnn \@@_check_pagesafter:nn #1#2 { F , TF }
+  {
+    \group_begin:
+      \bool_set_true:N \l_@@_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abspage } { \l_@@_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abspage } { \l_@@_ref_int }
+      \bool_lazy_and:nnTF
+        { \l_@@_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l_@@_lbl_int } > { \l_@@_ref_int } &&
+          ! \int_compare_p:nNn { \l_@@_lbl_int } = { 0 } &&
+          ! \int_compare_p:nNn { \l_@@_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\cs_new_eq:NN \@@_check_ppafter:nnF \@@_check_pagesafter:nnF
+\prg_new_conditional:Npnn \@@_check_facing:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l_@@_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abspage } { \l_@@_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abspage } { \l_@@_ref_int }
+      \bool_lazy_and:nnTF
+        { \l_@@_integer_bool }
+        {
+%    \end{macrocode}
+% There exists no ``facing'' page if the document is not twoside.
+%    \begin{macrocode}
+          \legacy_if_p:n { @twoside } &&
+%    \end{macrocode}
+% Now we test ``facing''.
+%    \begin{macrocode}
+          (
+            (
+              \int_if_odd_p:n { \l_@@_ref_int } &&
+              \int_compare_p:nNn
+                { \l_@@_lbl_int } = { \l_@@_ref_int - 1 }
+            ) ||
+            (
+              \int_if_even_p:n { \l_@@_ref_int } &&
+              \int_compare_p:nNn
+                { \l_@@_lbl_int } = { \l_@@_ref_int + 1 }
+            )
+          ) &&
+          ! \int_compare_p:nNn { \l_@@_lbl_int } = { 0 } &&
+          ! \int_compare_p:nNn { \l_@@_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \subsubsection{Close / Far}
+%
+% \begin{macro}{\@@_check_close:nn, \@@_check_far:nn}
+%    \begin{macrocode}
+\prg_new_conditional:Npnn \@@_check_close:nn #1#2 { F , TF }
+  {
+    \group_begin:
+      \bool_set_true:N \l_@@_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abspage } { \l_@@_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abspage } { \l_@@_ref_int }
+      \bool_lazy_and:nnTF
+        { \l_@@_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \int_abs:n { \l_@@_lbl_int - \l_@@_ref_int } }
+            <
+            { \l_@@_close_range_int + 1 } &&
+          ! \int_compare_p:nNn { \l_@@_lbl_int } = { 0 } &&
+          ! \int_compare_p:nNn { \l_@@_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \@@_check_far:nn #1#2 { F }
+  {
+    \@@_check_close:nnTF {#1} {#2}
+      { \prg_return_false: }
+      { \prg_return_true:  }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \subsubsection{Chapter}
+%
+% \begin{macro}
+%   {
+%     \@@_check_thischap:nn ,
+%     \@@_check_nextchap:nn ,
+%     \@@_check_prevchap:nn ,
+%     \@@_check_chapsafter:nn ,
+%     \@@_check_chapsbefore:nn
+%   }
+%    \begin{macrocode}
+\prg_new_conditional:Npnn \@@_check_thischap:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l_@@_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abschap } { \l_@@_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abschap } { \l_@@_ref_int }
+      \bool_lazy_and:nnTF
+        { \l_@@_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l_@@_lbl_int } = { \l_@@_ref_int } &&
+%    \end{macrocode}
+% `0' is the default value of \texttt{abschap} property, and means here no
+% \cs{chapter} has yet been issued, therefore it cannot be ``this chapter'',
+% nor ``the next chapter'', nor ``the previous chapter'', it is just ``no
+% chapter''.  Note, however, that a statement about a ``future'' chapter does
+% not require the ``current'' one to exist.  This comment extends to all
+% chapter checks.
+%    \begin{macrocode}
+          ! \int_compare_p:nNn { \l_@@_lbl_int } = { 0 } &&
+          ! \int_compare_p:nNn { \l_@@_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \@@_check_nextchap:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l_@@_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abschap } { \l_@@_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abschap } { \l_@@_ref_int }
+      \bool_lazy_and:nnTF
+        { \l_@@_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l_@@_lbl_int } = { \l_@@_ref_int + 1 } &&
+          ! \int_compare_p:nNn { \l_@@_lbl_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \@@_check_prevchap:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l_@@_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abschap } { \l_@@_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abschap } { \l_@@_ref_int }
+      \bool_lazy_and:nnTF
+        { \l_@@_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l_@@_lbl_int } = { \l_@@_ref_int - 1 } &&
+          ! \int_compare_p:nNn { \l_@@_lbl_int } = { 0 } &&
+          ! \int_compare_p:nNn { \l_@@_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \@@_check_chapsafter:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l_@@_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abschap } { \l_@@_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abschap } { \l_@@_ref_int }
+      \bool_lazy_and:nnTF
+        { \l_@@_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l_@@_lbl_int } > { \l_@@_ref_int } &&
+          ! \int_compare_p:nNn { \l_@@_lbl_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \@@_check_chapsbefore:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l_@@_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abschap } { \l_@@_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abschap } { \l_@@_ref_int }
+      \bool_lazy_and:nnTF
+        { \l_@@_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l_@@_lbl_int } < { \l_@@_ref_int } &&
+          ! \int_compare_p:nNn { \l_@@_lbl_int } = { 0 } &&
+          ! \int_compare_p:nNn { \l_@@_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \subsubsection{Section}
+%
+% \begin{macro}
+%   {
+%     \@@_check_thissec:nn ,
+%     \@@_check_nextsec:nn ,
+%     \@@_check_prevsec:nn ,
+%     \@@_check_secsafter:nn ,
+%     \@@_check_secsbefore:nn
+%   }
+%    \begin{macrocode}
+\prg_new_conditional:Npnn \@@_check_thissec:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l_@@_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abssec  } { \l_@@_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abssec  } { \l_@@_ref_int }
+      \zrefcheck_get_asint:nnn {#1} { abschap } { \l_@@_lbl_b_int }
+      \zrefcheck_get_asint:nnn {#2} { abschap } { \l_@@_ref_b_int }
+      \bool_lazy_and:nnTF
+        { \l_@@_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l_@@_lbl_b_int } = { \l_@@_ref_b_int } &&
+          \int_compare_p:nNn
+            { \l_@@_lbl_int } = { \l_@@_ref_int } &&
+%    \end{macrocode}
+% `0' is the default value of \texttt{abssec} property, and means here no
+% \cs{section} has yet been issued since its counter has been reset, which
+% occurs at the beginning of the document and at every chapter.  Hence, as is
+% the case for chapters, `0' is just ``not a section''.  The same observation
+% about the need of the ``current'' section to exist to be able to refer to a
+% ``future'' one also holds.  This comment extends to all section checks.
+%    \begin{macrocode}
+          ! \int_compare_p:nNn { \l_@@_lbl_int } = { 0 } &&
+          ! \int_compare_p:nNn { \l_@@_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \@@_check_nextsec:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l_@@_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abssec  } { \l_@@_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abssec  } { \l_@@_ref_int }
+      \zrefcheck_get_asint:nnn {#1} { abschap } { \l_@@_lbl_b_int }
+      \zrefcheck_get_asint:nnn {#2} { abschap } { \l_@@_ref_b_int }
+      \bool_lazy_and:nnTF
+        { \l_@@_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l_@@_lbl_b_int } = { \l_@@_ref_b_int } &&
+          \int_compare_p:nNn
+            { \l_@@_lbl_int } = { \l_@@_ref_int + 1 } &&
+          ! \int_compare_p:nNn { \l_@@_lbl_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \@@_check_prevsec:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l_@@_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abssec  } { \l_@@_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abssec  } { \l_@@_ref_int }
+      \zrefcheck_get_asint:nnn {#1} { abschap } { \l_@@_lbl_b_int }
+      \zrefcheck_get_asint:nnn {#2} { abschap } { \l_@@_ref_b_int }
+      \bool_lazy_and:nnTF
+        { \l_@@_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l_@@_lbl_b_int } = { \l_@@_ref_b_int } &&
+          \int_compare_p:nNn
+            { \l_@@_lbl_int } = { \l_@@_ref_int - 1 } &&
+          ! \int_compare_p:nNn { \l_@@_lbl_int } = { 0 } &&
+          ! \int_compare_p:nNn { \l_@@_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \@@_check_secsafter:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l_@@_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abssec  } { \l_@@_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abssec  } { \l_@@_ref_int }
+      \zrefcheck_get_asint:nnn {#1} { abschap } { \l_@@_lbl_b_int }
+      \zrefcheck_get_asint:nnn {#2} { abschap } { \l_@@_ref_b_int }
+      \bool_lazy_and:nnTF
+        { \l_@@_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l_@@_lbl_b_int } = { \l_@@_ref_b_int } &&
+          \int_compare_p:nNn
+            { \l_@@_lbl_int } > { \l_@@_ref_int } &&
+          ! \int_compare_p:nNn { \l_@@_lbl_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \@@_check_secsbefore:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l_@@_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abssec  } { \l_@@_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abssec  } { \l_@@_ref_int }
+      \zrefcheck_get_asint:nnn {#1} { abschap } { \l_@@_lbl_b_int }
+      \zrefcheck_get_asint:nnn {#2} { abschap } { \l_@@_ref_b_int }
+      \bool_lazy_and:nnTF
+        { \l_@@_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l_@@_lbl_b_int } = { \l_@@_ref_b_int } &&
+          \int_compare_p:nNn
+            { \l_@@_lbl_int } < { \l_@@_ref_int } &&
+          ! \int_compare_p:nNn { \l_@@_lbl_int } = { 0 } &&
+          ! \int_compare_p:nNn { \l_@@_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+%    \begin{macrocode}
+%</package>
+%    \end{macrocode}
+%
+% \PrintIndex
+%
+% \end{implementation}
+%


Property changes on: trunk/Master/texmf-dist/source/latex/zref-check/zref-check.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/zref-check/zref-check.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/zref-check/zref-check.ins	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/zref-check/zref-check.ins	2021-08-05 20:47:40 UTC (rev 60171)
@@ -0,0 +1,98 @@
+% \iffalse meta-comment
+%
+% File: zref-check.ins
+%
+% This file is part of the LaTeX package "zref-check".
+%
+% Copyright (C) 2021  Gustavo Barros
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version.  The latest version
+% of this license is in the file:
+%
+%    https://www.latex-project.org/lppl.txt
+%
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+%
+% This work is "maintained" (as per LPPL maintenance status) by
+% Gustavo Barros.
+%
+% This work consists of the files zref-check.dtx,
+%                                 zref-check.ins,
+%                                 zref-check.tex,
+%                                 zref-check-code.tex,
+%           and the derived files zref-check.sty and
+%                                 zref-check.pdf,
+%                                 zref-check-code.pdf.
+%
+% The released version of this package is available from CTAN.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the package can be found at
+%
+%    https://github.com/gusbrs/zref-check
+%
+% for those people who are interested.
+%
+% -----------------------------------------------------------------------
+%
+% \fi
+
+\input l3docstrip.tex
+
+\keepsilent
+
+\askforoverwritefalse
+
+\preamble
+
+This file was generated from file(s) of the LaTeX package "zref-check".
+
+Copyright (C) 2021  Gustavo Barros
+
+It may be distributed and/or modified under the conditions of the
+LaTeX Project Public License (LPPL), either version 1.3c of this
+license or (at your option) any later version.  The latest version
+of this license is in the file:
+
+   https://www.latex-project.org/lppl.txt
+
+and version 1.3 or later is part of all distributions of LaTeX
+version 2005/12/01 or later.
+
+
+This work is "maintained" (as per LPPL maintenance status) by
+  Gustavo Barros.
+
+This work consists of the files zref-check.dtx,
+                                zref-check.ins,
+                                zref-check.tex,
+                                zref-check-code.tex,
+          and the derived files zref-check.sty and
+                                zref-check.pdf,
+                                zref-check-code.pdf.
+
+The released version of this package is available from CTAN.
+
+-----------------------------------------------------------------------
+
+The development version of the package can be found at
+
+   https://github.com/gusbrs/zref-check
+
+for those people who are interested.
+
+-----------------------------------------------------------------------
+
+\endpreamble
+
+\postamble
+\endpostamble
+
+\generate{\file{zref-check.sty}{\from{zref-check.dtx}{package}}}
+
+\endbatchfile

Added: trunk/Master/texmf-dist/tex/latex/zref-check/zref-check.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/zref-check/zref-check.sty	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/zref-check/zref-check.sty	2021-08-05 20:47:40 UTC (rev 60171)
@@ -0,0 +1,962 @@
+%%
+%% This is file `zref-check.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% zref-check.dtx  (with options: `package')
+%% 
+%% This file was generated from file(s) of the LaTeX package "zref-check".
+%% 
+%% Copyright (C) 2021  Gustavo Barros
+%% 
+%% It may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License (LPPL), either version 1.3c of this
+%% license or (at your option) any later version.  The latest version
+%% of this license is in the file:
+%% 
+%%    https://www.latex-project.org/lppl.txt
+%% 
+%% and version 1.3 or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%% 
+%% 
+%% This work is "maintained" (as per LPPL maintenance status) by
+%%   Gustavo Barros.
+%% 
+%% This work consists of the files zref-check.dtx,
+%%                                 zref-check.ins,
+%%                                 zref-check.tex,
+%%                                 zref-check-code.tex,
+%%           and the derived files zref-check.sty and
+%%                                 zref-check.pdf,
+%%                                 zref-check-code.pdf.
+%% 
+%% The released version of this package is available from CTAN.
+%% 
+%% -----------------------------------------------------------------------
+%% 
+%% The development version of the package can be found at
+%% 
+%%    https://github.com/gusbrs/zref-check
+%% 
+%% for those people who are interested.
+%% 
+%% -----------------------------------------------------------------------
+%% 
+\providecommand\IfFormatAtLeastTF{\@ifl at t@r\fmtversion}
+\IfFormatAtLeastTF{2021-06-01}
+  {}
+  {%
+    \PackageError{zref-check}{LaTeX kernel too old}
+      {%
+        'zref-check' requires a LaTeX kernel newer than 2021-06-01.%
+        \MessageBreak Loading will abort!%
+      }%
+    \endinput
+  }%
+\ProvidesExplPackage {zref-check} {2021-08-04} {0.1.0}
+  {Flexible cross-references with contextual checks based on zref}
+\RequirePackage { zref-user }
+\RequirePackage { zref-abspage }
+\RequirePackage { ifdraft }
+\int_new:N \g__zrefcheck_abschap_int
+\int_new:N \g__zrefcheck_abssec_int
+\AddToHook { cmd / chapter / before }
+  {
+    \int_gincr:N \g__zrefcheck_abschap_int
+    \int_zero:N \g__zrefcheck_abssec_int
+  }
+\zref at newprop { abschap } [0] { \int_use:N \g__zrefcheck_abschap_int }
+\zref at addprop \ZREF at mainlist { abschap }
+\AddToHook { cmd / section / before }
+  { \int_gincr:N \g__zrefcheck_abssec_int }
+\zref at newprop { abssec } [0] { \int_use:N \g__zrefcheck_abssec_int }
+\zref at addprop \ZREF at mainlist { abssec }
+\zref at newlist { zrefcheck }
+\zref at addprops { zrefcheck }
+  {
+    abspage ,
+    abschap ,
+    abssec ,
+    page
+  }
+\cs_new:Npn \__zrefcheck_message:nnnn #1#2#3#4
+  {
+    \use:c { msg_ \l__zrefcheck_msglevel_tl :nnnnn }
+      { zref-check } {#1} {#2} {#3} {#4}
+  }
+\cs_generate_variant:Nn \__zrefcheck_message:nnnn { nnnx }
+\msg_new:nnn { zref-check } { check-failed }
+  {
+    Failed~check~'#1'~for~label~'#2' \iow_newline:
+    on~page~#3~on~input~line~\msg_line_number:.
+  }
+\msg_new:nnn { zref-check } { double-check }
+  {
+    Double-check~'#1'~for~label~'#2' \iow_newline:
+    on~page~#3~on~input~line~\msg_line_number:.
+  }
+\msg_new:nnn { zref-check } { check-missing }
+  { Check~'#1'~not~defined~on~input~line~\msg_line_number:. }
+\msg_new:nnn { zref-check } { property-undefined }
+  { Property~'#1'~not~defined~on~input~line~\msg_line_number:. }
+\msg_new:nnn { zref-check } { property-not-in-label }
+  { Label~'#1'~has~no~property~'#2'~on~input~line~\msg_line_number:. }
+\msg_new:nnn { zref-check } { property-not-integer }
+  {
+    Property~'#1'~for~label~'#2'~not~an~integer \iow_newline:
+    on~input~line~\msg_line_number:.
+  }
+\msg_new:nnn { zref-check } { hyperref-preamble-only }
+  {
+    Option~'hyperref'~only~available~in~the~preamble. \iow_newline:
+    Use~the~starred~version~of~'\noexpand\zcheck'~instead.
+  }
+\msg_new:nnn { zref-check } { missing-hyperref }
+  { Missing~'hyperref'~package. \iow_newline: Setting~'hyperref=false'. }
+\msg_new:nnn { zref-check } { ignore-document-only }
+  {
+    Option~'ignore'~only~available~in~the~document. \iow_newline:
+    Use~option~'msglevel'~instead.
+  }
+\msg_new:nnn { zref-check } { option-preamble-only }
+  {
+    Option~'#1'~only~available~in~the~preamble \iow_newline:
+    on~input~line~\msg_line_number:.
+  }
+\msg_new:nnn { zref-check } { closerange-not-positive-integer }
+  {
+    Option~'closerange'~not~a~positive~integer \iow_newline:
+    on~input~line~\msg_line_number:.~Using~default~value.
+  }
+\msg_new:nnn { zref-check } { labelcmd-undefined }
+  {
+    Control~sequence~named~'#1'~used~in~option~'labelcmd'~is~not~defined.~
+    Using~default~value.
+  }
+\cs_new_eq:NN \__zrefcheck_int_to_roman:w \__int_to_roman:w
+\prg_new_conditional:Npnn \__zrefcheck_is_integer:n #1 { p, T , F , TF }
+  {
+    \tl_if_empty:oTF {#1}
+      { \prg_return_false: }
+      {
+        \tl_if_empty:oTF { \__zrefcheck_int_to_roman:w -0#1 }
+          { \prg_return_true:  }
+          { \prg_return_false: }
+      }
+  }
+\prg_new_protected_conditional:Npnn \__zrefcheck_is_integer_rgx:n #1 { TF }
+  {
+    \regex_match:nnTF { \A\d+\Z } {#1}
+      { \prg_return_true:  }
+      { \prg_return_false: }
+  }
+\bool_new:N \l__zrefcheck_use_hyperref_bool
+\bool_new:N \l__zrefcheck_warn_hyperref_bool
+\keys_define:nn { zref-check }
+  {
+    hyperref .choice: ,
+    hyperref / auto .code:n =
+      {
+        \bool_set_true:N \l__zrefcheck_use_hyperref_bool
+        \bool_set_false:N \l__zrefcheck_warn_hyperref_bool
+      } ,
+    hyperref / true .code:n =
+      {
+        \bool_set_true:N \l__zrefcheck_use_hyperref_bool
+        \bool_set_true:N \l__zrefcheck_warn_hyperref_bool
+      } ,
+    hyperref / false .code:n =
+      {
+        \bool_set_false:N \l__zrefcheck_use_hyperref_bool
+        \bool_set_false:N \l__zrefcheck_warn_hyperref_bool
+      } ,
+    hyperref .initial:n = auto ,
+    hyperref .default:n = auto
+  }
+\AtBeginDocument
+  {
+    \@ifpackageloaded { hyperref }
+      {
+        \bool_if:NT \l__zrefcheck_use_hyperref_bool
+          {
+            \RequirePackage { zref-hyperref }
+            \zref at addprop { zrefcheck } { anchor }
+          }
+      }
+      {
+        \bool_if:NT \l__zrefcheck_warn_hyperref_bool
+          { \msg_warning:nn { zref-check } { missing-hyperref } }
+        \bool_set_false:N \l__zrefcheck_use_hyperref_bool
+      }
+    \keys_define:nn { zref-check }
+      {
+        hyperref .code:n =
+          { \msg_warning:nn { zref-check } { hyperref-preamble-only } }
+      }
+  }
+\tl_new:N \l__zrefcheck_msglevel_tl
+\keys_define:nn { zref-check }
+  {
+    msglevel .choice: ,
+    msglevel / warn .code:n =
+      { \tl_set:Nn \l__zrefcheck_msglevel_tl { warning } } ,
+    msglevel / info .code:n =
+      { \tl_set:Nn \l__zrefcheck_msglevel_tl { info } } ,
+    msglevel / none .code:n =
+      { \tl_set:Nn \l__zrefcheck_msglevel_tl { none } } ,
+    msglevel / obeydraft .code:n =
+      {
+        \ifdraft
+          { \tl_set:Nn \l__zrefcheck_msglevel_tl { info } }
+          { \tl_set:Nn \l__zrefcheck_msglevel_tl { warning } }
+      } ,
+    msglevel / obeyfinal .code:n =
+      {
+        \ifoptionfinal
+          { \tl_set:Nn \l__zrefcheck_msglevel_tl { warning } }
+          { \tl_set:Nn \l__zrefcheck_msglevel_tl { info } }
+      } ,
+    msglevel .value_required:n = true ,
+    msglevel .initial:n = warn ,
+    ignore .code:n =
+      { \msg_warning:nn { zref-check } { ignore-document-only } } ,
+    ignore .value_forbidden:n = true
+  }
+\AtBeginDocument
+  {
+    \keys_define:nn { zref-check }
+      { ignore .meta:n = { msglevel = none } }
+  }
+\bool_new:N \l__zrefcheck_msgonpage_bool
+\keys_define:nn { zref-check }
+  {
+    onpage .choice: ,
+    onpage / labelseq .code:n =
+      {
+        \bool_set_false:N \l__zrefcheck_msgonpage_bool
+      } ,
+    onpage / msg .code:n =
+      {
+        \bool_set_true:N \l__zrefcheck_msgonpage_bool
+      } ,
+    onpage / obeydraft .code:n =
+      {
+        \ifdraft
+          { \bool_set_false:N \l__zrefcheck_msgonpage_bool }
+          { \bool_set_true:N \l__zrefcheck_msgonpage_bool }
+      } ,
+    onpage / obeyfinal .code:n =
+      {
+        \ifoptionfinal
+          { \bool_set_true:N \l__zrefcheck_msgonpage_bool }
+          { \bool_set_false:N \l__zrefcheck_msgonpage_bool }
+      } ,
+    onpage .value_required:n = true ,
+    onpage .initial:n = labelseq
+  }
+\int_new:N \l__zrefcheck_close_range_int
+\keys_define:nn { zref-check }
+  {
+    closerange .code:n =
+      {
+        \__zrefcheck_is_integer_rgx:nTF {#1}
+          { \int_set:Nn \l__zrefcheck_close_range_int { \int_eval:n {#1} } }
+          {
+            \msg_warning:nn { zref-check } { closerange-not-positive-integer }
+            \int_set:Nn \l__zrefcheck_close_range_int { 5 }
+          }
+      } ,
+    closerange .value_required:n = true ,
+    closerange .initial:n = 5
+  }
+\tl_new:N \l__zrefcheck_target_label_tl
+\bool_new:N \l__zrefcheck_target_label_bool
+\keys_define:nn { zref-check }
+  {
+    labelcmd .code:n =
+      {
+        \tl_set:Nn \l__zrefcheck_target_label_tl {#1}
+        \bool_set_true:N \l__zrefcheck_target_label_bool
+      } ,
+    labelcmd .value_required:n = true ,
+  }
+\cs_new:Npn \__zrefcheck_target_label:n #1
+  { \zref at labelbylist {#1} { zrefcheck } }
+\AtBeginDocument
+  {
+    \bool_if:NT \l__zrefcheck_target_label_bool
+      {
+        \tl_if_blank:VT \l__zrefcheck_target_label_tl
+          { \tl_clear:N \l__zrefcheck_target_label_tl }
+        \cs_if_exist:cTF { \l__zrefcheck_target_label_tl }
+          {
+            \cs_set:Npx \__zrefcheck_target_label:n #1
+              {
+                \exp_not:o
+                  { \cs:w \l__zrefcheck_target_label_tl \cs_end: }
+                  {#1}
+              }
+          }
+          {
+            \exp_args:NnnV \msg_warning:nnn { zref-check }
+              { labelcmd-undefined } { \l__zrefcheck_target_label_tl }
+          }
+      }
+    \keys_define:nn { zref-check }
+      {
+        labelcmd .code:n =
+          {
+            \msg_warning:nnn { zref-check }
+              { option-preamble-only } { labelcmd }
+          }
+      }
+  }
+\RequirePackage { l3keys2e }
+\ProcessKeysOptions { zref-check }
+\NewDocumentCommand \zrefchecksetup { m }
+  { \keys_set:nn { zref-check } {#1} }
+\prop_new:N \g__zrefcheck_auxfile_lblseq_prop
+\tl_set:Nn \g_tmpa_tl { \c_sys_jobname_str .aux }
+\file_if_exist:nT { \g_tmpa_tl }
+  {
+    \ior_open:Nn \g_tmpa_ior { \g_tmpa_tl }
+    \group_begin:
+      \int_zero:N \l_tmpa_int
+      \tl_clear:N \l_tmpa_tl
+      \tl_clear:N \l_tmpb_tl
+      \bool_set_false:N \l_tmpa_bool
+      \ior_map_variable:NNn \g_tmpa_ior \l_tmpa_tl
+        {
+          \tl_map_variable:NNn \l_tmpa_tl \l_tmpb_tl
+            {
+              \tl_if_eq:NnTF \l_tmpb_tl { \zref at newlabel }
+                {
+                  \bool_set_true:N \l_tmpa_bool
+                }
+                {
+                  \bool_if:NTF \l_tmpa_bool
+                    {
+                      \bool_set_false:N \l_tmpa_bool
+                      \int_incr:N \l_tmpa_int
+                      \prop_gput:Nxx \g__zrefcheck_auxfile_lblseq_prop
+                        { \l_tmpb_tl } { \int_use:N \l_tmpa_int }
+                    }
+                    {
+                      \tl_map_break:
+                    }
+                }
+            }
+        }
+    \group_end:
+    \ior_close:N \g_tmpa_ior
+  }
+\begingroup
+  \let \@addtoreset \ltx at gobbletwo
+  \newcounter { zrefcheck }
+\endgroup
+\setcounter { zrefcheck } { 0 }
+\cs_new:Npn \__zrefcheck_check_lblfmt:n #1 { zrefcheck@ \int_use:N #1 }
+\cs_new:Npn \__zrefcheck_end_lblfmt:n #1 { #1 @zrefcheck }
+\cs_new:Npn \zrefcheck_get_astl:nnn #1#2#3
+  {
+    \tl_clear:N #3
+    \tl_if_eq:nnTF {#2} { lblseq }
+      {
+        \prop_get:NnNF \g__zrefcheck_auxfile_lblseq_prop {#1} #3
+          {
+            \msg_warning:nnnn { zref-check }
+              { property-not-in-label } {#1} {#2}
+          }
+      }
+      {
+        \zref at ifrefundefined {#1}
+          {}
+          {
+            \zref at ifpropundefined {#2}
+              { \msg_warning:nnnn { zref-check } { property-undefined } {#2} }
+              {
+                \zref at ifrefcontainsprop {#1} {#2}
+                  {
+                    \tl_set:Nx #3
+                      { \zref at extractdefault {#1} {#2} { \c_empty_tl } }
+                  }
+                  {
+                    \msg_warning:nnnn
+                      { zref-check } { property-not-in-label } {#1} {#2}
+                  }
+              }
+          }
+      }
+  }
+\bool_new:N \l__zrefcheck_integer_bool
+\tl_new:N \l__zrefcheck_propval_tl
+\cs_new:Npn \zrefcheck_get_asint:nnn #1#2#3
+  {
+    \zrefcheck_get_astl:nnn {#1} {#2} { \l__zrefcheck_propval_tl }
+    \__zrefcheck_is_integer:nTF { \l__zrefcheck_propval_tl }
+      {
+        \int_set:Nn #3 { \int_eval:n { \l__zrefcheck_propval_tl } }
+      }
+      {
+        \bool_set_false:N \l__zrefcheck_integer_bool
+        \zref at ifrefundefined {#1}
+          { }
+          {
+            \msg_warning:nnnn { zref-check }
+              { property-not-integer } {#2} {#1}
+          }
+      }
+  }
+\NewDocumentCommand \zcheck
+  { s O { } > { \SplitList { , } } m > { \SplitList { , } } O { } m }
+  { \zref at wrapper@babel \__zrefcheck_zcheck:nnnnn {#3} {#1} {#2} {#4} {#5} }
+\int_new:N \g__zrefcheck_id_int
+\tl_new:N \l__zrefcheck_checkbeg_tl
+\tl_new:N \l__zrefcheck_checkend_tl
+\tl_new:N \l__zrefcheck_link_label_tl
+\tl_new:N \l__zrefcheck_link_anchor_tl
+\bool_new:N \l__zrefcheck_link_star_tl
+\cs_new:Npn \__zrefcheck_zcheck:nnnnn #1#2#3#4#5
+  {
+    \group_begin:
+      \keys_set:nn { zref-check } {#3}
+      \int_gincr:N \g__zrefcheck_id_int
+      \tl_set:Nx \l__zrefcheck_checkbeg_tl
+        { \__zrefcheck_check_lblfmt:n { \g__zrefcheck_id_int } }
+      \tl_set:Nx \l__zrefcheck_checkend_tl
+        { \__zrefcheck_end_lblfmt:n { \l__zrefcheck_checkbeg_tl } }
+      \zref at labelbylist { \l__zrefcheck_checkbeg_tl } { zrefcheck }
+      \tl_set:Nn \l__zrefcheck_link_label_tl { \tl_head:n {#1} }
+      \bool_set:Nn \l__zrefcheck_link_star_tl {#2}
+      \zref at ifrefundefined { \l__zrefcheck_link_label_tl }
+        {#5}
+        {
+          \bool_if:nTF
+            {
+              \l__zrefcheck_use_hyperref_bool &&
+              ! \l__zrefcheck_link_star_tl
+            }
+            {
+              \exp_args:Nx \zrefcheck_get_astl:nnn
+                { \l__zrefcheck_link_label_tl }
+                { anchor } { \l__zrefcheck_link_anchor_tl }
+              \hyperlink { \l__zrefcheck_link_anchor_tl } {#5}
+            }
+            {#5}
+        }
+      \zref at labelbylist { \l__zrefcheck_checkend_tl } { zrefcheck }
+      \tl_map_function:nN {#1} \zref at refused
+      \__zrefcheck_run_checks:nnV {#4} {#1} { \l__zrefcheck_checkbeg_tl }
+    \group_end:
+  }
+\NewDocumentCommand \zctarget { m +m }
+  {
+    \group_begin:
+    \refstepcounter { zrefcheck }
+    \zref at wrapper@babel \__zrefcheck_target_label:n {#1}
+    #2
+    \zref at wrapper@babel
+      \zref at labelbylist { \__zrefcheck_end_lblfmt:n {#1} } { zrefcheck }
+    \group_end:
+  }
+\NewDocumentEnvironment {zcregion} { m }
+  {
+    \refstepcounter { zrefcheck }
+    \zref at wrapper@babel \__zrefcheck_target_label:n {#1}
+  }
+  {
+    \zref at wrapper@babel
+      \zref at labelbylist { \__zrefcheck_end_lblfmt:n {#1} } { zrefcheck }
+  }
+\cs_new:Npn \__zrefcheck_run_checks:nnn #1#2#3
+  {
+    \group_begin:
+      \tl_map_inline:nn {#2}
+        {
+          \tl_map_inline:nn {#1}
+            { \__zrefcheck_do_check:nnn {####1} {##1} {#3} }
+        }
+    \group_end:
+  }
+\cs_generate_variant:Nn \__zrefcheck_run_checks:nnn { nnV }
+\bool_new:N \l__zrefcheck_passedcheck_bool
+\bool_new:N \l__zrefcheck_onpage_bool
+\seq_new:N \c__zrefcheck_onpage_checks_seq
+\seq_set_from_clist:Nn \c__zrefcheck_onpage_checks_seq
+  { above , below , before , after }
+\cs_generate_variant:Nn \exp_args:Nnno { Nnoo }
+\cs_new:Npn \__zrefcheck_do_check:nnn #1#2#3
+  {
+    \group_begin:
+      \zref at ifrefundefined {#2}
+        {}
+        {
+          \tl_if_empty:nF {#1}
+            {
+              \bool_set_true:N \l__zrefcheck_passedcheck_bool
+              \bool_set_false:N \l__zrefcheck_onpage_bool
+              \cs_if_exist:cTF { __zrefcheck_check_ #1 :nnF }
+                {
+                  \use:c { __zrefcheck_check_ #1 :nnF }
+                    {#2} {#3}
+                    { \bool_set_false:N \l__zrefcheck_passedcheck_bool }
+                  \exp_args:Nnno \use:c { __zrefcheck_check_ #1 :nnF }
+                    {#2} { \__zrefcheck_end_lblfmt:n {#3} }
+                    { \bool_set_false:N \l__zrefcheck_passedcheck_bool }
+                  \zref at ifrefundefined { \__zrefcheck_end_lblfmt:n {#2} }
+                    {}
+                    {
+                      \exp_args:Nno \use:c { __zrefcheck_check_ #1 :nnF }
+                        { \__zrefcheck_end_lblfmt:n {#2} } {#3}
+                        { \bool_set_false:N \l__zrefcheck_passedcheck_bool }
+                      \exp_args:Nnoo \use:c { __zrefcheck_check_ #1 :nnF }
+                        { \__zrefcheck_end_lblfmt:n {#2} }
+                        { \__zrefcheck_end_lblfmt:n {#3} }
+                        { \bool_set_false:N \l__zrefcheck_passedcheck_bool }
+                    }
+                  \seq_if_in:NnT \c__zrefcheck_onpage_checks_seq {#1}
+                    {
+                      \__zrefcheck_check_thispage:nnT
+                        {#2} {#3}
+                        { \bool_set_true:N \l__zrefcheck_onpage_bool }
+                      \__zrefcheck_check_thispage:nnT
+                        {#2} { \__zrefcheck_end_lblfmt:n {#3} }
+                        { \bool_set_true:N \l__zrefcheck_onpage_bool }
+                      \zref at ifrefundefined { \__zrefcheck_end_lblfmt:n {#2} }
+                        {}
+                        {
+                          \__zrefcheck_check_thispage:nnT
+                            { \__zrefcheck_end_lblfmt:n {#2} } {#3}
+                            { \bool_set_true:N \l__zrefcheck_onpage_bool }
+                          \__zrefcheck_check_thispage:nnT
+                            { \__zrefcheck_end_lblfmt:n {#2} }
+                            { \__zrefcheck_end_lblfmt:n {#3} }
+                            { \bool_set_true:N \l__zrefcheck_onpage_bool }
+                        }
+                    }
+                  \bool_if:NTF \l__zrefcheck_passedcheck_bool
+                    {
+                      \bool_if:nT
+                        {
+                          \l__zrefcheck_msgonpage_bool &&
+                          \l__zrefcheck_onpage_bool
+                        }
+                        {
+                          \__zrefcheck_message:nnnx { double-check } {#1} {#2}
+                            { \zref at extractdefault {#3} {page} {'unknown'} }
+                        }
+                    }
+                    {
+                      \__zrefcheck_message:nnnx { check-failed } {#1} {#2}
+                        { \zref at extractdefault {#3} {page} {'unknown'} }
+                    }
+                }
+                { \msg_warning:nnn { zref-check } { check-missing } {#1} }
+            }
+        }
+    \group_end:
+  }
+\int_new:N \l__zrefcheck_lbl_int
+\int_new:N \l__zrefcheck_ref_int
+\int_new:N \l__zrefcheck_lbl_b_int
+\int_new:N \l__zrefcheck_ref_b_int
+\prg_new_conditional:Npnn \__zrefcheck_check_thispage:nn #1#2 { T , F , TF }
+  {
+    \group_begin:
+      \bool_set_true:N \l__zrefcheck_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abspage } { \l__zrefcheck_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abspage } { \l__zrefcheck_ref_int }
+      \bool_lazy_and:nnTF
+        { \l__zrefcheck_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l__zrefcheck_lbl_int } = { \l__zrefcheck_ref_int } &&
+            ! \int_compare_p:nNn { \l__zrefcheck_lbl_int } = { 0 } &&
+            ! \int_compare_p:nNn { \l__zrefcheck_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \__zrefcheck_check_above:nn #1#2 { F , TF }
+  {
+    \group_begin:
+      \__zrefcheck_check_thispage:nnTF {#1} {#2}
+        {
+          \bool_set_true:N \l__zrefcheck_integer_bool
+          \zrefcheck_get_asint:nnn {#1} { lblseq } { \l__zrefcheck_lbl_int }
+          \zrefcheck_get_asint:nnn {#2} { lblseq } { \l__zrefcheck_ref_int }
+          \bool_lazy_and:nnTF
+            { \l__zrefcheck_integer_bool }
+            {
+              \int_compare_p:nNn
+                { \l__zrefcheck_lbl_int } < { \l__zrefcheck_ref_int } &&
+              ! \int_compare_p:nNn { \l__zrefcheck_lbl_int } = { 0 } &&
+              ! \int_compare_p:nNn { \l__zrefcheck_ref_int } = { 0 }
+            }
+            { \group_insert_after:N \prg_return_true:  }
+            { \group_insert_after:N \prg_return_false: }
+        }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \__zrefcheck_check_below:nn #1#2 { F , TF }
+  {
+    \__zrefcheck_check_thispage:nnTF {#1} {#2}
+      {
+        \__zrefcheck_check_above:nnTF {#1} {#2}
+          { \prg_return_false: }
+          { \prg_return_true:  }
+      }
+      { \prg_return_false: }
+  }
+\prg_new_conditional:Npnn \__zrefcheck_check_before:nn #1#2 { F }
+  {
+    \__zrefcheck_check_pagesbefore:nnTF {#1} {#2}
+      { \prg_return_true: }
+      {
+        \__zrefcheck_check_above:nnTF {#1} {#2}
+          { \prg_return_true:  }
+          { \prg_return_false: }
+      }
+  }
+\prg_new_conditional:Npnn \__zrefcheck_check_after:nn #1#2 { F }
+  {
+    \__zrefcheck_check_pagesafter:nnTF {#1} {#2}
+      { \prg_return_true: }
+      {
+        \__zrefcheck_check_below:nnTF {#1} {#2}
+          { \prg_return_true:  }
+          { \prg_return_false: }
+      }
+  }
+\prg_new_conditional:Npnn \__zrefcheck_check_nextpage:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l__zrefcheck_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abspage } { \l__zrefcheck_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abspage } { \l__zrefcheck_ref_int }
+      \bool_lazy_and:nnTF
+        { \l__zrefcheck_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l__zrefcheck_lbl_int } = { \l__zrefcheck_ref_int + 1 } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_lbl_int } = { 0 } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \__zrefcheck_check_prevpage:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l__zrefcheck_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abspage } { \l__zrefcheck_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abspage } { \l__zrefcheck_ref_int }
+      \bool_lazy_and:nnTF
+        { \l__zrefcheck_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l__zrefcheck_lbl_int } = { \l__zrefcheck_ref_int - 1 } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_lbl_int } = { 0 } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \__zrefcheck_check_pagesbefore:nn #1#2 { F , TF }
+  {
+    \group_begin:
+      \bool_set_true:N \l__zrefcheck_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abspage } { \l__zrefcheck_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abspage } { \l__zrefcheck_ref_int }
+      \bool_lazy_and:nnTF
+        { \l__zrefcheck_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l__zrefcheck_lbl_int } < { \l__zrefcheck_ref_int } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_lbl_int } = { 0 } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\cs_new_eq:NN \__zrefcheck_check_ppbefore:nnF \__zrefcheck_check_pagesbefore:nnF
+\prg_new_conditional:Npnn \__zrefcheck_check_pagesafter:nn #1#2 { F , TF }
+  {
+    \group_begin:
+      \bool_set_true:N \l__zrefcheck_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abspage } { \l__zrefcheck_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abspage } { \l__zrefcheck_ref_int }
+      \bool_lazy_and:nnTF
+        { \l__zrefcheck_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l__zrefcheck_lbl_int } > { \l__zrefcheck_ref_int } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_lbl_int } = { 0 } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\cs_new_eq:NN \__zrefcheck_check_ppafter:nnF \__zrefcheck_check_pagesafter:nnF
+\prg_new_conditional:Npnn \__zrefcheck_check_facing:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l__zrefcheck_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abspage } { \l__zrefcheck_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abspage } { \l__zrefcheck_ref_int }
+      \bool_lazy_and:nnTF
+        { \l__zrefcheck_integer_bool }
+        {
+          \legacy_if_p:n { @twoside } &&
+          (
+            (
+              \int_if_odd_p:n { \l__zrefcheck_ref_int } &&
+              \int_compare_p:nNn
+                { \l__zrefcheck_lbl_int } = { \l__zrefcheck_ref_int - 1 }
+            ) ||
+            (
+              \int_if_even_p:n { \l__zrefcheck_ref_int } &&
+              \int_compare_p:nNn
+                { \l__zrefcheck_lbl_int } = { \l__zrefcheck_ref_int + 1 }
+            )
+          ) &&
+          ! \int_compare_p:nNn { \l__zrefcheck_lbl_int } = { 0 } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \__zrefcheck_check_close:nn #1#2 { F , TF }
+  {
+    \group_begin:
+      \bool_set_true:N \l__zrefcheck_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abspage } { \l__zrefcheck_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abspage } { \l__zrefcheck_ref_int }
+      \bool_lazy_and:nnTF
+        { \l__zrefcheck_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \int_abs:n { \l__zrefcheck_lbl_int - \l__zrefcheck_ref_int } }
+            <
+            { \l__zrefcheck_close_range_int + 1 } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_lbl_int } = { 0 } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \__zrefcheck_check_far:nn #1#2 { F }
+  {
+    \__zrefcheck_check_close:nnTF {#1} {#2}
+      { \prg_return_false: }
+      { \prg_return_true:  }
+  }
+\prg_new_conditional:Npnn \__zrefcheck_check_thischap:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l__zrefcheck_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abschap } { \l__zrefcheck_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abschap } { \l__zrefcheck_ref_int }
+      \bool_lazy_and:nnTF
+        { \l__zrefcheck_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l__zrefcheck_lbl_int } = { \l__zrefcheck_ref_int } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_lbl_int } = { 0 } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \__zrefcheck_check_nextchap:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l__zrefcheck_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abschap } { \l__zrefcheck_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abschap } { \l__zrefcheck_ref_int }
+      \bool_lazy_and:nnTF
+        { \l__zrefcheck_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l__zrefcheck_lbl_int } = { \l__zrefcheck_ref_int + 1 } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_lbl_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \__zrefcheck_check_prevchap:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l__zrefcheck_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abschap } { \l__zrefcheck_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abschap } { \l__zrefcheck_ref_int }
+      \bool_lazy_and:nnTF
+        { \l__zrefcheck_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l__zrefcheck_lbl_int } = { \l__zrefcheck_ref_int - 1 } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_lbl_int } = { 0 } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \__zrefcheck_check_chapsafter:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l__zrefcheck_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abschap } { \l__zrefcheck_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abschap } { \l__zrefcheck_ref_int }
+      \bool_lazy_and:nnTF
+        { \l__zrefcheck_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l__zrefcheck_lbl_int } > { \l__zrefcheck_ref_int } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_lbl_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \__zrefcheck_check_chapsbefore:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l__zrefcheck_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abschap } { \l__zrefcheck_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abschap } { \l__zrefcheck_ref_int }
+      \bool_lazy_and:nnTF
+        { \l__zrefcheck_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l__zrefcheck_lbl_int } < { \l__zrefcheck_ref_int } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_lbl_int } = { 0 } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \__zrefcheck_check_thissec:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l__zrefcheck_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abssec  } { \l__zrefcheck_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abssec  } { \l__zrefcheck_ref_int }
+      \zrefcheck_get_asint:nnn {#1} { abschap } { \l__zrefcheck_lbl_b_int }
+      \zrefcheck_get_asint:nnn {#2} { abschap } { \l__zrefcheck_ref_b_int }
+      \bool_lazy_and:nnTF
+        { \l__zrefcheck_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l__zrefcheck_lbl_b_int } = { \l__zrefcheck_ref_b_int } &&
+          \int_compare_p:nNn
+            { \l__zrefcheck_lbl_int } = { \l__zrefcheck_ref_int } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_lbl_int } = { 0 } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \__zrefcheck_check_nextsec:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l__zrefcheck_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abssec  } { \l__zrefcheck_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abssec  } { \l__zrefcheck_ref_int }
+      \zrefcheck_get_asint:nnn {#1} { abschap } { \l__zrefcheck_lbl_b_int }
+      \zrefcheck_get_asint:nnn {#2} { abschap } { \l__zrefcheck_ref_b_int }
+      \bool_lazy_and:nnTF
+        { \l__zrefcheck_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l__zrefcheck_lbl_b_int } = { \l__zrefcheck_ref_b_int } &&
+          \int_compare_p:nNn
+            { \l__zrefcheck_lbl_int } = { \l__zrefcheck_ref_int + 1 } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_lbl_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \__zrefcheck_check_prevsec:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l__zrefcheck_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abssec  } { \l__zrefcheck_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abssec  } { \l__zrefcheck_ref_int }
+      \zrefcheck_get_asint:nnn {#1} { abschap } { \l__zrefcheck_lbl_b_int }
+      \zrefcheck_get_asint:nnn {#2} { abschap } { \l__zrefcheck_ref_b_int }
+      \bool_lazy_and:nnTF
+        { \l__zrefcheck_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l__zrefcheck_lbl_b_int } = { \l__zrefcheck_ref_b_int } &&
+          \int_compare_p:nNn
+            { \l__zrefcheck_lbl_int } = { \l__zrefcheck_ref_int - 1 } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_lbl_int } = { 0 } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \__zrefcheck_check_secsafter:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l__zrefcheck_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abssec  } { \l__zrefcheck_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abssec  } { \l__zrefcheck_ref_int }
+      \zrefcheck_get_asint:nnn {#1} { abschap } { \l__zrefcheck_lbl_b_int }
+      \zrefcheck_get_asint:nnn {#2} { abschap } { \l__zrefcheck_ref_b_int }
+      \bool_lazy_and:nnTF
+        { \l__zrefcheck_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l__zrefcheck_lbl_b_int } = { \l__zrefcheck_ref_b_int } &&
+          \int_compare_p:nNn
+            { \l__zrefcheck_lbl_int } > { \l__zrefcheck_ref_int } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_lbl_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+\prg_new_conditional:Npnn \__zrefcheck_check_secsbefore:nn #1#2 { F }
+  {
+    \group_begin:
+      \bool_set_true:N \l__zrefcheck_integer_bool
+      \zrefcheck_get_asint:nnn {#1} { abssec  } { \l__zrefcheck_lbl_int }
+      \zrefcheck_get_asint:nnn {#2} { abssec  } { \l__zrefcheck_ref_int }
+      \zrefcheck_get_asint:nnn {#1} { abschap } { \l__zrefcheck_lbl_b_int }
+      \zrefcheck_get_asint:nnn {#2} { abschap } { \l__zrefcheck_ref_b_int }
+      \bool_lazy_and:nnTF
+        { \l__zrefcheck_integer_bool }
+        {
+          \int_compare_p:nNn
+            { \l__zrefcheck_lbl_b_int } = { \l__zrefcheck_ref_b_int } &&
+          \int_compare_p:nNn
+            { \l__zrefcheck_lbl_int } < { \l__zrefcheck_ref_int } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_lbl_int } = { 0 } &&
+          ! \int_compare_p:nNn { \l__zrefcheck_ref_int } = { 0 }
+        }
+        { \group_insert_after:N \prg_return_true:  }
+        { \group_insert_after:N \prg_return_false: }
+    \group_end:
+  }
+%% 
+%%
+%% End of file `zref-check.sty'.


Property changes on: trunk/Master/texmf-dist/tex/latex/zref-check/zref-check.sty
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/tlpkg/bin/tlpkg-ctan-check
===================================================================
--- trunk/Master/tlpkg/bin/tlpkg-ctan-check	2021-08-05 20:47:05 UTC (rev 60170)
+++ trunk/Master/tlpkg/bin/tlpkg-ctan-check	2021-08-05 20:47:40 UTC (rev 60171)
@@ -859,7 +859,7 @@
     yinit-otf york-thesis youngtab yplan yquant ytableau
   zapfchan zapfding zbmath-review-template zebra-goodies zed-csp
     zhlineskip zhlipsum zhnumber zhmetrics zhmetrics-uptex zhspacing
-    ziffer zlmtt zootaxa-bst zref
+    ziffer zlmtt zootaxa-bst zref zref-check
     zwgetfdate zwpagelayout
     zxjafbfont zxjafont zxjatype zztex
 ); 

Modified: trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
===================================================================
--- trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc	2021-08-05 20:47:05 UTC (rev 60170)
+++ trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc	2021-08-05 20:47:40 UTC (rev 60171)
@@ -1387,5 +1387,6 @@
 depend zed-csp
 depend ziffer
 depend zref
+depend zref-check
 depend zwgetfdate
 depend zwpagelayout

Added: trunk/Master/tlpkg/tlpsrc/zref-check.tlpsrc
===================================================================


More information about the tex-live-commits mailing list.