texlive[61145] Master: zref-clever (24nov21)

commits+karl at tug.org commits+karl at tug.org
Wed Nov 24 22:31:19 CET 2021


Revision: 61145
          http://tug.org/svn/texlive?view=revision&revision=61145
Author:   karl
Date:     2021-11-24 22:31:19 +0100 (Wed, 24 Nov 2021)
Log Message:
-----------
zref-clever (24nov21)

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

Added Paths:
-----------
    trunk/Master/texmf-dist/doc/latex/zref-clever/
    trunk/Master/texmf-dist/doc/latex/zref-clever/CHANGELOG.md
    trunk/Master/texmf-dist/doc/latex/zref-clever/DEPENDS.txt
    trunk/Master/texmf-dist/doc/latex/zref-clever/MANIFEST.md
    trunk/Master/texmf-dist/doc/latex/zref-clever/README.md
    trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever-code.pdf
    trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever-code.tex
    trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever.pdf
    trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever.tex
    trunk/Master/texmf-dist/source/latex/zref-clever/
    trunk/Master/texmf-dist/source/latex/zref-clever/zref-clever.dtx
    trunk/Master/texmf-dist/source/latex/zref-clever/zref-clever.ins
    trunk/Master/texmf-dist/tex/latex/zref-clever/
    trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-english.dict
    trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-french.dict
    trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-german.dict
    trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-portuguese.dict
    trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-spanish.dict
    trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever.sty
    trunk/Master/tlpkg/tlpsrc/zref-clever.tlpsrc

Added: trunk/Master/texmf-dist/doc/latex/zref-clever/CHANGELOG.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/zref-clever/CHANGELOG.md	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/zref-clever/CHANGELOG.md	2021-11-24 21:31:19 UTC (rev 61145)
@@ -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.


Property changes on: trunk/Master/texmf-dist/doc/latex/zref-clever/CHANGELOG.md
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/zref-clever/DEPENDS.txt
===================================================================
--- trunk/Master/texmf-dist/doc/latex/zref-clever/DEPENDS.txt	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/zref-clever/DEPENDS.txt	2021-11-24 21:31:19 UTC (rev 61145)
@@ -0,0 +1,5 @@
+hard zref
+hard l3packages
+hard oberdiek
+soft hyperref
+soft zref-check


Property changes on: trunk/Master/texmf-dist/doc/latex/zref-clever/DEPENDS.txt
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/zref-clever/MANIFEST.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/zref-clever/MANIFEST.md	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/zref-clever/MANIFEST.md	2021-11-24 21:31:19 UTC (rev 61145)
@@ -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 


Property changes on: trunk/Master/texmf-dist/doc/latex/zref-clever/MANIFEST.md
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/zref-clever/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/zref-clever/README.md	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/zref-clever/README.md	2021-11-24 21:31:19 UTC (rev 61145)
@@ -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


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

Index: trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever-code.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever-code.pdf	2021-11-24 21:30:42 UTC (rev 61144)
+++ trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever-code.pdf	2021-11-24 21:31:19 UTC (rev 61145)

Property changes on: trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever-code.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever-code.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever-code.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever-code.tex	2021-11-24 21:31:19 UTC (rev 61145)
@@ -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}


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

Index: trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever.pdf	2021-11-24 21:30:42 UTC (rev 61144)
+++ trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever.pdf	2021-11-24 21:31:19 UTC (rev 61145)

Property changes on: trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever.tex	2021-11-24 21:31:19 UTC (rev 61145)
@@ -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 at key,
+    patchcmd,
+    eq at setnumber,
+    DeclareFloatingEnvironment,
+    newlist,
+    setlist,
+    zexternaldocument,
+    next at label,
+    next at 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 at AddToHook { PreInit }
+  {
+    \cs_if_exist:cT { c@ \lstenv at name }
+      { \exp_args:Nx \refstepcounter { \lstenv at 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 at 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 at 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 at 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 at label} which is called at the appropriate time to actually set the
+label.  So, what \pkg{zref-clever} does is redefine \cs{ltx at 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 at 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 at 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 at key{breqn}{label}{%
+  \edef\next at label{%
+    \noexpand\label{\next at label@pre#1}%
+    \noexpand\zlabel{\next at label@pre#1}}%
+  \let\next at label@pre\@empty}
+\makeatother
+\usepackage{hyperref}
+\usepackage{etoolbox}
+\makeatletter
+\patchcmd\eq at setnumber{\stepcounter}{\refstepcounter}{}{%
+  \errmessage{Patching \noexpand\eq at 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}


Property changes on: trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/zref-clever/zref-clever.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/zref-clever/zref-clever.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/zref-clever/zref-clever.dtx	2021-11-24 21:31:19 UTC (rev 61145)
@@ -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 at 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 at 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 at newprop { zc at counter } { \l_@@_current_counter_tl }
+\zref at addprop \ZREF at mainlist { zc at 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 at ...}
+% prefix.
+%
+%    \begin{macrocode}
+\zref at 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 at addprop \ZREF at 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 at newprop { zc at 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 at addprop \ZREF at mainlist { zc at 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 at cntval} and
+% \texttt{zc at 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 at newprop { zc at 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 at addprop \ZREF at mainlist { zc at cntval }
+\zref at newprop* { zc at pgval } [0] { \int_use:c { c at page } }
+\zref at addprop \ZREF at mainlist { zc at 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 at 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 at enclval} property, and add it to the
+% \texttt{main} property list.
+%    \begin{macrocode}
+\zref at newprop { zc at enclval }
+  {
+    \@@_get_enclosing_counters_value:e
+      \l_@@_current_counter_tl
+  }
+\zref at addprop \ZREF at mainlist { zc at 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 at 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 at 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 at newprop}*\{zc at 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 at page \@@_page_format_aux:
+    \tl_gset:Nx \g_@@_page_format_tl { \thepage }
+    \group_end:
+  }
+\zref at newprop* { zc at pgfmt } { \g_@@_page_format_tl }
+\zref at addprop \ZREF at mainlist { zc at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at ifrefundefined {##1}
+          {
+            \zref at 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 at 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 at 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 at type } { zc at missingtype }
+    \@@_def_extract:Nnnn
+      \l_@@_label_type_b_tl {#2} { zc at type } { zc at 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 at enclval } { \c_empty_tl }
+    \tl_reverse:N \l_@@_label_enclval_a_tl
+    \@@_def_extract:Nnnn \l_@@_label_enclval_b_tl
+      {#2} { zc at 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 at cntval } { -1 } }
+                >
+              { \@@_extract:nnn {#2} { zc at 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 at 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 at 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 at type } { zc at missingtype }
+            \@@_def_extract:NVnn \l_@@_label_type_b_tl
+              \l_@@_label_b_tl { zc at type } { zc at 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 at ifrefundefined { \l_@@_label_a_tl }
+              {
+                \zref at ifrefundefined { \l_@@_label_b_tl }
+                  { \bool_set_false:N \l_@@_last_of_type_bool }
+                  { \bool_set_true:N \l_@@_last_of_type_bool  }
+              }
+              {
+                \zref at 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 at refused { \l_@@_label_a_tl }
+        % Test: 'zc-typeset01.lvt': "Typeset refs: warn missing type"
+        \zref at ifrefundefined { \l_@@_label_a_tl }
+          {}
+          {
+            \tl_if_eq:NnT \l_@@_label_type_a_tl { zc at missingtype }
+              {
+                \msg_warning:nnx { zref-clever } { missing-type }
+                  { \l_@@_label_a_tl }
+              }
+            \zref at 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 at 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 at 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 at 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 at 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 at 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 at default} would require, since we already define them protected.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_ref_default:
+  { \zref at default }
+\cs_new_protected:Npn \@@_name_default:
+  { \zref at 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 at 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 at ifrefundefined { \l_@@_type_first_label_tl }
+      { \@@_ref_default: }
+      {
+        \bool_if:NTF \l_@@_name_in_link_bool
+          {
+            \zref at 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 at 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 at ifrefundefined { \l_@@_type_first_label_tl }
+      { \tl_clear:N \l_@@_type_name_tl }
+      {
+        \tl_if_eq:NnTF
+          \l_@@_type_first_label_type_tl { zc at 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 at 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 at ifpropundefined { urluse }
+      { \@@_extract_unexp:nnn {#1} { url } { \c_empty_tl } }
+      {
+        \zref at 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 at pgfmt } { } }
+              { \@@_extract_unexp:nnn {#2} { zc at pgfmt } { } }
+              {
+                \int_compare:nNnTF
+                  { \@@_extract:nnn {#1} { zc at pgval } { -2 } + 1 }
+                    =
+                  { \@@_extract:nnn {#2} { zc at pgval } { -1 } }
+                  { \bool_set_true:N \l_@@_next_maybe_range_bool }
+                  {
+                    \int_compare:nNnT
+                      { \@@_extract:nnn {#1} { zc at pgval } { -1 } }
+                        =
+                      { \@@_extract:nnn {#2} { zc at 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 at counter } { } }
+              { \@@_extract_unexp:nnn {#2} { zc at counter } { } }
+              {
+                \exp_args:Nxx \tl_if_eq:nnT
+                  { \@@_extract_unexp:nnn {#1} { zc at enclval } { } }
+                  { \@@_extract_unexp:nnn {#2} { zc at enclval } { } }
+                  {
+                    \int_compare:nNnTF
+                      { \@@_extract:nnn {#1} { zc at cntval } { -2 } + 1 }
+                        =
+                      { \@@_extract:nnn {#2} { zc at cntval } { -1 } }
+                      { \bool_set_true:N \l_@@_next_maybe_range_bool }
+                      {
+                        \int_compare:nNnT
+                          { \@@_extract:nnn {#1} { zc at cntval } { -1 } }
+                            =
+                          { \@@_extract:nnn {#2} { zc at 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 at appendix }
+        \newcounter { zc at save@appendix }
+        \setcounter { zc at appendix } { 0 }
+        \setcounter { zc at save@appendix } { 0 }
+        \cs_if_exist:cTF { chapter }
+          {
+            \@@_zcsetup:n
+              { counterresetby = { chapter = zc at appendix } }
+          }
+          {
+            \cs_if_exist:cT { section }
+              {
+                \@@_zcsetup:n
+                  { counterresetby = { section = zc at appendix } }
+              }
+          }
+        \AddToHook { env / appendices / begin }
+          {
+            \stepcounter { zc at save@appendix }
+            \setcounter { zc at appendix } { \value { zc at save@appendix } }
+            \@@_zcsetup:n
+              {
+                countertype =
+                  {
+                    chapter       = appendix ,
+                    section       = appendix ,
+                    subsection    = appendix ,
+                    subsubsection = appendix ,
+                    paragraph     = appendix ,
+                    subparagraph  = appendix ,
+                  }
+              }
+          }
+        \AddToHook { env / appendices / end }
+          { \setcounter { zc at appendix } { 0 } }
+        \AddToHook { cmd / appendix / before }
+          {
+            \stepcounter { zc at save@appendix }
+            \setcounter { zc at appendix } { \value { zc at 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 at 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 at 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 at 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 at 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 at newprop { subcaption }
+          { \cs_if_exist_use:c { @@@@thesub \@captype } }
+        \AddToHook{ cmd / @memsubcaption / before }
+          { \zref at localaddprop \ZREF at 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 at label} in this context, and hence also handle
+% protection with \cs{zref at wrapper@babel}, because \cs{zlabel} makes itself
+% no-op when \cs{label} is equal to \cs{ltx at 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 at wrapper@babel \zref at label {#1}
+          }
+%    \end{macrocode}
+% Then we must store the original value of \cs{ltx at 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 at label} be \cs{label}.  This has to come after
+% \pkg{nameref}.  Other classes packages also redefine \cs{ltx at 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 at label
+                \cs_set_eq:NN \ltx at label \@@_ltxlabel:n
+              }
+          }
+          {
+            \cs_new_eq:NN \@@_orig_ltxlabel:n \ltx at label
+            \cs_set_eq:NN \ltx at 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 at type } { } }
+                      { equation }
+                      {
+                        \protected at write \@auxout { }
+                          { \string \MT at newlabel {##1} }
+                      }
+                      {
+                        \exp_args:Nx \tl_if_eq:nnT
+                          { \@@_extract_unexp:nnn {##1} { zc at type } { } }
+                          { parentequation }
+                          {
+                            \protected at write \@auxout { }
+                              { \string \MT at 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 at MakeCaption} in \cs{lst at 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 at 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 at AddToHook { PreInit }
+          { \tl_if_empty:NF \lst at label { \zlabel { \lst at 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 at 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 at 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 at 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 at newprop { subref }
+          { \cs_if_exist_use:c { thesub \@captype } }
+        \tl_put_right:Nn \caption at subtypehook
+          { \zref at localaddprop \ZREF at 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
+%
+%


Property changes on: trunk/Master/texmf-dist/source/latex/zref-clever/zref-clever.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/zref-clever/zref-clever.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/zref-clever/zref-clever.ins	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/zref-clever/zref-clever.ins	2021-11-24 21:31:19 UTC (rev 61145)
@@ -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

Added: trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-english.dict
===================================================================
--- trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-english.dict	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-english.dict	2021-11-24 21:31:19 UTC (rev 61145)
@@ -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'.

Added: trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-french.dict
===================================================================
--- trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-french.dict	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-french.dict	2021-11-24 21:31:19 UTC (rev 61145)
@@ -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'.

Added: trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-german.dict
===================================================================
--- trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-german.dict	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-german.dict	2021-11-24 21:31:19 UTC (rev 61145)
@@ -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'.

Added: trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-portuguese.dict
===================================================================
--- trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-portuguese.dict	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-portuguese.dict	2021-11-24 21:31:19 UTC (rev 61145)
@@ -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'.

Added: trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-spanish.dict
===================================================================
--- trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-spanish.dict	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-spanish.dict	2021-11-24 21:31:19 UTC (rev 61145)
@@ -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'.

Added: trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever.sty	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever.sty	2021-11-24 21:31:19 UTC (rev 61145)
@@ -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 at 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 at newprop { zc at counter } { \l__zrefclever_current_counter_tl }
+\zref at addprop \ZREF at mainlist { zc at counter }
+\zref at 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 at addprop \ZREF at mainlist { thecounter }
+\zref at newprop { zc at 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 at addprop \ZREF at mainlist { zc at type }
+\zref at newprop { zc at 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 at addprop \ZREF at mainlist { zc at cntval }
+\zref at newprop* { zc at pgval } [0] { \int_use:c { c at page } }
+\zref at addprop \ZREF at mainlist { zc at 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 at newprop { zc at enclval }
+  {
+    \__zrefclever_get_enclosing_counters_value:e
+      \l__zrefclever_current_counter_tl
+  }
+\zref at addprop \ZREF at mainlist { zc at 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 at page \__zrefclever_page_format_aux:
+    \tl_gset:Nx \g__zrefclever_page_format_tl { \thepage }
+    \group_end:
+  }
+\zref at newprop* { zc at pgfmt } { \g__zrefclever_page_format_tl }
+\zref at addprop \ZREF at mainlist { zc at 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 at 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 at 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 at 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 at 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 at 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 at 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 at ifrefundefined {##1}
+          {
+            \zref at 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 at 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 at 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 at type } { zc at missingtype }
+    \__zrefclever_def_extract:Nnnn
+      \l__zrefclever_label_type_b_tl {#2} { zc at type } { zc at 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 at 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 at 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 at cntval } { -1 } }
+                >
+              { \__zrefclever_extract:nnn {#2} { zc at 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 at 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 at 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 at type } { zc at missingtype }
+            \__zrefclever_def_extract:NVnn \l__zrefclever_label_type_b_tl
+              \l__zrefclever_label_b_tl { zc at type } { zc at 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 at ifrefundefined { \l__zrefclever_label_a_tl }
+              {
+                \zref at 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 at 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 at refused { \l__zrefclever_label_a_tl }
+        % Test: 'zc-typeset01.lvt': "Typeset refs: warn missing type"
+        \zref at ifrefundefined { \l__zrefclever_label_a_tl }
+          {}
+          {
+            \tl_if_eq:NnT \l__zrefclever_label_type_a_tl { zc at missingtype }
+              {
+                \msg_warning:nnx { zref-clever } { missing-type }
+                  { \l__zrefclever_label_a_tl }
+              }
+            \zref at 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 at 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 at 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 at 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 at default }
+\cs_new_protected:Npn \__zrefclever_name_default:
+  { \zref at default }
+\cs_new:Npn \__zrefclever_get_ref:n #1
+  {
+    \zref at 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 at ifrefundefined { \l__zrefclever_type_first_label_tl }
+      { \__zrefclever_ref_default: }
+      {
+        \bool_if:NTF \l__zrefclever_name_in_link_bool
+          {
+            \zref at 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 at 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 at 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 at 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 at ifpropundefined { urluse }
+      { \__zrefclever_extract_unexp:nnn {#1} { url } { \c_empty_tl } }
+      {
+        \zref at 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 at pgfmt } { } }
+              { \__zrefclever_extract_unexp:nnn {#2} { zc at pgfmt } { } }
+              {
+                \int_compare:nNnTF
+                  { \__zrefclever_extract:nnn {#1} { zc at pgval } { -2 } + 1 }
+                    =
+                  { \__zrefclever_extract:nnn {#2} { zc at pgval } { -1 } }
+                  { \bool_set_true:N \l__zrefclever_next_maybe_range_bool }
+                  {
+                    \int_compare:nNnT
+                      { \__zrefclever_extract:nnn {#1} { zc at pgval } { -1 } }
+                        =
+                      { \__zrefclever_extract:nnn {#2} { zc at 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 at counter } { } }
+              { \__zrefclever_extract_unexp:nnn {#2} { zc at counter } { } }
+              {
+                \exp_args:Nxx \tl_if_eq:nnT
+                  { \__zrefclever_extract_unexp:nnn {#1} { zc at enclval } { } }
+                  { \__zrefclever_extract_unexp:nnn {#2} { zc at enclval } { } }
+                  {
+                    \int_compare:nNnTF
+                      { \__zrefclever_extract:nnn {#1} { zc at cntval } { -2 } + 1 }
+                        =
+                      { \__zrefclever_extract:nnn {#2} { zc at cntval } { -1 } }
+                      { \bool_set_true:N \l__zrefclever_next_maybe_range_bool }
+                      {
+                        \int_compare:nNnT
+                          { \__zrefclever_extract:nnn {#1} { zc at cntval } { -1 } }
+                            =
+                          { \__zrefclever_extract:nnn {#2} { zc at 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 at appendix }
+        \newcounter { zc at save@appendix }
+        \setcounter { zc at appendix } { 0 }
+        \setcounter { zc at save@appendix } { 0 }
+        \cs_if_exist:cTF { chapter }
+          {
+            \__zrefclever_zcsetup:n
+              { counterresetby = { chapter = zc at appendix } }
+          }
+          {
+            \cs_if_exist:cT { section }
+              {
+                \__zrefclever_zcsetup:n
+                  { counterresetby = { section = zc at appendix } }
+              }
+          }
+        \AddToHook { env / appendices / begin }
+          {
+            \stepcounter { zc at save@appendix }
+            \setcounter { zc at appendix } { \value { zc at save@appendix } }
+            \__zrefclever_zcsetup:n
+              {
+                countertype =
+                  {
+                    chapter       = appendix ,
+                    section       = appendix ,
+                    subsection    = appendix ,
+                    subsubsection = appendix ,
+                    paragraph     = appendix ,
+                    subparagraph  = appendix ,
+                  }
+              }
+          }
+        \AddToHook { env / appendices / end }
+          { \setcounter { zc at appendix } { 0 } }
+        \AddToHook { cmd / appendix / before }
+          {
+            \stepcounter { zc at save@appendix }
+            \setcounter { zc at appendix } { \value { zc at 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 at newprop { subcaption }
+          { \cs_if_exist_use:c { @@thesub \@captype } }
+        \AddToHook{ cmd / @memsubcaption / before }
+          { \zref at localaddprop \ZREF at 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 at wrapper@babel \zref at label {#1}
+          }
+        \__zrefclever_if_package_loaded:nTF { hyperref }
+          {
+            \AddToHook { package / nameref / after }
+              {
+                \cs_new_eq:NN \__zrefclever_orig_ltxlabel:n \ltx at label
+                \cs_set_eq:NN \ltx at label \__zrefclever_ltxlabel:n
+              }
+          }
+          {
+            \cs_new_eq:NN \__zrefclever_orig_ltxlabel:n \ltx at label
+            \cs_set_eq:NN \ltx at 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 at type } { } }
+                      { equation }
+                      {
+                        \protected at write \@auxout { }
+                          { \string \MT at newlabel {##1} }
+                      }
+                      {
+                        \exp_args:Nx \tl_if_eq:nnT
+                          { \__zrefclever_extract_unexp:nnn {##1} { zc at type } { } }
+                          { parentequation }
+                          {
+                            \protected at write \@auxout { }
+                              { \string \MT at 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 at AddToHook { PreInit }
+          { \tl_if_empty:NF \lst at label { \zlabel { \lst at label } } }
+        \lst at 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 at newprop { subref }
+          { \cs_if_exist_use:c { thesub \@captype } }
+        \tl_put_right:Nn \caption at subtypehook
+          { \zref at localaddprop \ZREF at 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'.


Property changes on: trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever.sty
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/tlpkg/bin/tlpkg-ctan-check
===================================================================
--- trunk/Master/tlpkg/bin/tlpkg-ctan-check	2021-11-24 21:30:42 UTC (rev 61144)
+++ trunk/Master/tlpkg/bin/tlpkg-ctan-check	2021-11-24 21:31:19 UTC (rev 61145)
@@ -866,7 +866,7 @@
     yinit-otf york-thesis youngtab yplan yquant ytableau
   zapfchan zapfding zbmath-review-template zebra-goodies zed-csp
     zhlineskip zhlipsum zhnumber zhmetrics zhmetrics-uptex zhspacing
-    ziffer 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
 ); 

Modified: trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
===================================================================
--- trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc	2021-11-24 21:30:42 UTC (rev 61144)
+++ trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc	2021-11-24 21:31:19 UTC (rev 61145)
@@ -1405,5 +1405,6 @@
 depend ziffer
 depend zref
 depend zref-check
+depend zref-clever
 depend zwgetfdate
 depend zwpagelayout

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


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