% \iffalse meta-comment
%
% File: zref-clever.tex
%
% This file is part of the LaTeX package "zref-clever".
%
% Copyright (C) 2021-2023  gusbrs
%
% 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 gusbrs.
%
% This work consists of the files zref-clever.dtx,
%                                 zref-clever.ins,
%                                 zref-clever-doc.tex,
%                                 zref-clever-code.tex,
%                   and the files generated from them.
%
% 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}

\usepackage{fontspec}
\setmainfont{TeX Gyre Pagella}
\setsansfont{TeX Gyre Heros}[Scale=MatchLowercase]
\setmonofont{inconsolata}[Scale=MatchLowercase]

% The package itself *must* be loaded so that \GetFileInfo can pick up date
% and version data.  Naturally, we also use it.
\usepackage{zref-clever}
\zcsetup{cap}
\usepackage{zref-check}
\usepackage{zref-titleref}

\usepackage{listings}

\usepackage{microtype}

\hypersetup{hidelinks}

\NewDocumentCommand\opt{m}{\texttt{#1}}

\NewDocumentCommand\contributor{m}{#1}
\NewDocumentCommand\username{m}{`\texttt{#1}'}

\makeatletter
\newcommand{\zcrequiredkernel}{\zrefclever@required@kernel}
\makeatother

\setlength{\marginparsep}{2\labelsep}

\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,
    AddToHookWithArguments,
    DeclareHookRule,
    define@key,
    patchcmd,
    eq@setnumber,
    DeclareFloatingEnvironment,
    newlist,
    setlist,
    zexternaldocument,
    next@label,
    next@label@pre,
    @empty,
    tag,
    text,
    lstset,
    condition,
    RenewDocumentCommand,
    NewCommandCopy,
    ltx@gobble,
    @currentcounter,
    @currentHref,
    zref@label,
    zref@wrapper@babel,
    zref@ifpropundefined,
    zref@setcurrent,
    zref@newprop,
    zref@addprop,
    beamer@old@zref@label,
    alt,
    beamer@nameslide,
    beamer@dummynameslide,
    uncover,
    only,
    ordinal,
    tcbuselibrary,
    tcbset,
    newtcolorbox,
    newtcbtheorem,
  }
}
\lstdefinestyle{zrefclever}{
  style=code,
  moretexcs={
    zcref,
    zcpageref,
    zlabel,
    zcsetup,
    zcLanguageSetup,
    zcRefTypeSetup,
    zcheck,
    zvref,
    zvpageref,
    zvrefrange,
    zvpagerefrange,
    zfullref,
  }
}
\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}%
  \renewcommand*\theHlstlisting{ht.\thelstlisting}%
  \zcsetup{countertype={lstlisting=zchowto}}%
  \lstset{#1}%
  \stepcounter{zchowto}%
  \setcounter{lstlisting}{\value{zchowto}-1}%
}{}
\newcounter{zcworkaround}
\lstnewenvironment{zcworkaround}[1][]{%
  \renewcommand{\lstlistingname}{Work-around}%
  \renewcommand*\theHlstlisting{wa.\thelstlisting}%
  \zcsetup{countertype={lstlisting=zcworkaround}}%
  \lstset{#1}%
  \stepcounter{zcworkaround}%
  \setcounter{lstlisting}{\value{zcworkaround}-1}%
}{}
\lstnewenvironment{zcexample}[1][]{%
  \renewcommand{\lstlistingname}{Example}%
  \lstset{#1}%
}{}

\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%
  \texorpdfstring{\\{}\medskip{}}{ - }%
  User manual%
  \texorpdfstring{\medskip{}}{}%
}

\author{%
  \texorpdfstring{\texttt{gusbrs}\\[0.8em]
  \url{https://github.com/gusbrs/zref-clever}\\
  \url{https://www.ctan.org/pkg/zref-clever}}{gusbrs}}

\date{Version \fileversion\ -- \filedate}

\maketitle

\begin{center}
  {\bfseries \abstractname\vspace{-.5em}\vspace{0pt}}
\end{center}

\begin{quotation}
  \pkg{zref-clever} provides a 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{quotation}

\bigskip{}

\begin{center}
  \textbf{EXPERIMENTAL}

  Please read \zcref{sec:warning} carefully.
\end{center}

\clearpage{}

\tableofcontents

\clearpage{}

\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 some of the most popular:
\pkg{cleveref}, \pkg{nameref}, \pkg{titleref}, \pkg{varioref}, \pkg{fancyref},
and the kernel's \cs{labelformat}.

However, the standard cross-referencing system traditionally stored 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, or which somehow
depended on extending the cross-referencing mechanism, were bound to step on
each other's toes as a result.  Nowadays (2024), many of these issues have
changed for the better.  Notably, now the kernel's \cs{label} already stores
five arguments, regardless of the presence of \pkg{hyperref}, and also
provides a hook with the label as argument so that packages can extend its
functionality without the need to redefine it, as \pkg{nameref} now already
does (and so does \pkg{zref-clever}).\footnote{We are currently observing some
  of the pains of adjusting the ecosystem to these improvements though\dots{}}

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 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 \pkg{zref-vario} offers integration of \pkg{zref-clever} with
\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.  All in all, hopefully \pkg{zref-clever} can make \pkg{zref} more
accessible to the average user, and more interesting to users in general.


\section{Warning}
\label{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{\pkg{zref-clever} for the impatient}

Making cross-references with \pkg{zref-clever} is very similar to the standard
referencing system in its user interface: one sets a label, with \cs{label},
which can then be referenced, in our case with \cs{zcref}, which is the main
and basic entrance for making references with \pkg{zref-clever}.  \cs{zcref}
receives a list of labels as argument and its behavior can be locally changed
through the optional argument.

A basic document using \pkg{zref-clever} is shown in \zcref{how:basic} which
should feel very familiar to any \LaTeX{} user acquainted with the standard
referencing system:

\begin{zchowto}[caption={Basic usage},label={how:basic}]
\documentclass{article}
\usepackage{zref-clever}
\usepackage{hyperref}
\begin{document}
\section{Section 1}
\label{sec:section-1}
\begin{figure}
  A figure.
  \caption{Figure 1}
  \label{fig:figure-1}
\end{figure}
A reference to \zcref{sec:section-1}. \zcref[S]{fig:figure-1} shows some
interesting information.
A page reference can be done with either \zcpageref{sec:section-1} or with
\zcref[page]{sec:section-1}.
A reference can also be made to multiple labels, as in \zcref{sec:section-1,
  fig:figure-1}.
\end{document}
\end{zchowto}

The references in the document of \zcref{how:basic} illustrate one of the main
features of \pkg{zref-clever}, which is to include an appropriate ``type
name'' of the reference, alongside of the reference itself.  The document
renders its references as:
\begin{quote}
  A reference to section 1. Figure 1 shows some interesting information. A
  page reference can be done with either page 1 or with page 1. A reference
  can also be made to multiple labels, as in section 1 and figure 1.
\end{quote}

\zcref[S]{how:basic} also illustrates the use the optional argument of
\cs{zcref} to modulate the behavior of the reference.  In particular, the
\opt{S} option is one you should get acquainted with from the start, as it
ensures that the type name of a reference is properly capitalized and not
abbreviated, and it is meant to be used in references made at the beginning of
a sentence.

But \pkg{zref-clever} is highly customizable, and several other options exist,
and multiple places where you can set them:

\begin{itemize}
\item The optional argument of \cs{zcref}: for individual references.
\item \cs{zcsetup}: for settings meant to affect all references.
\item \cs{zcRefTypeSetup}: to customize the behavior of each reference type.
\item \cs{zcLanguageSetup}: for language-specific settings.
\end{itemize}

For the list of available options, and for these different scopes in which
they can be used, see \zcref{sec:user-interface, sec:options,
  sec:reference-format, sec:internationalization}.  Other usage examples are
available at \zcref{sec:how-tos}.


\section{Loading the package}
\label{sec:loading-package}

\pkg{zref-clever} can be loaded with the usual:

\begin{zcexample}
\usepackage{zref-clever}
\end{zcexample}

The package does not accept load-time options, package options must be set
using \cs{zcsetup} (see \zcref{sec:user-interface}).


\subsection{Dependencies}

\pkg{zref-clever} requires \pkg{zref}, particularly its \pkg{zref-base},
\pkg{zref-user} and \pkg{zref-abspage} modules, and the \LaTeX{} kernel
\zcrequiredkernel{}, or newer.  It requires UTF-8 input encoding, which has
been the kernel's default for some time.  It also needs \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-hyperref} and \pkg{zref-xr} modules.


\section{User interface}
\label{sec:user-interface}

\begin{function}{\zcref}
  \begin{syntax}
    \cs{zcref}\meta{*}\oarg{options}\marg{labels}
  \end{syntax}
\end{function}
Typesets references to \meta{labels}, given as a comma separated list.  When
\pkg{hyperref} support is enabled, references will be hyperlinked to their
respective anchors, according to options.  The starred version of the command
does the same as the plain one, just does not form links.  The \meta{options}
are (mostly) the same as those of the package, and can be given to local
effect.  The \meta{labels} argument is protected by \pkg{zref}'s
\cs{zref@wrapper@babel}, so that it enjoys the same support for \pkg{babel}'s
active characters as \pkg{zref} itself does.

\begin{function}{\zcpageref}
  \begin{syntax}
    \cs{zcpageref}\meta{*}\oarg{options}\marg{labels}
  \end{syntax}
\end{function}
Typesets page references to \meta{labels}, given as a comma separated list.
It is equivalent to calling \cs{zcref} with the \opt{ref=page} option:
\cs{zcref}\texttt{\meta{*}[}\meta{options}\texttt{,ref=page]}\marg{labels}.


\begin{function}{\zcsetup}
  \begin{syntax}
    \cs{zcsetup}\marg{options}
  \end{syntax}
\end{function}
Sets \pkg{zref-clever}'s general options (see \zcref{sec:options,
  sec:reference-format}).  The settings performed by \cs{zcsetup} are local,
within the current group.  But, of course, it can also be used to global
effects if ungrouped, e.g.\ in the preamble.

\begin{function}{\zcRefTypeSetup}
  \begin{syntax}
    \cs{zcRefTypeSetup}\marg{type}\marg{options}
  \end{syntax}
\end{function}
Sets type-specific reference format options (see
\zcref{sec:reference-format}).  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,
including \cs{zref} and \cs{zpageref}, but notably:


\section{Options}
\label{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:reference-format}).  General options can be set globally 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 initial value is
\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, with
initial value \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,
with initial value \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{endrange} %
The \opt{endrange} option provides additional control over how the end
reference of a range is typeset, so as to achieve terse ranges.  The option
can operate in two technically different ways.  It may receive one of a number
of predefined values, which can process the end reference of the range,
comparing it with the beginning reference, to achieve a given end
result.\footnote{For the \TeX{}nically inclined: those values that perform
  some processing -- namely \texttt{stripprefix}, \texttt{pagecomp}, and
  \texttt{pagecomp2} -- fully expand the references before comparing them,
  since it makes sense to perform this task as close as possible to the
  printed representation of the references.  I don't expect this to be a
  problem in normal use cases, but it does represent a limitation on what the
  references can contain.  In case some control over this is needed, check the
  \texttt{zref-clever/endrange-setup} hook in the code documentation.}  Or, it
can specify a label property to be used directly, without any processing.  The
available predefined values are: \texttt{ref}, \texttt{stripprefix},
\texttt{pagecomp}, and \texttt{pagecomp2}.  \texttt{ref} corresponds to the
default behavior, and instructs \cs{zcref} to use whatever property was set at
the \opt{ref} option for the end of range reference.  \texttt{stripprefix}
strips the common part at the start of each reference from the end one.
\texttt{pagecomp} is the equivalent of \texttt{stripprefix} for page numbers,
it does the same thing, but only if the references are comprised exclusively
of Arabic numerals.  \texttt{pagecomp2} is a variant of \texttt{pagecomp} that
leaves at least two digits at the end reference (except for a leading zero).
If values other than the predefined ones are given to \opt{endrange} they are
considered as label properties, as long as they are declared.  This property
is used to typeset the end of range reference if the label contains it, and if
both references would be ``compressible'' according to the \opt{comp} option,
otherwise the property specified by the \opt{ref} option is used.  This is
useful for things like sub-elements for which we can build a proper
abbreviated sub-reference and populate the label with it (some compatibility
modules already provide a number of such properties, but other ones can be
built with \pkg{zref}, as needed).

\DescribeOption{range} %
\DescribeOption{rangetopair} %
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.  It is a boolean option, and
the initial value is \texttt{false}.  \cs{zcref} is smart enough 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''.  But this behavior
can be disabled by setting the \opt{rangetopair} option to \texttt{false}.

\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 it can also be set for
specific reference types or languages (see \zcref{sec:reference-format}).  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 it can also be set
for specific reference types or languages (see \zcref{sec:reference-format}).
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{noabbrevfirst=true, capfirst=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
initial 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 initial value is
\texttt{nameinlink=tsingle}, and the option given without a value is
equivalent to \texttt{nameinlink=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:reference-format}).  The initial 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{v} %
The \opt{v} option sets the variant, 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 initial value 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:reference-format}).  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 files can store the gender(s) of each type name
(this is done for built-in language files, 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(s) for the type name in the language file.  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:reference-format}).  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.

\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:reference-format}).

\DescribeOption{check} %
Provides integration of \pkg{zref-clever} with the \pkg{zref-check} package.
The option is only functional in the document body and if \pkg{zref-check} has
been loaded.  \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:reference-format}).

\DescribeOption{countertype} %
\DescribeOption{reftype} %
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 initial
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.  The \opt{reftype}
option allows one to specify the reference type manually, regardless of the
current counter.  This can be used to locally override any \opt{countertype}
settings of the package and, for those acquainted with it, is the equivalent
of \pkg{cleveref}'s optional argument to \cs{label}.  Normally, you'd want to
use this option within a group, but if you must do otherwise, the default
value can be restored by setting the option without a value.  Since these
options only affect how labels are set, they are 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 receives a full comma separated list of counter
names, which \pkg{zref-clever} uses to search for ``enclosing counters'' of
the counter for which a label is being set.  The order matters (see code
documentation for details), and you should also take care to start from the
initial value set by the package.  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
initial 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 initial 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{label} set after it: \cs{@currentlabel} and \cs{@currentcounter}.  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,\footnote{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).} it is likely that in some 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, take care that 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 initial value is, quite naturally, \cs{@currentcounter}, which can be
reset by calling the option with no value.  Since this option only affects how
labels are set, it is not available in \cs{zcref}.

\DescribeOption{\raisebox{.4em}{\dbend}\ labelhook} %
\opt{labelhook} is a boolean option which controls whether \pkg{zref-clever}
uses the kernel's \texttt{label} hook to, whenever a standard \cs{label} is
called, also set a \cs{zlabel} with the same name (which is what
\pkg{zref-clever} actually uses to make its references).  The package's
initial value is \texttt{true} so that one can use \cs{label}s along the
document and refer to them (also) with \pkg{zref} and \pkg{zref-clever}
reference commands.  This value is not only the default, but also a
recommended value.  Disabling this option means you are on your own to handle
cases where \cs{zlabel} does not work, which are not many, but can be tricky
to deal with where they occur.  Since this option only affects how labels are
set, it is not available in \cs{zcref}.  See \zcref{sec:label-or-zlabel} for
some discussion of different labeling approaches this options allows for.

\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 types}
\label{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 initial 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 language files.}  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 \cs{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 \cs{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 ``name'' which \pkg{zref-clever} uses to look for a whole set of
type-specific reference format options (see \zcref{sec:reference-format}).
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.


\section{Reference format}
\label{sec:reference-format}

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 a 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- and type-specific options}; and iv) as
\emph{language-specific default options}.  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} (see \zcref{sec:options}).
``Type'' specific options (ii) are handled by \cs{zcRefTypeSetup} (see
\zcref{sec:user-interface}).  ``Language'' options, whether ``type'' specific
(iii) or ``default'' (iv) have their user interface in \cs{zcLanguageSetup},
and have their values populated by the package's built-in language files (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      & \multicolumn{2}{c}{Language} \\
                                                             \cmidrule(lr){5-6}
                     &             &           &           & Type      & Default   \\
                     &             & (i)       & (ii)      & (iii)     & (iv)      \\

    \midrule
    Typesetting      & tpairsep    & $\bullet$ &           &           & $\bullet$ \\
    (necessarily not & tlistsep    & $\bullet$ &           &           & $\bullet$ \\
    type-specific)   & tlastsep    & $\bullet$ &           &           & $\bullet$ \\
                     & notesep     & $\bullet$ &           &           & $\bullet$ \\

    \addlinespace
    Typesetting      & namesep     & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
    (possibly        & pairsep     & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
    type-specific)   & listsep     & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
                     & lastsep     & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
                     & rangesep    & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
                     & refbounds   & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\

    \addlinespace
    Typesetting      & Name-sg     &           & $\bullet$ & $\bullet$ &           \\
    (necessarily     & name-sg     &           & $\bullet$ & $\bullet$ &           \\
    type-specific)   & 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$ & $\bullet$ & $\bullet$ \\
                     & reffont     & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\

    \addlinespace
    Other            & cap         & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
                     & abbrev      & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
                     & endrange    & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
                     & rangetopair & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
    \bottomrule
  \end{tabular}
  \caption{Reference format options and their scopes}
  \label{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{preref*}
  \raisebox{-\baselineskip}{\makebox[0pt]{\^{}}}%
  \raisebox{-1.2\baselineskip}{\makebox[0pt]{\footnotesize{}hyperlink start}}
  \reffmt{preref} \reffmt{ref} \reffmt{postref}
  \raisebox{-\baselineskip}{\makebox[0pt]{\^{}}}%
  \raisebox{-1.2\baselineskip}{\makebox[0pt]{\footnotesize{}hyperlink end}}
 \reffmt{postref*}
\end{refformat}

Where the \opt{refbounds} option, which receives as value a comma separated
list of four items in the form \texttt{\{preref*,preref,postref,postref*\}},
sets the surrounding elements to \texttt{ref}.\footnote{As usual, if each of
  the items contains start or end spaces, or commas anywhere, they must be
  protected by a pair of braces.  However, care is taken that empty items
  don't need such protection.  So you can set, for example, something like
  \texttt{refbounds=\{(,{},{},)\}} to get parentheses around your references,
  outside the hyperlink.}  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 three general categories: i)
``typesetting'' options, the ones which we have seen thus far, as ``building
blocks'' of the reference; ii) ``font'' options, which control font attributes
of parts of the reference, namely \opt{namefont} and \opt{reffont}; and iii)
``other'' options.  ``Typesetting'' options are intended exclusively for
typesetting material: things you expect to see in the output of your
references.  ``Font'' 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}).  These options
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 language file 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.  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} ,
\end{zcexample}


\subsection{Advanced reference formatting}

The reference format options discussed above and presented in
\zcref{tab:reference-format} should suffice for most needs.  However, if more
fine-grained control of the reference format is needed, this can be achieved
through a more detailed specification of \opt{refbounds} for the different
cases in which they may occur when a reference is processed.  The options
available for this purpose are presented in
\zcref{tab:advanced-reference-format}.

\begin{table}
  \centering
  \DeleteShortVerb \|
  \begin{tabular}{l>{\ttfamily}lcccc}
    \toprule
             &          & General   & Type      & \multicolumn{2}{c}{Language} \\
                                                  \cmidrule(lr){5-6}
             &          &           &           & Type      & Default   \\
             &          & (i)       & (ii)      & (iii)     & (iv)      \\

    \midrule
    Base     & refbounds-first     & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
    options  & refbounds-first-sg  & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
             & refbounds-first-pb  & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
             & refbounds-first-rb  & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
             & refbounds-mid       & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
             & refbounds-mid-rb    & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
             & refbounds-mid-re    & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
             & refbounds-last      & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
             & refbounds-last-pe   & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
             & refbounds-last-re   & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\

    \addlinespace
    Derived  & +refbounds-first    & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
    options  & +refbounds-mid      & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
    (groups) & +refbounds-last     & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
             & +refbounds-rb       & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
             & +refbounds-re       & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
             & +refbounds          & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
    \bottomrule
  \end{tabular}
  \caption{Advanced reference format options and their scopes}
  \label{tab:advanced-reference-format}
\end{table}

The ``base'' options are the actually operative ones, while the ``derived''
options are convenience aliases to set multiple base options in one go.  In
the naming scheme of these options, as is easy to presume, ``\texttt{first}''
refers to the first reference of a type-block, ``\texttt{mid}'' to the middle
ones, and ``\texttt{last}'' to the last reference of the type-block.  Less
obviously, but hopefully still mnemonic enough, ``\texttt{sg}'' stands for
``single'', ``\texttt{pb}'' and ``\texttt{pe}'' for ``pair begin'' and ``pair
end'', and finally ``\texttt{rb}'' and ``\texttt{re}'' for ``range begin'' and
``range end''.  Each of them receives as value a comma separated list of four
items in the form \texttt{\{preref*,preref,postref,postref*\}}, just like
\opt{refbounds}.

The base options are mutually exclusive, which means, for example, that it is
not sufficient to set \opt{refbounds-first} to define the behavior of all
first references of a type block.  \opt{refbounds-first} is the value used for
the first reference when not single, not the beginning of a pair, and not the
beginning of a range.  Setting a group of them is the purpose of the derived
options.  Each of these sets all options under it.  Some examples.
\opt{+refbounds-first} sets \opt{refbounds-first}, \opt{refbounds-first-sg},
\opt{refbounds-first-pb}, and \opt{refbounds-first-rg}.  In turn,
\opt{+refbounds-rb} sets \opt{refbounds-first-rb} and \opt{refbounds-mid-rb}.
And quite conveniently, \opt{+refbounds} sets \opt{+refbounds-first},
\opt{+refbounds-mid}, and \opt{+refbounds-last}, it is hence sufficient to set
it to define the behavior of what is typeset around all references for the
whole type-block.  As you probably guessed by now, the \opt{refbounds} option
presented in \zcref{tab:reference-format} is an alias of \opt{+refbounds}.

Given that base and derived options are actually setting the same group of
underlying options (the base ones), the order in which they are given is
relevant: the last one prevails.  The idea here is to use first the derived
options to set some general defaults, and then change one or another base
option to handle exceptions as needed.  Of course, how best to use them
depends on the case.


\section{Internationalization}
\label{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 see \zcref{sec:reference-format}).
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 ``language file'' for it, most use cases will
likely be covered by the \opt{lang} option (see \zcref{sec:options}), and its
values \texttt{current} and \texttt{main}.  When the \opt{lang} option is set
to \texttt{current} or \texttt{main}, \pkg{zref-check} will use, respectively,
the \emph{current} or \emph{main} language of the document, as defined by
\pkg{babel} or \pkg{polyglossia}.\footnote{Technically, \pkg{zref-clever} uses
  \cs{languagename} and \cs{bbl@main@language} for \pkg{babel}, and
  \cs{babelname} and \cs{mainbabelname} for \pkg{polyglossia}, which boils
  down to \pkg{zref-clever} always using \emph{\pkg{babel} names} internally,
  regardless of which language package is in use.  Indeed, an acquainted user
  will note that \zcref{tab:languages-and-aliases} contains only \pkg{babel}
  language names.}  Users can also set \opt{lang} to a specific language
directly, in which case \pkg{babel} and \pkg{polyglossia} are disregarded.
\pkg{zref-clever} provides a number of built-in ``language files'', for the
languages listed in \zcref{tab:languages-and-aliases}, which also includes the
declared aliases to those languages.

\pkg{zref-clever}'s ``language files'' are loaded sparingly and lazily.  A
language file 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 language file 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 language files 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
    dutch      &              \\
    english    & american     \\
               & australian   \\
               & british      \\
               & canadian     \\
               & newzealand   \\
               & UKenglish    \\
               & USenglish    \\
    french     & acadian      \\
               &              \\
               &              \\
               &              \\
    \bottomrule
  \end{tabular}
  \quad
  \begin{tabular}{ll}
    \toprule
    Language   & Aliases      \\
    \midrule
    german     & ngerman      \\
               & austrian     \\
               & naustrian    \\
               & swissgerman  \\
               & nswissgerman \\
    italian    &              \\
    portuguese & brazilian    \\
               & brazil       \\
               & portuges     \\
    russian    &              \\
    spanish    &              \\
    swedish    &              \\
    \bottomrule
  \end{tabular}
  \caption{Declared languages and aliases}
  \label{tab:languages-and-aliases}
\end{table}


But if the built-in language files 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
  language file 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{variants},
\opt{gender}, and \opt{allcaps}.  \opt{variants} receives a coma separated
list of valid type name variants for \meta{language}.\footnote{This option was
  initially conceived to support declension cases, but was eventually
  generalized to encompass a broader meaning, and is now more flexibly
  interpreted as simply ``variants''.}  The first element of the list is
considered to be the default variant, both for the \opt{v} option in
\cs{zcref} and for the \opt{variant} 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 language files 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   & variants    & gender & allcaps \\
    \midrule
    dutch      & --          & f,m,n  & --      \\
    english    & --          & --     & --      \\
    french     & --          & f,m    & --      \\
    german     & N,A,D,G     & f,m,n  & yes     \\
    italian    & --          & f,m    & --      \\
    portuguese & --          & f,m    & --      \\
    spanish    & --          & f,m    & --      \\
    russian    & n,a,g,d,i,p & f,m,n  & --      \\
    swedish    & --          & --     & --      \\
    \bottomrule
  \end{tabular}
  \caption{Options for declared languages}
  \label{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:reference-format}), 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{variant}, 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{variant=X}
(provided \texttt{X} is a valid variant for \meta{language}), the following
\texttt{[Nn]ame-} options will set values for the \texttt{X} variant (other
reference format options are not affected by \opt{variant}).  Before the first
occurrence of either \opt{type} or \opt{variant} default values are set.  For
\opt{variant} this means the default variant, which is the first element of
the list provided to the \opt{variants} option in \cs{zcDeclareLanguage}.  For
\opt{type} this means language-specific but not type-specific option values
(see \zcref{sec:reference-format}).  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}).  For \texttt{type}s which have multiple valid genders
for a given language, the option can also receive a comma separated list.
\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 ,
    variant = N ,
      Name-sg = Abschnitt ,
      Name-pl = Abschnitte ,
    variant = A ,
      Name-sg = Abschnitt ,
      Name-pl = Abschnitte ,
    variant = D ,
      Name-sg = Abschnitt ,
      Name-pl = Abschnitten ,
    variant = 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 as \opt{variants} with \cs{zcDeclareLanguage}, and the name reference
format options must be provided for each case, which is done for built-in
language files 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{v} option (see \zcref{sec:options}).  So you may
write something like ``\texttt{nach den
  \cs{zcref}[v=D]\{sec:section-1,sec:section-2\}}'' to get ``nach den
Abschnitten 1 und 2''.  Or ``\texttt{trotz des
  \cs{zcref}[v=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 set in the language file or with
\cs{zcLanguageSetup}, 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
language files 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 given 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}
\label{sec: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{Extended page references (\pkg{varioref})}

\zctask{Make cross-references to pages which are sensitive to the relative
  position between the reference and the label being referred to using
  \pkg{varioref}.}

The \pkg{zref-vario} package offers a layer of compatibility with
\pkg{varioref} and provides \texttt{\textbackslash{}z}\dots{} counterparts for
the latter's main reference commands.

\begin{zchowto}[caption={\pkg{zref-vario}}]
\documentclass{article}
\usepackage{zref-clever}
\usepackage{zref-vario}
\begin{document}
\section{Section 1}
\label{sec:section-1}
\begin{figure}
  A figure.
  \caption{Figure 1}
  \label{fig:figure-1}
\end{figure}
\begin{figure}
  Another figure.
  \caption{Figure 2}
  \label{fig:figure-2}
\end{figure}
\zvref[S]{sec:section-1}\par
\zvpageref{fig:figure-1}\par
\zvrefrange{fig:figure-1}{fig:figure-2}\par
\zvpagerefrange{fig:figure-1}{fig:figure-2}\par
\zfullref{fig:figure-1}
\end{document}
\end{zchowto}


\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 if 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} and \opt{refname} 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}\label{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}\label{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}\label{theorem-1}
  A theorem.
\end{mytheorem}
\begin{myproposition}\label{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 language options 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}\label{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}
  \label{diagram-1}
\end{diagram}
\zcref{diagram-1}
\end{document}
\end{zchowto}


\subsection{Overriding the reference type}

\zctask{Make references to a system of equations, which should be referred to
  in the plural.}

Though, usually, setting the \opt{countertype} option may provide a more
general and convenient way to set the reference type of a given counter,
sometimes we just need to do it for a particular label or set of labels.  The
\opt{reftype} option allows us to do so and set the reference type directly,
regardless of what the current counter is.

\begin{zchowto}[caption={Overriding the reference type}]
\documentclass{article}
\usepackage{amsmath}
\usepackage{zref-clever}
\usepackage{hyperref}
\zcRefTypeSetup{pluralequation}{
  Name-sg = Equations ,
  name-sg = equations ,
  Name-pl = Equations ,
  name-pl = equations ,
}
\begin{document}
\section{Section 1}
\begin{equation}
  \zcsetup{reftype=pluralequation}
  \label{eq:1}
  \begin{aligned}
    A+B&=B+A\\
    C&=D+E\\
    E&=F
  \end{aligned}
\end{equation}
\zcref{eq:1}
\end{document}
\end{zchowto}


\subsection{\pkg{enumitem}}

\zctask{Setup a custom enumerate environment created with \pkg{enumitem} to be
  referred to.}

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.\label{item-1}
  \begin{myenumerate}
  \item An item.\label{item-2}
    \begin{myenumerate}
    \item An item.\label{item-3}
      \begin{myenumerate}
      \item An item.\label{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.}

\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}
\label{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}
\label{sec:section-b1}
\end{document}
\end{zchowto}


\subsection{\pkg{tcolorbox}}

\zctask{Make references to boxes from the \pkg{tcolorbox} package.}

\pkg{tcolorbox} has support for \pkg{zref} and \pkg{zref-clever}, hence
setting labels with the \opt{label} option works out of the box (as long as
\opt{labelhook} is enabled).  If you are using the \opt{auto counter}, or some
other custom counter, \pkg{tcolorbox}'s \opt{label type} option can be used to
set \pkg{zref-clever}'s \opt{reftype} for the relevant scope.  Furthermore,
those who prefer to work with \cs{zlabel}s only can set the \opt{label is
  zlabel} option, which makes the \opt{label} option set a \cs{zlabel}
directly.

\begin{zchowto}[caption={\pkg{tcolorbox}}]
\documentclass{article}
\usepackage{zref-clever}
\usepackage{zref-titleref}
\usepackage{tcolorbox}
\tcbuselibrary{theorems}
\usepackage{hyperref}
\newtcolorbox[auto counter,number within=section]{pabox}[2][]{%
  label type=example,
  title=Example~\thetcbcounter: #2,#1}
\newtcolorbox[use counter from=pabox,number within=section]{pabox2}[2][]{%
  label type=solution,
  title=Solution~\thetcbcounter: #2,#1}
\newtcbtheorem[number within=section]{mytheo}{My Theorem}{%
  label type=mytheorem}{th}
\zcRefTypeSetup{mytheorem}{
  Name-sg=Mytheorem,
  name-sg=mytheorem,
  Name-pl=Mytheorems,
  name-pl=mytheorems,
}
\begin{document}
\section{Section 1}
\label{sec:section-1}
\begin{pabox}[label={box:1}]{Title text}
  This is tcolorbox \zcref{box:1} on \zcpageref{box:1}.
\end{pabox}
\begin{pabox2}[label={box:2}]{Title text}
  This is tcolorbox \zcref{box:2} on \zcpageref{box:2}.
\end{pabox2}
\begin{mytheo}{This is my title}{theo}
  This is \zcref{th:theo} on \zcpageref{th:theo} and it is titled
  ``\zcref[noname,ref=title]{th:theo}''.
\end{mytheo}
\end{document}
\end{zchowto}


\subsection{\cls{beamer}}

\zctask{Making references in \cls{beamer}.}

\cls{beamer} does some atypical things with regard to cross-references, in
particular it redefines \cs{label} to support overlays.  The special treatment
is not extended to \cs{zlabel}, hence \cls{beamer} requires the use of
\cs{label} with the \opt{labelhook} option.  Some setup for references to
frames is also needed, with a fitting setting for the \opt{countertype} of the
\texttt{framenumber} counter and, possibly, corresponding type names for
it.\footnote{I'm not sure what the best type name for it would be though.
  ``Frame'' sounds too \cls{beamer}-specific, and possibly ``slide'' is what
  ``the audience'' would expect.  But \emph{some} name (or preexisting type)
  would need to be assigned, and you can always choose something else, of
  course.  This is just to illustrate the procedure.}

\begin{zchowto}[caption={\cls{beamer}}]
\documentclass{beamer}
\usepackage{zref-clever}
\zcsetup{countertype={framenumber=slide}}
\zcRefTypeSetup{slide}{
  Name-sg = Slide ,
  name-sg = slide ,
  Name-pl = Slides ,
  name-pl = slides ,
}
\begin{document}
\begin{frame}[label={fr:1}]
  \begin{table}
    \begin{tabular}{cc}
      1 & 2 \\
      3 & 4 \\
    \end{tabular}
    \caption{Table 1}
    \label{tab:1}
  \end{table}
\end{frame}
\begin{frame}[label={fr:2}]
  \begin{figure}
    \rule{5cm}{5cm}
    \caption{Figure 1}
    \label{fig:1}
  \end{figure}
\end{frame}
\begin{frame}
  \zcref{fr:1,fr:2,tab:1,fig:1}
\end{frame}
\begin{frame}
  \begin{align}
    a &= b + c \label{eq:1}\\
    c &= d + e \label{eq:2}
  \end{align}
  Blah blah. \uncover<2>{More blah blah.}\par
  \only<3>{Specification is needed now.\label<3>{overlay}}
\end{frame}
\begin{frame}
  \zcref{eq:1,eq:2,overlay}
\end{frame}
\end{document}
\end{zchowto}


\subsection{Ordinal references}

\zctask{Typesetting the references as ordinal numbers.}

This example is intended as an illustration of the flexibility \pkg{zref}'s
extensible referencing system grants us.\footnote{Though clearly simplified,
  the example is less than academic.
  See \url{https://tex.stackexchange.com/a/670088} for an application to add a
  reference suffix needed in Turkish.}  Getting references as ordinal numbers,
something that would be normally a tricky task, can be handled with a simple
custom \pkg{zref} property, which we then use to set \pkg{zref-clever}'s
\opt{ref} option.

\begin{zchowto}[caption={Ordinal references}]
\documentclass{article}
\usepackage{zref-clever}
\usepackage{fmtcount}
\makeatletter
\zref@newprop{ordref}{\ordinal{\@currentcounter}}
\zref@addprop{main}{ordref}
\makeatother
\zcsetup{ref=ordref}
\begin{document}
\section{Section 1}
\label{sec:section-1}
\begin{figure}
A figure.
\caption{Figure 1}
\label{fig:figure-1}
\end{figure}
\zcref{sec:section-1,fig:figure-1}
\end{document}
\end{zchowto}


\section{\cs{label} or \cs{zlabel}?}
\label{sec:label-or-zlabel}

TL;DR: Just use \cs{label}, unless you have special requirements.

\medskip{}

Technically, \pkg{zref}'s referencing system, and thus also \pkg{zref-clever},
require a label set with \cs{zlabel} to make a reference.  However, the
\opt{labelhook} option (see \zcref{sec:options}) leverages the kernel's
\texttt{label} hook to also set a \cs{zlabel} when a standard \cs{label} is
called, so that we can simply use \cs{label}s in our document and refer to
them with either referencing system.  Indeed, in some places the use of
\cs{label} this way may be required.  That given, which is to be preferred:
use \cs{label} all around or normally use \cs{zlabel} and, occasionally resort
to \cs{label} where required?  I guess it depends, but we can reason the pros
and cons of both alternatives.

Simply using \cs{label} across your document clearly speaks for convenience.
You don't have to worry with the exceptional case where a \cs{zlabel} may not
work or setting it is not possible.  You can use either referencing system for
your labels as desired.  Your favorite editor may have some facilities to ease
the insertion of labels, but does not support \cs{zlabel}.  And so on.  The
only disadvantage I can see with this approach is that two labels end up in
the \file{.aux} file which, arguably, may be seen as a redundancy, or waste.

It is probably fair to consider this redundancy, in most use cases, as a
negligible cost.  But you may disagree, or the size of your document or your
requirements may say otherwise, in which case you may prefer the second
approach and use \cs{zlabel} normally, with some occasional \cs{label} where
required.  Outright disabling the \opt{labelhook} option leaves you uncovered
in such cases, but you can always locally (re-)enable it as needed.  As far as
my experience goes, the restrictions should not be that many, and some trial
and error can easily tell what the situation is.  See
\zcref{sec:limitations,sec:comp-modules} for some discussion and known cases.

All in all, as far as \pkg{zref-clever} is concerned, the use of \cs{label}
throughout (with the \opt{labelhook} option) is the recommended approach.
Consider the use of \cs{zlabel} directly if you have some special requirements
at stake and are willing to handle a few rough edges.


\section{Limitations}
\label{sec:limitations}

Being based on \pkg{zref} entails one significant 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.  Which leads to less
compatibility problems and load order issues than some traditional
cross-reference related packages.  On the other hand, being based on
\pkg{zref} also has some potential implications to the supported scope of
\pkg{zref-clever}.  Not because of any particular limitation of either, but
because any class or package which implements some special handling for
reference labels universally does so aiming at the standard referencing
system, and whether specific support for \pkg{zref} is included, or whether
things work by spillover of the particular technique employed, is not
guaranteed.

The limitation here is less one of \pkg{zref-clever} than that of a potencial
lack of support for \pkg{zref} itself.  Broadly speaking, what
\pkg{zref-clever} does is setup \pkg{zref} so that its \cs{zref@newlabel}s
contains the information we need using \pkg{zref}'s API.  Once the \cs{zlabel}
is set correctly, there is little in the way of \pkg{zref-clever}, it can just
extract the label's information, again using \pkg{zref}'s API, and do its job.
Therefore, the problems that may arise are really in \emph{label setting}.

For \cs{zlabel} to be able to set a label with everything \pkg{zref-clever}
needs, some conditions must be fulfilled, most of which are pretty much the
same as that of a regular label, but not only.  As far as my experience goes,
the following label setting requirements can be potentially problematic and
are not necessarily granted for \cs{zlabel}:

\begin{enumerate}
\item One must be able to call \cs{zlabel}, directly or indirectly, at the
  appropriate scope/location so as to set the label.
\item When \cs{zlabel} is set, it must see a correct value of
  \cs{@currentcounter}.
\end{enumerate}

As to the first, it is not everywhere we technically can set a (z)label.  On
verbatim-like environments it depends on how they are defined and whether they
provide a proper place or option to do so.  But other places may be
problematic too, for example, \pkg{amsmath} display math environments also
handle \cs{label} specially and the same work is not done for \cs{zlabel}.
Classes and packages may offer label setting by means of arguments or options,
and those usually only cater for the standard referencing system, etc.
Fortunately for us, the \texttt{label} hook introduced by the \LaTeX{} kernel
in the 2023-06-01 release improves the situation considerably.
\pkg{zref-clever} makes use of it with the \opt{labelhook} option, enabled by
default, so that a standard \cs{label} also sets a \cs{zlabel} with the same
name, thus providing a very general and reliable way to deal with this issue.

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, the label will tend to have all
information within its grasp at the time it is set.  But that's not
necessarily 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, specially since the kernel's \texttt{label} hook has been made
available, we can expect to find very little trouble in setting proper labels
for \pkg{zref-clever}.  Which is not to say ``none'', of course.


\section{Compatibility modules}
\label{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.

Note that settings performed by the compatibility modules require special care
if they are to be changed by users.  Since the modules depend on what has been
loaded or not in the document, the settings are done at
\texttt{begindocument}.  Hence, to override a setting performed by a
compatibility module, the user must ensure their change comes after that,
e.g.\ by adding their setting to the \texttt{begindocument} hook.

The purpose of outlining to some extend what the compatibility modules do is
twofold.  First, some of them may require usage adjustments, or awareness,
which must be somehow conveyed in this documentation.  Second, the kind and
degree of intervention in external code varies 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 more 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}.  Also, the
sorting of appendix labels relative to those in the rest of the document
requires attention, which is done by setting the main sectioning level counter
as being reset by an internal counter with the \opt{counterresetby} option.
And this is what this compatibility module does, using 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 and ensuring
proper sorting of labels.  This module employs environment hooks to
\env{appendices} and \env{subappendices}.

\DescribeOption{memoir} %
This compatibility module provides support for some of \cls{memoir}'s
cross-referencing features. Namely, it: i) sets counter types for counters
\texttt{subfigure}, \texttt{subtable}, \texttt{poemline} (used in the
\env{verse} environment), \texttt{sidefootnote}, and \texttt{pagenote}; ii)
configures resetting behavior (\opt{counterresetby} option) for
\texttt{subfigure} and \texttt{subtable} counters; iii) provides the
\pkg{zref} property ``\texttt{subcaption}'' so that we can use
\texttt{ref=subcaption} to emulate the functionality of \cls{memoir}'s
\cs{subcaptionref}.

\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}.  Therefore, you must use \cs{label} (not \cs{zlabel}) inside
\pkg{amsmath}'s display math environments, but unless you disabled the
\opt{labelhook} option you need not worry about that, and can just go with
\cs{label} as usual.  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.  Besides that, the module ensures proper \opt{currentcounter} values
are in place for the display math environments, for which it uses environment
hooks.  The module also provides a \texttt{subeq} property, for display math
environments used inside the \env{subequations} environment, which can be used
to refer to them directly with the \opt{ref} option, or to build terse ranges
with the \opt{endrange} option.

\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 \pkg{mathtools}' \cs{noeqref} for the purpose, 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, in part, this is needed
because \pkg{breqn} does not use \cs{refstepcounter} to increment the equation
counters and, as a result, fails to set \cs{@currentcounter}.  But, for the
same reason, it also fails to set \pkg{hyperref} anchors for the equations
(thus affecting the standard labels too).  So, you may wish to use the
work-around provided by Heiko Oberdiek at
\url{https://tex.stackexchange.com/a/241150} (or equivalent).

\DescribeOption{listings} %
Being \env{lstlisting} a verbatim environment, setting labels inside it
requires special treatment.  \pkg{zref-clever}'s \opt{labelhook} option
provides that a label given to the \opt{label} works out of the box, so unless
you disabled the \opt{labelhook} option you need not worry about it.  Setting
labels for specific lines of the environment can also be done, subject to
escaping as due.  The module sets appropriate \opt{countertype},
\opt{counterresetby} and \opt{currentcounter} values for the \pkg{listings}'
counters: \texttt{lstlisting} and \texttt{lstnumber}.

\DescribeOption{enumitem} %
\LaTeX{}'s \env{enumerate} environment requires some special treatment from
\pkg{zref-clever}, since its resetting behavior is not stored in the standard
way, and the counters' names, given they are numbered by level, do not map to
the reference type naturally.  This is done by default for the up to four
levels of nested \env{enumerate} environments the kernel offers.
\pkg{enumitem}, though, allows one to increase this maximum list depth for
\env{enumerate} and, if this is done, setup for these deeper nesting levels
have also to be taken care of, and that's what this compatibility module does.
All settings here are internal to \pkg{zref-clever}, no hooks or redefinitions
are needed, we just check the existing pertinent counters at
\texttt{begindocument}, and supply settings for them.  Of course, this means
that only \pkg{enumitem}'s settings done in the preamble will be visible to
the module and provided for.

\DescribeOption{subcaption} %
This compatibility module sets appropriate \opt{countertype} and
\opt{counterresetby} for the \texttt{subfigure} and \texttt{subtable}
counters, and provides the \pkg{zref} property ``\texttt{subref}'' so that we
can refer to, for example, \texttt{\cs{zcref}[ref=subref]\{\meta{label}\}} to
emulate the functionality of \cls{subcaption}'s \cs{subref}.  The later
feature uses the \cs{caption@subtypehook} provided by \pkg{caption} to locally
add the \texttt{subref} property to \pkg{zref}'s main property list.

\DescribeOption{subfig} %
This module just sets appropriate \opt{countertype} and \opt{counterresetby}
for the \texttt{subfigure} and \texttt{subtable} counters.

\DescribeOption{beamer} %
This compatibility module sets proper values of \cs{@currentHref}, so that the
\cs{label}s are stored with anchors which correspond to the ones \cls{beamer}
actually creates, using the \texttt{label} hook for the purpose, meaning this
strictly requires the use of \cs{label} with the \opt{labelhook} option.  It
also sets appropriate \cs{@currentcounter} for frames, using a generic
\texttt{cmd} hook on \cls{beamer}'s \cs{refcounter} macro.


% \section{Work-arounds}
%
% \marginpar{\raggedleft\raisebox{-1.5ex}{\dbend}}The compatibility modules
% presented in \zcref{sec:comp-modules} should go a long way in ensuring the
% user has little to worry about in setting up \pkg{zref-clever} for some more
% traditional document classes and packages, but they cannot be expected to 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,
% 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''.


\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 a 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 \LaTeX{} Project 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 (in chronological order):
  Ulrike Fischer,
  % 2021-07-03: It's Ulrike's fault :-) : https://tex.stackexchange.com/questions/603514/#comment1513982_603514
  % 2021-08-20: https://tex.stackexchange.com/q/611424/105447 (comments)
  % 2021-09-06: https://github.com/ho-tex/zref/issues/13
  % 2021-10-26: https://github.com/latex3/latex2e/issues/687
  % 2022-01-12: https://chat.stackexchange.com/transcript/message/60129233#60129233
  % 2022-04-09: https://github.com/latex3/hyperref/issues/229#issuecomment-1093870142
  % 2023-01-02: https://tex.stackexchange.com/q/670399 (comments)
  % 2023-06-01: https://github.com/latex3/latex2e/pull/956
  % 2023-07-27: https://chat.stackexchange.com/transcript/message/64067726#64067726
  % 2024-11-14: https://tex.stackexchange.com/a/730792
  % 2024-11-14: https://github.com/josephwright/beamer/issues/917
  Phelype Oleinik,
  % 2021-08-20: https://tex.stackexchange.com/q/611370 (comments)
  % 2021-09-09: https://tex.stackexchange.com/a/614704
  % 2021-10-06: https://tex.stackexchange.com/a/617998
  % 2021-10-21: https://github.com/latex3/latex2e/pull/699
  % 2022-01-12: https://tex.stackexchange.com/questions/629946/#comment1571118_629946
  % 2022-01-11: https://tex.stackexchange.com/questions/633341/#comment1579825_633347
  % 2023-06-01: https://github.com/latex3/latex2e/pull/1020
  Enrico Gregorio,
  % 2021-08-20: https://tex.stackexchange.com/a/611385
  % 2021-08-20: https://tex.stackexchange.com/q/611370/#comment1529282_611385
  Steven B.\ Segletes,
  % 2021-08-20: https://tex.stackexchange.com/a/611373
  Jonathan P.\ Spratte,
  % 2021-09-09: https://tex.stackexchange.com/a/614719
  % 2021-09-09: https://github.com/latex3/latex3/pull/988
  David Carlisle,
  % 2021-10-10: https://tex.stackexchange.com/questions/618434/#comment1544401_618439
  % 2022-01-12: https://chat.stackexchange.com/transcript/message/60129096#60129096
  %             and following discussion.
  % 2022-12-26: https://chat.stackexchange.com/transcript/message/62644791#62644791
  %             and following discussion.
  % 2023-01-02: https://chat.stackexchange.com/transcript/message/62684358#62684358
  %             and following discussion.
  % 2023-02-10: https://tex.stackexchange.com/a/674846
  % 2023-07-27: https://chat.stackexchange.com/transcript/message/64067575#64067575
  Frank Mittelbach,
  % 2021-10-14: https://github.com/latex3/latex2e/issues/687
  \username{samcarter},
  % 2021-10-14: https://chat.stackexchange.com/transcript/message/59361777#59361777
  % 2021-10-21: https://chat.stackexchange.com/transcript/message/59418309#59418309
  % 2024-11-14: https://github.com/josephwright/beamer/issues/917
  Alan Munn,
  % 2021-10-14: https://chat.stackexchange.com/transcript/message/59364073#59364073
  % 2021-10-21: https://chat.stackexchange.com/transcript/message/59418189#59418189
  Florent Rougon,
  % https://github.com/frougon/xcref has been an useful reference for
  % declension support.
  Denis Bitouzé,
  % 2021-11-25: https://github.com/gusbrs/zref-clever/issues/1
  Marcel Krüger,
  % 2021-11-26: https://github.com/latex3/l3build/issues/215
  Jürgen Spitzmüller,
  % 2021-11-28: https://github.com/gusbrs/zref-clever/issues/2
  \username{niluxv},
  % 2022-01-05: https://github.com/gusbrs/zref-clever/issues/4
  Joseph Wright,
  % 2023-01-02: https://chat.stackexchange.com/transcript/message/62684358#62684358
  %             and following discussion.
  Thomas F. Sturm,
  % 2023-02-09: https://github.com/T-F-S/tcolorbox/issues/206
  % 2023-05-12: https://github.com/T-F-S/tcolorbox/issues/230
  Yukai Chou, % 'muzimuzhi'
  % 2023-02-18: https://github.com/gusbrs/zref-clever/pull/14
  % 2023-02-18: https://github.com/gusbrs/zref-clever/pull/15
  % 2023-05-11: https://github.com/T-F-S/tcolorbox/issues/230
  % 2023-11-09: https://github.com/gusbrs/zref-clever/issues/20
  % 2024-01-20: https://github.com/gusbrs/zref-clever/pull/25
  % 2024-05-04: https://github.com/gusbrs/zref-clever/pull/27
  % 2024-07-19: https://github.com/gusbrs/zref-clever/pull/32
  and Lars Madsen.
  % 2023-07-24: https://chat.stackexchange.com/transcript/message/64039717#64039717
  %             and following discussion.
  % 2023-07-26: https://chat.stackexchange.com/transcript/message/64057725#64057725
  % 2023-07-31: https://chat.stackexchange.com/transcript/message/64105457#64105457
  %             and following discussion.
  % 2023-08-08: Improved 'zref' and 'zref-clever' support for 'memoir' with
  %             v3.8.  Email exchange "Subject: [FR] Improve support for zref
  %             in memoir", starting with
  %             rfc822msgid:CAM9ALR84v=nUTO14moPhbuDjQx9EJ1pcWAku5FdwOo9hbadwYA@mail.gmail.com.

The package's language files have been provided or improved thanks to:
  Denis Bitouzé (French),
  % 2021-11-25: https://github.com/gusbrs/zref-clever/issues/1
  François Lagarde (French), % 'flagarde'
  % 2021-12-09: discussion at https://github.com/gusbrs/zref-clever/issues/1
  \username{niluxv} (Dutch),
  % 2022-01-09: https://github.com/gusbrs/zref-clever/pull/5
  % 2022-12-27: https://github.com/gusbrs/zref-clever/pull/12
  % 2022-12-27: https://github.com/gusbrs/zref-clever/pull/13
  Matteo Ferrigato (Italian), % 'matteo339'
  % 2022-12-12: https://github.com/gusbrs/zref-clever/issues/11
  Sergey Slyusarev (Russian), % 'jemmybutton'
  % 2024-05-18: https://github.com/gusbrs/zref-clever/issues/28
  % 2024-05-19: https://github.com/gusbrs/zref-clever/pull/29
  % 2024-05-20: https://github.com/gusbrs/zref-clever/pull/30
  and \username{Timmyfox} (Swedish).
  % 2024-11-22: https://github.com/gusbrs/zref-clever/issues/35

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}.  The
change log is also distributed with the package's documentation through CTAN
upon release so, most likely, \texttt{texdoc zref-clever/changelog} should
provide easy local access to it.  An archive of historical versions of the
package is also kept at \url{https://github.com/gusbrs/zref-clever/releases}.

\end{document}

% Local Variables:
% TeX-engine: luatex
% End:
