summaryrefslogtreecommitdiff
path: root/Master
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2021-11-24 21:31:19 +0000
committerKarl Berry <karl@freefriends.org>2021-11-24 21:31:19 +0000
commitd1cb4d61e001c353e99cf0209daeb7e265e350c5 (patch)
tree5001e82104eca492dda3f8ffe60e281b668f1c20 /Master
parent2912d9e2b694d852f5d6812fe972ab65cf585b10 (diff)
zref-clever (24nov21)
git-svn-id: svn://tug.org/texlive/trunk@61145 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
-rw-r--r--Master/texmf-dist/doc/latex/zref-clever/CHANGELOG.md8
-rw-r--r--Master/texmf-dist/doc/latex/zref-clever/DEPENDS.txt5
-rw-r--r--Master/texmf-dist/doc/latex/zref-clever/MANIFEST.md350
-rw-r--r--Master/texmf-dist/doc/latex/zref-clever/README.md22
-rw-r--r--Master/texmf-dist/doc/latex/zref-clever/zref-clever-code.pdfbin0 -> 1035367 bytes
-rw-r--r--Master/texmf-dist/doc/latex/zref-clever/zref-clever-code.tex53
-rw-r--r--Master/texmf-dist/doc/latex/zref-clever/zref-clever.pdfbin0 -> 304271 bytes
-rw-r--r--Master/texmf-dist/doc/latex/zref-clever/zref-clever.tex2163
-rw-r--r--Master/texmf-dist/source/latex/zref-clever/zref-clever.dtx7161
-rw-r--r--Master/texmf-dist/source/latex/zref-clever/zref-clever.ins99
-rw-r--r--Master/texmf-dist/tex/latex/zref-clever/zref-clever-english.dict247
-rw-r--r--Master/texmf-dist/tex/latex/zref-clever/zref-clever-french.dict262
-rw-r--r--Master/texmf-dist/tex/latex/zref-clever/zref-clever-german.dict502
-rw-r--r--Master/texmf-dist/tex/latex/zref-clever/zref-clever-portuguese.dict276
-rw-r--r--Master/texmf-dist/tex/latex/zref-clever/zref-clever-spanish.dict262
-rw-r--r--Master/texmf-dist/tex/latex/zref-clever/zref-clever.sty3519
-rwxr-xr-xMaster/tlpkg/bin/tlpkg-ctan-check2
-rw-r--r--Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc1
-rw-r--r--Master/tlpkg/tlpsrc/zref-clever.tlpsrc0
19 files changed, 14931 insertions, 1 deletions
diff --git a/Master/texmf-dist/doc/latex/zref-clever/CHANGELOG.md b/Master/texmf-dist/doc/latex/zref-clever/CHANGELOG.md
new file mode 100644
index 00000000000..dc8ce5a3ebc
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/zref-clever/CHANGELOG.md
@@ -0,0 +1,8 @@
+# Changelog
+
+## [Unreleased](https://github.com/gusbrs/zref-clever/compare/v0.1.0-alpha...HEAD)
+
+## [v0.1.0-alpha]
+
+### Added
+- Initial release.
diff --git a/Master/texmf-dist/doc/latex/zref-clever/DEPENDS.txt b/Master/texmf-dist/doc/latex/zref-clever/DEPENDS.txt
new file mode 100644
index 00000000000..4b47b749558
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/zref-clever/DEPENDS.txt
@@ -0,0 +1,5 @@
+hard zref
+hard l3packages
+hard oberdiek
+soft hyperref
+soft zref-check
diff --git a/Master/texmf-dist/doc/latex/zref-clever/MANIFEST.md b/Master/texmf-dist/doc/latex/zref-clever/MANIFEST.md
new file mode 100644
index 00000000000..98f72887da7
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/zref-clever/MANIFEST.md
@@ -0,0 +1,350 @@
+# Manifest for zref-clever
+
+This file is a listing of all files considered to be part of this package.
+It is automatically generated with `texlua build.lua manifest`.
+
+
+## Repository manifest
+
+The following groups list the files included in the development repository of the package.
+Files listed with a ‘†’ marker are included in the TDS but not CTAN files, and files listed
+with ‘‡’ are included in both.
+
+### Source files
+
+These are source files for a number of purposes, including the `unpack` process which
+generates the installation files of the package. Additional files included here will also
+be installed for processing such as testing.
+
+* zref-clever.dtx ‡
+* zref-clever.ins ‡
+
+### Typeset documentation source files
+
+These files are typeset using LaTeX to produce the PDF documentation for the package.
+
+* zref-clever-code.tex ‡
+* zref-clever.tex ‡
+
+### Text files
+
+Plain text files included as documentation or metadata.
+
+* CHANGELOG.md ‡
+* MANIFEST.md ‡
+* README.md ‡
+* readme-ctan.md
+* DEPENDS.txt ‡
+
+### Derived files
+
+The files created by ‘unpacking’ the package sources. This typically includes
+`.sty` and `.cls` files created from DocStrip `.dtx` files.
+
+* zref-clever.sty †
+* zref-clever-english.dict †
+* zref-clever-french.dict †
+* zref-clever-german.dict †
+* zref-clever-portuguese.dict †
+* zref-clever-spanish.dict †
+
+### Typeset documents
+
+The output files (PDF, essentially) from typesetting the various source, demo,
+etc., package files.
+
+* zref-clever-code.pdf ‡
+* zref-clever.pdf ‡
+
+### Test files
+
+These files form the test suite for the package. `.lvt` or `.lte` files are the individual
+unit tests, and `.tlg` are the stored output for ensuring changes to the package produce
+the same output. These output files are sometimes shared and sometime specific for
+different engines (pdfTeX, XeTeX, LuaTeX, etc.).
+
+* zc-LanguageSetup01.lvt
+* zc-RefTypeSetup01.lvt
+* zc-class-article01.lvt
+* zc-class-book01.lvt
+* zc-class-memoir01.lvt
+* zc-class-report01.lvt
+* zc-class-scrartcl01.lvt
+* zc-class-scrbook01.lvt
+* zc-class-scrreprt01.lvt
+* zc-compat-amsmath01.lvt
+* zc-compat-appendices01.lvt
+* zc-compat-appendix01.lvt
+* zc-compat-breqn01.lvt
+* zc-compat-enumitem01.lvt
+* zc-compat-koma-script01.lvt
+* zc-compat-listings01.lvt
+* zc-compat-memoir01.lvt
+* zc-compat-subcaption01.lvt
+* zc-compat-subfig01.lvt
+* zc-dictionaries01.lvt
+* zc-dictionaries02.lvt
+* zc-howto-amsmath01.lvt
+* zc-howto-enumitem01.lvt
+* zc-howto-listings01.lvt
+* zc-howto-newfloat01.lvt
+* zc-howto-newfloat02.lvt
+* zc-howto-newfloat03.lvt
+* zc-howto-newfloat04.lvt
+* zc-howto-newfloat05.lvt
+* zc-howto-newtheorem01.lvt
+* zc-howto-newtheorem02.lvt
+* zc-howto-newtheorem03.lvt
+* zc-howto-newtheorem04.lvt
+* zc-howto-zref-xr01.lvt
+* zc-label-options01.lvt
+* zc-languages01.lvt
+* zc-opt-check01.lvt
+* zc-opt-d01.lvt
+* zc-opt-g01.lvt
+* zc-opt-hyperref01.lvt
+* zc-opt-hyperref02.lvt
+* zc-opt-hyperref03.lvt
+* zc-opt-hyperref04.lvt
+* zc-opt-hyperref05.lvt
+* zc-opt-lang01.lvt
+* zc-opt-lang02.lvt
+* zc-opt-lang03.lvt
+* zc-opt-lang04.lvt
+* zc-opt-lang05.lvt
+* zc-opt-lang06.lvt
+* zc-opt-nocompat01.lvt
+* zc-opt-nocompat02.lvt
+* zc-opt-nocompat03.lvt
+* zc-opt-ref01.lvt
+* zc-opt-ref02.lvt
+* zc-opt-titleref01.lvt
+* zc-precedence-rules01.lvt
+* zc-sort01.lvt
+* zc-typeset01.lvt
+* zc-workaround-breqn01.lvt
+* zc-zcref-options01.lvt
+* zc-LanguageSetup01.luatex.tlg
+* zc-LanguageSetup01.tlg
+* zc-LanguageSetup01.xetex.tlg
+* zc-RefTypeSetup01.luatex.tlg
+* zc-RefTypeSetup01.tlg
+* zc-RefTypeSetup01.xetex.tlg
+* zc-class-article01.luatex.tlg
+* zc-class-article01.tlg
+* zc-class-article01.xetex.tlg
+* zc-class-book01.luatex.tlg
+* zc-class-book01.tlg
+* zc-class-book01.xetex.tlg
+* zc-class-memoir01.luatex.tlg
+* zc-class-memoir01.tlg
+* zc-class-memoir01.xetex.tlg
+* zc-class-report01.luatex.tlg
+* zc-class-report01.tlg
+* zc-class-report01.xetex.tlg
+* zc-class-scrartcl01.luatex.tlg
+* zc-class-scrartcl01.tlg
+* zc-class-scrartcl01.xetex.tlg
+* zc-class-scrbook01.luatex.tlg
+* zc-class-scrbook01.tlg
+* zc-class-scrbook01.xetex.tlg
+* zc-class-scrreprt01.luatex.tlg
+* zc-class-scrreprt01.tlg
+* zc-class-scrreprt01.xetex.tlg
+* zc-compat-amsmath01.luatex.tlg
+* zc-compat-amsmath01.tlg
+* zc-compat-amsmath01.xetex.tlg
+* zc-compat-appendices01.luatex.tlg
+* zc-compat-appendices01.tlg
+* zc-compat-appendices01.xetex.tlg
+* zc-compat-appendix01.luatex.tlg
+* zc-compat-appendix01.tlg
+* zc-compat-appendix01.xetex.tlg
+* zc-compat-breqn01.luatex.tlg
+* zc-compat-breqn01.tlg
+* zc-compat-breqn01.xetex.tlg
+* zc-compat-enumitem01.luatex.tlg
+* zc-compat-enumitem01.tlg
+* zc-compat-enumitem01.xetex.tlg
+* zc-compat-koma-script01.luatex.tlg
+* zc-compat-koma-script01.tlg
+* zc-compat-koma-script01.xetex.tlg
+* zc-compat-listings01.luatex.tlg
+* zc-compat-listings01.tlg
+* zc-compat-listings01.xetex.tlg
+* zc-compat-memoir01.luatex.tlg
+* zc-compat-memoir01.tlg
+* zc-compat-memoir01.xetex.tlg
+* zc-compat-subcaption01.luatex.tlg
+* zc-compat-subcaption01.tlg
+* zc-compat-subcaption01.xetex.tlg
+* zc-compat-subfig01.luatex.tlg
+* zc-compat-subfig01.tlg
+* zc-compat-subfig01.xetex.tlg
+* zc-dictionaries01.tlg
+* zc-dictionaries02.luatex.tlg
+* zc-dictionaries02.tlg
+* zc-dictionaries02.xetex.tlg
+* zc-howto-amsmath01.luatex.tlg
+* zc-howto-amsmath01.tlg
+* zc-howto-amsmath01.xetex.tlg
+* zc-howto-enumitem01.luatex.tlg
+* zc-howto-enumitem01.tlg
+* zc-howto-enumitem01.xetex.tlg
+* zc-howto-listings01.luatex.tlg
+* zc-howto-listings01.tlg
+* zc-howto-listings01.xetex.tlg
+* zc-howto-newfloat01.luatex.tlg
+* zc-howto-newfloat01.tlg
+* zc-howto-newfloat01.xetex.tlg
+* zc-howto-newfloat02.luatex.tlg
+* zc-howto-newfloat02.tlg
+* zc-howto-newfloat02.xetex.tlg
+* zc-howto-newfloat03.luatex.tlg
+* zc-howto-newfloat03.tlg
+* zc-howto-newfloat03.xetex.tlg
+* zc-howto-newfloat04.luatex.tlg
+* zc-howto-newfloat04.tlg
+* zc-howto-newfloat04.xetex.tlg
+* zc-howto-newfloat05.luatex.tlg
+* zc-howto-newfloat05.tlg
+* zc-howto-newfloat05.xetex.tlg
+* zc-howto-newtheorem01.luatex.tlg
+* zc-howto-newtheorem01.tlg
+* zc-howto-newtheorem01.xetex.tlg
+* zc-howto-newtheorem02.luatex.tlg
+* zc-howto-newtheorem02.tlg
+* zc-howto-newtheorem02.xetex.tlg
+* zc-howto-newtheorem03.luatex.tlg
+* zc-howto-newtheorem03.tlg
+* zc-howto-newtheorem03.xetex.tlg
+* zc-howto-newtheorem04.luatex.tlg
+* zc-howto-newtheorem04.tlg
+* zc-howto-newtheorem04.xetex.tlg
+* zc-howto-zref-xr01.luatex.tlg
+* zc-howto-zref-xr01.tlg
+* zc-howto-zref-xr01.xetex.tlg
+* zc-label-options01.luatex.tlg
+* zc-label-options01.tlg
+* zc-languages01.tlg
+* zc-opt-check01.luatex.tlg
+* zc-opt-check01.tlg
+* zc-opt-d01.tlg
+* zc-opt-g01.tlg
+* zc-opt-hyperref01.luatex.tlg
+* zc-opt-hyperref01.tlg
+* zc-opt-hyperref01.xetex.tlg
+* zc-opt-hyperref02.luatex.tlg
+* zc-opt-hyperref02.tlg
+* zc-opt-hyperref02.xetex.tlg
+* zc-opt-hyperref03.luatex.tlg
+* zc-opt-hyperref03.tlg
+* zc-opt-hyperref03.xetex.tlg
+* zc-opt-hyperref04.luatex.tlg
+* zc-opt-hyperref04.tlg
+* zc-opt-hyperref04.xetex.tlg
+* zc-opt-hyperref05.luatex.tlg
+* zc-opt-hyperref05.tlg
+* zc-opt-hyperref05.xetex.tlg
+* zc-opt-lang01.luatex.tlg
+* zc-opt-lang01.tlg
+* zc-opt-lang01.xetex.tlg
+* zc-opt-lang02.luatex.tlg
+* zc-opt-lang02.tlg
+* zc-opt-lang02.xetex.tlg
+* zc-opt-lang03.luatex.tlg
+* zc-opt-lang03.tlg
+* zc-opt-lang03.xetex.tlg
+* zc-opt-lang04.luatex.tlg
+* zc-opt-lang04.tlg
+* zc-opt-lang04.xetex.tlg
+* zc-opt-lang05.luatex.tlg
+* zc-opt-lang05.tlg
+* zc-opt-lang05.xetex.tlg
+* zc-opt-lang06.luatex.tlg
+* zc-opt-lang06.tlg
+* zc-opt-lang06.xetex.tlg
+* zc-opt-nocompat01.luatex.tlg
+* zc-opt-nocompat01.tlg
+* zc-opt-nocompat01.xetex.tlg
+* zc-opt-nocompat02.luatex.tlg
+* zc-opt-nocompat02.tlg
+* zc-opt-nocompat02.xetex.tlg
+* zc-opt-nocompat03.luatex.tlg
+* zc-opt-nocompat03.tlg
+* zc-opt-nocompat03.xetex.tlg
+* zc-opt-ref01.tlg
+* zc-opt-ref02.luatex.tlg
+* zc-opt-ref02.tlg
+* zc-opt-ref02.xetex.tlg
+* zc-opt-titleref01.luatex.tlg
+* zc-opt-titleref01.tlg
+* zc-opt-titleref01.xetex.tlg
+* zc-precedence-rules01.luatex.tlg
+* zc-precedence-rules01.tlg
+* zc-precedence-rules01.xetex.tlg
+* zc-sort01.tlg
+* zc-typeset01.luatex.tlg
+* zc-typeset01.tlg
+* zc-typeset01.xetex.tlg
+* zc-workaround-breqn01.luatex.tlg
+* zc-workaround-breqn01.tlg
+* zc-workaround-breqn01.xetex.tlg
+* zc-zcref-options01.luatex.tlg
+* zc-zcref-options01.tlg
+* zc-zcref-options01.xetex.tlg
+
+
+## TDS manifest
+
+The following groups list the files included in the TeX Directory Structure used to install
+the package into a TeX distribution.
+
+### Source files (TDS)
+
+All files included in the `zref-clever/source` directory.
+
+* zref-clever.dtx
+* zref-clever.ins
+
+### TeX files (TDS)
+
+All files included in the `zref-clever/tex` directory.
+
+* zref-clever-english.dict
+* zref-clever-french.dict
+* zref-clever-german.dict
+* zref-clever-portuguese.dict
+* zref-clever-spanish.dict
+* zref-clever.sty
+
+### Doc files (TDS)
+
+All files included in the `zref-clever/doc` directory.
+
+* CHANGELOG.md
+* DEPENDS.txt
+* MANIFEST.md
+* README.md
+* zref-clever-code.pdf
+* zref-clever-code.tex
+* zref-clever.pdf
+* zref-clever.tex
+
+
+## CTAN manifest
+
+The following group lists the files included in the CTAN package.
+
+### CTAN files
+
+* CHANGELOG.md
+* DEPENDS.txt
+* MANIFEST.md
+* README.md
+* zref-clever-code.pdf
+* zref-clever-code.tex
+* zref-clever.dtx
+* zref-clever.ins
+* zref-clever.pdf
+* zref-clever.tex
diff --git a/Master/texmf-dist/doc/latex/zref-clever/README.md b/Master/texmf-dist/doc/latex/zref-clever/README.md
new file mode 100644
index 00000000000..b260c87ec06
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/zref-clever/README.md
@@ -0,0 +1,22 @@
+# zref-clever
+
+**Clever LaTeX cross-references based on zref**
+
+Author: Gustavo Barros
+Maintainer: Gustavo Barros
+
+`zref-clever` provides an user interface for making LaTeX cross-references
+which automates some of their typical features, thus easing their input in the
+document and improving the consistency of typeset results. A reference made
+with `\zcref` includes a "name" according to its "type" and lists of multiple
+labels can be automatically sorted and compressed into ranges when due. The
+reference format is highly and easily customizable, both globally and locally.
+`zref-clever` is based on `zref`'s extensible referencing system.
+
+License: LPPL Version 1.3c
+
+Repository: https://github.com/gusbrs/zref-clever
+
+Bug tracker: https://github.com/gusbrs/zref-clever/issues
+
+CTAN: https://ctan.org/pkg/zref-clever
diff --git a/Master/texmf-dist/doc/latex/zref-clever/zref-clever-code.pdf b/Master/texmf-dist/doc/latex/zref-clever/zref-clever-code.pdf
new file mode 100644
index 00000000000..b8105bc9e2c
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/zref-clever/zref-clever-code.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/zref-clever/zref-clever-code.tex b/Master/texmf-dist/doc/latex/zref-clever/zref-clever-code.tex
new file mode 100644
index 00000000000..a258484cccb
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/zref-clever/zref-clever-code.tex
@@ -0,0 +1,53 @@
+% \iffalse meta-comment
+%
+% File: zref-clever-code.tex
+%
+% This file is part of the LaTeX package "zref-clever".
+%
+% 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-clever.dtx,
+% zref-clever.ins,
+% zref-clever.tex,
+% zref-clever-code.tex,
+% and the derived files listed in MANIFEST.md.
+%
+% 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-clever
+%
+% for those people who are interested.
+%
+% -----------------------------------------------------------------------
+%
+% \fi
+
+\documentclass{l3doc}
+
+% Have \GetFileInfo pick up date and version data and used in the
+% documentation.
+\usepackage[cap,nameinlink=false,check,titleref]{zref-clever}
+
+\begin{document}
+
+\DocInput{zref-clever.dtx}
+
+\end{document}
diff --git a/Master/texmf-dist/doc/latex/zref-clever/zref-clever.pdf b/Master/texmf-dist/doc/latex/zref-clever/zref-clever.pdf
new file mode 100644
index 00000000000..1b0c6f93f92
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/zref-clever/zref-clever.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/zref-clever/zref-clever.tex b/Master/texmf-dist/doc/latex/zref-clever/zref-clever.tex
new file mode 100644
index 00000000000..c2fa9f19b2c
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/zref-clever/zref-clever.tex
@@ -0,0 +1,2163 @@
+% \iffalse meta-comment
+%
+% File: zref-clever.tex
+%
+% This file is part of the LaTeX package "zref-clever".
+%
+% 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-clever.dtx,
+% zref-clever.ins,
+% zref-clever.tex,
+% zref-clever-code.tex,
+% and the derived files listed in MANIFEST.md.
+%
+% 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-clever
+%
+% for those people who are interested.
+%
+% -----------------------------------------------------------------------
+%
+% \fi
+
+\documentclass{l3doc}
+
+% The package itself *must* be loaded so that \GetFileInfo can pick up date
+% and version data. Naturally, we also use it.
+\usepackage[cap,check,titleref]{zref-clever}
+
+\usepackage[T1]{fontenc}
+
+\usepackage[sc]{mathpazo}
+\linespread{1.05}
+\usepackage[scale=.88]{tgheros} % sans
+\usepackage[varqu,scaled=1.03]{inconsolata} % tt
+
+\usepackage{listings}
+
+\usepackage{microtype}
+
+\hypersetup{hidelinks}
+
+\NewDocumentCommand\opt{m}{\texttt{#1}}
+
+\definecolor{reffmtbox}{gray}{0.15}
+\definecolor{reffmtback}{gray}{0.85}
+\NewDocumentCommand\reffmt{m}{%
+ \fcolorbox{reffmtbox}{reffmtback}{%
+ \rule[-0.2\baselineskip]{0pt}{0.8\baselineskip}\texttt{#1}}}
+
+\newlist{refformat}{itemize}{1}
+\setlist[refformat]{label={}, beginpenalty=500, midpenalty=500}
+
+\NewDocumentCommand\zctask{m}{%
+ \begin{description}
+ \item[Task] #1
+ \end{description}}
+
+\lstdefinestyle{code}{
+ language=[LaTeX]TeX,
+ moretexcs={
+ AddToHook,
+ define@key,
+ patchcmd,
+ eq@setnumber,
+ DeclareFloatingEnvironment,
+ newlist,
+ setlist,
+ zexternaldocument,
+ next@label,
+ next@label@pre,
+ @empty,
+ tag,
+ text,
+ lstset,
+ condition,
+ }
+}
+\lstdefinestyle{zrefclever}{
+ style=code,
+ moretexcs={
+ zcref,
+ zcpageref,
+ zlabel,
+ zcsetup,
+ zcLanguageSetup,
+ zcRefTypeSetup,
+ zcheck,
+ }
+}
+\lstset{
+ style=zrefclever,
+ basicstyle=\ttfamily\small,
+ columns=fullflexible,
+ keepspaces,
+ xleftmargin=\leftmargin,
+ xrightmargin=.5\leftmargin,
+}
+% Setup inspired by https://tex.stackexchange.com/a/4068. For how to use these
+% environments in a .dtx context see https://tex.stackexchange.com/a/31026.
+\newcounter{zchowto}
+\lstnewenvironment{zchowto}[1][]{%
+ \renewcommand{\lstlistingname}{How-to}%
+ \lstset{#1}%
+ \setcounter{lstlisting}{\value{zchowto}}%
+}{}
+\newcounter{zcworkaround}
+\lstnewenvironment{zcworkaround}[1][]{%
+ \renewcommand{\lstlistingname}{Work-around}%
+ \lstset{#1}%
+ \setcounter{lstlisting}{\value{zcworkaround}}%
+}{}
+\lstnewenvironment{zcexample}[1][]{%
+ \renewcommand{\lstlistingname}{Example}%
+ \lstset{#1}%
+}{}
+\ExplSyntaxOn
+\makeatletter
+\lst@AddToHook { PreInit }
+ {
+ \cs_if_exist:cT { c@ \lstenv@name }
+ { \exp_args:Nx \refstepcounter { \lstenv@name } }
+ }
+\makeatother
+\ExplSyntaxOff
+
+\zcRefTypeSetup{zchowto}{
+ Name-sg = {How-to},
+ name-sg = {how-to},
+ Name-pl = {How-tos},
+ name-pl = {how-tos},
+}
+\zcRefTypeSetup{zcworkaround}{
+ Name-sg = {Work-around},
+ name-sg = {work-around},
+ Name-pl = {Work-arounds},
+ name-pl = {work-arounds},
+}
+
+\begin{document}
+
+\GetFileInfo{zref-clever.sty}
+
+\title{%
+ The \pkg{zref-clever} package%
+ \thanks{This file describes \fileversion, released \filedate.}%
+}
+
+\author{%
+ Gustavo Barros%
+ \thanks{\url{https://github.com/gusbrs/zref-clever}}%
+}
+
+\date{\filedate}
+
+\maketitle
+
+\begin{abstract}
+ \pkg{zref-clever} provides an user interface for making \LaTeX{}
+ cross-references which automates some of their typical features, thus easing
+ their input in the document and improving the consistency of typeset
+ results. A reference made with \cs{zcref} includes a ``name'' according to
+ its ``type'' and lists of multiple labels can be automatically sorted and
+ compressed into ranges when due. The reference format is highly and easily
+ customizable, both globally and locally. \pkg{zref-clever} is based on
+ \pkg{zref}'s extensible referencing system.
+\end{abstract}
+
+\begin{center}
+ \small
+ \textbf{EXPERIMENTAL}
+
+ Please read \zcref{sec:warning} carefully.
+\end{center}
+
+\tableofcontents
+
+\section{Introduction}
+
+Cross-referencing is an area which lends itself quite naturally to automation.
+Not only for input convenience but also, and most importantly, for end results
+consistency. Indeed, the standard \LaTeX{} cross-referencing system -- with
+\cs{label}, \cs{ref}, and \cs{pageref} -- is already a form of automation, by
+relieving us from checking the number of the referenced object, and the page
+where it lies.
+
+But the plethora of existing features, packages and document classes which, in
+one way or another, extends this basic functionality is a clear indication of
+a demand for more automation. Just to name the most popular: \pkg{cleveref},
+\pkg{hyperref}, \pkg{titleref}, \pkg{nameref}, \pkg{varioref}, \pkg{fancyref},
+and the kernel's \cs{labelformat}.
+
+However, the standard cross-referencing system stores two, and only two,
+properties with the label: the printed representation of the counter last
+incremented with \cs{refstepcounter} and the page. Of course, out of the
+mentioned desire to automate more, the need arose to store more information
+about the label to support this: the title or caption of the referenced
+object; its counter or, even better, its ``type'', that is, whether it is a
+section, chapter, figure, etc.; its hyperlink anchor, and so on. Thus those
+two property ``fields'' of the standard label became quite a disputed real
+state. And the packages in this area of functionality were bound to step on
+each other's toes as a result.
+
+Out of this conundrum, Heiko Oberdiek eventually developed \pkg{zref}, which
+implements an extensible referencing system, making the labels store a
+property list of flexible length, so that new properties can be easily added
+and queried. However, even when \pkg{zref} can rightfully boast this powerful
+basic concept and is really quite featureful, with several different modules
+available, it is fair to say that, for the average user, the package may
+appear to be somewhat raw. Indeed, for someone who ``just wants to make a
+cross-reference'', the user interface of the \pkg{zref-user} module is akin to
+the standard \LaTeX{} cross-referencing system, and even requires some extra
+work if you want to have a hyperlinked reference. In other words, \pkg{zref}
+seems to have focused on infrastructure and on performing a number of
+specialized tasks with different modules, and a large part of the landscape of
+automation features available for the standard referencing system was not
+carried over to \pkg{zref}, neither by the \pkg{zref} itself nor by other
+packages.
+
+\pkg{zref-clever} tries to cover this gap, by bringing a number of existing
+features available for the standard referencing system to \pkg{zref}, and
+hopefully making \pkg{zref} more accessible, and interesting, to the average
+user. And the package's name makes it clear that the core of the envisaged
+feature set is that of \pkg{cleveref}, even though the attempt was less one of
+replicating functionality per se than that of having it as a successful point
+of reference, from where we could then try to tap into \pkg{zref}'s potential.
+Indeed, although there is a significant intersection, the features of
+\pkg{zref-clever} are neither a superset nor a subset of those of
+\pkg{cleveref}. There are things either of them can do that the other can't.
+There are also important differences in user interface design. In particular,
+\pkg{zref-clever} relies heavily on \texttt{key=value} interfaces both for
+general configuration and for centering in a single user command, \cs{zcref},
+as the main entrance for reference making, whose behavior can be modulated by
+local options.
+
+Considering that \pkg{zref} itself offers the \pkg{zref-titleref} module, and
+that the integration with \pkg{zref-check} allows \pkg{zref-clever} to make
+context sensitive references, akin to those of \pkg{varioref}, a significant
+part of the most prominent automation features available to the standard
+referencing system is thus brought to \pkg{zref}, working under a single
+consistent underlying infrastructure and user interface. Alas, there are
+limitations, of course (see \zcref{sec:limitations}). Still, all in all,
+hopefully \pkg{zref-clever} can be the missing piece for \pkg{zref} to fulfill
+the promise insinuated by the ``z'' in its name, and be your ``last ref''.
+
+
+\subsection{Warning}
+\zlabel{sec:warning}
+
+This package is in its early days, and should be considered experimental. By
+this I don't mean I expect it to be ``edgy'', indeed quite a lot of effort has
+been put into it so that this is not the case. However, during the initial
+development, I had to make a number of calls for which I felt I had
+insufficient information: in relation to features, packages, or classes I
+don't use much, or to languages I don't know well, user needs I found hard to
+anticipate etc. Hence, the package needs some time, and some use by more
+adventurous people, until it can settle down with more conviction. In the
+meantime, polishing the user interface and the infrastructure have a clear
+priority over backward compatibility. So, if you choose to use this package,
+you should be ready to accommodate to eventual upstream changes.
+
+
+\section{Loading the package}
+\zlabel{sec:loading-package}
+
+As usual:
+
+\begin{zcexample}[escapeinside=`']
+\usepackage`\oarg{options}'{zref-clever}
+\end{zcexample}
+
+
+\subsection{Dependencies}
+
+\pkg{zref-clever} requires \pkg{zref}, and \LaTeX{} kernel 2021-11-15, or
+newer. It also needs \pkg{l3keys2e} and \pkg{ifdraft}. Some packages are
+leveraged by \pkg{zref-clever} if they are present, but are not loaded by
+default or required by it, namely: \pkg{hyperref}, \pkg{zref-check}, and
+\pkg{zref}'s \pkg{zref-titleref}, \pkg{zref-hyperref}, and \pkg{zref-xr}
+modules.
+
+
+\section{User interface}
+\zlabel{sec:user-interface}
+
+\begin{function}{\zcref}
+ \begin{syntax}
+ \cs{zcref}\meta{*}\oarg{options}\marg{labels}
+ \end{syntax}
+\end{function}
+Typesets references to \meta{labels}, given as a comma separated list. When
+\pkg{hyperref} support is enabled, references will be hyperlinked to their
+respective anchors, according to options. The starred version of the command
+does the same as the plain one, just does not form links. The \meta{options}
+are (mostly) the same as those of the package, and can be given to local
+effect. The \meta{labels} argument is protected by \pkg{zref}'s
+\cs{zref@wrapper@babel}, so that it enjoys the same support for \pkg{babel}'s
+active characters as \pkg{zref} itself does.
+
+\begin{function}{\zcpageref}
+ \begin{syntax}
+ \cs{zcpageref}\meta{*}\oarg{options}\marg{labels}
+ \end{syntax}
+\end{function}
+Typesets page references to \meta{labels}, given as a comma separated list.
+It is equivalent to calling \cs{zcref} with the \opt{ref=page} option:
+\cs{zcref}\texttt{\meta{*}[}\meta{options}\texttt{,ref=page]}\marg{labels}.
+
+
+\begin{function}{\zcsetup}
+ \begin{syntax}
+ \cs{zcsetup}\marg{options}
+ \end{syntax}
+\end{function}
+Sets \pkg{zref-clever}'s general options (see \zcref{sec:options,
+ sec:reference-format}). The settings performed by \cs{zcsetup} are local,
+within the current group. But, of course, it can also be used to global
+effects if ungrouped, e.g.\ in the preamble.
+
+\begin{function}{\zcRefTypeSetup}
+ \begin{syntax}
+ \cs{zcRefTypeSetup}\marg{type}\marg{options}
+ \end{syntax}
+\end{function}
+Sets type-specific reference format options (see \zcref{sec:ref-format-opts}).
+Just as for \cs{zcsetup}, the settings performed by \cs{zcRefTypeSetup} are
+local, within the current group.
+
+\bigskip{}
+
+Besides these, user facing commands related to \zcref*[ref=title,
+ noname]{sec:internationalization} are presented in
+\zcref{sec:internationalization}. Note still that all user commands are
+defined with \cs{NewDocumentCommand}, which translates into the usual handling
+of arguments by it and/or processing by \pkg{l3keys}, particularly with regard
+to brace-stripping and space-trimming.
+
+Furthermore, \pkg{zref-clever} loads \pkg{zref}'s \pkg{zref-user} module by
+default. So you also have its user commands available out of the box, notably
+\cs{zlabel}, but also \cs{zref} and \cs{zpageref} themselves.
+
+
+
+\subsection{Options}
+\zlabel{sec:options}
+
+\pkg{zref-clever} is highly configurable, offering a lot of flexibility in
+typeset results of the references, but it also tries to keep these ``handles''
+as convenient and user friendly as possible. To this end, most of what one
+can do with \pkg{zref-clever} (pretty much all of it), can be achieved
+directly through the standard and familiar ``comma separated list of
+\texttt{key=value} options''.
+
+There are two main groups of options in \pkg{zref-clever}: ``general
+options'', which affect the overall behavior of the package, or the reference
+as a whole; and ``reference format options'', which control the detail of
+reference formatting, including type-specific and language-specific settings.
+
+This section covers the first group (for the second one, see
+\zcref{sec:ref-format-opts}). General options can be set globally either as
+package options at load-time (see \zcref{sec:loading-package}) or by means of
+\cs{zcsetup} in the preamble (see \zcref{sec:user-interface}). They can also
+be set locally with \cs{zcsetup} along the document or through the optional
+argument of \cs{zcref} (see \zcref{sec:user-interface}). Most general options
+can be used in any of these contexts, but that is not necessarily true for all
+cases, some restrictions may apply, as described in each option's
+documentation.
+
+\bigskip{}
+
+\DescribeOption{ref} %
+\DescribeOption{page} %
+The \opt{ref} option controls the label property to which \cs{zcref} refers
+to. It can receive \pkg{zref} properties, as long as they are declared, but
+notably \texttt{default}, \texttt{page}, \texttt{thecounter} and, if
+\pkg{zref-titleref} is loaded, \texttt{title}. The package's default is,
+well, \texttt{default}, which is our standard reference. \texttt{thecounter}
+is a property set by \pkg{zref-clever} and is similar to \pkg{zref}'s
+\texttt{default} property, except that it is not affected by the kernel's
+\cs{labelformat}.\footnote{Technical note: the \texttt{default} property
+ stores \cs{@currentlabel}, while the \texttt{thecounter} property stores
+ \cs{the}\cs{@currentcounter}. The later is exactly what \cs{refstepcounter}
+ uses to build \cs{@currentlabel}, except for the \cs{labelformat} prefix
+ and, hence, has the advantage of being unaffected by it. But the former is
+ \emph{more reliable} since \cs{@currentlabel} is expected to be correct
+ pretty much anywhere whereas, although \cs{refstepcounter} does set
+ \cs{@currentcounter}, it is not everywhere that uses \cs{refstepcounter} for
+ the purpose. In the cases where the references from these two do diverge,
+ \pkg{zref-clever} will likely misbehave (reference type, sorting and
+ compression inevitably depend on a correct \opt{currentcounter}), but using
+ \texttt{default} at least ensures that the reference itself is correct.
+ That said, if you do set \cs{labelformat} for some reason,
+ \texttt{thecounter} may be useful.} By default, reference formatting,
+sorting, and compression are done according to information inferred from the
+\emph{current counter} (see \opt{currentcounter} option below). Special
+treatment in these areas is provided for \texttt{page}, but not for any other
+properties. The \opt{page} option is a convenience alias for
+\texttt{ref=page}.
+
+\DescribeOption{typeset} %
+\DescribeOption{noname} %
+\DescribeOption{noref} %
+When \cs{zcref} typesets a set of references, each group of references of the
+same type can be, and by default are, preceded by the type's ``name'', and
+this is indeed an important feature of \pkg{zref-clever}. This is optional
+however, and the \opt{typeset} option controls this behavior. It can receive
+values \texttt{ref}, in which case it typesets only the reference(s),
+\texttt{name}, in which case it typesets only the name(s), or \texttt{both},
+in which case it typesets, well, both of them. Note that, when value
+\texttt{name} is used, the name is still typeset according to the set of
+references given to \cs{zcref}. For example, for multiple references, the
+plural form is used, capitalization options are honored, etc. Also
+hyperlinking behaves just \emph{as if} the references were present and,
+depending on the corresponding options, the name may be linked to the first
+reference of the type group. The \opt{noname} and \opt{noref} options are
+convenience aliases for \texttt{typeset=ref} and \texttt{typeset=name},
+respectively.
+
+\DescribeOption{sort} %
+\DescribeOption{nosort} %
+The \opt{sort} option controls whether the list of \meta{labels} received as
+argument by \cs{zcref} should be sorted or not. It is a boolean option, and
+defaults to \texttt{true}. The \opt{nosort} option is a convenience alias for
+\texttt{sort=false}.
+
+\DescribeOption{typesort} %
+\DescribeOption{notypesort} %
+Sorting references of the same type can be done with well defined logical
+criteria. They either have the same counter or their counters share a clear
+hierarchical relation (in the resetting behavior), such that a definite
+sorting rule can be inferred from the label's data. The same is not true for
+sorting of references of different types. Should ``tables'' come before or
+after ``figures''? The \pkg{typesort} option allows to specify the sorting
+priority of different reference types. It receives as value a comma separated
+list of reference types, specifying that their sorting is to be done in the
+order of that list. But \opt{typesort} does not need to receive \emph{all}
+possible reference types. The special value \texttt{\{\{othertypes\}\}} (yes,
+double braced, one for \pkg{l3keys}, so that the second can make the list) can
+be placed anywhere along the list, to specify the sort priority of any type
+not included explicitly. If \texttt{\{othertypes\}} is not present in the
+list, it is presumed to be at the end of it. Any unspecified types (that is,
+those falling implicitly or explicitly into the \texttt{\{othertypes\}}
+category) get sorted between themselves in the order of their first appearance
+in the label list given as argument to \cs{zcref}. I presume the common use
+cases will not need to specify \texttt{\{othertypes\}} at all but, for the
+sake of example, if you just really dislike equations, you could use
+\texttt{typesort=\{\{\{othertypes\}\}, equation\}}. \opt{typesort}'s default
+value is \texttt{\{part, chapter, section, paragraph\}}, which places the
+sectioning reference types first in the list, in their hierarchical order, and
+leaves everything else to the order of appearance of the labels. The
+\opt{notypesort} option behaves like \texttt{typesort=\{\{\{othertypes\}\}\}}
+would do, that is, it sorts all types in the order of the first appearance in
+the labels' list.
+
+\DescribeOption{comp} %
+\DescribeOption{nocomp} %
+\cs{zcref} can automatically compress a set of references of the same type
+into a range, when they occur in immediate sequence. The \opt{comp} controls
+whether this compression should take place or not. It is a boolean option,
+and defaults to \texttt{true}. The \opt{nocomp} option is a convenience alias
+for \texttt{comp=false}. Of course, for better compression results the
+\opt{sort} is recommended, but the two options are technically independent.
+
+\DescribeOption{range} %
+By default (that is, when the \opt{range} option is not given), \cs{zcref}
+typesets a complete list of references according to the \meta{labels} it
+received as argument, and only compresses some of them into ranges if the
+\opt{comp} option is enabled and if references of the same type occur in
+immediate sequence. The \opt{range} option makes \cs{zcref} behave
+differently. Sorting is implied by this option (the \opt{sort} option is
+disregarded) and, for each reference type group in \meta{labels}, \cs{zcref}
+builds a range from the first to the last reference in it, even if references
+in between do not occur in immediate sequence. \cs{zcref} is smart enough,
+though, to recognize when the first and last references of a type do happen to
+be contiguous, in which case it typesets a ``pair'', instead of a ``range''.
+It is a boolean option, and the package's default is \texttt{range=false}.
+The option given without a value is equivalent to \texttt{range=true} (in the
+\pkg{l3keys}' jargon, the \emph{option}'s default is \texttt{true}).
+
+\DescribeOption{cap} %
+\DescribeOption{nocap} %
+\DescribeOption{capfirst} %
+The \opt{cap} option controls whether the reference type names should be
+capitalized or not. It is a boolean option, and the package's default is
+\texttt{cap=false}. The option given without a value is equivalent to
+\texttt{cap=true}. The \opt{nocap} option is a convenience alias for
+\texttt{cap=false}. The \opt{capfirst} option ensures that the reference type
+name of the \emph{first} type block is capitalized, even when \opt{cap} is set
+to \texttt{false}.
+
+\DescribeOption{abbrev} %
+\DescribeOption{noabbrev} %
+\DescribeOption{noabbrevfirst} %
+The \opt{abbrev} option controls whether to use abbreviated reference type
+names when they are available. It is a boolean option, and the package's
+default is \texttt{abbrev=false}. The option given without a value is
+equivalent to \texttt{abbrev=true}. The \opt{noabbrev} option is a
+convenience alias for \texttt{abbrev=false}. The \opt{noabbrevfirst} ensures
+that the reference type name of the \emph{first} type block is never
+abbreviated, even when \opt{abbrev} is set to \texttt{true}.
+
+\DescribeOption{S} %
+\opt{S} for ``Sentence''. The \opt{S} option is a convenience alias for
+\texttt{capfirst=true, noabbrevfirst=true}, and is intended to be used in
+references made at the beginning of a sentence. It is highly recommended that
+you make a habit of using the \opt{S} option for beginning of sentence
+references. Even if you do happen to be currently using \texttt{cap=true,
+ abbrev=false}, proper semantic markup will ensure you get expected results
+even if you change your mind in that regard later on. For that reason, it was
+made short and mnemonic, it can't get any easier.
+
+\DescribeOption{hyperref} %
+The \opt{hyperref} option controls the use of \pkg{hyperref} by
+\pkg{zref-clever} and takes values \opt{auto}, \opt{true}, \opt{false}. The
+default value, \opt{auto}, makes \pkg{zref-clever} use \pkg{hyperref} if it is
+loaded, meaning that references made with \cs{zcref} get hyperlinked to the
+anchors of their respective \meta{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-clever}. \opt{false} means
+not to use \pkg{hyperref} regardless of its availability. This is a preamble
+only option, but \cs{zcref} provides granular control of hyperlinking by means
+of its starred version.
+
+\DescribeOption{nameinlink} %
+The \opt{nameinlink} option controls whether the type name should be included
+in the reference hyperlink or not (provided there is a link, of course).
+Naturally, the name can only be included in the link of the \emph{first}
+reference of each type block. \opt{nameinlink} can receive values
+\texttt{true}, \texttt{false}, \texttt{single}, and \texttt{tsingle}. When
+the value is \texttt{true} the type name is always included in the hyperlink.
+When it is \texttt{false} the type name is never included in the link. When
+the value is \texttt{single}, the type name is included in the link only if
+\cs{zcref} is typesetting a single reference (not necessarily having received
+a single label as argument, as they may have been compressed), otherwise, the
+name is left out of the link. When the value is \texttt{tsingle}, the type
+name is included in the link for each type block with a single reference,
+otherwise, it isn't. An example: suppose you make a couple of references to
+something like \cs{zcref}\texttt{\{chap:chapter1\}} and
+\cs{zcref}\texttt{\{chap:chapter1, sec:section1, fig:figure1, fig:figure2\}}.
+The ``figure'' type name will only be included in the hyperlink if
+\opt{nameinlink} option is set to \texttt{true}. If it is set to
+\texttt{tsingle}, the first reference will include the name in the link for
+``chapter'', as expected, but also in the second reference the ``chapter'' and
+``section'' names will be included in their respective links, while that of
+``figure'' will not. If the option is set to \texttt{single}, only the name
+for ``chapter'' in the first reference will be included in the link, while in
+the second reference none of them will. The package's default is
+\texttt{nameinlink=tsingle}, and the option given without a value is
+equivalent to \texttt{nameinlink=true}.
+
+\DescribeOption{preposinlink} %
+The \opt{preposinlink} option controls whether the \opt{refpre} and
+\opt{refpos} reference format options (see \zcref{sec:ref-format-opts}) are
+included in the reference hyperlink or not. It is a boolean option. The
+package's default is \texttt{preposinlink=false}, and the option given without
+a value is equivalent to \texttt{preposinlink=true}.
+
+\DescribeOption{lang} %
+The \opt{lang} option controls the language used by \cs{zcref} when looking
+for language-specific reference format options (see
+\zcref{sec:ref-format-opts}). The default value, \texttt{current}, uses the
+current language, as defined by \pkg{babel} or \pkg{polyglossia} (or
+\texttt{english} if none of them is loaded). Value \texttt{main} uses the
+main document language, as defined by \pkg{babel} or \pkg{polyglossia} (or
+\texttt{english} if none of them is loaded). The \opt{lang} option also
+accepts that the language be specified directly by its name, as long as it's a
+language known by \pkg{zref-clever}. For more details on
+\zcref*[ref=title,noname]{sec:internationalization}, see
+\zcref{sec:internationalization}.
+
+\DescribeOption{d} %
+The \opt{d} option sets the declension case, and affects the type name used
+for typesetting the reference. Whether this option is operative, and which
+values it accepts, depends on the declared setup for each language. For
+details, see \zcref{sec:internationalization}.
+
+\DescribeOption{nudge} %
+\DescribeOption{nudgeif} %
+\DescribeOption{nonudge} %
+\DescribeOption{sg} %
+\DescribeOption{g} %
+This set of options revolving around \opt{nudge} aims to offer some guard
+against mischievous automation on the part of \pkg{zref-clever} by providing a
+number of ``nudges'' (compilation time messages) for cases in which you may
+wish to revise material \emph{surrounding} the reference -- an article, a
+preposition -- according to the reference typeset results. Useful mainly for
+languages which inflect the preceding article to gender and/or number, but may
+be used generally to fine-tune the language and style around the
+cross-references made with \cs{zcref}. The \opt{nudge} option is the main
+entrance to this feature and takes values \texttt{true}, \texttt{false},
+\texttt{ifdraft}, or \texttt{iffinal}. The first two, respectively, enable or
+disable the ``nudging'' unconditionally. With \texttt{ifdraft}, \opt{nudge}
+keeps quiet when option \texttt{draft} is given to \cs{documentclass}, while
+with \texttt{iffinal}, nudging is only enabled when option \texttt{final} is
+(explicitly) passed to \cs{documentclass}. The option given without a value
+is equivalent to \texttt{nudge=true} and the package's default is
+\texttt{nudge=false}. \opt{nonudge} is a convenience alias for
+\texttt{nudge=false}, and can be used to silence individual references. The
+\opt{nudgeif} option controls the events which may trigger a nudge. It takes
+a comma separated list of elements, and recognizes values \texttt{multitype},
+\texttt{comptosing}, \texttt{gender}, and \texttt{all}. The
+\texttt{multitype} nudge warns when the reference is composed by multiple type
+blocks (see \zcref{sec:ref-format-opts}). The \texttt{comptosing} nudge let's
+you know when multiple labels of the same type have been compressed to a
+singular type name form. It can be combined with the \opt{sg} option, which
+is the way to tell \cs{zcref} you know it's a singular and so not to nudge if
+a compression to singular occurs, but to nudge if the contrary occurs, that
+is, when a plural type name form is employed. The \texttt{gender} nudge must
+be combined with option \opt{g}, and depends on the language having support
+for it. In essence language dictionaries can store the gender of each type
+name (this is done for built-in dictionaries, but can also be done with
+\cs{zcLanguageSetup} for languages declared to support it). The \opt{g}
+option let's you specify the gender you expect for that particular reference
+and the nudge is triggered if there is a mismatch between \opt{g} and the
+gender for the type name in the dictionary. Both the \texttt{comptosing} and
+the \texttt{gender} nudges have a type block as its scope. See
+\zcref{sec:internationalization} for more details and intended use cases of
+the ``nudging'' feature.
+
+\DescribeOption{font} %
+The \opt{font} option can receive font styling commands to change the
+appearance of the whole reference list (see also the \opt{namefont} and
+\opt{reffont} reference format options in \zcref{sec:ref-format-opts}). It
+does not affect the content of the \opt{note}, however. The option is
+intended exclusively for commands that only change font attributes: style,
+family, shape, weight, size, color, etc. Anything else, particularly commands
+that may generate typeset output, is not supported. Given how package options
+are handled by \LaTeX{}, the fact that this option receives commands as value
+means this option \emph{can't} be set at load time, as a package option. If
+you want to set it globally, use \cs{zcsetup} instead.
+
+\DescribeOption{titleref} %
+The \opt{titleref} option receives no value and, when given, loads
+\pkg{zref}'s \pkg{zref-titleref} module. This is a preamble only option.
+
+\DescribeOption{note} %
+The \opt{note} option receives as value some text to be typeset at the end of
+the whole reference list. It is separated from it by \opt{notesep} (see
+\zcref{sec:ref-format-opts}).
+
+\DescribeOption{check} %
+Provides integration of \pkg{zref-clever} with the \pkg{zref-check} package.
+In the preamble, the \opt{check} option receives no value and, when given,
+loads \pkg{zref-check}. In the document body, \opt{check} requires a value,
+which works exactly like the optional argument of \cs{zcheck}, and can receive
+both checks and \cs{zcheck}'s options. And the checks are performed for each
+label in \marg{labels} received as argument by \cs{zcref}. See the User
+manual of \pkg{zref-check} for details. The checks done by the \opt{check}
+option in \cs{zcref} comprise the complete reference, including the \opt{note}
+(see \zcref{sec:ref-format-opts}). If \pkg{zref-check} was not loaded in the
+preamble, at begin document the option is made no-op and issues a warning.
+
+\DescribeOption{countertype} %
+The \opt{countertype} option allows to specify the ``reference type'' of each
+counter, which is stored as a label property when the label is set. This
+``reference type'' is what determines how a reference to this label will
+eventually be typeset when it is referred to (see
+\zcref{sec:reference-types}). A value like \texttt{countertype = \{foo =
+ bar\}} sets the \texttt{foo} counter to use the reference type \texttt{bar}.
+There's only need to specify the \opt{countertype} for counters whose name
+differs from that of their type, since \pkg{zref-clever} presumes the type has
+the same name as the counter, unless otherwise specified. Also, the default
+value of the option already sets appropriate types for basic \LaTeX{}
+counters, including those from the standard classes. Setting a counter type
+to an empty value removes any (explicit) type association for that counter, in
+practice, this means it then uses a type equal to its name. Since this option
+only affects how labels are set, it is not available in \cs{zcref}.
+
+\DescribeOption{\raisebox{-.2em}{\dbend}\ counterresetters} %
+\DescribeOption{counterresetby} %
+The sorting and compression of references done by \cs{zcref} requires that we
+know the counter associated with a particular label but also information on
+any counter whose stepping may trigger its resetting, or its ``enclosing
+counters''. This information is not easily retrievable from the counter
+itself but is (normally) stored with the counter that does the resetting. The
+\opt{counterresetters} option adds counter names, received as a comma
+separated list, to the list of counters \pkg{zref-clever} uses to search for
+``enclosing counters'' of the counter for which a label is being set.
+Unfortunately, not every counter gets reset through the standard machinery for
+this, including some \LaTeX{} kernel ones (e.g. the \texttt{enumerate}
+environment counters). For those, there is really no way to retrieve this
+information directly, so we have to just tell \pkg{zref-clever} about them.
+And that's what the \opt{counterresetby} option is made for. It receives a
+comma separated list of \texttt{key=value} pairs, in which \texttt{key} is the
+counter, and \texttt{value} is its ``enclosing counter'', that is, the counter
+whose stepping results in its resetting. This is not really an ``option'' in
+the sense of ``user choice'', it is more of a way to inform \pkg{zref-clever}
+of something it cannot know or automatically find in general. One cannot
+place arbitrary information there, or \pkg{zref-clever} can be thoroughly
+confused. The setting must correspond to the actual resetting behavior of the
+involved counters. \opt{counterresetby} has precedence over the search done
+in the \opt{counterresetters} list. The default value of
+\opt{counterresetters} includes the counters for sectioning commands of the
+standard classes which, in most cases, should be the relevant ones for
+cross-referencing purposes. The default value of \opt{counterresetby}
+includes the \texttt{enumerate} environment counters. So, hopefully, you
+don't need to ever bother with either of these options. But, if you do, they
+are here. Use them with caution though. Since these options only affect how
+labels are set, they are not available in \cs{zcref}.
+
+\DescribeOption{\raisebox{.4em}{\dbend}\ currentcounter} %
+\LaTeX{}'s \cs{refstepcounter} sets two variables which potentially affect the
+\cs{zlabel} set after it: \cs{@currentlabel} and \cs{@currentcounter}.
+Actually, traditionally, only the current label was thus stored, the current
+counter was added to \cs{refstepcounter} somewhat recently (with the
+2020-10-01 kernel release). But, since \pkg{zref-clever} relies heavily on
+the information of what the current counter is, it must set \pkg{zref} to
+store that information with the label, as it does. As long as the document
+element we are trying to refer to uses the standard machinery of
+\cs{refstepcounter} we are on solid ground and can retrieve the correct
+information. However, it is not always ensured that \cs{@currentcounter} is
+kept up to date. For example, packages which handle labels specially, for one
+reason or another, may or may not set \cs{@currentcounter} as required.
+Considering the addition of \cs{@currentcounter} to \cs{refstepcounter} itself
+is not that old, it is likely that in a good number of places a reliable
+\cs{@currentcounter} is not really in place. Therefore, it may happen we need
+to tell \pkg{zref-clever} what the current counter is in certain
+circumstances, and that's what \opt{currentcounter} does. The same as with
+the previous two options, this is not really an ``user choice'' kind of
+option, but a way to tell \pkg{zref-clever} a piece of information it has no
+means to retrieve automatically. The setting must correspond to the actual
+``current counter'', meaning here ``the counter underlying
+\cs{@currentlabel}'' in a given situation. Also, when using the
+\opt{currentcounter} option, make sure the setting is duly grouped because, if
+set, it has precedence over \cs{@currentcounter} and, contrary to the later,
+the former is not reset the next time \cs{refstepcounter} runs. Its default
+value is, quite naturally, \cs{@currentcounter}. Since this option only
+affects how labels are set, it is not available in \cs{zcref}.
+
+\DescribeOption{nocompat} %
+Some packages, document classes, or LaTeX features may require specific
+support to work with \pkg{zref-clever} (see \zcref{sec:limitations}).
+\pkg{zref-clever} tries to make things smoother by covering some of them.
+Depending on the case, this can take the form of some simple setup for
+\pkg{zref-clever}, or may involve the use of hooks to external environments or
+commands and, eventually, a patch or redefinition. By default, all the
+available compatibility modules are enabled. Should this be undesired or
+cause any problems in your environment, the option \opt{nocompat} can
+selectively or completely inhibit their loading. \opt{nocompat} receives a
+comma separated list of compatibility modules to disable (for the list of
+available modules and details about each of them, see
+\zcref{sec:comp-modules}). You can disable all modules by setting
+\opt{nocompat} without a value (or an empty one). This is a preamble only
+option.
+
+\section{Reference format}
+\zlabel{sec:reference-format}
+
+\subsection{Reference types}
+\zlabel{sec:reference-types}
+
+A ``reference type'' is the basic \pkg{zref-clever} setup unit for specifying
+how a cross-reference group of a certain kind is to be typeset. Though,
+usually, it will have the same name as the underlying \LaTeX{} \emph{counter},
+they are conceptually different. \pkg{zref-clever} sets up \emph{reference
+ types} and an association between each \emph{counter} and its \emph{type},
+it does not define the counters themselves, which are defined by your
+document. One \emph{reference type} can be associated with one or more
+\emph{counters}, and a \emph{counter} can be associated with different
+\emph{types} at different points in your document. But each label is stored
+with only one \emph{type}, as specified by the counter-type association at the
+moment it is set, and that determines how the reference to that label is
+typeset. References to different \emph{counters} of the same \emph{type} are
+grouped together, and treated alike by \cs{zcref}. A \emph{reference type}
+may be known to \pkg{zref-clever} when the \emph{counter} it is associated
+with is not actually defined, and this inconsequential. In practice, the
+contrary may also happen, a \emph{counter} may be defined but we have no
+\emph{type} for it, but this must be handled by \pkg{zref-clever} as an error
+(at least, if we try to refer to it), usually a ``missing name'' error.
+
+\pkg{zref-clever} provides default settings for the following reference types:
+\texttt{part}, \texttt{chapter}, \texttt{section}, \texttt{paragraph},
+\texttt{appendix}, \texttt{subappendix}, \texttt{page}, \texttt{line},
+\texttt{figure}, \texttt{table}, \texttt{item}, \texttt{footnote},
+\texttt{endnote}, \texttt{note}, \texttt{equation}, \texttt{theorem},
+\texttt{lemma}, \texttt{corollary}, \texttt{proposition}, \texttt{definition},
+\texttt{proof}, \texttt{result}, \texttt{remark}, \texttt{example},
+\texttt{algorithm}, \texttt{listing}, \texttt{exercise}, and
+\texttt{solution}. Therefore, if you are using a language for which
+\pkg{zref-clever} has built-in support (see \zcref{sec:internationalization}),
+these reference types are available for use out of the box.\footnote{There may
+ be slight availability differences depending on the language, but
+ \pkg{zref-clever} strives to keep this complete list available for the
+ languages it has built-in dictionaries.} And, in any case, it is always
+easy to setup custom reference types with \cs{zcRefTypeSetup} or
+\cs{zcLanguageSetup} (see \zcref{sec:user-interface, sec:reference-format,
+ sec:internationalization}).
+
+The association of a \emph{counter} to its \emph{type} is controlled by the
+\opt{countertype} option. As seen in its documentation, \pkg{zref-clever}
+presumes the \emph{type} to be the same as the \emph{counter} unless
+instructed otherwise by that option. This association, as determined by the
+local value of the option, affects how the \emph{label} is set, which stores
+the type among its properties. However, when it comes to typesetting, that is
+from the perspective of \cs{zcref}, only the \emph{type} matters. In other
+words, how the reference is supposed to be typeset is determined at the point
+the \emph{label} gets set. In sum, they may be namesakes (or not), but type
+is type and counter is counter.
+
+Indeed, a reference type can be associated with multiple counters because we
+may want to refer to different document elements, with different
+\emph{counters}, as a single \emph{type}, with a single name. One prominent
+case of this are sectioning commands. \cs{section}, \cs{subsection}, and
+\cs{subsubsection} have each their counter, but we'd like to refer to all of
+them by ``sections'' and group them together. The same for \cs{paragraph} and
+\cs{subparagraph}.
+
+There are also cases in which we may want to use different \emph{reference
+ types} to refer to document objects sharing the same \emph{counter}.
+Notably, the environments created with \LaTeX{}'s \cs{newtheorem} command and
+the \cs{appendix}.
+
+
+One more observation about ``reference types'' is due here. A \emph{type} is
+not really ``defined'' in the sense a variable or a function is. It is more
+of a ``string'' which \pkg{zref-clever} uses to look for a whole set of
+type-specific reference format options (see \zcref{sec:ref-format-opts}).
+Each of these options individually may be ``set'' or not, ``defined'' or not.
+And, depending on the setup and the relevant precedence rules for this, some
+of them may be required and some not. In practice, \pkg{zref-clever} uses the
+\emph{type} to look for these options when it needs one, and issues a
+compilation warning when it cannot find a suitable value.
+
+
+\subsection{Reference format options}
+\zlabel{sec:ref-format-opts}
+
+Formatting how the reference is to be typeset is, quite naturally, a big part
+of the user interface of \pkg{zref-clever}. In this area, we tried to balance
+``flexibility'' and ``user friendliness''. But the former does place a big
+toll overall, since there are indeed many places where tweaking may be
+desired, and the settings may depend on at least two important dimensions of
+variation: the reference type and the language. Combination of those
+necessarily makes for a large set of possibilities. Hence, the attempt here
+is to provide a rich set of ``handles'' for fine tuning the reference format
+but, at the same time, do not \emph{require} detailed setup by the users,
+unless they really want it.
+
+With that in mind, we have settled with an user interface for reference
+formatting which allows settings to be done in different scopes, with more or
+less overarching effects, and some precedence rules to regulate the relation
+of settings given in each of these scopes. There are four scopes in which
+reference formatting can be specified by the user, in the following precedence
+order: i) as \emph{general options}; ii) as \emph{type-specific options}; iii)
+as \emph{language-specific and type-specific translations}; and iv) as
+\emph{default translations} (that is, language-specific but not
+type-specific). Besides those, there's a fifth \emph{internal} scope, with
+the least priority of all, a ``fallback'', for the cases where it is
+meaningful to provide some value, even for an unknown language. The package
+itself places the default setup for reference formatting at low precedence
+levels, and the users can easily and conveniently override them as desired.
+
+``General options'' (i) can be given by the user in the optional argument of
+\cs{zcref}, but also set through \cs{zcsetup} or even, depending on the case,
+as package options at load-time (see \zcref{sec:options}).\footnote{The use of
+ \cs{zcsetup} for global reference format settings is recommended though.
+ Whether you can use load-time options or not depends on the values of the
+ options: due to how \LaTeX{} handles package options, if the values of the
+ options you are setting include \emph{commands} you can't set them at
+ load-time, and rather \emph{must} use \cs{zcsetup}.} ``Type-specific
+options'' (ii) are handled by \cs{zcRefTypeSetup} (see
+\zcref{sec:user-interface}). ``Language-specific translations'', be they
+``type-specific'' (iii) or ``default'' (iv) have their user interface in
+\cs{zcLanguageSetup}, and have their values populated by the package's
+built-in dictionaries (see \zcref{sec:internationalization}). Not all
+reference format specifications can be given in all of these scopes, though.
+Some of them can't be type-specific, others must be type-specific, so the set
+available in each scope depends on the pertinence of the case.
+\zcref{tab:reference-format} introduces the available reference format
+options, which will be discussed in more detail soon, and lists the scopes in
+which each is available.
+
+
+\begin{table}[htb]
+ \centering
+ \begin{tabular}{l>{\ttfamily}lcccc}
+ \toprule
+ & & General & Type & Type-specific & Default \\
+ & & options & options & translations & translations \\
+ & & (i) & (ii) & (iii) & (iv) \\
+
+ \midrule
+ Necessarily not & tpairsep & $\bullet$ & & & $\bullet$ \\
+ type-specific & tlistsep & $\bullet$ & & & $\bullet$ \\
+ & tlastsep & $\bullet$ & & & $\bullet$ \\
+ & notesep & $\bullet$ & & & $\bullet$ \\
+
+ \addlinespace
+ Possibly & namesep & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
+ type-specific & pairsep & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
+ & listsep & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
+ & lastsep & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
+ & rangesep & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
+ & refpre & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
+ & refpos & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
+
+ \addlinespace
+ Necessarily & Name-sg & & $\bullet$ & $\bullet$ & \\
+ type-specific & name-sg & & $\bullet$ & $\bullet$ & \\
+ & Name-pl & & $\bullet$ & $\bullet$ & \\
+ & name-pl & & $\bullet$ & $\bullet$ & \\
+ & Name-sg-ab & & $\bullet$ & $\bullet$ & \\
+ & name-sg-ab & & $\bullet$ & $\bullet$ & \\
+ & Name-pl-ab & & $\bullet$ & $\bullet$ & \\
+ & name-pl-ab & & $\bullet$ & $\bullet$ & \\
+
+ \addlinespace
+ Font & namefont & $\bullet$ & $\bullet$ & & \\
+ options & reffont & $\bullet$ & $\bullet$ & & \\
+ \bottomrule
+ \end{tabular}
+ \caption{Reference format options and their scopes}
+ \zlabel{tab:reference-format}
+\end{table}
+
+
+Understanding the role of each of these reference format options is likely
+eased by some visual schemes of how \pkg{zref-clever} builds a reference based
+on the labels' data and the value of these options. Take a \texttt{ref} to be
+that which a standard \LaTeX{} \cs{ref} would typeset. A \pkg{zref-clever}
+``reference block'', or \texttt{ref-block}, is constructed as:
+
+\begin{refformat}
+\item \reffmt{ref-block} \(\equiv\)
+\item \reffmt{refpre} \reffmt{ref} \reffmt{refpos}
+\end{refformat}
+
+A \texttt{ref-block} is built for \emph{each} label given as argument to
+\cs{zcref}. When the \meta{labels} argument is comprised of multiple labels,
+each ``reference type group'', or \texttt{type-group} is potentially made from
+the combination of single reference blocks, ``reference block pairs'',
+``reference block lists'', or ``reference block ranges'', where each is
+respectively built as:
+
+\begin{refformat}
+\item \reffmt{type-group} is a combination of:
+\item \reffmt{ref-block}
+\item \reffmt{ref-block1} \reffmt{pairsep} \reffmt{ref-block2}
+\item \reffmt{ref-block1} \reffmt{listsep} \reffmt{ref-block2}
+ \reffmt{listsep} \reffmt{ref-block3} \dots{} \par \qquad
+ \dots{}\reffmt{ref-blockN-1} \reffmt{lastsep} \reffmt{ref-blockN}
+\item \reffmt{ref-block1} \reffmt{rangesep} \reffmt{ref-blockN}
+\end{refformat}
+
+To complete a ``type-block'', a \texttt{type-group} only needs to be
+accompanied by the ``type name'':
+
+\begin{refformat}
+\item \reffmt{type-block} \(\equiv\)
+\item \reffmt{type-name} \reffmt{namesep} \reffmt{type-group}
+\end{refformat}
+
+The \texttt{type-name} is determined not by one single reference format option
+but by the appropriate one among the \opt{[Nn]ame-} options according to the
+composition of \texttt{type-group} and the general options. The reference
+format name options are eight in total: \opt{Name-sg}, \opt{name-sg},
+\opt{Name-pl}, \opt{name-pl}, \opt{Name-sg-ab}, \opt{name-sg-ab},
+\opt{Name-pl-ab}, and \opt{name-pl-ab}. The initial uppercase ``\texttt{N}''
+signals the capitalized form of the type name. The \texttt{-sg} suffix stands
+for singular, while \texttt{-pl} for plural. The \texttt{-ab} is appended to
+the abbreviated type name form options. When setting up a type, not
+necessarily all forms need to be provided. \pkg{zref-clever} will always use
+the non-abbreviated form as a fallback to the abbreviated one, if the later is
+not available. Hence, if a reference type is not intended to be used with
+abbreviated names (the most common case), only the basic four forms are
+needed. Besides that, if you are using the \opt{cap} option, only the
+capitalized forms will ever be required by \cs{zcref}, so you can get away
+setting only \opt{Name-sg} and \opt{Name-pl}. You should not do the contrary
+though, and provide only the non-capitalized forms because, even if you are
+using the \opt{nocap} option, the capitalized forms will be still required for
+\opt{capfirst} and \opt{S} options to work. Whatever the case may be, you
+need not worry too much about being remiss in this area: if \cs{zcref} does
+lack a name form in any given reference, it will let you know with a
+compilation warning (and will typeset the usual missing reference sign:
+``\textbf{??}'').
+
+A complete reference typeset by \cs{zcref} may be comprised of multiple
+\texttt{type-block}s, in which case the ``type-block-group'' can also be made
+of single type blocks, ``type block pairs'' or ``type block lists'', where
+each is respectively built as:
+
+\begin{refformat}
+\item \reffmt{type-block-group} is one of:
+\item \reffmt{type-block}
+\item \reffmt{type-block1} \reffmt{tpairsep} \reffmt{type-block2}
+\item \reffmt{type-block1} \reffmt{tlistsep} \reffmt{type-block2}
+ \reffmt{tlistsep} \reffmt{type-block3} \dots{} \par \qquad \dots{}
+ \reffmt{type-blockN-1} \reffmt{tlastsep} \reffmt{type-blockN}
+\end{refformat}
+
+Finally, since \cs{zcref} can also receive an optional \opt{note}, its full
+typeset output is built as:
+
+\begin{refformat}
+\item A complete \reffmt{\cs{zcref}} reference:
+\item \reffmt{type-block-group} \reffmt{notesep} \reffmt{note}
+\end{refformat}
+
+Reference format options can yet be divided in two general categories: i)
+``string'' options, the ones which we have seen thus far, as ``building
+blocks'' of the reference; and ii) ``font'' options, which control font
+attributes of parts of the reference, namely \opt{namefont} and \opt{reffont}.
+These options set the font, respectively, for the \texttt{type-name} and for
+\texttt{ref} (to set the font for the whole reference, see the \opt{font}
+option in \zcref{sec:options}). ``String'' options is not really a strict
+denomination for the first category, but this set of options is intended
+exclusively for typesetting material: things you expect to see in the output
+of your references. The ``font'' options, on the other hand, are intended
+exclusively for commands that only change font attributes: style, family,
+shape, weight, size, color, etc. In either case, anything other than their
+intended uses is not supported.
+
+Finally, a comment about the internal ``fallback'' reference format values
+mentioned above. These ``last resort'' option values are required by
+\pkg{zref-clever} for a clear particular case: if the user loads either
+\pkg{babel} or \pkg{polyglossia}, or explicitly sets a language, with a
+language that \pkg{zref-clever} does not know and has no dictionary for, it
+cannot guess what language that is, and thus has to provide some reasonable
+``language agnostic'' default, at least for the options for which this makes
+sense (all the ``string'' options, except for the \texttt{[Nn]ame-} ones).
+Users do not need to have access to this scope, since they know the language
+of their document, or know the values they want for those options, and can set
+them as general options, type-specific options, or language options through
+the user interface provided for the purpose. But the ``fallback'' options are
+documented here so that you can recognize when you are getting these values
+and change them appropriately as desired. Though hopefully reasonable, they
+may not be what you want. The ``fallback'' option values are the following:
+
+\begin{zcexample}[escapeinside=`']
+tpairsep = {,`\textvisiblespace{}'} ,
+tlistsep = {,`\textvisiblespace{}'} ,
+tlastsep = {,`\textvisiblespace{}'} ,
+notesep = {`\textvisiblespace{}'} ,
+namesep = {\nobreakspace} ,
+pairsep = {,`\textvisiblespace{}'} ,
+listsep = {,`\textvisiblespace{}'} ,
+lastsep = {,`\textvisiblespace{}'} ,
+rangesep = {\textendash} ,
+refpre = {} ,
+refpos = {} ,
+\end{zcexample}
+
+
+\section{Internationalization}
+\zlabel{sec:internationalization}
+
+\pkg{zref-clever} provides internationalization facilities and integrates with
+\pkg{babel} and \pkg{polyglossia} to adapt to the languages in use by either
+of these language packages, or to a language specified directly by the user.
+This is primarily relevant for reference format options, particularly
+reference type \emph{names} (though not only, since most reference format
+options can have language-specific values, or ``translations'', see
+\zcref{sec:ref-format-opts}). But other features of the package also cater
+for language specific needs.
+
+As far as language selection is concerned, if the language is declared and
+\pkg{zref-clever} has a built-in ``dictionary'' for it, most use cases will
+likely be covered by the \opt{lang} option (see \zcref{sec:options}), and its
+values \texttt{current} and \texttt{main}. When the \opt{lang} option is set
+to \texttt{current} or \texttt{main}, \pkg{zref-check} will use, respectively,
+the \emph{current} or \emph{main} language of the document, as defined by
+\pkg{babel} or \pkg{polyglossia}.\footnote{Technically, \pkg{zref-clever} uses
+ \cs{languagename} and \cs{bbl@main@language} for \pkg{babel}, and
+ \cs{babelname} and \cs{mainbabelname} for \pkg{polyglossia}, which boils
+ down to \pkg{zref-clever} always using \emph{\pkg{babel} names} internally,
+ regardless of which language package is in use. Indeed, an acquainted user
+ will note that \zcref{tab:languages-and-aliases} contains only \pkg{babel}
+ language names.} Users can also set \opt{lang} to a specific language
+directly, in which case \pkg{babel} and \pkg{polyglossia} are disregarded.
+\pkg{zref-clever} provides a number of built-in ``dictionaries'', for the
+languages listed in \zcref{tab:languages-and-aliases}, which also includes the
+declared aliases to those languages.
+
+\pkg{zref-clever}'s ``dictionaries'' are loaded sparingly and lazily. A
+dictionary for a single language -- that specified by user options in the
+preamble, which by default is the current document language -- is loaded at
+\texttt{begindocument}. If any other dictionary is needed, it is loaded on
+the fly, if and when required. Of course, in either case, conditioned on
+availability. In sum, \pkg{zref-clever} loads as little as possible, but
+allows for convenient on the fly loading of dictionaries if the values are
+indeed required, without users having to worry about it at all.
+
+\begin{table}
+ \centering
+ \begin{tabular}{ll}
+ \toprule
+ Language & Aliases \\
+ \midrule
+ english & american \\
+ & australian \\
+ & british \\
+ & canadian \\
+ & newzealand \\
+ & UKenglish \\
+ & USenglish \\
+ french & acadian \\
+ & canadien \\
+ & francais \\
+ & frenchb \\
+ \bottomrule
+ \end{tabular}
+ \quad
+ \begin{tabular}{ll}
+ \toprule
+ Language & Aliases \\
+ \midrule
+ german & austrian \\
+ & germanb \\
+ & ngerman \\
+ & naustrian \\
+ & nswissgerman \\
+ & swissgerman \\
+ portuguese & brazilian \\
+ & brazil \\
+ & portuges \\
+ spanish & \\
+ & \\
+ \bottomrule
+ \end{tabular}
+ \caption{Declared languages and aliases}
+ \zlabel{tab:languages-and-aliases}
+\end{table}
+
+
+But if the built-in dictionaries do not cover your language, or if you'd like
+to adjust some of the default language-specific options, this can be done with
+\cs{zcDeclareLanguage}, \cs{zcDeclareLanguageAlias}, and
+\cs{zcLanguageSetup}.\footnote{Needless to say, if you'd like to contribute a
+ dictionary or improve an existing one, that is much welcome at
+ \url{https://github.com/gusbrs/zref-clever/issues}.}
+
+\begin{function}{\zcDeclareLanguage}
+ \begin{syntax}
+ \cs{zcDeclareLanguage}\oarg{options}\marg{language}
+ \end{syntax}
+\end{function}
+Declare a new language for use with \pkg{zref-clever}. If \meta{language} has
+already been declared, just warn. The \meta{options} argument receives the
+usual \texttt{key=value} list and recognizes three keys: \opt{declension},
+\opt{gender}, and \opt{allcaps}. \opt{declension} receives a coma separated
+list of valid declension cases for \meta{language}. The first element of the
+list is considered to be the default case, both for the \opt{d} option in
+\cs{zcref} and for the \opt{case} option in \cs{zcLanguageSetup}. Similarly,
+\opt{gender} receives a comma separated list of genders for \meta{language}.
+The elements in this list are those which are recognized as valid for the
+language for both the \opt{g} option in \cs{zcref} and the \opt{gender} option
+in \cs{zcLanguageSetup}. There is no default presumed in this case. Finally,
+\opt{allcaps} can be used with languages for which nouns must be always
+capitalized for grammatical reasons. For a language declared with the
+\opt{allcaps} option, the \opt{cap} reference option (see \zcref{sec:options})
+is disregarded, and \cs{zcref} always uses the capitalized type name forms.
+This means that dictionaries for languages with such a trait can be halved in
+size, and that user customization for them is simplified, only requiring the
+capitalized name forms. On the other hand, the non-capitalized \texttt{name-}
+reference format options are rendered no-op for the language in question.
+\zcref[S]{tab:language-options} presents an overview of the options in effect
+for the languages declared by \pkg{zref-clever}. \cs{zcDeclareLanguage} is
+preamble only.
+
+\begin{table}
+ \centering
+ \begin{tabular}{l>{\ttfamily}c>{\ttfamily}c>{\ttfamily}c}
+ \toprule
+ Language & declension & gender & allcaps \\
+ \midrule
+ english & -- & -- & -- \\
+ french & -- & f,m & -- \\
+ german & N,A,D,G & f,m,n & yes \\
+ portuguese & -- & f,m & -- \\
+ spanish & -- & f,m & -- \\
+ \bottomrule
+ \end{tabular}
+ \caption{Options for declared languages}
+ \zlabel{tab:language-options}
+\end{table}
+
+\begin{function}{\zcDeclareLanguageAlias}
+ \begin{syntax}
+ \cs{zcDeclareLanguageAlias}\marg{language alias}\marg{aliased language}
+ \end{syntax}
+\end{function}
+Declare \meta{language alias} to be an alias of \meta{aliased language}.
+\meta{aliased language} must be already known to \pkg{zref-clever}. Once set,
+the \meta{language alias} is treated by \pkg{zref-clever} as completely
+equivalent to the \meta{aliased language} for any language specification by
+the user. \cs{zcDeclareLanguageAlias} is preamble only.
+
+\begin{function}{\zcLanguageSetup}
+ \begin{syntax}
+ \cs{zcLanguageSetup}\marg{language}\marg{options}
+ \end{syntax}
+\end{function}
+Sets language-specific reference format options for \meta{language} (see
+\zcref{sec:ref-format-opts}), be they type-specific or not. \meta{language}
+must be already known to \pkg{zref-clever}. Besides reference format options,
+\cs{zcLanguageSetup} knows three other keys: \opt{type}, \opt{case}, and
+\opt{gender}. The first two work like a ``switch'' affecting the options
+\emph{following} it. For example, if \texttt{type=foo} is given in
+\meta{options} the options following it will be set as type-specific options
+for reference type \texttt{foo}. Similarly, after \texttt{case=X} (provided
+\texttt{X} is a valid declension case for \meta{language}), the following
+\texttt{[Nn]ame-} options will set values for the \texttt{X} declension case
+(other reference format options are not affected by \opt{case}). Before the
+first occurrence of either \opt{type} or \opt{case} default values are set.
+For \opt{case} this means the default declension case, which is the first
+element of the list provided to the \opt{declension} option in
+\cs{zcDeclareLanguage}. For \opt{type} this means ``default translations'',
+which are language-specific but not type-specific option values (see
+\zcref{sec:ref-format-opts}). An empty valued \texttt{type=} key can also
+``unset'' the type. The \opt{gender} key sets the gender of the current
+\texttt{type} (provided the value it receives is one of the declared genders
+for \meta{language}). \cs{zcLanguageSetup} is preamble only.
+
+A couple of examples to illustrate the syntax of \cs{zcLanguageSetup}:
+
+\begin{zcexample}
+\zcLanguageSetup{french}{
+ type = section ,
+ gender = f ,
+ Name-sg = Section ,
+ name-sg = section ,
+ Name-pl = Sections ,
+ name-pl = sections ,
+}
+\zcLanguageSetup{german}{
+ type = section ,
+ gender = m ,
+ case = N ,
+ Name-sg = Abschnitt ,
+ Name-pl = Abschnitte ,
+ case = A ,
+ Name-sg = Abschnitt ,
+ Name-pl = Abschnitte ,
+ case = D ,
+ Name-sg = Abschnitt ,
+ Name-pl = Abschnitten ,
+ case = G ,
+ Name-sg = Abschnitts ,
+ Name-pl = Abschnitte ,
+}
+\end{zcexample}
+
+\bigskip{}
+
+As already noted, \pkg{zref-clever} has some support for languages with
+declension. This means mainly the declension of \emph{nouns}, which is used
+for the reference type names. But some tools are also provided to support the
+user in getting better results for the text surrounding a reference,
+particularly for numbered and gendered articles, even if those don't have
+their typeset output automated.
+
+For reference type names, the declension cases for each language must be
+declared with \cs{zcDeclareLanguage}, and the name reference format options
+must be provided for each case, which is done for built-in dictionaries of
+languages which have noun declension, and can be done by the user with
+\cs{zcLanguageSetup}, as we've seen. \pkg{zref-clever} does not try to guess
+or infer the case though, you must tell it to \cs{zcref}. And this is done by
+means of the \opt{d} option (see \zcref{sec:options}). So you may write
+something like ``\texttt{nach den
+ \cs{zcref}[d=D]\{sec:section-1,sec:section-2\}}'' to get ``nach den
+Abschnitten 1 und 2''. Or ``\texttt{trotz des
+ \cs{zcref}[d=G]\{eq:theorem-1\}}'' to get ``trotz des Theorems 1''.
+
+Regarding the text surrounding the reference -- the inflected article, the
+passing preposition, etc.\ --, the issue is more delicate. \pkg{zref-clever}
+cannot and intends not to typeset those for you. But, depending on the
+language, it is true that the kind of automation provided by \pkg{zref-clever}
+may betray your best efforts to get a proper surrounding text. Multiple
+labels passed to \cs{zcref} may result in singular type names, either because
+the labels are of different types, or because they got compressed into a
+single reference. References comprised of multiple type blocks may have each
+a name with a different gender. Or, worse, \opt{tpairsep}, \opt{tpairsep},
+and \opt{tlastsep} may not provide a general enough way to separate different
+type blocks in your language altogether. You may change something in your
+document that causes a label to change its type, and hence the gender of the
+type name. A page reference to a couple of floats which were by chance on the
+same page and all of a sudden no longer are. And so on.
+
+In this area, the approach taken by \pkg{zref-clever} is to identify some
+typical situations in which your attention may be required in reviewing the
+surrounding text, and signal it at compilation time. Just like bad boxes, for
+example. This feature can be enabled by the \opt{nudge} option (which is
+opt-in, see \zcref{sec:options}). There are three ``nudges'' available for
+this purpose which trigger messages at different events: \opt{multitype},
+\opt{comptosing}, and \opt{gender}. \opt{multitype} nudges when a reference
+is comprised of multiple type blocks. \opt{comptosing} when multiple labels
+of the same type block have been compressed into a single one and, hence, the
+type name used is singular. Finally, \opt{gender} nudges when there is a
+mismatch between the gender specified in \cs{zcref} with the \opt{g} option
+and the gender of the type name, as stored in the dictionary or language
+settings, for each type block. Which nudges to use is configurable with the
+option \opt{nudgeif}. And, if you're sure of the results for a particular
+\cs{zcref} call, you can always silence the nudges locally with the
+\opt{nonudge} option.
+
+The main reason to watch for multiple type references with the \opt{multitype}
+nudge is that bundling together automatically a list of type blocks is less
+smooth an operation than it is for a single reference type. While it arguably
+works reasonably well for English, even there it is not always flawless, and
+depending on the language, results may range from ``poor style'' to outright
+wrong. A typical case would be of that of a language with inflected articles
+and a reference with multiple types of different genders or numbers. For
+example, in French, with a standard ``\texttt{au \cs{zcref}\{cha:chapter-3,
+ sec:section-3.1\}}'' we get ``au chapitre 3 et section 3.1'' which sounds
+ugly, at best. So we may be better off writing instead ``\texttt{au
+ \cs{zcref}\{cha:chapter-3\} et à la \cs{zcref}\{sec:section-3.1\}}''. Or
+something else, of course. But the general point is that, depending on
+circumstances and on the language, the results of automating the grouping of
+multiple reference types, as \pkg{zref-clever} is able to do, may leave things
+to be desired for. Hence it lets you know when one such case occurs, so that
+you can review it for best results.
+
+The case of the \opt{comptosing} and \opt{gender} nudges is more objective in
+nature, they respectively signal mismatches of number and gender. When a
+reference is made with \cs{zcref} to a single label we are sure the type name
+will be a singular form. However, when \cs{zcref} receives multiple labels of
+the same type, the type name will normally be a plural, but not necessarily
+so, since the labels may be compressed into a single one (see the \opt{comp}
+option in \zcref{sec:options}), in which case the singular is used. The
+compression of multiple labels into a single reference should be an exception
+for default references, but not so for \opt{page} references, where it is easy
+to conceive practical situations where it may occur. Suppose, for example,
+you have two contiguous floats in your document and make a page reference to
+both of them. Will they end up in the same page or not? Maybe we know what
+the current state is, but we cannot know what may happen as the document keeps
+being edited. As a consequence, we don't know whether that reference will end
+up having a plural or a singular type name. That given, the logic of the
+\opt{comptosing} nudge is the following. If we are giving multiple labels to
+\cs{zcref}, we can \emph{presume} a plural type name, but we get a nudge in
+case the compression of the labels results in a singular type name form. If
+one such compression did happen to one of your references, you can use a
+singular article and then tell \cs{zcref} you did so with option \opt{sg}.
+The effect of the \opt{sg} option is to inhibit the nudge when a compression
+to singular occurs, but to do it instead when the compression \emph{ceases} to
+occur, that is, if we get a plural type name again at some point.
+
+The \opt{gender} nudge aims to guard against one particular situation:
+possible changes of a reference's type. This does not occur by reason of any
+internal behavior of \pkg{zref-clever}, but it may be caused by changes in the
+document. You may wish to change one \texttt{theorem} into a
+\texttt{proposition} and, if you're writing in French or Portuguese, for
+example, that implies that the reference to it changes gender and the likely
+preceding article will no longer pass to the reference. The \opt{gender}
+nudge requires that the gender of each type name and of each reference be
+explicitly specified. For the type names, this is done for the built-in
+dictionaries of languages were this matters, and can be done with
+\cs{zcLanguageSetup} as well. For the references, that is the purpose of the
+\opt{g} option. When there is a mismatch between the two for any type block,
+the nudge is triggered. Of couse, this means that the gender markup has to be
+supplied in the document at each reference. And considering such type changes
+may not be frequent for you, or considered not particularly problematic,
+you'll have to balance if doing so is worth it. Still, the feature is
+available, and it's up to you.
+
+
+\section{How-tos}
+
+This section gathers some usage examples, or ``how-tos'', of cases which may
+require some \pkg{zref-clever} setup, or usage adjustments, and each item is
+set around a cross-reference ``task'' we'd like to perform with
+\pkg{zref-clever}.
+
+
+\subsection{Context sensitive references}
+
+\zctask{Make cross-references which are sensitive to the relative position
+ between the reference and the label being referred to, à la \pkg{varioref}.}
+
+\pkg{varioref}'s \cs{vref} provides for varied references for three different
+basic cases: when the reference and the label are on the same page, it
+typesets a plain reference; when the reference and the label are in contiguous
+pages (next, previous, or facing), it typesets the reference and a fixed
+string corresponding to the relative position; when the reference and the
+label are in different non-contiguous pages, it typesets a regular reference
+and a page reference. The same end result, but with a different user
+interface concept can be achieved through \pkg{zref-clever}'s integration with
+\pkg{zref-check}. For this, the later must be loaded, which can be most
+conveniently done with the \opt{check} option in the preamble. With that in
+place, the different cases could be covered by the following examples:
+
+\begin{zcexample}
+\zcref[check=thispage]{fig:1}
+\zcref[check=nextpage,note={on the following page}]{fig:1}
+\zcref[check=prevpage,note={on the preceding page}]{fig:1}
+\zcref[check=facing,note={on the facing page}]{fig:1}
+\zcref[check=pagegap]{fig:1} on \zcpageref{fig:1}
+\end{zcexample}
+
+And, similarly for the cases of \cs{vpageref}:
+
+\begin{zcexample}
+\zcref[noref,check=thispage,note={on this page}]{fig:1}
+\zcref[noref,check=nextpage,note={on the following page}]{fig:1}
+\zcref[noref,check=prevpage,note={on the preceding page}]{fig:1}
+\zcref[noref,check=facing,note={on the facing page}]{fig:1}
+\zcref[noref,check=pagegap]{fig:1} on \zcpageref{fig:1}
+\end{zcexample}
+
+Since \cs{zcref} can receive multiple labels, and make ranges out of them, it
+is not difficult to extend these examples to the functionality of
+\cs{vrefrange} and \cs{vpagerefrange}.
+
+Evidently, this does not fully automate the typeset results, but it does
+automate the checking that the reference context is the intended one. If the
+relation between the reference and the label does not correspond to the
+specified one, a compilation warning is issued (according to the options given
+to \pkg{zref-check}), so that the problem can be easily identified and
+corrected. See \pkg{zref-check}'s documentation for details, and further
+available checks.
+
+
+\subsection{\cs{newtheorem}}
+
+Since \LaTeX{}'s \cs{newtheorem} allows users to create arbitrary numbered
+environments, with respective arbitrary counters, the most \pkg{zref-clever}
+can do in this regard is to provide some ``typical'' built-in reference types
+to smooth user setup but, in the general case, some user setup may be indeed
+required. The examples below are equaly valid for \pkg{amsthm}'s
+\cs{newtheorem} since, even it provides features beyond those available in the
+kernel, its syntax and underlying relation with counters is pretty much the
+same. The same for \pkg{ntheorem}. For \pkg{thmtools}' \cs{declaretheorem},
+though some adjustments to the examples below may be required, the basic logic
+is the same (there is no integration with the \opt{Refname}, \opt{refname},
+and \opt{label} options, which are targeted to the standard reference system,
+but you don't actually need them to get things working conveniently).
+
+
+\subsubsection*{Simple case}
+
+\zctask{Setup up a new theorem environment created with \cs{newtheorem} to be
+ referred to with \cs{zcref}. The theorem environment does not share its
+ counter with other theorem environments, and one of \pkg{zref-clever}
+ built-in reference types is adequate for my needs.}
+
+Suppose you set a ``Lemma'' environment with:
+
+\begin{zcexample}
+\newtheorem{lemma}{Lemma}[section]
+\end{zcexample}
+
+In this case, since \pkg{zref-clever} provides a built-in \texttt{lemma} type
+(for supported languages) and presumes the reference type to be the same name
+as the counter, there is no need for setup, and things just work out of the
+box. So, you can go ahead with:
+
+\begin{zchowto}[caption={\cs{newtheorem}, simple case}]
+\documentclass{article}
+\usepackage{zref-clever}
+\newtheorem{lemma}{Lemma}[section]
+\begin{document}
+\section{Section 1}
+\begin{lemma}\zlabel{lemma-1}
+ A lemma.
+\end{lemma}
+\zcref{lemma-1}
+\end{document}
+\end{zchowto}
+
+If, however, you had chosen an environment name which did not happen to
+coincide with the built-in reference type, all you'd need to do is instruct
+\pkg{zref-clever} to associate the counter for your environment to the desired
+type with the \opt{countertype} option:
+
+\begin{zchowto}[caption={\cs{newtheorem}, simple case}]
+\documentclass{article}
+\usepackage{zref-clever}
+\zcsetup{countertype={lem=lemma}}
+\newtheorem{lem}{Lemma}[section]
+\begin{document}
+\section{Section 1}
+\begin{lem}\zlabel{lemma-1}
+ A lemma.
+\end{lem}
+\zcref{lemma-1}
+\end{document}
+\end{zchowto}
+
+
+\subsubsection*{Shared counter}
+
+\zctask{Setup up two new theorem environments created with \cs{newtheorem} to
+ be referred to with \cs{zcref}. The theorem environments share the same
+ counter, and the available \pkg{zref-clever} built-in reference types are
+ adequate for my needs.}
+
+In this case, we need to set the \opt{countertype} option in the appropriate
+contexts, so that the labels of each environment get set with the expected
+reference type. As we've seen (at \zcref{sec:user-interface}), \cs{zcsetup}
+has local effects, so it can be issued inside the respective environments for
+the purpose. Even better, we can leverage the kernel's new hook management
+system and just set it for all occurrences with
+\cs{AddToHook}\texttt{\{env/\meta{myenv}/begin\}}.
+
+\begin{zchowto}[caption={\cs{newtheorem}, shared counter}]
+\documentclass{article}
+\usepackage{zref-clever}
+\AddToHook{env/mytheorem/begin}{%
+ \zcsetup{countertype={mytheorem=theorem}}}
+\AddToHook{env/myproposition/begin}{%
+ \zcsetup{countertype={mytheorem=proposition}}}
+\newtheorem{mytheorem}{Theorem}[section]
+\newtheorem{myproposition}[mytheorem]{Proposition}
+\begin{document}
+\section{Section 1}
+\begin{mytheorem}\zlabel{theorem-1}
+ A theorem.
+\end{mytheorem}
+\begin{myproposition}\zlabel{proposition-1}
+ A proposition.
+\end{myproposition}
+\zcref{theorem-1, proposition-1}
+\end{document}
+\end{zchowto}
+
+
+\subsubsection*{Custom type}
+
+\zctask{Setup up a new theorem environment created with \cs{newtheorem} to be
+ referred to with \cs{zcref}. The theorem environment does not share its
+ counter with other theorem environments, but none of \pkg{zref-clever}
+ built-in reference types is adequate for my needs.}
+
+In this case, we need to provide \pkg{zref-clever} with settings pertaining to
+the custom reference type we'd like to use. Unless you need to typeset your
+cross-references in multiple languages, in which case you'd require
+\cs{zcLanguageSetup}, the most convenient way to setup a reference type is
+\cs{zcRefTypeSetup}. In most cases, what we really need to provide for a
+custom type are the ``type names'' and other reference format options can rely
+on default translations already provided by the package (assuming the language
+is supported).
+
+\begin{zchowto}[caption={\cs{newtheorem}, custom type}]
+\documentclass{article}
+\usepackage{zref-clever}
+\newtheorem{myconjecture}{Conjecture}[section]
+\zcRefTypeSetup{myconjecture}{
+ Name-sg = Conjecture ,
+ name-sg = conjecture ,
+ Name-pl = Conjectures ,
+ name-pl = conjectures ,
+}
+\begin{document}
+\section{Section 1}
+\begin{myconjecture}\zlabel{conjecture-1}
+ A conjecture.
+\end{myconjecture}
+\zcref{conjecture-1}
+\end{document}
+\end{zchowto}
+
+
+\subsection{\pkg{newfloat}}
+
+\zctask{Setup a new float environment created with \pkg{newfloat} to be
+ referred to with \cs{zcref}. None of \pkg{zref-clever} built-in reference
+ types is adequate for my needs.}
+
+The case here is pretty much the same as that for \cs{newtheorem} with a
+custom type. Hence, we need to setup a corresponding type, for which
+providing the ``type names'' should normally suffice. Note that, as far as
+\pkg{zref-clever} is concerned, there's nothing specific to the \pkg{newfloat}
+package in the setup, the same procedure can be used with \cls{memoir}'s
+\cs{newfloat} command or with the \pkg{float}, \pkg{floatrow}, and
+\pkg{trivfloat} packages.
+
+\begin{zchowto}[caption={\pkg{newfloat}}]
+\documentclass{article}
+\usepackage{newfloat}
+\DeclareFloatingEnvironment{diagram}
+\usepackage{zref-clever}
+\zcRefTypeSetup{diagram}{
+ Name-sg = Diagram ,
+ name-sg = diagram ,
+ Name-pl = Diagrams ,
+ name-pl = diagrams ,
+}
+\begin{document}
+\section{Section 1}
+\begin{diagram}
+ A diagram.
+ \caption{A diagram}
+ \zlabel{diagram-1}
+\end{diagram}
+\zcref{diagram-1}
+\end{document}
+\end{zchowto}
+
+
+\subsection{\pkg{amsmath}}
+
+\zctask{Make references to \pkg{amsmath} display math environments with
+ \cs{zcref}.}
+
+Given how \pkg{amsmath}'s display math environments work, they need to handle
+\cs{label} specially, and this support is quite hard-wired into the
+environments, but it is not extended to \cs{zlabel}. \pkg{zref-clever}'s
+\opt{amsmath} compatibility module provides that a \cs{label} used inside
+these environments set both a regular \cs{label} and a \cs{zlabel}, so that we
+can refer to the equations with both referencing systems. Note the use of
+\cs{zlabel} for \env{subequations} though. For more details, see the
+description of the \opt{amsmath} compatibility module at
+\zcref{sec:comp-modules}.
+
+\begin{zchowto}[caption={\pkg{amsmath}},label={how:amsmath}]
+\documentclass{article}
+\usepackage{amsmath}
+\usepackage{zref-clever}
+\usepackage{hyperref}
+\begin{document}
+\section{Section 1}
+\begin{equation}\label{eq:1}
+ A^{(1)}_l =\begin{cases} n!,&\text{if }l =1\\
+ 0,&\text{otherwise}.\end{cases}
+\end{equation}
+\begin{equation*} \tag{foo}\label{eq:2}
+ A^{(1)}_l =\begin{cases} n!,&\text{if }l =1\\
+ 0,&\text{otherwise}.\end{cases}
+\end{equation*}
+\begin{subequations}\zlabel{eq:3}
+ \begin{align}
+ A+B&=B+A\\
+ C&=D+E\label{eq:3b}\\
+ E&=F
+ \end{align}
+\end{subequations}
+\zcref{eq:1, eq:2, eq:3, eq:3b}
+\end{document}
+\end{zchowto}
+
+
+\subsection{\pkg{listings}}
+
+\zctask{Make references to a \env{lstlisting} environment from the
+ \pkg{listings} package with \cs{zcref}.}
+
+Being \env{lstlisting} a verbatim environment, setting labels inside it
+requires special treatment. \pkg{zref-clever}'s \opt{listings} compatibility
+module provides that a label given to the \opt{label} option gets set with
+both a regular \cs{label} and a \cs{zlabel}, so that we can refer to it with
+both referencing systems. Setting labels for specific lines of the
+environment can be done with \cs{zlabel} directly, subject to the same
+escaping as for the standard \cs{label}. For more details, see the
+description of the \opt{listings} compatibility module at
+\zcref{sec:comp-modules}.
+
+\begin{zchowto}[caption={\pkg{listings}},label={how:listings},escapeinside=`']
+\documentclass{article}
+\usepackage{listings}
+\usepackage{zref-clever}
+\usepackage{hyperref}
+\begin{document}
+\section{Section 1}
+\lstset{escapeinside={(*@}{@*)}, numbers=left, numberstyle=\tiny}
+\begin{lstlisting}[caption={Useless code}, label=lst:1]
+ for i:=maxint to 0 do
+ begin
+ { do nothing }(*@\zlabel{ln:1.1}@*)
+ end;
+\end{lstlisting}
+\zcref{lst:1, ln:1.1}
+\end{document}
+\end{zchowto}
+
+
+\subsection{\pkg{enumitem}}
+
+\zctask{Setup a custom enumerate environment created with \pkg{enumitem} to be
+ referred to with \cs{zcref}.}
+
+Since the \texttt{enumerate} environment's counters are reset at each nesting
+level, but not with the standard machinery, we have to inform
+\pkg{zref-clever} of this resetting behavior with the \opt{counterresetby}
+option. Also, given the naming of the underlying counters is tied with the
+environment's name and the level's number, we cannot really rely on an
+implicit counter-type association, and have to set it explicitly with the
+\opt{countertype} option.
+
+\begin{zchowto}[caption={\pkg{enumitem}}]
+\documentclass{article}
+\usepackage{zref-clever}
+\zcsetup{
+ countertype = {
+ myenumeratei = item ,
+ myenumerateii = item ,
+ myenumerateiii = item ,
+ myenumerateiv = item ,
+ } ,
+ counterresetby = {
+ myenumerateii = myenumeratei ,
+ myenumerateiii = myenumerateii ,
+ myenumerateiv = myenumerateiii ,
+ }
+}
+\usepackage{enumitem}
+\newlist{myenumerate}{enumerate}{4}
+\setlist[myenumerate,1]{label=(\arabic*)}
+\setlist[myenumerate,2]{label=(\Roman*)}
+\setlist[myenumerate,3]{label=(\Alph*)}
+\setlist[myenumerate,4]{label=(\roman*)}
+\begin{document}
+\begin{myenumerate}
+\item An item.\zlabel{item-1}
+ \begin{myenumerate}
+ \item An item.\zlabel{item-2}
+ \begin{myenumerate}
+ \item An item.\zlabel{item-3}
+ \begin{myenumerate}
+ \item An item.\zlabel{item-4}
+ \end{myenumerate}
+ \end{myenumerate}
+ \end{myenumerate}
+\end{myenumerate}
+\zcref{item-1, item-2, item-3, item-4}
+\end{document}
+\end{zchowto}
+
+
+\subsection{\pkg{zref-xr}}
+
+\zctask{Make references to labels set in an external document with
+ \cs{zcref}.}
+
+\pkg{zref} itself offers this functionality with module \pkg{zref-xr}, and
+\pkg{zref-clever} is prepared to make use of it. Just a couple of details
+have to be taken care of, for it to work as intended: i) \pkg{zref-clever}
+must be loaded in both the main document and the external document, so that
+the imported labels also contain the properties required by \pkg{zref-clever};
+ii) since \cs{zexternaldocument} defines any properties it finds in the labels
+from the external document when it imports them, it must be called after
+\pkg{zref-clever} is loaded, otherwise the later will find its own internal
+properties already defined when it does get loaded, and will justifiably
+complain. Note as well that the starred version of \cs{zexternaldocument*},
+which imports the standard labels from the external document, is not
+sufficient for \pkg{zref-clever}, since the imported labels will not contain
+all the required properties.
+
+Assuming here \file{documentA.tex} as the main file and \file{documentB.tex}
+as the external one, and also assuming we just want to refer in ``\texttt{A}''
+to the labels from ``\texttt{B}'', and not the contrary, a minimum setup would
+be the following.
+
+
+\begin{zchowto}[caption={\pkg{zref-xr}},escapeinside=`']
+`\hspace*{-1em}\file{documentA.tex}:\vspace{1ex}'
+\documentclass{article}
+\usepackage{zref-clever}
+\usepackage{zref-xr}
+\zexternaldocument[B-]{documentB}
+\usepackage{hyperref}
+\begin{document}
+\section{Section A1}
+\zlabel{sec:section-a1}
+\zcref{sec:section-a1, B-sec:section-b1}
+\end{document}
+`\vspace{-1ex}'
+`\hspace*{-1em}\file{documentB.tex}:\vspace{1ex}'
+\documentclass{article}
+\usepackage{zref-clever}
+\usepackage{hyperref}
+\begin{document}
+\section{Section B1}
+\zlabel{sec:section-b1}
+\end{document}
+\end{zchowto}
+
+\section{Compatibility}
+\zlabel{sec:compatibility}
+
+\subsection{Limitations}
+\zlabel{sec:limitations}
+
+Being based on \pkg{zref} entails one quite sizable advantage for
+\pkg{zref-clever}: the extensible referencing system of the former allows
+\pkg{zref-clever} to store and retrieve the information it needs to work
+without having to redefine some core \LaTeX{} commands. This alone makes for
+reduced compatibility problems and less load order issues than the average
+package in this functionality area. On the other hand, being based on
+\pkg{zref} also does impair the supported scope of \pkg{zref-clever}. Not
+because of any particular limitation of either, but because any class or
+package which implements some special handling for reference labels
+universally does so aiming at the standard referencing system, and whether
+specific support for \pkg{zref} is included, or whether things work by
+spillover of the particular technique employed, is not guaranteed.
+
+The limitation here is less one of \pkg{zref-clever} than that of a potencial
+lack of support for \pkg{zref} itself. Broadly speaking, what
+\pkg{zref-clever} does is setup \pkg{zref} so that its \cs{zref@newlabel}s
+contains the information we need using \pkg{zref}'s API. Once the \cs{zlabel}
+is set correctly, there is little in the way of \pkg{zref-clever}, it can just
+extract the label's information, again using \pkg{zref}'s API, and do its job.
+Therefore, the problems that may arise are really in \emph{label setting}.
+
+For \cs{zlabel} to be able to set a label with everything \pkg{zref-clever}
+needs, some conditions must be fulfilled, most of which are pretty much the
+same as that of a regular label, but not only. As far as my experience goes,
+the following label setting requirements can be potentially problematic and
+are not necessarily granted for \cs{zlabel}:
+
+\begin{enumerate}
+\item One must be able to call \cs{zlabel}, directly or indirectly, at the
+ appropriate scope/location so as to set the label.
+\item When \cs{zlabel} is set, it must see a correct value of
+ \cs{@currentcounter}.
+\end{enumerate}
+
+As to the first, it is not everywhere we technically can set a (z)label. On
+verbatim-like environments it depends on how they are defined and whether they
+provide a proper place or option to do so. But other places may be
+problematic too, for example, \pkg{amsmath} display math environments also
+handle \cs{label} specially and the same work is not done for \cs{zlabel}.
+
+Regarding the second, a correctly set \cs{@currentcounter} is critical for the
+task of \pkg{zref-clever}: the reference type will depend on that and,
+consequently, sorting and compression as well, counter resetting behavior
+information is also retrieved based on it, and so on. Since the 2020-10-01
+\LaTeX{} release, \cs{@currentcounter} is set by \cs{refstepcounter} alongside
+\cs{@currentlabel} and, since the 2021-11-15 release, the support for
+\cs{@currentcounter} has been further extended in the kernel. Hence, as long
+as kernel features are involved, or as long as \cs{refstepcounter} is the tool
+used for the purpose of reference setting, \cs{zlabel} will tend to have all
+information within its grasp at label setting time. But that's not always the
+case. For this reason, \pkg{zref-clever} has the option \opt{currentcounter}
+which at least allows for some viable work-arounds when the value of
+\cs{@currentcounter} cannot be relied upon. Whether we have a proper opening
+to set it, depends on the case. Still, \cs{refstepcounter} is ubiquitous
+enough a tool that we can count on \cs{@currentcounter} most of the time.
+
+All in all, most things work, but some things don't. And if the later will
+eventually work depends essentially on whether support for \pkg{zref} is
+provided by the relevant packages and classes or not. Or, failing that,
+whether \pkg{zref-clever} is able to provide some specific support when a
+reasonable way to do so is within reach.
+
+
+\subsection{Compatibility modules}
+\zlabel{sec:comp-modules}
+
+This section gives a description of each compatibility module provided by
+\pkg{zref-clever}. These modules intend to smooth the interaction of \LaTeX{}
+features, document classes, and packages with \pkg{zref-clever} and
+\pkg{zref}, and they can be selectively or completely disabled with the option
+\opt{nocompat} (see \zcref{sec:options}). This set is not to be confused with
+``the list of packages or classes supported by \pkg{zref-clever}''. In most
+circumstances, things should just work out of the box, and need no specific
+handling. These are just the ones for which some special treatment was
+required. Of course, this effort is bound to be incomplete (see
+\zcref{sec:limitations}).
+
+The purpose of outlining to some extend what the compatibility modules do is
+twofold. First, some of them require usage adjustments for label setting,
+which must be somehow conveyed in this documentation. Second, the kind and
+degree of intervention in external code varies significantly for each module,
+and since this is an area of potential friction, a minimum of information for
+the users to judge whether they want to leave these modules enabled or not is
+due. For this reason, this is also a little technical, but for full details,
+see the code documentation.
+
+\bigskip{}
+
+\DescribeOption{appendix} %
+The \cs{appendix} command provided by many document classes is normally used
+to change the behavior of the sectioning commands after that point. Usually,
+depending on the class, the changes that interest us involve using \cs{@Alph}
+for numbering and \cs{appendixname} for chapter's names. In sum, we'd like to
+refer to the appendix sectioning commands as ``appendices'' rather than
+``chapters'' or ``sections''. Since the sectioning commands are the same as
+before \cs{appendix}, and so are their underlying counters, we must configure
+the counter type of the sectioning counters to \texttt{appendix}. And this is
+what this compatibility module does, and it uses a \pkg{ltcmdhooks} hook on
+\cs{appendix} for the purpose. Hence, this module applies to any document
+class or package which provides that command.
+
+\DescribeOption{appendices} %
+This module implements support for the \env{appendices} and
+\env{subappendices} environments provided by the \pkg{appendix} package, and
+also by \cls{memoir}. The task is the same as for the \texttt{appendix}
+module: set proper counter types for the sectioning counters. This module
+employs environment hooks to \env{appendices} and \env{subappendices} and a
+command hook to \cs{appendix} for the purpose.
+
+\DescribeOption{memoir} %
+The \cls{memoir} class implements several features with one or another
+implication for cross-referencing, usually bearing just the standard
+referencing system in mind, and related mainly to captions, subfloats, and
+notes. This compatibility module tries to adjust \pkg{zref-clever} to these
+features with support for the following: i) set counter types for counters
+\texttt{subfigure}, \texttt{subtable}, and \texttt{poemline} (used in the
+\env{verse} environment); ii) configure resetting behavior
+(\opt{counterresetby} option) for \texttt{subfigure} and \texttt{subtable}
+counters; iii) provide that the \meta{label} arguments to environments
+\env{sidecaption} and \env{sidecontcaption} and commands \cs{bitwonumcaption},
+\cs{bionenumcaption}, and \cs{bicaption} \emph{also} set a \cs{zlabel} of the
+same name; iv) provide the \pkg{zref} property ``\texttt{subcaption}'' so that
+we can refer to, for example, \texttt{\cs{zcref}[ref=subcaption]\{subcap-1\}}
+to emulate the functionality of \cls{memoir}'s \cs{subcaptionref}; v) provide
+that \cs{footnote}, \cs{verbfootnote}, \cs{sidefootnote}, and \cs{pagenote}
+get a proper \opt{currentcounter} set; and v) set counter types for counters
+\texttt{sidefootnote} and \texttt{pagenote}. Naturally, the sheer number of
+features that required some specific support implies that some gymnastics were
+needed here. But the most sensitive changes are: i) a local redefinition of
+\cs{label} inside the environments \env{sidecaption} and \env{sidecontcaption}
+and the commands \cs{bitwonumcaption}, \cs{bionenumcaption}, and
+\cs{bicaption}; and ii) the use of \pkg{ltcmdhooks} command hooks on
+\cs{bitwonumcaption}, \cs{bionenumcaption}, \cs{bicaption},
+\cs{@memsubcaption}, \cs{@makefntext}, and \cs{@makesidefntext}.
+
+\DescribeOption{KOMA} %
+The \cls{KOMA-Script} document classes are much more strict than \cls{memoir}
+in using standard mechanisms for cross-reference related features, so that
+very little adjustment is needed here. Only the environments
+\env{captionbeside} and \env{captionofbeside} require special treatment. And,
+though they do use \cs{refstepcounter} under the hood, since they are
+environments, we don't get to see reference variables outside them.
+\cs{@currentlabel} is smuggled out of the group, but not \cs{@currentcounter},
+so we must arrange for the later to have a correct value outside the caption
+environments too. Environment hooks are used for the purpose, essentially
+setting \cs{@currentcounter} to \cs{@captype}, which would be the value the
+captioning infrastructure would set for it.
+
+\DescribeOption{amsmath} %
+\pkg{amsmath}'s display math environments have their contents processed twice,
+once for measuring and the second does the final typesetting. Hence,
+\pkg{amsmath} needs to handle \cs{label} specially inside these environments,
+otherwise we'd have duplicate labels all around, and indeed it does redefine
+\cs{label} locally inside them. Alas, the same treatment is not granted to
+\cs{zlabel}. However, \cs{label} is set basically to \emph{store} the value
+of the argument inside the environments, and its global meaning is kept in
+\cs{ltx@label} which is called at the appropriate time to actually set the
+label. So, what \pkg{zref-clever} does is redefine \cs{ltx@label} to set
+\texttt{both} a regular \cs{label} and a \cs{zlabel} for the same \meta{label}
+(which does not generate a duplicate label problem since the referencing
+systems are independent). Therefore, you must use \cs{label} (not
+\cs{zlabel}) inside \pkg{amsmath}'s display math environments, and this
+compatibility module arranges that you can also refer to that label with
+\pkg{zref} and, thus, with \cs{zcref} as well. The following environments are
+subject to this usage restriction: \env{equation}, \env{align}, \env{alignat},
+\env{flalign}, \env{xalignat}, \env{gather}, \env{multline}, and their
+respective starred versions. In particular, the same is not the case for the
+\env{subequations} environment, inside which \cs{zlabel} works as usual (to
+refer to the main equation number, that is, right after
+\texttt{\cs{begin}\{subequations\}}). See the \zcref{how:amsmath} for an
+usage example. The module also ensures proper \opt{currentcounter} values are
+in place for the display math environments, for which it uses environment
+hooks, and sets the font of equation references to \cs{upshape}, following
+\pkg{amsmath}'s \cs{eqref}. Note, however, that \pkg{zref-clever} is not the
+only package to redefine \cs{ltx@label}, and compatibility problems may arise
+if this module is used with such packages or with document classes that do the
+same. In case of trouble, you can load \pkg{zref-clever} with option
+\texttt{nocompat=amsmath} and either use the standard referencing system's
+facilities to refer to \pkg{amsmath}'s equations or check the code
+documentation for the technique used for this (which is pretty standard) and
+adapt it to your case. Given that any trouble that may arise here is one of
+the proper ``timing'' of the redefinition, it should not be particularly
+complicated to make such adjustments.
+
+\DescribeOption{mathtools} %
+\pkg{mathtools} has a feature to show the numbers only for those equations
+actually referenced (with \cs{eqref} or \cs{refeq}), which is enabled by the
+\opt{showonlyrefs} option. This compatibility module adds support for this
+feature, such that equation references made with \cs{zcref} also get marked as
+``referenced'' for \pkg{mathtools}, when the option is active, of course. The
+module uses a couple of \pkg{mathtools} functions, but does not need to
+redefine or hook into anything, everything is handled on \pkg{zref-clever}'s
+side.
+
+\DescribeOption{breqn} %
+This compatibility module only sets proper \opt{currentcounter} values for the
+environments \env{dgroup}, \env{dmath}, \env{dseries}, and \env{darray}, and
+uses environment hooks for the purpose. Note that these environments offer a
+\opt{label} option for label setting, but implements it in a way that is
+somewhat tricky to grab for our purposes, so we don't do it. However,
+\pkg{breqn}'s documentation says the following about the use of \cs{label}
+inside its environments: \textquote{Use of the normal \cs{label} command
+ instead of the \opt{label} option works, I think, most of the time
+ (untested)}. My light testing suggests the same is true for \cs{zlabel},
+which can then be used directly in these environments. But the ``second
+class'' status for this use is the one granted by \pkg{breqn}, there's not
+much we can do here. If you have any trouble with this, you may wish to check
+\zcref{wkrnd:breqn}.
+
+\DescribeOption{listings} %
+Being \env{lstlisting}s environments what they are, one cannot simply place a
+label inside them without special treatment. \pkg{listings} arranges to this
+by providing a \opt{label} option for setting a label for the whole
+environment, and a properly escaped label command inside the environment can
+be used to refer to the line number. While the later can also be used to set
+a \cs{zlabel} to make line number references, the \opt{label} option is
+catered to the standard labels exclusively. Hence, this compatibility module
+uses the same label name -- which luckily and atypically is stored in a
+variable -- and sets a \cs{zlabel} as well. This is done by using
+\pkg{listings}' \texttt{PreInit} hook, se we don't have to redefine or tamper
+with anything for the purpose. Besides this, the module also sets appropriate
+\opt{countertype}, \opt{counterresetby} and \opt{currentcounter} values for
+the \pkg{listings}' counters: \texttt{lstlisting} and \texttt{lstnumber}. See
+the \zcref{how:listings} for an usage example.
+
+\DescribeOption{enumitem} %
+\LaTeX{}'s \env{enumerate} environment requires some special treatment from
+\pkg{zref-clever}, since its resetting behavior is not stored in the standard
+way, and the counters' names, given they are numbered by level, do not map to
+the reference type naturally. This is done by default for the up to four
+levels of nested \env{enumerate} environments the kernel offers.
+\pkg{enumitem}, though, allows one to increase this maximum list depth for
+\env{enumerate} and, if this is done, setup for these deeper nesting levels
+have also to be taken care of, and that's what this compatibility module does.
+All settings here are internal to \pkg{zref-clever}, no hooks or redefinitions
+are needed, we just check the existing pertinent counters at
+\texttt{begindocument}, and supply settings for them. Of course, this means
+that only \pkg{enumitem}'s settings done in the preamble will be visible to
+the module and provided for.
+
+\DescribeOption{subcaption} %
+This compatibility module sets appropriate \opt{countertype} and
+\opt{counterresetby} for the \texttt{subfigure} and \texttt{subtable}
+counters, and provides the \pkg{zref} property ``\texttt{subref}'' so that we
+can refer to, for example, \texttt{\cs{zcref}[ref=subref]\{\meta{label}\}} to
+emulate the functionality of \cls{subcaption}'s \cs{subref}. The later
+feature uses the \cs{caption@subtypehook} provided by \pkg{caption} to locally
+add the \texttt{subref} property to \pkg{zref}'s main property list.
+
+\DescribeOption{subfig} %
+This module just sets appropriate \opt{countertype} and \opt{counterresetby}
+for the \texttt{subfigure} and \texttt{subtable} counters.
+
+
+\subsection{Work-arounds}
+
+\marginpar{\raggedleft\raisebox{-1.5ex}{\dbend}}As should be clear by now, the
+use of \pkg{zref}'s \cs{zlabel} and thus of \pkg{zref-clever} may occasionally
+require some adjustments, since it does not enjoy the universal support the
+standard referencing system does. The compatibility modules presented in
+\zcref{sec:comp-modules} go a long way in ensuring the user has to worry very
+little about it, but they cannot hopefully go all the way. Not only because
+this kind of support will never be exhaustive, but also since, sometimes,
+given the way certain features are implemented by packages or document
+classes, there may not be a reasonable way to provide this support, from our
+side. But, still, most of the time, it is still ``viable'' to get there, if
+one really wishes to do so. So, this section keeps track of some known
+recipes, which I don't think belong in \pkg{zref-clever} itself, but which you
+may choose to use. Note that this list is intended to spare users from having
+to reinvent the wheel every time someone needs something of the sort, but from
+\pkg{zref-clever}'s perspective, their status is ``not supported''.
+
+
+\subsection*{\pkg{breqn}}
+
+As mentioned in \opt{breqn}'s compatibility module (\zcref{sec:comp-modules}),
+\pkg{breqn}'s math environments \env{dgroup}, \env{dmath}, \env{dseries}, and
+\env{darray} offer a \opt{label} option (plus \opt{labelprefix}) for the
+purpose of label setting. Setting a \cs{zlabel} alongside with a regular
+\cs{label} based on that option requires redefining some of \pkg{breqn}
+internals. Also, \pkg{breqn} does not use \cs{refstepcounter} to increment
+the equation counters and, as a result, fails to set \pkg{hyperref} anchors
+for the equations (thus affecting standard labels too). The example below
+also provides to that.\footnote{The later work-around thanks to Heiko
+ Oberdiek, at \url{https://tex.stackexchange.com/a/241150}.}
+
+
+\begin{zcworkaround}[caption={\pkg{breqn}},label={wkrnd:breqn}]
+\documentclass{article}
+\usepackage{zref-clever}
+\usepackage{breqn}
+\makeatletter
+\define@key{breqn}{label}{%
+ \edef\next@label{%
+ \noexpand\label{\next@label@pre#1}%
+ \noexpand\zlabel{\next@label@pre#1}}%
+ \let\next@label@pre\@empty}
+\makeatother
+\usepackage{hyperref}
+\usepackage{etoolbox}
+\makeatletter
+\patchcmd\eq@setnumber{\stepcounter}{\refstepcounter}{}{%
+ \errmessage{Patching \noexpand\eq@setnumber failed}}
+\makeatother
+\begin{document}
+\section{Section 1}
+\begin{dmath}[label={eq:1}]
+ f(x)=\frac{1}{x} \condition{for $x\neq 0$}
+\end{dmath}
+\begin{dmath}[labelprefix={eq:},label={2}]
+ H_2^2 = x_1^2 + x_1 x_2 + x_2^2 - q_1 - q_2
+\end{dmath}
+\zcref{eq:1, eq:2}
+\end{document}
+\end{zcworkaround}
+
+Of course, you can always adapt things to your needs and, e.g., make the
+\opt{label} option set just \cs{zlabel} instead of both labels, or create a
+separate \opt{zlabel} option.
+
+
+\section{Acknowledgments}
+
+\pkg{zref-clever} would not be possible without other people's previous work
+and help.
+
+Heiko Oberdiek's \pkg{zref}, now maintained by the Oberdiek Package Support
+Group, is the underlying infrastructure of this package. The potential of its
+basic concept and the solid implementation were certainly among the reasons
+I've chosen to venture into these waters, to start with. And I believe they
+will remain one of the main assets of \pkg{zref-clever} as it matures.
+
+The name of the package makes no secret that a major inspiration for the kind
+of ``feel'' I strove to achieve has been Toby Cubitt's \pkg{cleveref}.
+Indeed, I have been an user of \pkg{cleveref} for several years, and a happy
+one at that. But the role \pkg{cleveref} played in the development of
+\pkg{zref-clever} extends beyond the visible influence in the design of user
+facing functionality. Some technical solutions and, specially, the handling
+of support for other packages were a valuable reference. Hence, the
+accumulated experience of \pkg{cleveref} allowed for \pkg{zref-clever} to
+start on a more solid foundation than would otherwise be the case.
+
+The long term efforts of the \LaTeX3 \cs{Team} around \pkg{expl3} and
+\pkg{xparse} have also left their marks in this package. By implementing
+powerful tools and smoothing several regular programming tasks, they have
+certainly reduced my entry barrier to \LaTeX{} programming and enabled me to
+develop this package with a significantly reduced effort. And, given the
+constraints of my abilities, the result is no doubt much better than it would
+be in their absence.
+
+Besides these more general acknowledgments, a number of people have
+contributed to \pkg{zref-clever}, whether they are aware of it or not.
+Suggestions, ideas, solutions to problems, bug reports or even encouragement
+were generously provided by: Ulrike Fischer, Frank Mittelbach, Phelype
+Oleinik, Jonathan P.\ Spratte, Enrico Gregorio, Steven B.\ Segletes,
+\texttt{@samcarter}, Alan Munn, Florent Rougon, and David Carlisle.
+
+If I have inadvertently left anyone off the list I apologize, and please let
+me know, so that I can correct the oversight.
+
+Thank you all very much!
+
+
+\section{Change history}
+
+A change log with relevant changes for each version, eventual upgrade
+instructions, and upcoming changes, is maintained in the package's repository,
+at \url{https://github.com/gusbrs/zref-clever/blob/main/CHANGELOG.md}. An
+archive of historical versions of the package is also kept at
+\url{https://github.com/gusbrs/zref-clever/releases}.
+
+\end{document}
diff --git a/Master/texmf-dist/source/latex/zref-clever/zref-clever.dtx b/Master/texmf-dist/source/latex/zref-clever/zref-clever.dtx
new file mode 100644
index 00000000000..024aa50a991
--- /dev/null
+++ b/Master/texmf-dist/source/latex/zref-clever/zref-clever.dtx
@@ -0,0 +1,7161 @@
+% \iffalse meta-comment
+%
+% File: zref-clever.dtx
+%
+% This file is part of the LaTeX package "zref-clever".
+%
+% 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-clever.dtx,
+% zref-clever.ins,
+% zref-clever.tex,
+% zref-clever-code.tex,
+% and the derived files listed in MANIFEST.md.
+%
+% 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-clever
+%
+% for those people who are interested.
+%
+% -----------------------------------------------------------------------
+%
+% \fi
+%
+% \iffalse
+%<*driver>
+\documentclass{l3doc}
+
+% Have \GetFileInfo pick up date and version data and used in the
+% documentation.
+\usepackage[cap,nameinlink=false,check,titleref]{zref-clever}
+
+\begin{document}
+
+\DocInput{zref-clever.dtx}
+
+\end{document}
+%</driver>
+% \fi
+%
+% \DoNotIndex{\\,\{,\}}
+% \DoNotIndex{\c@,\cl@,\c@enumN,\p@}
+% \DoNotIndex{\the}
+%
+%
+% \NewDocumentCommand\opt{m}{\texttt{#1}}
+%
+% \pdfstringdefDisableCommands{%
+% \def\opt#1{#1}
+% }
+%
+% ^^A Have the Index at 'section' level rather than 'part'. Otherwise it is
+% ^^A 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.%
+% }
+%
+%
+% \GetFileInfo{zref-clever.sty}
+%
+% \title{%
+% The \pkg{zref-clever} package implementation%
+% \thanks{This file describes \fileversion, released \filedate.}%
+% }
+%
+% \author{%
+% Gustavo Barros%
+% \thanks{\url{https://github.com/gusbrs/zref-clever}}%
+% }
+%
+% \date{\filedate}
+%
+% \maketitle
+%
+% \tableofcontents
+%
+%
+% \section{Initial setup}
+%
+% Start the \pkg{DocStrip} guards.
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% Identify the internal prefix (\LaTeX3 \pkg{DocStrip} convention).
+% \begin{macrocode}
+%<@@=zrefclever>
+% \end{macrocode}
+%
+% Taking a stance on backward compatibility of the package. During initial
+% development, we have used freely recent features of the kernel (albeit
+% refraining from \pkg{l3candidates}, even though I'd have loved to have used
+% \cs{bool_case_true:}\dots{}). We presume \pkg{xparse} (which made to the
+% kernel in the 2020-10-01 release), and \pkg{expl3} as well (which made to
+% the kernel in the 2020-02-02 release). We also just use UTF-8 for the
+% dictionaries (which became the default input encoding in the 2018-04-01
+% release). Finally, a couple of changes came with the 2021-11-15 kernel
+% release, which are important here. First, a fix was made to the new hook
+% management system (\pkg{ltcmdhooks}), with implications to the hook we add
+% to \cs{appendix} (see \url{https://tex.stackexchange.com/q/617905} and
+% \url{https://github.com/latex3/latex2e/pull/699}, thanks Phelype Oleinik).
+% Second, the support for \cs{@currentcounter} has been improved, including
+% \cs{footnote} and \pkg{amsmath} (see
+% \url{https://github.com/latex3/latex2e/issues/687}, thanks Frank Mittelbach
+% and Ulrike Fischer). Hence, since we would not be able to go much backwards
+% without special handling anyway, we make the cut at the 2021-11-15 kernel
+% release.
+%
+% \begin{macrocode}
+\providecommand\IfFormatAtLeastTF{\@ifl@t@r\fmtversion}
+\IfFormatAtLeastTF{2021-11-15}
+ {}
+ {%
+ \PackageError{zref-clever}{LaTeX kernel too old}
+ {%
+ 'zref-clever' requires a LaTeX kernel 2021-11-15 or newer.%
+ \MessageBreak Loading will abort!%
+ }%
+ \endinput
+ }%
+% \end{macrocode}
+%
+%
+% Identify the package.
+% \begin{macrocode}
+\ProvidesExplPackage {zref-clever} {2021-11-24} {0.1.0-alpha}
+ {Clever LaTeX cross-references based on zref}
+% \end{macrocode}
+%
+%
+% \section{Dependencies}
+%
+% Required packages. Besides these, \pkg{zref-hyperref}, \pkg{zref-titleref},
+% and \pkg{zref-check} may also be loaded depending on user options.
+%
+% \begin{macrocode}
+\RequirePackage { zref-base }
+\RequirePackage { zref-user }
+\RequirePackage { zref-abspage }
+\RequirePackage { l3keys2e }
+\RequirePackage { ifdraft }
+% \end{macrocode}
+%
+%
+% \section{\pkg{zref} setup}
+%
+% For the purposes of the package, we need to store some information with the
+% labels, some of it standard, some of it not so much. So, we have to setup
+% \pkg{zref} to do so.
+%
+% Some basic properties are handled by \pkg{zref} itself, or some of its
+% modules. The \texttt{default} and \texttt{page} properties are provided by
+% \pkg{zref-base}, while \pkg{zref-abspage} provides the \texttt{abspage}
+% property which gives us a safe and easy way to sort labels for page
+% references.
+%
+% The \texttt{counter} property, in most cases, will be just the kernel's
+% \cs{@currentcounter}, set by \cs{refstepcounter}. However, not everywhere
+% is it assured that \cs{@currentcounter} gets updated as it should, so we
+% need to have some means to manually tell \pkg{zref-clever} what the current
+% counter actually is. This is done with the \opt{currentcounter} option, and
+% stored in \cs{l_@@_current_counter_tl}, whose default is
+% \cs{@currentcounter}.
+%
+% \begin{macrocode}
+\zref@newprop { zc@counter } { \l_@@_current_counter_tl }
+\zref@addprop \ZREF@mainlist { zc@counter }
+% \end{macrocode}
+%
+% The reference itself, stored by \pkg{zref-base} in the \texttt{default}
+% property, is somewhat a disputed real estate. In particular, the use of
+% \cs{labelformat} (previously from \pkg{varioref}, now in the kernel) will
+% include there the reference ``prefix'' and complicate the job we are trying
+% to do here. Hence, we isolate \cs[no-index]{the}\meta{counter} and store it
+% ``clean'' in \texttt{thecounter} for reserved use. Since
+% \cs{@currentlabel}, which populates the \texttt{default} property, is
+% \emph{more reliable} than \cs{@currentcounter}, \texttt{thecounter} is meant
+% to be kept as an \emph{option} (\opt{ref} option), in case there's need to
+% use \pkg{zref-clever} together with \cs{labelformat}. Based on the
+% definition of \cs{@currentlabel} done inside \cs{refstepcounter} in `texdoc
+% source2e', section `ltxref.dtx'. We just drop the \cs[no-index]{p@...}
+% prefix.
+%
+% \begin{macrocode}
+\zref@newprop { thecounter }
+ {
+ \cs_if_exist:cTF { c@ \l_@@_current_counter_tl }
+ { \use:c { the \l_@@_current_counter_tl } }
+ {
+ \cs_if_exist:cT { c@ \@currentcounter }
+ { \use:c { the \@currentcounter } }
+ }
+ }
+\zref@addprop \ZREF@mainlist { thecounter }
+% \end{macrocode}
+%
+%
+% Much of the work of \pkg{zref-clever} relies on the association between a
+% label's ``counter'' and its ``type'' (see the User manual section on
+% ``Reference types''). Superficially examined, one might think this relation
+% could just be stored in a global property list, rather than in the label
+% itself. However, there are cases in which we want to distinguish different
+% types for the same counter, depending on the document context. Hence, we
+% need to store the ``type'' of the ``counter'' for each ``label''. In
+% setting this, the presumption is that the label's type has the same name as
+% its counter, unless it is specified otherwise by the \opt{countertype}
+% option, as stored in \cs{l_@@_counter_type_prop}.
+%
+% \begin{macrocode}
+\zref@newprop { zc@type }
+ {
+ \exp_args:NNe \prop_if_in:NnTF \l_@@_counter_type_prop
+ \l_@@_current_counter_tl
+ {
+ \exp_args:NNe \prop_item:Nn \l_@@_counter_type_prop
+ { \l_@@_current_counter_tl }
+ }
+ { \l_@@_current_counter_tl }
+ }
+\zref@addprop \ZREF@mainlist { zc@type }
+% \end{macrocode}
+%
+%
+% Since the \texttt{default}/\texttt{thecounter} and \texttt{page} properties
+% store the ``\emph{printed} representation'' of their respective counters,
+% for sorting and compressing purposes, we are also interested in their
+% numeric values. So we store them in \texttt{zc@cntval} and
+% \texttt{zc@pgval}. For this, we use \cs[no-index]{c@}\meta{counter}, which
+% contains the counter's numerical value (see `texdoc source2e', section
+% `ltcounts.dtx').
+% \begin{macrocode}
+\zref@newprop { zc@cntval } [0]
+ {
+ \cs_if_exist:cTF { c@ \l_@@_current_counter_tl }
+ { \int_use:c { c@ \l_@@_current_counter_tl } }
+ {
+ \cs_if_exist:cT { c@ \@currentcounter }
+ { \int_use:c { c@ \@currentcounter } }
+ }
+ }
+\zref@addprop \ZREF@mainlist { zc@cntval }
+\zref@newprop* { zc@pgval } [0] { \int_use:c { c@page } }
+\zref@addprop \ZREF@mainlist { zc@pgval }
+% \end{macrocode}
+%
+%
+% However, since many counters (may) get reset along the document, we require
+% more than just their numeric values. We need to know the reset chain of a
+% given counter, in order to sort and compress a group of references. Also
+% here, the ``printed representation'' is not enough, not only because it is
+% easier to work with the numeric values but, given we occasionally group
+% multiple counters within a single type, sorting this group requires to know
+% the actual counter reset chain.
+%
+% Furthermore, even if it is true that most of the definitions of counters,
+% and hence of their reset behavior, is likely to be defined in the preamble,
+% this is not necessarily true. Users can create counters, newtheorems
+% mid-document, and alter their reset behavior along the way. Was that not
+% the case, we could just store the desired information at
+% \texttt{begindocument} in a variable and retrieve it when needed. But since
+% it is, we need to store the information with the label, with the values as
+% current when the label is set.
+%
+% Though counters can be reset at any time, and in different ways at that, the
+% most important use case is the automatic resetting of counters when some
+% other counter is stepped, as performed by the standard mechanisms of the
+% kernel (optional argument of \cs{newcounter}, \cs{@addtoreset},
+% \cs{counterwithin}, and related infrastructure). The canonical optional
+% argument of \cs{newcounter} establishes that the counter being created (the
+% mandatory argument) gets reset every time the ``enclosing counter'' gets
+% stepped (this is called in the usual sources ``within-counter'', ``old
+% counter'', ``supercounter'', ``parent counter'' etc.). This information is
+% somewhat tricky to get. For starters, the counters which may reset the
+% current counter are not retrievable from the counter itself, because this
+% information is stored with the counter that does the resetting, not with the
+% one that gets reset (the list is stored in \cs[no-index]{cl@}\meta{counter}
+% with format
+% \texttt{\cs{@elt}\{countera\}\cs{@elt}\{counterb\}\cs{@elt}\{counterc\}},
+% see \file{ltcounts.dtx} in \texttt{texdoc source2e}). Besides, there may be
+% a chain of resetting counters, which must be taken into account: if
+% \texttt{counterC} gets reset by \texttt{counterB}, and \texttt{counterB}
+% gets reset by \texttt{counterA}, stepping the latter affects all three of
+% them.
+%
+% The procedure below examines a set of counters, those in
+% \cs{l_@@_counter_resetters_seq}, and for each of them retrieves the set of
+% counters it resets, as stored in \cs[no-index]{cl@}\meta{counter}, looking
+% for the counter for which we are trying to set a label
+% (\cs{l_@@_current_counter_tl}, by default \cs{@currentcounter}, passed as an
+% argument to the functions). There is one relevant caveat to this procedure:
+% \cs{l_@@_counter_resetters_seq} is populated by hand with the ``usual
+% suspects'', there is no way (that I know of) to ensure it is exhaustive.
+% However, it is not that difficult to create a reasonable ``usual suspects''
+% list which, of course, should include the counters for the sectioning
+% commands to start with, and it is easy to add more counters to this list if
+% needed, with the option \opt{counterresetters}. Unfortunately, not all
+% counters are created alike, or reset alike. Some counters, even some kernel
+% ones, get reset by other mechanisms (notably, the \texttt{enumerate}
+% environment counters do not use the regular counter machinery for resetting
+% on each level, but are nested nevertheless by other means). Therefore,
+% inspecting \cs[no-index]{cl@}\meta{counter} cannot possibly fully account
+% for all of the automatic counter resetting which takes place in the
+% document. And there's also no other ``general rule'' we could grab on for
+% this, as far as I know. So we provide a way to manually tell
+% \pkg{zref-clever} of these cases, by means of the \opt{counterresetby}
+% option, whose information is stored in \cs{l_@@_counter_resetby_prop}. This
+% manual specification has precedence over the search through
+% \cs{l_@@_counter_resetters_seq}, and should be handled with care, since
+% there is no possible verification mechanism for this.
+%
+%
+% \begin{macro}[EXP]{\@@_get_enclosing_counters_value:n}
+% Recursively generate a \emph{sequence} of ``enclosing counters'' values,
+% for a given \meta{counter} and leave it in the input stream. This
+% function must be expandable, since it gets called from \cs{zref@newprop}
+% and is the one responsible for generating the desired information when
+% the label is being set. Note that the order in which we are getting this
+% information is reversed, since we are navigating the counter reset chain
+% bottom-up. But it is very hard to do otherwise here where we need
+% expandable functions, and easy to handle at the reading side.
+% \begin{syntax}
+% \cs{@@_get_enclosing_counters_value:n} \Arg{counter}
+% \end{syntax}
+% \begin{macrocode}
+\cs_new:Npn \@@_get_enclosing_counters_value:n #1
+ {
+ \cs_if_exist:cT { c@ \@@_counter_reset_by:n {#1} }
+ {
+ { \int_use:c { c@ \@@_counter_reset_by:n {#1} } }
+ \@@_get_enclosing_counters_value:e
+ { \@@_counter_reset_by:n {#1} }
+ }
+ }
+% \end{macrocode}
+%
+% Both \texttt{e} and \texttt{f} expansions work for this particular recursive
+% call. I'll stay with the \texttt{e} variant, since conceptually it is what
+% I want (\texttt{x} itself is not expandable), and this package is anyway not
+% compatible with older kernels for which the performance penalty of the
+% \texttt{e} expansion would ensue (see also
+% \url{https://tex.stackexchange.com/q/611370/#comment1529282_611385}, thanks
+% Enrico Gregorio, aka `egreg').
+% \begin{macrocode}
+\cs_generate_variant:Nn \@@_get_enclosing_counters_value:n { e }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}[EXP]{\@@_counter_reset_by:n}
+% Auxiliary function for \cs{@@_get_enclosing_counters_value:n}, and useful
+% on its own standing. It is broken in parts to be able to use the
+% expandable mapping functions. \cs{@@_counter_reset_by:n} leaves in the
+% stream the ``enclosing counter'' which resets \meta{counter}.
+% \begin{syntax}
+% \cs{@@_counter_reset_by:n} \Arg{counter}
+% \end{syntax}
+% \begin{macrocode}
+\cs_new:Npn \@@_counter_reset_by:n #1
+ {
+ \bool_if:nTF
+ { \prop_if_in_p:Nn \l_@@_counter_resetby_prop {#1} }
+ { \prop_item:Nn \l_@@_counter_resetby_prop {#1} }
+ {
+ \seq_map_tokens:Nn \l_@@_counter_resetters_seq
+ { \@@_counter_reset_by_aux:nn {#1} }
+ }
+ }
+\cs_new:Npn \@@_counter_reset_by_aux:nn #1#2
+ {
+ \cs_if_exist:cT { c@ #2 }
+ {
+ \tl_if_empty:cF { cl@ #2 }
+ {
+ \tl_map_tokens:cn { cl@ #2 }
+ { \@@_counter_reset_by_auxi:nnn {#2} {#1} }
+ }
+ }
+ }
+\cs_new:Npn \@@_counter_reset_by_auxi:nnn #1#2#3
+ {
+ \str_if_eq:nnT {#2} {#3}
+ { \tl_map_break:n { \seq_map_break:n {#1} } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% Finally, we create the \texttt{zc@enclval} property, and add it to the
+% \texttt{main} property list.
+% \begin{macrocode}
+\zref@newprop { zc@enclval }
+ {
+ \@@_get_enclosing_counters_value:e
+ \l_@@_current_counter_tl
+ }
+\zref@addprop \ZREF@mainlist { zc@enclval }
+% \end{macrocode}
+%
+%
+% Another piece of information we need is the page numbering format being used
+% by \cs{thepage}, so that we know when we can (or not) group a set of page
+% references in a range. Unfortunately, \texttt{page} is not a typical
+% counter in ways which complicates things. First, it does commonly get reset
+% along the document, not necessarily by the usual counter reset chains, but
+% rather with \cs{pagenumbering} or variations thereof. Second, the format of
+% the page number commonly changes in the document (roman, arabic, etc.), not
+% necessarily, though usually, together with a reset. Trying to ``parse''
+% \cs{thepage} to retrieve such information is bound to go wrong: we don't
+% know, and can't know, what is within that macro, and that's the business of
+% the user, or of the documentclass, or of the loaded packages. The technique
+% used by \pkg{cleveref}, which we borrow here, is simple and smart: store
+% with the label what \cs{thepage} would return, if the counter \cs{c@page}
+% was ``\(1\)''. That does not allow us to \emph{sort} the references,
+% luckily however, we have \texttt{abspage} which solves this problem. But we
+% can decide whether two labels can be compressed into a range or not based on
+% this format: if they are identical, we can compress them, otherwise, we
+% can't. To do so, we locally redefine \cs{c@page} to return ``1'', thus
+% avoiding any global spillovers of this trick. Since this operation is not
+% expandable we cannot run it directly from the property definition. Hence,
+% we use a shipout hook, and set \cs{g_@@_page_format_tl}, which can then be
+% retrieved by the starred definition of
+% \texttt{\cs{zref@newprop}*\{zc@pgfmt\}}.
+%
+% \begin{macrocode}
+\tl_new:N \g_@@_page_format_tl
+\cs_new_protected:Npx \@@_page_format_aux: { \int_eval:n { 1 } }
+\AddToHook { shipout / before }
+ {
+ \group_begin:
+ \cs_set_eq:NN \c@page \@@_page_format_aux:
+ \tl_gset:Nx \g_@@_page_format_tl { \thepage }
+ \group_end:
+ }
+\zref@newprop* { zc@pgfmt } { \g_@@_page_format_tl }
+\zref@addprop \ZREF@mainlist { zc@pgfmt }
+% \end{macrocode}
+%
+%
+% Still some other properties which we don't need to handle at the data
+% provision side, but need to cater for at the retrieval side, are the ones
+% from the \pkg{zref-xr} module, which are added to the labels imported from
+% external documents, and needed to construct hyperlinks to them and to
+% distinguish them from the current document ones at sorting and compressing:
+% \texttt{urluse}, \texttt{url} and \texttt{externaldocument}.
+%
+%
+%
+% \section{Plumbing}
+%
+%
+% \subsection{Auxiliary}
+%
+%
+% \begin{macro}
+% {
+% \@@_if_package_loaded:n ,
+% \@@_if_class_loaded:n ,
+% }
+% Just a convenience, since sometimes we just need one of the branches, and
+% it is particularly easy to miss the empty F branch after a long T one.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \@@_if_package_loaded:n #1 { T , F , TF }
+ { \IfPackageLoadedTF {#1} { \prg_return_true: } { \prg_return_false: } }
+\prg_new_conditional:Npnn \@@_if_class_loaded:n #1 { T , F , TF }
+ { \IfClassLoadedTF {#1} { \prg_return_true: } { \prg_return_false: } }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Messages}
+%
+%
+% \begin{macrocode}
+\msg_new:nnn { zref-clever } { option-not-type-specific }
+ {
+ Option~'#1'~is~not~type-specific~\msg_line_context:.~
+ Set~it~in~'\iow_char:N\\zcLanguageSetup'~before~first~'type'~
+ switch~or~as~package~option.
+ }
+\msg_new:nnn { zref-clever } { option-only-type-specific }
+ {
+ No~type~specified~for~option~'#1'~\msg_line_context:.~
+ Set~it~after~'type'~switch.
+ }
+\msg_new:nnn { zref-clever } { key-requires-value }
+ { The~'#1'~key~'#2'~requires~a~value~\msg_line_context:. }
+\msg_new:nnn { zref-clever } { language-declared }
+ { Language~'#1'~is~already~declared~\msg_line_context:.~Nothing~to~do. }
+\msg_new:nnn { zref-clever } { unknown-language-alias }
+ {
+ Language~'#1'~is~unknown~\msg_line_context:.~Can't~alias~to~it.~
+ See~documentation~for~'\iow_char:N\\zcDeclareLanguage'~and~
+ '\iow_char:N\\zcDeclareLanguageAlias'.
+ }
+\msg_new:nnn { zref-clever } { unknown-language-setup }
+ {
+ Language~'#1'~is~unknown~\msg_line_context:.~Can't~set~it~up.~
+ See~documentation~for~'\iow_char:N\\zcDeclareLanguage'~and~
+ '\iow_char:N\\zcDeclareLanguageAlias'.
+ }
+\msg_new:nnn { zref-clever } { unknown-language-opt }
+ {
+ Language~'#1'~is~unknown~\msg_line_context:.~Using~default.~
+ See~documentation~for~'\iow_char:N\\zcDeclareLanguage'~and~
+ '\iow_char:N\\zcDeclareLanguageAlias'.
+ }
+\msg_new:nnn { zref-clever } { unknown-language-decl }
+ {
+ Can't~set~declension~'#1'~for~unknown~language~'#2'~\msg_line_context:.~
+ See~documentation~for~'\iow_char:N\\zcDeclareLanguage'~and~
+ '\iow_char:N\\zcDeclareLanguageAlias'.
+ }
+\msg_new:nnn { zref-clever } { language-no-decl-ref }
+ {
+ Language~'#1'~has~no~declared~declension~cases~\msg_line_context:.~
+ Nothing~to~do~with~option~'d=#2'.
+ }
+\msg_new:nnn { zref-clever } { language-no-gender }
+ {
+ Language~'#1'~has~no~declared~gender~\msg_line_context:.~
+ Nothing~to~do~with~option~'#2=#3'.
+ }
+\msg_new:nnn { zref-clever } { language-no-decl-setup }
+ {
+ Language~'#1'~has~no~declared~declension~cases~\msg_line_context:.~
+ Nothing~to~do~with~option~'case=#2'.
+ }
+\msg_new:nnn { zref-clever } { unknown-decl-case }
+ {
+ Declension~case~'#1'~unknown~for~language~'#2'~\msg_line_context:.~
+ Using~default~declension~case.
+ }
+\msg_new:nnn { zref-clever } { nudge-multitype }
+ {
+ Reference~with~multiple~types~\msg_line_context:.~
+ You~may~wish~to~separate~them~or~review~language~around~it.
+ }
+\msg_new:nnn { zref-clever } { nudge-comptosing }
+ {
+ Multiple~labels~have~been~compressed~into~singular~type~name~
+ for~type~'#1'~\msg_line_context:.
+ }
+\msg_new:nnn { zref-clever } { nudge-plural-when-sg }
+ {
+ Option~'sg'~signals~that~a~singular~type~name~was~expected~
+ \msg_line_context:.~But~type~'#1'~has~plural~type~name.
+ }
+\msg_new:nnn { zref-clever } { gender-not-declared }
+ { Language~'#1'~has~no~'#2'~gender~declared~\msg_line_context:. }
+\msg_new:nnn { zref-clever } { nudge-gender-mismatch }
+ {
+ Gender~mismatch~for~type~'#1'~\msg_line_context:.~
+ You've~specified~'g=#2'~but~type~name~is~'#3'~for~language~'#4'.
+ }
+\msg_new:nnn { zref-clever } { nudge-gender-not-declared-for-type }
+ {
+ You've~specified~'g=#1'~\msg_line_context:.~
+ But~gender~for~type~'#2'~is~not~declared~for~language~'#3'.
+ }
+\msg_new:nnn { zref-clever } { nudgeif-unknown-value }
+ { Unknown~value~'#1'~for~'nudgeif'~option~\msg_line_context:. }
+\msg_new:nnn { zref-clever } { option-document-only }
+ { Option~'#1'~is~only~available~after~\iow_char:N\\begin\{document\}. }
+\msg_new:nnn { zref-clever } { dict-loaded }
+ { Loaded~'#1'~dictionary. }
+\msg_new:nnn { zref-clever } { dict-not-available }
+ { Dictionary~for~'#1'~not~available~\msg_line_context:. }
+\msg_new:nnn { zref-clever } { unknown-language-load }
+ {
+ Language~'#1'~is~unknown~\msg_line_context:.~Unable~to~load~dictionary.~
+ See~documentation~for~'\iow_char:N\\zcDeclareLanguage'~and~
+ '\iow_char:N\\zcDeclareLanguageAlias'.
+ }
+\msg_new:nnn { zref-clever } { zref-property-undefined }
+ {
+ Option~'ref=#1'~requested~\msg_line_context:.~
+ But~the~property~'#1'~is~not~declared,~falling-back~to~'default'.
+ }
+\msg_new:nnn { zref-clever } { hyperref-preamble-only }
+ {
+ Option~'hyperref'~only~available~in~the~preamble~\msg_line_context:.~
+ To~inhibit~hyperlinking~locally,~you~can~use~the~starred~version~of~
+ '\iow_char:N\\zcref'.
+ }
+\msg_new:nnn { zref-clever } { missing-hyperref }
+ { Missing~'hyperref'~package.~Setting~'hyperref=false'. }
+\msg_new:nnn { zref-clever } { titleref-preamble-only }
+ {
+ Option~'titleref'~only~available~in~the~preamble~\msg_line_context:.~
+ Did~you~mean~'ref=title'?.
+ }
+\msg_new:nnn { zref-clever } { option-preamble-only }
+ { Option~'#1'~only~available~in~the~preamble~\msg_line_context:. }
+\msg_new:nnn { zref-clever } { unknown-compat-module }
+ {
+ Unknown~compatibility~module~'#1'~given~to~option~'nocompat'.~
+ Nothing~to~do.
+ }
+\msg_new:nnn { zref-clever } { missing-zref-check }
+ {
+ Option~'check'~requested~\msg_line_context:.~
+ But~package~'zref-check'~is~not~loaded,~can't~run~the~checks.
+ }
+\msg_new:nnn { zref-clever } { missing-type }
+ { Reference~type~undefined~for~label~'#1'~\msg_line_context:. }
+\msg_new:nnn { zref-clever } { missing-property }
+ { Reference~property~'#1'~undefined~for~label~'#2'~\msg_line_context:. }
+\msg_new:nnn { zref-clever } { missing-name }
+ { Reference~format~option~'#1'~undefined~for~type~'#2'~\msg_line_context:. }
+\msg_new:nnn { zref-clever } { missing-string }
+ {
+ We~couldn't~find~a~value~for~reference~option~'#1'~\msg_line_context:.~
+ But~we~should~have:~throw~a~rock~at~the~maintainer.
+ }
+\msg_new:nnn { zref-clever } { single-element-range }
+ { Range~for~type~'#1'~resulted~in~single~element~\msg_line_context:. }
+\msg_new:nnn { zref-clever } { compat-package }
+ { Loaded~support~for~'#1'~package. }
+\msg_new:nnn { zref-clever } { compat-class }
+ { Loaded~support~for~'#1'~documentclass. }
+% \end{macrocode}
+%
+%
+% \subsection{Data extraction}
+%
+%
+% \begin{macro}{\@@_def_extract:Nnnn}
+% Extract property \meta{prop} from \meta{label} and sets variable \meta{tl
+% var} with extracted value. Ensure \cs{zref@extractdefault} is expanded
+% exactly twice, but no further to retrieve the proper value. In case the
+% property is not found, set \meta{tl var} with \meta{default}.
+% \begin{syntax}
+% \cs{@@_def_extract:Nnnn} \Arg{tl val}
+% ~~\Arg{label} \Arg{prop} \Arg{default}
+% \end{syntax}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_def_extract:Nnnn #1#2#3#4
+ {
+ \exp_args:NNNo \exp_args:NNo \tl_set:Nn #1
+ { \zref@extractdefault {#2} {#3} {#4} }
+ }
+\cs_generate_variant:Nn \@@_def_extract:Nnnn { NVnn }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_extract_unexp:nnn}
+% Extract property \meta{prop} from \meta{label}. Ensure that, in the
+% context of an x expansion, \cs{zref@extractdefault} is expanded exactly
+% twice, but no further to retrieve the proper value. Thus, this is meant
+% to be use in an x expansion context, not in other situations. In case the
+% property is not found, leave \meta{default} in the stream.
+% \begin{syntax}
+% \cs{@@_extract_unexp:nnn}\Arg{label}\Arg{prop}\Arg{default}
+% \end{syntax}
+% \begin{macrocode}
+\cs_new:Npn \@@_extract_unexp:nnn #1#2#3
+ {
+ \exp_args:NNo \exp_args:No
+ \exp_not:n { \zref@extractdefault {#1} {#2} {#3} }
+ }
+\cs_generate_variant:Nn \@@_extract_unexp:nnn { Vnn , nvn , Vvn }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_extract:nnn}
+% An internal version for \cs{zref@extractdefault}.
+% \begin{syntax}
+% \cs{@@_extract:nnn}\Arg{label}\Arg{prop}\Arg{default}
+% \end{syntax}
+% \begin{macrocode}
+\cs_new:Npn \@@_extract:nnn #1#2#3
+ { \zref@extractdefault {#1} {#2} {#3} }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Reference format}
+%
+% For a general discussion on the precedence rules for reference format
+% options, see Section ``Reference format'' in the User manual. Internally,
+% these precedence rules are handled / enforced in \cs{@@_get_ref_string:nN},
+% \cs{@@_get_ref_font:nN}, and \cs{@@_type_name_setup:} which are the basic
+% functions to retrieve proper values for reference format settings. The
+% ``fallback'' settings are stored in \cs{g_@@_fallback_dict_prop}.
+%
+%
+% \begin{macro}
+% {
+% \l_@@_setup_type_tl ,
+% \l_@@_dict_language_tl ,
+% \l_@@_dict_decl_case_tl ,
+% \l_@@_dict_declension_seq ,
+% \l_@@_dict_gender_seq ,
+% }
+% Store ``current'' type, language, and declension cases in different places
+% for option and translation handling, notably in
+% \cs{@@_provide_dictionary:n}, \cs{zcRefTypeSetup}, and
+% \cs{zcLanguageSetup}. But also for translations retrieval, in
+% \cs{@@_get_type_transl:nnnN} and \cs{@@_get_default_transl:nnN}.
+% \begin{macrocode}
+\tl_new:N \l_@@_setup_type_tl
+\tl_new:N \l_@@_dict_language_tl
+\tl_new:N \l_@@_dict_decl_case_tl
+\seq_new:N \l_@@_dict_declension_seq
+\seq_new:N \l_@@_dict_gender_seq
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}
+% {
+% \c_@@_ref_options_necessarily_not_type_specific_seq ,
+% \c_@@_ref_options_possibly_type_specific_seq ,
+% \c_@@_ref_options_type_names_seq ,
+% \c_@@_ref_options_font_seq ,
+% \c_@@_ref_options_typesetup_seq ,
+% \c_@@_ref_options_reference_seq ,
+% }
+% Lists of reference format related options in ``categories''. Since
+% these options are set in different scopes, and at different places,
+% storing the actual lists in centralized variables makes the job not only
+% easier later on, but also keeps things consistent.
+% \begin{macrocode}
+\seq_const_from_clist:Nn
+ \c_@@_ref_options_necessarily_not_type_specific_seq
+ {
+ tpairsep ,
+ tlistsep ,
+ tlastsep ,
+ notesep ,
+ }
+\seq_const_from_clist:Nn
+ \c_@@_ref_options_possibly_type_specific_seq
+ {
+ namesep ,
+ pairsep ,
+ listsep ,
+ lastsep ,
+ rangesep ,
+ refpre ,
+ refpos ,
+ }
+% \end{macrocode}
+% Only ``type names'' are ``necessarily type-specific'', which makes them
+% somewhat special on the retrieval side of things. In short, they don't have
+% their values queried by \cs{@@_get_ref_string:nN}, but by
+% \cs{@@_type_name_setup:}.
+% \begin{macrocode}
+\seq_const_from_clist:Nn
+ \c_@@_ref_options_type_names_seq
+ {
+ Name-sg ,
+ name-sg ,
+ Name-pl ,
+ name-pl ,
+ Name-sg-ab ,
+ name-sg-ab ,
+ Name-pl-ab ,
+ name-pl-ab ,
+ }
+% \end{macrocode}
+% \cs{c_@@_ref_options_font_seq} are technically ``possibly type-specific'',
+% but are not ``language-specific'', so we separate them.
+% \begin{macrocode}
+\seq_const_from_clist:Nn
+ \c_@@_ref_options_font_seq
+ {
+ namefont ,
+ reffont ,
+ }
+% \end{macrocode}
+% And, finally, some combined groups of the above variables, for convenience.
+% \begin{macrocode}
+\seq_new:N \c_@@_ref_options_typesetup_seq
+\seq_gconcat:NNN \c_@@_ref_options_typesetup_seq
+ \c_@@_ref_options_possibly_type_specific_seq
+ \c_@@_ref_options_type_names_seq
+\seq_gconcat:NNN \c_@@_ref_options_typesetup_seq
+ \c_@@_ref_options_typesetup_seq
+ \c_@@_ref_options_font_seq
+\seq_new:N \c_@@_ref_options_reference_seq
+\seq_gconcat:NNN \c_@@_ref_options_reference_seq
+ \c_@@_ref_options_necessarily_not_type_specific_seq
+ \c_@@_ref_options_possibly_type_specific_seq
+\seq_gconcat:NNN \c_@@_ref_options_reference_seq
+ \c_@@_ref_options_reference_seq
+ \c_@@_ref_options_font_seq
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsection{Languages}
+%
+% \begin{macro}{\g_@@_languages_prop}
+% Stores the names of known languages and the mapping from ``language name''
+% to ``dictionary name''. Whether or not a language or alias is known to
+% \pkg{zref-clever} is decided by its presence in this property list. A
+% ``base language'' (loose concept here, meaning just ``the name we gave for
+% the dictionary in that particular language'') is just like any other one,
+% the only difference is that the ``language name'' happens to be the same
+% as the ``dictionary name'', in other words, it is an ``alias to itself''.
+% \begin{macrocode}
+\prop_new:N \g_@@_languages_prop
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}[int]{\zcDeclareLanguage}
+% Declare a new language for use with \pkg{zref-clever}. \meta{language} is
+% taken to be both the ``language name'' and the ``dictionary name''.
+% \oarg{options} receive a \texttt{k=v} set of options, with three valid
+% options. The first, \opt{declension}, takes the noun declension cases
+% prefixes for \meta{language} as a comma separated list, whose first
+% element is taken to be the default case. The second, \opt{gender},
+% receives the genders for \meta{language} as comma separated list. The
+% third, \opt{allcaps}, receives no value, and indicates that for
+% \meta{language} all nouns must be capitalized for grammatical reasons, in
+% which case, the \opt{cap} option is disregarded for \meta{language}. If
+% \meta{language} is already known, just warn. This implies a particular
+% restriction regarding \oarg{options}, namely that these options, when
+% defined by the package, cannot be redefined by the user. This is
+% deliberate, otherwise the built-in dictionaries would become much too
+% sensitive to this particular user input, and unnecessarily so.
+% \cs{zcDeclareLanguage} is preamble only.
+% \begin{syntax}
+% \cs{zcDeclareLanguage} \oarg{options} \marg{language}
+% \end{syntax}
+% \begin{macrocode}
+\NewDocumentCommand \zcDeclareLanguage { O { } m }
+ {
+ \group_begin:
+ \tl_if_empty:nF {#2}
+ {
+ \prop_if_in:NnTF \g_@@_languages_prop {#2}
+ { \msg_warning:nnn { zref-clever } { language-declared } {#2} }
+ {
+ \prop_gput:Nnn \g_@@_languages_prop {#2} {#2}
+ \prop_new:c { g_@@_dict_ #2 _prop }
+ \tl_set:Nn \l_@@_dict_language_tl {#2}
+ \keys_set:nn { zref-clever / declarelang } {#1}
+ }
+ }
+ \group_end:
+ }
+\@onlypreamble \zcDeclareLanguage
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}[int]{\zcDeclareLanguageAlias}
+% Declare \meta{language alias} to be an alias of \meta{aliased language}.
+% \meta{aliased language} must be already known to \pkg{zref-clever}, as
+% stored in \cs{g_@@_languages_prop}. \cs{zcDeclareLanguageAlias} is
+% preamble only.
+% \begin{syntax}
+% \cs{zcDeclareLanguageAlias} \marg{language alias} \marg{aliased language}
+% \end{syntax}
+% \begin{macrocode}
+\NewDocumentCommand \zcDeclareLanguageAlias { m m }
+ {
+ \tl_if_empty:nF {#1}
+ {
+ \prop_if_in:NnTF \g_@@_languages_prop {#2}
+ {
+ \exp_args:NNnx
+ \prop_gput:Nnn \g_@@_languages_prop {#1}
+ { \prop_item:Nn \g_@@_languages_prop {#2} }
+ }
+ { \msg_warning:nnn { zref-clever } { unknown-language-alias } {#2} }
+ }
+ }
+\@onlypreamble \zcDeclareLanguageAlias
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macrocode}
+\keys_define:nn { zref-clever / declarelang }
+ {
+ declension .code:n =
+ {
+ \prop_gput:cnn
+ { g_@@_dict_ \l_@@_dict_language_tl _prop }
+ { declension } {#1}
+ } ,
+ declension .value_required:n = true ,
+ gender .code:n =
+ {
+ \prop_gput:cnn
+ { g_@@_dict_ \l_@@_dict_language_tl _prop }
+ { gender } {#1}
+ } ,
+ gender .value_required:n = true ,
+ allcaps .code:n =
+ {
+ \prop_gput:cnn
+ { g_@@_dict_ \l_@@_dict_language_tl _prop }
+ { allcaps } { true }
+ } ,
+ allcaps .value_forbidden:n = true ,
+ }
+% \end{macrocode}
+%
+%
+%
+% \begin{macro}{\@@_process_language_options:}
+% Auxiliary function for \cs{@@_zcref:nnn}, responsible for processing
+% options from \cs{zcDeclareLanguage}. It is necessary to separate them
+% from the reference options machinery because their behavior is language
+% dependent, but the language itself can also be set as an option
+% (\opt{lang}, value stored in \cs{l_@@_ref_language_tl}). Hence, we must
+% validate these options after the reference options have been set. It is
+% expected to be called right (or soon) after \cs{keys_set:nn} in
+% \cs{@@_zcref:nnn}, where current values for \cs{l_@@_ref_language_tl} and
+% \cs{l_@@_ref_decl_case_tl} are in place.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_process_language_options:
+ {
+ \exp_args:NNx \prop_get:NnNTF \g_@@_languages_prop
+ { \l_@@_ref_language_tl }
+ \l_@@_dict_language_tl
+ {
+% \end{macrocode}
+% Validate the declension case (\opt{d}) option against the declared cases for
+% the reference language. If the user value for the latter does not match the
+% declension cases declared for the former, the function sets an appropriate
+% value for \cs{l_@@_ref_decl_case_tl}, either using the default case, or
+% clearing the variable, depending on the language setup. And also issues a
+% warning about it.
+% \begin{macrocode}
+ \exp_args:NNx \seq_set_from_clist:Nn
+ \l_@@_dict_declension_seq
+ {
+ \prop_item:cn
+ {
+ g_@@_dict_
+ \l_@@_dict_language_tl _prop
+ }
+ { declension }
+ }
+ \seq_if_empty:NTF \l_@@_dict_declension_seq
+ {
+ \tl_if_empty:NF \l_@@_ref_decl_case_tl
+ {
+ \msg_warning:nnxx { zref-clever }
+ { language-no-decl-ref }
+ { \l_@@_ref_language_tl }
+ { \l_@@_ref_decl_case_tl }
+ \tl_clear:N \l_@@_ref_decl_case_tl
+ }
+ }
+ {
+ \tl_if_empty:NTF \l_@@_ref_decl_case_tl
+ {
+ \seq_get_left:NN \l_@@_dict_declension_seq
+ \l_@@_ref_decl_case_tl
+ }
+ {
+ \seq_if_in:NVF \l_@@_dict_declension_seq
+ \l_@@_ref_decl_case_tl
+ {
+ \msg_warning:nnxx { zref-clever }
+ { unknown-decl-case }
+ { \l_@@_ref_decl_case_tl }
+ { \l_@@_ref_language_tl }
+ \seq_get_left:NN \l_@@_dict_declension_seq
+ \l_@@_ref_decl_case_tl
+ }
+ }
+ }
+% \end{macrocode}
+% Validate the gender (\opt{g}) option against the declared genders for the
+% reference language. If the user value for the latter does not match the
+% genders declared for the former, clear \cs{l_@@_ref_gender_tl} and warn.
+% \begin{macrocode}
+ \exp_args:NNx \seq_set_from_clist:Nn
+ \l_@@_dict_gender_seq
+ {
+ \prop_item:cn
+ {
+ g_@@_dict_
+ \l_@@_dict_language_tl _prop
+ }
+ { gender }
+ }
+ \seq_if_empty:NTF \l_@@_dict_gender_seq
+ {
+ \tl_if_empty:NF \l_@@_ref_gender_tl
+ {
+ \msg_warning:nnxxx { zref-clever }
+ { language-no-gender }
+ { \l_@@_ref_language_tl }
+ { g }
+ { \l_@@_ref_gender_tl }
+ \tl_clear:N \l_@@_ref_gender_tl
+ }
+ }
+ {
+ \tl_if_empty:NF \l_@@_ref_gender_tl
+ {
+ \seq_if_in:NVF \l_@@_dict_gender_seq
+ \l_@@_ref_gender_tl
+ {
+ \msg_warning:nnxx { zref-clever }
+ { gender-not-declared }
+ { \l_@@_ref_language_tl }
+ { \l_@@_ref_gender_tl }
+ \tl_clear:N \l_@@_ref_gender_tl
+ }
+ }
+ }
+% \end{macrocode}
+% Ensure \cs{l_@@_capitalize_bool} is set to \texttt{true} when the language
+% was declared with \opt{allcaps} option.
+% \begin{macrocode}
+ \str_if_eq:eeT
+ {
+ \prop_item:cn
+ {
+ g_@@_dict_
+ \l_@@_dict_language_tl _prop
+ }
+ { allcaps }
+ }
+ { true }
+ { \bool_set_true:N \l_@@_capitalize_bool }
+ }
+ {
+% \end{macrocode}
+% If the language itself is not declared, we still have to issue declension
+% and gender warnings, if \opt{d} or \opt{g} options were used.
+% \begin{macrocode}
+ \tl_if_empty:NF \l_@@_ref_decl_case_tl
+ {
+ \msg_warning:nnxx { zref-clever } { unknown-language-decl }
+ { \l_@@_ref_decl_case_tl }
+ { \l_@@_ref_language_tl }
+ \tl_clear:N \l_@@_ref_decl_case_tl
+ }
+ \tl_if_empty:NF \l_@@_ref_gender_tl
+ {
+ \msg_warning:nnxxx { zref-clever }
+ { language-no-gender }
+ { \l_@@_ref_language_tl }
+ { g }
+ { \l_@@_ref_gender_tl }
+ \tl_clear:N \l_@@_ref_gender_tl
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsection{Dictionaries}
+%
+% Contrary to general options and type options, which are always \emph{local},
+% ``dictionaries'', ``translations'' or ``language-specific settings'' are
+% always \emph{global}. Hence, the loading of built-in dictionaries, as well
+% as settings done with \cs{zcLanguageSetup}, should set the relevant
+% variables globally.
+%
+% The built-in dictionaries and their related infrastructure are designed to
+% perform ``on the fly'' loading of dictionaries, ``lazily'' as needed. Much
+% like \pkg{babel} does for languages not declared in the preamble, but used
+% in the document. This offers some convenience, of course, and that's one
+% reason to do it. But it also has the purpose of parsimony, of ``loading the
+% least possible''. Therefore, we load at \texttt{begindocument} one single
+% language (see \zcref[ref=title, noname]{sec:lang-option}), as specified by
+% the user in the preamble with the \opt{lang} option or, failing any
+% specification, the current language of the document, which is the default.
+% Anything else is lazily loaded, on the fly, along the document.
+%
+% This design decision has also implications to the \emph{form} the dictionary
+% files assumed. As far as my somewhat impressionistic sampling goes,
+% dictionary or localization files of the most common packages in this area of
+% functionality, are usually a set of commands which perform the relevant
+% definitions and assignments in the preamble or at \texttt{begindocument}.
+% This includes \pkg{translator}, \pkg{translations}, but also \pkg{babel}'s
+% \file{.ldf} files, and \pkg{biblatex}'s \file{.lbx} files. I'm not really
+% well acquainted with this machinery, but as far as I grasp, they all rely on
+% some variation of \cs{ProvidesFile} and \cs{input}. And they can be safely
+% \cs{input} without generating spurious content, because they rely on being
+% loaded before the document has actually started. As far as I can tell,
+% \pkg{babel}'s ``on the fly'' functionality is not based on the \file{.ldf}
+% files, but on the \file{.ini} files, and on \cs{babelprovide}. And the
+% \file{.ini} files are not in this form, but actually resemble
+% ``configuration files'' of sorts, which means they are read and processed
+% somehow else than with just \cs{input}. So we do the more or less the same
+% here. It seems a reasonable way to ensure we can load dictionaries on the
+% fly robustly mid-document, without getting paranoid with the last bit of
+% white-space in them, and without introducing any undue content on the stream
+% when we cannot afford to do it. Hence, \pkg{zref-clever}'s built-in
+% dictionary files are a set of \emph{key-value options} which are read from
+% the file, and fed to \texttt{\cs{keys_set:nn}\{zref-clever/dictionary\}} by
+% \cs{@@_provide_dictionary:n}. And they use the same syntax and options as
+% \cs{zcLanguageSetup} does. The dictionary file itself is read with
+% \cs{ExplSyntaxOn} with the usual implications for white-space and catcodes.
+%
+% \cs{@@_provide_dictionary:n} is only meant to load the built-in
+% dictionaries. For languages declared by the user, or for any settings to a
+% known language made with \cs{zcLanguageSetup}, values are populated directly
+% to a variable \cs{g_@@_dict_\meta{language}_prop}. Hence, there is no need
+% to ``load'' anything in this case: definitions and assignments made by the
+% user are performed immediately.
+%
+%
+% \subsubsection*{Provide}
+%
+% \begin{macro}{\g_@@_loaded_dictionaries_seq}
+% Used to keep track of whether a dictionary has already been loaded or not.
+% \begin{macrocode}
+\seq_new:N \g_@@_loaded_dictionaries_seq
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l_@@_load_dict_verbose_bool}
+% Controls whether \cs{@@_provide_dictionary:n} fails silently or verbosely
+% in case of unknown languages or dictionaries not found.
+% \begin{macrocode}
+\bool_new:N \l_@@_load_dict_verbose_bool
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_provide_dictionary:n}
+% Load dictionary for known \meta{language} if it is available and if it has
+% not already been loaded.
+% \begin{syntax}
+% \cs{@@_provide_dictionary:n} \Arg{language}
+% \end{syntax}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_provide_dictionary:n #1
+ {
+ \group_begin:
+ \@bsphack
+ \prop_get:NnNTF \g_@@_languages_prop {#1}
+ \l_@@_dict_language_tl
+ {
+ \seq_if_in:NVF
+ \g_@@_loaded_dictionaries_seq
+ \l_@@_dict_language_tl
+ {
+ \exp_args:Nx \file_get:nnNTF
+ { zref-clever- \l_@@_dict_language_tl .dict }
+ { \ExplSyntaxOn }
+ \l_tmpa_tl
+ {
+ \tl_clear:N \l_@@_setup_type_tl
+ \exp_args:NNx \seq_set_from_clist:Nn
+ \l_@@_dict_declension_seq
+ {
+ \prop_item:cn
+ {
+ g_@@_dict_
+ \l_@@_dict_language_tl _prop
+ }
+ { declension }
+ }
+ \seq_if_empty:NTF \l_@@_dict_declension_seq
+ { \tl_clear:N \l_@@_dict_decl_case_tl }
+ {
+ \seq_get_left:NN \l_@@_dict_declension_seq
+ \l_@@_dict_decl_case_tl
+ }
+ \exp_args:NNx \seq_set_from_clist:Nn
+ \l_@@_dict_gender_seq
+ {
+ \prop_item:cn
+ {
+ g_@@_dict_
+ \l_@@_dict_language_tl _prop
+ }
+ { gender }
+ }
+ \keys_set:nV { zref-clever / dictionary } \l_tmpa_tl
+ \seq_gput_right:NV \g_@@_loaded_dictionaries_seq
+ \l_@@_dict_language_tl
+ \msg_note:nnx { zref-clever } { dict-loaded }
+ { \l_@@_dict_language_tl }
+ }
+ {
+ \bool_if:NT \l_@@_load_dict_verbose_bool
+ {
+ \msg_warning:nnx { zref-clever } { dict-not-available }
+ { \l_@@_dict_language_tl }
+ }
+% \end{macrocode}
+% Even if we don't have the actual dictionary, we register it as ``loaded''.
+% At this point, it is a known language, properly declared. There is no point
+% in trying to load it multiple times, because users cannot really provide the
+% dictionary files (well, technically they could, but we are working so they
+% don't need to, and have better ways to do what they want). And if the users
+% had provided some translations themselves, by means of \cs{zcLanguageSetup},
+% everything would be in place, and they could use the \opt{lang} option
+% multiple times, and the \texttt{dict-not-available} warning would never go
+% away.
+% \begin{macrocode}
+ \seq_gput_right:NV \g_@@_loaded_dictionaries_seq
+ \l_@@_dict_language_tl
+ }
+ }
+ }
+ {
+ \bool_if:NT \l_@@_load_dict_verbose_bool
+ { \msg_warning:nnn { zref-clever } { unknown-language-load } {#1} }
+ }
+ \@esphack
+ \group_end:
+ }
+\cs_generate_variant:Nn \@@_provide_dictionary:n { x }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_provide_dictionary_verbose:n}
+% Does the same as \cs{@@_provide_dictionary:n}, but warns if the loading of
+% the dictionary has failed.
+% \begin{syntax}
+% \cs{@@_provide_dictionary_verbose:n} \Arg{language}
+% \end{syntax}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_provide_dictionary_verbose:n #1
+ {
+ \group_begin:
+ \bool_set_true:N \l_@@_load_dict_verbose_bool
+ \@@_provide_dictionary:n {#1}
+ \group_end:
+ }
+\cs_generate_variant:Nn \@@_provide_dictionary_verbose:n { x }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}
+% {
+% \@@_provide_dict_type_transl:nn ,
+% \@@_provide_dict_default_transl:nn ,
+% }
+% A couple of auxiliary functions for the of
+% \texttt{{zref-clever/dictionary}} keys set in
+% \cs{@@_provide_dictionary:n}. They respectively ``provide'' (i.e. set if
+% it value does not exist, do nothing if it already does) ``type-specific''
+% and ``default'' translations. Both receive \meta{key} and
+% \meta{translation} as arguments, but \cs{@@_provide_dict_type_transl:nn}
+% relies on the current value of \cs{l_@@_setup_type_tl}, as set by the
+% \texttt{type} key.
+% \begin{syntax}
+% \cs{@@_provide_dict_type_transl:nn} \Arg{key} \Arg{translation}
+% \cs{@@_provide_dict_default_transl:nn} \Arg{key} \Arg{translation}
+% \end{syntax}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_provide_dict_type_transl:nn #1#2
+ {
+ \exp_args:Nnx \prop_gput_if_new:cnn
+ { g_@@_dict_ \l_@@_dict_language_tl _prop }
+ { type- \l_@@_setup_type_tl - #1 } {#2}
+ }
+\cs_new_protected:Npn \@@_provide_dict_default_transl:nn #1#2
+ {
+ \prop_gput_if_new:cnn
+ { g_@@_dict_ \l_@@_dict_language_tl _prop }
+ { default- #1 } {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% The set of keys for \texttt{{zref-clever/dictionary}}, which is used to
+% process the dictionary files in \cs{@@_provide_dictionary:n}. The no-op
+% cases for each category have their messages sent to ``info''. These
+% messages should not occur, as long as the dictionaries are well formed, but
+% they're placed there nevertheless, and can be leveraged in regression tests.
+%
+% \begin{macrocode}
+\keys_define:nn { zref-clever / dictionary }
+ {
+ type .code:n =
+ {
+ \tl_if_empty:nTF {#1}
+ { \tl_clear:N \l_@@_setup_type_tl }
+ { \tl_set:Nn \l_@@_setup_type_tl {#1} }
+ } ,
+ case .code:n =
+ {
+ \seq_if_empty:NTF \l_@@_dict_declension_seq
+ {
+ \msg_info:nnxx { zref-clever } { language-no-decl-setup }
+ { \l_@@_dict_language_tl } {#1}
+ }
+ {
+ \seq_if_in:NnTF \l_@@_dict_declension_seq {#1}
+ { \tl_set:Nn \l_@@_dict_decl_case_tl {#1} }
+ {
+ \msg_info:nnxx { zref-clever } { unknown-decl-case }
+ {#1} { \l_@@_dict_language_tl }
+ \seq_get_left:NN \l_@@_dict_declension_seq
+ \l_@@_dict_decl_case_tl
+ }
+ }
+ } ,
+ case .value_required:n = true ,
+ gender .code:n =
+ {
+ \seq_if_empty:NTF \l_@@_dict_gender_seq
+ {
+ \msg_info:nnxxx { zref-clever } { language-no-gender }
+ { \l_@@_dict_language_tl } { gender } {#1}
+ }
+ {
+ \tl_if_empty:NTF \l_@@_setup_type_tl
+ {
+ \msg_info:nnn { zref-clever }
+ { option-only-type-specific } { gender }
+ }
+ {
+ \seq_if_in:NnTF \l_@@_dict_gender_seq {#1}
+ { \@@_provide_dict_type_transl:nn { gender } {#1} }
+ {
+ \msg_info:nnxx { zref-clever } { gender-not-declared }
+ { \l_@@_dict_language_tl } {#1}
+ }
+ }
+ }
+ } ,
+ gender .value_required:n = true ,
+ }
+\seq_map_inline:Nn
+ \c_@@_ref_options_necessarily_not_type_specific_seq
+ {
+ \keys_define:nn { zref-clever / dictionary }
+ {
+ #1 .value_required:n = true ,
+ #1 .code:n =
+ {
+ \tl_if_empty:NTF \l_@@_setup_type_tl
+ { \@@_provide_dict_default_transl:nn {#1} {##1} }
+ {
+ \msg_info:nnn { zref-clever }
+ { option-not-type-specific } {#1}
+ }
+ } ,
+ }
+ }
+\seq_map_inline:Nn
+ \c_@@_ref_options_possibly_type_specific_seq
+ {
+ \keys_define:nn { zref-clever / dictionary }
+ {
+ #1 .value_required:n = true ,
+ #1 .code:n =
+ {
+ \tl_if_empty:NTF \l_@@_setup_type_tl
+ { \@@_provide_dict_default_transl:nn {#1} {##1} }
+ { \@@_provide_dict_type_transl:nn {#1} {##1} }
+ } ,
+ }
+ }
+\seq_map_inline:Nn
+ \c_@@_ref_options_type_names_seq
+ {
+ \keys_define:nn { zref-clever / dictionary }
+ {
+ #1 .value_required:n = true ,
+ #1 .code:n =
+ {
+ \tl_if_empty:NTF \l_@@_setup_type_tl
+ {
+ \msg_info:nnn { zref-clever }
+ { option-only-type-specific } {#1}
+ }
+ {
+ \tl_if_empty:NTF \l_@@_dict_decl_case_tl
+ { \@@_provide_dict_type_transl:nn {#1} {##1} }
+ {
+ \@@_provide_dict_type_transl:nn
+ { \l_@@_dict_decl_case_tl - #1 } {##1}
+ }
+ }
+ } ,
+ }
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsubsection*{Fallback}
+%
+% All ``strings'' queried with \cs{@@_get_ref_string:nN} -- in practice, those
+% in either \cs{c_@@_ref_options_necessarily_not_type_specific_seq} or
+% \cs{c_@@_ref_options_possibly_type_specific_seq} -- must have their values
+% set for ``fallback'', even if to empty ones, since this is what will be
+% retrieved in the absence of a proper translation, which will be the case if
+% \pkg{babel} or \pkg{polyglossia} is loaded and sets a language which
+% \pkg{zref-clever} does not know. On the other hand, ``type names'' are not
+% looked for in ``fallback'', since it is indeed impossible to provide any
+% reasonable value for them for a ``specified but unknown language''. Also
+% ``font'' options -- those in \cs{c_@@_ref_options_font_seq}, and queried
+% with \cs{@@_get_ref_font:nN} -- do not need to be provided here, since the
+% later function sets an empty value if the option is not found.
+%
+% \begin{macrocode}
+\prop_new:N \g_@@_fallback_dict_prop
+\prop_gset_from_keyval:Nn \g_@@_fallback_dict_prop
+ {
+ tpairsep = {,~} ,
+ tlistsep = {,~} ,
+ tlastsep = {,~} ,
+ notesep = {~} ,
+ namesep = {\nobreakspace} ,
+ pairsep = {,~} ,
+ listsep = {,~} ,
+ lastsep = {,~} ,
+ rangesep = {\textendash} ,
+ refpre = {} ,
+ refpos = {} ,
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsubsection*{Get translations}
+%
+% \begin{macro}{\@@_get_type_transl:nnnNF}
+% Get type-specific translation of \meta{key} for \meta{type} and
+% \meta{language}, and store it in \meta{tl variable} if found. If not
+% found, leave the \meta{false code} on the stream, in which case the value
+% of \meta{tl variable} should not be relied upon.
+% \begin{syntax}
+% \cs{@@_get_type_transl:nnnNF} \Arg{language} \Arg{type} \Arg{key}
+% ~~\meta{tl variable} \Arg{false code}
+% \end{syntax}
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn
+ \@@_get_type_transl:nnnN #1#2#3#4 { F }
+ {
+ \prop_get:NnNTF \g_@@_languages_prop {#1}
+ \l_@@_dict_language_tl
+ {
+ \prop_get:cnNTF
+ { g_@@_dict_ \l_@@_dict_language_tl _prop }
+ { type- #2 - #3 } #4
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ { \prg_return_false: }
+ }
+\prg_generate_conditional_variant:Nnn
+ \@@_get_type_transl:nnnN { xxxN , xxnN } { F }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_get_default_transl:nnNF}
+% Get default translation of \meta{key} for \meta{language}, and store it in
+% \meta{tl variable} if found. If not found, leave the \meta{false code} on
+% the stream, in which case the value of \meta{tl variable} should not be
+% relied upon.
+% \begin{syntax}
+% \cs{@@_get_default_transl:nnNF} \Arg{language} \Arg{key}
+% ~~\meta{tl variable} \Arg{false code}
+% \end{syntax}
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn
+ \@@_get_default_transl:nnN #1#2#3 { F }
+ {
+ \prop_get:NnNTF \g_@@_languages_prop {#1}
+ \l_@@_dict_language_tl
+ {
+ \prop_get:cnNTF
+ { g_@@_dict_ \l_@@_dict_language_tl _prop }
+ { default- #2 } #3
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ { \prg_return_false: }
+ }
+\prg_generate_conditional_variant:Nnn
+ \@@_get_default_transl:nnN { xnN } { F }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_get_fallback_transl:nNF}
+% Get fallback translation of \meta{key}, and store it in \meta{tl variable}
+% if found. If not found, leave the \meta{false code} on the stream, in
+% which case the value of \meta{tl variable} should not be relied upon.
+% \begin{syntax}
+% \cs{@@_get_fallback_transl:nNF} \Arg{key}
+% ~~\meta{tl variable} \Arg{false code}
+% \end{syntax}
+% \begin{macrocode}
+% {<key>}<tl var to set>
+\prg_new_protected_conditional:Npnn
+ \@@_get_fallback_transl:nN #1#2 { F }
+ {
+ \prop_get:NnNTF \g_@@_fallback_dict_prop
+ { #1 } #2
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsection{Options}
+%
+%
+% \subsubsection*{Auxiliary}
+%
+%
+% \begin{macro}{\@@_prop_put_non_empty:Nnn}
+% If \meta{value} is empty, remove \meta{key} from \meta{property list}.
+% Otherwise, add \meta{key} = \meta{value} to \meta{property list}.
+% \begin{syntax}
+% \cs{@@_prop_put_non_empty:Nnn} \meta{property list} \Arg{key} \Arg{value}
+% \end{syntax}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_prop_put_non_empty:Nnn #1#2#3
+ {
+ \tl_if_empty:nTF {#3}
+ { \prop_remove:Nn #1 {#2} }
+ { \prop_put:Nnn #1 {#2} {#3} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsubsection*{\opt{ref} option}
+%
+% \cs{l_@@_ref_property_tl} stores the property to which the reference is
+% being made. Note that one thing \emph{must} be handled at this point: the
+% existence of the property itself, as far as \pkg{zref} is concerned. This
+% because typesetting relies on the check \cs{zref@ifrefcontainsprop}, which
+% \emph{presumes} the property is defined and silently expands the \emph{true}
+% branch if it is not (see \url{https://github.com/ho-tex/zref/issues/13},
+% thanks Ulrike Fischer). Therefore, before adding anything to
+% \cs{l_@@_ref_property_tl}, check if first here with
+% \cs{zref@ifpropundefined}: close it at the door.
+%
+%
+% \begin{macrocode}
+\tl_new:N \l_@@_ref_property_tl
+\keys_define:nn { zref-clever / reference }
+ {
+ ref .code:n =
+ {
+ \zref@ifpropundefined {#1}
+ {
+ \msg_warning:nnn { zref-clever } { zref-property-undefined } {#1}
+ \tl_set:Nn \l_@@_ref_property_tl { default }
+ }
+ { \tl_set:Nn \l_@@_ref_property_tl {#1} }
+ } ,
+ ref .initial:n = default ,
+ ref .value_required:n = true ,
+ page .meta:n = { ref = page },
+ page .value_forbidden:n = true ,
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsubsection*{\opt{typeset} option}
+%
+% \begin{macrocode}
+\bool_new:N \l_@@_typeset_ref_bool
+\bool_new:N \l_@@_typeset_name_bool
+\keys_define:nn { zref-clever / reference }
+ {
+ typeset .choice: ,
+ typeset / both .code:n =
+ {
+ \bool_set_true:N \l_@@_typeset_ref_bool
+ \bool_set_true:N \l_@@_typeset_name_bool
+ } ,
+ typeset / ref .code:n =
+ {
+ \bool_set_true:N \l_@@_typeset_ref_bool
+ \bool_set_false:N \l_@@_typeset_name_bool
+ } ,
+ typeset / name .code:n =
+ {
+ \bool_set_false:N \l_@@_typeset_ref_bool
+ \bool_set_true:N \l_@@_typeset_name_bool
+ } ,
+ typeset .initial:n = both ,
+ typeset .value_required:n = true ,
+
+ noname .meta:n = { typeset = ref } ,
+ noname .value_forbidden:n = true ,
+ noref .meta:n = { typeset = name } ,
+ noref .value_forbidden:n = true ,
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsubsection*{\opt{sort} option}
+%
+% \begin{macrocode}
+\bool_new:N \l_@@_typeset_sort_bool
+\keys_define:nn { zref-clever / reference }
+ {
+ sort .bool_set:N = \l_@@_typeset_sort_bool ,
+ sort .initial:n = true ,
+ sort .default:n = true ,
+ nosort .meta:n = { sort = false },
+ nosort .value_forbidden:n = true ,
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsubsection*{\opt{typesort} option}
+%
+% \cs{l_@@_typesort_seq} is stored reversed, since the sort priorities are
+% computed in the negative range in \cs{@@_sort_default_different_types:nn},
+% so that we can implicitly rely on `0' being the ``last value'', and spare
+% creating an integer variable using \cs{seq_map_indexed_inline:Nn}.
+%
+% \begin{macrocode}
+\seq_new:N \l_@@_typesort_seq
+\keys_define:nn { zref-clever / reference }
+ {
+ typesort .code:n =
+ {
+ \seq_set_from_clist:Nn \l_@@_typesort_seq {#1}
+ \seq_reverse:N \l_@@_typesort_seq
+ } ,
+ typesort .initial:n =
+ { part , chapter , section , paragraph },
+ typesort .value_required:n = true ,
+ notypesort .code:n =
+ { \seq_clear:N \l_@@_typesort_seq } ,
+ notypesort .value_forbidden:n = true ,
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsubsection*{\opt{comp} option}
+%
+% \begin{macrocode}
+\bool_new:N \l_@@_typeset_compress_bool
+\keys_define:nn { zref-clever / reference }
+ {
+ comp .bool_set:N = \l_@@_typeset_compress_bool ,
+ comp .initial:n = true ,
+ comp .default:n = true ,
+ nocomp .meta:n = { comp = false },
+ nocomp .value_forbidden:n = true ,
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsubsection*{\opt{range} option}
+%
+% \begin{macrocode}
+\bool_new:N \l_@@_typeset_range_bool
+\keys_define:nn { zref-clever / reference }
+ {
+ range .bool_set:N = \l_@@_typeset_range_bool ,
+ range .initial:n = false ,
+ range .default:n = true ,
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsubsection*{\opt{cap} and \opt{capfirst} options}
+%
+% \begin{macrocode}
+\bool_new:N \l_@@_capitalize_bool
+\bool_new:N \l_@@_capitalize_first_bool
+\keys_define:nn { zref-clever / reference }
+ {
+ cap .bool_set:N = \l_@@_capitalize_bool ,
+ cap .initial:n = false ,
+ cap .default:n = true ,
+ nocap .meta:n = { cap = false },
+ nocap .value_forbidden:n = true ,
+
+ capfirst .bool_set:N = \l_@@_capitalize_first_bool ,
+ capfirst .initial:n = false ,
+ capfirst .default:n = true ,
+ }
+% \end{macrocode}
+%
+%
+% \subsubsection*{\opt{abbrev} and \opt{noabbrevfirst} options}
+%
+% \begin{macrocode}
+\bool_new:N \l_@@_abbrev_bool
+\bool_new:N \l_@@_noabbrev_first_bool
+\keys_define:nn { zref-clever / reference }
+ {
+ abbrev .bool_set:N = \l_@@_abbrev_bool ,
+ abbrev .initial:n = false ,
+ abbrev .default:n = true ,
+ noabbrev .meta:n = { abbrev = false },
+ noabbrev .value_forbidden:n = true ,
+
+ noabbrevfirst .bool_set:N = \l_@@_noabbrev_first_bool ,
+ noabbrevfirst .initial:n = false ,
+ noabbrevfirst .default:n = true ,
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsubsection*{\opt{S} option}
+%
+% \begin{macrocode}
+\keys_define:nn { zref-clever / reference }
+ {
+ S .meta:n =
+ { capfirst = true , noabbrevfirst = true },
+ S .value_forbidden:n = true ,
+ }
+% \end{macrocode}
+%
+%
+% \subsubsection*{\opt{hyperref} option}
+%
+% \begin{macrocode}
+\bool_new:N \l_@@_use_hyperref_bool
+\bool_new:N \l_@@_warn_hyperref_bool
+\keys_define:nn { zref-clever / reference }
+ {
+ 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}
+%
+% \begin{macrocode}
+\AddToHook { begindocument }
+ {
+ \@@_if_package_loaded:nTF { hyperref }
+ {
+ \bool_if:NT \l_@@_use_hyperref_bool
+ { \RequirePackage { zref-hyperref } }
+ }
+ {
+ \bool_if:NT \l_@@_warn_hyperref_bool
+ { \msg_warning:nn { zref-clever } { missing-hyperref } }
+ \bool_set_false:N \l_@@_use_hyperref_bool
+ }
+ \keys_define:nn { zref-clever / reference }
+ {
+ hyperref .code:n =
+ { \msg_warning:nn { zref-clever } { hyperref-preamble-only } }
+ }
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsubsection*{\opt{nameinlink} option}
+%
+% \begin{macrocode}
+\str_new:N \l_@@_nameinlink_str
+\keys_define:nn { zref-clever / reference }
+ {
+ nameinlink .choice: ,
+ nameinlink / true .code:n =
+ { \str_set:Nn \l_@@_nameinlink_str { true } } ,
+ nameinlink / false .code:n =
+ { \str_set:Nn \l_@@_nameinlink_str { false } } ,
+ nameinlink / single .code:n =
+ { \str_set:Nn \l_@@_nameinlink_str { single } } ,
+ nameinlink / tsingle .code:n =
+ { \str_set:Nn \l_@@_nameinlink_str { tsingle } } ,
+ nameinlink .initial:n = tsingle ,
+ nameinlink .default:n = true ,
+ }
+% \end{macrocode}
+%
+%
+% \subsubsection*{\opt{preposinlink} option}
+%
+% \begin{macrocode}
+\bool_new:N \l_@@_preposinlink_bool
+\keys_define:nn { zref-clever / reference }
+ {
+ preposinlink .bool_set:N = \l_@@_preposinlink_bool ,
+ preposinlink .initial:n = false ,
+ preposinlink .default:n = true ,
+ }
+% \end{macrocode}
+%
+%
+% \subsubsection*{\opt{lang} option}
+% \phantomsection{}\zlabel{sec:lang-option}
+%
+% \cs{l_@@_current_language_tl} is an internal alias for \pkg{babel}'s
+% \cs{languagename} or \pkg{polyglossia}'s \cs{mainbabelname} and, if none of
+% them is loaded, we set it to \texttt{english}. \cs{l_@@_main_language_tl}
+% is an internal alias for \pkg{babel}'s \cs{bbl@main@language} or for
+% \pkg{polyglossia}'s \cs{mainbabelname}, as the case may be. Note that for
+% \pkg{polyglossia} we get \pkg{babel}'s language names, so that we only need
+% to handle those internally. \cs{l_@@_ref_language_tl} is the internal
+% variable which stores the language in which the reference is to be made.
+%
+% The overall setup here seems a little roundabout, but this is actually
+% required. In the preamble, we (potentially) don't yet have values for the
+% ``current'' and ``main'' document languages, this must be retrieved at a
+% \texttt{begindocument} hook. The \texttt{begindocument} hook is responsible
+% to get values for \cs{l_@@_current_language_tl} and
+% \cs{l_@@_main_language_tl}, and to set the default for
+% \cs{l_@@_ref_language_tl}. Package options, or preamble calls to
+% \cs{zcsetup} are also hooked at \texttt{begindocument}, but come after the
+% first hook, so that the pertinent variables have been set when they are
+% executed. Finally, we set a third \texttt{begindocument} hook, at
+% \texttt{begindocument/before}, so that it runs after any options set in the
+% preamble. This hook redefines the \opt{lang} option for immediate execution
+% in the document body, and ensures the \texttt{current} language's dictionary
+% gets loaded, if it hadn't been already.
+%
+% For the \pkg{babel} and \pkg{polyglossia} variables which store the
+% ``current'' and ``main'' languages, see
+% \url{https://tex.stackexchange.com/a/233178}, including comments,
+% particularly the one by Javier Bezos. For the \pkg{babel} and
+% \pkg{polyglossia} variables which store the list of loaded languages, see
+% \url{https://tex.stackexchange.com/a/281220}, including comments,
+% particularly PLK's. Note, however, that languages loaded by
+% \cs{babelprovide}, either directly, ``on the fly'', or with the
+% \texttt{provide} option, \texttt{do not} get included in \cs{bbl@loaded}.
+%
+
+% \begin{macrocode}
+\tl_new:N \l_@@_ref_language_tl
+\tl_new:N \l_@@_current_language_tl
+\tl_new:N \l_@@_main_language_tl
+\AddToHook { begindocument }
+ {
+ \@@_if_package_loaded:nTF { babel }
+ {
+ \tl_set:Nn \l_@@_current_language_tl { \languagename }
+ \tl_set:Nn \l_@@_main_language_tl { \bbl@main@language }
+ }
+ {
+ \@@_if_package_loaded:nTF { polyglossia }
+ {
+ \tl_set:Nn \l_@@_current_language_tl { \babelname }
+ \tl_set:Nn \l_@@_main_language_tl { \mainbabelname }
+ }
+ {
+ \tl_set:Nn \l_@@_current_language_tl { english }
+ \tl_set:Nn \l_@@_main_language_tl { english }
+ }
+ }
+% \end{macrocode}
+% Provide default value for \cs{l_@@_ref_language_tl} corresponding to option
+% \opt{current}, but do so outside of the \pkg{l3keys} machinery (that is,
+% instead of using \texttt{.initial:n}), so that we are able to distinguish
+% when the user actually gave the option, in which case the dictionary loading
+% is done verbosely, from when we are setting the default value (here), in
+% which case the dictionary loading is done silently.
+% \begin{macrocode}
+ \tl_set:Nn \l_@@_ref_language_tl
+ { \l_@@_current_language_tl }
+ }
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+\keys_define:nn { zref-clever / reference }
+ {
+ lang .code:n =
+ {
+ \AddToHook { begindocument }
+ {
+ \str_case:nnF {#1}
+ {
+ { current }
+ {
+ \tl_set:Nn \l_@@_ref_language_tl
+ { \l_@@_current_language_tl }
+ \@@_provide_dictionary_verbose:x
+ { \l_@@_ref_language_tl }
+ }
+
+ { main }
+ {
+ \tl_set:Nn \l_@@_ref_language_tl
+ { \l_@@_main_language_tl }
+ \@@_provide_dictionary_verbose:x
+ { \l_@@_ref_language_tl }
+ }
+ }
+ {
+ \prop_if_in:NnTF \g_@@_languages_prop {#1}
+ { \tl_set:Nn \l_@@_ref_language_tl {#1} }
+ {
+ \msg_warning:nnn { zref-clever }
+ { unknown-language-opt } {#1}
+ \tl_set:Nn \l_@@_ref_language_tl
+ { \l_@@_current_language_tl }
+ }
+ \@@_provide_dictionary_verbose:x
+ { \l_@@_ref_language_tl }
+ }
+ }
+ } ,
+ lang .value_required:n = true ,
+ }
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+\AddToHook { begindocument / before }
+ {
+ \AddToHook { begindocument }
+ {
+% \end{macrocode}
+% If any \opt{lang} option has been given by the user, the corresponding
+% language is already loaded, otherwise, ensure the default one
+% (\texttt{current}) gets loaded early, but not verbosely.
+% \begin{macrocode}
+ \@@_provide_dictionary:x { \l_@@_ref_language_tl }
+% \end{macrocode}
+% Redefinition of the \texttt{lang} key option for the document body. Also,
+% drop the verbose dictionary loading in the document body, as it can become
+% intrusive depending on the use case, and does not provide much ``juice''
+% anyway: in \cs{zcref} missing names warnings will already ensue.
+% \begin{macrocode}
+ \keys_define:nn { zref-clever / reference }
+ {
+ lang .code:n =
+ {
+ \str_case:nnF {#1}
+ {
+ { current }
+ {
+ \tl_set:Nn \l_@@_ref_language_tl
+ { \l_@@_current_language_tl }
+ \@@_provide_dictionary:x
+ { \l_@@_ref_language_tl }
+ }
+
+ { main }
+ {
+ \tl_set:Nn \l_@@_ref_language_tl
+ { \l_@@_main_language_tl }
+ \@@_provide_dictionary:x
+ { \l_@@_ref_language_tl }
+ }
+ }
+ {
+ \prop_if_in:NnTF \g_@@_languages_prop {#1}
+ { \tl_set:Nn \l_@@_ref_language_tl {#1} }
+ {
+ \msg_warning:nnn { zref-clever }
+ { unknown-language-opt } {#1}
+ \tl_set:Nn \l_@@_ref_language_tl
+ { \l_@@_current_language_tl }
+ }
+ \@@_provide_dictionary:x
+ { \l_@@_ref_language_tl }
+ }
+ } ,
+ lang .value_required:n = true ,
+ }
+ }
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsubsection*{\opt{d} option}
+%
+% For setting the declension case. Short for convenience and for not
+% polluting the markup too much given that, for languages that need it, it may
+% get to be used frequently.
+%
+% Thanks \texttt{@samcarter} and Alan Munn for useful comments about
+% declension on the TeX.SX chat. Also, Florent Rougon's efforts in this area,
+% with the \pkg{xcref} package (\url{https://github.com/frougon/xcref}), have
+% been an insightful source to frame the problem in general terms.
+%
+% \begin{macrocode}
+\tl_new:N \l_@@_ref_decl_case_tl
+\keys_define:nn { zref-clever / reference }
+ {
+ d .code:n =
+ { \msg_warning:nnn { zref-clever } { option-document-only } { d } } ,
+ }
+\AddToHook { begindocument }
+ {
+ \keys_define:nn { zref-clever / reference }
+ {
+% \end{macrocode}
+% We just store the value at this point, which is validated by
+% \cs{@@_process_language_options:} after \cs{keys_set:nn}.
+% \begin{macrocode}
+ d .tl_set:N = \l_@@_ref_decl_case_tl ,
+ d .value_required:n = true ,
+ }
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsubsection*{\opt{nudge} \& co.\ options}
+%
+% \begin{macrocode}
+\bool_new:N \l_@@_nudge_enabled_bool
+\bool_new:N \l_@@_nudge_multitype_bool
+\bool_new:N \l_@@_nudge_comptosing_bool
+\bool_new:N \l_@@_nudge_singular_bool
+\bool_new:N \l_@@_nudge_gender_bool
+\tl_new:N \l_@@_ref_gender_tl
+\keys_define:nn { zref-clever / reference }
+ {
+ nudge .choice: ,
+ nudge / true .code:n =
+ { \bool_set_true:N \l_@@_nudge_enabled_bool } ,
+ nudge / false .code:n =
+ { \bool_set_false:N \l_@@_nudge_enabled_bool } ,
+ nudge / ifdraft .code:n =
+ {
+ \ifdraft
+ { \bool_set_false:N \l_@@_nudge_enabled_bool }
+ { \bool_set_true:N \l_@@_nudge_enabled_bool }
+ } ,
+ nudge / iffinal .code:n =
+ {
+ \ifoptionfinal
+ { \bool_set_true:N \l_@@_nudge_enabled_bool }
+ { \bool_set_false:N \l_@@_nudge_enabled_bool }
+ } ,
+ nudge .initial:n = false ,
+ nudge .default:n = true ,
+ nonudge .meta:n = { nudge = false } ,
+ nonudge .value_forbidden:n = true ,
+ nudgeif .code:n =
+ {
+ \bool_set_false:N \l_@@_nudge_multitype_bool
+ \bool_set_false:N \l_@@_nudge_comptosing_bool
+ \bool_set_false:N \l_@@_nudge_gender_bool
+ \clist_map_inline:nn {#1}
+ {
+ \str_case:nnF {##1}
+ {
+ { multitype }
+ { \bool_set_true:N \l_@@_nudge_multitype_bool }
+ { comptosing }
+ { \bool_set_true:N \l_@@_nudge_comptosing_bool }
+ { gender }
+ { \bool_set_true:N \l_@@_nudge_gender_bool }
+ { all }
+ {
+ \bool_set_true:N \l_@@_nudge_multitype_bool
+ \bool_set_true:N \l_@@_nudge_comptosing_bool
+ \bool_set_true:N \l_@@_nudge_gender_bool
+ }
+ }
+ {
+ \msg_warning:nnn { zref-clever }
+ { nudgeif-unknown-value } {##1}
+ }
+ }
+ } ,
+ nudgeif .value_required:n = true ,
+ nudgeif .initial:n = all ,
+ sg .bool_set:N = \l_@@_nudge_singular_bool ,
+ sg .initial:n = false ,
+ sg .default:n = true ,
+ g .code:n =
+ { \msg_warning:nnn { zref-clever } { option-document-only } { g } } ,
+ }
+\AddToHook { begindocument }
+ {
+ \keys_define:nn { zref-clever / reference }
+ {
+% \end{macrocode}
+% We just store the value at this point, which is validated by
+% \cs{@@_process_language_options:} after \cs{keys_set:nn}.
+% \begin{macrocode}
+ g .tl_set:N = \l_@@_ref_gender_tl ,
+ g .value_required:n = true ,
+ }
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsubsection*{\opt{font} option}
+%
+% \opt{font} \emph{can't be used as a package option}, since the options get
+% expanded by \LaTeX{} before being passed to the package (see
+% \url{https://tex.stackexchange.com/a/489570}). It can be set in \cs{zcref}
+% and, for global settings, with \cs{zcsetup}. Note that, technically, the
+% ``raw'' options are already available as \cs{@raw@opt@\meta{package}.sty}
+% (see \url{https://tex.stackexchange.com/a/618439}, thanks David Carlisle).
+%
+% \begin{macrocode}
+\tl_new:N \l_@@_ref_typeset_font_tl
+\keys_define:nn { zref-clever / reference }
+ { font .tl_set:N = \l_@@_ref_typeset_font_tl }
+% \end{macrocode}
+%
+%
+%
+% \subsubsection*{\opt{titleref} option}
+%
+% \begin{macrocode}
+\keys_define:nn { zref-clever / reference }
+ {
+ titleref .code:n = { \RequirePackage { zref-titleref } } ,
+ titleref .value_forbidden:n = true ,
+ }
+\AddToHook { begindocument }
+ {
+ \keys_define:nn { zref-clever / reference }
+ {
+ titleref .code:n =
+ { \msg_warning:nn { zref-clever } { titleref-preamble-only } }
+ }
+ }
+% \end{macrocode}
+%
+%
+% \subsubsection*{\opt{note} option}
+%
+% \begin{macrocode}
+\tl_new:N \l_@@_zcref_note_tl
+\keys_define:nn { zref-clever / reference }
+ {
+ note .tl_set:N = \l_@@_zcref_note_tl ,
+ note .value_required:n = true ,
+ }
+% \end{macrocode}
+%
+%
+% \subsubsection*{\opt{check} option}
+%
+% Integration with \pkg{zref-check}.
+%
+% \begin{macrocode}
+\bool_new:N \l_@@_zrefcheck_available_bool
+\bool_new:N \l_@@_zcref_with_check_bool
+\keys_define:nn { zref-clever / reference }
+ {
+ check .code:n = { \RequirePackage { zref-check } } ,
+ check .value_forbidden:n = true ,
+ }
+\AddToHook { begindocument }
+ {
+ \@@_if_package_loaded:nTF { zref-check }
+ {
+ \bool_set_true:N \l_@@_zrefcheck_available_bool
+ \keys_define:nn { zref-clever / reference }
+ {
+ check .code:n =
+ {
+ \bool_set_true:N \l_@@_zcref_with_check_bool
+ \keys_set:nn { zref-check / zcheck } {#1}
+ } ,
+ check .value_required:n = true ,
+ }
+ }
+ {
+ \bool_set_false:N \l_@@_zrefcheck_available_bool
+ \keys_define:nn { zref-clever / reference }
+ {
+ check .value_forbidden:n = false ,
+ check .code:n =
+ { \msg_warning:nn { zref-clever } { missing-zref-check } } ,
+ }
+ }
+ }
+% \end{macrocode}
+%
+%
+% \subsubsection*{\opt{countertype} option}
+%
+% \cs{l_@@_counter_type_prop} is used by \texttt{zc@type} property, and stores
+% a mapping from ``counter'' to ``reference type''. Only those counters whose
+% type name is different from that of the counter need to be specified, since
+% \texttt{zc@type} presumes the counter as the type if the counter is not
+% found in \cs{l_@@_counter_type_prop}.
+%
+% \begin{macrocode}
+\prop_new:N \l_@@_counter_type_prop
+\keys_define:nn { zref-clever / label }
+ {
+ countertype .code:n =
+ {
+ \keyval_parse:nnn
+ {
+ \msg_warning:nnnn { zref-clever }
+ { key-requires-value } { countertype }
+ }
+ {
+ \@@_prop_put_non_empty:Nnn
+ \l_@@_counter_type_prop
+ }
+ {#1}
+ } ,
+ countertype .value_required:n = true ,
+ countertype .initial:n =
+ {
+ subsection = section ,
+ subsubsection = section ,
+ subparagraph = paragraph ,
+ enumi = item ,
+ enumii = item ,
+ enumiii = item ,
+ enumiv = item ,
+ mpfootnote = footnote ,
+ } ,
+ }
+% \end{macrocode}
+%
+%
+% \subsubsection*{\opt{counterresetters} option}
+%
+% \cs{l_@@_counter_resetters_seq} is used by \cs{@@_counter_reset_by:n} to
+% populate the \texttt{zc@enclval} property, and stores the list of counters
+% which are potential ``enclosing counters'' for other counters. This option
+% is constructed such that users can only \emph{add} items to the variable.
+% There would be little gain and some risk in allowing removal, and the syntax
+% of the option would become unnecessarily more complicated. Besides, users
+% can already override, for any particular counter, the search done from the
+% set in \cs{l_@@_counter_resetters_seq} with the \opt{counterresetby} option.
+%
+% \begin{macrocode}
+\seq_new:N \l_@@_counter_resetters_seq
+\keys_define:nn { zref-clever / label }
+ {
+ counterresetters .code:n =
+ {
+ \clist_map_inline:nn {#1}
+ {
+ \seq_if_in:NnF \l_@@_counter_resetters_seq {##1}
+ {
+ \seq_put_right:Nn
+ \l_@@_counter_resetters_seq {##1}
+ }
+ }
+ } ,
+ counterresetters .initial:n =
+ {
+ part ,
+ chapter ,
+ section ,
+ subsection ,
+ subsubsection ,
+ paragraph ,
+ subparagraph ,
+ },
+ counterresetters .value_required:n = true ,
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsubsection*{\opt{counterresetby} option}
+%
+% \cs{l_@@_counter_resetby_prop} is used by \cs{@@_counter_reset_by:n} to
+% populate the \texttt{zc@enclval} property, and stores a mapping from
+% counters to the counter which resets each of them. This mapping has
+% precedence in \cs{@@_counter_reset_by:n} over the search through
+% \cs{l_@@_counter_resetters_seq}.
+%
+% \begin{macrocode}
+\prop_new:N \l_@@_counter_resetby_prop
+\keys_define:nn { zref-clever / label }
+ {
+ counterresetby .code:n =
+ {
+ \keyval_parse:nnn
+ {
+ \msg_warning:nnn { zref-clever }
+ { key-requires-value } { counterresetby }
+ }
+ {
+ \@@_prop_put_non_empty:Nnn
+ \l_@@_counter_resetby_prop
+ }
+ {#1}
+ } ,
+ counterresetby .value_required:n = true ,
+ counterresetby .initial:n =
+ {
+% \end{macrocode}
+% The counters for the \texttt{enumerate} environment do not use the regular
+% counter machinery for resetting on each level, but are nested nevertheless
+% by other means, treat them as exception.
+% \begin{macrocode}
+ enumii = enumi ,
+ enumiii = enumii ,
+ enumiv = enumiii ,
+ } ,
+ }
+% \end{macrocode}
+%
+%
+% \subsubsection*{\opt{currentcounter} option}
+%
+% \cs{l_@@_current_counter_tl} is pretty much the starting point of all of the
+% data specification for label setting done by \pkg{zref} with our setup for
+% it. It exists because we must provide some ``handle'' to specify the
+% current counter for packages/features that do not set \cs{@currentcounter}
+% appropriately.
+%
+% \begin{macrocode}
+\tl_new:N \l_@@_current_counter_tl
+\keys_define:nn { zref-clever / label }
+ {
+ currentcounter .tl_set:N = \l_@@_current_counter_tl ,
+ currentcounter .value_required:n = true ,
+ currentcounter .initial:n = \@currentcounter ,
+ }
+% \end{macrocode}
+%
+%
+% \subsubsection*{\opt{nocompat} option}
+%
+%
+% \begin{macrocode}
+\bool_new:N \g_@@_nocompat_bool
+\seq_new:N \g_@@_nocompat_modules_seq
+\keys_define:nn { zref-clever / reference }
+ {
+ nocompat .code:n =
+ {
+ \tl_if_empty:nTF {#1}
+ { \bool_gset_true:N \g_@@_nocompat_bool }
+ {
+ \clist_map_inline:nn {#1}
+ {
+ \seq_if_in:NnF \g_@@_nocompat_modules_seq {##1}
+ {
+ \seq_gput_right:Nn
+ \g_@@_nocompat_modules_seq {##1}
+ }
+ }
+ }
+ } ,
+ }
+\AddToHook { begindocument }
+ {
+ \keys_define:nn { zref-clever / reference }
+ {
+ nocompat .code:n =
+ {
+ \msg_warning:nnn { zref-clever }
+ { option-preamble-only } { nocompat }
+ }
+ }
+ }
+\AtEndOfPackage
+ {
+ \AddToHook { begindocument }
+ {
+ \seq_map_inline:Nn \g_@@_nocompat_modules_seq
+ { \msg_warning:nnn { zref-clever } { unknown-compat-module } {#1} }
+ }
+ }
+% \end{macrocode}
+%
+% \begin{macro}{\@@_compat_module:nn}
+% Function to be used for compatibility modules loading. It should load the
+% module as long as \cs{l_@@_nocompat_bool} is false and \meta{module} is
+% not in \cs{l_@@_nocompat_modules_seq}. The \texttt{begindocument} hook is
+% needed so that we can have the option functional along the whole preamble,
+% not just at package load time. This requirement might be relaxed if we
+% made the option only available at load time, but this would not buy us
+% much leeway anyway, since for most compatibility modules, we must test for
+% the presence of packages at \texttt{begindocument}, only kernel features
+% and document classes could be checked reliably before that. Besides,
+% since we are using the new hook management system, there is always its
+% functionality to deal with potential loading order issues.
+% \begin{syntax}
+% \cs{@@_compat_module:nn} \Arg{module} \Arg{code}
+% \end{syntax}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_compat_module:nn #1#2
+ {
+ \AddToHook { begindocument }
+ {
+ \bool_if:NF \g_@@_nocompat_bool
+ { \seq_if_in:NnF \g_@@_nocompat_modules_seq {#1} {#2} }
+ \seq_gremove_all:Nn \g_@@_nocompat_modules_seq {#1}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsubsection*{Reference options}
+% \zlabel{sec:reference-options}
+%
+% This is a set of options related to reference typesetting which receive
+% equal treatment and, hence, are handled in batch. Since we are dealing with
+% options to be passed to \cs{zcref} or to \cs{zcsetup} or at load time, only
+% ``not necessarily type-specific'' options are pertinent here. However, they
+% \emph{may} either be type-specific or language-specific, and thus must be
+% stored in a property list, \cs{l_@@_ref_options_prop}, in order to be
+% retrieved from the option \emph{name} by \cs{@@_get_ref_string:nN} and
+% \cs{@@_get_ref_font:nN} according to context and precedence rules.
+%
+% The keys are set so that any value, including an empty one, is added to
+% \cs{l_@@_ref_options_prop}, while a key with \emph{no value} removes the
+% property from the list, so that these options can then fall back to lower
+% precedence levels settings. For discussion about the used technique, see
+% \zcref{sec:zcreftypesetup}.
+%
+% \begin{macrocode}
+\prop_new:N \l_@@_ref_options_prop
+\seq_map_inline:Nn
+ \c_@@_ref_options_reference_seq
+ {
+ \keys_define:nn { zref-clever / reference }
+ {
+ #1 .default:V = \c_novalue_tl ,
+ #1 .code:n =
+ {
+ \tl_if_novalue:nTF {##1}
+ { \prop_remove:Nn \l_@@_ref_options_prop {#1} }
+ { \prop_put:Nnn \l_@@_ref_options_prop {#1} {##1} }
+ } ,
+ }
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsubsection*{Package options}
+%
+% The options have been separated in two different groups, so that we can
+% potentially apply them selectively to different contexts: \texttt{label} and
+% \texttt{reference}. Currently, the only use of this selection is the
+% ability to exclude label related options from \cs{zcref}'s options. Anyway,
+% for load-time package options and for \cs{zcsetup} we want the whole set, so
+% we aggregate the two into \texttt{zref-clever/zcsetup}, and use that here.
+%
+% \begin{macrocode}
+\keys_define:nn { }
+ {
+ zref-clever / zcsetup .inherit:n =
+ {
+ zref-clever / label ,
+ zref-clever / reference ,
+ }
+ }
+% \end{macrocode}
+%
+%
+% Process load-time package options
+% (\url{https://tex.stackexchange.com/a/15840}).
+% \begin{macrocode}
+\ProcessKeysOptions { zref-clever / zcsetup }
+% \end{macrocode}
+%
+%
+%
+% \section{Configuration}
+%
+% \subsection{\cs{zcsetup}}
+%
+%
+% \begin{macro}[int]{\zcsetup}
+% Provide \cs{zcsetup}.
+% \begin{syntax}
+% \cs{zcsetup}\marg{options}
+% \end{syntax}
+% \begin{macrocode}
+\NewDocumentCommand \zcsetup { m }
+ { \@@_zcsetup:n {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_zcsetup:n}
+% A version of \cs{zcsetup} for internal use with variant.
+% \begin{syntax}
+% \cs{@@_zcsetup:n}\marg{options}
+% \end{syntax}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_zcsetup:n #1
+ { \keys_set:nn { zref-clever / zcsetup } {#1} }
+\cs_generate_variant:Nn \@@_zcsetup:n { x }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsection{\cs{zcRefTypeSetup}}
+% \zlabel{sec:zcreftypesetup}
+%
+% \cs{zcRefTypeSetup} is the main user interface for ``type-specific''
+% reference formatting. Settings done by this command have a higher
+% precedence than any translation, hence they override any language-specific
+% setting, either done at \cs{zcLanguageSetup} or by the package's
+% dictionaries. On the other hand, they have a lower precedence than non
+% type-specific general options. The \meta{options} should be given in the
+% usual \texttt{key=val} format. The \meta{type} does not need to pre-exist,
+% the property list variable to store the properties for the type gets created
+% if need be.
+%
+% \begin{macro}[int]{\zcRefTypeSetup}
+% \begin{syntax}
+% \cs{zcRefTypeSetup} \marg{type} \marg{options}
+% \end{syntax}
+% \begin{macrocode}
+\NewDocumentCommand \zcRefTypeSetup { m m }
+ {
+ \prop_if_exist:cF { l_@@_type_ #1 _options_prop }
+ { \prop_new:c { l_@@_type_ #1 _options_prop } }
+ \tl_set:Nn \l_@@_setup_type_tl {#1}
+ \keys_set:nn { zref-clever / typesetup } {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% Inside \cs{zcRefTypeSetup} any of the options \emph{can} receive empty
+% values, and those values, if they exist in the property list, will override
+% translations, regardless of their emptiness. In principle, we could live
+% with the situation of, once a setting has been made in
+% \cs{l_@@_type_<type>_options_prop} or in \cs{l_@@_ref_options_prop} it stays
+% there forever, and can only be overridden by a new value at the same
+% precedence level or a higher one. But it would be nice if an user can
+% ``unset'' an option at either of those scopes to go back to the lower
+% precedence level of the translations at any given point. So both in
+% \cs{zcRefTypeSetup} and in setting reference options (see
+% \zcref{sec:reference-options}), we leverage the distinction of an ``empty
+% valued key'' (\texttt{key=} or \texttt{key=\{\}}) from a ``key with no
+% value'' (\texttt{key}). This distinction is captured internally by the
+% lower-level key parsing, but must be made explicit at \cs{keys_set:nn} by
+% means of the \texttt{.default:V} property of the key in \cs{keys_define:nn}.
+% For the technique and some discussion about it, see
+% \url{https://tex.stackexchange.com/q/614690} (thanks Jonathan P.\ Spratte,
+% aka `Skillmon', and Phelype Oleinik) and
+% \url{https://github.com/latex3/latex3/pull/988}.
+%
+% \begin{macrocode}
+\seq_map_inline:Nn
+ \c_@@_ref_options_necessarily_not_type_specific_seq
+ {
+ \keys_define:nn { zref-clever / typesetup }
+ {
+ #1 .code:n =
+ {
+ \msg_warning:nnn { zref-clever }
+ { option-not-type-specific } {#1}
+ } ,
+ }
+ }
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+\seq_map_inline:Nn
+ \c_@@_ref_options_typesetup_seq
+ {
+ \keys_define:nn { zref-clever / typesetup }
+ {
+ #1 .default:V = \c_novalue_tl ,
+ #1 .code:n =
+ {
+ \tl_if_novalue:nTF {##1}
+ {
+ \prop_remove:cn
+ {
+ l_@@_type_
+ \l_@@_setup_type_tl _options_prop
+ }
+ {#1}
+ }
+ {
+ \prop_put:cnn
+ {
+ l_@@_type_
+ \l_@@_setup_type_tl _options_prop
+ }
+ {#1} {##1}
+ }
+ } ,
+ }
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsection{\cs{zcLanguageSetup}}
+%
+% \cs{zcLanguageSetup} is the main user interface for ``language-specific''
+% reference formatting, be it ``type-specific'' or not. The difference
+% between the two cases is captured by the \texttt{type} key, which works as a
+% sort of a ``switch''. Inside the \meta{options} argument of
+% \cs{zcLanguageSetup}, any options made before the first \texttt{type} key
+% declare ``default'' (non type-specific) translations. When the
+% \texttt{type} key is given with a value, the options following it will set
+% ``type-specific'' translations for that type. The current type can be
+% switched off by an empty \texttt{type} key. \cs{zcLanguageSetup} is
+% preamble only.
+%
+% \begin{macro}[int]{\zcLanguageSetup}
+% \begin{syntax}
+% \cs{zcLanguageSetup}\marg{language}\marg{options}
+% \end{syntax}
+% \begin{macrocode}
+\NewDocumentCommand \zcLanguageSetup { m m }
+ {
+ \group_begin:
+ \prop_get:NnNTF \g_@@_languages_prop {#1}
+ \l_@@_dict_language_tl
+ {
+ \tl_clear:N \l_@@_setup_type_tl
+ \exp_args:NNx \seq_set_from_clist:Nn
+ \l_@@_dict_declension_seq
+ {
+ \prop_item:cn
+ {
+ g_@@_dict_
+ \l_@@_dict_language_tl _prop
+ }
+ { declension }
+ }
+ \seq_if_empty:NTF \l_@@_dict_declension_seq
+ { \tl_clear:N \l_@@_dict_decl_case_tl }
+ {
+ \seq_get_left:NN \l_@@_dict_declension_seq
+ \l_@@_dict_decl_case_tl
+ }
+ \exp_args:NNx \seq_set_from_clist:Nn
+ \l_@@_dict_gender_seq
+ {
+ \prop_item:cn
+ {
+ g_@@_dict_
+ \l_@@_dict_language_tl _prop
+ }
+ { gender }
+ }
+ \keys_set:nn { zref-clever / langsetup } {#2}
+ }
+ { \msg_warning:nnn { zref-clever } { unknown-language-setup } {#1} }
+ \group_end:
+ }
+\@onlypreamble \zcLanguageSetup
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}
+% {
+% \@@_declare_type_transl:nnnn ,
+% \@@_declare_default_transl:nnn ,
+% }
+% A couple of auxiliary functions for the of
+% \texttt{{zref-clever/translation}} keys set in \cs{zcLanguageSetup}. They
+% respectively declare (unconditionally set) ``type-specific'' and
+% ``default'' translations.
+% \begin{syntax}
+% \cs{@@_declare_type_transl:nnnn} \Arg{language} \Arg{type}
+% ~~\Arg{key} \Arg{translation}
+% \cs{@@_declare_default_transl:nnn} \Arg{language}
+% ~~\Arg{key} \Arg{translation}
+% \end{syntax}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_declare_type_transl:nnnn #1#2#3#4
+ {
+ \prop_gput:cnn { g_@@_dict_ #1 _prop }
+ { type- #2 - #3 } {#4}
+ }
+\cs_generate_variant:Nn \@@_declare_type_transl:nnnn { VVnn , VVxn }
+\cs_new_protected:Npn \@@_declare_default_transl:nnn #1#2#3
+ {
+ \prop_gput:cnn { g_@@_dict_ #1 _prop }
+ { default- #2 } {#3}
+ }
+\cs_generate_variant:Nn \@@_declare_default_transl:nnn { Vnn }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% The set of keys for \texttt{{zref-clever/langsetup}}, which is used to
+% set language-specific translations in \cs{zcLanguageSetup}.
+%
+% \begin{macrocode}
+\keys_define:nn { zref-clever / langsetup }
+ {
+ type .code:n =
+ {
+ \tl_if_empty:nTF {#1}
+ { \tl_clear:N \l_@@_setup_type_tl }
+ { \tl_set:Nn \l_@@_setup_type_tl {#1} }
+ } ,
+ case .code:n =
+ {
+ \seq_if_empty:NTF \l_@@_dict_declension_seq
+ {
+ \msg_warning:nnxx { zref-clever } { language-no-decl-setup }
+ { \l_@@_dict_language_tl } {#1}
+ }
+ {
+ \seq_if_in:NnTF \l_@@_dict_declension_seq {#1}
+ { \tl_set:Nn \l_@@_dict_decl_case_tl {#1} }
+ {
+ \msg_warning:nnxx { zref-clever } { unknown-decl-case }
+ {#1} { \l_@@_dict_language_tl }
+ \seq_get_left:NN \l_@@_dict_declension_seq
+ \l_@@_dict_decl_case_tl
+ }
+ }
+ } ,
+ case .value_required:n = true ,
+ gender .code:n =
+ {
+ \seq_if_empty:NTF \l_@@_dict_gender_seq
+ {
+ \msg_warning:nnxxx { zref-clever } { language-no-gender }
+ { \l_@@_dict_language_tl } { gender } {#1}
+ }
+ {
+ \tl_if_empty:NTF \l_@@_setup_type_tl
+ {
+ \msg_warning:nnn { zref-clever }
+ { option-only-type-specific } { gender }
+ }
+ {
+ \seq_if_in:NnTF \l_@@_dict_gender_seq {#1}
+ {
+ \@@_declare_type_transl:VVnn
+ \l_@@_dict_language_tl
+ \l_@@_setup_type_tl
+ { gender } {#1}
+ }
+ {
+ \msg_warning:nnxx { zref-clever } { gender-not-declared }
+ { \l_@@_dict_language_tl } {#1}
+ }
+ }
+ }
+ } ,
+ gender .value_required:n = true ,
+ }
+\seq_map_inline:Nn
+ \c_@@_ref_options_necessarily_not_type_specific_seq
+ {
+ \keys_define:nn { zref-clever / langsetup }
+ {
+ #1 .value_required:n = true ,
+ #1 .code:n =
+ {
+ \tl_if_empty:NTF \l_@@_setup_type_tl
+ {
+ \@@_declare_default_transl:Vnn
+ \l_@@_dict_language_tl
+ {#1} {##1}
+ }
+ {
+ \msg_warning:nnn { zref-clever }
+ { option-not-type-specific } {#1}
+ }
+ } ,
+ }
+ }
+\seq_map_inline:Nn
+ \c_@@_ref_options_possibly_type_specific_seq
+ {
+ \keys_define:nn { zref-clever / langsetup }
+ {
+ #1 .value_required:n = true ,
+ #1 .code:n =
+ {
+ \tl_if_empty:NTF \l_@@_setup_type_tl
+ {
+ \@@_declare_default_transl:Vnn
+ \l_@@_dict_language_tl
+ {#1} {##1}
+ }
+ {
+ \@@_declare_type_transl:VVnn
+ \l_@@_dict_language_tl
+ \l_@@_setup_type_tl
+ {#1} {##1}
+ }
+ } ,
+ }
+ }
+\seq_map_inline:Nn
+ \c_@@_ref_options_type_names_seq
+ {
+ \keys_define:nn { zref-clever / langsetup }
+ {
+ #1 .value_required:n = true ,
+ #1 .code:n =
+ {
+ \tl_if_empty:NTF \l_@@_setup_type_tl
+ {
+ \msg_warning:nnn { zref-clever }
+ { option-only-type-specific } {#1}
+ }
+ {
+ \tl_if_empty:NTF \l_@@_dict_decl_case_tl
+ {
+ \@@_declare_type_transl:VVnn
+ \l_@@_dict_language_tl
+ \l_@@_setup_type_tl
+ {#1} {##1}
+ }
+ {
+ \@@_declare_type_transl:VVxn
+ \l_@@_dict_language_tl
+ \l_@@_setup_type_tl
+ { \l_@@_dict_decl_case_tl - #1 } {##1}
+ }
+ }
+ } ,
+ }
+ }
+% \end{macrocode}
+%
+%
+%
+% \section{User interface}
+%
+% \subsection{\cs{zcref}}
+%
+%
+% \begin{macro}[int]{\zcref}
+% The main user command of the package.
+% \begin{syntax}
+% \cs{zcref}\meta{*}\oarg{options}\marg{labels}
+% \end{syntax}
+% \begin{macrocode}
+\NewDocumentCommand \zcref { s O { } m }
+ { \zref@wrapper@babel \@@_zcref:nnn {#3} {#1} {#2} }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_zcref:nnnn}
+% 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@wrapper@babel} in \cs{zcref}.
+% \begin{syntax}
+% \cs{@@_zcref:nnnn} \Arg{labels} \Arg{*} \Arg{options}
+% \end{syntax}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_zcref:nnn #1#2#3
+ {
+ \group_begin:
+% \end{macrocode}
+% Set options.
+% \begin{macrocode}
+ \keys_set:nn { zref-clever / reference } {#3}
+% \end{macrocode}
+% Store arguments values.
+% \begin{macrocode}
+ \seq_set_from_clist:Nn \l_@@_zcref_labels_seq {#1}
+ \bool_set:Nn \l_@@_link_star_bool {#2}
+% \end{macrocode}
+% Ensure dictionary for reference language is loaded, if available. We cannot
+% rely on \cs{keys_set:nn} for the task, since if the \opt{lang} option is set
+% for \texttt{current}, the actual language may have changed outside our
+% control. \cs{@@_provide_dictionary:x} does nothing if the dictionary is
+% already loaded.
+% \begin{macrocode}
+ \@@_provide_dictionary:x { \l_@@_ref_language_tl }
+% \end{macrocode}
+% Process \cs{zcDeclareLanguage} options.
+% \begin{macrocode}
+ \@@_process_language_options:
+% \end{macrocode}
+% Integration with \pkg{zref-check}.
+% \begin{macrocode}
+ \bool_lazy_and:nnT
+ { \l_@@_zrefcheck_available_bool }
+ { \l_@@_zcref_with_check_bool }
+ { \zrefcheck_zcref_beg_label: }
+% \end{macrocode}
+% Sort the labels.
+% \begin{macrocode}
+ \bool_lazy_or:nnT
+ { \l_@@_typeset_sort_bool }
+ { \l_@@_typeset_range_bool }
+ { \@@_sort_labels: }
+% \end{macrocode}
+% Typeset the references. Also, set the reference font, and group it, so that
+% it does not leak to the note.
+% \begin{macrocode}
+ \group_begin:
+ \l_@@_ref_typeset_font_tl
+ \@@_typeset_refs:
+ \group_end:
+% \end{macrocode}
+% Typeset \texttt{note}.
+% \begin{macrocode}
+ \tl_if_empty:NF \l_@@_zcref_note_tl
+ {
+ \@@_get_ref_string:nN { notesep } \l_tmpa_tl
+ \l_tmpa_tl
+ \l_@@_zcref_note_tl
+ }
+% \end{macrocode}
+% Integration with \pkg{zref-check}.
+% \begin{macrocode}
+ \bool_lazy_and:nnT
+ { \l_@@_zrefcheck_available_bool }
+ { \l_@@_zcref_with_check_bool }
+ {
+ \zrefcheck_zcref_end_label_maybe:
+ \zrefcheck_zcref_run_checks_on_labels:n
+ { \l_@@_zcref_labels_seq }
+ }
+% \end{macrocode}
+% Integration with \pkg{mathtools}.
+% \begin{macrocode}
+ \bool_if:NT \l_@@_mathtools_showonlyrefs_bool
+ {
+ \@@_mathtools_showonlyrefs:n
+ { \l_@@_zcref_labels_seq }
+ }
+ \group_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l_@@_zcref_labels_seq, \l_@@_link_star_bool}
+% \begin{macrocode}
+\seq_new:N \l_@@_zcref_labels_seq
+\bool_new:N \l_@@_link_star_bool
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsection{\cs{zcpageref}}
+%
+%
+% \begin{macro}[int]{\zcpageref}
+% A \cs{pageref} equivalent of \cs{zcref}.
+% \begin{syntax}
+% \cs{zcpageref}\meta{*}\oarg{options}\marg{labels}
+% \end{syntax}
+% \begin{macrocode}
+\NewDocumentCommand \zcpageref { s O { } m }
+ {
+ \IfBooleanTF {#1}
+ { \zcref*[#2, ref = page] {#3} }
+ { \zcref [#2, ref = page] {#3} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \section{Sorting}
+%
+% Sorting is certainly a ``big task'' for \pkg{zref-clever} but, in the end,
+% it boils down to ``carefully done branching'', and quite some of it. The
+% sorting of ``page'' references is very much lightened by the availability of
+% \texttt{abspage}, from the \pkg{zref-abspage} module, which offers ``just
+% what we need'' for our purposes. The sorting of ``default'' references
+% falls on two main cases: i) labels of the same type; ii) labels of different
+% types. The first case is sorted according to the priorities set by the
+% \opt{typesort} option or, if that is silent for the case, by the order in
+% which labels were given by the user in \cs{zcref}. The second case is the
+% most involved one, since it is possible for multiple counters to be bundled
+% together in a single reference type. Because of this, sorting must take
+% into account the whole chain of ``enclosing counters'' for the counters of
+% the labels at hand.
+%
+% \begin{macro}
+% {
+% \l_@@_label_type_a_tl ,
+% \l_@@_label_type_b_tl ,
+% \l_@@_label_enclval_a_tl ,
+% \l_@@_label_enclval_b_tl ,
+% \l_@@_label_extdoc_a_tl ,
+% \l_@@_label_extdoc_b_tl ,
+% }
+% Auxiliary variables, for use in sorting, and some also in typesetting.
+% Used to store reference information -- label properties -- of the
+% ``current'' (\texttt{a}) and ``next'' (\texttt{b}) labels.
+% \begin{macrocode}
+\tl_new:N \l_@@_label_type_a_tl
+\tl_new:N \l_@@_label_type_b_tl
+\tl_new:N \l_@@_label_enclval_a_tl
+\tl_new:N \l_@@_label_enclval_b_tl
+\tl_new:N \l_@@_label_extdoc_a_tl
+\tl_new:N \l_@@_label_extdoc_b_tl
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l_@@_sort_decided_bool}
+% Auxiliary variable for \cs{@@_sort_default_same_type:nn}, signals if the
+% sorting between two labels has been decided or not.
+% \begin{macrocode}
+\bool_new:N \l_@@_sort_decided_bool
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l_@@_sort_prior_a_int,\l_@@_sort_prior_b_int}
+% Auxiliary variables for \cs{@@_sort_default_different_types:nn}. Store
+% the sort priority of the ``current'' and ``next'' labels.
+% \begin{macrocode}
+\int_new:N \l_@@_sort_prior_a_int
+\int_new:N \l_@@_sort_prior_b_int
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l_@@_label_types_seq}
+% Stores the order in which reference types appear in the label list
+% supplied by the user in \cs{zcref}. This variable is populated by
+% \cs{@@_label_type_put_new_right:n} at the start of \cs{@@_sort_labels:}.
+% This order is required as a ``last resort'' sort criterion between the
+% reference types, for use in \cs{@@_sort_default_different_types:nn}.
+% \begin{macrocode}
+\seq_new:N \l_@@_label_types_seq
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_sort_labels:}
+% The main sorting function. It does not receive arguments, but it is
+% expected to be run inside \cs{@@_zcref:nnnn} where a number of environment
+% variables are to be set appropriately. In particular,
+% \cs{l_@@_zcref_labels_seq} should contain the labels received as argument
+% to \cs{zcref}, and the function performs its task by sorting this
+% variable.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_sort_labels:
+ {
+% \end{macrocode}
+% Store label types sequence.
+% \begin{macrocode}
+ \seq_clear:N \l_@@_label_types_seq
+ \tl_if_eq:NnF \l_@@_ref_property_tl { page }
+ {
+ \seq_map_function:NN \l_@@_zcref_labels_seq
+ \@@_label_type_put_new_right:n
+ }
+% \end{macrocode}
+% Sort.
+% \begin{macrocode}
+ \seq_sort:Nn \l_@@_zcref_labels_seq
+ {
+ \zref@ifrefundefined {##1}
+ {
+ \zref@ifrefundefined {##2}
+ {
+ % Neither label is defined.
+ \sort_return_same:
+ }
+ {
+ % The second label is defined, but the first isn't, leave the
+ % undefined first (to be more visible).
+ \sort_return_same:
+ }
+ }
+ {
+ \zref@ifrefundefined {##2}
+ {
+ % The first label is defined, but the second isn't, bring the
+ % second forward.
+ \sort_return_swapped:
+ }
+ {
+ % The interesting case: both labels are defined. References
+ % to the "default" property or to the "page" are quite
+ % different with regard to sorting, so we branch them here to
+ % specialized functions.
+ \tl_if_eq:NnTF \l_@@_ref_property_tl { page }
+ { \@@_sort_page:nn {##1} {##2} }
+ { \@@_sort_default:nn {##1} {##2} }
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_label_type_put_new_right:n}
+% Auxiliary function used to store the order in which reference types appear
+% in the label list supplied by the user in \cs{zcref}. It is expected to
+% be run inside \cs{@@_sort_labels:}, and stores the types sequence in
+% \cs{l_@@_label_types_seq}. I have tried to handle the same task inside
+% \cs{seq_sort:Nn} in \cs{@@_sort_labels:} to spare mapping over
+% \cs{l_@@_zcref_labels_seq}, but it turned out it not to be easy to rely on
+% the order the labels get processed at that point, since the variable is
+% being sorted there. Besides, the mapping is simple, not a particularly
+% expensive operation. Anyway, this keeps things clean.
+% \begin{syntax}
+% \cs{@@_label_type_put_new_right:n} \Arg{label}
+% \end{syntax}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_label_type_put_new_right:n #1
+ {
+ \@@_def_extract:Nnnn
+ \l_@@_label_type_a_tl {#1} { zc@type } { \c_empty_tl }
+ \seq_if_in:NVF \l_@@_label_types_seq
+ \l_@@_label_type_a_tl
+ {
+ \seq_put_right:NV \l_@@_label_types_seq
+ \l_@@_label_type_a_tl
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_sort_default:nn}
+% The heavy-lifting function for sorting of defined labels for ``default''
+% references (that is, a standard reference, not to ``page''). This
+% function is expected to be called within the sorting loop of
+% \cs{@@_sort_labels:} and receives the pair of labels being considered for
+% a change of order or not. It should \emph{always} ``return'' either
+% \cs{sort_return_same:} or \cs{sort_return_swapped:}.
+% \begin{syntax}
+% \cs{@@_sort_default:nn} \Arg{label a} \Arg{label b}
+% \end{syntax}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_sort_default:nn #1#2
+ {
+ \@@_def_extract:Nnnn
+ \l_@@_label_type_a_tl {#1} { zc@type } { zc@missingtype }
+ \@@_def_extract:Nnnn
+ \l_@@_label_type_b_tl {#2} { zc@type } { zc@missingtype }
+
+ \tl_if_eq:NNTF
+ \l_@@_label_type_a_tl
+ \l_@@_label_type_b_tl
+ { \@@_sort_default_same_type:nn {#1} {#2} }
+ { \@@_sort_default_different_types:nn {#1} {#2} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_sort_default_same_type:nn}
+% \begin{syntax}
+% \cs{@@_sort_default_same_type:nn} \Arg{label a} \Arg{label b}
+% \end{syntax}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_sort_default_same_type:nn #1#2
+ {
+ \@@_def_extract:Nnnn \l_@@_label_enclval_a_tl
+ {#1} { zc@enclval } { \c_empty_tl }
+ \tl_reverse:N \l_@@_label_enclval_a_tl
+ \@@_def_extract:Nnnn \l_@@_label_enclval_b_tl
+ {#2} { zc@enclval } { \c_empty_tl }
+ \tl_reverse:N \l_@@_label_enclval_b_tl
+ \@@_def_extract:Nnnn \l_@@_label_extdoc_a_tl
+ {#1} { externaldocument } { \c_empty_tl }
+ \@@_def_extract:Nnnn \l_@@_label_extdoc_b_tl
+ {#2} { externaldocument } { \c_empty_tl }
+
+ \bool_set_false:N \l_@@_sort_decided_bool
+
+ % First we check if there's any "external document" difference (coming
+ % from 'zref-xr') and, if so, sort based on that.
+ \tl_if_eq:NNF
+ \l_@@_label_extdoc_a_tl
+ \l_@@_label_extdoc_b_tl
+ {
+ \bool_if:nTF
+ {
+ \tl_if_empty_p:V \l_@@_label_extdoc_a_tl &&
+ ! \tl_if_empty_p:V \l_@@_label_extdoc_b_tl
+ }
+ {
+ \bool_set_true:N \l_@@_sort_decided_bool
+ \sort_return_same:
+ }
+ {
+ \bool_if:nTF
+ {
+ ! \tl_if_empty_p:V \l_@@_label_extdoc_a_tl &&
+ \tl_if_empty_p:V \l_@@_label_extdoc_b_tl
+ }
+ {
+ \bool_set_true:N \l_@@_sort_decided_bool
+ \sort_return_swapped:
+ }
+ {
+ \bool_set_true:N \l_@@_sort_decided_bool
+ % Two different "external documents": last resort, sort by the
+ % document name itself.
+ \str_compare:eNeTF
+ { \l_@@_label_extdoc_b_tl } <
+ { \l_@@_label_extdoc_a_tl }
+ { \sort_return_swapped: }
+ { \sort_return_same: }
+ }
+ }
+ }
+
+ \bool_until_do:Nn \l_@@_sort_decided_bool
+ {
+ \bool_if:nTF
+ {
+ % Both are empty: neither label has any (further) "enclosing
+ % counters" (left).
+ \tl_if_empty_p:V \l_@@_label_enclval_a_tl &&
+ \tl_if_empty_p:V \l_@@_label_enclval_b_tl
+ }
+ {
+ \bool_set_true:N \l_@@_sort_decided_bool
+ \int_compare:nNnTF
+ { \@@_extract:nnn {#1} { zc@cntval } { -1 } }
+ >
+ { \@@_extract:nnn {#2} { zc@cntval } { -1 } }
+ { \sort_return_swapped: }
+ { \sort_return_same: }
+ }
+ {
+ \bool_if:nTF
+ {
+ % `a' is empty (and `b' is not): `b' may be nested in `a'.
+ \tl_if_empty_p:V \l_@@_label_enclval_a_tl
+ }
+ {
+ \bool_set_true:N \l_@@_sort_decided_bool
+ \int_compare:nNnTF
+ { \@@_extract:nnn {#1} { zc@cntval } { } }
+ >
+ { \tl_head:N \l_@@_label_enclval_b_tl }
+ { \sort_return_swapped: }
+ { \sort_return_same: }
+ }
+ {
+ \bool_if:nTF
+ {
+ % `b' is empty (and `a' is not): `a' may be nested in `b'.
+ \tl_if_empty_p:V \l_@@_label_enclval_b_tl
+ }
+ {
+ \bool_set_true:N \l_@@_sort_decided_bool
+ \int_compare:nNnTF
+ { \tl_head:N \l_@@_label_enclval_a_tl }
+ <
+ { \@@_extract:nnn {#2} { zc@cntval } { } }
+ { \sort_return_same: }
+ { \sort_return_swapped: }
+ }
+ {
+ % Neither is empty: we can compare the values of the
+ % current enclosing counter in the loop, if they are
+ % equal, we are still in the loop, if they are not, a
+ % sorting decision can be made directly.
+ \int_compare:nNnTF
+ { \tl_head:N \l_@@_label_enclval_a_tl }
+ =
+ { \tl_head:N \l_@@_label_enclval_b_tl }
+ {
+ \tl_set:Nx \l_@@_label_enclval_a_tl
+ { \tl_tail:N \l_@@_label_enclval_a_tl }
+ \tl_set:Nx \l_@@_label_enclval_b_tl
+ { \tl_tail:N \l_@@_label_enclval_b_tl }
+ }
+ {
+ \bool_set_true:N \l_@@_sort_decided_bool
+ \int_compare:nNnTF
+ { \tl_head:N \l_@@_label_enclval_a_tl }
+ >
+ { \tl_head:N \l_@@_label_enclval_b_tl }
+ { \sort_return_swapped: }
+ { \sort_return_same: }
+ }
+ }
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_sort_default_different_types:nn}
+% \begin{syntax}
+% \cs{@@_sort_default_different_types:nn} \Arg{label a} \Arg{label b}
+% \end{syntax}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_sort_default_different_types:nn #1#2
+ {
+% \end{macrocode}
+% Retrieve sort priorities for \meta{label a} and \meta{label b}.
+% \cs{l_@@_typesort_seq} was stored in reverse sequence, and we compute the
+% sort priorities in the negative range, so that we can implicitly rely on `0'
+% being the ``last value''.
+% \begin{macrocode}
+ \int_zero:N \l_@@_sort_prior_a_int
+ \int_zero:N \l_@@_sort_prior_b_int
+ \seq_map_indexed_inline:Nn \l_@@_typesort_seq
+ {
+ \tl_if_eq:nnTF {##2} {{othertypes}}
+ {
+ \int_compare:nNnT { \l_@@_sort_prior_a_int } = { 0 }
+ { \int_set:Nn \l_@@_sort_prior_a_int { - ##1 } }
+ \int_compare:nNnT { \l_@@_sort_prior_b_int } = { 0 }
+ { \int_set:Nn \l_@@_sort_prior_b_int { - ##1 } }
+ }
+ {
+ \tl_if_eq:NnTF \l_@@_label_type_a_tl {##2}
+ { \int_set:Nn \l_@@_sort_prior_a_int { - ##1 } }
+ {
+ \tl_if_eq:NnT \l_@@_label_type_b_tl {##2}
+ { \int_set:Nn \l_@@_sort_prior_b_int { - ##1 } }
+ }
+ }
+ }
+% \end{macrocode}
+% Then do the actual sorting.
+% \begin{macrocode}
+ \bool_if:nTF
+ {
+ \int_compare_p:nNn
+ { \l_@@_sort_prior_a_int } <
+ { \l_@@_sort_prior_b_int }
+ }
+ { \sort_return_same: }
+ {
+ \bool_if:nTF
+ {
+ \int_compare_p:nNn
+ { \l_@@_sort_prior_a_int } >
+ { \l_@@_sort_prior_b_int }
+ }
+ { \sort_return_swapped: }
+ {
+ % Sort priorities are equal: the type that occurs first in
+ % `labels', as given by the user, is kept (or brought) forward.
+ \seq_map_inline:Nn \l_@@_label_types_seq
+ {
+ \tl_if_eq:NnTF \l_@@_label_type_a_tl {##1}
+ { \seq_map_break:n { \sort_return_same: } }
+ {
+ \tl_if_eq:NnT \l_@@_label_type_b_tl {##1}
+ { \seq_map_break:n { \sort_return_swapped: } }
+ }
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_sort_page:nn}
+% The sorting function for sorting of defined labels for references to
+% ``page''. This function is expected to be called within the sorting loop
+% of \cs{@@_sort_labels:} and receives the pair of labels being considered
+% for a change of order or not. It should \emph{always} ``return'' either
+% \cs{sort_return_same:} or \cs{sort_return_swapped:}. Compared to the
+% sorting of default labels, this is a piece of cake (thanks to
+% \texttt{abspage}).
+% \begin{syntax}
+% \cs{@@_sort_page:nn} \Arg{label a} \Arg{label b}
+% \end{syntax}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_sort_page:nn #1#2
+ {
+ \int_compare:nNnTF
+ { \@@_extract:nnn {#1} { abspage } { -1 } }
+ >
+ { \@@_extract:nnn {#2} { abspage } { -1 } }
+ { \sort_return_swapped: }
+ { \sort_return_same: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \section{Typesetting}
+%
+% ``Typesetting'' the reference, which here includes the parsing of the labels
+% and eventual compression of labels in sequence into ranges, is definitely
+% the ``crux'' of \pkg{zref-clever}. This because we process the label set as
+% a stack, in a single pass, and hence ``parsing'', ``compressing'', and
+% ``typesetting'' must be decided upon at the same time, making it difficult
+% to slice the job into more specific and self-contained tasks. So, do bear
+% this in mind before you curse me for the length of some of the functions
+% below, or before a more orthodox ``docstripper'' complains about me not
+% sticking to code commenting conventions to keep the code more readable in
+% the \file{.dtx} file.
+%
+% While processing the label stack (kept in \cs{l_@@_typeset_labels_seq}),
+% \cs{@@_typeset_refs:} ``sees'' two labels, and two labels only, the
+% ``current'' one (kept in \cs{l_@@_label_a_tl}), and the ``next'' one (kept
+% in \cs{l_@@_label_b_tl}). However, the typesetting needs (a lot) more
+% information than just these two immediate labels to make a number of
+% critical decisions. Some examples: i) We cannot know if labels ``current''
+% and ``next'' of the same type are a ``pair'', or just ``elements in a
+% list'', until we examine the label after ``next''; ii) If the ``next'' label
+% is of the same type as the ``current'', and it is in immediate sequence to
+% it, it potentially forms a ``range'', but we cannot know if ``next'' is
+% actually the end of the range until we examined an arbitrary number of
+% labels, and found one which is not in sequence from the previous one; iii)
+% When processing a type block, the ``name'' comes first, however, we only
+% know if that name should be plural, or if it should be included in the
+% hyperlink, after processing an arbitrary number of labels and find one of a
+% different type. One could naively assume that just examining ``next'' would
+% be enough for this, since we can know if it is of the same type or not.
+% Alas, ``there be ranges'', and a compression operation may boil down to a
+% single element, so we have to process the whole type block to know how its
+% name should be typeset; iv) Similar issues apply to lists of type blocks,
+% each of which is of arbitrary length: we can only know if two type blocks
+% form a ``pair'' or are ``elements in a list'' when we finish the
+% block. Etc.\ etc.\ etc.
+%
+% We handle this by storing the reference ``pieces'' in ``queues'', instead of
+% typesetting them immediately upon processing. The ``queues'' get typeset at
+% the point where all the information needed is available, which usually
+% happens when a type block finishes (we see something of a different type in
+% ``next'', signaled by \cs{l_@@_last_of_type_bool}), or the stack itself
+% finishes (has no more elements, signaled by \cs{l_@@_typeset_last_bool}).
+% And, in processing a type block, the type ``name'' gets added last (on the
+% left) of the queue. The very first reference of its type always follows the
+% name, since it may form a hyperlink with it (so we keep it stored
+% separately, in \cs{l_@@_type_first_label_tl}, with
+% \cs{l_@@_type_first_label_type_tl} being its type). And, since we may need
+% up to two type blocks in storage before typesetting, we have two of these
+% ``queues'': \cs{l_@@_typeset_queue_curr_tl} and
+% \cs{l_@@_typeset_queue_prev_tl}.
+%
+% Some of the relevant cases (e.g., distinguishing ``pair'' from ``list'') are
+% handled by counters, the main ones are: one for the ``type''
+% (\cs{l_@@_type_count_int}) and one for the ``label in the current type
+% block'' (\cs{l_@@_label_count_int}).
+%
+% Range compression, in particular, relies heavily on counting to be able do
+% distinguish relevant cases. \cs{l_@@_range_count_int} counts the number of
+% elements in the current sequential ``streak'', and
+% \cs{l_@@_range_same_count_int} counts the number of \emph{equal} elements in
+% that same ``streak''. The difference between the two allows us to
+% distinguish the cases in which a range actually ``skips'' a number in the
+% sequence, in which case we should use a range separator, from when they are
+% after all just contiguous, in which case a pair separator is called for.
+% Since, as usual, we can only know this when a arbitrary long ``streak''
+% finishes, we have to store the label which (potentially) begins a range
+% (kept in \cs{l_@@_range_beg_label_tl}). \cs{l_@@_next_maybe_range_bool}
+% signals when ``next'' is potentially a range with ``current'', and
+% \cs{l_@@_next_is_same_bool} when their values are actually equal.
+%
+%
+% One further thing to discuss here -- to keep this ``on record'' -- is
+% inhibition of compression for individual labels. It is not difficult to
+% handle it at the infrastructure side, what gets sloppy is the user facing
+% syntax to signal such inhibition. For some possible alternatives for this
+% (and good ones at that) see \url{https://tex.stackexchange.com/q/611370}
+% (thanks Enrico Gregorio, Phelype Oleinik, and Steven B.\ Segletes). Yet
+% another alternative would be an option receiving the label(s) not to be
+% compressed, this would be a repetition, but would keep the syntax clean.
+% All in all, probably the best is simply not to allow individual inhibition
+% of compression. We can already control compression of each \cs{zcref} call
+% with existing options, this should be enough. I don't think the small extra
+% flexibility individual label control for this would grant is worth the
+% syntax disruption it would entail. Anyway, it would be easy to deal with
+% this in case the need arose, by just adding another condition (coming from
+% whatever the chosen syntax was) when we check for
+% \cs{@@_labels_in_sequence:nn} in \cs{@@_typeset_refs_not_last_of_type:}.
+% But I remain unconvinced of the pertinence of doing so.
+%
+%
+% \subsection*{Variables}
+%
+% \begin{macro}
+% {
+% \l_@@_typeset_labels_seq ,
+% \l_@@_typeset_last_bool ,
+% \l_@@_last_of_type_bool ,
+% }
+% Auxiliary variables for \cs{@@_typeset_refs:} main stack control.
+% \begin{macrocode}
+\seq_new:N \l_@@_typeset_labels_seq
+\bool_new:N \l_@@_typeset_last_bool
+\bool_new:N \l_@@_last_of_type_bool
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \l_@@_type_count_int ,
+% \l_@@_label_count_int ,
+% }
+% Auxiliary variables for \cs{@@_typeset_refs:} main counters.
+% \begin{macrocode}
+\int_new:N \l_@@_type_count_int
+\int_new:N \l_@@_label_count_int
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \l_@@_label_a_tl ,
+% \l_@@_label_b_tl ,
+% \l_@@_typeset_queue_prev_tl ,
+% \l_@@_typeset_queue_curr_tl ,
+% \l_@@_type_first_label_tl ,
+% \l_@@_type_first_label_type_tl
+% }
+% Auxiliary variables for \cs{@@_typeset_refs:} main ``queue'' control and
+% storage.
+% \begin{macrocode}
+\tl_new:N \l_@@_label_a_tl
+\tl_new:N \l_@@_label_b_tl
+\tl_new:N \l_@@_typeset_queue_prev_tl
+\tl_new:N \l_@@_typeset_queue_curr_tl
+\tl_new:N \l_@@_type_first_label_tl
+\tl_new:N \l_@@_type_first_label_type_tl
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \l_@@_type_name_tl ,
+% \l_@@_name_in_link_bool ,
+% \l_@@_name_format_tl ,
+% \l_@@_name_format_fallback_tl ,
+% \l_@@_type_name_gender_tl ,
+% }
+% Auxiliary variables for \cs{@@_typeset_refs:} type name handling.
+% \begin{macrocode}
+\tl_new:N \l_@@_type_name_tl
+\bool_new:N \l_@@_name_in_link_bool
+\tl_new:N \l_@@_name_format_tl
+\tl_new:N \l_@@_name_format_fallback_tl
+\tl_new:N \l_@@_type_name_gender_tl
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \l_@@_range_count_int ,
+% \l_@@_range_same_count_int ,
+% \l_@@_range_beg_label_tl ,
+% \l_@@_next_maybe_range_bool ,
+% \l_@@_next_is_same_bool ,
+% }
+% Auxiliary variables for \cs{@@_typeset_refs:} range handling.
+% \begin{macrocode}
+\int_new:N \l_@@_range_count_int
+\int_new:N \l_@@_range_same_count_int
+\tl_new:N \l_@@_range_beg_label_tl
+\bool_new:N \l_@@_next_maybe_range_bool
+\bool_new:N \l_@@_next_is_same_bool
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \l_@@_tpairsep_tl ,
+% \l_@@_tlistsep_tl ,
+% \l_@@_tlastsep_tl ,
+% \l_@@_namesep_tl ,
+% \l_@@_pairsep_tl ,
+% \l_@@_listsep_tl ,
+% \l_@@_lastsep_tl ,
+% \l_@@_rangesep_tl ,
+% \l_@@_refpre_tl ,
+% \l_@@_refpos_tl ,
+% \l_@@_namefont_tl ,
+% \l_@@_reffont_tl ,
+% }
+% Auxiliary variables for \cs{@@_typeset_refs:} separators, refpre/pos and
+% font options.
+% \begin{macrocode}
+\tl_new:N \l_@@_tpairsep_tl
+\tl_new:N \l_@@_tlistsep_tl
+\tl_new:N \l_@@_tlastsep_tl
+\tl_new:N \l_@@_namesep_tl
+\tl_new:N \l_@@_pairsep_tl
+\tl_new:N \l_@@_listsep_tl
+\tl_new:N \l_@@_lastsep_tl
+\tl_new:N \l_@@_rangesep_tl
+\tl_new:N \l_@@_refpre_tl
+\tl_new:N \l_@@_refpos_tl
+\tl_new:N \l_@@_namefont_tl
+\tl_new:N \l_@@_reffont_tl
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\l_@@_verbose_testing_bool}
+% Internal variable which enables extra log messaging at points of interest
+% in the code for purposes of regression testing. Particularly relevant to
+% keep track of expansion control in \cs{l_@@_typeset_queue_curr_tl}.
+% \begin{macrocode}
+\bool_new:N \l_@@_verbose_testing_bool
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection*{Main functions}
+%
+% \begin{macro}{\@@_typeset_refs:}
+% Main typesetting function for \cs{zcref}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_typeset_refs:
+ {
+ \seq_set_eq:NN \l_@@_typeset_labels_seq
+ \l_@@_zcref_labels_seq
+ \tl_clear:N \l_@@_typeset_queue_prev_tl
+ \tl_clear:N \l_@@_typeset_queue_curr_tl
+ \tl_clear:N \l_@@_type_first_label_tl
+ \tl_clear:N \l_@@_type_first_label_type_tl
+ \tl_clear:N \l_@@_range_beg_label_tl
+ \int_zero:N \l_@@_label_count_int
+ \int_zero:N \l_@@_type_count_int
+ \int_zero:N \l_@@_range_count_int
+ \int_zero:N \l_@@_range_same_count_int
+
+ % Get type block options (not type-specific).
+ \@@_get_ref_string:nN { tpairsep }
+ \l_@@_tpairsep_tl
+ \@@_get_ref_string:nN { tlistsep }
+ \l_@@_tlistsep_tl
+ \@@_get_ref_string:nN { tlastsep }
+ \l_@@_tlastsep_tl
+
+ % Process label stack.
+ \bool_set_false:N \l_@@_typeset_last_bool
+ \bool_until_do:Nn \l_@@_typeset_last_bool
+ {
+ \seq_pop_left:NN \l_@@_typeset_labels_seq
+ \l_@@_label_a_tl
+ \seq_if_empty:NTF \l_@@_typeset_labels_seq
+ {
+ \tl_clear:N \l_@@_label_b_tl
+ \bool_set_true:N \l_@@_typeset_last_bool
+ }
+ {
+ \seq_get_left:NN \l_@@_typeset_labels_seq
+ \l_@@_label_b_tl
+ }
+
+ \tl_if_eq:NnTF \l_@@_ref_property_tl { page }
+ {
+ \tl_set:Nn \l_@@_label_type_a_tl { page }
+ \tl_set:Nn \l_@@_label_type_b_tl { page }
+ }
+ {
+ \@@_def_extract:NVnn \l_@@_label_type_a_tl
+ \l_@@_label_a_tl { zc@type } { zc@missingtype }
+ \@@_def_extract:NVnn \l_@@_label_type_b_tl
+ \l_@@_label_b_tl { zc@type } { zc@missingtype }
+ }
+
+ % First, we establish whether the "current label" (i.e. `a') is the
+ % last one of its type. This can happen because the "next label"
+ % (i.e. `b') is of a different type (or different definition status),
+ % or because we are at the end of the list.
+ \bool_if:NTF \l_@@_typeset_last_bool
+ { \bool_set_true:N \l_@@_last_of_type_bool }
+ {
+ \zref@ifrefundefined { \l_@@_label_a_tl }
+ {
+ \zref@ifrefundefined { \l_@@_label_b_tl }
+ { \bool_set_false:N \l_@@_last_of_type_bool }
+ { \bool_set_true:N \l_@@_last_of_type_bool }
+ }
+ {
+ \zref@ifrefundefined { \l_@@_label_b_tl }
+ { \bool_set_true:N \l_@@_last_of_type_bool }
+ {
+ % Neither is undefined, we must check the types.
+ \tl_if_eq:NNTF
+ \l_@@_label_type_a_tl
+ \l_@@_label_type_b_tl
+ { \bool_set_false:N \l_@@_last_of_type_bool }
+ { \bool_set_true:N \l_@@_last_of_type_bool }
+ }
+ }
+ }
+
+ % Handle warnings in case of reference or type undefined.
+ % Test: 'zc-typeset01.lvt': "Typeset refs: warn ref undefined"
+ \zref@refused { \l_@@_label_a_tl }
+ % Test: 'zc-typeset01.lvt': "Typeset refs: warn missing type"
+ \zref@ifrefundefined { \l_@@_label_a_tl }
+ {}
+ {
+ \tl_if_eq:NnT \l_@@_label_type_a_tl { zc@missingtype }
+ {
+ \msg_warning:nnx { zref-clever } { missing-type }
+ { \l_@@_label_a_tl }
+ }
+ \zref@ifrefcontainsprop
+ { \l_@@_label_a_tl }
+ { \l_@@_ref_property_tl }
+ { }
+ {
+ \msg_warning:nnxx { zref-clever } { missing-property }
+ { \l_@@_ref_property_tl }
+ { \l_@@_label_a_tl }
+ }
+ }
+
+ % Get type-specific separators, refpre/pos and font options, once per
+ % type.
+ \int_compare:nNnT { \l_@@_label_count_int } = { 0 }
+ {
+ \@@_get_ref_string:nN { namesep }
+ \l_@@_namesep_tl
+ \@@_get_ref_string:nN { pairsep }
+ \l_@@_pairsep_tl
+ \@@_get_ref_string:nN { listsep }
+ \l_@@_listsep_tl
+ \@@_get_ref_string:nN { lastsep }
+ \l_@@_lastsep_tl
+ \@@_get_ref_string:nN { rangesep }
+ \l_@@_rangesep_tl
+ \@@_get_ref_string:nN { refpre }
+ \l_@@_refpre_tl
+ \@@_get_ref_string:nN { refpos }
+ \l_@@_refpos_tl
+ \@@_get_ref_font:nN { namefont }
+ \l_@@_namefont_tl
+ \@@_get_ref_font:nN { reffont }
+ \l_@@_reffont_tl
+ }
+
+ % Here we send this to a couple of auxiliary functions.
+ \bool_if:NTF \l_@@_last_of_type_bool
+ % There exists no next label of the same type as the current.
+ { \@@_typeset_refs_last_of_type: }
+ % There exists a next label of the same type as the current.
+ { \@@_typeset_refs_not_last_of_type: }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% This is actually the one meaningful ``big branching'' we can do while
+% processing the label stack: i) the ``current'' label is the last of its type
+% block; or ii) the ``current'' label is \emph{not} the last of its type
+% block. Indeed, as mentioned above, quite a number of things can only be
+% decided when the type block ends, and we only know this when we look at the
+% ``next'' label and find something of a different ``type'' (loose here, maybe
+% different definition status, maybe end of stack). So, though this is not
+% very strict, \cs{@@_typeset_refs_last_of_type:} is more of a ``wrapping
+% up'' function, and it is indeed the one which does the actual typesetting,
+% while \cs{@@_typeset_refs_not_last_of_type:} is more of an
+% ``accumulation'' function.
+%
+%
+% \begin{macro}{\@@_typeset_refs_last_of_type:}
+% Handles typesetting when the current label is the last of its type.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_typeset_refs_last_of_type:
+ {
+ % Process the current label to the current queue.
+ \int_case:nnF { \l_@@_label_count_int }
+ {
+ % It is the last label of its type, but also the first one, and that's
+ % what matters here: just store it.
+ % Test: 'zc-typeset01.lvt': "Last of type: single"
+ { 0 }
+ {
+ \tl_set:NV \l_@@_type_first_label_tl
+ \l_@@_label_a_tl
+ \tl_set:NV \l_@@_type_first_label_type_tl
+ \l_@@_label_type_a_tl
+ }
+
+ % The last is the second: we have a pair (if not repeated).
+ % Test: 'zc-typeset01.lvt': "Last of type: pair"
+ { 1 }
+ {
+ \int_compare:nNnF { \l_@@_range_same_count_int } = { 1 }
+ {
+ \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+ {
+ \exp_not:V \l_@@_pairsep_tl
+ \@@_get_ref:V \l_@@_label_a_tl
+ }
+ }
+ }
+ }
+ % Last is third or more of its type: without repetition, we'd have the
+ % last element on a list, but control for possible repetition.
+ {
+ \int_case:nnF { \l_@@_range_count_int }
+ {
+ % There was no range going on.
+ % Test: 'zc-typeset01.lvt': "Last of type: not range"
+ { 0 }
+ {
+ \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+ {
+ \exp_not:V \l_@@_lastsep_tl
+ \@@_get_ref:V \l_@@_label_a_tl
+ }
+ }
+ % Last in the range is also the second in it.
+ % Test: 'zc-typeset01.lvt': "Last of type: pair in sequence"
+ { 1 }
+ {
+ \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+ {
+ % We know `range_beg_label' is not empty, since this is the
+ % second element in the range, but the third or more in the
+ % type list.
+ \exp_not:V \l_@@_listsep_tl
+ \@@_get_ref:V \l_@@_range_beg_label_tl
+ \int_compare:nNnF
+ { \l_@@_range_same_count_int } = { 1 }
+ {
+ \exp_not:V \l_@@_lastsep_tl
+ \@@_get_ref:V \l_@@_label_a_tl
+ }
+ }
+ }
+ }
+ % Last in the range is third or more in it.
+ {
+ \int_case:nnF
+ {
+ \l_@@_range_count_int -
+ \l_@@_range_same_count_int
+ }
+ {
+ % Repetition, not a range.
+ % Test: 'zc-typeset01.lvt': "Last of type: range to one"
+ { 0 }
+ {
+ % If `range_beg_label' is empty, it means it was also the
+ % first of the type, and hence was already handled.
+ \tl_if_empty:VF \l_@@_range_beg_label_tl
+ {
+ \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+ {
+ \exp_not:V \l_@@_lastsep_tl
+ \@@_get_ref:V
+ \l_@@_range_beg_label_tl
+ }
+ }
+ }
+ % A `range', but with no skipped value, treat as list.
+ % Test: 'zc-typeset01.lvt': "Last of type: range to pair"
+ { 1 }
+ {
+ \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+ {
+ % Ditto.
+ \tl_if_empty:VF \l_@@_range_beg_label_tl
+ {
+ \exp_not:V \l_@@_listsep_tl
+ \@@_get_ref:V
+ \l_@@_range_beg_label_tl
+ }
+ \exp_not:V \l_@@_lastsep_tl
+ \@@_get_ref:V \l_@@_label_a_tl
+ }
+ }
+ }
+ {
+ % An actual range.
+ % Test: 'zc-typeset01.lvt': "Last of type: range"
+ \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+ {
+ % Ditto.
+ \tl_if_empty:VF \l_@@_range_beg_label_tl
+ {
+ \exp_not:V \l_@@_lastsep_tl
+ \@@_get_ref:V
+ \l_@@_range_beg_label_tl
+ }
+ \exp_not:V \l_@@_rangesep_tl
+ \@@_get_ref:V \l_@@_label_a_tl
+ }
+ }
+ }
+ }
+
+ % Handle "range" option. The idea is simple: if the queue is not empty,
+ % we replace it with the end of the range (or pair). We can still
+ % retrieve the end of the range from `label_a' since we know to be
+ % processing the last label of its type at this point.
+ \bool_if:NT \l_@@_typeset_range_bool
+ {
+ \tl_if_empty:NTF \l_@@_typeset_queue_curr_tl
+ {
+ \zref@ifrefundefined { \l_@@_type_first_label_tl }
+ { }
+ {
+ \msg_warning:nnx { zref-clever } { single-element-range }
+ { \l_@@_type_first_label_type_tl }
+ }
+ }
+ {
+ \bool_set_false:N \l_@@_next_maybe_range_bool
+ \zref@ifrefundefined { \l_@@_type_first_label_tl }
+ { }
+ {
+ \@@_labels_in_sequence:nn
+ { \l_@@_type_first_label_tl }
+ { \l_@@_label_a_tl }
+ }
+ % Test: 'zc-typeset01.lvt': "Last of type: option range"
+ % Test: 'zc-typeset01.lvt': "Last of type: option range to pair"
+ \tl_set:Nx \l_@@_typeset_queue_curr_tl
+ {
+ \bool_if:NTF \l_@@_next_maybe_range_bool
+ { \exp_not:V \l_@@_pairsep_tl }
+ { \exp_not:V \l_@@_rangesep_tl }
+ \@@_get_ref:V \l_@@_label_a_tl
+ }
+ }
+ }
+
+ % Now that the type block is finished, we can add the name and the first
+ % ref to the queue. Also, if "typeset" option is not "both", handle it
+ % here as well.
+ \@@_type_name_setup:
+ \bool_if:nTF
+ { \l_@@_typeset_ref_bool && \l_@@_typeset_name_bool }
+ {
+ \tl_put_left:Nx \l_@@_typeset_queue_curr_tl
+ { \@@_get_ref_first: }
+ }
+ {
+ \bool_if:NTF \l_@@_typeset_ref_bool
+ {
+ % Test: 'zc-typeset01.lvt': "Last of type: option typeset ref"
+ \tl_put_left:Nx \l_@@_typeset_queue_curr_tl
+ { \@@_get_ref:V \l_@@_type_first_label_tl }
+ }
+ {
+ \bool_if:NTF \l_@@_typeset_name_bool
+ {
+ % Test: 'zc-typeset01.lvt': "Last of type: option typeset name"
+ \tl_set:Nx \l_@@_typeset_queue_curr_tl
+ {
+ \bool_if:NTF \l_@@_name_in_link_bool
+ {
+ \exp_not:N \group_begin:
+ \exp_not:V \l_@@_namefont_tl
+ % It's two '@s', but escaped for DocStrip.
+ \exp_not:N \hyper@@@@link
+ {
+ \@@_extract_url_unexp:V
+ \l_@@_type_first_label_tl
+ }
+ {
+ \@@_extract_unexp:Vnn
+ \l_@@_type_first_label_tl
+ { anchor } { }
+ }
+ { \exp_not:V \l_@@_type_name_tl }
+ \exp_not:N \group_end:
+ }
+ {
+ \exp_not:N \group_begin:
+ \exp_not:V \l_@@_namefont_tl
+ \exp_not:V \l_@@_type_name_tl
+ \exp_not:N \group_end:
+ }
+ }
+ }
+ {
+ % Logically, this case would correspond to "typeset=none", but
+ % it should not occur, given that the options are set up to
+ % typeset either "ref" or "name". Still, leave here a
+ % sensible fallback, equal to the behavior of "both".
+ % Test: 'zc-typeset01.lvt': "Last of type: option typeset none"
+ \tl_put_left:Nx \l_@@_typeset_queue_curr_tl
+ { \@@_get_ref_first: }
+ }
+ }
+ }
+
+ % Typeset the previous type block, if there is one.
+ \int_compare:nNnT { \l_@@_type_count_int } > { 0 }
+ {
+ \int_compare:nNnT { \l_@@_type_count_int } > { 1 }
+ { \l_@@_tlistsep_tl }
+ \l_@@_typeset_queue_prev_tl
+ }
+
+ % Extra log for testing.
+ \bool_if:NT \l_@@_verbose_testing_bool
+ { \tl_show:N \l_@@_typeset_queue_curr_tl }
+
+ % Wrap up loop, or prepare for next iteration.
+ \bool_if:NTF \l_@@_typeset_last_bool
+ {
+ % We are finishing, typeset the current queue.
+ \int_case:nnF { \l_@@_type_count_int }
+ {
+ % Single type.
+ % Test: 'zc-typeset01.lvt': "Last of type: single type"
+ { 0 }
+ { \l_@@_typeset_queue_curr_tl }
+ % Pair of types.
+ % Test: 'zc-typeset01.lvt': "Last of type: pair of types"
+ { 1 }
+ {
+ \l_@@_tpairsep_tl
+ \l_@@_typeset_queue_curr_tl
+ }
+ }
+ {
+ % Last in list of types.
+ % Test: 'zc-typeset01.lvt': "Last of type: list of types"
+ \l_@@_tlastsep_tl
+ \l_@@_typeset_queue_curr_tl
+ }
+ % And nudge in case of multitype reference.
+ \bool_lazy_all:nT
+ {
+ { \l_@@_nudge_enabled_bool }
+ { \l_@@_nudge_multitype_bool }
+ { \int_compare_p:nNn { \l_@@_type_count_int } > { 0 } }
+ }
+ { \msg_warning:nn { zref-clever } { nudge-multitype } }
+ }
+ {
+ % There are further labels, set variables for next iteration.
+ \tl_set_eq:NN \l_@@_typeset_queue_prev_tl
+ \l_@@_typeset_queue_curr_tl
+ \tl_clear:N \l_@@_typeset_queue_curr_tl
+ \tl_clear:N \l_@@_type_first_label_tl
+ \tl_clear:N \l_@@_type_first_label_type_tl
+ \tl_clear:N \l_@@_range_beg_label_tl
+ \int_zero:N \l_@@_label_count_int
+ \int_incr:N \l_@@_type_count_int
+ \int_zero:N \l_@@_range_count_int
+ \int_zero:N \l_@@_range_same_count_int
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_typeset_refs_not_last_of_type:}
+% Handles typesetting when the current label is not the last of its type.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_typeset_refs_not_last_of_type:
+ {
+ % Signal if next label may form a range with the current one (only
+ % considered if compression is enabled in the first place).
+ \bool_set_false:N \l_@@_next_maybe_range_bool
+ \bool_set_false:N \l_@@_next_is_same_bool
+ \bool_if:NT \l_@@_typeset_compress_bool
+ {
+ \zref@ifrefundefined { \l_@@_label_a_tl }
+ { }
+ {
+ \@@_labels_in_sequence:nn
+ { \l_@@_label_a_tl } { \l_@@_label_b_tl }
+ }
+ }
+
+ % Process the current label to the current queue.
+ \int_compare:nNnTF { \l_@@_label_count_int } = { 0 }
+ {
+ % Current label is the first of its type (also not the last, but it
+ % doesn't matter here): just store the label.
+ \tl_set:NV \l_@@_type_first_label_tl
+ \l_@@_label_a_tl
+ \tl_set:NV \l_@@_type_first_label_type_tl
+ \l_@@_label_type_a_tl
+
+ % If the next label may be part of a range, we set `range_beg_label'
+ % to "empty" (we deal with it as the "first", and must do it there, to
+ % handle hyperlinking), but also step the range counters.
+ % Test: 'zc-typeset01.lvt': "Not last of type: first is range"
+ \bool_if:NT \l_@@_next_maybe_range_bool
+ {
+ \tl_clear:N \l_@@_range_beg_label_tl
+ \int_incr:N \l_@@_range_count_int
+ \bool_if:NT \l_@@_next_is_same_bool
+ { \int_incr:N \l_@@_range_same_count_int }
+ }
+ }
+ {
+ % Current label is neither the first (nor the last) of its type.
+ \bool_if:NTF \l_@@_next_maybe_range_bool
+ {
+ % Starting, or continuing a range.
+ \int_compare:nNnTF
+ { \l_@@_range_count_int } = { 0 }
+ {
+ % There was no range going, we are starting one.
+ \tl_set:NV \l_@@_range_beg_label_tl
+ \l_@@_label_a_tl
+ \int_incr:N \l_@@_range_count_int
+ \bool_if:NT \l_@@_next_is_same_bool
+ { \int_incr:N \l_@@_range_same_count_int }
+ }
+ {
+ % Second or more in the range, but not the last.
+ \int_incr:N \l_@@_range_count_int
+ \bool_if:NT \l_@@_next_is_same_bool
+ { \int_incr:N \l_@@_range_same_count_int }
+ }
+ }
+ {
+ % Next element is not in sequence: there was no range, or we are
+ % closing one.
+ \int_case:nnF { \l_@@_range_count_int }
+ {
+ % There was no range going on.
+ % Test: 'zc-typeset01.lvt': "Not last of type: no range"
+ { 0 }
+ {
+ \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+ {
+ \exp_not:V \l_@@_listsep_tl
+ \@@_get_ref:V \l_@@_label_a_tl
+ }
+ }
+ % Last is second in the range: if `range_same_count' is also
+ % `1', it's a repetition (drop it), otherwise, it's a "pair
+ % within a list", treat as list.
+ % Test: 'zc-typeset01.lvt': "Not last of type: range pair to one"
+ % Test: 'zc-typeset01.lvt': "Not last of type: range pair"
+ { 1 }
+ {
+ \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+ {
+ \tl_if_empty:VF \l_@@_range_beg_label_tl
+ {
+ \exp_not:V \l_@@_listsep_tl
+ \@@_get_ref:V
+ \l_@@_range_beg_label_tl
+ }
+ \int_compare:nNnF
+ { \l_@@_range_same_count_int } = { 1 }
+ {
+ \exp_not:V \l_@@_listsep_tl
+ \@@_get_ref:V
+ \l_@@_label_a_tl
+ }
+ }
+ }
+ }
+ {
+ % Last is third or more in the range: if `range_count' and
+ % `range_same_count' are the same, its a repetition (drop it),
+ % if they differ by `1', its a list, if they differ by more,
+ % it is a real range.
+ \int_case:nnF
+ {
+ \l_@@_range_count_int -
+ \l_@@_range_same_count_int
+ }
+ {
+ % Test: 'zc-typeset01.lvt': "Not last of type: range to one"
+ { 0 }
+ {
+ \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+ {
+ \tl_if_empty:VF \l_@@_range_beg_label_tl
+ {
+ \exp_not:V \l_@@_listsep_tl
+ \@@_get_ref:V
+ \l_@@_range_beg_label_tl
+ }
+ }
+ }
+ % Test: 'zc-typeset01.lvt': "Not last of type: range to pair"
+ { 1 }
+ {
+ \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+ {
+ \tl_if_empty:VF \l_@@_range_beg_label_tl
+ {
+ \exp_not:V \l_@@_listsep_tl
+ \@@_get_ref:V
+ \l_@@_range_beg_label_tl
+ }
+ \exp_not:V \l_@@_listsep_tl
+ \@@_get_ref:V \l_@@_label_a_tl
+ }
+ }
+ }
+ {
+ % Test: 'zc-typeset01.lvt': "Not last of type: range"
+ \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+ {
+ \tl_if_empty:VF \l_@@_range_beg_label_tl
+ {
+ \exp_not:V \l_@@_listsep_tl
+ \@@_get_ref:V
+ \l_@@_range_beg_label_tl
+ }
+ \exp_not:V \l_@@_rangesep_tl
+ \@@_get_ref:V \l_@@_label_a_tl
+ }
+ }
+ }
+ % Reset counters.
+ \int_zero:N \l_@@_range_count_int
+ \int_zero:N \l_@@_range_same_count_int
+ }
+ }
+ % Step label counter for next iteration.
+ \int_incr:N \l_@@_label_count_int
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsection*{Auxiliary functions}
+%
+% \cs{@@_get_ref:n} and \cs{@@_get_ref_first:} are the two functions which
+% actually build the reference blocks for typesetting. \cs{@@_get_ref:n}
+% handles all references but the first of its type, and \cs{@@_get_ref_first:}
+% deals with the first reference of a type. Saying they do ``typesetting'' is
+% imprecise though, they actually prepare material to be accumulated in
+% \cs{l_@@_typeset_queue_curr_tl} inside \cs{@@_typeset_refs_last_of_type:}
+% and \cs{@@_typeset_refs_not_last_of_type:}. And this difference results
+% quite crucial for the \TeX{}nical requirements of these functions. This
+% because, as we are processing the label stack and accumulating content in
+% the queue, we are using a number of variables which are transient to the
+% current label, the label properties among them, but not only. Hence, these
+% variables \emph{must} be expanded to their current values to be stored in
+% the queue. Indeed, \cs{@@_get_ref:n} and \cs{@@_get_ref_first:} get called,
+% as they must, in the context of \texttt{x} type expansions. But we don't
+% want to expand the values of the variables themselves, so we need to get
+% current values, but stop expansion after that. In particular, reference
+% options given by the user should reach the stream for its final typesetting
+% (when the queue itself gets typeset) \emph{unmodified} (``no manipulation'',
+% to use the \texttt{n} signature jargon). We also need to prevent premature
+% expansion of material that can't be expanded at this point (e.g. grouping,
+% \cs{zref@default} or \cs[replace=false]{hyper@@link}). In a nutshell, the
+% job of these two functions is putting the pieces in place, but with proper
+% expansion control.
+%
+%
+% \begin{macro}{\@@_ref_default:, \@@_name_default:}
+% Default values for undefined references and undefined type names,
+% respectively. We are ultimately using \cs{zref@default}, but calls to it
+% should be made through these internal functions, according to the case.
+% As a bonus, we don't need to protect them with \cs{exp_not:N}, as
+% \cs{zref@default} would require, since we already define them protected.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_ref_default:
+ { \zref@default }
+\cs_new_protected:Npn \@@_name_default:
+ { \zref@default }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_get_ref:n}
+% Handles a complete reference block to be accumulated in the ``queue'',
+% including ``pre'' and ``pos'' elements, and hyperlinking. For use with
+% all labels, except the first of its type, which is done by
+% \cs{@@_get_ref_first:}.
+% \begin{syntax}
+% \cs{@@_get_ref:n} \Arg{label}
+% \end{syntax}
+% \begin{macrocode}
+\cs_new:Npn \@@_get_ref:n #1
+ {
+ \zref@ifrefcontainsprop {#1} { \l_@@_ref_property_tl }
+ {
+ \bool_if:nTF
+ {
+ \l_@@_use_hyperref_bool &&
+ ! \l_@@_link_star_bool
+ }
+ {
+ \bool_if:NF \l_@@_preposinlink_bool
+ { \exp_not:V \l_@@_refpre_tl }
+ % It's two `@s', but escaped for DocStrip.
+ \exp_not:N \hyper@@@@link
+ { \@@_extract_url_unexp:n {#1} }
+ { \@@_extract_unexp:nnn {#1} { anchor } { } }
+ {
+ \bool_if:NT \l_@@_preposinlink_bool
+ { \exp_not:V \l_@@_refpre_tl }
+ \exp_not:N \group_begin:
+ \exp_not:V \l_@@_reffont_tl
+ \@@_extract_unexp:nvn {#1}
+ { l_@@_ref_property_tl } { }
+ \exp_not:N \group_end:
+ \bool_if:NT \l_@@_preposinlink_bool
+ { \exp_not:V \l_@@_refpos_tl }
+ }
+ \bool_if:NF \l_@@_preposinlink_bool
+ { \exp_not:V \l_@@_refpos_tl }
+ }
+ {
+ \exp_not:V \l_@@_refpre_tl
+ \exp_not:N \group_begin:
+ \exp_not:V \l_@@_reffont_tl
+ \@@_extract_unexp:nvn {#1}
+ { l_@@_ref_property_tl } { }
+ \exp_not:N \group_end:
+ \exp_not:V \l_@@_refpos_tl
+ }
+ }
+ { \@@_ref_default: }
+ }
+\cs_generate_variant:Nn \@@_get_ref:n { V }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_get_ref_first:}
+% Handles a complete reference block for the first label of its type to be
+% accumulated in the ``queue'', including ``pre'' and ``pos'' elements,
+% hyperlinking, and the reference type ``name''. It does not receive
+% arguments, but relies on being called in the appropriate place in
+% \cs{@@_typeset_refs_last_of_type:} where a number of variables are
+% expected to be appropriately set for it to consume. Prominently among
+% those is \cs{l_@@_type_first_label_tl}, but it also expected to be called
+% right after \cs{@@_type_name_setup:} which sets \cs{l_@@_type_name_tl} and
+% \cs{l_@@_name_in_link_bool} which it uses.
+% \begin{macrocode}
+\cs_new:Npn \@@_get_ref_first:
+ {
+ \zref@ifrefundefined { \l_@@_type_first_label_tl }
+ { \@@_ref_default: }
+ {
+ \bool_if:NTF \l_@@_name_in_link_bool
+ {
+ \zref@ifrefcontainsprop
+ { \l_@@_type_first_label_tl }
+ { \l_@@_ref_property_tl }
+ {
+ % It's two `@s', but escaped for DocStrip.
+ \exp_not:N \hyper@@@@link
+ {
+ \@@_extract_url_unexp:V
+ \l_@@_type_first_label_tl
+ }
+ {
+ \@@_extract_unexp:Vnn
+ \l_@@_type_first_label_tl { anchor } { }
+ }
+ {
+ \exp_not:N \group_begin:
+ \exp_not:V \l_@@_namefont_tl
+ \exp_not:V \l_@@_type_name_tl
+ \exp_not:N \group_end:
+ \exp_not:V \l_@@_namesep_tl
+ \exp_not:V \l_@@_refpre_tl
+ \exp_not:N \group_begin:
+ \exp_not:V \l_@@_reffont_tl
+ \@@_extract_unexp:Vvn
+ \l_@@_type_first_label_tl
+ { l_@@_ref_property_tl } { }
+ \exp_not:N \group_end:
+ \bool_if:NT \l_@@_preposinlink_bool
+ { \exp_not:V \l_@@_refpos_tl }
+ }
+ \bool_if:NF \l_@@_preposinlink_bool
+ { \exp_not:V \l_@@_refpos_tl }
+ }
+ {
+ \exp_not:N \group_begin:
+ \exp_not:V \l_@@_namefont_tl
+ \exp_not:V \l_@@_type_name_tl
+ \exp_not:N \group_end:
+ \exp_not:V \l_@@_namesep_tl
+ \@@_ref_default:
+ }
+ }
+ {
+ \tl_if_empty:NTF \l_@@_type_name_tl
+ {
+ \@@_name_default:
+ \exp_not:V \l_@@_namesep_tl
+ }
+ {
+ \exp_not:N \group_begin:
+ \exp_not:V \l_@@_namefont_tl
+ \exp_not:V \l_@@_type_name_tl
+ \exp_not:N \group_end:
+ \exp_not:V \l_@@_namesep_tl
+ }
+ \zref@ifrefcontainsprop
+ { \l_@@_type_first_label_tl }
+ { \l_@@_ref_property_tl }
+ {
+ \bool_if:nTF
+ {
+ \l_@@_use_hyperref_bool &&
+ ! \l_@@_link_star_bool
+ }
+ {
+ \bool_if:NF \l_@@_preposinlink_bool
+ { \exp_not:V \l_@@_refpre_tl }
+ % It's two '@s', but escaped for DocStrip.
+ \exp_not:N \hyper@@@@link
+ {
+ \@@_extract_url_unexp:V
+ \l_@@_type_first_label_tl
+ }
+ {
+ \@@_extract_unexp:Vnn
+ \l_@@_type_first_label_tl { anchor } { }
+ }
+ {
+ \bool_if:NT \l_@@_preposinlink_bool
+ { \exp_not:V \l_@@_refpre_tl }
+ \exp_not:N \group_begin:
+ \exp_not:V \l_@@_reffont_tl
+ \@@_extract_unexp:Vvn
+ \l_@@_type_first_label_tl
+ { l_@@_ref_property_tl } { }
+ \exp_not:N \group_end:
+ \bool_if:NT \l_@@_preposinlink_bool
+ { \exp_not:V \l_@@_refpos_tl }
+ }
+ \bool_if:NF \l_@@_preposinlink_bool
+ { \exp_not:V \l_@@_refpos_tl }
+ }
+ {
+ \exp_not:V \l_@@_refpre_tl
+ \exp_not:N \group_begin:
+ \exp_not:V \l_@@_reffont_tl
+ \@@_extract_unexp:Vvn
+ \l_@@_type_first_label_tl
+ { l_@@_ref_property_tl } { }
+ \exp_not:N \group_end:
+ \exp_not:V \l_@@_refpos_tl
+ }
+ }
+ { \@@_ref_default: }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_type_name_setup:}
+% Auxiliary function to \cs{@@_typeset_refs_last_of_type:}. It is
+% responsible for setting the type name variable \cs{l_@@_type_name_tl} and
+% \cs{l_@@_name_in_link_bool}. If a type name can't be found,
+% \cs{l_@@_type_name_tl} is cleared. The function takes no arguments, but
+% is expected to be called in \cs{@@_typeset_refs_last_of_type:} right
+% before \cs{@@_get_ref_first:}, which is the main consumer of the variables
+% it sets, though not the only one (and hence this cannot be moved into
+% \cs{@@_get_ref_first:} itself). It also expects a number of relevant
+% variables to have been appropriately set, and which it uses, prominently
+% \cs{l_@@_type_first_label_type_tl}, but also the queue itself in
+% \cs{l_@@_typeset_queue_curr_tl}, which should be ``ready except for the
+% first label'', and the type counter \cs{l_@@_type_count_int}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_type_name_setup:
+ {
+ \zref@ifrefundefined { \l_@@_type_first_label_tl }
+ { \tl_clear:N \l_@@_type_name_tl }
+ {
+ \tl_if_eq:NnTF
+ \l_@@_type_first_label_type_tl { zc@missingtype }
+ { \tl_clear:N \l_@@_type_name_tl }
+ {
+ % Determine whether we should use capitalization, abbreviation,
+ % and plural.
+ \bool_lazy_or:nnTF
+ { \l_@@_capitalize_bool }
+ {
+ \l_@@_capitalize_first_bool &&
+ \int_compare_p:nNn { \l_@@_type_count_int } = { 0 }
+ }
+ { \tl_set:Nn \l_@@_name_format_tl {Name} }
+ { \tl_set:Nn \l_@@_name_format_tl {name} }
+ % If the queue is empty, we have a singular, otherwise, plural.
+ \tl_if_empty:NTF \l_@@_typeset_queue_curr_tl
+ { \tl_put_right:Nn \l_@@_name_format_tl { -sg } }
+ { \tl_put_right:Nn \l_@@_name_format_tl { -pl } }
+ \bool_lazy_and:nnTF
+ { \l_@@_abbrev_bool }
+ {
+ ! \int_compare_p:nNn
+ { \l_@@_type_count_int } = { 0 } ||
+ ! \l_@@_noabbrev_first_bool
+ }
+ {
+ \tl_set:NV \l_@@_name_format_fallback_tl
+ \l_@@_name_format_tl
+ \tl_put_right:Nn \l_@@_name_format_tl { -ab }
+ }
+ { \tl_clear:N \l_@@_name_format_fallback_tl }
+
+ % Handle number and gender nudges.
+ \bool_if:NT \l_@@_nudge_enabled_bool
+ {
+ \bool_if:NTF \l_@@_nudge_singular_bool
+ {
+ \tl_if_empty:NF \l_@@_typeset_queue_curr_tl
+ {
+ \msg_warning:nnx { zref-clever }
+ { nudge-plural-when-sg }
+ { \l_@@_type_first_label_type_tl }
+ }
+ }
+ {
+ \bool_lazy_all:nT
+ {
+ { \l_@@_nudge_comptosing_bool }
+ { \tl_if_empty_p:N \l_@@_typeset_queue_curr_tl }
+ {
+ \int_compare_p:nNn
+ { \l_@@_label_count_int } > { 0 }
+ }
+ }
+ {
+ \msg_warning:nnx { zref-clever }
+ { nudge-comptosing }
+ { \l_@@_type_first_label_type_tl }
+ }
+ }
+ \bool_lazy_and:nnT
+ { \l_@@_nudge_gender_bool }
+ { ! \tl_if_empty_p:N \l_@@_ref_gender_tl }
+ {
+ \@@_get_type_transl:xxnNF
+ { \l_@@_ref_language_tl }
+ { \l_@@_type_first_label_type_tl }
+ { gender }
+ \l_@@_type_name_gender_tl
+ { \tl_clear:N \l_@@_type_name_gender_tl }
+ \tl_if_eq:NNF
+ \l_@@_ref_gender_tl
+ \l_@@_type_name_gender_tl
+ {
+ \tl_if_empty:NTF \l_@@_type_name_gender_tl
+ {
+ \msg_warning:nnxxx { zref-clever }
+ { nudge-gender-not-declared-for-type }
+ { \l_@@_ref_gender_tl }
+ { \l_@@_type_first_label_type_tl }
+ { \l_@@_ref_language_tl }
+ }
+ {
+ \msg_warning:nnxxxx { zref-clever }
+ { nudge-gender-mismatch }
+ { \l_@@_type_first_label_type_tl }
+ { \l_@@_ref_gender_tl }
+ { \l_@@_type_name_gender_tl }
+ { \l_@@_ref_language_tl }
+ }
+ }
+ }
+ }
+
+ \tl_if_empty:NTF \l_@@_name_format_fallback_tl
+ {
+ \prop_get:cVNF
+ {
+ l_@@_type_
+ \l_@@_type_first_label_type_tl _options_prop
+ }
+ \l_@@_name_format_tl
+ \l_@@_type_name_tl
+ {
+ \tl_if_empty:NF \l_@@_ref_decl_case_tl
+ {
+ \tl_put_left:Nn \l_@@_name_format_tl { - }
+ \tl_put_left:NV \l_@@_name_format_tl
+ \l_@@_ref_decl_case_tl
+ }
+ \@@_get_type_transl:xxxNF
+ { \l_@@_ref_language_tl }
+ { \l_@@_type_first_label_type_tl }
+ { \l_@@_name_format_tl }
+ \l_@@_type_name_tl
+ {
+ \tl_clear:N \l_@@_type_name_tl
+ \msg_warning:nnxx { zref-clever } { missing-name }
+ { \l_@@_name_format_tl }
+ { \l_@@_type_first_label_type_tl }
+ }
+ }
+ }
+ {
+ \prop_get:cVNF
+ {
+ l_@@_type_
+ \l_@@_type_first_label_type_tl _options_prop
+ }
+ \l_@@_name_format_tl
+ \l_@@_type_name_tl
+ {
+ \prop_get:cVNF
+ {
+ l_@@_type_
+ \l_@@_type_first_label_type_tl _options_prop
+ }
+ \l_@@_name_format_fallback_tl
+ \l_@@_type_name_tl
+ {
+ \tl_if_empty:NF \l_@@_ref_decl_case_tl
+ {
+ \tl_put_left:Nn
+ \l_@@_name_format_tl { - }
+ \tl_put_left:NV \l_@@_name_format_tl
+ \l_@@_ref_decl_case_tl
+ \tl_put_left:Nn
+ \l_@@_name_format_fallback_tl { - }
+ \tl_put_left:NV
+ \l_@@_name_format_fallback_tl
+ \l_@@_ref_decl_case_tl
+ }
+ \@@_get_type_transl:xxxNF
+ { \l_@@_ref_language_tl }
+ { \l_@@_type_first_label_type_tl }
+ { \l_@@_name_format_tl }
+ \l_@@_type_name_tl
+ {
+ \@@_get_type_transl:xxxNF
+ { \l_@@_ref_language_tl }
+ { \l_@@_type_first_label_type_tl }
+ { \l_@@_name_format_fallback_tl }
+ \l_@@_type_name_tl
+ {
+ \tl_clear:N \l_@@_type_name_tl
+ \msg_warning:nnxx { zref-clever }
+ { missing-name }
+ { \l_@@_name_format_tl }
+ { \l_@@_type_first_label_type_tl }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ % Signal whether the type name is to be included in the hyperlink or not.
+ \bool_lazy_any:nTF
+ {
+ { ! \l_@@_use_hyperref_bool }
+ { \l_@@_link_star_bool }
+ { \tl_if_empty_p:N \l_@@_type_name_tl }
+ { \str_if_eq_p:Vn \l_@@_nameinlink_str { false } }
+ }
+ { \bool_set_false:N \l_@@_name_in_link_bool }
+ {
+ \bool_lazy_any:nTF
+ {
+ { \str_if_eq_p:Vn \l_@@_nameinlink_str { true } }
+ {
+ \str_if_eq_p:Vn \l_@@_nameinlink_str { tsingle } &&
+ \tl_if_empty_p:N \l_@@_typeset_queue_curr_tl
+ }
+ {
+ \str_if_eq_p:Vn \l_@@_nameinlink_str { single } &&
+ \tl_if_empty_p:N \l_@@_typeset_queue_curr_tl &&
+ \l_@@_typeset_last_bool &&
+ \int_compare_p:nNn { \l_@@_type_count_int } = { 0 }
+ }
+ }
+ { \bool_set_true:N \l_@@_name_in_link_bool }
+ { \bool_set_false:N \l_@@_name_in_link_bool }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_extract_url_unexp:n}
+% A convenience auxiliary function for extraction of the \texttt{url} /
+% \texttt{urluse} property, provided by the \pkg{zref-xr} module. Ensure
+% that, in the context of an x expansion, \cs{zref@extractdefault} is
+% expanded exactly twice, but no further to retrieve the proper value. See
+% documentation for \cs{@@_extract_unexp:nnn}.
+% \begin{macrocode}
+\cs_new:Npn \@@_extract_url_unexp:n #1
+ {
+ \zref@ifpropundefined { urluse }
+ { \@@_extract_unexp:nnn {#1} { url } { \c_empty_tl } }
+ {
+ \zref@ifrefcontainsprop {#1} { urluse }
+ { \@@_extract_unexp:nnn {#1} { urluse } { \c_empty_tl } }
+ { \@@_extract_unexp:nnn {#1} { url } { \c_empty_tl } }
+ }
+ }
+\cs_generate_variant:Nn \@@_extract_url_unexp:n { V }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_labels_in_sequence:nn}
+% Auxiliary function to \cs{@@_typeset_refs_not_last_of_type:}. Sets
+% \cs{l_@@_next_maybe_range_bool} to true if \meta{label b} comes in
+% immediate sequence from \meta{label a}. And sets both
+% \cs{l_@@_next_maybe_range_bool} and \cs{l_@@_next_is_same_bool} to true if
+% the two labels are the ``same'' (that is, have the same counter value).
+% These two boolean variables are the basis for all range and compression
+% handling inside \cs{@@_typeset_refs_not_last_of_type:}, so this function
+% is expected to be called at its beginning, if compression is enabled.
+% \begin{syntax}
+% \cs{@@_labels_in_sequence:nn} \Arg{label a} \Arg{label b}
+% \end{syntax}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_labels_in_sequence:nn #1#2
+ {
+ \@@_def_extract:Nnnn \l_@@_label_extdoc_a_tl
+ {#1} { externaldocument } { \c_empty_tl }
+ \@@_def_extract:Nnnn \l_@@_label_extdoc_b_tl
+ {#2} { externaldocument } { \c_empty_tl }
+
+ \tl_if_eq:NNT
+ \l_@@_label_extdoc_a_tl
+ \l_@@_label_extdoc_b_tl
+ {
+ \tl_if_eq:NnTF \l_@@_ref_property_tl { page }
+ {
+ \exp_args:Nxx \tl_if_eq:nnT
+ { \@@_extract_unexp:nnn {#1} { zc@pgfmt } { } }
+ { \@@_extract_unexp:nnn {#2} { zc@pgfmt } { } }
+ {
+ \int_compare:nNnTF
+ { \@@_extract:nnn {#1} { zc@pgval } { -2 } + 1 }
+ =
+ { \@@_extract:nnn {#2} { zc@pgval } { -1 } }
+ { \bool_set_true:N \l_@@_next_maybe_range_bool }
+ {
+ \int_compare:nNnT
+ { \@@_extract:nnn {#1} { zc@pgval } { -1 } }
+ =
+ { \@@_extract:nnn {#2} { zc@pgval } { -1 } }
+ {
+ \bool_set_true:N \l_@@_next_maybe_range_bool
+ \bool_set_true:N \l_@@_next_is_same_bool
+ }
+ }
+ }
+ }
+ {
+ \exp_args:Nxx \tl_if_eq:nnT
+ { \@@_extract_unexp:nnn {#1} { zc@counter } { } }
+ { \@@_extract_unexp:nnn {#2} { zc@counter } { } }
+ {
+ \exp_args:Nxx \tl_if_eq:nnT
+ { \@@_extract_unexp:nnn {#1} { zc@enclval } { } }
+ { \@@_extract_unexp:nnn {#2} { zc@enclval } { } }
+ {
+ \int_compare:nNnTF
+ { \@@_extract:nnn {#1} { zc@cntval } { -2 } + 1 }
+ =
+ { \@@_extract:nnn {#2} { zc@cntval } { -1 } }
+ { \bool_set_true:N \l_@@_next_maybe_range_bool }
+ {
+ \int_compare:nNnT
+ { \@@_extract:nnn {#1} { zc@cntval } { -1 } }
+ =
+ { \@@_extract:nnn {#2} { zc@cntval } { -1 } }
+ {
+ \bool_set_true:N
+ \l_@@_next_maybe_range_bool
+ \exp_args:Nxx \tl_if_eq:nnT
+ {
+ \@@_extract_unexp:nvn {#1}
+ { l_@@_ref_property_tl } { }
+ }
+ {
+ \@@_extract_unexp:nvn {#2}
+ { l_@@_ref_property_tl } { }
+ }
+ {
+ \bool_set_true:N
+ \l_@@_next_is_same_bool
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% Finally, a couple of functions for retrieving options values, according to
+% the relevant precedence rules. They both receive an \meta{option} as
+% argument, and store the retrieved value in \meta{tl variable}. Though these
+% are mostly general functions (for a change\dots{}), they are not completely
+% so, they rely on the current state of \cs{l_@@_label_type_a_tl}, as set
+% during the processing of the label stack. This could be easily generalized,
+% of course, but I don't think it is worth it, \cs{l_@@_label_type_a_tl} is
+% indeed what we want in all practical cases. The difference between
+% \cs{@@_get_ref_string:nN} and \cs{@@_get_ref_font:nN} is the kind of option
+% each should be used for. \cs{@@_get_ref_string:nN} is meant for the general
+% options, and attempts to find values for them in all precedence levels (four
+% plus ``fallback''). \cs{@@_get_ref_font:nN} is intended for ``font''
+% options, which cannot be ``language-specific'', thus for these we just
+% search general options and type options.
+%
+% \begin{macro}{\@@_get_ref_string:nN}
+% \begin{syntax}
+% \cs{@@_get_ref_string:nN} \Arg{option} \Arg{tl variable}
+% \end{syntax}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_get_ref_string:nN #1#2
+ {
+ % First attempt: general options.
+ \prop_get:NnNF \l_@@_ref_options_prop {#1} #2
+ {
+ % If not found, try type specific options.
+ \bool_lazy_and:nnTF
+ {
+ \prop_if_exist_p:c
+ {
+ l_@@_type_
+ \l_@@_label_type_a_tl _options_prop
+ }
+ }
+ {
+ \prop_if_in_p:cn
+ {
+ l_@@_type_
+ \l_@@_label_type_a_tl _options_prop
+ }
+ {#1}
+ }
+ {
+ \prop_get:cnN
+ {
+ l_@@_type_
+ \l_@@_label_type_a_tl _options_prop
+ }
+ {#1} #2
+ }
+ {
+ % If not found, try type specific translations.
+ \@@_get_type_transl:xxnNF
+ { \l_@@_ref_language_tl }
+ { \l_@@_label_type_a_tl }
+ {#1} #2
+ {
+ % If not found, try default translations.
+ \@@_get_default_transl:xnNF
+ { \l_@@_ref_language_tl }
+ {#1} #2
+ {
+ % If not found, try fallback.
+ \@@_get_fallback_transl:nNF {#1} #2
+ {
+ \tl_clear:N #2
+ \msg_warning:nnn { zref-clever }
+ { missing-string } {#1}
+ }
+ }
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_get_ref_font:nN}
+% \begin{syntax}
+% \cs{@@_get_ref_font:nN} \Arg{option} \Arg{tl variable}
+% \end{syntax}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_get_ref_font:nN #1#2
+ {
+ % First attempt: general options.
+ \prop_get:NnNF \l_@@_ref_options_prop {#1} #2
+ {
+ % If not found, try type specific options.
+ \bool_if:nTF
+ {
+ \prop_if_exist_p:c
+ {
+ l_@@_type_
+ \l_@@_label_type_a_tl _options_prop
+ }
+ }
+ {
+ \prop_get:cnNF
+ {
+ l_@@_type_
+ \l_@@_label_type_a_tl _options_prop
+ }
+ {#1} #2
+ { \tl_clear:N #2 }
+ }
+ { \tl_clear:N #2 }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \section{Compatibility}
+%
+% This section is meant to aggregate any ``special handling'' needed for
+% \LaTeX{} kernel features, document classes, and packages, needed for
+% \pkg{zref-clever} to work properly with them.
+%
+%
+% \subsection{\opt{appendix}}
+%
+% One relevant case of different reference types sharing the same counter is
+% the \cs{appendix} which in some document classes, including the standard
+% ones, change the sectioning commands looks but, of course, keep using the
+% same counter. \file{book.cls} and \file{report.cls} reset counters
+% \texttt{chapter} and \texttt{section} to 0, change \cs{@chapapp} to use
+% \cs{appendixname} and use \cs{@Alph} for \cs{thechapter}. \file{article.cls}
+% resets counters \texttt{section} and \texttt{subsection} to 0, and uses
+% \cs{@Alph} for \cs{thesection}. \file{memoir.cls}, \file{scrbook.cls} and
+% \file{scrarticle.cls} do the same as their corresponding standard classes,
+% and sometimes a little more, but what interests us here is pretty much the
+% same. See also the \pkg{appendix} package.
+%
+% The standard \cs{appendix} command is a one way switch, in other words, it
+% cannot be reverted (see \url{https://tex.stackexchange.com/a/444057}). So,
+% even if the fact that it is a ``switch'' rather than an environment
+% complicates things, because we have to make ungrouped settings to correspond
+% to its effects, in practice this is not a big deal, since these settings are
+% never really reverted (by default, at least). Hence, hooking into
+% \cs{appendix} is a viable and natural alternative. The \cls{memoir} class
+% and the \pkg{appendix} package define the \texttt{appendices} and
+% \texttt{subappendices} environments, which provide for a way for the
+% appendix to ``end'', but in this case, of course, we can hook into the
+% environment instead.
+%
+% \begin{macrocode}
+\@@_compat_module:nn { appendix }
+ {
+ \AddToHook { cmd / appendix / before }
+ {
+ \@@_zcsetup:n
+ {
+ countertype =
+ {
+ chapter = appendix ,
+ section = appendix ,
+ subsection = appendix ,
+ subsubsection = appendix ,
+ paragraph = appendix ,
+ subparagraph = appendix ,
+ }
+ }
+ }
+ }
+% \end{macrocode}
+%
+% Depending on the definition of \cs{appendix}, using the hook may lead to
+% trouble with the first released version of \pkg{ltcmdhooks} (the one
+% released with the 2021-06-01 kernel). Particularly, if the definition of
+% the command being hooked at contains a double hash mark (\texttt{\#\#}) the
+% patch to add the hook, if it needs to be done with the \cs{scantokens}
+% method, may fail noisily (see \url{https://tex.stackexchange.com/q/617905},
+% thanks Phelype Oleinik). The 2021-11-15 kernel release already handle this
+% gracefully (see \url{https://github.com/latex3/latex2e/pull/699}, thanks
+% Phelype Oleinik).
+%
+%
+% \subsection{\opt{appendices}}
+%
+% This module applies both to the \pkg{appendix} package, and to the
+% \cls{memoir} class, since it ``emulates'' the package.
+%
+% \begin{macrocode}
+\@@_compat_module:nn { appendices }
+ {
+ \@@_if_package_loaded:nT { appendix }
+ {
+ \newcounter { zc@appendix }
+ \newcounter { zc@save@appendix }
+ \setcounter { zc@appendix } { 0 }
+ \setcounter { zc@save@appendix } { 0 }
+ \cs_if_exist:cTF { chapter }
+ {
+ \@@_zcsetup:n
+ { counterresetby = { chapter = zc@appendix } }
+ }
+ {
+ \cs_if_exist:cT { section }
+ {
+ \@@_zcsetup:n
+ { counterresetby = { section = zc@appendix } }
+ }
+ }
+ \AddToHook { env / appendices / begin }
+ {
+ \stepcounter { zc@save@appendix }
+ \setcounter { zc@appendix } { \value { zc@save@appendix } }
+ \@@_zcsetup:n
+ {
+ countertype =
+ {
+ chapter = appendix ,
+ section = appendix ,
+ subsection = appendix ,
+ subsubsection = appendix ,
+ paragraph = appendix ,
+ subparagraph = appendix ,
+ }
+ }
+ }
+ \AddToHook { env / appendices / end }
+ { \setcounter { zc@appendix } { 0 } }
+ \AddToHook { cmd / appendix / before }
+ {
+ \stepcounter { zc@save@appendix }
+ \setcounter { zc@appendix } { \value { zc@save@appendix } }
+ }
+ \AddToHook { env / subappendices / begin }
+ {
+ \@@_zcsetup:n
+ {
+ countertype =
+ {
+ section = appendix ,
+ subsection = appendix ,
+ subsubsection = appendix ,
+ paragraph = appendix ,
+ subparagraph = appendix ,
+ } ,
+ }
+ }
+ \msg_info:nnn { zref-clever } { compat-package } { appendix }
+ }
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsection{\opt{memoir}}
+%
+% The \cls{memoir} document class has quite a number of cross-referencing
+% related features, mostly dealing with captions, subfloats, and notes. Some
+% of them are implemented in ways which make difficult the use of \pkg{zref},
+% particularly \cs{zlabel}, short of redefining the whole stuff ourselves.
+% Hopefully, these features are specialized enough to make \pkg{zref-clever}
+% useful enough with \cls{memoir} without much friction, but unless some
+% support is added upstream, it is difficult not to be a little intrusive
+% here.
+%
+% \begin{enumerate}
+% \item Caption functionality which receives \meta{label} as optional
+% argument, namely:
+% \begin{enumerate}
+% \item The \env{sidecaption} and \env{sidecontcaption} environments. These
+% environments \emph{store} the label in an internal macro,
+% \cs{m@mscaplabel}, at the begin environment code (more precisely in
+% \cs[replace=false]{@@sidecaption}), but both the call to
+% \cs{refstepcounter} and the expansion of \cs{m@mscaplabel} take place at
+% \cs{endsidecaption}. For this reason, hooks are not particularly
+% helpful, and there is not any easy way to grab the \meta{label} argument
+% to start with. I can see two ways to deal with these environments, none
+% of which I really like. First, map through \cs{m@mscaplabel} until
+% \cs{label} is found, then grab the next token which is the \meta{label}.
+% This can be used to set a \cs{zlabel} either with a kernel environment
+% hook, or with \cs{@mem@scap@afterhook} (the former requires running
+% \cs{refstepcounter} on our own, since the \texttt{env/.../end} hook
+% comes before this is done by \cs{endsidecaption}). Second, locally
+% redefine \cs{label} to set both labels inside the environments.
+% \item The bilingual caption commands: \cs{bitwonumcaption},
+% \cs{bionenumcaption}, and \cs{bicaption}. These commands do not support
+% setting the label in their arguments (the labels do get set, but they
+% end up included in the \texttt{title} property of the label too). So we
+% do the same for them as for \env{sidecaption}, just taking care of
+% grouping, since we can't count on the convenience of the environment
+% hook (luckily for us, they are scoped themselves, so we can add an extra
+% group there).
+% \end{enumerate}
+% \item The \cs{subcaptionref} command, which makes a reference to the
+% subcaption without the number of the main caption (e.g. ``(b)'', instead
+% of ``2.3(b)''), for labels set inside the \meta{subtitle} argument of the
+% subcaptioning commands, namely: \cs{subcaption}, \cs{contsubcaption},
+% \cs{subbottom}, \cs{contsubbottom}, \cs{subtop}. This functionality is
+% implemented by \cls{memoir} by setting a \emph{second label} with prefix
+% \texttt{sub@\meta{label}}, and storing there just that part of interest.
+% With \pkg{zref} this part is easier, since we can just add an extra
+% property and retrieve it later on. The thing is that it is hard to find a
+% place to hook into to add the property to the \texttt{main} list, since
+% \cls{memoir} does not really consider the possibility of some other
+% command setting labels. \cs{@memsubcaption} is the best place to hook I
+% could find. It is used by subcaptioning commands, and only those. And
+% there is no hope for an environment hook in this case anyway.
+% \item \cls{memoir}'s \cs{footnote}, \cs{verbfootnote}, \cs{sidefootnote} and
+% \cs{pagenote}, just as the regular \cs{footnote} until recently in the
+% kernel, do not set \cs{@currentcounter} alongside \cs{@currentlabel},
+% proper referencing to them requires setting the type for it.
+% \item Note that \cls{memoir}'s appendix features ``emulates'' the
+% \pkg{appendix} package, hence the corresponding compatibility module is
+% loaded for \cls{memoir} even if that package is not itself loaded. The
+% same is true for the \cs{appendix} command module, since it is also
+% defined.
+% \end{enumerate}
+%
+%
+% \begin{macrocode}
+\@@_compat_module:nn { memoir }
+ {
+ \@@_if_class_loaded:nT { memoir }
+ {
+% \end{macrocode}
+% Add subfigure and subtable support out of the box. Technically, this is not
+% ``default'' behavior for \cls{memoir}, users have to enable it with
+% \cs{newsubfloat}, but let this be smooth. Still, this does not cover any
+% other floats created with \cs{newfloat}. Also include setup for
+% \env{verse}.
+% \begin{macrocode}
+ \@@_zcsetup:n
+ {
+ countertype =
+ {
+ subfigure = figure ,
+ subtable = table ,
+ poemline = line ,
+ } ,
+ counterresetby =
+ {
+ subfigure = figure ,
+ subtable = table ,
+ } ,
+ }
+% \end{macrocode}
+% Support for caption \cls{memoir} features that require that \meta{label} be
+% supplied as an optional argument.
+% \begin{macrocode}
+ \cs_new_protected:Npn \@@_memoir_both_labels:
+ {
+ \cs_set_eq:NN \@@_memoir_orig_label:n \label
+ \cs_set:Npn \@@_memoir_label_and_zlabel:n ##1
+ {
+ \@@_memoir_orig_label:n {##1}
+ \zlabel{##1}
+ }
+ \cs_set_eq:NN \label \@@_memoir_label_and_zlabel:n
+ }
+ \AddToHook { env / sidecaption / begin }
+ { \@@_memoir_both_labels: }
+ \AddToHook { env / sidecontcaption / begin }
+ { \@@_memoir_both_labels: }
+ \AddToHook{ cmd / bitwonumcaption / before }
+ { \group_begin: \@@_memoir_both_labels: }
+ \AddToHook{ cmd / bitwonumcaption / after }
+ { \group_end: }
+ \AddToHook{ cmd / bionenumcaption / before }
+ { \group_begin: \@@_memoir_both_labels: }
+ \AddToHook{ cmd / bionenumcaption / after }
+ { \group_end: }
+ \AddToHook{ cmd / bicaption / before }
+ { \group_begin: \@@_memoir_both_labels: }
+ \AddToHook{ cmd / bicaption / after }
+ { \group_end: }
+% \end{macrocode}
+% Support for \texttt{subcaption} reference.
+% \begin{macrocode}
+ \zref@newprop { subcaption }
+ { \cs_if_exist_use:c { @@@@thesub \@captype } }
+ \AddToHook{ cmd / @memsubcaption / before }
+ { \zref@localaddprop \ZREF@mainlist { subcaption } }
+% \end{macrocode}
+% Support for \cs{footnote}, \cs{verbfootnote}, \cs{sidefootnote}, and
+% \cs{pagenote}.
+% \begin{macrocode}
+ \tl_new:N \l_@@_memoir_footnote_type_tl
+ \tl_set:Nn \l_@@_memoir_footnote_type_tl { footnote }
+ \AddToHook { env / minipage / begin }
+ { \tl_set:Nn \l_@@_memoir_footnote_type_tl { mpfootnote } }
+ \AddToHook { cmd / @makefntext / before }
+ {
+ \@@_zcsetup:x
+ { currentcounter = \l_@@_memoir_footnote_type_tl }
+ }
+ \AddToHook { cmd / @makesidefntext / before }
+ { \@@_zcsetup:n { currentcounter = sidefootnote } }
+ \@@_zcsetup:n
+ {
+ countertype =
+ {
+ sidefootnote = footnote ,
+ pagenote = endnote ,
+ } ,
+ }
+ \AddToHook { file / \jobname.ent / before }
+ { \@@_zcsetup:x { currentcounter = pagenote } }
+ \msg_info:nnn { zref-clever } { compat-class } { memoir }
+ }
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsection{\opt{KOMA}}
+%
+% Support for \texttt{KOMA-Script} document classes.
+%
+% \begin{macrocode}
+\@@_compat_module:nn { KOMA }
+ {
+ \cs_if_exist:NT \KOMAClassName
+ {
+% \end{macrocode}
+% Add support for \env{captionbeside} and \env{captionofbeside} environments.
+% These environments \emph{do} run some variation of \cs{caption} and hence
+% \cs{refstepcounter}. However, this happens inside a parbox inside the
+% environment, thus grouped, such that we cannot see the variables set by
+% \cs{refstepcounter} when we are setting the label. \cs{@currentlabel} is
+% smuggled out of the group by KOMA, but the same care is not granted for
+% \cs{@currentcounter}. So we have to rely on \cs{@captype}, which the
+% underlying caption infrastructure feeds to \cs{refstepcounter}. Since we
+% must use \texttt{env/.../after} hooks, care should be taken not to set the
+% \opt{currentcounter} option unscoped, which would be quite disastrous. For
+% this reason, though more ``invasive'', we set \cs{@currentcounter} instead,
+% which at least will be set straight the next time \cs{refstepcounter} runs.
+% It sounds reasonable, it is the same treatment \cs{@currentlabel} is
+% receiving in this case.
+% \begin{macrocode}
+ \AddToHook { env / captionbeside / after }
+ {
+ \tl_if_exist:NT \@captype
+ { \tl_set_eq:NN \@currentcounter \@captype }
+ }
+ \tl_new:N \g_@@_koma_captionofbeside_captype_tl
+ \AddToHook { env / captionofbeside / end }
+ { \tl_gset_eq:NN \g_@@_koma_captype_tl \@captype }
+ \AddToHook { env / captionofbeside / after }
+ {
+ \tl_if_eq:NnF \@currenvir { document }
+ {
+ \tl_if_empty:NF \g_@@_koma_captype_tl
+ {
+ \tl_set_eq:NN
+ \@currentcounter \g_@@_koma_captype_tl
+ }
+ }
+ \tl_gclear:N \g_@@_koma_captype_tl
+ }
+ \msg_info:nnx { zref-clever } { compat-class } { \KOMAClassName }
+ }
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsection{\opt{amsmath}}
+%
+% About this, see \url{https://tex.stackexchange.com/a/402297}.
+%
+% \begin{macrocode}
+\@@_compat_module:nn { amsmath }
+ {
+ \@@_if_package_loaded:nT { amsmath }
+ {
+% \end{macrocode}
+% First, we define a function for label setting inside \pkg{amsmath} math
+% environments, we want it to set both \cs{zlabel} and \cs{label}. We may
+% ``get a ride'', but not steal the place altogether. This makes for
+% potentially redundant labels, but seems a good compromise. We \emph{must}
+% use the lower level \cs{zref@label} in this context, and hence also handle
+% protection with \cs{zref@wrapper@babel}, because \cs{zlabel} makes itself
+% no-op when \cs{label} is equal to \cs{ltx@gobble}, and that's precisely the
+% case inside the \env{multline} environment (and, damn!, I took a beating of
+% this detail\dots{}).
+% \begin{macrocode}
+ \cs_set_nopar:Npn \@@_ltxlabel:n #1
+ {
+ \@@_orig_ltxlabel:n {#1}
+ \zref@wrapper@babel \zref@label {#1}
+ }
+% \end{macrocode}
+% Then we must store the original value of \cs{ltx@label}, which is the macro
+% actually responsible for setting the labels inside \pkg{amsmath}'s math
+% environments. And, after that, redefine it to be \cs{@@_ltxlabel:n}
+% instead. We must handle \pkg{hyperref} here, which comes very late in the
+% preamble, and which loads \pkg{nameref} at \texttt{begindocument}, which in
+% turn, lets \cs{ltx@label} be \cs{label}. This has to come after
+% \pkg{nameref}. Other classes packages also redefine \cs{ltx@label}, which
+% may cause some trouble. A \texttt{grep} on \texttt{texmf-dist} returns hits
+% for: \file{thm-restate.sty}, \file{smartref.sty}, \file{jmlrbook.cls},
+% \file{cleveref.sty}, \file{cryptocode.sty}, \file{nameref.sty},
+% \file{easyeqn.sty}, \file{empheq.sty}, \file{ntheorem.sty},
+% \file{nccmath.sty}, \file{nwejm.cls}, \file{nwejmart.cls},
+% \file{aguplus.sty}, \file{aguplus.cls}, \file{agupp.sty},
+% \file{amsmath.hyp}, \file{amsmath.sty} (surprise!), \file{amsmath.4ht},
+% \file{nameref.4ht}, \file{frenchle.sty}, \file{french.sty}, plus
+% corresponding documentations and different versions of the same packages.
+% That's not too many, but not ``just a few'' either. The critical ones are
+% explicitly handled here (\pkg{amsmath} itself, and \pkg{nameref}). A number
+% of those I'm really not acquainted with. For \pkg{cleveref}, in particular,
+% this procedure is not compatible with it. If we happen to come later than
+% it and override its definition, this may be a substantial problem for
+% \pkg{cleveref}, since it will find the label, but it won't contain the data
+% it is expecting. However, this should normally not occur, if the user has
+% followed the documented recommendation for \pkg{cleveref} to load it last,
+% or at least very late, and besides I don't see much of an use case for using
+% both \pkg{cleveref} and \pkg{zref-clever} together. I have documented in
+% the user manual that this module may cause potential issues, and how to work
+% around them. And I have made an upstream feature request for a hook, so
+% that this could be made more cleanly at
+% \url{https://github.com/latex3/hyperref/issues/212}.
+% \begin{macrocode}
+ \@@_if_package_loaded:nTF { hyperref }
+ {
+ \AddToHook { package / nameref / after }
+ {
+ \cs_new_eq:NN \@@_orig_ltxlabel:n \ltx@label
+ \cs_set_eq:NN \ltx@label \@@_ltxlabel:n
+ }
+ }
+ {
+ \cs_new_eq:NN \@@_orig_ltxlabel:n \ltx@label
+ \cs_set_eq:NN \ltx@label \@@_ltxlabel:n
+ }
+% \end{macrocode}
+% The \env{subequations} environment uses \texttt{parentequation} and
+% \texttt{equation} as counters, but only the later is subject to
+% \cs{refstepcounter}. What happens is: at the start, \texttt{equation} is
+% refstepped, it is then stored in \texttt{parentequation} and set to `0' and,
+% at the end of the environment it is restored to the value of
+% \texttt{parentequation}. We cannot even set \cs{@currentcounter} at
+% \texttt{env/.../begin}, since the call to
+% \cs{refstepcounter}\texttt{\{equation\}} done by \env{subequations} will
+% override that in sequence. Unfortunately, the suggestion to set
+% \cs{@currentcounter} to \texttt{parentequation} here was not accepted, see
+% \url{https://github.com/latex3/latex2e/issues/687#issuecomment-951451024}
+% and subsequent discussion. So, for \env{subequations}, we really must
+% specify manually \opt{currentcounter} and the resetting. Note that, for
+% \env{subequations}, \cs{zlabel} works just fine (that is, if given
+% immediately after \texttt{\\begin\{subequations\}}, to refer to the
+% parent equation).
+% \begin{macrocode}
+ \AddToHook { env / subequations / begin }
+ {
+ \@@_zcsetup:x
+ {
+ counterresetby =
+ {
+ parentequation =
+ \@@_counter_reset_by:n { equation } ,
+ equation = parentequation ,
+ } ,
+ currentcounter = parentequation ,
+ countertype = { parentequation = equation } ,
+ }
+ }
+% \end{macrocode}
+% \pkg{amsmath} does use \cs{refstepcounter} for the \texttt{equation} counter
+% throughout and does set \cs{@currentcounter} for \cs{tag}s. But we still
+% have to manually reset \opt{currentcounter} to default because, since we had
+% to manually set \opt{currentcounter} to \texttt{parentequation} in
+% \env{subequations}, we also have to manually set it to \env{equation} in
+% environments which may be used within it. The \env{xxalignat} environment
+% is not included, because it is ``starred'' by default (i.e.\ unnumbered),
+% and does not display or accepts labels or tags anyway. The \env{-ed}
+% (\env{gathered}, \env{aligned}, and \env{alignedat}) and \env{cases}
+% environments ``must appear within an enclosing math environment''. Same
+% logic applies to other environments defined or redefined by the package,
+% like \env{array}, \env{matrix} and variations. Finally, \env{split} too can
+% only be used as part of another environment.
+% \begin{macrocode}
+ \clist_map_inline:nn
+ {
+ equation ,
+ equation* ,
+ align ,
+ align* ,
+ alignat ,
+ alignat* ,
+ flalign ,
+ flalign* ,
+ xalignat ,
+ xalignat* ,
+ gather ,
+ gather* ,
+ multline ,
+ multline* ,
+ }
+ {
+ \AddToHook { env / #1 / begin }
+ { \@@_zcsetup:n { currentcounter = equation } }
+ }
+% \end{macrocode}
+% And a last touch of care for \pkg{amsmath}'s refinements: make the equation
+% references \cs{textup}.
+% \begin{macrocode}
+ \zcRefTypeSetup { equation }
+ {
+ reffont = \upshape ,
+ refpre = {\textup{(}} ,
+ refpos = {\textup{)}} ,
+ }
+ \msg_info:nnn { zref-clever } { compat-package } { amsmath }
+ }
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsection{\opt{mathtools}}
+%
+% All math environments defined by \pkg{mathtools}, extending the
+% \pkg{amsmath} set, are meant to be used within enclosing math environments,
+% hence we don't need to handle them specially, since the numbering and the
+% counting is being done on the side of \pkg{amsmath}. This includes the new
+% \env{cases} and \env{matrix} variants, and also \env{multlined}.
+%
+% Hence, as far as I can tell, the only cross-reference related feature to
+% deal with is the \opt{showonlyrefs} option, whose machinery involves writing
+% an extra internal label to the \file{.aux} file to track for labels which
+% get actually referred to. This is a little more involved, and implies in
+% doing special handling inside \cs{zcref}, but the feature is very cool, so
+% it's worth it.
+%
+% \begin{macrocode}
+\bool_new:N \l_@@_mathtools_showonlyrefs_bool
+\@@_compat_module:nn { mathtools }
+ {
+ \@@_if_package_loaded:nT { mathtools }
+ {
+ \MH_if_boolean:nT { show_only_refs }
+ {
+ \bool_set_true:N \l_@@_mathtools_showonlyrefs_bool
+ \cs_new_protected:Npn \@@_mathtools_showonlyrefs:n #1
+ {
+ \@bsphack
+ \seq_map_inline:Nn #1
+ {
+ \exp_args:Nx \tl_if_eq:nnTF
+ { \@@_extract_unexp:nnn {##1} { zc@type } { } }
+ { equation }
+ {
+ \protected@write \@auxout { }
+ { \string \MT@newlabel {##1} }
+ }
+ {
+ \exp_args:Nx \tl_if_eq:nnT
+ { \@@_extract_unexp:nnn {##1} { zc@type } { } }
+ { parentequation }
+ {
+ \protected@write \@auxout { }
+ { \string \MT@newlabel {##1} }
+ }
+ }
+ }
+ \@esphack
+ }
+ \msg_info:nnn { zref-clever } { compat-package } { mathtools }
+ }
+ }
+ }
+% \end{macrocode}
+%
+%
+% \subsection{\opt{breqn}}
+%
+% From the \pkg{breqn} documentation: \textquote{Use of the normal \cs{label}
+% command instead of the \opt{label} option works, I think, most of the time
+% (untested)}. Indeed, light testing suggests it does work for \cs{zlabel}
+% just as well. However, if it happens not to work, there was no easy
+% alternative handle I could find. In particular, it does not seem viable to
+% leverage the \opt{label=} option without hacking the package internals, even
+% if the case of doing so would not be specially tricky, just ``not very
+% civil''.
+%
+% \begin{macrocode}
+\@@_compat_module:nn { breqn }
+ {
+ \@@_if_package_loaded:nT { breqn }
+ {
+% \end{macrocode}
+% Contrary to the practice in \pkg{amsmath}, which prints \cs{tag} even in
+% unnumbered environments, the starred environments from \pkg{breqn} don't
+% typeset any tag/number at all, even for a manually given \opt{number=} as an
+% option. So, even if one can actually set a label in them, it is not really
+% meaningful to make a reference to them. Also contrary to \pkg{amsmath}'s
+% practice, \pkg{breqn} uses \cs{stepcounter} instead of \cs{refstepcounter}
+% for incrementing the equation counters (see
+% \url{https://tex.stackexchange.com/a/241150}).
+% \begin{macrocode}
+ \AddToHook { env / dgroup / begin }
+ {
+ \@@_zcsetup:x
+ {
+ counterresetby =
+ {
+ parentequation =
+ \@@_counter_reset_by:n { equation } ,
+ equation = parentequation ,
+ } ,
+ currentcounter = parentequation ,
+ countertype = { parentequation = equation } ,
+ }
+ }
+ \clist_map_inline:nn
+ {
+ dmath ,
+ dseries ,
+ darray ,
+ }
+ {
+ \AddToHook { env / #1 / begin }
+ { \@@_zcsetup:n { currentcounter = equation } }
+ }
+ \msg_info:nnn { zref-clever } { compat-package } { breqn }
+ }
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsection{\opt{listings}}
+%
+% \begin{macrocode}
+\@@_compat_module:nn { listings }
+ {
+ \@@_if_package_loaded:nT { listings }
+ {
+ \@@_zcsetup:n
+ {
+ countertype =
+ {
+ lstlisting = listing ,
+ lstnumber = line ,
+ } ,
+ counterresetby = { lstnumber = lstlisting } ,
+ }
+% \end{macrocode}
+% Set (also) a \cs{zlabel} with the label received in the \texttt{label=}
+% option from the \texttt{lstlisting} environment. The \emph{only} place to
+% set this label is the \texttt{PreInit} hook. This hook, comes right after
+% \cs{lst@MakeCaption} in \cs{lst@Init}, which runs \cs{refstepcounter} on
+% \texttt{lstlisting}, so we must come after it. Also \pkg{listings} itself
+% sets \cs{@currentlabel} to \cs{thelstnumber} in the \texttt{Init} hook,
+% which comes right after the \texttt{PreInit} one in \cs{lst@Init}. Since,
+% if we add to \texttt{Init} here, we go to the end of it, we'd be seeing the
+% wrong \cs{@currentlabel} at that point.
+% \begin{macrocode}
+ \lst@AddToHook { PreInit }
+ { \tl_if_empty:NF \lst@label { \zlabel { \lst@label } } }
+% \end{macrocode}
+% Set \texttt{currentcounter} to \texttt{lstnumber} in the \texttt{Init} hook,
+% since \pkg{listings} itself sets \cs{@currentlabel} to \cs{thelstnumber}
+% here. Note that \pkg{listings} \emph{does use} \cs{refstepcounter} on
+% \texttt{lstnumber}, but does so in the \texttt{EveryPar} hook, and there
+% must be some grouping involved such that \cs{@currentcounter} ends up not
+% being visible to the label. See section ``Line numbers'' of `\texttt{texdoc
+% listings-devel}' (the \file{.dtx}), and search for the definition of macro
+% \cs{c@lstnumber}. Indeed, the fact that \pkg{listings} manually sets
+% \cs{@currentlabel} to \cs{thelstnumber} is a signal that the work of
+% \cs{refstepcounter} is being restrained somehow.
+% \begin{macrocode}
+ \lst@AddToHook { Init }
+ { \@@_zcsetup:n { currentcounter = lstnumber } }
+ \msg_info:nnn { zref-clever } { compat-package } { listings }
+ }
+ }
+% \end{macrocode}
+%
+%
+% \subsection{\opt{enumitem}}
+%
+% The procedure below will ``see'' any changes made to the \texttt{enumerate}
+% environment (made with \pkg{enumitem}'s \cs{renewlist}) as long as it is
+% done in the preamble. Though, technically, \cs{renewlist} can be issued
+% anywhere in the document, this should be more than enough for the purpose at
+% hand. Besides, trying to retrieve this information ``on the fly'' would be
+% much overkill.
+%
+% The only real reason to ``renew'' \texttt{enumerate} itself is to change
+% \marg{max-depth}. \cs{renewlist} \emph{hard-codes} \texttt{max-depth} in
+% the environment's definition (well, just as the kernel does), so we cannot
+% retrieve this information from any sort of variable. But \cs{renewlist}
+% also creates any needed missing counters, so we can use their existence to
+% make the appropriate settings. In the end, the existence of the counters is
+% indeed what matters from \pkg{zref-clever}'s perspective. Since the first
+% four are defined by the kernel and already setup for \pkg{zref-clever} by
+% default, we start from \(5\), and stop at the first non-existent
+% \cs[no-index]{c@enumN} counter.
+%
+% \begin{macrocode}
+\@@_compat_module:nn { enumitem }
+ {
+ \@@_if_package_loaded:nT { enumitem }
+ {
+ \int_set:Nn \l_tmpa_int { 5 }
+ \bool_while_do:nn
+ {
+ \cs_if_exist_p:c
+ { c@ enum \int_to_roman:n { \l_tmpa_int } }
+ }
+ {
+ \@@_zcsetup:x
+ {
+ counterresetby =
+ {
+ enum \int_to_roman:n { \l_tmpa_int } =
+ enum \int_to_roman:n { \l_tmpa_int - 1 }
+ } ,
+ countertype =
+ { enum \int_to_roman:n { \l_tmpa_int } = item } ,
+ }
+ \int_incr:N \l_tmpa_int
+ }
+ \int_compare:nNnT { \l_tmpa_int } > { 5 }
+ { \msg_info:nnn { zref-clever } { compat-package } { enumitem } }
+ }
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsection{\opt{subcaption}}
+%
+%
+% \begin{macrocode}
+\@@_compat_module:nn { subcaption }
+ {
+ \@@_if_package_loaded:nT { subcaption }
+ {
+ \@@_zcsetup:n
+ {
+ countertype =
+ {
+ subfigure = figure ,
+ subtable = table ,
+ } ,
+ counterresetby =
+ {
+ subfigure = figure ,
+ subtable = table ,
+ } ,
+ }
+% \end{macrocode}
+% Support for \texttt{subref} reference.
+% \begin{macrocode}
+ \zref@newprop { subref }
+ { \cs_if_exist_use:c { thesub \@captype } }
+ \tl_put_right:Nn \caption@subtypehook
+ { \zref@localaddprop \ZREF@mainlist { subref } }
+ }
+ }
+% \end{macrocode}
+%
+%
+% \subsection{\opt{subfig}}
+%
+% Though \pkg{subfig} offers \cs{subref} (as \pkg{subcaption}), I could not
+% find any reasonable place to add the \texttt{subref} property to
+% \pkg{zref}'s main list.
+%
+% \begin{macrocode}
+\@@_compat_module:nn { subfig }
+ {
+ \@@_if_package_loaded:nT { subfig }
+ {
+ \@@_zcsetup:n
+ {
+ countertype =
+ {
+ subfigure = figure ,
+ subtable = table ,
+ } ,
+ counterresetby =
+ {
+ subfigure = figure ,
+ subtable = table ,
+ } ,
+ }
+ }
+ }
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+%
+%
+% \section{Dictionaries}
+%
+% \subsection{English}
+%
+% \begin{macrocode}
+%<*package>
+\zcDeclareLanguage { english }
+\zcDeclareLanguageAlias { american } { english }
+\zcDeclareLanguageAlias { australian } { english }
+\zcDeclareLanguageAlias { british } { english }
+\zcDeclareLanguageAlias { canadian } { english }
+\zcDeclareLanguageAlias { newzealand } { english }
+\zcDeclareLanguageAlias { UKenglish } { english }
+\zcDeclareLanguageAlias { USenglish } { english }
+%</package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*dict-english>
+% \end{macrocode}
+%
+% \begin{macrocode}
+namesep = {\nobreakspace} ,
+pairsep = {~and\nobreakspace} ,
+listsep = {,~} ,
+lastsep = {~and\nobreakspace} ,
+tpairsep = {~and\nobreakspace} ,
+tlistsep = {,~} ,
+tlastsep = {,~and\nobreakspace} ,
+notesep = {~} ,
+rangesep = {~to\nobreakspace} ,
+
+type = book ,
+ Name-sg = Book ,
+ name-sg = book ,
+ Name-pl = Books ,
+ name-pl = books ,
+
+type = part ,
+ Name-sg = Part ,
+ name-sg = part ,
+ Name-pl = Parts ,
+ name-pl = parts ,
+
+type = chapter ,
+ Name-sg = Chapter ,
+ name-sg = chapter ,
+ Name-pl = Chapters ,
+ name-pl = chapters ,
+
+type = section ,
+ Name-sg = Section ,
+ name-sg = section ,
+ Name-pl = Sections ,
+ name-pl = sections ,
+
+type = paragraph ,
+ Name-sg = Paragraph ,
+ name-sg = paragraph ,
+ Name-pl = Paragraphs ,
+ name-pl = paragraphs ,
+ Name-sg-ab = Par. ,
+ name-sg-ab = par. ,
+ Name-pl-ab = Par. ,
+ name-pl-ab = par. ,
+
+type = appendix ,
+ Name-sg = Appendix ,
+ name-sg = appendix ,
+ Name-pl = Appendices ,
+ name-pl = appendices ,
+
+type = subappendix ,
+ Name-sg = Appendix ,
+ name-sg = appendix ,
+ Name-pl = Appendices ,
+ name-pl = appendices ,
+
+type = page ,
+ Name-sg = Page ,
+ name-sg = page ,
+ Name-pl = Pages ,
+ name-pl = pages ,
+ name-sg-ab = p. ,
+ name-pl-ab = pp. ,
+ rangesep = {\textendash} ,
+
+type = line ,
+ Name-sg = Line ,
+ name-sg = line ,
+ Name-pl = Lines ,
+ name-pl = lines ,
+
+type = figure ,
+ Name-sg = Figure ,
+ name-sg = figure ,
+ Name-pl = Figures ,
+ name-pl = figures ,
+ Name-sg-ab = Fig. ,
+ name-sg-ab = fig. ,
+ Name-pl-ab = Figs. ,
+ name-pl-ab = figs. ,
+
+type = table ,
+ Name-sg = Table ,
+ name-sg = table ,
+ Name-pl = Tables ,
+ name-pl = tables ,
+
+type = item ,
+ Name-sg = Item ,
+ name-sg = item ,
+ Name-pl = Items ,
+ name-pl = items ,
+
+type = footnote ,
+ Name-sg = Footnote ,
+ name-sg = footnote ,
+ Name-pl = Footnotes ,
+ name-pl = footnotes ,
+
+type = endnote ,
+ Name-sg = Note ,
+ name-sg = note ,
+ Name-pl = Notes ,
+ name-pl = notes ,
+
+type = note ,
+ Name-sg = Note ,
+ name-sg = note ,
+ Name-pl = Notes ,
+ name-pl = notes ,
+
+type = equation ,
+ Name-sg = Equation ,
+ name-sg = equation ,
+ Name-pl = Equations ,
+ name-pl = equations ,
+ Name-sg-ab = Eq. ,
+ name-sg-ab = eq. ,
+ Name-pl-ab = Eqs. ,
+ name-pl-ab = eqs. ,
+ refpre = {(} ,
+ refpos = {)} ,
+
+type = theorem ,
+ Name-sg = Theorem ,
+ name-sg = theorem ,
+ Name-pl = Theorems ,
+ name-pl = theorems ,
+
+type = lemma ,
+ Name-sg = Lemma ,
+ name-sg = lemma ,
+ Name-pl = Lemmas ,
+ name-pl = lemmas ,
+
+type = corollary ,
+ Name-sg = Corollary ,
+ name-sg = corollary ,
+ Name-pl = Corollaries ,
+ name-pl = corollaries ,
+
+type = proposition ,
+ Name-sg = Proposition ,
+ name-sg = proposition ,
+ Name-pl = Propositions ,
+ name-pl = propositions ,
+
+type = definition ,
+ Name-sg = Definition ,
+ name-sg = definition ,
+ Name-pl = Definitions ,
+ name-pl = definitions ,
+
+type = proof ,
+ Name-sg = Proof ,
+ name-sg = proof ,
+ Name-pl = Proofs ,
+ name-pl = proofs ,
+
+type = result ,
+ Name-sg = Result ,
+ name-sg = result ,
+ Name-pl = Results ,
+ name-pl = results ,
+
+type = remark ,
+ Name-sg = Remark ,
+ name-sg = remark ,
+ Name-pl = Remarks ,
+ name-pl = remarks ,
+
+type = example ,
+ Name-sg = Example ,
+ name-sg = example ,
+ Name-pl = Examples ,
+ name-pl = examples ,
+
+type = algorithm ,
+ Name-sg = Algorithm ,
+ name-sg = algorithm ,
+ Name-pl = Algorithms ,
+ name-pl = algorithms ,
+
+type = listing ,
+ Name-sg = Listing ,
+ name-sg = listing ,
+ Name-pl = Listings ,
+ name-pl = listings ,
+
+type = exercise ,
+ Name-sg = Exercise ,
+ name-sg = exercise ,
+ Name-pl = Exercises ,
+ name-pl = exercises ,
+
+type = solution ,
+ Name-sg = Solution ,
+ name-sg = solution ,
+ Name-pl = Solutions ,
+ name-pl = solutions ,
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</dict-english>
+% \end{macrocode}
+%
+%
+%
+% \subsection{German}
+%
+% \begin{macrocode}
+%<*package>
+\zcDeclareLanguage
+ [ declension = { N , A , D , G } , gender = { f , m , n } , allcaps ]
+ { german }
+\zcDeclareLanguageAlias { austrian } { german }
+\zcDeclareLanguageAlias { germanb } { german }
+\zcDeclareLanguageAlias { ngerman } { german }
+\zcDeclareLanguageAlias { naustrian } { german }
+\zcDeclareLanguageAlias { nswissgerman } { german }
+\zcDeclareLanguageAlias { swissgerman } { german }
+%</package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*dict-german>
+% \end{macrocode}
+%
+% \begin{macrocode}
+namesep = {\nobreakspace} ,
+pairsep = {~und\nobreakspace} ,
+listsep = {,~} ,
+lastsep = {~und\nobreakspace} ,
+tpairsep = {~und\nobreakspace} ,
+tlistsep = {,~} ,
+tlastsep = {~und\nobreakspace} ,
+notesep = {~} ,
+rangesep = {~bis\nobreakspace} ,
+
+type = book ,
+ gender = n ,
+ case = N ,
+ Name-sg = Buch ,
+ Name-pl = Bücher ,
+ case = A ,
+ Name-sg = Buch ,
+ Name-pl = Bücher ,
+ case = D ,
+ Name-sg = Buch ,
+ Name-pl = Büchern ,
+ case = G ,
+ Name-sg = Buches ,
+ Name-pl = Bücher ,
+
+type = part ,
+ gender = m ,
+ case = N ,
+ Name-sg = Teil ,
+ Name-pl = Teile ,
+ case = A ,
+ Name-sg = Teil ,
+ Name-pl = Teile ,
+ case = D ,
+ Name-sg = Teil ,
+ Name-pl = Teilen ,
+ case = G ,
+ Name-sg = Teiles ,
+ Name-pl = Teile ,
+
+type = chapter ,
+ gender = n ,
+ case = N ,
+ Name-sg = Kapitel ,
+ Name-pl = Kapitel ,
+ case = A ,
+ Name-sg = Kapitel ,
+ Name-pl = Kapitel ,
+ case = D ,
+ Name-sg = Kapitel ,
+ Name-pl = Kapiteln ,
+ case = G ,
+ Name-sg = Kapitels ,
+ Name-pl = Kapitel ,
+
+type = section ,
+ gender = m ,
+ case = N ,
+ Name-sg = Abschnitt ,
+ Name-pl = Abschnitte ,
+ case = A ,
+ Name-sg = Abschnitt ,
+ Name-pl = Abschnitte ,
+ case = D ,
+ Name-sg = Abschnitt ,
+ Name-pl = Abschnitten ,
+ case = G ,
+ Name-sg = Abschnitts ,
+ Name-pl = Abschnitte ,
+
+type = paragraph ,
+ gender = m ,
+ case = N ,
+ Name-sg = Absatz ,
+ Name-pl = Absätze ,
+ case = A ,
+ Name-sg = Absatz ,
+ Name-pl = Absätze ,
+ case = D ,
+ Name-sg = Absatz ,
+ Name-pl = Absätzen ,
+ case = G ,
+ Name-sg = Absatzes ,
+ Name-pl = Absätze ,
+
+type = appendix ,
+ gender = m ,
+ case = N ,
+ Name-sg = Anhang ,
+ Name-pl = Anhänge ,
+ case = A ,
+ Name-sg = Anhang ,
+ Name-pl = Anhänge ,
+ case = D ,
+ Name-sg = Anhang ,
+ Name-pl = Anhängen ,
+ case = G ,
+ Name-sg = Anhangs ,
+ Name-pl = Anhänge ,
+
+type = subappendix ,
+ gender = m ,
+ case = N ,
+ Name-sg = Anhang ,
+ Name-pl = Anhänge ,
+ case = A ,
+ Name-sg = Anhang ,
+ Name-pl = Anhänge ,
+ case = D ,
+ Name-sg = Anhang ,
+ Name-pl = Anhängen ,
+ case = G ,
+ Name-sg = Anhangs ,
+ Name-pl = Anhänge ,
+
+type = page ,
+ gender = f ,
+ case = N ,
+ Name-sg = Seite ,
+ Name-pl = Seiten ,
+ case = A ,
+ Name-sg = Seite ,
+ Name-pl = Seiten ,
+ case = D ,
+ Name-sg = Seite ,
+ Name-pl = Seiten ,
+ case = G ,
+ Name-sg = Seite ,
+ Name-pl = Seiten ,
+ rangesep = {\textendash} ,
+
+type = line ,
+ gender = f ,
+ case = N ,
+ Name-sg = Zeile ,
+ Name-pl = Zeilen ,
+ case = A ,
+ Name-sg = Zeile ,
+ Name-pl = Zeilen ,
+ case = D ,
+ Name-sg = Zeile ,
+ Name-pl = Zeilen ,
+ case = G ,
+ Name-sg = Zeile ,
+ Name-pl = Zeilen ,
+
+type = figure ,
+ gender = f ,
+ case = N ,
+ Name-sg = Abbildung ,
+ Name-pl = Abbildungen ,
+ Name-sg-ab = Abb. ,
+ Name-pl-ab = Abb. ,
+ case = A ,
+ Name-sg = Abbildung ,
+ Name-pl = Abbildungen ,
+ Name-sg-ab = Abb. ,
+ Name-pl-ab = Abb. ,
+ case = D ,
+ Name-sg = Abbildung ,
+ Name-pl = Abbildungen ,
+ Name-sg-ab = Abb. ,
+ Name-pl-ab = Abb. ,
+ case = G ,
+ Name-sg = Abbildung ,
+ Name-pl = Abbildungen ,
+ Name-sg-ab = Abb. ,
+ Name-pl-ab = Abb. ,
+
+type = table ,
+ gender = f ,
+ case = N ,
+ Name-sg = Tabelle ,
+ Name-pl = Tabellen ,
+ case = A ,
+ Name-sg = Tabelle ,
+ Name-pl = Tabellen ,
+ case = D ,
+ Name-sg = Tabelle ,
+ Name-pl = Tabellen ,
+ case = G ,
+ Name-sg = Tabelle ,
+ Name-pl = Tabellen ,
+
+type = item ,
+ gender = m ,
+ case = N ,
+ Name-sg = Punkt ,
+ Name-pl = Punkte ,
+ case = A ,
+ Name-sg = Punkt ,
+ Name-pl = Punkte ,
+ case = D ,
+ Name-sg = Punkt ,
+ Name-pl = Punkten ,
+ case = G ,
+ Name-sg = Punktes ,
+ Name-pl = Punkte ,
+
+type = footnote ,
+ gender = f ,
+ case = N ,
+ Name-sg = Fußnote ,
+ Name-pl = Fußnoten ,
+ case = A ,
+ Name-sg = Fußnote ,
+ Name-pl = Fußnoten ,
+ case = D ,
+ Name-sg = Fußnote ,
+ Name-pl = Fußnoten ,
+ case = G ,
+ Name-sg = Fußnote ,
+ Name-pl = Fußnoten ,
+
+type = endnote ,
+ gender = f ,
+ case = N ,
+ Name-sg = Endnote ,
+ Name-pl = Endnoten ,
+ case = A ,
+ Name-sg = Endnote ,
+ Name-pl = Endnoten ,
+ case = D ,
+ Name-sg = Endnote ,
+ Name-pl = Endnoten ,
+ case = G ,
+ Name-sg = Endnote ,
+ Name-pl = Endnoten ,
+
+type = note ,
+ gender = f ,
+ case = N ,
+ Name-sg = Anmerkung ,
+ Name-pl = Anmerkungen ,
+ case = A ,
+ Name-sg = Anmerkung ,
+ Name-pl = Anmerkungen ,
+ case = D ,
+ Name-sg = Anmerkung ,
+ Name-pl = Anmerkungen ,
+ case = G ,
+ Name-sg = Anmerkung ,
+ Name-pl = Anmerkungen ,
+
+type = equation ,
+ gender = f ,
+ case = N ,
+ Name-sg = Gleichung ,
+ Name-pl = Gleichungen ,
+ case = A ,
+ Name-sg = Gleichung ,
+ Name-pl = Gleichungen ,
+ case = D ,
+ Name-sg = Gleichung ,
+ Name-pl = Gleichungen ,
+ case = G ,
+ Name-sg = Gleichung ,
+ Name-pl = Gleichungen ,
+ refpre = {(} ,
+ refpos = {)} ,
+
+type = theorem ,
+ gender = n ,
+ case = N ,
+ Name-sg = Theorem ,
+ Name-pl = Theoreme ,
+ case = A ,
+ Name-sg = Theorem ,
+ Name-pl = Theoreme ,
+ case = D ,
+ Name-sg = Theorem ,
+ Name-pl = Theoremen ,
+ case = G ,
+ Name-sg = Theorems ,
+ Name-pl = Theoreme ,
+
+type = lemma ,
+ gender = n ,
+ case = N ,
+ Name-sg = Lemma ,
+ Name-pl = Lemmata ,
+ case = A ,
+ Name-sg = Lemma ,
+ Name-pl = Lemmata ,
+ case = D ,
+ Name-sg = Lemma ,
+ Name-pl = Lemmata ,
+ case = G ,
+ Name-sg = Lemmas ,
+ Name-pl = Lemmata ,
+
+type = corollary ,
+ gender = n ,
+ case = N ,
+ Name-sg = Korollar ,
+ Name-pl = Korollare ,
+ case = A ,
+ Name-sg = Korollar ,
+ Name-pl = Korollare ,
+ case = D ,
+ Name-sg = Korollar ,
+ Name-pl = Korollaren ,
+ case = G ,
+ Name-sg = Korollars ,
+ Name-pl = Korollare ,
+
+type = proposition ,
+ gender = m ,
+ case = N ,
+ Name-sg = Satz ,
+ Name-pl = Sätze ,
+ case = A ,
+ Name-sg = Satz ,
+ Name-pl = Sätze ,
+ case = D ,
+ Name-sg = Satz ,
+ Name-pl = Sätzen ,
+ case = G ,
+ Name-sg = Satzes ,
+ Name-pl = Sätze ,
+
+type = definition ,
+ gender = f ,
+ case = N ,
+ Name-sg = Definition ,
+ Name-pl = Definitionen ,
+ case = A ,
+ Name-sg = Definition ,
+ Name-pl = Definitionen ,
+ case = D ,
+ Name-sg = Definition ,
+ Name-pl = Definitionen ,
+ case = G ,
+ Name-sg = Definition ,
+ Name-pl = Definitionen ,
+
+type = proof ,
+ gender = m ,
+ case = N ,
+ Name-sg = Beweis ,
+ Name-pl = Beweise ,
+ case = A ,
+ Name-sg = Beweis ,
+ Name-pl = Beweise ,
+ case = D ,
+ Name-sg = Beweis ,
+ Name-pl = Beweisen ,
+ case = G ,
+ Name-sg = Beweises ,
+ Name-pl = Beweise ,
+
+type = result ,
+ gender = n ,
+ case = N ,
+ Name-sg = Ergebnis ,
+ Name-pl = Ergebnisse ,
+ case = A ,
+ Name-sg = Ergebnis ,
+ Name-pl = Ergebnisse ,
+ case = D ,
+ Name-sg = Ergebnis ,
+ Name-pl = Ergebnissen ,
+ case = G ,
+ Name-sg = Ergebnisses ,
+ Name-pl = Ergebnisse ,
+
+type = remark ,
+ gender = f ,
+ case = N ,
+ Name-sg = Bemerkung ,
+ Name-pl = Bemerkungen ,
+ case = A ,
+ Name-sg = Bemerkung ,
+ Name-pl = Bemerkungen ,
+ case = D ,
+ Name-sg = Bemerkung ,
+ Name-pl = Bemerkungen ,
+ case = G ,
+ Name-sg = Bemerkung ,
+ Name-pl = Bemerkungen ,
+
+type = example ,
+ gender = n ,
+ case = N ,
+ Name-sg = Beispiel ,
+ Name-pl = Beispiele ,
+ case = A ,
+ Name-sg = Beispiel ,
+ Name-pl = Beispiele ,
+ case = D ,
+ Name-sg = Beispiel ,
+ Name-pl = Beispielen ,
+ case = G ,
+ Name-sg = Beispiels ,
+ Name-pl = Beispiele ,
+
+type = algorithm ,
+ gender = m ,
+ case = N ,
+ Name-sg = Algorithmus ,
+ Name-pl = Algorithmen ,
+ case = A ,
+ Name-sg = Algorithmus ,
+ Name-pl = Algorithmen ,
+ case = D ,
+ Name-sg = Algorithmus ,
+ Name-pl = Algorithmen ,
+ case = G ,
+ Name-sg = Algorithmus ,
+ Name-pl = Algorithmen ,
+
+type = listing ,
+ gender = n ,
+ case = N ,
+ Name-sg = Listing ,
+ Name-pl = Listings ,
+ case = A ,
+ Name-sg = Listing ,
+ Name-pl = Listings ,
+ case = D ,
+ Name-sg = Listing ,
+ Name-pl = Listings ,
+ case = G ,
+ Name-sg = Listings ,
+ Name-pl = Listings ,
+
+type = exercise ,
+ gender = f ,
+ case = N ,
+ Name-sg = Übungsaufgabe ,
+ Name-pl = Übungsaufgaben ,
+ case = A ,
+ Name-sg = Übungsaufgabe ,
+ Name-pl = Übungsaufgaben ,
+ case = D ,
+ Name-sg = Übungsaufgabe ,
+ Name-pl = Übungsaufgaben ,
+ case = G ,
+ Name-sg = Übungsaufgabe ,
+ Name-pl = Übungsaufgaben ,
+
+type = solution ,
+ gender = f ,
+ case = N ,
+ Name-sg = Lösung ,
+ Name-pl = Lösungen ,
+ case = A ,
+ Name-sg = Lösung ,
+ Name-pl = Lösungen ,
+ case = D ,
+ Name-sg = Lösung ,
+ Name-pl = Lösungen ,
+ case = G ,
+ Name-sg = Lösung ,
+ Name-pl = Lösungen ,
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</dict-german>
+% \end{macrocode}
+%
+%
+%
+% \subsection{French}
+%
+% \begin{macrocode}
+%<*package>
+\zcDeclareLanguage [ gender = { f , m } ] { french }
+\zcDeclareLanguageAlias { acadian } { french }
+\zcDeclareLanguageAlias { canadien } { french }
+\zcDeclareLanguageAlias { francais } { french }
+\zcDeclareLanguageAlias { frenchb } { french }
+%</package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*dict-french>
+% \end{macrocode}
+%
+% \begin{macrocode}
+namesep = {\nobreakspace} ,
+pairsep = {~et\nobreakspace} ,
+listsep = {,~} ,
+lastsep = {~et\nobreakspace} ,
+tpairsep = {~et\nobreakspace} ,
+tlistsep = {,~} ,
+tlastsep = {~et\nobreakspace} ,
+notesep = {~} ,
+rangesep = {~à\nobreakspace} ,
+
+type = book ,
+ gender = m ,
+ Name-sg = Livre ,
+ name-sg = livre ,
+ Name-pl = Livres ,
+ name-pl = livres ,
+
+type = part ,
+ gender = f ,
+ Name-sg = Partie ,
+ name-sg = partie ,
+ Name-pl = Parties ,
+ name-pl = parties ,
+
+type = chapter ,
+ gender = m ,
+ Name-sg = Chapitre ,
+ name-sg = chapitre ,
+ Name-pl = Chapitres ,
+ name-pl = chapitres ,
+
+type = section ,
+ gender = f ,
+ Name-sg = Section ,
+ name-sg = section ,
+ Name-pl = Sections ,
+ name-pl = sections ,
+
+type = paragraph ,
+ gender = m ,
+ Name-sg = Paragraphe ,
+ name-sg = paragraphe ,
+ Name-pl = Paragraphes ,
+ name-pl = paragraphes ,
+
+type = appendix ,
+ gender = f ,
+ Name-sg = Annexe ,
+ name-sg = annexe ,
+ Name-pl = Annexes ,
+ name-pl = annexes ,
+
+type = subappendix ,
+ gender = f ,
+ Name-sg = Annexe ,
+ name-sg = annexe ,
+ Name-pl = Annexes ,
+ name-pl = annexes ,
+
+type = page ,
+ gender = f ,
+ Name-sg = Page ,
+ name-sg = page ,
+ Name-pl = Pages ,
+ name-pl = pages ,
+ rangesep = {\textendash} ,
+
+type = line ,
+ gender = f ,
+ Name-sg = Ligne ,
+ name-sg = ligne ,
+ Name-pl = Lignes ,
+ name-pl = lignes ,
+
+type = figure ,
+ gender = f ,
+ Name-sg = Figure ,
+ name-sg = figure ,
+ Name-pl = Figures ,
+ name-pl = figures ,
+
+type = table ,
+ gender = f ,
+ Name-sg = Table ,
+ name-sg = table ,
+ Name-pl = Tables ,
+ name-pl = tables ,
+
+type = item ,
+ gender = m ,
+ Name-sg = Point ,
+ name-sg = point ,
+ Name-pl = Points ,
+ name-pl = points ,
+
+type = footnote ,
+ gender = f ,
+ Name-sg = Note ,
+ name-sg = note ,
+ Name-pl = Notes ,
+ name-pl = notes ,
+
+type = endnote ,
+ gender = f ,
+ Name-sg = Note ,
+ name-sg = note ,
+ Name-pl = Notes ,
+ name-pl = notes ,
+
+type = note ,
+ gender = f ,
+ Name-sg = Note ,
+ name-sg = note ,
+ Name-pl = Notes ,
+ name-pl = notes ,
+
+type = equation ,
+ gender = f ,
+ Name-sg = Équation ,
+ name-sg = équation ,
+ Name-pl = Équations ,
+ name-pl = équations ,
+ refpre = {(} ,
+ refpos = {)} ,
+
+type = theorem ,
+ gender = m ,
+ Name-sg = Théorème ,
+ name-sg = théorème ,
+ Name-pl = Théorèmes ,
+ name-pl = théorèmes ,
+
+type = lemma ,
+ gender = m ,
+ Name-sg = Lemme ,
+ name-sg = lemme ,
+ Name-pl = Lemmes ,
+ name-pl = lemmes ,
+
+type = corollary ,
+ gender = m ,
+ Name-sg = Corollaire ,
+ name-sg = corollaire ,
+ Name-pl = Corollaires ,
+ name-pl = corollaires ,
+
+type = proposition ,
+ gender = f ,
+ Name-sg = Proposition ,
+ name-sg = proposition ,
+ Name-pl = Propositions ,
+ name-pl = propositions ,
+
+type = definition ,
+ gender = f ,
+ Name-sg = Définition ,
+ name-sg = définition ,
+ Name-pl = Définitions ,
+ name-pl = définitions ,
+
+type = proof ,
+ gender = f ,
+ Name-sg = Démonstration ,
+ name-sg = démonstration ,
+ Name-pl = Démonstrations ,
+ name-pl = démonstrations ,
+
+type = result ,
+ gender = m ,
+ Name-sg = Résultat ,
+ name-sg = résultat ,
+ Name-pl = Résultats ,
+ name-pl = résultats ,
+
+type = remark ,
+ gender = f ,
+ Name-sg = Remarque ,
+ name-sg = remarque ,
+ Name-pl = Remarques ,
+ name-pl = remarques ,
+
+type = example ,
+ gender = m ,
+ Name-sg = Exemple ,
+ name-sg = exemple ,
+ Name-pl = Exemples ,
+ name-pl = exemples ,
+
+type = algorithm ,
+ gender = m ,
+ Name-sg = Algorithme ,
+ name-sg = algorithme ,
+ Name-pl = Algorithmes ,
+ name-pl = algorithmes ,
+
+type = listing ,
+ gender = f ,
+ Name-sg = Liste ,
+ name-sg = liste ,
+ Name-pl = Listes ,
+ name-pl = listes ,
+
+type = exercise ,
+ gender = m ,
+ Name-sg = Exercice ,
+ name-sg = exercice ,
+ Name-pl = Exercices ,
+ name-pl = exercices ,
+
+type = solution ,
+ gender = f ,
+ Name-sg = Solution ,
+ name-sg = solution ,
+ Name-pl = Solutions ,
+ name-pl = solutions ,
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</dict-french>
+% \end{macrocode}
+%
+%
+%
+% \subsection{Portuguese}
+%
+% \begin{macrocode}
+%<*package>
+\zcDeclareLanguage [ gender = { f , m } ] { portuguese }
+\zcDeclareLanguageAlias { brazilian } { portuguese }
+\zcDeclareLanguageAlias { brazil } { portuguese }
+\zcDeclareLanguageAlias { portuges } { portuguese }
+%</package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*dict-portuguese>
+% \end{macrocode}
+%
+% \begin{macrocode}
+namesep = {\nobreakspace} ,
+pairsep = {~e\nobreakspace} ,
+listsep = {,~} ,
+lastsep = {~e\nobreakspace} ,
+tpairsep = {~e\nobreakspace} ,
+tlistsep = {,~} ,
+tlastsep = {~e\nobreakspace} ,
+notesep = {~} ,
+rangesep = {~a\nobreakspace} ,
+
+type = book ,
+ gender = m ,
+ Name-sg = Livro ,
+ name-sg = livro ,
+ Name-pl = Livros ,
+ name-pl = livros ,
+
+type = part ,
+ gender = f ,
+ Name-sg = Parte ,
+ name-sg = parte ,
+ Name-pl = Partes ,
+ name-pl = partes ,
+
+type = chapter ,
+ gender = m ,
+ Name-sg = Capítulo ,
+ name-sg = capítulo ,
+ Name-pl = Capítulos ,
+ name-pl = capítulos ,
+
+type = section ,
+ gender = f ,
+ Name-sg = Seção ,
+ name-sg = seção ,
+ Name-pl = Seções ,
+ name-pl = seções ,
+
+type = paragraph ,
+ gender = m ,
+ Name-sg = Parágrafo ,
+ name-sg = parágrafo ,
+ Name-pl = Parágrafos ,
+ name-pl = parágrafos ,
+ Name-sg-ab = Par. ,
+ name-sg-ab = par. ,
+ Name-pl-ab = Par. ,
+ name-pl-ab = par. ,
+
+type = appendix ,
+ gender = m ,
+ Name-sg = Apêndice ,
+ name-sg = apêndice ,
+ Name-pl = Apêndices ,
+ name-pl = apêndices ,
+
+type = subappendix ,
+ gender = m ,
+ Name-sg = Apêndice ,
+ name-sg = apêndice ,
+ Name-pl = Apêndices ,
+ name-pl = apêndices ,
+
+type = page ,
+ gender = f ,
+ Name-sg = Página ,
+ name-sg = página ,
+ Name-pl = Páginas ,
+ name-pl = páginas ,
+ name-sg-ab = p. ,
+ name-pl-ab = pp. ,
+ rangesep = {\textendash} ,
+
+type = line ,
+ gender = f ,
+ Name-sg = Linha ,
+ name-sg = linha ,
+ Name-pl = Linhas ,
+ name-pl = linhas ,
+
+type = figure ,
+ gender = f ,
+ Name-sg = Figura ,
+ name-sg = figura ,
+ Name-pl = Figuras ,
+ name-pl = figuras ,
+ Name-sg-ab = Fig. ,
+ name-sg-ab = fig. ,
+ Name-pl-ab = Figs. ,
+ name-pl-ab = figs. ,
+
+type = table ,
+ gender = f ,
+ Name-sg = Tabela ,
+ name-sg = tabela ,
+ Name-pl = Tabelas ,
+ name-pl = tabelas ,
+
+type = item ,
+ gender = m ,
+ Name-sg = Item ,
+ name-sg = item ,
+ Name-pl = Itens ,
+ name-pl = itens ,
+
+type = footnote ,
+ gender = f ,
+ Name-sg = Nota ,
+ name-sg = nota ,
+ Name-pl = Notas ,
+ name-pl = notas ,
+
+type = endnote ,
+ gender = f ,
+ Name-sg = Nota ,
+ name-sg = nota ,
+ Name-pl = Notas ,
+ name-pl = notas ,
+
+type = note ,
+ gender = f ,
+ Name-sg = Nota ,
+ name-sg = nota ,
+ Name-pl = Notas ,
+ name-pl = notas ,
+
+type = equation ,
+ gender = f ,
+ Name-sg = Equação ,
+ name-sg = equação ,
+ Name-pl = Equações ,
+ name-pl = equações ,
+ Name-sg-ab = Eq. ,
+ name-sg-ab = eq. ,
+ Name-pl-ab = Eqs. ,
+ name-pl-ab = eqs. ,
+ refpre = {(} ,
+ refpos = {)} ,
+
+type = theorem ,
+ gender = m ,
+ Name-sg = Teorema ,
+ name-sg = teorema ,
+ Name-pl = Teoremas ,
+ name-pl = teoremas ,
+
+type = lemma ,
+ gender = m ,
+ Name-sg = Lema ,
+ name-sg = lema ,
+ Name-pl = Lemas ,
+ name-pl = lemas ,
+
+type = corollary ,
+ gender = m ,
+ Name-sg = Corolário ,
+ name-sg = corolário ,
+ Name-pl = Corolários ,
+ name-pl = corolários ,
+
+type = proposition ,
+ gender = f ,
+ Name-sg = Proposição ,
+ name-sg = proposição ,
+ Name-pl = Proposições ,
+ name-pl = proposições ,
+
+type = definition ,
+ gender = f ,
+ Name-sg = Definição ,
+ name-sg = definição ,
+ Name-pl = Definições ,
+ name-pl = definições ,
+
+type = proof ,
+ gender = f ,
+ Name-sg = Demonstração ,
+ name-sg = demonstração ,
+ Name-pl = Demonstrações ,
+ name-pl = demonstrações ,
+
+type = result ,
+ gender = m ,
+ Name-sg = Resultado ,
+ name-sg = resultado ,
+ Name-pl = Resultados ,
+ name-pl = resultados ,
+
+type = remark ,
+ gender = f ,
+ Name-sg = Observação ,
+ name-sg = observação ,
+ Name-pl = Observações ,
+ name-pl = observações ,
+
+type = example ,
+ gender = m ,
+ Name-sg = Exemplo ,
+ name-sg = exemplo ,
+ Name-pl = Exemplos ,
+ name-pl = exemplos ,
+
+type = algorithm ,
+ gender = m ,
+ Name-sg = Algoritmo ,
+ name-sg = algoritmo ,
+ Name-pl = Algoritmos ,
+ name-pl = algoritmos ,
+
+type = listing ,
+ gender = f ,
+ Name-sg = Listagem ,
+ name-sg = listagem ,
+ Name-pl = Listagens ,
+ name-pl = listagens ,
+
+type = exercise ,
+ gender = m ,
+ Name-sg = Exercício ,
+ name-sg = exercício ,
+ Name-pl = Exercícios ,
+ name-pl = exercícios ,
+
+type = solution ,
+ gender = f ,
+ Name-sg = Solução ,
+ name-sg = solução ,
+ Name-pl = Soluções ,
+ name-pl = soluções ,
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</dict-portuguese>
+% \end{macrocode}
+%
+%
+%
+% \subsection{Spanish}
+%
+% \begin{macrocode}
+%<*package>
+\zcDeclareLanguage [ gender = { f , m } ] { spanish }
+%</package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*dict-spanish>
+% \end{macrocode}
+%
+% \begin{macrocode}
+namesep = {\nobreakspace} ,
+pairsep = {~y\nobreakspace} ,
+listsep = {,~} ,
+lastsep = {~y\nobreakspace} ,
+tpairsep = {~y\nobreakspace} ,
+tlistsep = {,~} ,
+tlastsep = {~y\nobreakspace} ,
+notesep = {~} ,
+rangesep = {~a\nobreakspace} ,
+
+type = book ,
+ gender = m ,
+ Name-sg = Libro ,
+ name-sg = libro ,
+ Name-pl = Libros ,
+ name-pl = libros ,
+
+type = part ,
+ gender = f ,
+ Name-sg = Parte ,
+ name-sg = parte ,
+ Name-pl = Partes ,
+ name-pl = partes ,
+
+type = chapter ,
+ gender = m ,
+ Name-sg = Capítulo ,
+ name-sg = capítulo ,
+ Name-pl = Capítulos ,
+ name-pl = capítulos ,
+
+type = section ,
+ gender = f ,
+ Name-sg = Sección ,
+ name-sg = sección ,
+ Name-pl = Secciones ,
+ name-pl = secciones ,
+
+type = paragraph ,
+ gender = m ,
+ Name-sg = Párrafo ,
+ name-sg = párrafo ,
+ Name-pl = Párrafos ,
+ name-pl = párrafos ,
+
+type = appendix ,
+ gender = m ,
+ Name-sg = Apéndice ,
+ name-sg = apéndice ,
+ Name-pl = Apéndices ,
+ name-pl = apéndices ,
+
+type = subappendix ,
+ gender = m ,
+ Name-sg = Apéndice ,
+ name-sg = apéndice ,
+ Name-pl = Apéndices ,
+ name-pl = apéndices ,
+
+type = page ,
+ gender = f ,
+ Name-sg = Página ,
+ name-sg = página ,
+ Name-pl = Páginas ,
+ name-pl = páginas ,
+ rangesep = {\textendash} ,
+
+type = line ,
+ gender = f ,
+ Name-sg = Línea ,
+ name-sg = línea ,
+ Name-pl = Líneas ,
+ name-pl = líneas ,
+
+type = figure ,
+ gender = f ,
+ Name-sg = Figura ,
+ name-sg = figura ,
+ Name-pl = Figuras ,
+ name-pl = figuras ,
+
+type = table ,
+ gender = m ,
+ Name-sg = Cuadro ,
+ name-sg = cuadro ,
+ Name-pl = Cuadros ,
+ name-pl = cuadros ,
+
+type = item ,
+ gender = m ,
+ Name-sg = Punto ,
+ name-sg = punto ,
+ Name-pl = Puntos ,
+ name-pl = puntos ,
+
+type = footnote ,
+ gender = f ,
+ Name-sg = Nota ,
+ name-sg = nota ,
+ Name-pl = Notas ,
+ name-pl = notas ,
+
+type = endnote ,
+ gender = f ,
+ Name-sg = Nota ,
+ name-sg = nota ,
+ Name-pl = Notas ,
+ name-pl = notas ,
+
+type = note ,
+ gender = f ,
+ Name-sg = Nota ,
+ name-sg = nota ,
+ Name-pl = Notas ,
+ name-pl = notas ,
+
+type = equation ,
+ gender = f ,
+ Name-sg = Ecuación ,
+ name-sg = ecuación ,
+ Name-pl = Ecuaciones ,
+ name-pl = ecuaciones ,
+ refpre = {(} ,
+ refpos = {)} ,
+
+type = theorem ,
+ gender = m ,
+ Name-sg = Teorema ,
+ name-sg = teorema ,
+ Name-pl = Teoremas ,
+ name-pl = teoremas ,
+
+type = lemma ,
+ gender = m ,
+ Name-sg = Lema ,
+ name-sg = lema ,
+ Name-pl = Lemas ,
+ name-pl = lemas ,
+
+type = corollary ,
+ gender = m ,
+ Name-sg = Corolario ,
+ name-sg = corolario ,
+ Name-pl = Corolarios ,
+ name-pl = corolarios ,
+
+type = proposition ,
+ gender = f ,
+ Name-sg = Proposición ,
+ name-sg = proposición ,
+ Name-pl = Proposiciones ,
+ name-pl = proposiciones ,
+
+type = definition ,
+ gender = f ,
+ Name-sg = Definición ,
+ name-sg = definición ,
+ Name-pl = Definiciones ,
+ name-pl = definiciones ,
+
+type = proof ,
+ gender = f ,
+ Name-sg = Demostración ,
+ name-sg = demostración ,
+ Name-pl = Demostraciones ,
+ name-pl = demostraciones ,
+
+type = result ,
+ gender = m ,
+ Name-sg = Resultado ,
+ name-sg = resultado ,
+ Name-pl = Resultados ,
+ name-pl = resultados ,
+
+type = remark ,
+ gender = f ,
+ Name-sg = Observación ,
+ name-sg = observación ,
+ Name-pl = Observaciones ,
+ name-pl = observaciones ,
+
+type = example ,
+ gender = m ,
+ Name-sg = Ejemplo ,
+ name-sg = ejemplo ,
+ Name-pl = Ejemplos ,
+ name-pl = ejemplos ,
+
+type = algorithm ,
+ gender = m ,
+ Name-sg = Algoritmo ,
+ name-sg = algoritmo ,
+ Name-pl = Algoritmos ,
+ name-pl = algoritmos ,
+
+type = listing ,
+ gender = m ,
+ Name-sg = Listado ,
+ name-sg = listado ,
+ Name-pl = Listados ,
+ name-pl = listados ,
+
+type = exercise ,
+ gender = m ,
+ Name-sg = Ejercicio ,
+ name-sg = ejercicio ,
+ Name-pl = Ejercicios ,
+ name-pl = ejercicios ,
+
+type = solution ,
+ gender = f ,
+ Name-sg = Solución ,
+ name-sg = solución ,
+ Name-pl = Soluciones ,
+ name-pl = soluciones ,
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</dict-spanish>
+% \end{macrocode}
+%
+%
+% \PrintIndex
+%
+%
diff --git a/Master/texmf-dist/source/latex/zref-clever/zref-clever.ins b/Master/texmf-dist/source/latex/zref-clever/zref-clever.ins
new file mode 100644
index 00000000000..71259f4751f
--- /dev/null
+++ b/Master/texmf-dist/source/latex/zref-clever/zref-clever.ins
@@ -0,0 +1,99 @@
+% \iffalse meta-comment
+%
+% File: zref-clever.ins
+%
+% This file is part of the LaTeX package "zref-clever".
+%
+% 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-clever.dtx,
+% zref-clever.ins,
+% zref-clever.tex,
+% zref-clever-code.tex,
+% and the derived files listed in MANIFEST.md.
+%
+% 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-clever
+%
+% 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-clever".
+
+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-clever.dtx,
+ zref-clever.ins,
+ zref-clever.tex,
+ zref-clever-code.tex,
+and the derived files listed in MANIFEST.md.
+
+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-clever
+
+for those people who are interested.
+
+-----------------------------------------------------------------------
+
+\endpreamble
+
+\postamble
+\endpostamble
+
+\generate{\file{zref-clever.sty}{\from{zref-clever.dtx}{package}}}
+\generate{\file{zref-clever-english.dict}{\from{zref-clever.dtx}{dict-english}}}
+\generate{\file{zref-clever-german.dict}{\from{zref-clever.dtx}{dict-german}}}
+\generate{\file{zref-clever-french.dict}{\from{zref-clever.dtx}{dict-french}}}
+\generate{\file{zref-clever-portuguese.dict}{\from{zref-clever.dtx}{dict-portuguese}}}
+\generate{\file{zref-clever-spanish.dict}{\from{zref-clever.dtx}{dict-spanish}}}
+
+\endbatchfile
diff --git a/Master/texmf-dist/tex/latex/zref-clever/zref-clever-english.dict b/Master/texmf-dist/tex/latex/zref-clever/zref-clever-english.dict
new file mode 100644
index 00000000000..2b7530e24ae
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/zref-clever/zref-clever-english.dict
@@ -0,0 +1,247 @@
+%%
+%% This is file `zref-clever-english.dict',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% zref-clever.dtx (with options: `dict-english')
+%%
+%% This file was generated from file(s) of the LaTeX package "zref-clever".
+%%
+%% 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-clever.dtx,
+%% zref-clever.ins,
+%% zref-clever.tex,
+%% zref-clever-code.tex,
+%% and the derived files listed in MANIFEST.md.
+%%
+%% 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-clever
+%%
+%% for those people who are interested.
+%%
+%% -----------------------------------------------------------------------
+%%
+namesep = {\nobreakspace} ,
+pairsep = {~and\nobreakspace} ,
+listsep = {,~} ,
+lastsep = {~and\nobreakspace} ,
+tpairsep = {~and\nobreakspace} ,
+tlistsep = {,~} ,
+tlastsep = {,~and\nobreakspace} ,
+notesep = {~} ,
+rangesep = {~to\nobreakspace} ,
+
+type = book ,
+ Name-sg = Book ,
+ name-sg = book ,
+ Name-pl = Books ,
+ name-pl = books ,
+
+type = part ,
+ Name-sg = Part ,
+ name-sg = part ,
+ Name-pl = Parts ,
+ name-pl = parts ,
+
+type = chapter ,
+ Name-sg = Chapter ,
+ name-sg = chapter ,
+ Name-pl = Chapters ,
+ name-pl = chapters ,
+
+type = section ,
+ Name-sg = Section ,
+ name-sg = section ,
+ Name-pl = Sections ,
+ name-pl = sections ,
+
+type = paragraph ,
+ Name-sg = Paragraph ,
+ name-sg = paragraph ,
+ Name-pl = Paragraphs ,
+ name-pl = paragraphs ,
+ Name-sg-ab = Par. ,
+ name-sg-ab = par. ,
+ Name-pl-ab = Par. ,
+ name-pl-ab = par. ,
+
+type = appendix ,
+ Name-sg = Appendix ,
+ name-sg = appendix ,
+ Name-pl = Appendices ,
+ name-pl = appendices ,
+
+type = subappendix ,
+ Name-sg = Appendix ,
+ name-sg = appendix ,
+ Name-pl = Appendices ,
+ name-pl = appendices ,
+
+type = page ,
+ Name-sg = Page ,
+ name-sg = page ,
+ Name-pl = Pages ,
+ name-pl = pages ,
+ name-sg-ab = p. ,
+ name-pl-ab = pp. ,
+ rangesep = {\textendash} ,
+
+type = line ,
+ Name-sg = Line ,
+ name-sg = line ,
+ Name-pl = Lines ,
+ name-pl = lines ,
+
+type = figure ,
+ Name-sg = Figure ,
+ name-sg = figure ,
+ Name-pl = Figures ,
+ name-pl = figures ,
+ Name-sg-ab = Fig. ,
+ name-sg-ab = fig. ,
+ Name-pl-ab = Figs. ,
+ name-pl-ab = figs. ,
+
+type = table ,
+ Name-sg = Table ,
+ name-sg = table ,
+ Name-pl = Tables ,
+ name-pl = tables ,
+
+type = item ,
+ Name-sg = Item ,
+ name-sg = item ,
+ Name-pl = Items ,
+ name-pl = items ,
+
+type = footnote ,
+ Name-sg = Footnote ,
+ name-sg = footnote ,
+ Name-pl = Footnotes ,
+ name-pl = footnotes ,
+
+type = endnote ,
+ Name-sg = Note ,
+ name-sg = note ,
+ Name-pl = Notes ,
+ name-pl = notes ,
+
+type = note ,
+ Name-sg = Note ,
+ name-sg = note ,
+ Name-pl = Notes ,
+ name-pl = notes ,
+
+type = equation ,
+ Name-sg = Equation ,
+ name-sg = equation ,
+ Name-pl = Equations ,
+ name-pl = equations ,
+ Name-sg-ab = Eq. ,
+ name-sg-ab = eq. ,
+ Name-pl-ab = Eqs. ,
+ name-pl-ab = eqs. ,
+ refpre = {(} ,
+ refpos = {)} ,
+
+type = theorem ,
+ Name-sg = Theorem ,
+ name-sg = theorem ,
+ Name-pl = Theorems ,
+ name-pl = theorems ,
+
+type = lemma ,
+ Name-sg = Lemma ,
+ name-sg = lemma ,
+ Name-pl = Lemmas ,
+ name-pl = lemmas ,
+
+type = corollary ,
+ Name-sg = Corollary ,
+ name-sg = corollary ,
+ Name-pl = Corollaries ,
+ name-pl = corollaries ,
+
+type = proposition ,
+ Name-sg = Proposition ,
+ name-sg = proposition ,
+ Name-pl = Propositions ,
+ name-pl = propositions ,
+
+type = definition ,
+ Name-sg = Definition ,
+ name-sg = definition ,
+ Name-pl = Definitions ,
+ name-pl = definitions ,
+
+type = proof ,
+ Name-sg = Proof ,
+ name-sg = proof ,
+ Name-pl = Proofs ,
+ name-pl = proofs ,
+
+type = result ,
+ Name-sg = Result ,
+ name-sg = result ,
+ Name-pl = Results ,
+ name-pl = results ,
+
+type = remark ,
+ Name-sg = Remark ,
+ name-sg = remark ,
+ Name-pl = Remarks ,
+ name-pl = remarks ,
+
+type = example ,
+ Name-sg = Example ,
+ name-sg = example ,
+ Name-pl = Examples ,
+ name-pl = examples ,
+
+type = algorithm ,
+ Name-sg = Algorithm ,
+ name-sg = algorithm ,
+ Name-pl = Algorithms ,
+ name-pl = algorithms ,
+
+type = listing ,
+ Name-sg = Listing ,
+ name-sg = listing ,
+ Name-pl = Listings ,
+ name-pl = listings ,
+
+type = exercise ,
+ Name-sg = Exercise ,
+ name-sg = exercise ,
+ Name-pl = Exercises ,
+ name-pl = exercises ,
+
+type = solution ,
+ Name-sg = Solution ,
+ name-sg = solution ,
+ Name-pl = Solutions ,
+ name-pl = solutions ,
+%%
+%%
+%% End of file `zref-clever-english.dict'.
diff --git a/Master/texmf-dist/tex/latex/zref-clever/zref-clever-french.dict b/Master/texmf-dist/tex/latex/zref-clever/zref-clever-french.dict
new file mode 100644
index 00000000000..9de1ba4d4b0
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/zref-clever/zref-clever-french.dict
@@ -0,0 +1,262 @@
+%%
+%% This is file `zref-clever-french.dict',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% zref-clever.dtx (with options: `dict-french')
+%%
+%% This file was generated from file(s) of the LaTeX package "zref-clever".
+%%
+%% 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-clever.dtx,
+%% zref-clever.ins,
+%% zref-clever.tex,
+%% zref-clever-code.tex,
+%% and the derived files listed in MANIFEST.md.
+%%
+%% 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-clever
+%%
+%% for those people who are interested.
+%%
+%% -----------------------------------------------------------------------
+%%
+namesep = {\nobreakspace} ,
+pairsep = {~et\nobreakspace} ,
+listsep = {,~} ,
+lastsep = {~et\nobreakspace} ,
+tpairsep = {~et\nobreakspace} ,
+tlistsep = {,~} ,
+tlastsep = {~et\nobreakspace} ,
+notesep = {~} ,
+rangesep = {~à\nobreakspace} ,
+
+type = book ,
+ gender = m ,
+ Name-sg = Livre ,
+ name-sg = livre ,
+ Name-pl = Livres ,
+ name-pl = livres ,
+
+type = part ,
+ gender = f ,
+ Name-sg = Partie ,
+ name-sg = partie ,
+ Name-pl = Parties ,
+ name-pl = parties ,
+
+type = chapter ,
+ gender = m ,
+ Name-sg = Chapitre ,
+ name-sg = chapitre ,
+ Name-pl = Chapitres ,
+ name-pl = chapitres ,
+
+type = section ,
+ gender = f ,
+ Name-sg = Section ,
+ name-sg = section ,
+ Name-pl = Sections ,
+ name-pl = sections ,
+
+type = paragraph ,
+ gender = m ,
+ Name-sg = Paragraphe ,
+ name-sg = paragraphe ,
+ Name-pl = Paragraphes ,
+ name-pl = paragraphes ,
+
+type = appendix ,
+ gender = f ,
+ Name-sg = Annexe ,
+ name-sg = annexe ,
+ Name-pl = Annexes ,
+ name-pl = annexes ,
+
+type = subappendix ,
+ gender = f ,
+ Name-sg = Annexe ,
+ name-sg = annexe ,
+ Name-pl = Annexes ,
+ name-pl = annexes ,
+
+type = page ,
+ gender = f ,
+ Name-sg = Page ,
+ name-sg = page ,
+ Name-pl = Pages ,
+ name-pl = pages ,
+ rangesep = {\textendash} ,
+
+type = line ,
+ gender = f ,
+ Name-sg = Ligne ,
+ name-sg = ligne ,
+ Name-pl = Lignes ,
+ name-pl = lignes ,
+
+type = figure ,
+ gender = f ,
+ Name-sg = Figure ,
+ name-sg = figure ,
+ Name-pl = Figures ,
+ name-pl = figures ,
+
+type = table ,
+ gender = f ,
+ Name-sg = Table ,
+ name-sg = table ,
+ Name-pl = Tables ,
+ name-pl = tables ,
+
+type = item ,
+ gender = m ,
+ Name-sg = Point ,
+ name-sg = point ,
+ Name-pl = Points ,
+ name-pl = points ,
+
+type = footnote ,
+ gender = f ,
+ Name-sg = Note ,
+ name-sg = note ,
+ Name-pl = Notes ,
+ name-pl = notes ,
+
+type = endnote ,
+ gender = f ,
+ Name-sg = Note ,
+ name-sg = note ,
+ Name-pl = Notes ,
+ name-pl = notes ,
+
+type = note ,
+ gender = f ,
+ Name-sg = Note ,
+ name-sg = note ,
+ Name-pl = Notes ,
+ name-pl = notes ,
+
+type = equation ,
+ gender = f ,
+ Name-sg = Équation ,
+ name-sg = équation ,
+ Name-pl = Équations ,
+ name-pl = équations ,
+ refpre = {(} ,
+ refpos = {)} ,
+
+type = theorem ,
+ gender = m ,
+ Name-sg = Théorème ,
+ name-sg = théorème ,
+ Name-pl = Théorèmes ,
+ name-pl = théorèmes ,
+
+type = lemma ,
+ gender = m ,
+ Name-sg = Lemme ,
+ name-sg = lemme ,
+ Name-pl = Lemmes ,
+ name-pl = lemmes ,
+
+type = corollary ,
+ gender = m ,
+ Name-sg = Corollaire ,
+ name-sg = corollaire ,
+ Name-pl = Corollaires ,
+ name-pl = corollaires ,
+
+type = proposition ,
+ gender = f ,
+ Name-sg = Proposition ,
+ name-sg = proposition ,
+ Name-pl = Propositions ,
+ name-pl = propositions ,
+
+type = definition ,
+ gender = f ,
+ Name-sg = Définition ,
+ name-sg = définition ,
+ Name-pl = Définitions ,
+ name-pl = définitions ,
+
+type = proof ,
+ gender = f ,
+ Name-sg = Démonstration ,
+ name-sg = démonstration ,
+ Name-pl = Démonstrations ,
+ name-pl = démonstrations ,
+
+type = result ,
+ gender = m ,
+ Name-sg = Résultat ,
+ name-sg = résultat ,
+ Name-pl = Résultats ,
+ name-pl = résultats ,
+
+type = remark ,
+ gender = f ,
+ Name-sg = Remarque ,
+ name-sg = remarque ,
+ Name-pl = Remarques ,
+ name-pl = remarques ,
+
+type = example ,
+ gender = m ,
+ Name-sg = Exemple ,
+ name-sg = exemple ,
+ Name-pl = Exemples ,
+ name-pl = exemples ,
+
+type = algorithm ,
+ gender = m ,
+ Name-sg = Algorithme ,
+ name-sg = algorithme ,
+ Name-pl = Algorithmes ,
+ name-pl = algorithmes ,
+
+type = listing ,
+ gender = f ,
+ Name-sg = Liste ,
+ name-sg = liste ,
+ Name-pl = Listes ,
+ name-pl = listes ,
+
+type = exercise ,
+ gender = m ,
+ Name-sg = Exercice ,
+ name-sg = exercice ,
+ Name-pl = Exercices ,
+ name-pl = exercices ,
+
+type = solution ,
+ gender = f ,
+ Name-sg = Solution ,
+ name-sg = solution ,
+ Name-pl = Solutions ,
+ name-pl = solutions ,
+%%
+%%
+%% End of file `zref-clever-french.dict'.
diff --git a/Master/texmf-dist/tex/latex/zref-clever/zref-clever-german.dict b/Master/texmf-dist/tex/latex/zref-clever/zref-clever-german.dict
new file mode 100644
index 00000000000..502e5d29a62
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/zref-clever/zref-clever-german.dict
@@ -0,0 +1,502 @@
+%%
+%% This is file `zref-clever-german.dict',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% zref-clever.dtx (with options: `dict-german')
+%%
+%% This file was generated from file(s) of the LaTeX package "zref-clever".
+%%
+%% 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-clever.dtx,
+%% zref-clever.ins,
+%% zref-clever.tex,
+%% zref-clever-code.tex,
+%% and the derived files listed in MANIFEST.md.
+%%
+%% 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-clever
+%%
+%% for those people who are interested.
+%%
+%% -----------------------------------------------------------------------
+%%
+namesep = {\nobreakspace} ,
+pairsep = {~und\nobreakspace} ,
+listsep = {,~} ,
+lastsep = {~und\nobreakspace} ,
+tpairsep = {~und\nobreakspace} ,
+tlistsep = {,~} ,
+tlastsep = {~und\nobreakspace} ,
+notesep = {~} ,
+rangesep = {~bis\nobreakspace} ,
+
+type = book ,
+ gender = n ,
+ case = N ,
+ Name-sg = Buch ,
+ Name-pl = Bücher ,
+ case = A ,
+ Name-sg = Buch ,
+ Name-pl = Bücher ,
+ case = D ,
+ Name-sg = Buch ,
+ Name-pl = Büchern ,
+ case = G ,
+ Name-sg = Buches ,
+ Name-pl = Bücher ,
+
+type = part ,
+ gender = m ,
+ case = N ,
+ Name-sg = Teil ,
+ Name-pl = Teile ,
+ case = A ,
+ Name-sg = Teil ,
+ Name-pl = Teile ,
+ case = D ,
+ Name-sg = Teil ,
+ Name-pl = Teilen ,
+ case = G ,
+ Name-sg = Teiles ,
+ Name-pl = Teile ,
+
+type = chapter ,
+ gender = n ,
+ case = N ,
+ Name-sg = Kapitel ,
+ Name-pl = Kapitel ,
+ case = A ,
+ Name-sg = Kapitel ,
+ Name-pl = Kapitel ,
+ case = D ,
+ Name-sg = Kapitel ,
+ Name-pl = Kapiteln ,
+ case = G ,
+ Name-sg = Kapitels ,
+ Name-pl = Kapitel ,
+
+type = section ,
+ gender = m ,
+ case = N ,
+ Name-sg = Abschnitt ,
+ Name-pl = Abschnitte ,
+ case = A ,
+ Name-sg = Abschnitt ,
+ Name-pl = Abschnitte ,
+ case = D ,
+ Name-sg = Abschnitt ,
+ Name-pl = Abschnitten ,
+ case = G ,
+ Name-sg = Abschnitts ,
+ Name-pl = Abschnitte ,
+
+type = paragraph ,
+ gender = m ,
+ case = N ,
+ Name-sg = Absatz ,
+ Name-pl = Absätze ,
+ case = A ,
+ Name-sg = Absatz ,
+ Name-pl = Absätze ,
+ case = D ,
+ Name-sg = Absatz ,
+ Name-pl = Absätzen ,
+ case = G ,
+ Name-sg = Absatzes ,
+ Name-pl = Absätze ,
+
+type = appendix ,
+ gender = m ,
+ case = N ,
+ Name-sg = Anhang ,
+ Name-pl = Anhänge ,
+ case = A ,
+ Name-sg = Anhang ,
+ Name-pl = Anhänge ,
+ case = D ,
+ Name-sg = Anhang ,
+ Name-pl = Anhängen ,
+ case = G ,
+ Name-sg = Anhangs ,
+ Name-pl = Anhänge ,
+
+type = subappendix ,
+ gender = m ,
+ case = N ,
+ Name-sg = Anhang ,
+ Name-pl = Anhänge ,
+ case = A ,
+ Name-sg = Anhang ,
+ Name-pl = Anhänge ,
+ case = D ,
+ Name-sg = Anhang ,
+ Name-pl = Anhängen ,
+ case = G ,
+ Name-sg = Anhangs ,
+ Name-pl = Anhänge ,
+
+type = page ,
+ gender = f ,
+ case = N ,
+ Name-sg = Seite ,
+ Name-pl = Seiten ,
+ case = A ,
+ Name-sg = Seite ,
+ Name-pl = Seiten ,
+ case = D ,
+ Name-sg = Seite ,
+ Name-pl = Seiten ,
+ case = G ,
+ Name-sg = Seite ,
+ Name-pl = Seiten ,
+ rangesep = {\textendash} ,
+
+type = line ,
+ gender = f ,
+ case = N ,
+ Name-sg = Zeile ,
+ Name-pl = Zeilen ,
+ case = A ,
+ Name-sg = Zeile ,
+ Name-pl = Zeilen ,
+ case = D ,
+ Name-sg = Zeile ,
+ Name-pl = Zeilen ,
+ case = G ,
+ Name-sg = Zeile ,
+ Name-pl = Zeilen ,
+
+type = figure ,
+ gender = f ,
+ case = N ,
+ Name-sg = Abbildung ,
+ Name-pl = Abbildungen ,
+ Name-sg-ab = Abb. ,
+ Name-pl-ab = Abb. ,
+ case = A ,
+ Name-sg = Abbildung ,
+ Name-pl = Abbildungen ,
+ Name-sg-ab = Abb. ,
+ Name-pl-ab = Abb. ,
+ case = D ,
+ Name-sg = Abbildung ,
+ Name-pl = Abbildungen ,
+ Name-sg-ab = Abb. ,
+ Name-pl-ab = Abb. ,
+ case = G ,
+ Name-sg = Abbildung ,
+ Name-pl = Abbildungen ,
+ Name-sg-ab = Abb. ,
+ Name-pl-ab = Abb. ,
+
+type = table ,
+ gender = f ,
+ case = N ,
+ Name-sg = Tabelle ,
+ Name-pl = Tabellen ,
+ case = A ,
+ Name-sg = Tabelle ,
+ Name-pl = Tabellen ,
+ case = D ,
+ Name-sg = Tabelle ,
+ Name-pl = Tabellen ,
+ case = G ,
+ Name-sg = Tabelle ,
+ Name-pl = Tabellen ,
+
+type = item ,
+ gender = m ,
+ case = N ,
+ Name-sg = Punkt ,
+ Name-pl = Punkte ,
+ case = A ,
+ Name-sg = Punkt ,
+ Name-pl = Punkte ,
+ case = D ,
+ Name-sg = Punkt ,
+ Name-pl = Punkten ,
+ case = G ,
+ Name-sg = Punktes ,
+ Name-pl = Punkte ,
+
+type = footnote ,
+ gender = f ,
+ case = N ,
+ Name-sg = Fußnote ,
+ Name-pl = Fußnoten ,
+ case = A ,
+ Name-sg = Fußnote ,
+ Name-pl = Fußnoten ,
+ case = D ,
+ Name-sg = Fußnote ,
+ Name-pl = Fußnoten ,
+ case = G ,
+ Name-sg = Fußnote ,
+ Name-pl = Fußnoten ,
+
+type = endnote ,
+ gender = f ,
+ case = N ,
+ Name-sg = Endnote ,
+ Name-pl = Endnoten ,
+ case = A ,
+ Name-sg = Endnote ,
+ Name-pl = Endnoten ,
+ case = D ,
+ Name-sg = Endnote ,
+ Name-pl = Endnoten ,
+ case = G ,
+ Name-sg = Endnote ,
+ Name-pl = Endnoten ,
+
+type = note ,
+ gender = f ,
+ case = N ,
+ Name-sg = Anmerkung ,
+ Name-pl = Anmerkungen ,
+ case = A ,
+ Name-sg = Anmerkung ,
+ Name-pl = Anmerkungen ,
+ case = D ,
+ Name-sg = Anmerkung ,
+ Name-pl = Anmerkungen ,
+ case = G ,
+ Name-sg = Anmerkung ,
+ Name-pl = Anmerkungen ,
+
+type = equation ,
+ gender = f ,
+ case = N ,
+ Name-sg = Gleichung ,
+ Name-pl = Gleichungen ,
+ case = A ,
+ Name-sg = Gleichung ,
+ Name-pl = Gleichungen ,
+ case = D ,
+ Name-sg = Gleichung ,
+ Name-pl = Gleichungen ,
+ case = G ,
+ Name-sg = Gleichung ,
+ Name-pl = Gleichungen ,
+ refpre = {(} ,
+ refpos = {)} ,
+
+type = theorem ,
+ gender = n ,
+ case = N ,
+ Name-sg = Theorem ,
+ Name-pl = Theoreme ,
+ case = A ,
+ Name-sg = Theorem ,
+ Name-pl = Theoreme ,
+ case = D ,
+ Name-sg = Theorem ,
+ Name-pl = Theoremen ,
+ case = G ,
+ Name-sg = Theorems ,
+ Name-pl = Theoreme ,
+
+type = lemma ,
+ gender = n ,
+ case = N ,
+ Name-sg = Lemma ,
+ Name-pl = Lemmata ,
+ case = A ,
+ Name-sg = Lemma ,
+ Name-pl = Lemmata ,
+ case = D ,
+ Name-sg = Lemma ,
+ Name-pl = Lemmata ,
+ case = G ,
+ Name-sg = Lemmas ,
+ Name-pl = Lemmata ,
+
+type = corollary ,
+ gender = n ,
+ case = N ,
+ Name-sg = Korollar ,
+ Name-pl = Korollare ,
+ case = A ,
+ Name-sg = Korollar ,
+ Name-pl = Korollare ,
+ case = D ,
+ Name-sg = Korollar ,
+ Name-pl = Korollaren ,
+ case = G ,
+ Name-sg = Korollars ,
+ Name-pl = Korollare ,
+
+type = proposition ,
+ gender = m ,
+ case = N ,
+ Name-sg = Satz ,
+ Name-pl = Sätze ,
+ case = A ,
+ Name-sg = Satz ,
+ Name-pl = Sätze ,
+ case = D ,
+ Name-sg = Satz ,
+ Name-pl = Sätzen ,
+ case = G ,
+ Name-sg = Satzes ,
+ Name-pl = Sätze ,
+
+type = definition ,
+ gender = f ,
+ case = N ,
+ Name-sg = Definition ,
+ Name-pl = Definitionen ,
+ case = A ,
+ Name-sg = Definition ,
+ Name-pl = Definitionen ,
+ case = D ,
+ Name-sg = Definition ,
+ Name-pl = Definitionen ,
+ case = G ,
+ Name-sg = Definition ,
+ Name-pl = Definitionen ,
+
+type = proof ,
+ gender = m ,
+ case = N ,
+ Name-sg = Beweis ,
+ Name-pl = Beweise ,
+ case = A ,
+ Name-sg = Beweis ,
+ Name-pl = Beweise ,
+ case = D ,
+ Name-sg = Beweis ,
+ Name-pl = Beweisen ,
+ case = G ,
+ Name-sg = Beweises ,
+ Name-pl = Beweise ,
+
+type = result ,
+ gender = n ,
+ case = N ,
+ Name-sg = Ergebnis ,
+ Name-pl = Ergebnisse ,
+ case = A ,
+ Name-sg = Ergebnis ,
+ Name-pl = Ergebnisse ,
+ case = D ,
+ Name-sg = Ergebnis ,
+ Name-pl = Ergebnissen ,
+ case = G ,
+ Name-sg = Ergebnisses ,
+ Name-pl = Ergebnisse ,
+
+type = remark ,
+ gender = f ,
+ case = N ,
+ Name-sg = Bemerkung ,
+ Name-pl = Bemerkungen ,
+ case = A ,
+ Name-sg = Bemerkung ,
+ Name-pl = Bemerkungen ,
+ case = D ,
+ Name-sg = Bemerkung ,
+ Name-pl = Bemerkungen ,
+ case = G ,
+ Name-sg = Bemerkung ,
+ Name-pl = Bemerkungen ,
+
+type = example ,
+ gender = n ,
+ case = N ,
+ Name-sg = Beispiel ,
+ Name-pl = Beispiele ,
+ case = A ,
+ Name-sg = Beispiel ,
+ Name-pl = Beispiele ,
+ case = D ,
+ Name-sg = Beispiel ,
+ Name-pl = Beispielen ,
+ case = G ,
+ Name-sg = Beispiels ,
+ Name-pl = Beispiele ,
+
+type = algorithm ,
+ gender = m ,
+ case = N ,
+ Name-sg = Algorithmus ,
+ Name-pl = Algorithmen ,
+ case = A ,
+ Name-sg = Algorithmus ,
+ Name-pl = Algorithmen ,
+ case = D ,
+ Name-sg = Algorithmus ,
+ Name-pl = Algorithmen ,
+ case = G ,
+ Name-sg = Algorithmus ,
+ Name-pl = Algorithmen ,
+
+type = listing ,
+ gender = n ,
+ case = N ,
+ Name-sg = Listing ,
+ Name-pl = Listings ,
+ case = A ,
+ Name-sg = Listing ,
+ Name-pl = Listings ,
+ case = D ,
+ Name-sg = Listing ,
+ Name-pl = Listings ,
+ case = G ,
+ Name-sg = Listings ,
+ Name-pl = Listings ,
+
+type = exercise ,
+ gender = f ,
+ case = N ,
+ Name-sg = Übungsaufgabe ,
+ Name-pl = Übungsaufgaben ,
+ case = A ,
+ Name-sg = Übungsaufgabe ,
+ Name-pl = Übungsaufgaben ,
+ case = D ,
+ Name-sg = Übungsaufgabe ,
+ Name-pl = Übungsaufgaben ,
+ case = G ,
+ Name-sg = Übungsaufgabe ,
+ Name-pl = Übungsaufgaben ,
+
+type = solution ,
+ gender = f ,
+ case = N ,
+ Name-sg = Lösung ,
+ Name-pl = Lösungen ,
+ case = A ,
+ Name-sg = Lösung ,
+ Name-pl = Lösungen ,
+ case = D ,
+ Name-sg = Lösung ,
+ Name-pl = Lösungen ,
+ case = G ,
+ Name-sg = Lösung ,
+ Name-pl = Lösungen ,
+%%
+%%
+%% End of file `zref-clever-german.dict'.
diff --git a/Master/texmf-dist/tex/latex/zref-clever/zref-clever-portuguese.dict b/Master/texmf-dist/tex/latex/zref-clever/zref-clever-portuguese.dict
new file mode 100644
index 00000000000..180a729f527
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/zref-clever/zref-clever-portuguese.dict
@@ -0,0 +1,276 @@
+%%
+%% This is file `zref-clever-portuguese.dict',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% zref-clever.dtx (with options: `dict-portuguese')
+%%
+%% This file was generated from file(s) of the LaTeX package "zref-clever".
+%%
+%% 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-clever.dtx,
+%% zref-clever.ins,
+%% zref-clever.tex,
+%% zref-clever-code.tex,
+%% and the derived files listed in MANIFEST.md.
+%%
+%% 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-clever
+%%
+%% for those people who are interested.
+%%
+%% -----------------------------------------------------------------------
+%%
+namesep = {\nobreakspace} ,
+pairsep = {~e\nobreakspace} ,
+listsep = {,~} ,
+lastsep = {~e\nobreakspace} ,
+tpairsep = {~e\nobreakspace} ,
+tlistsep = {,~} ,
+tlastsep = {~e\nobreakspace} ,
+notesep = {~} ,
+rangesep = {~a\nobreakspace} ,
+
+type = book ,
+ gender = m ,
+ Name-sg = Livro ,
+ name-sg = livro ,
+ Name-pl = Livros ,
+ name-pl = livros ,
+
+type = part ,
+ gender = f ,
+ Name-sg = Parte ,
+ name-sg = parte ,
+ Name-pl = Partes ,
+ name-pl = partes ,
+
+type = chapter ,
+ gender = m ,
+ Name-sg = Capítulo ,
+ name-sg = capítulo ,
+ Name-pl = Capítulos ,
+ name-pl = capítulos ,
+
+type = section ,
+ gender = f ,
+ Name-sg = Seção ,
+ name-sg = seção ,
+ Name-pl = Seções ,
+ name-pl = seções ,
+
+type = paragraph ,
+ gender = m ,
+ Name-sg = Parágrafo ,
+ name-sg = parágrafo ,
+ Name-pl = Parágrafos ,
+ name-pl = parágrafos ,
+ Name-sg-ab = Par. ,
+ name-sg-ab = par. ,
+ Name-pl-ab = Par. ,
+ name-pl-ab = par. ,
+
+type = appendix ,
+ gender = m ,
+ Name-sg = Apêndice ,
+ name-sg = apêndice ,
+ Name-pl = Apêndices ,
+ name-pl = apêndices ,
+
+type = subappendix ,
+ gender = m ,
+ Name-sg = Apêndice ,
+ name-sg = apêndice ,
+ Name-pl = Apêndices ,
+ name-pl = apêndices ,
+
+type = page ,
+ gender = f ,
+ Name-sg = Página ,
+ name-sg = página ,
+ Name-pl = Páginas ,
+ name-pl = páginas ,
+ name-sg-ab = p. ,
+ name-pl-ab = pp. ,
+ rangesep = {\textendash} ,
+
+type = line ,
+ gender = f ,
+ Name-sg = Linha ,
+ name-sg = linha ,
+ Name-pl = Linhas ,
+ name-pl = linhas ,
+
+type = figure ,
+ gender = f ,
+ Name-sg = Figura ,
+ name-sg = figura ,
+ Name-pl = Figuras ,
+ name-pl = figuras ,
+ Name-sg-ab = Fig. ,
+ name-sg-ab = fig. ,
+ Name-pl-ab = Figs. ,
+ name-pl-ab = figs. ,
+
+type = table ,
+ gender = f ,
+ Name-sg = Tabela ,
+ name-sg = tabela ,
+ Name-pl = Tabelas ,
+ name-pl = tabelas ,
+
+type = item ,
+ gender = m ,
+ Name-sg = Item ,
+ name-sg = item ,
+ Name-pl = Itens ,
+ name-pl = itens ,
+
+type = footnote ,
+ gender = f ,
+ Name-sg = Nota ,
+ name-sg = nota ,
+ Name-pl = Notas ,
+ name-pl = notas ,
+
+type = endnote ,
+ gender = f ,
+ Name-sg = Nota ,
+ name-sg = nota ,
+ Name-pl = Notas ,
+ name-pl = notas ,
+
+type = note ,
+ gender = f ,
+ Name-sg = Nota ,
+ name-sg = nota ,
+ Name-pl = Notas ,
+ name-pl = notas ,
+
+type = equation ,
+ gender = f ,
+ Name-sg = Equação ,
+ name-sg = equação ,
+ Name-pl = Equações ,
+ name-pl = equações ,
+ Name-sg-ab = Eq. ,
+ name-sg-ab = eq. ,
+ Name-pl-ab = Eqs. ,
+ name-pl-ab = eqs. ,
+ refpre = {(} ,
+ refpos = {)} ,
+
+type = theorem ,
+ gender = m ,
+ Name-sg = Teorema ,
+ name-sg = teorema ,
+ Name-pl = Teoremas ,
+ name-pl = teoremas ,
+
+type = lemma ,
+ gender = m ,
+ Name-sg = Lema ,
+ name-sg = lema ,
+ Name-pl = Lemas ,
+ name-pl = lemas ,
+
+type = corollary ,
+ gender = m ,
+ Name-sg = Corolário ,
+ name-sg = corolário ,
+ Name-pl = Corolários ,
+ name-pl = corolários ,
+
+type = proposition ,
+ gender = f ,
+ Name-sg = Proposição ,
+ name-sg = proposição ,
+ Name-pl = Proposições ,
+ name-pl = proposições ,
+
+type = definition ,
+ gender = f ,
+ Name-sg = Definição ,
+ name-sg = definição ,
+ Name-pl = Definições ,
+ name-pl = definições ,
+
+type = proof ,
+ gender = f ,
+ Name-sg = Demonstração ,
+ name-sg = demonstração ,
+ Name-pl = Demonstrações ,
+ name-pl = demonstrações ,
+
+type = result ,
+ gender = m ,
+ Name-sg = Resultado ,
+ name-sg = resultado ,
+ Name-pl = Resultados ,
+ name-pl = resultados ,
+
+type = remark ,
+ gender = f ,
+ Name-sg = Observação ,
+ name-sg = observação ,
+ Name-pl = Observações ,
+ name-pl = observações ,
+
+type = example ,
+ gender = m ,
+ Name-sg = Exemplo ,
+ name-sg = exemplo ,
+ Name-pl = Exemplos ,
+ name-pl = exemplos ,
+
+type = algorithm ,
+ gender = m ,
+ Name-sg = Algoritmo ,
+ name-sg = algoritmo ,
+ Name-pl = Algoritmos ,
+ name-pl = algoritmos ,
+
+type = listing ,
+ gender = f ,
+ Name-sg = Listagem ,
+ name-sg = listagem ,
+ Name-pl = Listagens ,
+ name-pl = listagens ,
+
+type = exercise ,
+ gender = m ,
+ Name-sg = Exercício ,
+ name-sg = exercício ,
+ Name-pl = Exercícios ,
+ name-pl = exercícios ,
+
+type = solution ,
+ gender = f ,
+ Name-sg = Solução ,
+ name-sg = solução ,
+ Name-pl = Soluções ,
+ name-pl = soluções ,
+%%
+%%
+%% End of file `zref-clever-portuguese.dict'.
diff --git a/Master/texmf-dist/tex/latex/zref-clever/zref-clever-spanish.dict b/Master/texmf-dist/tex/latex/zref-clever/zref-clever-spanish.dict
new file mode 100644
index 00000000000..04291ac7358
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/zref-clever/zref-clever-spanish.dict
@@ -0,0 +1,262 @@
+%%
+%% This is file `zref-clever-spanish.dict',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% zref-clever.dtx (with options: `dict-spanish')
+%%
+%% This file was generated from file(s) of the LaTeX package "zref-clever".
+%%
+%% 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-clever.dtx,
+%% zref-clever.ins,
+%% zref-clever.tex,
+%% zref-clever-code.tex,
+%% and the derived files listed in MANIFEST.md.
+%%
+%% 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-clever
+%%
+%% for those people who are interested.
+%%
+%% -----------------------------------------------------------------------
+%%
+namesep = {\nobreakspace} ,
+pairsep = {~y\nobreakspace} ,
+listsep = {,~} ,
+lastsep = {~y\nobreakspace} ,
+tpairsep = {~y\nobreakspace} ,
+tlistsep = {,~} ,
+tlastsep = {~y\nobreakspace} ,
+notesep = {~} ,
+rangesep = {~a\nobreakspace} ,
+
+type = book ,
+ gender = m ,
+ Name-sg = Libro ,
+ name-sg = libro ,
+ Name-pl = Libros ,
+ name-pl = libros ,
+
+type = part ,
+ gender = f ,
+ Name-sg = Parte ,
+ name-sg = parte ,
+ Name-pl = Partes ,
+ name-pl = partes ,
+
+type = chapter ,
+ gender = m ,
+ Name-sg = Capítulo ,
+ name-sg = capítulo ,
+ Name-pl = Capítulos ,
+ name-pl = capítulos ,
+
+type = section ,
+ gender = f ,
+ Name-sg = Sección ,
+ name-sg = sección ,
+ Name-pl = Secciones ,
+ name-pl = secciones ,
+
+type = paragraph ,
+ gender = m ,
+ Name-sg = Párrafo ,
+ name-sg = párrafo ,
+ Name-pl = Párrafos ,
+ name-pl = párrafos ,
+
+type = appendix ,
+ gender = m ,
+ Name-sg = Apéndice ,
+ name-sg = apéndice ,
+ Name-pl = Apéndices ,
+ name-pl = apéndices ,
+
+type = subappendix ,
+ gender = m ,
+ Name-sg = Apéndice ,
+ name-sg = apéndice ,
+ Name-pl = Apéndices ,
+ name-pl = apéndices ,
+
+type = page ,
+ gender = f ,
+ Name-sg = Página ,
+ name-sg = página ,
+ Name-pl = Páginas ,
+ name-pl = páginas ,
+ rangesep = {\textendash} ,
+
+type = line ,
+ gender = f ,
+ Name-sg = Línea ,
+ name-sg = línea ,
+ Name-pl = Líneas ,
+ name-pl = líneas ,
+
+type = figure ,
+ gender = f ,
+ Name-sg = Figura ,
+ name-sg = figura ,
+ Name-pl = Figuras ,
+ name-pl = figuras ,
+
+type = table ,
+ gender = m ,
+ Name-sg = Cuadro ,
+ name-sg = cuadro ,
+ Name-pl = Cuadros ,
+ name-pl = cuadros ,
+
+type = item ,
+ gender = m ,
+ Name-sg = Punto ,
+ name-sg = punto ,
+ Name-pl = Puntos ,
+ name-pl = puntos ,
+
+type = footnote ,
+ gender = f ,
+ Name-sg = Nota ,
+ name-sg = nota ,
+ Name-pl = Notas ,
+ name-pl = notas ,
+
+type = endnote ,
+ gender = f ,
+ Name-sg = Nota ,
+ name-sg = nota ,
+ Name-pl = Notas ,
+ name-pl = notas ,
+
+type = note ,
+ gender = f ,
+ Name-sg = Nota ,
+ name-sg = nota ,
+ Name-pl = Notas ,
+ name-pl = notas ,
+
+type = equation ,
+ gender = f ,
+ Name-sg = Ecuación ,
+ name-sg = ecuación ,
+ Name-pl = Ecuaciones ,
+ name-pl = ecuaciones ,
+ refpre = {(} ,
+ refpos = {)} ,
+
+type = theorem ,
+ gender = m ,
+ Name-sg = Teorema ,
+ name-sg = teorema ,
+ Name-pl = Teoremas ,
+ name-pl = teoremas ,
+
+type = lemma ,
+ gender = m ,
+ Name-sg = Lema ,
+ name-sg = lema ,
+ Name-pl = Lemas ,
+ name-pl = lemas ,
+
+type = corollary ,
+ gender = m ,
+ Name-sg = Corolario ,
+ name-sg = corolario ,
+ Name-pl = Corolarios ,
+ name-pl = corolarios ,
+
+type = proposition ,
+ gender = f ,
+ Name-sg = Proposición ,
+ name-sg = proposición ,
+ Name-pl = Proposiciones ,
+ name-pl = proposiciones ,
+
+type = definition ,
+ gender = f ,
+ Name-sg = Definición ,
+ name-sg = definición ,
+ Name-pl = Definiciones ,
+ name-pl = definiciones ,
+
+type = proof ,
+ gender = f ,
+ Name-sg = Demostración ,
+ name-sg = demostración ,
+ Name-pl = Demostraciones ,
+ name-pl = demostraciones ,
+
+type = result ,
+ gender = m ,
+ Name-sg = Resultado ,
+ name-sg = resultado ,
+ Name-pl = Resultados ,
+ name-pl = resultados ,
+
+type = remark ,
+ gender = f ,
+ Name-sg = Observación ,
+ name-sg = observación ,
+ Name-pl = Observaciones ,
+ name-pl = observaciones ,
+
+type = example ,
+ gender = m ,
+ Name-sg = Ejemplo ,
+ name-sg = ejemplo ,
+ Name-pl = Ejemplos ,
+ name-pl = ejemplos ,
+
+type = algorithm ,
+ gender = m ,
+ Name-sg = Algoritmo ,
+ name-sg = algoritmo ,
+ Name-pl = Algoritmos ,
+ name-pl = algoritmos ,
+
+type = listing ,
+ gender = m ,
+ Name-sg = Listado ,
+ name-sg = listado ,
+ Name-pl = Listados ,
+ name-pl = listados ,
+
+type = exercise ,
+ gender = m ,
+ Name-sg = Ejercicio ,
+ name-sg = ejercicio ,
+ Name-pl = Ejercicios ,
+ name-pl = ejercicios ,
+
+type = solution ,
+ gender = f ,
+ Name-sg = Solución ,
+ name-sg = solución ,
+ Name-pl = Soluciones ,
+ name-pl = soluciones ,
+%%
+%%
+%% End of file `zref-clever-spanish.dict'.
diff --git a/Master/texmf-dist/tex/latex/zref-clever/zref-clever.sty b/Master/texmf-dist/tex/latex/zref-clever/zref-clever.sty
new file mode 100644
index 00000000000..5728b971d1f
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/zref-clever/zref-clever.sty
@@ -0,0 +1,3519 @@
+%%
+%% This is file `zref-clever.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% zref-clever.dtx (with options: `package')
+%%
+%% This file was generated from file(s) of the LaTeX package "zref-clever".
+%%
+%% 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-clever.dtx,
+%% zref-clever.ins,
+%% zref-clever.tex,
+%% zref-clever-code.tex,
+%% and the derived files listed in MANIFEST.md.
+%%
+%% 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-clever
+%%
+%% for those people who are interested.
+%%
+%% -----------------------------------------------------------------------
+%%
+\providecommand\IfFormatAtLeastTF{\@ifl@t@r\fmtversion}
+\IfFormatAtLeastTF{2021-11-15}
+ {}
+ {%
+ \PackageError{zref-clever}{LaTeX kernel too old}
+ {%
+ 'zref-clever' requires a LaTeX kernel 2021-11-15 or newer.%
+ \MessageBreak Loading will abort!%
+ }%
+ \endinput
+ }%
+\ProvidesExplPackage {zref-clever} {2021-11-24} {0.1.0-alpha}
+ {Clever LaTeX cross-references based on zref}
+\RequirePackage { zref-base }
+\RequirePackage { zref-user }
+\RequirePackage { zref-abspage }
+\RequirePackage { l3keys2e }
+\RequirePackage { ifdraft }
+\zref@newprop { zc@counter } { \l__zrefclever_current_counter_tl }
+\zref@addprop \ZREF@mainlist { zc@counter }
+\zref@newprop { thecounter }
+ {
+ \cs_if_exist:cTF { c@ \l__zrefclever_current_counter_tl }
+ { \use:c { the \l__zrefclever_current_counter_tl } }
+ {
+ \cs_if_exist:cT { c@ \@currentcounter }
+ { \use:c { the \@currentcounter } }
+ }
+ }
+\zref@addprop \ZREF@mainlist { thecounter }
+\zref@newprop { zc@type }
+ {
+ \exp_args:NNe \prop_if_in:NnTF \l__zrefclever_counter_type_prop
+ \l__zrefclever_current_counter_tl
+ {
+ \exp_args:NNe \prop_item:Nn \l__zrefclever_counter_type_prop
+ { \l__zrefclever_current_counter_tl }
+ }
+ { \l__zrefclever_current_counter_tl }
+ }
+\zref@addprop \ZREF@mainlist { zc@type }
+\zref@newprop { zc@cntval } [0]
+ {
+ \cs_if_exist:cTF { c@ \l__zrefclever_current_counter_tl }
+ { \int_use:c { c@ \l__zrefclever_current_counter_tl } }
+ {
+ \cs_if_exist:cT { c@ \@currentcounter }
+ { \int_use:c { c@ \@currentcounter } }
+ }
+ }
+\zref@addprop \ZREF@mainlist { zc@cntval }
+\zref@newprop* { zc@pgval } [0] { \int_use:c { c@page } }
+\zref@addprop \ZREF@mainlist { zc@pgval }
+\cs_new:Npn \__zrefclever_get_enclosing_counters_value:n #1
+ {
+ \cs_if_exist:cT { c@ \__zrefclever_counter_reset_by:n {#1} }
+ {
+ { \int_use:c { c@ \__zrefclever_counter_reset_by:n {#1} } }
+ \__zrefclever_get_enclosing_counters_value:e
+ { \__zrefclever_counter_reset_by:n {#1} }
+ }
+ }
+\cs_generate_variant:Nn \__zrefclever_get_enclosing_counters_value:n { e }
+\cs_new:Npn \__zrefclever_counter_reset_by:n #1
+ {
+ \bool_if:nTF
+ { \prop_if_in_p:Nn \l__zrefclever_counter_resetby_prop {#1} }
+ { \prop_item:Nn \l__zrefclever_counter_resetby_prop {#1} }
+ {
+ \seq_map_tokens:Nn \l__zrefclever_counter_resetters_seq
+ { \__zrefclever_counter_reset_by_aux:nn {#1} }
+ }
+ }
+\cs_new:Npn \__zrefclever_counter_reset_by_aux:nn #1#2
+ {
+ \cs_if_exist:cT { c@ #2 }
+ {
+ \tl_if_empty:cF { cl@ #2 }
+ {
+ \tl_map_tokens:cn { cl@ #2 }
+ { \__zrefclever_counter_reset_by_auxi:nnn {#2} {#1} }
+ }
+ }
+ }
+\cs_new:Npn \__zrefclever_counter_reset_by_auxi:nnn #1#2#3
+ {
+ \str_if_eq:nnT {#2} {#3}
+ { \tl_map_break:n { \seq_map_break:n {#1} } }
+ }
+\zref@newprop { zc@enclval }
+ {
+ \__zrefclever_get_enclosing_counters_value:e
+ \l__zrefclever_current_counter_tl
+ }
+\zref@addprop \ZREF@mainlist { zc@enclval }
+\tl_new:N \g__zrefclever_page_format_tl
+\cs_new_protected:Npx \__zrefclever_page_format_aux: { \int_eval:n { 1 } }
+\AddToHook { shipout / before }
+ {
+ \group_begin:
+ \cs_set_eq:NN \c@page \__zrefclever_page_format_aux:
+ \tl_gset:Nx \g__zrefclever_page_format_tl { \thepage }
+ \group_end:
+ }
+\zref@newprop* { zc@pgfmt } { \g__zrefclever_page_format_tl }
+\zref@addprop \ZREF@mainlist { zc@pgfmt }
+\prg_new_conditional:Npnn \__zrefclever_if_package_loaded:n #1 { T , F , TF }
+ { \IfPackageLoadedTF {#1} { \prg_return_true: } { \prg_return_false: } }
+\prg_new_conditional:Npnn \__zrefclever_if_class_loaded:n #1 { T , F , TF }
+ { \IfClassLoadedTF {#1} { \prg_return_true: } { \prg_return_false: } }
+\msg_new:nnn { zref-clever } { option-not-type-specific }
+ {
+ Option~'#1'~is~not~type-specific~\msg_line_context:.~
+ Set~it~in~'\iow_char:N\\zcLanguageSetup'~before~first~'type'~
+ switch~or~as~package~option.
+ }
+\msg_new:nnn { zref-clever } { option-only-type-specific }
+ {
+ No~type~specified~for~option~'#1'~\msg_line_context:.~
+ Set~it~after~'type'~switch.
+ }
+\msg_new:nnn { zref-clever } { key-requires-value }
+ { The~'#1'~key~'#2'~requires~a~value~\msg_line_context:. }
+\msg_new:nnn { zref-clever } { language-declared }
+ { Language~'#1'~is~already~declared~\msg_line_context:.~Nothing~to~do. }
+\msg_new:nnn { zref-clever } { unknown-language-alias }
+ {
+ Language~'#1'~is~unknown~\msg_line_context:.~Can't~alias~to~it.~
+ See~documentation~for~'\iow_char:N\\zcDeclareLanguage'~and~
+ '\iow_char:N\\zcDeclareLanguageAlias'.
+ }
+\msg_new:nnn { zref-clever } { unknown-language-setup }
+ {
+ Language~'#1'~is~unknown~\msg_line_context:.~Can't~set~it~up.~
+ See~documentation~for~'\iow_char:N\\zcDeclareLanguage'~and~
+ '\iow_char:N\\zcDeclareLanguageAlias'.
+ }
+\msg_new:nnn { zref-clever } { unknown-language-opt }
+ {
+ Language~'#1'~is~unknown~\msg_line_context:.~Using~default.~
+ See~documentation~for~'\iow_char:N\\zcDeclareLanguage'~and~
+ '\iow_char:N\\zcDeclareLanguageAlias'.
+ }
+\msg_new:nnn { zref-clever } { unknown-language-decl }
+ {
+ Can't~set~declension~'#1'~for~unknown~language~'#2'~\msg_line_context:.~
+ See~documentation~for~'\iow_char:N\\zcDeclareLanguage'~and~
+ '\iow_char:N\\zcDeclareLanguageAlias'.
+ }
+\msg_new:nnn { zref-clever } { language-no-decl-ref }
+ {
+ Language~'#1'~has~no~declared~declension~cases~\msg_line_context:.~
+ Nothing~to~do~with~option~'d=#2'.
+ }
+\msg_new:nnn { zref-clever } { language-no-gender }
+ {
+ Language~'#1'~has~no~declared~gender~\msg_line_context:.~
+ Nothing~to~do~with~option~'#2=#3'.
+ }
+\msg_new:nnn { zref-clever } { language-no-decl-setup }
+ {
+ Language~'#1'~has~no~declared~declension~cases~\msg_line_context:.~
+ Nothing~to~do~with~option~'case=#2'.
+ }
+\msg_new:nnn { zref-clever } { unknown-decl-case }
+ {
+ Declension~case~'#1'~unknown~for~language~'#2'~\msg_line_context:.~
+ Using~default~declension~case.
+ }
+\msg_new:nnn { zref-clever } { nudge-multitype }
+ {
+ Reference~with~multiple~types~\msg_line_context:.~
+ You~may~wish~to~separate~them~or~review~language~around~it.
+ }
+\msg_new:nnn { zref-clever } { nudge-comptosing }
+ {
+ Multiple~labels~have~been~compressed~into~singular~type~name~
+ for~type~'#1'~\msg_line_context:.
+ }
+\msg_new:nnn { zref-clever } { nudge-plural-when-sg }
+ {
+ Option~'sg'~signals~that~a~singular~type~name~was~expected~
+ \msg_line_context:.~But~type~'#1'~has~plural~type~name.
+ }
+\msg_new:nnn { zref-clever } { gender-not-declared }
+ { Language~'#1'~has~no~'#2'~gender~declared~\msg_line_context:. }
+\msg_new:nnn { zref-clever } { nudge-gender-mismatch }
+ {
+ Gender~mismatch~for~type~'#1'~\msg_line_context:.~
+ You've~specified~'g=#2'~but~type~name~is~'#3'~for~language~'#4'.
+ }
+\msg_new:nnn { zref-clever } { nudge-gender-not-declared-for-type }
+ {
+ You've~specified~'g=#1'~\msg_line_context:.~
+ But~gender~for~type~'#2'~is~not~declared~for~language~'#3'.
+ }
+\msg_new:nnn { zref-clever } { nudgeif-unknown-value }
+ { Unknown~value~'#1'~for~'nudgeif'~option~\msg_line_context:. }
+\msg_new:nnn { zref-clever } { option-document-only }
+ { Option~'#1'~is~only~available~after~\iow_char:N\\begin\{document\}. }
+\msg_new:nnn { zref-clever } { dict-loaded }
+ { Loaded~'#1'~dictionary. }
+\msg_new:nnn { zref-clever } { dict-not-available }
+ { Dictionary~for~'#1'~not~available~\msg_line_context:. }
+\msg_new:nnn { zref-clever } { unknown-language-load }
+ {
+ Language~'#1'~is~unknown~\msg_line_context:.~Unable~to~load~dictionary.~
+ See~documentation~for~'\iow_char:N\\zcDeclareLanguage'~and~
+ '\iow_char:N\\zcDeclareLanguageAlias'.
+ }
+\msg_new:nnn { zref-clever } { zref-property-undefined }
+ {
+ Option~'ref=#1'~requested~\msg_line_context:.~
+ But~the~property~'#1'~is~not~declared,~falling-back~to~'default'.
+ }
+\msg_new:nnn { zref-clever } { hyperref-preamble-only }
+ {
+ Option~'hyperref'~only~available~in~the~preamble~\msg_line_context:.~
+ To~inhibit~hyperlinking~locally,~you~can~use~the~starred~version~of~
+ '\iow_char:N\\zcref'.
+ }
+\msg_new:nnn { zref-clever } { missing-hyperref }
+ { Missing~'hyperref'~package.~Setting~'hyperref=false'. }
+\msg_new:nnn { zref-clever } { titleref-preamble-only }
+ {
+ Option~'titleref'~only~available~in~the~preamble~\msg_line_context:.~
+ Did~you~mean~'ref=title'?.
+ }
+\msg_new:nnn { zref-clever } { option-preamble-only }
+ { Option~'#1'~only~available~in~the~preamble~\msg_line_context:. }
+\msg_new:nnn { zref-clever } { unknown-compat-module }
+ {
+ Unknown~compatibility~module~'#1'~given~to~option~'nocompat'.~
+ Nothing~to~do.
+ }
+\msg_new:nnn { zref-clever } { missing-zref-check }
+ {
+ Option~'check'~requested~\msg_line_context:.~
+ But~package~'zref-check'~is~not~loaded,~can't~run~the~checks.
+ }
+\msg_new:nnn { zref-clever } { missing-type }
+ { Reference~type~undefined~for~label~'#1'~\msg_line_context:. }
+\msg_new:nnn { zref-clever } { missing-property }
+ { Reference~property~'#1'~undefined~for~label~'#2'~\msg_line_context:. }
+\msg_new:nnn { zref-clever } { missing-name }
+ { Reference~format~option~'#1'~undefined~for~type~'#2'~\msg_line_context:. }
+\msg_new:nnn { zref-clever } { missing-string }
+ {
+ We~couldn't~find~a~value~for~reference~option~'#1'~\msg_line_context:.~
+ But~we~should~have:~throw~a~rock~at~the~maintainer.
+ }
+\msg_new:nnn { zref-clever } { single-element-range }
+ { Range~for~type~'#1'~resulted~in~single~element~\msg_line_context:. }
+\msg_new:nnn { zref-clever } { compat-package }
+ { Loaded~support~for~'#1'~package. }
+\msg_new:nnn { zref-clever } { compat-class }
+ { Loaded~support~for~'#1'~documentclass. }
+\cs_new_protected:Npn \__zrefclever_def_extract:Nnnn #1#2#3#4
+ {
+ \exp_args:NNNo \exp_args:NNo \tl_set:Nn #1
+ { \zref@extractdefault {#2} {#3} {#4} }
+ }
+\cs_generate_variant:Nn \__zrefclever_def_extract:Nnnn { NVnn }
+\cs_new:Npn \__zrefclever_extract_unexp:nnn #1#2#3
+ {
+ \exp_args:NNo \exp_args:No
+ \exp_not:n { \zref@extractdefault {#1} {#2} {#3} }
+ }
+\cs_generate_variant:Nn \__zrefclever_extract_unexp:nnn { Vnn , nvn , Vvn }
+\cs_new:Npn \__zrefclever_extract:nnn #1#2#3
+ { \zref@extractdefault {#1} {#2} {#3} }
+\tl_new:N \l__zrefclever_setup_type_tl
+\tl_new:N \l__zrefclever_dict_language_tl
+\tl_new:N \l__zrefclever_dict_decl_case_tl
+\seq_new:N \l__zrefclever_dict_declension_seq
+\seq_new:N \l__zrefclever_dict_gender_seq
+\seq_const_from_clist:Nn
+ \c__zrefclever_ref_options_necessarily_not_type_specific_seq
+ {
+ tpairsep ,
+ tlistsep ,
+ tlastsep ,
+ notesep ,
+ }
+\seq_const_from_clist:Nn
+ \c__zrefclever_ref_options_possibly_type_specific_seq
+ {
+ namesep ,
+ pairsep ,
+ listsep ,
+ lastsep ,
+ rangesep ,
+ refpre ,
+ refpos ,
+ }
+\seq_const_from_clist:Nn
+ \c__zrefclever_ref_options_type_names_seq
+ {
+ Name-sg ,
+ name-sg ,
+ Name-pl ,
+ name-pl ,
+ Name-sg-ab ,
+ name-sg-ab ,
+ Name-pl-ab ,
+ name-pl-ab ,
+ }
+\seq_const_from_clist:Nn
+ \c__zrefclever_ref_options_font_seq
+ {
+ namefont ,
+ reffont ,
+ }
+\seq_new:N \c__zrefclever_ref_options_typesetup_seq
+\seq_gconcat:NNN \c__zrefclever_ref_options_typesetup_seq
+ \c__zrefclever_ref_options_possibly_type_specific_seq
+ \c__zrefclever_ref_options_type_names_seq
+\seq_gconcat:NNN \c__zrefclever_ref_options_typesetup_seq
+ \c__zrefclever_ref_options_typesetup_seq
+ \c__zrefclever_ref_options_font_seq
+\seq_new:N \c__zrefclever_ref_options_reference_seq
+\seq_gconcat:NNN \c__zrefclever_ref_options_reference_seq
+ \c__zrefclever_ref_options_necessarily_not_type_specific_seq
+ \c__zrefclever_ref_options_possibly_type_specific_seq
+\seq_gconcat:NNN \c__zrefclever_ref_options_reference_seq
+ \c__zrefclever_ref_options_reference_seq
+ \c__zrefclever_ref_options_font_seq
+\prop_new:N \g__zrefclever_languages_prop
+\NewDocumentCommand \zcDeclareLanguage { O { } m }
+ {
+ \group_begin:
+ \tl_if_empty:nF {#2}
+ {
+ \prop_if_in:NnTF \g__zrefclever_languages_prop {#2}
+ { \msg_warning:nnn { zref-clever } { language-declared } {#2} }
+ {
+ \prop_gput:Nnn \g__zrefclever_languages_prop {#2} {#2}
+ \prop_new:c { g__zrefclever_dict_ #2 _prop }
+ \tl_set:Nn \l__zrefclever_dict_language_tl {#2}
+ \keys_set:nn { zref-clever / declarelang } {#1}
+ }
+ }
+ \group_end:
+ }
+\@onlypreamble \zcDeclareLanguage
+\NewDocumentCommand \zcDeclareLanguageAlias { m m }
+ {
+ \tl_if_empty:nF {#1}
+ {
+ \prop_if_in:NnTF \g__zrefclever_languages_prop {#2}
+ {
+ \exp_args:NNnx
+ \prop_gput:Nnn \g__zrefclever_languages_prop {#1}
+ { \prop_item:Nn \g__zrefclever_languages_prop {#2} }
+ }
+ { \msg_warning:nnn { zref-clever } { unknown-language-alias } {#2} }
+ }
+ }
+\@onlypreamble \zcDeclareLanguageAlias
+\keys_define:nn { zref-clever / declarelang }
+ {
+ declension .code:n =
+ {
+ \prop_gput:cnn
+ { g__zrefclever_dict_ \l__zrefclever_dict_language_tl _prop }
+ { declension } {#1}
+ } ,
+ declension .value_required:n = true ,
+ gender .code:n =
+ {
+ \prop_gput:cnn
+ { g__zrefclever_dict_ \l__zrefclever_dict_language_tl _prop }
+ { gender } {#1}
+ } ,
+ gender .value_required:n = true ,
+ allcaps .code:n =
+ {
+ \prop_gput:cnn
+ { g__zrefclever_dict_ \l__zrefclever_dict_language_tl _prop }
+ { allcaps } { true }
+ } ,
+ allcaps .value_forbidden:n = true ,
+ }
+\cs_new_protected:Npn \__zrefclever_process_language_options:
+ {
+ \exp_args:NNx \prop_get:NnNTF \g__zrefclever_languages_prop
+ { \l__zrefclever_ref_language_tl }
+ \l__zrefclever_dict_language_tl
+ {
+ \exp_args:NNx \seq_set_from_clist:Nn
+ \l__zrefclever_dict_declension_seq
+ {
+ \prop_item:cn
+ {
+ g__zrefclever_dict_
+ \l__zrefclever_dict_language_tl _prop
+ }
+ { declension }
+ }
+ \seq_if_empty:NTF \l__zrefclever_dict_declension_seq
+ {
+ \tl_if_empty:NF \l__zrefclever_ref_decl_case_tl
+ {
+ \msg_warning:nnxx { zref-clever }
+ { language-no-decl-ref }
+ { \l__zrefclever_ref_language_tl }
+ { \l__zrefclever_ref_decl_case_tl }
+ \tl_clear:N \l__zrefclever_ref_decl_case_tl
+ }
+ }
+ {
+ \tl_if_empty:NTF \l__zrefclever_ref_decl_case_tl
+ {
+ \seq_get_left:NN \l__zrefclever_dict_declension_seq
+ \l__zrefclever_ref_decl_case_tl
+ }
+ {
+ \seq_if_in:NVF \l__zrefclever_dict_declension_seq
+ \l__zrefclever_ref_decl_case_tl
+ {
+ \msg_warning:nnxx { zref-clever }
+ { unknown-decl-case }
+ { \l__zrefclever_ref_decl_case_tl }
+ { \l__zrefclever_ref_language_tl }
+ \seq_get_left:NN \l__zrefclever_dict_declension_seq
+ \l__zrefclever_ref_decl_case_tl
+ }
+ }
+ }
+ \exp_args:NNx \seq_set_from_clist:Nn
+ \l__zrefclever_dict_gender_seq
+ {
+ \prop_item:cn
+ {
+ g__zrefclever_dict_
+ \l__zrefclever_dict_language_tl _prop
+ }
+ { gender }
+ }
+ \seq_if_empty:NTF \l__zrefclever_dict_gender_seq
+ {
+ \tl_if_empty:NF \l__zrefclever_ref_gender_tl
+ {
+ \msg_warning:nnxxx { zref-clever }
+ { language-no-gender }
+ { \l__zrefclever_ref_language_tl }
+ { g }
+ { \l__zrefclever_ref_gender_tl }
+ \tl_clear:N \l__zrefclever_ref_gender_tl
+ }
+ }
+ {
+ \tl_if_empty:NF \l__zrefclever_ref_gender_tl
+ {
+ \seq_if_in:NVF \l__zrefclever_dict_gender_seq
+ \l__zrefclever_ref_gender_tl
+ {
+ \msg_warning:nnxx { zref-clever }
+ { gender-not-declared }
+ { \l__zrefclever_ref_language_tl }
+ { \l__zrefclever_ref_gender_tl }
+ \tl_clear:N \l__zrefclever_ref_gender_tl
+ }
+ }
+ }
+ \str_if_eq:eeT
+ {
+ \prop_item:cn
+ {
+ g__zrefclever_dict_
+ \l__zrefclever_dict_language_tl _prop
+ }
+ { allcaps }
+ }
+ { true }
+ { \bool_set_true:N \l__zrefclever_capitalize_bool }
+ }
+ {
+ \tl_if_empty:NF \l__zrefclever_ref_decl_case_tl
+ {
+ \msg_warning:nnxx { zref-clever } { unknown-language-decl }
+ { \l__zrefclever_ref_decl_case_tl }
+ { \l__zrefclever_ref_language_tl }
+ \tl_clear:N \l__zrefclever_ref_decl_case_tl
+ }
+ \tl_if_empty:NF \l__zrefclever_ref_gender_tl
+ {
+ \msg_warning:nnxxx { zref-clever }
+ { language-no-gender }
+ { \l__zrefclever_ref_language_tl }
+ { g }
+ { \l__zrefclever_ref_gender_tl }
+ \tl_clear:N \l__zrefclever_ref_gender_tl
+ }
+ }
+ }
+\seq_new:N \g__zrefclever_loaded_dictionaries_seq
+\bool_new:N \l__zrefclever_load_dict_verbose_bool
+\cs_new_protected:Npn \__zrefclever_provide_dictionary:n #1
+ {
+ \group_begin:
+ \@bsphack
+ \prop_get:NnNTF \g__zrefclever_languages_prop {#1}
+ \l__zrefclever_dict_language_tl
+ {
+ \seq_if_in:NVF
+ \g__zrefclever_loaded_dictionaries_seq
+ \l__zrefclever_dict_language_tl
+ {
+ \exp_args:Nx \file_get:nnNTF
+ { zref-clever- \l__zrefclever_dict_language_tl .dict }
+ { \ExplSyntaxOn }
+ \l_tmpa_tl
+ {
+ \tl_clear:N \l__zrefclever_setup_type_tl
+ \exp_args:NNx \seq_set_from_clist:Nn
+ \l__zrefclever_dict_declension_seq
+ {
+ \prop_item:cn
+ {
+ g__zrefclever_dict_
+ \l__zrefclever_dict_language_tl _prop
+ }
+ { declension }
+ }
+ \seq_if_empty:NTF \l__zrefclever_dict_declension_seq
+ { \tl_clear:N \l__zrefclever_dict_decl_case_tl }
+ {
+ \seq_get_left:NN \l__zrefclever_dict_declension_seq
+ \l__zrefclever_dict_decl_case_tl
+ }
+ \exp_args:NNx \seq_set_from_clist:Nn
+ \l__zrefclever_dict_gender_seq
+ {
+ \prop_item:cn
+ {
+ g__zrefclever_dict_
+ \l__zrefclever_dict_language_tl _prop
+ }
+ { gender }
+ }
+ \keys_set:nV { zref-clever / dictionary } \l_tmpa_tl
+ \seq_gput_right:NV \g__zrefclever_loaded_dictionaries_seq
+ \l__zrefclever_dict_language_tl
+ \msg_note:nnx { zref-clever } { dict-loaded }
+ { \l__zrefclever_dict_language_tl }
+ }
+ {
+ \bool_if:NT \l__zrefclever_load_dict_verbose_bool
+ {
+ \msg_warning:nnx { zref-clever } { dict-not-available }
+ { \l__zrefclever_dict_language_tl }
+ }
+ \seq_gput_right:NV \g__zrefclever_loaded_dictionaries_seq
+ \l__zrefclever_dict_language_tl
+ }
+ }
+ }
+ {
+ \bool_if:NT \l__zrefclever_load_dict_verbose_bool
+ { \msg_warning:nnn { zref-clever } { unknown-language-load } {#1} }
+ }
+ \@esphack
+ \group_end:
+ }
+\cs_generate_variant:Nn \__zrefclever_provide_dictionary:n { x }
+\cs_new_protected:Npn \__zrefclever_provide_dictionary_verbose:n #1
+ {
+ \group_begin:
+ \bool_set_true:N \l__zrefclever_load_dict_verbose_bool
+ \__zrefclever_provide_dictionary:n {#1}
+ \group_end:
+ }
+\cs_generate_variant:Nn \__zrefclever_provide_dictionary_verbose:n { x }
+\cs_new_protected:Npn \__zrefclever_provide_dict_type_transl:nn #1#2
+ {
+ \exp_args:Nnx \prop_gput_if_new:cnn
+ { g__zrefclever_dict_ \l__zrefclever_dict_language_tl _prop }
+ { type- \l__zrefclever_setup_type_tl - #1 } {#2}
+ }
+\cs_new_protected:Npn \__zrefclever_provide_dict_default_transl:nn #1#2
+ {
+ \prop_gput_if_new:cnn
+ { g__zrefclever_dict_ \l__zrefclever_dict_language_tl _prop }
+ { default- #1 } {#2}
+ }
+\keys_define:nn { zref-clever / dictionary }
+ {
+ type .code:n =
+ {
+ \tl_if_empty:nTF {#1}
+ { \tl_clear:N \l__zrefclever_setup_type_tl }
+ { \tl_set:Nn \l__zrefclever_setup_type_tl {#1} }
+ } ,
+ case .code:n =
+ {
+ \seq_if_empty:NTF \l__zrefclever_dict_declension_seq
+ {
+ \msg_info:nnxx { zref-clever } { language-no-decl-setup }
+ { \l__zrefclever_dict_language_tl } {#1}
+ }
+ {
+ \seq_if_in:NnTF \l__zrefclever_dict_declension_seq {#1}
+ { \tl_set:Nn \l__zrefclever_dict_decl_case_tl {#1} }
+ {
+ \msg_info:nnxx { zref-clever } { unknown-decl-case }
+ {#1} { \l__zrefclever_dict_language_tl }
+ \seq_get_left:NN \l__zrefclever_dict_declension_seq
+ \l__zrefclever_dict_decl_case_tl
+ }
+ }
+ } ,
+ case .value_required:n = true ,
+ gender .code:n =
+ {
+ \seq_if_empty:NTF \l__zrefclever_dict_gender_seq
+ {
+ \msg_info:nnxxx { zref-clever } { language-no-gender }
+ { \l__zrefclever_dict_language_tl } { gender } {#1}
+ }
+ {
+ \tl_if_empty:NTF \l__zrefclever_setup_type_tl
+ {
+ \msg_info:nnn { zref-clever }
+ { option-only-type-specific } { gender }
+ }
+ {
+ \seq_if_in:NnTF \l__zrefclever_dict_gender_seq {#1}
+ { \__zrefclever_provide_dict_type_transl:nn { gender } {#1} }
+ {
+ \msg_info:nnxx { zref-clever } { gender-not-declared }
+ { \l__zrefclever_dict_language_tl } {#1}
+ }
+ }
+ }
+ } ,
+ gender .value_required:n = true ,
+ }
+\seq_map_inline:Nn
+ \c__zrefclever_ref_options_necessarily_not_type_specific_seq
+ {
+ \keys_define:nn { zref-clever / dictionary }
+ {
+ #1 .value_required:n = true ,
+ #1 .code:n =
+ {
+ \tl_if_empty:NTF \l__zrefclever_setup_type_tl
+ { \__zrefclever_provide_dict_default_transl:nn {#1} {##1} }
+ {
+ \msg_info:nnn { zref-clever }
+ { option-not-type-specific } {#1}
+ }
+ } ,
+ }
+ }
+\seq_map_inline:Nn
+ \c__zrefclever_ref_options_possibly_type_specific_seq
+ {
+ \keys_define:nn { zref-clever / dictionary }
+ {
+ #1 .value_required:n = true ,
+ #1 .code:n =
+ {
+ \tl_if_empty:NTF \l__zrefclever_setup_type_tl
+ { \__zrefclever_provide_dict_default_transl:nn {#1} {##1} }
+ { \__zrefclever_provide_dict_type_transl:nn {#1} {##1} }
+ } ,
+ }
+ }
+\seq_map_inline:Nn
+ \c__zrefclever_ref_options_type_names_seq
+ {
+ \keys_define:nn { zref-clever / dictionary }
+ {
+ #1 .value_required:n = true ,
+ #1 .code:n =
+ {
+ \tl_if_empty:NTF \l__zrefclever_setup_type_tl
+ {
+ \msg_info:nnn { zref-clever }
+ { option-only-type-specific } {#1}
+ }
+ {
+ \tl_if_empty:NTF \l__zrefclever_dict_decl_case_tl
+ { \__zrefclever_provide_dict_type_transl:nn {#1} {##1} }
+ {
+ \__zrefclever_provide_dict_type_transl:nn
+ { \l__zrefclever_dict_decl_case_tl - #1 } {##1}
+ }
+ }
+ } ,
+ }
+ }
+\prop_new:N \g__zrefclever_fallback_dict_prop
+\prop_gset_from_keyval:Nn \g__zrefclever_fallback_dict_prop
+ {
+ tpairsep = {,~} ,
+ tlistsep = {,~} ,
+ tlastsep = {,~} ,
+ notesep = {~} ,
+ namesep = {\nobreakspace} ,
+ pairsep = {,~} ,
+ listsep = {,~} ,
+ lastsep = {,~} ,
+ rangesep = {\textendash} ,
+ refpre = {} ,
+ refpos = {} ,
+ }
+\prg_new_protected_conditional:Npnn
+ \__zrefclever_get_type_transl:nnnN #1#2#3#4 { F }
+ {
+ \prop_get:NnNTF \g__zrefclever_languages_prop {#1}
+ \l__zrefclever_dict_language_tl
+ {
+ \prop_get:cnNTF
+ { g__zrefclever_dict_ \l__zrefclever_dict_language_tl _prop }
+ { type- #2 - #3 } #4
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ { \prg_return_false: }
+ }
+\prg_generate_conditional_variant:Nnn
+ \__zrefclever_get_type_transl:nnnN { xxxN , xxnN } { F }
+\prg_new_protected_conditional:Npnn
+ \__zrefclever_get_default_transl:nnN #1#2#3 { F }
+ {
+ \prop_get:NnNTF \g__zrefclever_languages_prop {#1}
+ \l__zrefclever_dict_language_tl
+ {
+ \prop_get:cnNTF
+ { g__zrefclever_dict_ \l__zrefclever_dict_language_tl _prop }
+ { default- #2 } #3
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ { \prg_return_false: }
+ }
+\prg_generate_conditional_variant:Nnn
+ \__zrefclever_get_default_transl:nnN { xnN } { F }
+\prg_new_protected_conditional:Npnn
+ \__zrefclever_get_fallback_transl:nN #1#2 { F }
+ {
+ \prop_get:NnNTF \g__zrefclever_fallback_dict_prop
+ { #1 } #2
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+\cs_new_protected:Npn \__zrefclever_prop_put_non_empty:Nnn #1#2#3
+ {
+ \tl_if_empty:nTF {#3}
+ { \prop_remove:Nn #1 {#2} }
+ { \prop_put:Nnn #1 {#2} {#3} }
+ }
+\tl_new:N \l__zrefclever_ref_property_tl
+\keys_define:nn { zref-clever / reference }
+ {
+ ref .code:n =
+ {
+ \zref@ifpropundefined {#1}
+ {
+ \msg_warning:nnn { zref-clever } { zref-property-undefined } {#1}
+ \tl_set:Nn \l__zrefclever_ref_property_tl { default }
+ }
+ { \tl_set:Nn \l__zrefclever_ref_property_tl {#1} }
+ } ,
+ ref .initial:n = default ,
+ ref .value_required:n = true ,
+ page .meta:n = { ref = page },
+ page .value_forbidden:n = true ,
+ }
+\bool_new:N \l__zrefclever_typeset_ref_bool
+\bool_new:N \l__zrefclever_typeset_name_bool
+\keys_define:nn { zref-clever / reference }
+ {
+ typeset .choice: ,
+ typeset / both .code:n =
+ {
+ \bool_set_true:N \l__zrefclever_typeset_ref_bool
+ \bool_set_true:N \l__zrefclever_typeset_name_bool
+ } ,
+ typeset / ref .code:n =
+ {
+ \bool_set_true:N \l__zrefclever_typeset_ref_bool
+ \bool_set_false:N \l__zrefclever_typeset_name_bool
+ } ,
+ typeset / name .code:n =
+ {
+ \bool_set_false:N \l__zrefclever_typeset_ref_bool
+ \bool_set_true:N \l__zrefclever_typeset_name_bool
+ } ,
+ typeset .initial:n = both ,
+ typeset .value_required:n = true ,
+
+ noname .meta:n = { typeset = ref } ,
+ noname .value_forbidden:n = true ,
+ noref .meta:n = { typeset = name } ,
+ noref .value_forbidden:n = true ,
+ }
+\bool_new:N \l__zrefclever_typeset_sort_bool
+\keys_define:nn { zref-clever / reference }
+ {
+ sort .bool_set:N = \l__zrefclever_typeset_sort_bool ,
+ sort .initial:n = true ,
+ sort .default:n = true ,
+ nosort .meta:n = { sort = false },
+ nosort .value_forbidden:n = true ,
+ }
+\seq_new:N \l__zrefclever_typesort_seq
+\keys_define:nn { zref-clever / reference }
+ {
+ typesort .code:n =
+ {
+ \seq_set_from_clist:Nn \l__zrefclever_typesort_seq {#1}
+ \seq_reverse:N \l__zrefclever_typesort_seq
+ } ,
+ typesort .initial:n =
+ { part , chapter , section , paragraph },
+ typesort .value_required:n = true ,
+ notypesort .code:n =
+ { \seq_clear:N \l__zrefclever_typesort_seq } ,
+ notypesort .value_forbidden:n = true ,
+ }
+\bool_new:N \l__zrefclever_typeset_compress_bool
+\keys_define:nn { zref-clever / reference }
+ {
+ comp .bool_set:N = \l__zrefclever_typeset_compress_bool ,
+ comp .initial:n = true ,
+ comp .default:n = true ,
+ nocomp .meta:n = { comp = false },
+ nocomp .value_forbidden:n = true ,
+ }
+\bool_new:N \l__zrefclever_typeset_range_bool
+\keys_define:nn { zref-clever / reference }
+ {
+ range .bool_set:N = \l__zrefclever_typeset_range_bool ,
+ range .initial:n = false ,
+ range .default:n = true ,
+ }
+\bool_new:N \l__zrefclever_capitalize_bool
+\bool_new:N \l__zrefclever_capitalize_first_bool
+\keys_define:nn { zref-clever / reference }
+ {
+ cap .bool_set:N = \l__zrefclever_capitalize_bool ,
+ cap .initial:n = false ,
+ cap .default:n = true ,
+ nocap .meta:n = { cap = false },
+ nocap .value_forbidden:n = true ,
+
+ capfirst .bool_set:N = \l__zrefclever_capitalize_first_bool ,
+ capfirst .initial:n = false ,
+ capfirst .default:n = true ,
+ }
+\bool_new:N \l__zrefclever_abbrev_bool
+\bool_new:N \l__zrefclever_noabbrev_first_bool
+\keys_define:nn { zref-clever / reference }
+ {
+ abbrev .bool_set:N = \l__zrefclever_abbrev_bool ,
+ abbrev .initial:n = false ,
+ abbrev .default:n = true ,
+ noabbrev .meta:n = { abbrev = false },
+ noabbrev .value_forbidden:n = true ,
+
+ noabbrevfirst .bool_set:N = \l__zrefclever_noabbrev_first_bool ,
+ noabbrevfirst .initial:n = false ,
+ noabbrevfirst .default:n = true ,
+ }
+\keys_define:nn { zref-clever / reference }
+ {
+ S .meta:n =
+ { capfirst = true , noabbrevfirst = true },
+ S .value_forbidden:n = true ,
+ }
+\bool_new:N \l__zrefclever_use_hyperref_bool
+\bool_new:N \l__zrefclever_warn_hyperref_bool
+\keys_define:nn { zref-clever / reference }
+ {
+ hyperref .choice: ,
+ hyperref / auto .code:n =
+ {
+ \bool_set_true:N \l__zrefclever_use_hyperref_bool
+ \bool_set_false:N \l__zrefclever_warn_hyperref_bool
+ } ,
+ hyperref / true .code:n =
+ {
+ \bool_set_true:N \l__zrefclever_use_hyperref_bool
+ \bool_set_true:N \l__zrefclever_warn_hyperref_bool
+ } ,
+ hyperref / false .code:n =
+ {
+ \bool_set_false:N \l__zrefclever_use_hyperref_bool
+ \bool_set_false:N \l__zrefclever_warn_hyperref_bool
+ } ,
+ hyperref .initial:n = auto ,
+ hyperref .default:n = auto
+ }
+\AddToHook { begindocument }
+ {
+ \__zrefclever_if_package_loaded:nTF { hyperref }
+ {
+ \bool_if:NT \l__zrefclever_use_hyperref_bool
+ { \RequirePackage { zref-hyperref } }
+ }
+ {
+ \bool_if:NT \l__zrefclever_warn_hyperref_bool
+ { \msg_warning:nn { zref-clever } { missing-hyperref } }
+ \bool_set_false:N \l__zrefclever_use_hyperref_bool
+ }
+ \keys_define:nn { zref-clever / reference }
+ {
+ hyperref .code:n =
+ { \msg_warning:nn { zref-clever } { hyperref-preamble-only } }
+ }
+ }
+\str_new:N \l__zrefclever_nameinlink_str
+\keys_define:nn { zref-clever / reference }
+ {
+ nameinlink .choice: ,
+ nameinlink / true .code:n =
+ { \str_set:Nn \l__zrefclever_nameinlink_str { true } } ,
+ nameinlink / false .code:n =
+ { \str_set:Nn \l__zrefclever_nameinlink_str { false } } ,
+ nameinlink / single .code:n =
+ { \str_set:Nn \l__zrefclever_nameinlink_str { single } } ,
+ nameinlink / tsingle .code:n =
+ { \str_set:Nn \l__zrefclever_nameinlink_str { tsingle } } ,
+ nameinlink .initial:n = tsingle ,
+ nameinlink .default:n = true ,
+ }
+\bool_new:N \l__zrefclever_preposinlink_bool
+\keys_define:nn { zref-clever / reference }
+ {
+ preposinlink .bool_set:N = \l__zrefclever_preposinlink_bool ,
+ preposinlink .initial:n = false ,
+ preposinlink .default:n = true ,
+ }
+
+\tl_new:N \l__zrefclever_ref_language_tl
+\tl_new:N \l__zrefclever_current_language_tl
+\tl_new:N \l__zrefclever_main_language_tl
+\AddToHook { begindocument }
+ {
+ \__zrefclever_if_package_loaded:nTF { babel }
+ {
+ \tl_set:Nn \l__zrefclever_current_language_tl { \languagename }
+ \tl_set:Nn \l__zrefclever_main_language_tl { \bbl@main@language }
+ }
+ {
+ \__zrefclever_if_package_loaded:nTF { polyglossia }
+ {
+ \tl_set:Nn \l__zrefclever_current_language_tl { \babelname }
+ \tl_set:Nn \l__zrefclever_main_language_tl { \mainbabelname }
+ }
+ {
+ \tl_set:Nn \l__zrefclever_current_language_tl { english }
+ \tl_set:Nn \l__zrefclever_main_language_tl { english }
+ }
+ }
+ \tl_set:Nn \l__zrefclever_ref_language_tl
+ { \l__zrefclever_current_language_tl }
+ }
+\keys_define:nn { zref-clever / reference }
+ {
+ lang .code:n =
+ {
+ \AddToHook { begindocument }
+ {
+ \str_case:nnF {#1}
+ {
+ { current }
+ {
+ \tl_set:Nn \l__zrefclever_ref_language_tl
+ { \l__zrefclever_current_language_tl }
+ \__zrefclever_provide_dictionary_verbose:x
+ { \l__zrefclever_ref_language_tl }
+ }
+
+ { main }
+ {
+ \tl_set:Nn \l__zrefclever_ref_language_tl
+ { \l__zrefclever_main_language_tl }
+ \__zrefclever_provide_dictionary_verbose:x
+ { \l__zrefclever_ref_language_tl }
+ }
+ }
+ {
+ \prop_if_in:NnTF \g__zrefclever_languages_prop {#1}
+ { \tl_set:Nn \l__zrefclever_ref_language_tl {#1} }
+ {
+ \msg_warning:nnn { zref-clever }
+ { unknown-language-opt } {#1}
+ \tl_set:Nn \l__zrefclever_ref_language_tl
+ { \l__zrefclever_current_language_tl }
+ }
+ \__zrefclever_provide_dictionary_verbose:x
+ { \l__zrefclever_ref_language_tl }
+ }
+ }
+ } ,
+ lang .value_required:n = true ,
+ }
+\AddToHook { begindocument / before }
+ {
+ \AddToHook { begindocument }
+ {
+ \__zrefclever_provide_dictionary:x { \l__zrefclever_ref_language_tl }
+ \keys_define:nn { zref-clever / reference }
+ {
+ lang .code:n =
+ {
+ \str_case:nnF {#1}
+ {
+ { current }
+ {
+ \tl_set:Nn \l__zrefclever_ref_language_tl
+ { \l__zrefclever_current_language_tl }
+ \__zrefclever_provide_dictionary:x
+ { \l__zrefclever_ref_language_tl }
+ }
+
+ { main }
+ {
+ \tl_set:Nn \l__zrefclever_ref_language_tl
+ { \l__zrefclever_main_language_tl }
+ \__zrefclever_provide_dictionary:x
+ { \l__zrefclever_ref_language_tl }
+ }
+ }
+ {
+ \prop_if_in:NnTF \g__zrefclever_languages_prop {#1}
+ { \tl_set:Nn \l__zrefclever_ref_language_tl {#1} }
+ {
+ \msg_warning:nnn { zref-clever }
+ { unknown-language-opt } {#1}
+ \tl_set:Nn \l__zrefclever_ref_language_tl
+ { \l__zrefclever_current_language_tl }
+ }
+ \__zrefclever_provide_dictionary:x
+ { \l__zrefclever_ref_language_tl }
+ }
+ } ,
+ lang .value_required:n = true ,
+ }
+ }
+ }
+\tl_new:N \l__zrefclever_ref_decl_case_tl
+\keys_define:nn { zref-clever / reference }
+ {
+ d .code:n =
+ { \msg_warning:nnn { zref-clever } { option-document-only } { d } } ,
+ }
+\AddToHook { begindocument }
+ {
+ \keys_define:nn { zref-clever / reference }
+ {
+ d .tl_set:N = \l__zrefclever_ref_decl_case_tl ,
+ d .value_required:n = true ,
+ }
+ }
+\bool_new:N \l__zrefclever_nudge_enabled_bool
+\bool_new:N \l__zrefclever_nudge_multitype_bool
+\bool_new:N \l__zrefclever_nudge_comptosing_bool
+\bool_new:N \l__zrefclever_nudge_singular_bool
+\bool_new:N \l__zrefclever_nudge_gender_bool
+\tl_new:N \l__zrefclever_ref_gender_tl
+\keys_define:nn { zref-clever / reference }
+ {
+ nudge .choice: ,
+ nudge / true .code:n =
+ { \bool_set_true:N \l__zrefclever_nudge_enabled_bool } ,
+ nudge / false .code:n =
+ { \bool_set_false:N \l__zrefclever_nudge_enabled_bool } ,
+ nudge / ifdraft .code:n =
+ {
+ \ifdraft
+ { \bool_set_false:N \l__zrefclever_nudge_enabled_bool }
+ { \bool_set_true:N \l__zrefclever_nudge_enabled_bool }
+ } ,
+ nudge / iffinal .code:n =
+ {
+ \ifoptionfinal
+ { \bool_set_true:N \l__zrefclever_nudge_enabled_bool }
+ { \bool_set_false:N \l__zrefclever_nudge_enabled_bool }
+ } ,
+ nudge .initial:n = false ,
+ nudge .default:n = true ,
+ nonudge .meta:n = { nudge = false } ,
+ nonudge .value_forbidden:n = true ,
+ nudgeif .code:n =
+ {
+ \bool_set_false:N \l__zrefclever_nudge_multitype_bool
+ \bool_set_false:N \l__zrefclever_nudge_comptosing_bool
+ \bool_set_false:N \l__zrefclever_nudge_gender_bool
+ \clist_map_inline:nn {#1}
+ {
+ \str_case:nnF {##1}
+ {
+ { multitype }
+ { \bool_set_true:N \l__zrefclever_nudge_multitype_bool }
+ { comptosing }
+ { \bool_set_true:N \l__zrefclever_nudge_comptosing_bool }
+ { gender }
+ { \bool_set_true:N \l__zrefclever_nudge_gender_bool }
+ { all }
+ {
+ \bool_set_true:N \l__zrefclever_nudge_multitype_bool
+ \bool_set_true:N \l__zrefclever_nudge_comptosing_bool
+ \bool_set_true:N \l__zrefclever_nudge_gender_bool
+ }
+ }
+ {
+ \msg_warning:nnn { zref-clever }
+ { nudgeif-unknown-value } {##1}
+ }
+ }
+ } ,
+ nudgeif .value_required:n = true ,
+ nudgeif .initial:n = all ,
+ sg .bool_set:N = \l__zrefclever_nudge_singular_bool ,
+ sg .initial:n = false ,
+ sg .default:n = true ,
+ g .code:n =
+ { \msg_warning:nnn { zref-clever } { option-document-only } { g } } ,
+ }
+\AddToHook { begindocument }
+ {
+ \keys_define:nn { zref-clever / reference }
+ {
+ g .tl_set:N = \l__zrefclever_ref_gender_tl ,
+ g .value_required:n = true ,
+ }
+ }
+\tl_new:N \l__zrefclever_ref_typeset_font_tl
+\keys_define:nn { zref-clever / reference }
+ { font .tl_set:N = \l__zrefclever_ref_typeset_font_tl }
+\keys_define:nn { zref-clever / reference }
+ {
+ titleref .code:n = { \RequirePackage { zref-titleref } } ,
+ titleref .value_forbidden:n = true ,
+ }
+\AddToHook { begindocument }
+ {
+ \keys_define:nn { zref-clever / reference }
+ {
+ titleref .code:n =
+ { \msg_warning:nn { zref-clever } { titleref-preamble-only } }
+ }
+ }
+\tl_new:N \l__zrefclever_zcref_note_tl
+\keys_define:nn { zref-clever / reference }
+ {
+ note .tl_set:N = \l__zrefclever_zcref_note_tl ,
+ note .value_required:n = true ,
+ }
+\bool_new:N \l__zrefclever_zrefcheck_available_bool
+\bool_new:N \l__zrefclever_zcref_with_check_bool
+\keys_define:nn { zref-clever / reference }
+ {
+ check .code:n = { \RequirePackage { zref-check } } ,
+ check .value_forbidden:n = true ,
+ }
+\AddToHook { begindocument }
+ {
+ \__zrefclever_if_package_loaded:nTF { zref-check }
+ {
+ \bool_set_true:N \l__zrefclever_zrefcheck_available_bool
+ \keys_define:nn { zref-clever / reference }
+ {
+ check .code:n =
+ {
+ \bool_set_true:N \l__zrefclever_zcref_with_check_bool
+ \keys_set:nn { zref-check / zcheck } {#1}
+ } ,
+ check .value_required:n = true ,
+ }
+ }
+ {
+ \bool_set_false:N \l__zrefclever_zrefcheck_available_bool
+ \keys_define:nn { zref-clever / reference }
+ {
+ check .value_forbidden:n = false ,
+ check .code:n =
+ { \msg_warning:nn { zref-clever } { missing-zref-check } } ,
+ }
+ }
+ }
+\prop_new:N \l__zrefclever_counter_type_prop
+\keys_define:nn { zref-clever / label }
+ {
+ countertype .code:n =
+ {
+ \keyval_parse:nnn
+ {
+ \msg_warning:nnnn { zref-clever }
+ { key-requires-value } { countertype }
+ }
+ {
+ \__zrefclever_prop_put_non_empty:Nnn
+ \l__zrefclever_counter_type_prop
+ }
+ {#1}
+ } ,
+ countertype .value_required:n = true ,
+ countertype .initial:n =
+ {
+ subsection = section ,
+ subsubsection = section ,
+ subparagraph = paragraph ,
+ enumi = item ,
+ enumii = item ,
+ enumiii = item ,
+ enumiv = item ,
+ mpfootnote = footnote ,
+ } ,
+ }
+\seq_new:N \l__zrefclever_counter_resetters_seq
+\keys_define:nn { zref-clever / label }
+ {
+ counterresetters .code:n =
+ {
+ \clist_map_inline:nn {#1}
+ {
+ \seq_if_in:NnF \l__zrefclever_counter_resetters_seq {##1}
+ {
+ \seq_put_right:Nn
+ \l__zrefclever_counter_resetters_seq {##1}
+ }
+ }
+ } ,
+ counterresetters .initial:n =
+ {
+ part ,
+ chapter ,
+ section ,
+ subsection ,
+ subsubsection ,
+ paragraph ,
+ subparagraph ,
+ },
+ counterresetters .value_required:n = true ,
+ }
+\prop_new:N \l__zrefclever_counter_resetby_prop
+\keys_define:nn { zref-clever / label }
+ {
+ counterresetby .code:n =
+ {
+ \keyval_parse:nnn
+ {
+ \msg_warning:nnn { zref-clever }
+ { key-requires-value } { counterresetby }
+ }
+ {
+ \__zrefclever_prop_put_non_empty:Nnn
+ \l__zrefclever_counter_resetby_prop
+ }
+ {#1}
+ } ,
+ counterresetby .value_required:n = true ,
+ counterresetby .initial:n =
+ {
+ enumii = enumi ,
+ enumiii = enumii ,
+ enumiv = enumiii ,
+ } ,
+ }
+\tl_new:N \l__zrefclever_current_counter_tl
+\keys_define:nn { zref-clever / label }
+ {
+ currentcounter .tl_set:N = \l__zrefclever_current_counter_tl ,
+ currentcounter .value_required:n = true ,
+ currentcounter .initial:n = \@currentcounter ,
+ }
+\bool_new:N \g__zrefclever_nocompat_bool
+\seq_new:N \g__zrefclever_nocompat_modules_seq
+\keys_define:nn { zref-clever / reference }
+ {
+ nocompat .code:n =
+ {
+ \tl_if_empty:nTF {#1}
+ { \bool_gset_true:N \g__zrefclever_nocompat_bool }
+ {
+ \clist_map_inline:nn {#1}
+ {
+ \seq_if_in:NnF \g__zrefclever_nocompat_modules_seq {##1}
+ {
+ \seq_gput_right:Nn
+ \g__zrefclever_nocompat_modules_seq {##1}
+ }
+ }
+ }
+ } ,
+ }
+\AddToHook { begindocument }
+ {
+ \keys_define:nn { zref-clever / reference }
+ {
+ nocompat .code:n =
+ {
+ \msg_warning:nnn { zref-clever }
+ { option-preamble-only } { nocompat }
+ }
+ }
+ }
+\AtEndOfPackage
+ {
+ \AddToHook { begindocument }
+ {
+ \seq_map_inline:Nn \g__zrefclever_nocompat_modules_seq
+ { \msg_warning:nnn { zref-clever } { unknown-compat-module } {#1} }
+ }
+ }
+\cs_new_protected:Npn \__zrefclever_compat_module:nn #1#2
+ {
+ \AddToHook { begindocument }
+ {
+ \bool_if:NF \g__zrefclever_nocompat_bool
+ { \seq_if_in:NnF \g__zrefclever_nocompat_modules_seq {#1} {#2} }
+ \seq_gremove_all:Nn \g__zrefclever_nocompat_modules_seq {#1}
+ }
+ }
+\prop_new:N \l__zrefclever_ref_options_prop
+\seq_map_inline:Nn
+ \c__zrefclever_ref_options_reference_seq
+ {
+ \keys_define:nn { zref-clever / reference }
+ {
+ #1 .default:V = \c_novalue_tl ,
+ #1 .code:n =
+ {
+ \tl_if_novalue:nTF {##1}
+ { \prop_remove:Nn \l__zrefclever_ref_options_prop {#1} }
+ { \prop_put:Nnn \l__zrefclever_ref_options_prop {#1} {##1} }
+ } ,
+ }
+ }
+\keys_define:nn { }
+ {
+ zref-clever / zcsetup .inherit:n =
+ {
+ zref-clever / label ,
+ zref-clever / reference ,
+ }
+ }
+\ProcessKeysOptions { zref-clever / zcsetup }
+\NewDocumentCommand \zcsetup { m }
+ { \__zrefclever_zcsetup:n {#1} }
+\cs_new_protected:Npn \__zrefclever_zcsetup:n #1
+ { \keys_set:nn { zref-clever / zcsetup } {#1} }
+\cs_generate_variant:Nn \__zrefclever_zcsetup:n { x }
+\NewDocumentCommand \zcRefTypeSetup { m m }
+ {
+ \prop_if_exist:cF { l__zrefclever_type_ #1 _options_prop }
+ { \prop_new:c { l__zrefclever_type_ #1 _options_prop } }
+ \tl_set:Nn \l__zrefclever_setup_type_tl {#1}
+ \keys_set:nn { zref-clever / typesetup } {#2}
+ }
+\seq_map_inline:Nn
+ \c__zrefclever_ref_options_necessarily_not_type_specific_seq
+ {
+ \keys_define:nn { zref-clever / typesetup }
+ {
+ #1 .code:n =
+ {
+ \msg_warning:nnn { zref-clever }
+ { option-not-type-specific } {#1}
+ } ,
+ }
+ }
+\seq_map_inline:Nn
+ \c__zrefclever_ref_options_typesetup_seq
+ {
+ \keys_define:nn { zref-clever / typesetup }
+ {
+ #1 .default:V = \c_novalue_tl ,
+ #1 .code:n =
+ {
+ \tl_if_novalue:nTF {##1}
+ {
+ \prop_remove:cn
+ {
+ l__zrefclever_type_
+ \l__zrefclever_setup_type_tl _options_prop
+ }
+ {#1}
+ }
+ {
+ \prop_put:cnn
+ {
+ l__zrefclever_type_
+ \l__zrefclever_setup_type_tl _options_prop
+ }
+ {#1} {##1}
+ }
+ } ,
+ }
+ }
+\NewDocumentCommand \zcLanguageSetup { m m }
+ {
+ \group_begin:
+ \prop_get:NnNTF \g__zrefclever_languages_prop {#1}
+ \l__zrefclever_dict_language_tl
+ {
+ \tl_clear:N \l__zrefclever_setup_type_tl
+ \exp_args:NNx \seq_set_from_clist:Nn
+ \l__zrefclever_dict_declension_seq
+ {
+ \prop_item:cn
+ {
+ g__zrefclever_dict_
+ \l__zrefclever_dict_language_tl _prop
+ }
+ { declension }
+ }
+ \seq_if_empty:NTF \l__zrefclever_dict_declension_seq
+ { \tl_clear:N \l__zrefclever_dict_decl_case_tl }
+ {
+ \seq_get_left:NN \l__zrefclever_dict_declension_seq
+ \l__zrefclever_dict_decl_case_tl
+ }
+ \exp_args:NNx \seq_set_from_clist:Nn
+ \l__zrefclever_dict_gender_seq
+ {
+ \prop_item:cn
+ {
+ g__zrefclever_dict_
+ \l__zrefclever_dict_language_tl _prop
+ }
+ { gender }
+ }
+ \keys_set:nn { zref-clever / langsetup } {#2}
+ }
+ { \msg_warning:nnn { zref-clever } { unknown-language-setup } {#1} }
+ \group_end:
+ }
+\@onlypreamble \zcLanguageSetup
+\cs_new_protected:Npn \__zrefclever_declare_type_transl:nnnn #1#2#3#4
+ {
+ \prop_gput:cnn { g__zrefclever_dict_ #1 _prop }
+ { type- #2 - #3 } {#4}
+ }
+\cs_generate_variant:Nn \__zrefclever_declare_type_transl:nnnn { VVnn , VVxn }
+\cs_new_protected:Npn \__zrefclever_declare_default_transl:nnn #1#2#3
+ {
+ \prop_gput:cnn { g__zrefclever_dict_ #1 _prop }
+ { default- #2 } {#3}
+ }
+\cs_generate_variant:Nn \__zrefclever_declare_default_transl:nnn { Vnn }
+\keys_define:nn { zref-clever / langsetup }
+ {
+ type .code:n =
+ {
+ \tl_if_empty:nTF {#1}
+ { \tl_clear:N \l__zrefclever_setup_type_tl }
+ { \tl_set:Nn \l__zrefclever_setup_type_tl {#1} }
+ } ,
+ case .code:n =
+ {
+ \seq_if_empty:NTF \l__zrefclever_dict_declension_seq
+ {
+ \msg_warning:nnxx { zref-clever } { language-no-decl-setup }
+ { \l__zrefclever_dict_language_tl } {#1}
+ }
+ {
+ \seq_if_in:NnTF \l__zrefclever_dict_declension_seq {#1}
+ { \tl_set:Nn \l__zrefclever_dict_decl_case_tl {#1} }
+ {
+ \msg_warning:nnxx { zref-clever } { unknown-decl-case }
+ {#1} { \l__zrefclever_dict_language_tl }
+ \seq_get_left:NN \l__zrefclever_dict_declension_seq
+ \l__zrefclever_dict_decl_case_tl
+ }
+ }
+ } ,
+ case .value_required:n = true ,
+ gender .code:n =
+ {
+ \seq_if_empty:NTF \l__zrefclever_dict_gender_seq
+ {
+ \msg_warning:nnxxx { zref-clever } { language-no-gender }
+ { \l__zrefclever_dict_language_tl } { gender } {#1}
+ }
+ {
+ \tl_if_empty:NTF \l__zrefclever_setup_type_tl
+ {
+ \msg_warning:nnn { zref-clever }
+ { option-only-type-specific } { gender }
+ }
+ {
+ \seq_if_in:NnTF \l__zrefclever_dict_gender_seq {#1}
+ {
+ \__zrefclever_declare_type_transl:VVnn
+ \l__zrefclever_dict_language_tl
+ \l__zrefclever_setup_type_tl
+ { gender } {#1}
+ }
+ {
+ \msg_warning:nnxx { zref-clever } { gender-not-declared }
+ { \l__zrefclever_dict_language_tl } {#1}
+ }
+ }
+ }
+ } ,
+ gender .value_required:n = true ,
+ }
+\seq_map_inline:Nn
+ \c__zrefclever_ref_options_necessarily_not_type_specific_seq
+ {
+ \keys_define:nn { zref-clever / langsetup }
+ {
+ #1 .value_required:n = true ,
+ #1 .code:n =
+ {
+ \tl_if_empty:NTF \l__zrefclever_setup_type_tl
+ {
+ \__zrefclever_declare_default_transl:Vnn
+ \l__zrefclever_dict_language_tl
+ {#1} {##1}
+ }
+ {
+ \msg_warning:nnn { zref-clever }
+ { option-not-type-specific } {#1}
+ }
+ } ,
+ }
+ }
+\seq_map_inline:Nn
+ \c__zrefclever_ref_options_possibly_type_specific_seq
+ {
+ \keys_define:nn { zref-clever / langsetup }
+ {
+ #1 .value_required:n = true ,
+ #1 .code:n =
+ {
+ \tl_if_empty:NTF \l__zrefclever_setup_type_tl
+ {
+ \__zrefclever_declare_default_transl:Vnn
+ \l__zrefclever_dict_language_tl
+ {#1} {##1}
+ }
+ {
+ \__zrefclever_declare_type_transl:VVnn
+ \l__zrefclever_dict_language_tl
+ \l__zrefclever_setup_type_tl
+ {#1} {##1}
+ }
+ } ,
+ }
+ }
+\seq_map_inline:Nn
+ \c__zrefclever_ref_options_type_names_seq
+ {
+ \keys_define:nn { zref-clever / langsetup }
+ {
+ #1 .value_required:n = true ,
+ #1 .code:n =
+ {
+ \tl_if_empty:NTF \l__zrefclever_setup_type_tl
+ {
+ \msg_warning:nnn { zref-clever }
+ { option-only-type-specific } {#1}
+ }
+ {
+ \tl_if_empty:NTF \l__zrefclever_dict_decl_case_tl
+ {
+ \__zrefclever_declare_type_transl:VVnn
+ \l__zrefclever_dict_language_tl
+ \l__zrefclever_setup_type_tl
+ {#1} {##1}
+ }
+ {
+ \__zrefclever_declare_type_transl:VVxn
+ \l__zrefclever_dict_language_tl
+ \l__zrefclever_setup_type_tl
+ { \l__zrefclever_dict_decl_case_tl - #1 } {##1}
+ }
+ }
+ } ,
+ }
+ }
+\NewDocumentCommand \zcref { s O { } m }
+ { \zref@wrapper@babel \__zrefclever_zcref:nnn {#3} {#1} {#2} }
+\cs_new_protected:Npn \__zrefclever_zcref:nnn #1#2#3
+ {
+ \group_begin:
+ \keys_set:nn { zref-clever / reference } {#3}
+ \seq_set_from_clist:Nn \l__zrefclever_zcref_labels_seq {#1}
+ \bool_set:Nn \l__zrefclever_link_star_bool {#2}
+ \__zrefclever_provide_dictionary:x { \l__zrefclever_ref_language_tl }
+ \__zrefclever_process_language_options:
+ \bool_lazy_and:nnT
+ { \l__zrefclever_zrefcheck_available_bool }
+ { \l__zrefclever_zcref_with_check_bool }
+ { \zrefcheck_zcref_beg_label: }
+ \bool_lazy_or:nnT
+ { \l__zrefclever_typeset_sort_bool }
+ { \l__zrefclever_typeset_range_bool }
+ { \__zrefclever_sort_labels: }
+ \group_begin:
+ \l__zrefclever_ref_typeset_font_tl
+ \__zrefclever_typeset_refs:
+ \group_end:
+ \tl_if_empty:NF \l__zrefclever_zcref_note_tl
+ {
+ \__zrefclever_get_ref_string:nN { notesep } \l_tmpa_tl
+ \l_tmpa_tl
+ \l__zrefclever_zcref_note_tl
+ }
+ \bool_lazy_and:nnT
+ { \l__zrefclever_zrefcheck_available_bool }
+ { \l__zrefclever_zcref_with_check_bool }
+ {
+ \zrefcheck_zcref_end_label_maybe:
+ \zrefcheck_zcref_run_checks_on_labels:n
+ { \l__zrefclever_zcref_labels_seq }
+ }
+ \bool_if:NT \l__zrefclever_mathtools_showonlyrefs_bool
+ {
+ \__zrefclever_mathtools_showonlyrefs:n
+ { \l__zrefclever_zcref_labels_seq }
+ }
+ \group_end:
+ }
+\seq_new:N \l__zrefclever_zcref_labels_seq
+\bool_new:N \l__zrefclever_link_star_bool
+\NewDocumentCommand \zcpageref { s O { } m }
+ {
+ \IfBooleanTF {#1}
+ { \zcref*[#2, ref = page] {#3} }
+ { \zcref [#2, ref = page] {#3} }
+ }
+\tl_new:N \l__zrefclever_label_type_a_tl
+\tl_new:N \l__zrefclever_label_type_b_tl
+\tl_new:N \l__zrefclever_label_enclval_a_tl
+\tl_new:N \l__zrefclever_label_enclval_b_tl
+\tl_new:N \l__zrefclever_label_extdoc_a_tl
+\tl_new:N \l__zrefclever_label_extdoc_b_tl
+\bool_new:N \l__zrefclever_sort_decided_bool
+\int_new:N \l__zrefclever_sort_prior_a_int
+\int_new:N \l__zrefclever_sort_prior_b_int
+\seq_new:N \l__zrefclever_label_types_seq
+\cs_new_protected:Npn \__zrefclever_sort_labels:
+ {
+ \seq_clear:N \l__zrefclever_label_types_seq
+ \tl_if_eq:NnF \l__zrefclever_ref_property_tl { page }
+ {
+ \seq_map_function:NN \l__zrefclever_zcref_labels_seq
+ \__zrefclever_label_type_put_new_right:n
+ }
+ \seq_sort:Nn \l__zrefclever_zcref_labels_seq
+ {
+ \zref@ifrefundefined {##1}
+ {
+ \zref@ifrefundefined {##2}
+ {
+ % Neither label is defined.
+ \sort_return_same:
+ }
+ {
+ % The second label is defined, but the first isn't, leave the
+ % undefined first (to be more visible).
+ \sort_return_same:
+ }
+ }
+ {
+ \zref@ifrefundefined {##2}
+ {
+ % The first label is defined, but the second isn't, bring the
+ % second forward.
+ \sort_return_swapped:
+ }
+ {
+ % The interesting case: both labels are defined. References
+ % to the "default" property or to the "page" are quite
+ % different with regard to sorting, so we branch them here to
+ % specialized functions.
+ \tl_if_eq:NnTF \l__zrefclever_ref_property_tl { page }
+ { \__zrefclever_sort_page:nn {##1} {##2} }
+ { \__zrefclever_sort_default:nn {##1} {##2} }
+ }
+ }
+ }
+ }
+\cs_new_protected:Npn \__zrefclever_label_type_put_new_right:n #1
+ {
+ \__zrefclever_def_extract:Nnnn
+ \l__zrefclever_label_type_a_tl {#1} { zc@type } { \c_empty_tl }
+ \seq_if_in:NVF \l__zrefclever_label_types_seq
+ \l__zrefclever_label_type_a_tl
+ {
+ \seq_put_right:NV \l__zrefclever_label_types_seq
+ \l__zrefclever_label_type_a_tl
+ }
+ }
+\cs_new_protected:Npn \__zrefclever_sort_default:nn #1#2
+ {
+ \__zrefclever_def_extract:Nnnn
+ \l__zrefclever_label_type_a_tl {#1} { zc@type } { zc@missingtype }
+ \__zrefclever_def_extract:Nnnn
+ \l__zrefclever_label_type_b_tl {#2} { zc@type } { zc@missingtype }
+
+ \tl_if_eq:NNTF
+ \l__zrefclever_label_type_a_tl
+ \l__zrefclever_label_type_b_tl
+ { \__zrefclever_sort_default_same_type:nn {#1} {#2} }
+ { \__zrefclever_sort_default_different_types:nn {#1} {#2} }
+ }
+\cs_new_protected:Npn \__zrefclever_sort_default_same_type:nn #1#2
+ {
+ \__zrefclever_def_extract:Nnnn \l__zrefclever_label_enclval_a_tl
+ {#1} { zc@enclval } { \c_empty_tl }
+ \tl_reverse:N \l__zrefclever_label_enclval_a_tl
+ \__zrefclever_def_extract:Nnnn \l__zrefclever_label_enclval_b_tl
+ {#2} { zc@enclval } { \c_empty_tl }
+ \tl_reverse:N \l__zrefclever_label_enclval_b_tl
+ \__zrefclever_def_extract:Nnnn \l__zrefclever_label_extdoc_a_tl
+ {#1} { externaldocument } { \c_empty_tl }
+ \__zrefclever_def_extract:Nnnn \l__zrefclever_label_extdoc_b_tl
+ {#2} { externaldocument } { \c_empty_tl }
+
+ \bool_set_false:N \l__zrefclever_sort_decided_bool
+
+ % First we check if there's any "external document" difference (coming
+ % from 'zref-xr') and, if so, sort based on that.
+ \tl_if_eq:NNF
+ \l__zrefclever_label_extdoc_a_tl
+ \l__zrefclever_label_extdoc_b_tl
+ {
+ \bool_if:nTF
+ {
+ \tl_if_empty_p:V \l__zrefclever_label_extdoc_a_tl &&
+ ! \tl_if_empty_p:V \l__zrefclever_label_extdoc_b_tl
+ }
+ {
+ \bool_set_true:N \l__zrefclever_sort_decided_bool
+ \sort_return_same:
+ }
+ {
+ \bool_if:nTF
+ {
+ ! \tl_if_empty_p:V \l__zrefclever_label_extdoc_a_tl &&
+ \tl_if_empty_p:V \l__zrefclever_label_extdoc_b_tl
+ }
+ {
+ \bool_set_true:N \l__zrefclever_sort_decided_bool
+ \sort_return_swapped:
+ }
+ {
+ \bool_set_true:N \l__zrefclever_sort_decided_bool
+ % Two different "external documents": last resort, sort by the
+ % document name itself.
+ \str_compare:eNeTF
+ { \l__zrefclever_label_extdoc_b_tl } <
+ { \l__zrefclever_label_extdoc_a_tl }
+ { \sort_return_swapped: }
+ { \sort_return_same: }
+ }
+ }
+ }
+
+ \bool_until_do:Nn \l__zrefclever_sort_decided_bool
+ {
+ \bool_if:nTF
+ {
+ % Both are empty: neither label has any (further) "enclosing
+ % counters" (left).
+ \tl_if_empty_p:V \l__zrefclever_label_enclval_a_tl &&
+ \tl_if_empty_p:V \l__zrefclever_label_enclval_b_tl
+ }
+ {
+ \bool_set_true:N \l__zrefclever_sort_decided_bool
+ \int_compare:nNnTF
+ { \__zrefclever_extract:nnn {#1} { zc@cntval } { -1 } }
+ >
+ { \__zrefclever_extract:nnn {#2} { zc@cntval } { -1 } }
+ { \sort_return_swapped: }
+ { \sort_return_same: }
+ }
+ {
+ \bool_if:nTF
+ {
+ % `a' is empty (and `b' is not): `b' may be nested in `a'.
+ \tl_if_empty_p:V \l__zrefclever_label_enclval_a_tl
+ }
+ {
+ \bool_set_true:N \l__zrefclever_sort_decided_bool
+ \int_compare:nNnTF
+ { \__zrefclever_extract:nnn {#1} { zc@cntval } { } }
+ >
+ { \tl_head:N \l__zrefclever_label_enclval_b_tl }
+ { \sort_return_swapped: }
+ { \sort_return_same: }
+ }
+ {
+ \bool_if:nTF
+ {
+ % `b' is empty (and `a' is not): `a' may be nested in `b'.
+ \tl_if_empty_p:V \l__zrefclever_label_enclval_b_tl
+ }
+ {
+ \bool_set_true:N \l__zrefclever_sort_decided_bool
+ \int_compare:nNnTF
+ { \tl_head:N \l__zrefclever_label_enclval_a_tl }
+ <
+ { \__zrefclever_extract:nnn {#2} { zc@cntval } { } }
+ { \sort_return_same: }
+ { \sort_return_swapped: }
+ }
+ {
+ % Neither is empty: we can compare the values of the
+ % current enclosing counter in the loop, if they are
+ % equal, we are still in the loop, if they are not, a
+ % sorting decision can be made directly.
+ \int_compare:nNnTF
+ { \tl_head:N \l__zrefclever_label_enclval_a_tl }
+ =
+ { \tl_head:N \l__zrefclever_label_enclval_b_tl }
+ {
+ \tl_set:Nx \l__zrefclever_label_enclval_a_tl
+ { \tl_tail:N \l__zrefclever_label_enclval_a_tl }
+ \tl_set:Nx \l__zrefclever_label_enclval_b_tl
+ { \tl_tail:N \l__zrefclever_label_enclval_b_tl }
+ }
+ {
+ \bool_set_true:N \l__zrefclever_sort_decided_bool
+ \int_compare:nNnTF
+ { \tl_head:N \l__zrefclever_label_enclval_a_tl }
+ >
+ { \tl_head:N \l__zrefclever_label_enclval_b_tl }
+ { \sort_return_swapped: }
+ { \sort_return_same: }
+ }
+ }
+ }
+ }
+ }
+ }
+\cs_new_protected:Npn \__zrefclever_sort_default_different_types:nn #1#2
+ {
+ \int_zero:N \l__zrefclever_sort_prior_a_int
+ \int_zero:N \l__zrefclever_sort_prior_b_int
+ \seq_map_indexed_inline:Nn \l__zrefclever_typesort_seq
+ {
+ \tl_if_eq:nnTF {##2} {{othertypes}}
+ {
+ \int_compare:nNnT { \l__zrefclever_sort_prior_a_int } = { 0 }
+ { \int_set:Nn \l__zrefclever_sort_prior_a_int { - ##1 } }
+ \int_compare:nNnT { \l__zrefclever_sort_prior_b_int } = { 0 }
+ { \int_set:Nn \l__zrefclever_sort_prior_b_int { - ##1 } }
+ }
+ {
+ \tl_if_eq:NnTF \l__zrefclever_label_type_a_tl {##2}
+ { \int_set:Nn \l__zrefclever_sort_prior_a_int { - ##1 } }
+ {
+ \tl_if_eq:NnT \l__zrefclever_label_type_b_tl {##2}
+ { \int_set:Nn \l__zrefclever_sort_prior_b_int { - ##1 } }
+ }
+ }
+ }
+ \bool_if:nTF
+ {
+ \int_compare_p:nNn
+ { \l__zrefclever_sort_prior_a_int } <
+ { \l__zrefclever_sort_prior_b_int }
+ }
+ { \sort_return_same: }
+ {
+ \bool_if:nTF
+ {
+ \int_compare_p:nNn
+ { \l__zrefclever_sort_prior_a_int } >
+ { \l__zrefclever_sort_prior_b_int }
+ }
+ { \sort_return_swapped: }
+ {
+ % Sort priorities are equal: the type that occurs first in
+ % `labels', as given by the user, is kept (or brought) forward.
+ \seq_map_inline:Nn \l__zrefclever_label_types_seq
+ {
+ \tl_if_eq:NnTF \l__zrefclever_label_type_a_tl {##1}
+ { \seq_map_break:n { \sort_return_same: } }
+ {
+ \tl_if_eq:NnT \l__zrefclever_label_type_b_tl {##1}
+ { \seq_map_break:n { \sort_return_swapped: } }
+ }
+ }
+ }
+ }
+ }
+\cs_new_protected:Npn \__zrefclever_sort_page:nn #1#2
+ {
+ \int_compare:nNnTF
+ { \__zrefclever_extract:nnn {#1} { abspage } { -1 } }
+ >
+ { \__zrefclever_extract:nnn {#2} { abspage } { -1 } }
+ { \sort_return_swapped: }
+ { \sort_return_same: }
+ }
+\seq_new:N \l__zrefclever_typeset_labels_seq
+\bool_new:N \l__zrefclever_typeset_last_bool
+\bool_new:N \l__zrefclever_last_of_type_bool
+\int_new:N \l__zrefclever_type_count_int
+\int_new:N \l__zrefclever_label_count_int
+\tl_new:N \l__zrefclever_label_a_tl
+\tl_new:N \l__zrefclever_label_b_tl
+\tl_new:N \l__zrefclever_typeset_queue_prev_tl
+\tl_new:N \l__zrefclever_typeset_queue_curr_tl
+\tl_new:N \l__zrefclever_type_first_label_tl
+\tl_new:N \l__zrefclever_type_first_label_type_tl
+\tl_new:N \l__zrefclever_type_name_tl
+\bool_new:N \l__zrefclever_name_in_link_bool
+\tl_new:N \l__zrefclever_name_format_tl
+\tl_new:N \l__zrefclever_name_format_fallback_tl
+\tl_new:N \l__zrefclever_type_name_gender_tl
+\int_new:N \l__zrefclever_range_count_int
+\int_new:N \l__zrefclever_range_same_count_int
+\tl_new:N \l__zrefclever_range_beg_label_tl
+\bool_new:N \l__zrefclever_next_maybe_range_bool
+\bool_new:N \l__zrefclever_next_is_same_bool
+\tl_new:N \l__zrefclever_tpairsep_tl
+\tl_new:N \l__zrefclever_tlistsep_tl
+\tl_new:N \l__zrefclever_tlastsep_tl
+\tl_new:N \l__zrefclever_namesep_tl
+\tl_new:N \l__zrefclever_pairsep_tl
+\tl_new:N \l__zrefclever_listsep_tl
+\tl_new:N \l__zrefclever_lastsep_tl
+\tl_new:N \l__zrefclever_rangesep_tl
+\tl_new:N \l__zrefclever_refpre_tl
+\tl_new:N \l__zrefclever_refpos_tl
+\tl_new:N \l__zrefclever_namefont_tl
+\tl_new:N \l__zrefclever_reffont_tl
+\bool_new:N \l__zrefclever_verbose_testing_bool
+\cs_new_protected:Npn \__zrefclever_typeset_refs:
+ {
+ \seq_set_eq:NN \l__zrefclever_typeset_labels_seq
+ \l__zrefclever_zcref_labels_seq
+ \tl_clear:N \l__zrefclever_typeset_queue_prev_tl
+ \tl_clear:N \l__zrefclever_typeset_queue_curr_tl
+ \tl_clear:N \l__zrefclever_type_first_label_tl
+ \tl_clear:N \l__zrefclever_type_first_label_type_tl
+ \tl_clear:N \l__zrefclever_range_beg_label_tl
+ \int_zero:N \l__zrefclever_label_count_int
+ \int_zero:N \l__zrefclever_type_count_int
+ \int_zero:N \l__zrefclever_range_count_int
+ \int_zero:N \l__zrefclever_range_same_count_int
+
+ % Get type block options (not type-specific).
+ \__zrefclever_get_ref_string:nN { tpairsep }
+ \l__zrefclever_tpairsep_tl
+ \__zrefclever_get_ref_string:nN { tlistsep }
+ \l__zrefclever_tlistsep_tl
+ \__zrefclever_get_ref_string:nN { tlastsep }
+ \l__zrefclever_tlastsep_tl
+
+ % Process label stack.
+ \bool_set_false:N \l__zrefclever_typeset_last_bool
+ \bool_until_do:Nn \l__zrefclever_typeset_last_bool
+ {
+ \seq_pop_left:NN \l__zrefclever_typeset_labels_seq
+ \l__zrefclever_label_a_tl
+ \seq_if_empty:NTF \l__zrefclever_typeset_labels_seq
+ {
+ \tl_clear:N \l__zrefclever_label_b_tl
+ \bool_set_true:N \l__zrefclever_typeset_last_bool
+ }
+ {
+ \seq_get_left:NN \l__zrefclever_typeset_labels_seq
+ \l__zrefclever_label_b_tl
+ }
+
+ \tl_if_eq:NnTF \l__zrefclever_ref_property_tl { page }
+ {
+ \tl_set:Nn \l__zrefclever_label_type_a_tl { page }
+ \tl_set:Nn \l__zrefclever_label_type_b_tl { page }
+ }
+ {
+ \__zrefclever_def_extract:NVnn \l__zrefclever_label_type_a_tl
+ \l__zrefclever_label_a_tl { zc@type } { zc@missingtype }
+ \__zrefclever_def_extract:NVnn \l__zrefclever_label_type_b_tl
+ \l__zrefclever_label_b_tl { zc@type } { zc@missingtype }
+ }
+
+ % First, we establish whether the "current label" (i.e. `a') is the
+ % last one of its type. This can happen because the "next label"
+ % (i.e. `b') is of a different type (or different definition status),
+ % or because we are at the end of the list.
+ \bool_if:NTF \l__zrefclever_typeset_last_bool
+ { \bool_set_true:N \l__zrefclever_last_of_type_bool }
+ {
+ \zref@ifrefundefined { \l__zrefclever_label_a_tl }
+ {
+ \zref@ifrefundefined { \l__zrefclever_label_b_tl }
+ { \bool_set_false:N \l__zrefclever_last_of_type_bool }
+ { \bool_set_true:N \l__zrefclever_last_of_type_bool }
+ }
+ {
+ \zref@ifrefundefined { \l__zrefclever_label_b_tl }
+ { \bool_set_true:N \l__zrefclever_last_of_type_bool }
+ {
+ % Neither is undefined, we must check the types.
+ \tl_if_eq:NNTF
+ \l__zrefclever_label_type_a_tl
+ \l__zrefclever_label_type_b_tl
+ { \bool_set_false:N \l__zrefclever_last_of_type_bool }
+ { \bool_set_true:N \l__zrefclever_last_of_type_bool }
+ }
+ }
+ }
+
+ % Handle warnings in case of reference or type undefined.
+ % Test: 'zc-typeset01.lvt': "Typeset refs: warn ref undefined"
+ \zref@refused { \l__zrefclever_label_a_tl }
+ % Test: 'zc-typeset01.lvt': "Typeset refs: warn missing type"
+ \zref@ifrefundefined { \l__zrefclever_label_a_tl }
+ {}
+ {
+ \tl_if_eq:NnT \l__zrefclever_label_type_a_tl { zc@missingtype }
+ {
+ \msg_warning:nnx { zref-clever } { missing-type }
+ { \l__zrefclever_label_a_tl }
+ }
+ \zref@ifrefcontainsprop
+ { \l__zrefclever_label_a_tl }
+ { \l__zrefclever_ref_property_tl }
+ { }
+ {
+ \msg_warning:nnxx { zref-clever } { missing-property }
+ { \l__zrefclever_ref_property_tl }
+ { \l__zrefclever_label_a_tl }
+ }
+ }
+
+ % Get type-specific separators, refpre/pos and font options, once per
+ % type.
+ \int_compare:nNnT { \l__zrefclever_label_count_int } = { 0 }
+ {
+ \__zrefclever_get_ref_string:nN { namesep }
+ \l__zrefclever_namesep_tl
+ \__zrefclever_get_ref_string:nN { pairsep }
+ \l__zrefclever_pairsep_tl
+ \__zrefclever_get_ref_string:nN { listsep }
+ \l__zrefclever_listsep_tl
+ \__zrefclever_get_ref_string:nN { lastsep }
+ \l__zrefclever_lastsep_tl
+ \__zrefclever_get_ref_string:nN { rangesep }
+ \l__zrefclever_rangesep_tl
+ \__zrefclever_get_ref_string:nN { refpre }
+ \l__zrefclever_refpre_tl
+ \__zrefclever_get_ref_string:nN { refpos }
+ \l__zrefclever_refpos_tl
+ \__zrefclever_get_ref_font:nN { namefont }
+ \l__zrefclever_namefont_tl
+ \__zrefclever_get_ref_font:nN { reffont }
+ \l__zrefclever_reffont_tl
+ }
+
+ % Here we send this to a couple of auxiliary functions.
+ \bool_if:NTF \l__zrefclever_last_of_type_bool
+ % There exists no next label of the same type as the current.
+ { \__zrefclever_typeset_refs_last_of_type: }
+ % There exists a next label of the same type as the current.
+ { \__zrefclever_typeset_refs_not_last_of_type: }
+ }
+ }
+\cs_new_protected:Npn \__zrefclever_typeset_refs_last_of_type:
+ {
+ % Process the current label to the current queue.
+ \int_case:nnF { \l__zrefclever_label_count_int }
+ {
+ % It is the last label of its type, but also the first one, and that's
+ % what matters here: just store it.
+ % Test: 'zc-typeset01.lvt': "Last of type: single"
+ { 0 }
+ {
+ \tl_set:NV \l__zrefclever_type_first_label_tl
+ \l__zrefclever_label_a_tl
+ \tl_set:NV \l__zrefclever_type_first_label_type_tl
+ \l__zrefclever_label_type_a_tl
+ }
+
+ % The last is the second: we have a pair (if not repeated).
+ % Test: 'zc-typeset01.lvt': "Last of type: pair"
+ { 1 }
+ {
+ \int_compare:nNnF { \l__zrefclever_range_same_count_int } = { 1 }
+ {
+ \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+ {
+ \exp_not:V \l__zrefclever_pairsep_tl
+ \__zrefclever_get_ref:V \l__zrefclever_label_a_tl
+ }
+ }
+ }
+ }
+ % Last is third or more of its type: without repetition, we'd have the
+ % last element on a list, but control for possible repetition.
+ {
+ \int_case:nnF { \l__zrefclever_range_count_int }
+ {
+ % There was no range going on.
+ % Test: 'zc-typeset01.lvt': "Last of type: not range"
+ { 0 }
+ {
+ \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+ {
+ \exp_not:V \l__zrefclever_lastsep_tl
+ \__zrefclever_get_ref:V \l__zrefclever_label_a_tl
+ }
+ }
+ % Last in the range is also the second in it.
+ % Test: 'zc-typeset01.lvt': "Last of type: pair in sequence"
+ { 1 }
+ {
+ \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+ {
+ % We know `range_beg_label' is not empty, since this is the
+ % second element in the range, but the third or more in the
+ % type list.
+ \exp_not:V \l__zrefclever_listsep_tl
+ \__zrefclever_get_ref:V \l__zrefclever_range_beg_label_tl
+ \int_compare:nNnF
+ { \l__zrefclever_range_same_count_int } = { 1 }
+ {
+ \exp_not:V \l__zrefclever_lastsep_tl
+ \__zrefclever_get_ref:V \l__zrefclever_label_a_tl
+ }
+ }
+ }
+ }
+ % Last in the range is third or more in it.
+ {
+ \int_case:nnF
+ {
+ \l__zrefclever_range_count_int -
+ \l__zrefclever_range_same_count_int
+ }
+ {
+ % Repetition, not a range.
+ % Test: 'zc-typeset01.lvt': "Last of type: range to one"
+ { 0 }
+ {
+ % If `range_beg_label' is empty, it means it was also the
+ % first of the type, and hence was already handled.
+ \tl_if_empty:VF \l__zrefclever_range_beg_label_tl
+ {
+ \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+ {
+ \exp_not:V \l__zrefclever_lastsep_tl
+ \__zrefclever_get_ref:V
+ \l__zrefclever_range_beg_label_tl
+ }
+ }
+ }
+ % A `range', but with no skipped value, treat as list.
+ % Test: 'zc-typeset01.lvt': "Last of type: range to pair"
+ { 1 }
+ {
+ \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+ {
+ % Ditto.
+ \tl_if_empty:VF \l__zrefclever_range_beg_label_tl
+ {
+ \exp_not:V \l__zrefclever_listsep_tl
+ \__zrefclever_get_ref:V
+ \l__zrefclever_range_beg_label_tl
+ }
+ \exp_not:V \l__zrefclever_lastsep_tl
+ \__zrefclever_get_ref:V \l__zrefclever_label_a_tl
+ }
+ }
+ }
+ {
+ % An actual range.
+ % Test: 'zc-typeset01.lvt': "Last of type: range"
+ \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+ {
+ % Ditto.
+ \tl_if_empty:VF \l__zrefclever_range_beg_label_tl
+ {
+ \exp_not:V \l__zrefclever_lastsep_tl
+ \__zrefclever_get_ref:V
+ \l__zrefclever_range_beg_label_tl
+ }
+ \exp_not:V \l__zrefclever_rangesep_tl
+ \__zrefclever_get_ref:V \l__zrefclever_label_a_tl
+ }
+ }
+ }
+ }
+
+ % Handle "range" option. The idea is simple: if the queue is not empty,
+ % we replace it with the end of the range (or pair). We can still
+ % retrieve the end of the range from `label_a' since we know to be
+ % processing the last label of its type at this point.
+ \bool_if:NT \l__zrefclever_typeset_range_bool
+ {
+ \tl_if_empty:NTF \l__zrefclever_typeset_queue_curr_tl
+ {
+ \zref@ifrefundefined { \l__zrefclever_type_first_label_tl }
+ { }
+ {
+ \msg_warning:nnx { zref-clever } { single-element-range }
+ { \l__zrefclever_type_first_label_type_tl }
+ }
+ }
+ {
+ \bool_set_false:N \l__zrefclever_next_maybe_range_bool
+ \zref@ifrefundefined { \l__zrefclever_type_first_label_tl }
+ { }
+ {
+ \__zrefclever_labels_in_sequence:nn
+ { \l__zrefclever_type_first_label_tl }
+ { \l__zrefclever_label_a_tl }
+ }
+ % Test: 'zc-typeset01.lvt': "Last of type: option range"
+ % Test: 'zc-typeset01.lvt': "Last of type: option range to pair"
+ \tl_set:Nx \l__zrefclever_typeset_queue_curr_tl
+ {
+ \bool_if:NTF \l__zrefclever_next_maybe_range_bool
+ { \exp_not:V \l__zrefclever_pairsep_tl }
+ { \exp_not:V \l__zrefclever_rangesep_tl }
+ \__zrefclever_get_ref:V \l__zrefclever_label_a_tl
+ }
+ }
+ }
+
+ % Now that the type block is finished, we can add the name and the first
+ % ref to the queue. Also, if "typeset" option is not "both", handle it
+ % here as well.
+ \__zrefclever_type_name_setup:
+ \bool_if:nTF
+ { \l__zrefclever_typeset_ref_bool && \l__zrefclever_typeset_name_bool }
+ {
+ \tl_put_left:Nx \l__zrefclever_typeset_queue_curr_tl
+ { \__zrefclever_get_ref_first: }
+ }
+ {
+ \bool_if:NTF \l__zrefclever_typeset_ref_bool
+ {
+ % Test: 'zc-typeset01.lvt': "Last of type: option typeset ref"
+ \tl_put_left:Nx \l__zrefclever_typeset_queue_curr_tl
+ { \__zrefclever_get_ref:V \l__zrefclever_type_first_label_tl }
+ }
+ {
+ \bool_if:NTF \l__zrefclever_typeset_name_bool
+ {
+ % Test: 'zc-typeset01.lvt': "Last of type: option typeset name"
+ \tl_set:Nx \l__zrefclever_typeset_queue_curr_tl
+ {
+ \bool_if:NTF \l__zrefclever_name_in_link_bool
+ {
+ \exp_not:N \group_begin:
+ \exp_not:V \l__zrefclever_namefont_tl
+ % It's two '@s', but escaped for DocStrip.
+ \exp_not:N \hyper@@link
+ {
+ \__zrefclever_extract_url_unexp:V
+ \l__zrefclever_type_first_label_tl
+ }
+ {
+ \__zrefclever_extract_unexp:Vnn
+ \l__zrefclever_type_first_label_tl
+ { anchor } { }
+ }
+ { \exp_not:V \l__zrefclever_type_name_tl }
+ \exp_not:N \group_end:
+ }
+ {
+ \exp_not:N \group_begin:
+ \exp_not:V \l__zrefclever_namefont_tl
+ \exp_not:V \l__zrefclever_type_name_tl
+ \exp_not:N \group_end:
+ }
+ }
+ }
+ {
+ % Logically, this case would correspond to "typeset=none", but
+ % it should not occur, given that the options are set up to
+ % typeset either "ref" or "name". Still, leave here a
+ % sensible fallback, equal to the behavior of "both".
+ % Test: 'zc-typeset01.lvt': "Last of type: option typeset none"
+ \tl_put_left:Nx \l__zrefclever_typeset_queue_curr_tl
+ { \__zrefclever_get_ref_first: }
+ }
+ }
+ }
+
+ % Typeset the previous type block, if there is one.
+ \int_compare:nNnT { \l__zrefclever_type_count_int } > { 0 }
+ {
+ \int_compare:nNnT { \l__zrefclever_type_count_int } > { 1 }
+ { \l__zrefclever_tlistsep_tl }
+ \l__zrefclever_typeset_queue_prev_tl
+ }
+
+ % Extra log for testing.
+ \bool_if:NT \l__zrefclever_verbose_testing_bool
+ { \tl_show:N \l__zrefclever_typeset_queue_curr_tl }
+
+ % Wrap up loop, or prepare for next iteration.
+ \bool_if:NTF \l__zrefclever_typeset_last_bool
+ {
+ % We are finishing, typeset the current queue.
+ \int_case:nnF { \l__zrefclever_type_count_int }
+ {
+ % Single type.
+ % Test: 'zc-typeset01.lvt': "Last of type: single type"
+ { 0 }
+ { \l__zrefclever_typeset_queue_curr_tl }
+ % Pair of types.
+ % Test: 'zc-typeset01.lvt': "Last of type: pair of types"
+ { 1 }
+ {
+ \l__zrefclever_tpairsep_tl
+ \l__zrefclever_typeset_queue_curr_tl
+ }
+ }
+ {
+ % Last in list of types.
+ % Test: 'zc-typeset01.lvt': "Last of type: list of types"
+ \l__zrefclever_tlastsep_tl
+ \l__zrefclever_typeset_queue_curr_tl
+ }
+ % And nudge in case of multitype reference.
+ \bool_lazy_all:nT
+ {
+ { \l__zrefclever_nudge_enabled_bool }
+ { \l__zrefclever_nudge_multitype_bool }
+ { \int_compare_p:nNn { \l__zrefclever_type_count_int } > { 0 } }
+ }
+ { \msg_warning:nn { zref-clever } { nudge-multitype } }
+ }
+ {
+ % There are further labels, set variables for next iteration.
+ \tl_set_eq:NN \l__zrefclever_typeset_queue_prev_tl
+ \l__zrefclever_typeset_queue_curr_tl
+ \tl_clear:N \l__zrefclever_typeset_queue_curr_tl
+ \tl_clear:N \l__zrefclever_type_first_label_tl
+ \tl_clear:N \l__zrefclever_type_first_label_type_tl
+ \tl_clear:N \l__zrefclever_range_beg_label_tl
+ \int_zero:N \l__zrefclever_label_count_int
+ \int_incr:N \l__zrefclever_type_count_int
+ \int_zero:N \l__zrefclever_range_count_int
+ \int_zero:N \l__zrefclever_range_same_count_int
+ }
+ }
+\cs_new_protected:Npn \__zrefclever_typeset_refs_not_last_of_type:
+ {
+ % Signal if next label may form a range with the current one (only
+ % considered if compression is enabled in the first place).
+ \bool_set_false:N \l__zrefclever_next_maybe_range_bool
+ \bool_set_false:N \l__zrefclever_next_is_same_bool
+ \bool_if:NT \l__zrefclever_typeset_compress_bool
+ {
+ \zref@ifrefundefined { \l__zrefclever_label_a_tl }
+ { }
+ {
+ \__zrefclever_labels_in_sequence:nn
+ { \l__zrefclever_label_a_tl } { \l__zrefclever_label_b_tl }
+ }
+ }
+
+ % Process the current label to the current queue.
+ \int_compare:nNnTF { \l__zrefclever_label_count_int } = { 0 }
+ {
+ % Current label is the first of its type (also not the last, but it
+ % doesn't matter here): just store the label.
+ \tl_set:NV \l__zrefclever_type_first_label_tl
+ \l__zrefclever_label_a_tl
+ \tl_set:NV \l__zrefclever_type_first_label_type_tl
+ \l__zrefclever_label_type_a_tl
+
+ % If the next label may be part of a range, we set `range_beg_label'
+ % to "empty" (we deal with it as the "first", and must do it there, to
+ % handle hyperlinking), but also step the range counters.
+ % Test: 'zc-typeset01.lvt': "Not last of type: first is range"
+ \bool_if:NT \l__zrefclever_next_maybe_range_bool
+ {
+ \tl_clear:N \l__zrefclever_range_beg_label_tl
+ \int_incr:N \l__zrefclever_range_count_int
+ \bool_if:NT \l__zrefclever_next_is_same_bool
+ { \int_incr:N \l__zrefclever_range_same_count_int }
+ }
+ }
+ {
+ % Current label is neither the first (nor the last) of its type.
+ \bool_if:NTF \l__zrefclever_next_maybe_range_bool
+ {
+ % Starting, or continuing a range.
+ \int_compare:nNnTF
+ { \l__zrefclever_range_count_int } = { 0 }
+ {
+ % There was no range going, we are starting one.
+ \tl_set:NV \l__zrefclever_range_beg_label_tl
+ \l__zrefclever_label_a_tl
+ \int_incr:N \l__zrefclever_range_count_int
+ \bool_if:NT \l__zrefclever_next_is_same_bool
+ { \int_incr:N \l__zrefclever_range_same_count_int }
+ }
+ {
+ % Second or more in the range, but not the last.
+ \int_incr:N \l__zrefclever_range_count_int
+ \bool_if:NT \l__zrefclever_next_is_same_bool
+ { \int_incr:N \l__zrefclever_range_same_count_int }
+ }
+ }
+ {
+ % Next element is not in sequence: there was no range, or we are
+ % closing one.
+ \int_case:nnF { \l__zrefclever_range_count_int }
+ {
+ % There was no range going on.
+ % Test: 'zc-typeset01.lvt': "Not last of type: no range"
+ { 0 }
+ {
+ \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+ {
+ \exp_not:V \l__zrefclever_listsep_tl
+ \__zrefclever_get_ref:V \l__zrefclever_label_a_tl
+ }
+ }
+ % Last is second in the range: if `range_same_count' is also
+ % `1', it's a repetition (drop it), otherwise, it's a "pair
+ % within a list", treat as list.
+ % Test: 'zc-typeset01.lvt': "Not last of type: range pair to one"
+ % Test: 'zc-typeset01.lvt': "Not last of type: range pair"
+ { 1 }
+ {
+ \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+ {
+ \tl_if_empty:VF \l__zrefclever_range_beg_label_tl
+ {
+ \exp_not:V \l__zrefclever_listsep_tl
+ \__zrefclever_get_ref:V
+ \l__zrefclever_range_beg_label_tl
+ }
+ \int_compare:nNnF
+ { \l__zrefclever_range_same_count_int } = { 1 }
+ {
+ \exp_not:V \l__zrefclever_listsep_tl
+ \__zrefclever_get_ref:V
+ \l__zrefclever_label_a_tl
+ }
+ }
+ }
+ }
+ {
+ % Last is third or more in the range: if `range_count' and
+ % `range_same_count' are the same, its a repetition (drop it),
+ % if they differ by `1', its a list, if they differ by more,
+ % it is a real range.
+ \int_case:nnF
+ {
+ \l__zrefclever_range_count_int -
+ \l__zrefclever_range_same_count_int
+ }
+ {
+ % Test: 'zc-typeset01.lvt': "Not last of type: range to one"
+ { 0 }
+ {
+ \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+ {
+ \tl_if_empty:VF \l__zrefclever_range_beg_label_tl
+ {
+ \exp_not:V \l__zrefclever_listsep_tl
+ \__zrefclever_get_ref:V
+ \l__zrefclever_range_beg_label_tl
+ }
+ }
+ }
+ % Test: 'zc-typeset01.lvt': "Not last of type: range to pair"
+ { 1 }
+ {
+ \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+ {
+ \tl_if_empty:VF \l__zrefclever_range_beg_label_tl
+ {
+ \exp_not:V \l__zrefclever_listsep_tl
+ \__zrefclever_get_ref:V
+ \l__zrefclever_range_beg_label_tl
+ }
+ \exp_not:V \l__zrefclever_listsep_tl
+ \__zrefclever_get_ref:V \l__zrefclever_label_a_tl
+ }
+ }
+ }
+ {
+ % Test: 'zc-typeset01.lvt': "Not last of type: range"
+ \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+ {
+ \tl_if_empty:VF \l__zrefclever_range_beg_label_tl
+ {
+ \exp_not:V \l__zrefclever_listsep_tl
+ \__zrefclever_get_ref:V
+ \l__zrefclever_range_beg_label_tl
+ }
+ \exp_not:V \l__zrefclever_rangesep_tl
+ \__zrefclever_get_ref:V \l__zrefclever_label_a_tl
+ }
+ }
+ }
+ % Reset counters.
+ \int_zero:N \l__zrefclever_range_count_int
+ \int_zero:N \l__zrefclever_range_same_count_int
+ }
+ }
+ % Step label counter for next iteration.
+ \int_incr:N \l__zrefclever_label_count_int
+ }
+\cs_new_protected:Npn \__zrefclever_ref_default:
+ { \zref@default }
+\cs_new_protected:Npn \__zrefclever_name_default:
+ { \zref@default }
+\cs_new:Npn \__zrefclever_get_ref:n #1
+ {
+ \zref@ifrefcontainsprop {#1} { \l__zrefclever_ref_property_tl }
+ {
+ \bool_if:nTF
+ {
+ \l__zrefclever_use_hyperref_bool &&
+ ! \l__zrefclever_link_star_bool
+ }
+ {
+ \bool_if:NF \l__zrefclever_preposinlink_bool
+ { \exp_not:V \l__zrefclever_refpre_tl }
+ % It's two `@s', but escaped for DocStrip.
+ \exp_not:N \hyper@@link
+ { \__zrefclever_extract_url_unexp:n {#1} }
+ { \__zrefclever_extract_unexp:nnn {#1} { anchor } { } }
+ {
+ \bool_if:NT \l__zrefclever_preposinlink_bool
+ { \exp_not:V \l__zrefclever_refpre_tl }
+ \exp_not:N \group_begin:
+ \exp_not:V \l__zrefclever_reffont_tl
+ \__zrefclever_extract_unexp:nvn {#1}
+ { l__zrefclever_ref_property_tl } { }
+ \exp_not:N \group_end:
+ \bool_if:NT \l__zrefclever_preposinlink_bool
+ { \exp_not:V \l__zrefclever_refpos_tl }
+ }
+ \bool_if:NF \l__zrefclever_preposinlink_bool
+ { \exp_not:V \l__zrefclever_refpos_tl }
+ }
+ {
+ \exp_not:V \l__zrefclever_refpre_tl
+ \exp_not:N \group_begin:
+ \exp_not:V \l__zrefclever_reffont_tl
+ \__zrefclever_extract_unexp:nvn {#1}
+ { l__zrefclever_ref_property_tl } { }
+ \exp_not:N \group_end:
+ \exp_not:V \l__zrefclever_refpos_tl
+ }
+ }
+ { \__zrefclever_ref_default: }
+ }
+\cs_generate_variant:Nn \__zrefclever_get_ref:n { V }
+\cs_new:Npn \__zrefclever_get_ref_first:
+ {
+ \zref@ifrefundefined { \l__zrefclever_type_first_label_tl }
+ { \__zrefclever_ref_default: }
+ {
+ \bool_if:NTF \l__zrefclever_name_in_link_bool
+ {
+ \zref@ifrefcontainsprop
+ { \l__zrefclever_type_first_label_tl }
+ { \l__zrefclever_ref_property_tl }
+ {
+ % It's two `@s', but escaped for DocStrip.
+ \exp_not:N \hyper@@link
+ {
+ \__zrefclever_extract_url_unexp:V
+ \l__zrefclever_type_first_label_tl
+ }
+ {
+ \__zrefclever_extract_unexp:Vnn
+ \l__zrefclever_type_first_label_tl { anchor } { }
+ }
+ {
+ \exp_not:N \group_begin:
+ \exp_not:V \l__zrefclever_namefont_tl
+ \exp_not:V \l__zrefclever_type_name_tl
+ \exp_not:N \group_end:
+ \exp_not:V \l__zrefclever_namesep_tl
+ \exp_not:V \l__zrefclever_refpre_tl
+ \exp_not:N \group_begin:
+ \exp_not:V \l__zrefclever_reffont_tl
+ \__zrefclever_extract_unexp:Vvn
+ \l__zrefclever_type_first_label_tl
+ { l__zrefclever_ref_property_tl } { }
+ \exp_not:N \group_end:
+ \bool_if:NT \l__zrefclever_preposinlink_bool
+ { \exp_not:V \l__zrefclever_refpos_tl }
+ }
+ \bool_if:NF \l__zrefclever_preposinlink_bool
+ { \exp_not:V \l__zrefclever_refpos_tl }
+ }
+ {
+ \exp_not:N \group_begin:
+ \exp_not:V \l__zrefclever_namefont_tl
+ \exp_not:V \l__zrefclever_type_name_tl
+ \exp_not:N \group_end:
+ \exp_not:V \l__zrefclever_namesep_tl
+ \__zrefclever_ref_default:
+ }
+ }
+ {
+ \tl_if_empty:NTF \l__zrefclever_type_name_tl
+ {
+ \__zrefclever_name_default:
+ \exp_not:V \l__zrefclever_namesep_tl
+ }
+ {
+ \exp_not:N \group_begin:
+ \exp_not:V \l__zrefclever_namefont_tl
+ \exp_not:V \l__zrefclever_type_name_tl
+ \exp_not:N \group_end:
+ \exp_not:V \l__zrefclever_namesep_tl
+ }
+ \zref@ifrefcontainsprop
+ { \l__zrefclever_type_first_label_tl }
+ { \l__zrefclever_ref_property_tl }
+ {
+ \bool_if:nTF
+ {
+ \l__zrefclever_use_hyperref_bool &&
+ ! \l__zrefclever_link_star_bool
+ }
+ {
+ \bool_if:NF \l__zrefclever_preposinlink_bool
+ { \exp_not:V \l__zrefclever_refpre_tl }
+ % It's two '@s', but escaped for DocStrip.
+ \exp_not:N \hyper@@link
+ {
+ \__zrefclever_extract_url_unexp:V
+ \l__zrefclever_type_first_label_tl
+ }
+ {
+ \__zrefclever_extract_unexp:Vnn
+ \l__zrefclever_type_first_label_tl { anchor } { }
+ }
+ {
+ \bool_if:NT \l__zrefclever_preposinlink_bool
+ { \exp_not:V \l__zrefclever_refpre_tl }
+ \exp_not:N \group_begin:
+ \exp_not:V \l__zrefclever_reffont_tl
+ \__zrefclever_extract_unexp:Vvn
+ \l__zrefclever_type_first_label_tl
+ { l__zrefclever_ref_property_tl } { }
+ \exp_not:N \group_end:
+ \bool_if:NT \l__zrefclever_preposinlink_bool
+ { \exp_not:V \l__zrefclever_refpos_tl }
+ }
+ \bool_if:NF \l__zrefclever_preposinlink_bool
+ { \exp_not:V \l__zrefclever_refpos_tl }
+ }
+ {
+ \exp_not:V \l__zrefclever_refpre_tl
+ \exp_not:N \group_begin:
+ \exp_not:V \l__zrefclever_reffont_tl
+ \__zrefclever_extract_unexp:Vvn
+ \l__zrefclever_type_first_label_tl
+ { l__zrefclever_ref_property_tl } { }
+ \exp_not:N \group_end:
+ \exp_not:V \l__zrefclever_refpos_tl
+ }
+ }
+ { \__zrefclever_ref_default: }
+ }
+ }
+ }
+\cs_new_protected:Npn \__zrefclever_type_name_setup:
+ {
+ \zref@ifrefundefined { \l__zrefclever_type_first_label_tl }
+ { \tl_clear:N \l__zrefclever_type_name_tl }
+ {
+ \tl_if_eq:NnTF
+ \l__zrefclever_type_first_label_type_tl { zc@missingtype }
+ { \tl_clear:N \l__zrefclever_type_name_tl }
+ {
+ % Determine whether we should use capitalization, abbreviation,
+ % and plural.
+ \bool_lazy_or:nnTF
+ { \l__zrefclever_capitalize_bool }
+ {
+ \l__zrefclever_capitalize_first_bool &&
+ \int_compare_p:nNn { \l__zrefclever_type_count_int } = { 0 }
+ }
+ { \tl_set:Nn \l__zrefclever_name_format_tl {Name} }
+ { \tl_set:Nn \l__zrefclever_name_format_tl {name} }
+ % If the queue is empty, we have a singular, otherwise, plural.
+ \tl_if_empty:NTF \l__zrefclever_typeset_queue_curr_tl
+ { \tl_put_right:Nn \l__zrefclever_name_format_tl { -sg } }
+ { \tl_put_right:Nn \l__zrefclever_name_format_tl { -pl } }
+ \bool_lazy_and:nnTF
+ { \l__zrefclever_abbrev_bool }
+ {
+ ! \int_compare_p:nNn
+ { \l__zrefclever_type_count_int } = { 0 } ||
+ ! \l__zrefclever_noabbrev_first_bool
+ }
+ {
+ \tl_set:NV \l__zrefclever_name_format_fallback_tl
+ \l__zrefclever_name_format_tl
+ \tl_put_right:Nn \l__zrefclever_name_format_tl { -ab }
+ }
+ { \tl_clear:N \l__zrefclever_name_format_fallback_tl }
+
+ % Handle number and gender nudges.
+ \bool_if:NT \l__zrefclever_nudge_enabled_bool
+ {
+ \bool_if:NTF \l__zrefclever_nudge_singular_bool
+ {
+ \tl_if_empty:NF \l__zrefclever_typeset_queue_curr_tl
+ {
+ \msg_warning:nnx { zref-clever }
+ { nudge-plural-when-sg }
+ { \l__zrefclever_type_first_label_type_tl }
+ }
+ }
+ {
+ \bool_lazy_all:nT
+ {
+ { \l__zrefclever_nudge_comptosing_bool }
+ { \tl_if_empty_p:N \l__zrefclever_typeset_queue_curr_tl }
+ {
+ \int_compare_p:nNn
+ { \l__zrefclever_label_count_int } > { 0 }
+ }
+ }
+ {
+ \msg_warning:nnx { zref-clever }
+ { nudge-comptosing }
+ { \l__zrefclever_type_first_label_type_tl }
+ }
+ }
+ \bool_lazy_and:nnT
+ { \l__zrefclever_nudge_gender_bool }
+ { ! \tl_if_empty_p:N \l__zrefclever_ref_gender_tl }
+ {
+ \__zrefclever_get_type_transl:xxnNF
+ { \l__zrefclever_ref_language_tl }
+ { \l__zrefclever_type_first_label_type_tl }
+ { gender }
+ \l__zrefclever_type_name_gender_tl
+ { \tl_clear:N \l__zrefclever_type_name_gender_tl }
+ \tl_if_eq:NNF
+ \l__zrefclever_ref_gender_tl
+ \l__zrefclever_type_name_gender_tl
+ {
+ \tl_if_empty:NTF \l__zrefclever_type_name_gender_tl
+ {
+ \msg_warning:nnxxx { zref-clever }
+ { nudge-gender-not-declared-for-type }
+ { \l__zrefclever_ref_gender_tl }
+ { \l__zrefclever_type_first_label_type_tl }
+ { \l__zrefclever_ref_language_tl }
+ }
+ {
+ \msg_warning:nnxxxx { zref-clever }
+ { nudge-gender-mismatch }
+ { \l__zrefclever_type_first_label_type_tl }
+ { \l__zrefclever_ref_gender_tl }
+ { \l__zrefclever_type_name_gender_tl }
+ { \l__zrefclever_ref_language_tl }
+ }
+ }
+ }
+ }
+
+ \tl_if_empty:NTF \l__zrefclever_name_format_fallback_tl
+ {
+ \prop_get:cVNF
+ {
+ l__zrefclever_type_
+ \l__zrefclever_type_first_label_type_tl _options_prop
+ }
+ \l__zrefclever_name_format_tl
+ \l__zrefclever_type_name_tl
+ {
+ \tl_if_empty:NF \l__zrefclever_ref_decl_case_tl
+ {
+ \tl_put_left:Nn \l__zrefclever_name_format_tl { - }
+ \tl_put_left:NV \l__zrefclever_name_format_tl
+ \l__zrefclever_ref_decl_case_tl
+ }
+ \__zrefclever_get_type_transl:xxxNF
+ { \l__zrefclever_ref_language_tl }
+ { \l__zrefclever_type_first_label_type_tl }
+ { \l__zrefclever_name_format_tl }
+ \l__zrefclever_type_name_tl
+ {
+ \tl_clear:N \l__zrefclever_type_name_tl
+ \msg_warning:nnxx { zref-clever } { missing-name }
+ { \l__zrefclever_name_format_tl }
+ { \l__zrefclever_type_first_label_type_tl }
+ }
+ }
+ }
+ {
+ \prop_get:cVNF
+ {
+ l__zrefclever_type_
+ \l__zrefclever_type_first_label_type_tl _options_prop
+ }
+ \l__zrefclever_name_format_tl
+ \l__zrefclever_type_name_tl
+ {
+ \prop_get:cVNF
+ {
+ l__zrefclever_type_
+ \l__zrefclever_type_first_label_type_tl _options_prop
+ }
+ \l__zrefclever_name_format_fallback_tl
+ \l__zrefclever_type_name_tl
+ {
+ \tl_if_empty:NF \l__zrefclever_ref_decl_case_tl
+ {
+ \tl_put_left:Nn
+ \l__zrefclever_name_format_tl { - }
+ \tl_put_left:NV \l__zrefclever_name_format_tl
+ \l__zrefclever_ref_decl_case_tl
+ \tl_put_left:Nn
+ \l__zrefclever_name_format_fallback_tl { - }
+ \tl_put_left:NV
+ \l__zrefclever_name_format_fallback_tl
+ \l__zrefclever_ref_decl_case_tl
+ }
+ \__zrefclever_get_type_transl:xxxNF
+ { \l__zrefclever_ref_language_tl }
+ { \l__zrefclever_type_first_label_type_tl }
+ { \l__zrefclever_name_format_tl }
+ \l__zrefclever_type_name_tl
+ {
+ \__zrefclever_get_type_transl:xxxNF
+ { \l__zrefclever_ref_language_tl }
+ { \l__zrefclever_type_first_label_type_tl }
+ { \l__zrefclever_name_format_fallback_tl }
+ \l__zrefclever_type_name_tl
+ {
+ \tl_clear:N \l__zrefclever_type_name_tl
+ \msg_warning:nnxx { zref-clever }
+ { missing-name }
+ { \l__zrefclever_name_format_tl }
+ { \l__zrefclever_type_first_label_type_tl }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ % Signal whether the type name is to be included in the hyperlink or not.
+ \bool_lazy_any:nTF
+ {
+ { ! \l__zrefclever_use_hyperref_bool }
+ { \l__zrefclever_link_star_bool }
+ { \tl_if_empty_p:N \l__zrefclever_type_name_tl }
+ { \str_if_eq_p:Vn \l__zrefclever_nameinlink_str { false } }
+ }
+ { \bool_set_false:N \l__zrefclever_name_in_link_bool }
+ {
+ \bool_lazy_any:nTF
+ {
+ { \str_if_eq_p:Vn \l__zrefclever_nameinlink_str { true } }
+ {
+ \str_if_eq_p:Vn \l__zrefclever_nameinlink_str { tsingle } &&
+ \tl_if_empty_p:N \l__zrefclever_typeset_queue_curr_tl
+ }
+ {
+ \str_if_eq_p:Vn \l__zrefclever_nameinlink_str { single } &&
+ \tl_if_empty_p:N \l__zrefclever_typeset_queue_curr_tl &&
+ \l__zrefclever_typeset_last_bool &&
+ \int_compare_p:nNn { \l__zrefclever_type_count_int } = { 0 }
+ }
+ }
+ { \bool_set_true:N \l__zrefclever_name_in_link_bool }
+ { \bool_set_false:N \l__zrefclever_name_in_link_bool }
+ }
+ }
+\cs_new:Npn \__zrefclever_extract_url_unexp:n #1
+ {
+ \zref@ifpropundefined { urluse }
+ { \__zrefclever_extract_unexp:nnn {#1} { url } { \c_empty_tl } }
+ {
+ \zref@ifrefcontainsprop {#1} { urluse }
+ { \__zrefclever_extract_unexp:nnn {#1} { urluse } { \c_empty_tl } }
+ { \__zrefclever_extract_unexp:nnn {#1} { url } { \c_empty_tl } }
+ }
+ }
+\cs_generate_variant:Nn \__zrefclever_extract_url_unexp:n { V }
+\cs_new_protected:Npn \__zrefclever_labels_in_sequence:nn #1#2
+ {
+ \__zrefclever_def_extract:Nnnn \l__zrefclever_label_extdoc_a_tl
+ {#1} { externaldocument } { \c_empty_tl }
+ \__zrefclever_def_extract:Nnnn \l__zrefclever_label_extdoc_b_tl
+ {#2} { externaldocument } { \c_empty_tl }
+
+ \tl_if_eq:NNT
+ \l__zrefclever_label_extdoc_a_tl
+ \l__zrefclever_label_extdoc_b_tl
+ {
+ \tl_if_eq:NnTF \l__zrefclever_ref_property_tl { page }
+ {
+ \exp_args:Nxx \tl_if_eq:nnT
+ { \__zrefclever_extract_unexp:nnn {#1} { zc@pgfmt } { } }
+ { \__zrefclever_extract_unexp:nnn {#2} { zc@pgfmt } { } }
+ {
+ \int_compare:nNnTF
+ { \__zrefclever_extract:nnn {#1} { zc@pgval } { -2 } + 1 }
+ =
+ { \__zrefclever_extract:nnn {#2} { zc@pgval } { -1 } }
+ { \bool_set_true:N \l__zrefclever_next_maybe_range_bool }
+ {
+ \int_compare:nNnT
+ { \__zrefclever_extract:nnn {#1} { zc@pgval } { -1 } }
+ =
+ { \__zrefclever_extract:nnn {#2} { zc@pgval } { -1 } }
+ {
+ \bool_set_true:N \l__zrefclever_next_maybe_range_bool
+ \bool_set_true:N \l__zrefclever_next_is_same_bool
+ }
+ }
+ }
+ }
+ {
+ \exp_args:Nxx \tl_if_eq:nnT
+ { \__zrefclever_extract_unexp:nnn {#1} { zc@counter } { } }
+ { \__zrefclever_extract_unexp:nnn {#2} { zc@counter } { } }
+ {
+ \exp_args:Nxx \tl_if_eq:nnT
+ { \__zrefclever_extract_unexp:nnn {#1} { zc@enclval } { } }
+ { \__zrefclever_extract_unexp:nnn {#2} { zc@enclval } { } }
+ {
+ \int_compare:nNnTF
+ { \__zrefclever_extract:nnn {#1} { zc@cntval } { -2 } + 1 }
+ =
+ { \__zrefclever_extract:nnn {#2} { zc@cntval } { -1 } }
+ { \bool_set_true:N \l__zrefclever_next_maybe_range_bool }
+ {
+ \int_compare:nNnT
+ { \__zrefclever_extract:nnn {#1} { zc@cntval } { -1 } }
+ =
+ { \__zrefclever_extract:nnn {#2} { zc@cntval } { -1 } }
+ {
+ \bool_set_true:N
+ \l__zrefclever_next_maybe_range_bool
+ \exp_args:Nxx \tl_if_eq:nnT
+ {
+ \__zrefclever_extract_unexp:nvn {#1}
+ { l__zrefclever_ref_property_tl } { }
+ }
+ {
+ \__zrefclever_extract_unexp:nvn {#2}
+ { l__zrefclever_ref_property_tl } { }
+ }
+ {
+ \bool_set_true:N
+ \l__zrefclever_next_is_same_bool
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+\cs_new_protected:Npn \__zrefclever_get_ref_string:nN #1#2
+ {
+ % First attempt: general options.
+ \prop_get:NnNF \l__zrefclever_ref_options_prop {#1} #2
+ {
+ % If not found, try type specific options.
+ \bool_lazy_and:nnTF
+ {
+ \prop_if_exist_p:c
+ {
+ l__zrefclever_type_
+ \l__zrefclever_label_type_a_tl _options_prop
+ }
+ }
+ {
+ \prop_if_in_p:cn
+ {
+ l__zrefclever_type_
+ \l__zrefclever_label_type_a_tl _options_prop
+ }
+ {#1}
+ }
+ {
+ \prop_get:cnN
+ {
+ l__zrefclever_type_
+ \l__zrefclever_label_type_a_tl _options_prop
+ }
+ {#1} #2
+ }
+ {
+ % If not found, try type specific translations.
+ \__zrefclever_get_type_transl:xxnNF
+ { \l__zrefclever_ref_language_tl }
+ { \l__zrefclever_label_type_a_tl }
+ {#1} #2
+ {
+ % If not found, try default translations.
+ \__zrefclever_get_default_transl:xnNF
+ { \l__zrefclever_ref_language_tl }
+ {#1} #2
+ {
+ % If not found, try fallback.
+ \__zrefclever_get_fallback_transl:nNF {#1} #2
+ {
+ \tl_clear:N #2
+ \msg_warning:nnn { zref-clever }
+ { missing-string } {#1}
+ }
+ }
+ }
+ }
+ }
+ }
+\cs_new_protected:Npn \__zrefclever_get_ref_font:nN #1#2
+ {
+ % First attempt: general options.
+ \prop_get:NnNF \l__zrefclever_ref_options_prop {#1} #2
+ {
+ % If not found, try type specific options.
+ \bool_if:nTF
+ {
+ \prop_if_exist_p:c
+ {
+ l__zrefclever_type_
+ \l__zrefclever_label_type_a_tl _options_prop
+ }
+ }
+ {
+ \prop_get:cnNF
+ {
+ l__zrefclever_type_
+ \l__zrefclever_label_type_a_tl _options_prop
+ }
+ {#1} #2
+ { \tl_clear:N #2 }
+ }
+ { \tl_clear:N #2 }
+ }
+ }
+\__zrefclever_compat_module:nn { appendix }
+ {
+ \AddToHook { cmd / appendix / before }
+ {
+ \__zrefclever_zcsetup:n
+ {
+ countertype =
+ {
+ chapter = appendix ,
+ section = appendix ,
+ subsection = appendix ,
+ subsubsection = appendix ,
+ paragraph = appendix ,
+ subparagraph = appendix ,
+ }
+ }
+ }
+ }
+\__zrefclever_compat_module:nn { appendices }
+ {
+ \__zrefclever_if_package_loaded:nT { appendix }
+ {
+ \newcounter { zc@appendix }
+ \newcounter { zc@save@appendix }
+ \setcounter { zc@appendix } { 0 }
+ \setcounter { zc@save@appendix } { 0 }
+ \cs_if_exist:cTF { chapter }
+ {
+ \__zrefclever_zcsetup:n
+ { counterresetby = { chapter = zc@appendix } }
+ }
+ {
+ \cs_if_exist:cT { section }
+ {
+ \__zrefclever_zcsetup:n
+ { counterresetby = { section = zc@appendix } }
+ }
+ }
+ \AddToHook { env / appendices / begin }
+ {
+ \stepcounter { zc@save@appendix }
+ \setcounter { zc@appendix } { \value { zc@save@appendix } }
+ \__zrefclever_zcsetup:n
+ {
+ countertype =
+ {
+ chapter = appendix ,
+ section = appendix ,
+ subsection = appendix ,
+ subsubsection = appendix ,
+ paragraph = appendix ,
+ subparagraph = appendix ,
+ }
+ }
+ }
+ \AddToHook { env / appendices / end }
+ { \setcounter { zc@appendix } { 0 } }
+ \AddToHook { cmd / appendix / before }
+ {
+ \stepcounter { zc@save@appendix }
+ \setcounter { zc@appendix } { \value { zc@save@appendix } }
+ }
+ \AddToHook { env / subappendices / begin }
+ {
+ \__zrefclever_zcsetup:n
+ {
+ countertype =
+ {
+ section = appendix ,
+ subsection = appendix ,
+ subsubsection = appendix ,
+ paragraph = appendix ,
+ subparagraph = appendix ,
+ } ,
+ }
+ }
+ \msg_info:nnn { zref-clever } { compat-package } { appendix }
+ }
+ }
+\__zrefclever_compat_module:nn { memoir }
+ {
+ \__zrefclever_if_class_loaded:nT { memoir }
+ {
+ \__zrefclever_zcsetup:n
+ {
+ countertype =
+ {
+ subfigure = figure ,
+ subtable = table ,
+ poemline = line ,
+ } ,
+ counterresetby =
+ {
+ subfigure = figure ,
+ subtable = table ,
+ } ,
+ }
+ \cs_new_protected:Npn \__zrefclever_memoir_both_labels:
+ {
+ \cs_set_eq:NN \__zrefclever_memoir_orig_label:n \label
+ \cs_set:Npn \__zrefclever_memoir_label_and_zlabel:n ##1
+ {
+ \__zrefclever_memoir_orig_label:n {##1}
+ \zlabel{##1}
+ }
+ \cs_set_eq:NN \label \__zrefclever_memoir_label_and_zlabel:n
+ }
+ \AddToHook { env / sidecaption / begin }
+ { \__zrefclever_memoir_both_labels: }
+ \AddToHook { env / sidecontcaption / begin }
+ { \__zrefclever_memoir_both_labels: }
+ \AddToHook{ cmd / bitwonumcaption / before }
+ { \group_begin: \__zrefclever_memoir_both_labels: }
+ \AddToHook{ cmd / bitwonumcaption / after }
+ { \group_end: }
+ \AddToHook{ cmd / bionenumcaption / before }
+ { \group_begin: \__zrefclever_memoir_both_labels: }
+ \AddToHook{ cmd / bionenumcaption / after }
+ { \group_end: }
+ \AddToHook{ cmd / bicaption / before }
+ { \group_begin: \__zrefclever_memoir_both_labels: }
+ \AddToHook{ cmd / bicaption / after }
+ { \group_end: }
+ \zref@newprop { subcaption }
+ { \cs_if_exist_use:c { @@thesub \@captype } }
+ \AddToHook{ cmd / @memsubcaption / before }
+ { \zref@localaddprop \ZREF@mainlist { subcaption } }
+ \tl_new:N \l__zrefclever_memoir_footnote_type_tl
+ \tl_set:Nn \l__zrefclever_memoir_footnote_type_tl { footnote }
+ \AddToHook { env / minipage / begin }
+ { \tl_set:Nn \l__zrefclever_memoir_footnote_type_tl { mpfootnote } }
+ \AddToHook { cmd / @makefntext / before }
+ {
+ \__zrefclever_zcsetup:x
+ { currentcounter = \l__zrefclever_memoir_footnote_type_tl }
+ }
+ \AddToHook { cmd / @makesidefntext / before }
+ { \__zrefclever_zcsetup:n { currentcounter = sidefootnote } }
+ \__zrefclever_zcsetup:n
+ {
+ countertype =
+ {
+ sidefootnote = footnote ,
+ pagenote = endnote ,
+ } ,
+ }
+ \AddToHook { file / \jobname.ent / before }
+ { \__zrefclever_zcsetup:x { currentcounter = pagenote } }
+ \msg_info:nnn { zref-clever } { compat-class } { memoir }
+ }
+ }
+\__zrefclever_compat_module:nn { KOMA }
+ {
+ \cs_if_exist:NT \KOMAClassName
+ {
+ \AddToHook { env / captionbeside / after }
+ {
+ \tl_if_exist:NT \@captype
+ { \tl_set_eq:NN \@currentcounter \@captype }
+ }
+ \tl_new:N \g__zrefclever_koma_captionofbeside_captype_tl
+ \AddToHook { env / captionofbeside / end }
+ { \tl_gset_eq:NN \g__zrefclever_koma_captype_tl \@captype }
+ \AddToHook { env / captionofbeside / after }
+ {
+ \tl_if_eq:NnF \@currenvir { document }
+ {
+ \tl_if_empty:NF \g__zrefclever_koma_captype_tl
+ {
+ \tl_set_eq:NN
+ \@currentcounter \g__zrefclever_koma_captype_tl
+ }
+ }
+ \tl_gclear:N \g__zrefclever_koma_captype_tl
+ }
+ \msg_info:nnx { zref-clever } { compat-class } { \KOMAClassName }
+ }
+ }
+\__zrefclever_compat_module:nn { amsmath }
+ {
+ \__zrefclever_if_package_loaded:nT { amsmath }
+ {
+ \cs_set_nopar:Npn \__zrefclever_ltxlabel:n #1
+ {
+ \__zrefclever_orig_ltxlabel:n {#1}
+ \zref@wrapper@babel \zref@label {#1}
+ }
+ \__zrefclever_if_package_loaded:nTF { hyperref }
+ {
+ \AddToHook { package / nameref / after }
+ {
+ \cs_new_eq:NN \__zrefclever_orig_ltxlabel:n \ltx@label
+ \cs_set_eq:NN \ltx@label \__zrefclever_ltxlabel:n
+ }
+ }
+ {
+ \cs_new_eq:NN \__zrefclever_orig_ltxlabel:n \ltx@label
+ \cs_set_eq:NN \ltx@label \__zrefclever_ltxlabel:n
+ }
+ \AddToHook { env / subequations / begin }
+ {
+ \__zrefclever_zcsetup:x
+ {
+ counterresetby =
+ {
+ parentequation =
+ \__zrefclever_counter_reset_by:n { equation } ,
+ equation = parentequation ,
+ } ,
+ currentcounter = parentequation ,
+ countertype = { parentequation = equation } ,
+ }
+ }
+ \clist_map_inline:nn
+ {
+ equation ,
+ equation* ,
+ align ,
+ align* ,
+ alignat ,
+ alignat* ,
+ flalign ,
+ flalign* ,
+ xalignat ,
+ xalignat* ,
+ gather ,
+ gather* ,
+ multline ,
+ multline* ,
+ }
+ {
+ \AddToHook { env / #1 / begin }
+ { \__zrefclever_zcsetup:n { currentcounter = equation } }
+ }
+ \zcRefTypeSetup { equation }
+ {
+ reffont = \upshape ,
+ refpre = {\textup{(}} ,
+ refpos = {\textup{)}} ,
+ }
+ \msg_info:nnn { zref-clever } { compat-package } { amsmath }
+ }
+ }
+\bool_new:N \l__zrefclever_mathtools_showonlyrefs_bool
+\__zrefclever_compat_module:nn { mathtools }
+ {
+ \__zrefclever_if_package_loaded:nT { mathtools }
+ {
+ \MH_if_boolean:nT { show_only_refs }
+ {
+ \bool_set_true:N \l__zrefclever_mathtools_showonlyrefs_bool
+ \cs_new_protected:Npn \__zrefclever_mathtools_showonlyrefs:n #1
+ {
+ \@bsphack
+ \seq_map_inline:Nn #1
+ {
+ \exp_args:Nx \tl_if_eq:nnTF
+ { \__zrefclever_extract_unexp:nnn {##1} { zc@type } { } }
+ { equation }
+ {
+ \protected@write \@auxout { }
+ { \string \MT@newlabel {##1} }
+ }
+ {
+ \exp_args:Nx \tl_if_eq:nnT
+ { \__zrefclever_extract_unexp:nnn {##1} { zc@type } { } }
+ { parentequation }
+ {
+ \protected@write \@auxout { }
+ { \string \MT@newlabel {##1} }
+ }
+ }
+ }
+ \@esphack
+ }
+ \msg_info:nnn { zref-clever } { compat-package } { mathtools }
+ }
+ }
+ }
+\__zrefclever_compat_module:nn { breqn }
+ {
+ \__zrefclever_if_package_loaded:nT { breqn }
+ {
+ \AddToHook { env / dgroup / begin }
+ {
+ \__zrefclever_zcsetup:x
+ {
+ counterresetby =
+ {
+ parentequation =
+ \__zrefclever_counter_reset_by:n { equation } ,
+ equation = parentequation ,
+ } ,
+ currentcounter = parentequation ,
+ countertype = { parentequation = equation } ,
+ }
+ }
+ \clist_map_inline:nn
+ {
+ dmath ,
+ dseries ,
+ darray ,
+ }
+ {
+ \AddToHook { env / #1 / begin }
+ { \__zrefclever_zcsetup:n { currentcounter = equation } }
+ }
+ \msg_info:nnn { zref-clever } { compat-package } { breqn }
+ }
+ }
+\__zrefclever_compat_module:nn { listings }
+ {
+ \__zrefclever_if_package_loaded:nT { listings }
+ {
+ \__zrefclever_zcsetup:n
+ {
+ countertype =
+ {
+ lstlisting = listing ,
+ lstnumber = line ,
+ } ,
+ counterresetby = { lstnumber = lstlisting } ,
+ }
+ \lst@AddToHook { PreInit }
+ { \tl_if_empty:NF \lst@label { \zlabel { \lst@label } } }
+ \lst@AddToHook { Init }
+ { \__zrefclever_zcsetup:n { currentcounter = lstnumber } }
+ \msg_info:nnn { zref-clever } { compat-package } { listings }
+ }
+ }
+\__zrefclever_compat_module:nn { enumitem }
+ {
+ \__zrefclever_if_package_loaded:nT { enumitem }
+ {
+ \int_set:Nn \l_tmpa_int { 5 }
+ \bool_while_do:nn
+ {
+ \cs_if_exist_p:c
+ { c@ enum \int_to_roman:n { \l_tmpa_int } }
+ }
+ {
+ \__zrefclever_zcsetup:x
+ {
+ counterresetby =
+ {
+ enum \int_to_roman:n { \l_tmpa_int } =
+ enum \int_to_roman:n { \l_tmpa_int - 1 }
+ } ,
+ countertype =
+ { enum \int_to_roman:n { \l_tmpa_int } = item } ,
+ }
+ \int_incr:N \l_tmpa_int
+ }
+ \int_compare:nNnT { \l_tmpa_int } > { 5 }
+ { \msg_info:nnn { zref-clever } { compat-package } { enumitem } }
+ }
+ }
+\__zrefclever_compat_module:nn { subcaption }
+ {
+ \__zrefclever_if_package_loaded:nT { subcaption }
+ {
+ \__zrefclever_zcsetup:n
+ {
+ countertype =
+ {
+ subfigure = figure ,
+ subtable = table ,
+ } ,
+ counterresetby =
+ {
+ subfigure = figure ,
+ subtable = table ,
+ } ,
+ }
+ \zref@newprop { subref }
+ { \cs_if_exist_use:c { thesub \@captype } }
+ \tl_put_right:Nn \caption@subtypehook
+ { \zref@localaddprop \ZREF@mainlist { subref } }
+ }
+ }
+\__zrefclever_compat_module:nn { subfig }
+ {
+ \__zrefclever_if_package_loaded:nT { subfig }
+ {
+ \__zrefclever_zcsetup:n
+ {
+ countertype =
+ {
+ subfigure = figure ,
+ subtable = table ,
+ } ,
+ counterresetby =
+ {
+ subfigure = figure ,
+ subtable = table ,
+ } ,
+ }
+ }
+ }
+\zcDeclareLanguage { english }
+\zcDeclareLanguageAlias { american } { english }
+\zcDeclareLanguageAlias { australian } { english }
+\zcDeclareLanguageAlias { british } { english }
+\zcDeclareLanguageAlias { canadian } { english }
+\zcDeclareLanguageAlias { newzealand } { english }
+\zcDeclareLanguageAlias { UKenglish } { english }
+\zcDeclareLanguageAlias { USenglish } { english }
+\zcDeclareLanguage
+ [ declension = { N , A , D , G } , gender = { f , m , n } , allcaps ]
+ { german }
+\zcDeclareLanguageAlias { austrian } { german }
+\zcDeclareLanguageAlias { germanb } { german }
+\zcDeclareLanguageAlias { ngerman } { german }
+\zcDeclareLanguageAlias { naustrian } { german }
+\zcDeclareLanguageAlias { nswissgerman } { german }
+\zcDeclareLanguageAlias { swissgerman } { german }
+\zcDeclareLanguage [ gender = { f , m } ] { french }
+\zcDeclareLanguageAlias { acadian } { french }
+\zcDeclareLanguageAlias { canadien } { french }
+\zcDeclareLanguageAlias { francais } { french }
+\zcDeclareLanguageAlias { frenchb } { french }
+\zcDeclareLanguage [ gender = { f , m } ] { portuguese }
+\zcDeclareLanguageAlias { brazilian } { portuguese }
+\zcDeclareLanguageAlias { brazil } { portuguese }
+\zcDeclareLanguageAlias { portuges } { portuguese }
+\zcDeclareLanguage [ gender = { f , m } ] { spanish }
+%%
+%%
+%% End of file `zref-clever.sty'.
diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check
index 4543aca6270..b5fe5c8f6b6 100755
--- a/Master/tlpkg/bin/tlpkg-ctan-check
+++ b/Master/tlpkg/bin/tlpkg-ctan-check
@@ -866,7 +866,7 @@ my @TLP_working = qw(
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 zitie zlmtt zootaxa-bst zref zref-check
+ ziffer zitie zlmtt zootaxa-bst zref zref-check zref-clever
zwgetfdate zwpagelayout
zx-calculus zxjafbfont zxjafont zxjatype zztex
);
diff --git a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
index d3af70d4e19..dc923fcf8c0 100644
--- a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
+++ b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
@@ -1405,5 +1405,6 @@ depend zed-csp
depend ziffer
depend zref
depend zref-check
+depend zref-clever
depend zwgetfdate
depend zwpagelayout
diff --git a/Master/tlpkg/tlpsrc/zref-clever.tlpsrc b/Master/tlpkg/tlpsrc/zref-clever.tlpsrc
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/Master/tlpkg/tlpsrc/zref-clever.tlpsrc