% \iffalse meta-comment
%
% File: zref-clever.tex
%
% This file is part of the LaTeX package "zref-clever".
%
% Copyright (C) 2021-2022  Gustavo Barros
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
% license or (at your option) any later version.  The latest version
% of this license is in the file:
%
%    https://www.latex-project.org/lppl.txt
%
% and version 1.3 or later is part of all distributions of LaTeX
% version 2005/12/01 or later.
%
%
% This work is "maintained" (as per LPPL maintenance status) by
% Gustavo Barros.
%
% This work consists of the files zref-clever.dtx,
%                                 zref-clever.ins,
%                                 zref-clever.tex,
%                                 zref-clever-code.tex,
%         and the files listed in MANIFEST.md.
%
% The released version of this package is available from CTAN.
%
% -----------------------------------------------------------------------
%
% The development version of the package can be found at
%
%    https://github.com/gusbrs/zref-clever
%
% for those people who are interested.
%
% -----------------------------------------------------------------------
%
% \fi

\documentclass{l3doc}

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

\usepackage[T1]{fontenc}

\usepackage[sc]{mathpazo}
\linespread{1.05}
\usepackage[scale=.88]{tgheros} % sans
\usepackage[varqu,scaled=1.03]{inconsolata} % tt

\usepackage{listings}

\usepackage{microtype}

\hypersetup{hidelinks}

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

\definecolor{reffmtbox}{gray}{0.15}
\definecolor{reffmtback}{gray}{0.85}
\NewDocumentCommand\reffmt{m}{%
  \fcolorbox{reffmtbox}{reffmtback}{%
    \rule[-0.2\baselineskip]{0pt}{0.8\baselineskip}\texttt{#1}}}

\newlist{refformat}{itemize}{1}
\setlist[refformat]{label={}, beginpenalty=500, midpenalty=500}

\NewDocumentCommand\zctask{m}{%
  \begin{description}
  \item[Task] #1
  \end{description}}

\lstdefinestyle{code}{
  language=[LaTeX]TeX,
  moretexcs={
    AddToHook,
    define@key,
    patchcmd,
    eq@setnumber,
    DeclareFloatingEnvironment,
    newlist,
    setlist,
    zexternaldocument,
    next@label,
    next@label@pre,
    @empty,
    tag,
    text,
    lstset,
    condition,
  }
}
\lstdefinestyle{zrefclever}{
  style=code,
  moretexcs={
    zcref,
    zcpageref,
    zlabel,
    zcsetup,
    zcLanguageSetup,
    zcRefTypeSetup,
    zcheck,
    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}%
  \lstset{#1}%
  \setcounter{lstlisting}{\value{zchowto}}%
}{}
\newcounter{zcworkaround}
\lstnewenvironment{zcworkaround}[1][]{%
  \renewcommand{\lstlistingname}{Work-around}%
  \renewcommand*\theHlstlisting{wa.\thelstlisting}%
  \lstset{#1}%
  \setcounter{lstlisting}{\value{zcworkaround}}%
}{}
\lstnewenvironment{zcexample}[1][]{%
  \renewcommand{\lstlistingname}{Example}%
  \lstset{#1}%
}{}
\ExplSyntaxOn
\makeatletter
\lst@AddToHook { PreInit }
  {
    \cs_if_exist:cT { c@ \lstenv@name }
      { \exp_args:Nx \refstepcounter { \lstenv@name } }
  }
\makeatother
\ExplSyntaxOff

\zcRefTypeSetup{zchowto}{
  Name-sg = {How-to},
  name-sg = {how-to},
  Name-pl = {How-tos},
  name-pl = {how-tos},
}
\zcRefTypeSetup{zcworkaround}{
  Name-sg = {Work-around},
  name-sg = {work-around},
  Name-pl = {Work-arounds},
  name-pl = {work-arounds},
}

\begin{document}

\GetFileInfo{zref-clever.sty}

\title{%
  The \pkg{zref-clever} package%
  \thanks{This file describes \fileversion, released \filedate.}%
  \texorpdfstring{\\{}\medskip{}}{ - }%
  User manual%
  \texorpdfstring{\medskip{}}{}%
}

\author{%
  Gustavo Barros%
  \thanks{\url{https://github.com/gusbrs/zref-clever}}%
}

\date{\filedate}

\maketitle

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

\begin{quotation}
  \pkg{zref-clever} provides an user interface for making \LaTeX{}
  cross-references which automates some of their typical features, thus easing
  their input in the document and improving the consistency of typeset
  results.  A reference made with \cs{zcref} includes a ``name'' according to
  its ``type'' and lists of multiple labels can be automatically sorted and
  compressed into ranges when due.  The reference format is highly and easily
  customizable, both globally and locally.  \pkg{zref-clever} is based on
  \pkg{zref}'s extensible referencing system.
\end{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 most popular: \pkg{cleveref},
\pkg{hyperref}, \pkg{titleref}, \pkg{nameref}, \pkg{varioref}, \pkg{fancyref},
and the kernel's \cs{labelformat}.

However, the standard cross-referencing system stores two, and only two,
properties with the label: the printed representation of the counter last
incremented with \cs{refstepcounter} and the page.  Of course, out of the
mentioned desire to automate more, the need arose to store more information
about the label to support this: the title or caption of the referenced
object; its counter or, even better, its ``type'', that is, whether it is a
section, chapter, figure, etc.; its hyperlink anchor, and so on.  Thus those
two property ``fields'' of the standard label became quite a disputed real
state.  And the packages in this area of functionality were bound to step on
each other's toes as a result.

Out of this conundrum, Heiko Oberdiek eventually developed \pkg{zref}, which
implements an extensible referencing system, making the labels store a
property list of flexible length, so that new properties can be easily added
and queried.  However, even when \pkg{zref} can rightfully boast this powerful
basic concept and is really quite featureful, with several different modules
available, it is fair to say that, for the average user, the package may
appear to be somewhat raw.  Indeed, for someone who ``just wants to make a
cross-reference'', the user interface of the \pkg{zref-user} module is akin to
the standard \LaTeX{} cross-referencing system, and even requires some extra
work if you want to have a hyperlinked reference.  In other words, \pkg{zref}
seems to have focused on infrastructure and on performing a number of
specialized tasks with different modules, and a large part of the landscape of
automation features available for the standard referencing system was not
carried over to \pkg{zref}, neither by the \pkg{zref} itself nor by other
packages.

\pkg{zref-clever} tries to cover this gap, by bringing a number of existing
features available for the standard referencing system to \pkg{zref}.  And 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.  Alas, there are some limitations (see \zcref{sec:limitations}),
and it may be your cup of tea or not.  Still, 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}
\zlabel{sec:warning}

This package is in its early days, and should be considered experimental.  By
this I don't mean I expect it to be ``edgy'', indeed quite a lot of effort has
been put into it so that this is not the case.  However, during the initial
development, I had to make a number of calls for which I felt I had
insufficient information: in relation to features, packages, or classes I
don't use much, or to languages I don't know well, user needs I found hard to
anticipate etc.  Hence, the package needs some time, and some use by more
adventurous people, until it can settle down with more conviction.  In the
meantime, polishing the user interface and the infrastructure have a clear
priority over backward compatibility.  So, if you choose to use this package,
you should be ready to accommodate to eventual upstream changes.


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

As usual:

\begin{zcexample}[escapeinside=`']
\usepackage`\oarg{options}'{zref-clever}
\end{zcexample}


\section{Dependencies}

\pkg{zref-clever} requires \pkg{zref}, and \LaTeX{} kernel 2021-11-15, or
newer.  It also needs \pkg{l3keys2e} and \pkg{ifdraft}.  Some packages are
leveraged by \pkg{zref-clever} if they are present, but are not loaded by
default or required by it, namely: \pkg{hyperref}, \pkg{zref-check}, and
\pkg{zref}'s \pkg{zref-titleref}, \pkg{zref-hyperref}, and \pkg{zref-xr}
modules.


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

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

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


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

\begin{function}{\zcRefTypeSetup}
  \begin{syntax}
    \cs{zcRefTypeSetup}\marg{type}\marg{options}
  \end{syntax}
\end{function}
Sets type-specific reference format options (see
\zcref{sec: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:

\begin{function}{\zlabel}
  \begin{syntax}
    \cs{zlabel}\marg{label}
  \end{syntax}
\end{function}
Sets \meta{label} for referencing with \cs{zref} and, thus, also \cs{zcref}.
\cs{zlabel} is provided by \pkg{zref-user} and is the counterpart of
\cs{label} for \pkg{zref}'s referencing system.


\section{Options}
\zlabel{sec:options}

\pkg{zref-clever} is highly configurable, offering a lot of flexibility in
typeset results of the references, but it also tries to keep these ``handles''
as convenient and user friendly as possible.  To this end, most of what one
can do with \pkg{zref-clever} (pretty much all of it), can be achieved
directly through the standard and familiar ``comma separated list of
\texttt{key=value} options''.

There are two main groups of options in \pkg{zref-clever}: ``general
options'', which affect the overall behavior of the package, or the reference
as a whole; and ``reference format options'', which control the detail of
reference formatting, including type-specific and language-specific settings.

This section covers the first group (for the second one, see
\zcref{sec:reference-format}).  General options can be set globally either as
package options at load-time (see \zcref{sec:loading-package}) or by means of
\cs{zcsetup} in the preamble (see \zcref{sec:user-interface}).  They can also
be set locally with \cs{zcsetup} along the document or through the optional
argument of \cs{zcref} (see \zcref{sec:user-interface}).  Most general options
can be used in any of these contexts, but that is not necessarily true for all
cases, some restrictions may apply, as described in each option's
documentation.

\bigskip{}

\DescribeOption{ref} %
\DescribeOption{page} %
The \opt{ref} option controls the label property to which \cs{zcref} refers
to.  It can receive \pkg{zref} properties, as long as they are declared, but
notably \texttt{default}, \texttt{page}, \texttt{thecounter} and, if
\pkg{zref-titleref} is loaded, \texttt{title}.  The package's default is,
well, \texttt{default}, which is our standard reference.  \texttt{thecounter}
is a property set by \pkg{zref-clever} and is similar to \pkg{zref}'s
\texttt{default} property, except that it is not affected by the kernel's
\cs{labelformat}.\footnote{Technical note: the \texttt{default} property
  stores \cs{@currentlabel}, while the \texttt{thecounter} property stores
  \cs{the}\cs{@currentcounter}.  The later is exactly what \cs{refstepcounter}
  uses to build \cs{@currentlabel}, except for the \cs{labelformat} prefix
  and, hence, has the advantage of being unaffected by it.  But the former is
  \emph{more reliable} since \cs{@currentlabel} is expected to be correct
  pretty much anywhere whereas, although \cs{refstepcounter} does set
  \cs{@currentcounter}, it is not everywhere that uses \cs{refstepcounter} for
  the purpose.  In the cases where the references from these two do diverge,
  \pkg{zref-clever} will likely misbehave (reference type, sorting and
  compression inevitably depend on a correct \opt{currentcounter}), but using
  \texttt{default} at least ensures that the reference itself is correct.
  That said, if you do set \cs{labelformat} for some reason,
  \texttt{thecounter} may be useful.}  By default, reference formatting,
sorting, and compression are done according to information inferred from the
\emph{current counter} (see \opt{currentcounter} option below).  Special
treatment in these areas is provided for \texttt{page}, but not for any other
properties.  The \opt{page} option is a convenience alias for
\texttt{ref=page}.

\DescribeOption{typeset} %
\DescribeOption{noname} %
\DescribeOption{noref} %
When \cs{zcref} typesets a set of references, each group of references of the
same type can be, and by default are, preceded by the type's ``name'', and
this is indeed an important feature of \pkg{zref-clever}.  This is optional
however, and the \opt{typeset} option controls this behavior.  It can receive
values \texttt{ref}, in which case it typesets only the reference(s),
\texttt{name}, in which case it typesets only the name(s), or \texttt{both},
in which case it typesets, well, both of them.  Note that, when value
\texttt{name} is used, the name is still typeset according to the set of
references given to \cs{zcref}.  For example, for multiple references, the
plural form is used, capitalization options are honored, etc.  Also
hyperlinking behaves just \emph{as if} the references were present and,
depending on the corresponding options, the name may be linked to the first
reference of the type group.  The \opt{noname} and \opt{noref} options are
convenience aliases for \texttt{typeset=ref} and \texttt{typeset=name},
respectively.

\DescribeOption{sort} %
\DescribeOption{nosort} %
The \opt{sort} option controls whether the list of \meta{labels} received as
argument by \cs{zcref} should be sorted or not.  It is a boolean option, and
defaults to \texttt{true}.  The \opt{nosort} option is a convenience alias for
\texttt{sort=false}.

\DescribeOption{typesort} %
\DescribeOption{notypesort} %
Sorting references of the same type can be done with well defined logical
criteria.  They either have the same counter or their counters share a clear
hierarchical relation (in the resetting behavior), such that a definite
sorting rule can be inferred from the label's data.  The same is not true for
sorting of references of different types.  Should ``tables'' come before or
after ``figures''?  The \pkg{typesort} option allows to specify the sorting
priority of different reference types.  It receives as value a comma separated
list of reference types, specifying that their sorting is to be done in the
order of that list.  But \opt{typesort} does not need to receive \emph{all}
possible reference types.  The special value \texttt{\{\{othertypes\}\}} (yes,
double braced, one for \pkg{l3keys}, so that the second can make the list) can
be placed anywhere along the list, to specify the sort priority of any type
not included explicitly.  If \texttt{\{othertypes\}} is not present in the
list, it is presumed to be at the end of it.  Any unspecified types (that is,
those falling implicitly or explicitly into the \texttt{\{othertypes\}}
category) get sorted between themselves in the order of their first appearance
in the label list given as argument to \cs{zcref}.  I presume the common use
cases will not need to specify \texttt{\{othertypes\}} at all but, for the
sake of example, if you just really dislike equations, you could use
\texttt{typesort=\{\{\{othertypes\}\}, equation\}}.  \opt{typesort}'s default
value is \texttt{\{part, chapter, section, paragraph\}}, which places the
sectioning reference types first in the list, in their hierarchical order, and
leaves everything else to the order of appearance of the labels.  The
\opt{notypesort} option behaves like \texttt{typesort=\{\{\{othertypes\}\}\}}
would do, that is, it sorts all types in the order of the first appearance in
the labels' list.

\DescribeOption{comp} %
\DescribeOption{nocomp} %
\cs{zcref} can automatically compress a set of references of the same type
into a range, when they occur in immediate sequence.  The \opt{comp} controls
whether this compression should take place or not.  It is a boolean option,
and defaults to \texttt{true}.  The \opt{nocomp} option is a convenience alias
for \texttt{comp=false}.  Of course, for better compression results the
\opt{sort} is recommended, but the two options are technically independent.

\DescribeOption{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 (\texttt{x}-type
  expansion) 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 package's default is \texttt{range=false}.  The option given without a
value is equivalent to \texttt{range=true} (in the \pkg{l3keys}' jargon, the
\emph{option}'s default is \texttt{true}).  \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 can receive values \texttt{true} or \texttt{false},
and it can also be set for specific reference types or languages (see
\zcref{sec:reference-format}).  The option given without a value is equivalent
to \texttt{cap=true}.  The \opt{nocap} option is a convenience alias for
\texttt{cap=false}.  The \opt{capfirst} option ensures that the reference type
name of the \emph{first} type block is capitalized, even when \opt{cap} is set
to \texttt{false}.

\DescribeOption{abbrev} %
\DescribeOption{noabbrev} %
\DescribeOption{noabbrevfirst} %
The \opt{abbrev} option controls whether to use abbreviated reference type
names when they are available.  It can receive values \texttt{true} or
\texttt{false}, and it can also be set for specific reference types or
languages (see \zcref{sec:reference-format}).  The option given without a
value is equivalent to \texttt{abbrev=true}.  The \opt{noabbrev} option is a
convenience alias for \texttt{abbrev=false}.  The \opt{noabbrevfirst} ensures
that the reference type name of the \emph{first} type block is never
abbreviated, even when \opt{abbrev} is set to \texttt{true}.

\DescribeOption{S} %
\opt{S} for ``Sentence''.  The \opt{S} option is a convenience alias for
\texttt{capfirst=true, noabbrevfirst=true}, and is intended to be used in
references made at the beginning of a sentence.  It is highly recommended that
you make a habit of using the \opt{S} option for beginning of sentence
references.  Even if you do happen to be currently using \texttt{cap=true,
  abbrev=false}, proper semantic markup will ensure you get expected results
even if you change your mind in that regard later on.  For that reason, it was
made short and mnemonic, it can't get any easier.

\DescribeOption{hyperref} %
The \opt{hyperref} option controls the use of \pkg{hyperref} by
\pkg{zref-clever} and takes values \opt{auto}, \opt{true}, \opt{false}.  The
default value, \opt{auto}, makes \pkg{zref-clever} use \pkg{hyperref} if it is
loaded, meaning that references made with \cs{zcref} get hyperlinked to the
anchors of their respective \meta{labels}.  \opt{true} does the same thing,
but warns if \pkg{hyperref} is not loaded (\pkg{hyperref} is never loaded for
you).  In either of these cases, if \pkg{hyperref} is loaded, module
\pkg{zref-hyperref} is also loaded by \pkg{zref-clever}.  \opt{false} means
not to use \pkg{hyperref} regardless of its availability.  This is a preamble
only option, but \cs{zcref} provides granular control of hyperlinking by means
of its starred version.

\DescribeOption{nameinlink} %
The \opt{nameinlink} option controls whether the type name should be included
in the reference hyperlink or not (provided there is a link, of course).
Naturally, the name can only be included in the link of the \emph{first}
reference of each type block.  \opt{nameinlink} can receive values
\texttt{true}, \texttt{false}, \texttt{single}, and \texttt{tsingle}.  When
the value is \texttt{true} the type name is always included in the hyperlink.
When it is \texttt{false} the type name is never included in the link.  When
the value is \texttt{single}, the type name is included in the link only if
\cs{zcref} is typesetting a single reference (not necessarily having received
a single label as argument, as they may have been compressed), otherwise, the
name is left out of the link.  When the value is \texttt{tsingle}, the type
name is included in the link for each type block with a single reference,
otherwise, it isn't.  An example: suppose you make a couple of references to
something like \cs{zcref}\texttt{\{chap:chapter1\}} and
\cs{zcref}\texttt{\{chap:chapter1, sec:section1, fig:figure1, fig:figure2\}}.
The ``figure'' type name will only be included in the hyperlink if
\opt{nameinlink} option is set to \texttt{true}.  If it is set to
\texttt{tsingle}, the first reference will include the name in the link for
``chapter'', as expected, but also in the second reference the ``chapter'' and
``section'' names will be included in their respective links, while that of
``figure'' will not.  If the option is set to \texttt{single}, only the name
for ``chapter'' in the first reference will be included in the link, while in
the second reference none of them will.  The package's default is
\texttt{nameinlink=tsingle}, and the option given without a value is
equivalent to \texttt{nameinlink=true}.

\DescribeOption{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 default value, \texttt{current}, uses the
current language, as defined by \pkg{babel} or \pkg{polyglossia} (or
\texttt{english} if none of them is loaded).  Value \texttt{main} uses the
main document language, as defined by \pkg{babel} or \pkg{polyglossia} (or
\texttt{english} if none of them is loaded).  The \opt{lang} option also
accepts that the language be specified directly by its name, as long as it's a
language known by \pkg{zref-clever}.  For more details on
\zcref*[ref=title,noname]{sec:internationalization}, see
\zcref{sec:internationalization}.

\DescribeOption{d} %
The \opt{d} option sets the declension case, and affects the type name used
for typesetting the reference.  Whether this option is operative, and which
values it accepts, depends on the declared setup for each language.  For
details, see \zcref{sec:internationalization}.

\DescribeOption{nudge} %
\DescribeOption{nudgeif} %
\DescribeOption{nonudge} %
\DescribeOption{sg} %
\DescribeOption{g} %
This set of options revolving around \opt{nudge} aims to offer some guard
against mischievous automation on the part of \pkg{zref-clever} by providing a
number of ``nudges'' (compilation time messages) for cases in which you may
wish to revise material \emph{surrounding} the reference -- an article, a
preposition -- according to the reference typeset results.  Useful mainly for
languages which inflect the preceding article to gender and/or number, but may
be used generally to fine-tune the language and style around the
cross-references made with \cs{zcref}.  The \opt{nudge} option is the main
entrance to this feature and takes values \texttt{true}, \texttt{false},
\texttt{ifdraft}, or \texttt{iffinal}.  The first two, respectively, enable or
disable the ``nudging'' unconditionally.  With \texttt{ifdraft}, \opt{nudge}
keeps quiet when option \texttt{draft} is given to \cs{documentclass}, while
with \texttt{iffinal}, nudging is only enabled when option \texttt{final} is
(explicitly) passed to \cs{documentclass}.  The option given without a value
is equivalent to \texttt{nudge=true} and the package's default is
\texttt{nudge=false}.  \opt{nonudge} is a convenience alias for
\texttt{nudge=false}, and can be used to silence individual references.  The
\opt{nudgeif} option controls the events which may trigger a nudge.  It takes
a comma separated list of elements, and recognizes values \texttt{multitype},
\texttt{comptosing}, \texttt{gender}, and \texttt{all}.  The
\texttt{multitype} nudge warns when the reference is composed by multiple type
blocks (see \zcref{sec: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.  Given how package options
are handled by \LaTeX{}, the fact that this option receives commands as value
means this option \emph{can't} be set at load time, as a package option.  If
you want to set it globally, use \cs{zcsetup} instead.

\DescribeOption{titleref} %
\DescribeOption{vario} %
The \opt{titleref} option receives no value and, when given, loads
\pkg{zref}'s \pkg{zref-titleref} module.  Similarly, the \opt{vario} option
loads the \pkg{zref-vario} package.  These are a preamble only options.  Note
that \pkg{zref-vario} loads \pkg{varioref}, which has known load order
interaction with other packages, prominently with \pkg{hyperref}.  Hence,
depending on your document, you may wish to load \pkg{zref-vario} separately,
instead of through the option.

\DescribeOption{note} %
The \opt{note} option receives as value some text to be typeset at the end of
the whole reference list.  It is separated from it by \opt{notesep} (see
\zcref{sec:reference-format}).

\DescribeOption{check} %
Provides integration of \pkg{zref-clever} with the \pkg{zref-check} package.
In the preamble, the \opt{check} option receives no value and, when given,
loads \pkg{zref-check}.  In the document body, \opt{check} requires a value,
which works exactly like the optional argument of \cs{zcheck}, and can receive
both checks and \cs{zcheck}'s options.  And the checks are performed for each
label in \marg{labels} received as argument by \cs{zcref}.  See the User
manual of \pkg{zref-check} for details.  The checks done by the \opt{check}
option in \cs{zcref} comprise the complete reference, including the \opt{note}
(see \zcref{sec:reference-format}).  If \pkg{zref-check} was not loaded in the
preamble, at begin document the option is made no-op and issues a warning.

\DescribeOption{countertype} %
The \opt{countertype} option allows to specify the ``reference type'' of each
counter, which is stored as a label property when the label is set.  This
``reference type'' is what determines how a reference to this label will
eventually be typeset when it is referred to (see
\zcref{sec:reference-types}).  A value like \texttt{countertype = \{foo =
  bar\}} sets the \texttt{foo} counter to use the reference type \texttt{bar}.
There's only need to specify the \opt{countertype} for counters whose name
differs from that of their type, since \pkg{zref-clever} presumes the type has
the same name as the counter, unless otherwise specified.  Also, the default
value of the option already sets appropriate types for basic \LaTeX{}
counters, including those from the standard classes.  Setting a counter type
to an empty value removes any (explicit) type association for that counter, in
practice, this means it then uses a type equal to its name.  Since this option
only affects how labels are set, it is not available in \cs{zcref}.

\DescribeOption{\raisebox{-.2em}{\dbend}\ counterresetters} %
\DescribeOption{counterresetby} %
The sorting and compression of references done by \cs{zcref} requires that we
know the counter associated with a particular label but also information on
any counter whose stepping may trigger its resetting, or its ``enclosing
counters''.  This information is not easily retrievable from the counter
itself but is (normally) stored with the counter that does the resetting.  The
\opt{counterresetters} option adds counter names, received as a comma
separated list, to the list of counters \pkg{zref-clever} uses to search for
``enclosing counters'' of the counter for which a label is being set.
Unfortunately, not every counter gets reset through the standard machinery for
this, including some \LaTeX{} kernel ones (e.g. the \texttt{enumerate}
environment counters).  For those, there is really no way to retrieve this
information directly, so we have to just tell \pkg{zref-clever} about them.
And that's what the \opt{counterresetby} option is made for.  It receives a
comma separated list of \texttt{key=value} pairs, in which \texttt{key} is the
counter, and \texttt{value} is its ``enclosing counter'', that is, the counter
whose stepping results in its resetting.  This is not really an ``option'' in
the sense of ``user choice'', it is more of a way to inform \pkg{zref-clever}
of something it cannot know or automatically find in general.  One cannot
place arbitrary information there, or \pkg{zref-clever} can be thoroughly
confused.  The setting must correspond to the actual resetting behavior of the
involved counters.  \opt{counterresetby} has precedence over the search done
in the \opt{counterresetters} list.  The default value of
\opt{counterresetters} includes the counters for sectioning commands of the
standard classes which, in most cases, should be the relevant ones for
cross-referencing purposes.  The default value of \opt{counterresetby}
includes the \texttt{enumerate} environment counters.  So, hopefully, you
don't need to ever bother with either of these options.  But, if you do, they
are here.  Use them with caution though.  Since these options only affect how
labels are set, they are not available in \cs{zcref}.

\DescribeOption{\raisebox{.4em}{\dbend}\ currentcounter} %
\LaTeX{}'s \cs{refstepcounter} sets two variables which potentially affect the
\cs{zlabel} set after it: \cs{@currentlabel} and \cs{@currentcounter}.
Actually, traditionally, only the current label was thus stored, the current
counter was added to \cs{refstepcounter} somewhat recently (with the
2020-10-01 kernel release).  But, since \pkg{zref-clever} relies heavily on
the information of what the current counter is, it must set \pkg{zref} to
store that information with the label, as it does.  As long as the document
element we are trying to refer to uses the standard machinery of
\cs{refstepcounter} we are on solid ground and can retrieve the correct
information.  However, it is not always ensured that \cs{@currentcounter} is
kept up to date.  For example, packages which handle labels specially, for one
reason or another, may or may not set \cs{@currentcounter} as required.
Considering the addition of \cs{@currentcounter} to \cs{refstepcounter} itself
is not that old, it is likely that in a good number of places a reliable
\cs{@currentcounter} is not really in place.  Therefore, it may happen we need
to tell \pkg{zref-clever} what the current counter is in certain
circumstances, and that's what \opt{currentcounter} does.  The same as with
the previous two options, this is not really an ``user choice'' kind of
option, but a way to tell \pkg{zref-clever} a piece of information it has no
means to retrieve automatically.  The setting must correspond to the actual
``current counter'', meaning here ``the counter underlying
\cs{@currentlabel}'' in a given situation.  Also, when using the
\opt{currentcounter} option, make sure the setting is duly grouped because, if
set, it has precedence over \cs{@currentcounter} and, contrary to the later,
the former is not reset the next time \cs{refstepcounter} runs.  Its default
value is, quite naturally, \cs{@currentcounter}.  Since this option only
affects how labels are set, it is not available in \cs{zcref}.

\DescribeOption{nocompat} %
Some packages, document classes, or LaTeX features may require specific
support to work with \pkg{zref-clever} (see \zcref{sec:limitations}).
\pkg{zref-clever} tries to make things smoother by covering some of them.
Depending on the case, this can take the form of some simple setup for
\pkg{zref-clever}, or may involve the use of hooks to external environments or
commands and, eventually, a patch or redefinition.  By default, all the
available compatibility modules are enabled.  Should this be undesired or
cause any problems in your environment, the option \opt{nocompat} can
selectively or completely inhibit their loading.  \opt{nocompat} receives a
comma separated list of compatibility modules to disable (for the list of
available modules and details about each of them, see
\zcref{sec:comp-modules}).  You can disable all modules by setting
\opt{nocompat} without a value (or an empty one).  This is a preamble only
option.


\section{Reference types}
\zlabel{sec:reference-types}

A ``reference type'' is the basic \pkg{zref-clever} setup unit for specifying
how a cross-reference group of a certain kind is to be typeset.  Though,
usually, it will have the same name as the underlying \LaTeX{} \emph{counter},
they are conceptually different.  \pkg{zref-clever} sets up \emph{reference
  types} and an association between each \emph{counter} and its \emph{type},
it does not define the counters themselves, which are defined by your
document.  One \emph{reference type} can be associated with one or more
\emph{counters}, and a \emph{counter} can be associated with different
\emph{types} at different points in your document.  But each label is stored
with only one \emph{type}, as specified by the counter-type association at the
moment it is set, and that determines how the reference to that label is
typeset.  References to different \emph{counters} of the same \emph{type} are
grouped together, and treated alike by \cs{zcref}.  A \emph{reference type}
may be known to \pkg{zref-clever} when the \emph{counter} it is associated
with is not actually defined, and this inconsequential.  In practice, the
contrary may also happen, a \emph{counter} may be defined but we have no
\emph{type} for it, but this must be handled by \pkg{zref-clever} as an error
(at least, if we try to refer to it), usually a ``missing name'' error.

\pkg{zref-clever} provides default settings for the following reference types:
\texttt{part}, \texttt{chapter}, \texttt{section}, \texttt{paragraph},
\texttt{appendix}, \texttt{subappendix}, \texttt{page}, \texttt{line},
\texttt{figure}, \texttt{table}, \texttt{item}, \texttt{footnote},
\texttt{endnote}, \texttt{note}, \texttt{equation}, \texttt{theorem},
\texttt{lemma}, \texttt{corollary}, \texttt{proposition}, \texttt{definition},
\texttt{proof}, \texttt{result}, \texttt{remark}, \texttt{example},
\texttt{algorithm}, \texttt{listing}, \texttt{exercise}, and
\texttt{solution}.  Therefore, if you are using a language for which
\pkg{zref-clever} has built-in support (see \zcref{sec:internationalization}),
these reference types are available for use out of the box.\footnote{There may
  be slight availability differences depending on the language, but
  \pkg{zref-clever} strives to keep this complete list available for the
  languages it has built-in 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 \emph{label} is set, which stores
the type among its properties.  However, when it comes to typesetting, that is
from the perspective of \cs{zcref}, only the \emph{type} matters.  In other
words, how the reference is supposed to be typeset is determined at the point
the \emph{label} gets set.  In sum, they may be namesakes (or not), but type
is type and counter is counter.

Indeed, a reference type can be associated with multiple counters because we
may want to refer to different document elements, with different
\emph{counters}, as a single \emph{type}, with a single name.  One prominent
case of this are sectioning commands.  \cs{section}, \cs{subsection}, and
\cs{subsubsection} have each their counter, but we'd like to refer to all of
them by ``sections'' and group them together.  The same for \cs{paragraph} and
\cs{subparagraph}.

There are also cases in which we may want to use different \emph{reference
  types} to refer to document objects sharing the same \emph{counter}.
Notably, the environments created with \LaTeX{}'s \cs{newtheorem} command and
the \cs{appendix}.


One more observation about ``reference types'' is due here.  A \emph{type} is
not really ``defined'' in the sense a variable or a function is.  It is more
of a ``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}
\zlabel{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 an user interface for reference
formatting which allows settings to be done in different scopes, with more or
less overarching effects, and some precedence rules to regulate the relation
of settings given in each of these scopes.  There are four scopes in which
reference formatting can be specified by the user, in the following precedence
order: i) as \emph{general options}; ii) as \emph{type-specific options}; iii)
as \emph{language- 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} or even, depending on the case,
as package options at load-time (see \zcref{sec:options}).\footnote{The use of
  \cs{zcsetup} for global reference format settings is recommended though.
  Whether you can use load-time options or not depends on the values of the
  options: due to how \LaTeX{} handles package options, if the values of the
  options you are setting include \emph{commands} you can't set them at
  load-time, and rather \emph{must} use \cs{zcsetup}.}  ``Type'' specific
options (ii) are handled by \cs{zcRefTypeSetup} (see
\zcref{sec:user-interface}).  ``Language'' 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}
  \zlabel{tab:reference-format}
\end{table}


Understanding the role of each of these reference format options is likely
eased by some visual schemes of how \pkg{zref-clever} builds a reference based
on the labels' data and the value of these options. Take a \texttt{ref} to be
that which a standard \LaTeX{} \cs{ref} would typeset.  A \pkg{zref-clever}
``reference block'', or \texttt{ref-block}, is constructed as:

\begin{refformat}
\item \reffmt{ref-block} \(\equiv\)
\item \reffmt{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}
  \zlabel{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 which 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-first-rb} sets \opt{refbounds-first-rb} and
\opt{refbounds-first-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}
\zlabel{sec:internationalization}

\pkg{zref-clever} provides internationalization facilities and integrates with
\pkg{babel} and \pkg{polyglossia} to adapt to the languages in use by either
of these language packages, or to a language specified directly by the user.
This is primarily relevant for reference format options, particularly
reference type \emph{names} (though not only, since most reference format
options can have language-specific values 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
    english    & american     \\
               & australian   \\
               & british      \\
               & canadian     \\
               & newzealand   \\
               & UKenglish    \\
               & USenglish    \\
    french     & acadian      \\
               & canadien     \\
               & francais     \\
               & frenchb      \\
    \bottomrule
  \end{tabular}
  \quad
  \begin{tabular}{ll}
    \toprule
    Language   & Aliases      \\
    \midrule
    german     & austrian     \\
               & germanb      \\
               & ngerman      \\
               & naustrian    \\
               & nswissgerman \\
               & swissgerman  \\
    portuguese & brazilian    \\
               & brazil       \\
               & portuges     \\
    spanish    &              \\
    dutch      &              \\
    \bottomrule
  \end{tabular}
  \caption{Declared languages and aliases}
  \zlabel{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{declension},
\opt{gender}, and \opt{allcaps}.  \opt{declension} receives a coma separated
list of valid declension cases for \meta{language}.  The first element of the
list is considered to be the default case, both for the \opt{d} option in
\cs{zcref} and for the \opt{case} option in \cs{zcLanguageSetup}.  Similarly,
\opt{gender} receives a comma separated list of genders for \meta{language}.
The elements in this list are those which are recognized as valid for the
language for both the \opt{g} option in \cs{zcref} and the \opt{gender} option
in \cs{zcLanguageSetup}.  There is no default presumed in this case.  Finally,
\opt{allcaps} can be used with languages for which nouns must be always
capitalized for grammatical reasons.  For a language declared with the
\opt{allcaps} option, the \opt{cap} reference option (see \zcref{sec:options})
is disregarded, and \cs{zcref} always uses the capitalized type name forms.
This means that 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   & declension & gender & allcaps \\
    \midrule
    english    & --         & --     & --      \\
    french     & --         & f,m    & --      \\
    german     & N,A,D,G    & f,m,n  & yes     \\
    portuguese & --         & f,m    & --      \\
    spanish    & --         & f,m    & --      \\
    dutch      & --         & f,m,n  & --      \\
    \bottomrule
  \end{tabular}
  \caption{Options for declared languages}
  \zlabel{tab:language-options}
\end{table}

\begin{function}{\zcDeclareLanguageAlias}
  \begin{syntax}
    \cs{zcDeclareLanguageAlias}\marg{language alias}\marg{aliased language}
  \end{syntax}
\end{function}
Declare \meta{language alias} to be an alias of \meta{aliased language}.
\meta{aliased language} must be already known to \pkg{zref-clever}.  Once set,
the \meta{language alias} is treated by \pkg{zref-clever} as completely
equivalent to the \meta{aliased language} for any language specification by
the user. \cs{zcDeclareLanguageAlias} is preamble only.

\begin{function}{\zcLanguageSetup}
  \begin{syntax}
    \cs{zcLanguageSetup}\marg{language}\marg{options}
  \end{syntax}
\end{function}
Sets language-specific reference format options for \meta{language} (see
\zcref{sec: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{case}, and
\opt{gender}.  The first two work like a ``switch'' affecting the options
\emph{following} it.  For example, if \texttt{type=foo} is given in
\meta{options} the options following it will be set as type-specific options
for reference type \texttt{foo}.  Similarly, after \texttt{case=X} (provided
\texttt{X} is a valid declension case for \meta{language}), the following
\texttt{[Nn]ame-} options will set values for the \texttt{X} declension case
(other reference format options are not affected by \opt{case}).  Before the
first occurrence of either \opt{type} or \opt{case} default values are set.
For \opt{case} this means the default declension case, which is the first
element of the list provided to the \opt{declension} option in
\cs{zcDeclareLanguage}.  For \opt{type} this means 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 ,
    case = N ,
      Name-sg = Abschnitt ,
      Name-pl = Abschnitte ,
    case = A ,
      Name-sg = Abschnitt ,
      Name-pl = Abschnitte ,
    case = D ,
      Name-sg = Abschnitt ,
      Name-pl = Abschnitten ,
    case = G ,
      Name-sg = Abschnitts ,
      Name-pl = Abschnitte ,
}
\end{zcexample}

\bigskip{}

As already noted, \pkg{zref-clever} has some support for languages with
declension.  This means mainly the declension of \emph{nouns}, which is used
for the reference type names.  But some tools are also provided to support the
user in getting better results for the text surrounding a reference,
particularly for numbered and gendered articles, even if those don't have
their typeset output automated.

For reference type names, the declension cases for each language must be
declared with \cs{zcDeclareLanguage}, and the name reference format options
must be provided for each case, which is done for built-in 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{d} option (see \zcref{sec:options}).  So you may write
something like ``\texttt{nach den
  \cs{zcref}[d=D]\{sec:section-1,sec:section-2\}}'' to get ``nach den
Abschnitten 1 und 2''.  Or ``\texttt{trotz des
  \cs{zcref}[d=G]\{eq:theorem-1\}}'' to get ``trotz des Theorems 1''.

Regarding the text surrounding the reference -- the inflected article, the
passing preposition, etc.\ --, the issue is more delicate.  \pkg{zref-clever}
cannot and intends not to typeset those for you.  But, depending on the
language, it is true that the kind of automation provided by \pkg{zref-clever}
may betray your best efforts to get a proper surrounding text.  Multiple
labels passed to \cs{zcref} may result in singular type names, either because
the labels are of different types, or because they got compressed into a
single reference.  References comprised of multiple type blocks may have each
a name with a different gender.  Or, worse, \opt{tpairsep}, \opt{tpairsep},
and \opt{tlastsep} may not provide a general enough way to separate different
type blocks in your language altogether.  You may change something in your
document that causes a label to change its type, and hence the gender of the
type name.  A page reference to a couple of floats which were by chance on the
same page and all of a sudden no longer are.  And so on.

In this area, the approach taken by \pkg{zref-clever} is to identify some
typical situations in which your attention may be required in reviewing the
surrounding text, and signal it at compilation time.  Just like bad boxes, for
example.  This feature can be enabled by the \opt{nudge} option (which is
opt-in, see \zcref{sec:options}).  There are three ``nudges'' available for
this purpose which trigger messages at different events: \opt{multitype},
\opt{comptosing}, and \opt{gender}.  \opt{multitype} nudges when a reference
is comprised of multiple type blocks.  \opt{comptosing} when multiple labels
of the same type block have been compressed into a single one and, hence, the
type name used is singular.  Finally, \opt{gender} nudges when there is a
mismatch between the gender specified in \cs{zcref} with the \opt{g} option
and the gender of the type name, as 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}

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}.}

\pkg{zref-vario}, which can be enabled with package option \opt{vario}, 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[vario]{zref-clever}
\begin{document}
\section{Section 1}
\zlabel{sec:section-1}
\begin{figure}
  A figure.
  \caption{Figure 1}
  \zlabel{fig:figure-1}
\end{figure}
\begin{figure}
  Another figure.
  \caption{Figure 2}
  \zlabel{fig:figure-2}
\end{figure}
\zvref[S]{sec:section-1}
\zvpageref{fig:figure-1}
\zvrefrange{fig:figure-1}{fig:figure-2}
\zvpagerefrange{fig:figure-1}{fig:figure-2}
\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 it provides features beyond those available in the
kernel, its syntax and underlying relation with counters is pretty much the
same.  The same for \pkg{ntheorem}.  For \pkg{thmtools}' \cs{declaretheorem},
though some adjustments to the examples below may be required, the basic logic
is the same (there is no integration with the \opt{Refname}, \opt{refname},
and \opt{label} options, which are targeted to the standard reference system,
but you don't actually need them to get things working conveniently).


\subsubsection*{Simple case}

\zctask{Setup up a new theorem environment created with \cs{newtheorem} to be
  referred to with \cs{zcref}.  The theorem environment does not share its
  counter with other theorem environments, and one of \pkg{zref-clever}
  built-in reference types is adequate for my needs.}

Suppose you set a ``Lemma'' environment with:

\begin{zcexample}
\newtheorem{lemma}{Lemma}[section]
\end{zcexample}

In this case, since \pkg{zref-clever} provides a built-in \texttt{lemma} type
(for supported languages) and presumes the reference type to be the same name
as the counter, there is no need for setup, and things just work out of the
box.  So, you can go ahead with:

\begin{zchowto}[caption={\cs{newtheorem}, simple case}]
\documentclass{article}
\usepackage{zref-clever}
\newtheorem{lemma}{Lemma}[section]
\begin{document}
\section{Section 1}
\begin{lemma}\zlabel{lemma-1}
  A lemma.
\end{lemma}
\zcref{lemma-1}
\end{document}
\end{zchowto}

If, however, you had chosen an environment name which did not happen to
coincide with the built-in reference type, all you'd need to do is instruct
\pkg{zref-clever} to associate the counter for your environment to the desired
type with the \opt{countertype} option:

\begin{zchowto}[caption={\cs{newtheorem}, simple case}]
\documentclass{article}
\usepackage{zref-clever}
\zcsetup{countertype={lem=lemma}}
\newtheorem{lem}{Lemma}[section]
\begin{document}
\section{Section 1}
\begin{lem}\zlabel{lemma-1}
  A lemma.
\end{lem}
\zcref{lemma-1}
\end{document}
\end{zchowto}


\subsubsection*{Shared counter}

\zctask{Setup up two new theorem environments created with \cs{newtheorem} to
  be referred to with \cs{zcref}.  The theorem environments share the same
  counter, and the available \pkg{zref-clever} built-in reference types are
  adequate for my needs.}

In this case, we need to set the \opt{countertype} option in the appropriate
contexts, so that the labels of each environment get set with the expected
reference type.  As we've seen (at \zcref{sec:user-interface}), \cs{zcsetup}
has local effects, so it can be issued inside the respective environments for
the purpose.  Even better, we can leverage the kernel's new hook management
system and just set it for all occurrences with
\cs{AddToHook}\texttt{\{env/\meta{myenv}/begin\}}.

\begin{zchowto}[caption={\cs{newtheorem}, shared counter}]
\documentclass{article}
\usepackage{zref-clever}
\AddToHook{env/mytheorem/begin}{%
  \zcsetup{countertype={mytheorem=theorem}}}
\AddToHook{env/myproposition/begin}{%
  \zcsetup{countertype={mytheorem=proposition}}}
\newtheorem{mytheorem}{Theorem}[section]
\newtheorem{myproposition}[mytheorem]{Proposition}
\begin{document}
\section{Section 1}
\begin{mytheorem}\zlabel{theorem-1}
  A theorem.
\end{mytheorem}
\begin{myproposition}\zlabel{proposition-1}
  A proposition.
\end{myproposition}
\zcref{theorem-1, proposition-1}
\end{document}
\end{zchowto}


\subsubsection*{Custom type}

\zctask{Setup up a new theorem environment created with \cs{newtheorem} to be
  referred to with \cs{zcref}.  The theorem environment does not share its
  counter with other theorem environments, but none of \pkg{zref-clever}
  built-in reference types is adequate for my needs.}

In this case, we need to provide \pkg{zref-clever} with settings pertaining to
the custom reference type we'd like to use.  Unless you need to typeset your
cross-references in multiple languages, in which case you'd require
\cs{zcLanguageSetup}, the most convenient way to setup a reference type is
\cs{zcRefTypeSetup}.  In most cases, what we really need to provide for a
custom type are the ``type names'' and other reference format options can rely
on default 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}\zlabel{conjecture-1}
  A conjecture.
\end{myconjecture}
\zcref{conjecture-1}
\end{document}
\end{zchowto}


\subsection{\pkg{newfloat}}

\zctask{Setup a new float environment created with \pkg{newfloat} to be
  referred to with \cs{zcref}.  None of \pkg{zref-clever} built-in reference
  types is adequate for my needs.}

The case here is pretty much the same as that for \cs{newtheorem} with a
custom type.  Hence, we need to setup a corresponding type, for which
providing the ``type names'' should normally suffice.  Note that, as far as
\pkg{zref-clever} is concerned, there's nothing specific to the \pkg{newfloat}
package in the setup, the same procedure can be used with \cls{memoir}'s
\cs{newfloat} command or with the \pkg{float}, \pkg{floatrow}, and
\pkg{trivfloat} packages.

\begin{zchowto}[caption={\pkg{newfloat}}]
\documentclass{article}
\usepackage{newfloat}
\DeclareFloatingEnvironment{diagram}
\usepackage{zref-clever}
\zcRefTypeSetup{diagram}{
  Name-sg = Diagram ,
  name-sg = diagram ,
  Name-pl = Diagrams ,
  name-pl = diagrams ,
}
\begin{document}
\section{Section 1}
\begin{diagram}
  A diagram.
  \caption{A diagram}
  \zlabel{diagram-1}
\end{diagram}
\zcref{diagram-1}
\end{document}
\end{zchowto}


\subsection{\pkg{amsmath}}

\zctask{Make references to \pkg{amsmath} display math environments with
  \cs{zcref}.}

Given how \pkg{amsmath}'s display math environments work, they need to handle
\cs{label} specially, and this support is quite hard-wired into the
environments, but it is not extended to \cs{zlabel}.  \pkg{zref-clever}'s
\opt{amsmath} compatibility module provides that a \cs{label} used inside
these environments set both a regular \cs{label} and a \cs{zlabel}, so that we
can refer to the equations with both referencing systems.  Note the use of
\cs{zlabel} for \env{subequations} though.  For more details, see the
description of the \opt{amsmath} compatibility module at
\zcref{sec:comp-modules}.

\begin{zchowto}[caption={\pkg{amsmath}},label={how:amsmath}]
\documentclass{article}
\usepackage{amsmath}
\usepackage{zref-clever}
\usepackage{hyperref}
\begin{document}
\section{Section 1}
\begin{equation}\label{eq:1}
  A^{(1)}_l =\begin{cases} n!,&\text{if }l =1\\
    0,&\text{otherwise}.\end{cases}
\end{equation}
\begin{equation*} \tag{foo}\label{eq:2}
  A^{(1)}_l =\begin{cases} n!,&\text{if }l =1\\
    0,&\text{otherwise}.\end{cases}
\end{equation*}
\begin{subequations}\zlabel{eq:3}
  \begin{align}
    A+B&=B+A\\
    C&=D+E\label{eq:3b}\\
    E&=F
  \end{align}
\end{subequations}
\zcref{eq:1, eq:2, eq:3, eq:3b}
\end{document}
\end{zchowto}


\subsection{\pkg{listings}}

\zctask{Make references to a \env{lstlisting} environment from the
  \pkg{listings} package with \cs{zcref}.}

Being \env{lstlisting} a verbatim environment, setting labels inside it
requires special treatment.  \pkg{zref-clever}'s \opt{listings} compatibility
module provides that a label given to the \opt{label} option gets set with
both a regular \cs{label} and a \cs{zlabel}, so that we can refer to it with
both referencing systems.  Setting labels for specific lines of the
environment can be done with \cs{zlabel} directly, subject to the same
escaping as for the standard \cs{label}.  For more details, see the
description of the \opt{listings} compatibility module at
\zcref{sec:comp-modules}.

\begin{zchowto}[caption={\pkg{listings}},label={how:listings},escapeinside=`']
\documentclass{article}
\usepackage{listings}
\usepackage{zref-clever}
\usepackage{hyperref}
\begin{document}
\section{Section 1}
\lstset{escapeinside={(*@}{@*)}, numbers=left, numberstyle=\tiny}
\begin{lstlisting}[caption={Useless code}, label=lst:1]
  for i:=maxint to 0 do
  begin
      { do nothing }(*@\zlabel{ln:1.1}@*)
  end;
\end{lstlisting}
\zcref{lst:1, ln:1.1}
\end{document}
\end{zchowto}


\subsection{\pkg{enumitem}}

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

Since the \texttt{enumerate} environment's counters are reset at each nesting
level, but not with the standard machinery, we have to inform
\pkg{zref-clever} of this resetting behavior with the \opt{counterresetby}
option.  Also, given the naming of the underlying counters is tied with the
environment's name and the level's number, we cannot really rely on an
implicit counter-type association, and have to set it explicitly with the
\opt{countertype} option.

\begin{zchowto}[caption={\pkg{enumitem}}]
\documentclass{article}
\usepackage{zref-clever}
\zcsetup{
  countertype = {
    myenumeratei   = item ,
    myenumerateii  = item ,
    myenumerateiii = item ,
    myenumerateiv  = item ,
  } ,
  counterresetby = {
    myenumerateii  = myenumeratei ,
    myenumerateiii = myenumerateii ,
    myenumerateiv  = myenumerateiii ,
  }
}
\usepackage{enumitem}
\newlist{myenumerate}{enumerate}{4}
\setlist[myenumerate,1]{label=(\arabic*)}
\setlist[myenumerate,2]{label=(\Roman*)}
\setlist[myenumerate,3]{label=(\Alph*)}
\setlist[myenumerate,4]{label=(\roman*)}
\begin{document}
\begin{myenumerate}
\item An item.\zlabel{item-1}
  \begin{myenumerate}
  \item An item.\zlabel{item-2}
    \begin{myenumerate}
    \item An item.\zlabel{item-3}
      \begin{myenumerate}
      \item An item.\zlabel{item-4}
      \end{myenumerate}
    \end{myenumerate}
  \end{myenumerate}
\end{myenumerate}
\zcref{item-1, item-2, item-3, item-4}
\end{document}
\end{zchowto}


\subsection{\pkg{zref-xr}}

\zctask{Make references to labels set in an external document with
  \cs{zcref}.}

\pkg{zref} itself offers this functionality with module \pkg{zref-xr}, and
\pkg{zref-clever} is prepared to make use of it.  Just a couple of details
have to be taken care of, for it to work as intended: i) \pkg{zref-clever}
must be loaded in both the main document and the external document, so that
the imported labels also contain the properties required by \pkg{zref-clever};
ii) since \cs{zexternaldocument} defines any properties it finds in the labels
from the external document when it imports them, it must be called after
\pkg{zref-clever} is loaded, otherwise the later will find its own internal
properties already defined when it does get loaded, and will justifiably
complain.  Note as well that the starred version of \cs{zexternaldocument*},
which imports the standard labels from the external document, is not
sufficient for \pkg{zref-clever}, since the imported labels will not contain
all the required properties.

Assuming here \file{documentA.tex} as the main file and \file{documentB.tex}
as the external one, and also assuming we just want to refer in ``\texttt{A}''
to the labels from ``\texttt{B}'', and not the contrary, a minimum setup would
be the following.


\begin{zchowto}[caption={\pkg{zref-xr}},escapeinside=`']
`\hspace*{-1em}\file{documentA.tex}:\vspace{1ex}'
\documentclass{article}
\usepackage{zref-clever}
\usepackage{zref-xr}
\zexternaldocument[B-]{documentB}
\usepackage{hyperref}
\begin{document}
\section{Section A1}
\zlabel{sec:section-a1}
\zcref{sec:section-a1, B-sec:section-b1}
\end{document}
`\vspace{-1ex}'
`\hspace*{-1em}\file{documentB.tex}:\vspace{1ex}'
\documentclass{article}
\usepackage{zref-clever}
\usepackage{hyperref}
\begin{document}
\section{Section B1}
\zlabel{sec:section-b1}
\end{document}
\end{zchowto}

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

Being based on \pkg{zref} entails one quite sizable advantage for
\pkg{zref-clever}: the extensible referencing system of the former allows
\pkg{zref-clever} to store and retrieve the information it needs to work
without having to redefine some core \LaTeX{} commands.  This alone makes for
reduced compatibility problems and less load order issues than the average
package in this functionality area.  On the other hand, being based on
\pkg{zref} also does impair the supported scope of \pkg{zref-clever}.  Not
because of any particular limitation of either, but because any class or
package which implements some special handling for reference labels
universally does so aiming at the standard referencing system, and whether
specific support for \pkg{zref} is included, or whether things work by
spillover of the particular technique employed, is not guaranteed.

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

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

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

As to the first, it is not everywhere we technically can set a (z)label.  On
verbatim-like environments it depends on how they are defined and whether they
provide a proper place or option to do so.  But other places may be
problematic too, for example, \pkg{amsmath} display math environments also
handle \cs{label} specially and the same work is not done for \cs{zlabel}.

Regarding the second, a correctly set \cs{@currentcounter} is critical for the
task of \pkg{zref-clever}: the reference type will depend on that and,
consequently, sorting and compression as well, counter resetting behavior
information is also retrieved based on it, and so on.  Since the 2020-10-01
\LaTeX{} release, \cs{@currentcounter} is set by \cs{refstepcounter} alongside
\cs{@currentlabel} and, since the 2021-11-15 release, the support for
\cs{@currentcounter} has been further extended in the kernel.  Hence, as long
as kernel features are involved, or as long as \cs{refstepcounter} is the tool
used for the purpose of reference setting, \cs{zlabel} will tend to have all
information within its grasp at label setting time.  But that's not always the
case.  For this reason, \pkg{zref-clever} has the option \opt{currentcounter}
which at least allows for some viable work-arounds when the value of
\cs{@currentcounter} cannot be relied upon.  Whether we have a proper opening
to set it, depends on the case.  Still, \cs{refstepcounter} is ubiquitous
enough a tool that we can count on \cs{@currentcounter} most of the time.

All in all, most things work, but some things don't.  And if the later will
eventually work depends essentially on whether support for \pkg{zref} is
provided by the relevant packages and classes or not.  Or, failing that,
whether \pkg{zref-clever} is able to provide some specific support when a
reasonable way to do so is within reach.


\section{Compatibility modules}
\zlabel{sec:comp-modules}

This section gives a description of each compatibility module provided by
\pkg{zref-clever}.  These modules intend to smooth the interaction of \LaTeX{}
features, document classes, and packages with \pkg{zref-clever} and
\pkg{zref}, and they can be selectively or completely disabled with the option
\opt{nocompat} (see \zcref{sec:options}).  This set is not to be confused with
``the list of packages or classes supported by \pkg{zref-clever}''.  In most
circumstances, things should just work out of the box, and need no specific
handling.  These are just the ones for which some special treatment was
required.  Of course, this effort is bound to be incomplete (see
\zcref{sec:limitations}).

The purpose of outlining to some extend what the compatibility modules do is
twofold.  First, some of them require usage adjustments for label setting,
which must be somehow conveyed in this documentation.  Second, the kind and
degree of intervention in external code varies significantly for each module,
and since this is an area of potential friction, a minimum of information for
the users to judge whether they want to leave these modules enabled or not is
due.  For this reason, this is also a little technical, but for full details,
see the code documentation.

\bigskip{}

\DescribeOption{appendix} %
The \cs{appendix} command provided by many document classes is normally used
to change the behavior of the sectioning commands after that point.  Usually,
depending on the class, the changes that interest us involve using \cs{@Alph}
for numbering and \cs{appendixname} for chapter's names.  In sum, we'd like to
refer to the appendix sectioning commands as ``appendices'' rather than
``chapters'' or ``sections''.  Since the sectioning commands are the same as
before \cs{appendix}, and so are their underlying counters, we must configure
the counter type of the sectioning counters to \texttt{appendix}.  And this is
what this compatibility module does, and it uses a \pkg{ltcmdhooks} hook on
\cs{appendix} for the purpose.  Hence, this module applies to any document
class or package which provides that command.

\DescribeOption{appendices} %
This module implements support for the \env{appendices} and
\env{subappendices} environments provided by the \pkg{appendix} package, and
also by \cls{memoir}.  The task is the same as for the \texttt{appendix}
module: set proper counter types for the sectioning counters.  This module
employs environment hooks to \env{appendices} and \env{subappendices} and a
command hook to \cs{appendix} for the purpose.

\DescribeOption{memoir} %
The \cls{memoir} class implements several features with one or another
implication for cross-referencing, usually bearing just the standard
referencing system in mind, and related mainly to captions, subfloats, and
notes.  This compatibility module tries to adjust \pkg{zref-clever} to these
features with support for the following: i) set counter types for counters
\texttt{subfigure}, \texttt{subtable}, and \texttt{poemline} (used in the
\env{verse} environment); ii) configure resetting behavior
(\opt{counterresetby} option) for \texttt{subfigure} and \texttt{subtable}
counters; iii) provide that the \meta{label} arguments to environments
\env{sidecaption} and \env{sidecontcaption} and commands \cs{bitwonumcaption},
\cs{bionenumcaption}, and \cs{bicaption} \emph{also} set a \cs{zlabel} of the
same name; iv) provide the \pkg{zref} property ``\texttt{subcaption}'' so that
we can refer to, for example, \texttt{\cs{zcref}[ref=subcaption]\{subcap-1\}}
to emulate the functionality of \cls{memoir}'s \cs{subcaptionref}; v) provide
that \cs{footnote}, \cs{verbfootnote}, \cs{sidefootnote}, and \cs{pagenote}
get a proper \opt{currentcounter} set; and v) set counter types for counters
\texttt{sidefootnote} and \texttt{pagenote}.  Naturally, the sheer number of
features that required some specific support implies that some gymnastics were
needed here.  But the most sensitive changes are: i) a local redefinition of
\cs{label} inside the environments \env{sidecaption} and \env{sidecontcaption}
and the commands \cs{bitwonumcaption}, \cs{bionenumcaption}, and
\cs{bicaption}; and ii) the use of \pkg{ltcmdhooks} command hooks on
\cs{bitwonumcaption}, \cs{bionenumcaption}, \cs{bicaption},
\cs{@memsubcaption}, \cs{@makefntext}, and \cs{@makesidefntext}.

\DescribeOption{KOMA} %
The \cls{KOMA-Script} document classes are much more strict than \cls{memoir}
in using standard mechanisms for cross-reference related features, so that
very little adjustment is needed here.  Only the environments
\env{captionbeside} and \env{captionofbeside} require special treatment.  And,
though they do use \cs{refstepcounter} under the hood, since they are
environments, we don't get to see reference variables outside them.
\cs{@currentlabel} is smuggled out of the group, but not \cs{@currentcounter},
so we must arrange for the later to have a correct value outside the caption
environments too.  Environment hooks are used for the purpose, essentially
setting \cs{@currentcounter} to \cs{@captype}, which would be the value the
captioning infrastructure would set for it.

\DescribeOption{amsmath} %
\pkg{amsmath}'s display math environments have their contents processed twice,
once for measuring and the second does the final typesetting.  Hence,
\pkg{amsmath} needs to handle \cs{label} specially inside these environments,
otherwise we'd have duplicate labels all around, and indeed it does redefine
\cs{label} locally inside them.  Alas, the same treatment is not granted to
\cs{zlabel}.  However, \cs{label} is set basically to \emph{store} the value
of the argument inside the environments, and its global meaning is kept in
\cs{ltx@label} which is called at the appropriate time to actually set the
label.  So, what \pkg{zref-clever} does is redefine \cs{ltx@label} to set
\texttt{both} a regular \cs{label} and a \cs{zlabel} for the same \meta{label}
(which does not generate a duplicate label problem since the referencing
systems are independent).  Therefore, you must use \cs{label} (not
\cs{zlabel}) inside \pkg{amsmath}'s display math environments, and this
compatibility module arranges that you can also refer to that label with
\pkg{zref} and, thus, with \cs{zcref} as well.  The following environments are
subject to this usage restriction: \env{equation}, \env{align}, \env{alignat},
\env{flalign}, \env{xalignat}, \env{gather}, \env{multline}, and their
respective starred versions.  In particular, the same is not the case for the
\env{subequations} environment, inside which \cs{zlabel} works as usual (to
refer to the main equation number, that is, right after
\texttt{\cs{begin}\{subequations\}}).  See the \zcref{how:amsmath} for an
usage example.  The module also ensures proper \opt{currentcounter} values are
in place for the display math environments, for which it uses environment
hooks, and sets the font of equation references to \cs{upshape}, following
\pkg{amsmath}'s \cs{eqref}.  Finally, 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.  Note that \pkg{zref-clever} is not the only package to redefine
\cs{ltx@label}, and compatibility problems may arise if this module is used
with such packages or with document classes that do the same.  In case of
trouble, you can load \pkg{zref-clever} with option \texttt{nocompat=amsmath}
and either use the standard referencing system's facilities to refer to
\pkg{amsmath}'s equations or check the code documentation for the technique
used for this (which is pretty standard) and adapt it to your case.  Given
that any trouble that may arise here is one of the proper ``timing'' of the
redefinition, it should not be particularly complicated to make such
adjustments.

\DescribeOption{mathtools} %
\pkg{mathtools} has a feature to show the numbers only for those equations
actually referenced (with \cs{eqref} or \cs{refeq}), which is enabled by the
\opt{showonlyrefs} option.  This compatibility module adds support for this
feature, such that equation references made with \cs{zcref} also get marked as
``referenced'' for \pkg{mathtools}, when the option is active, of course.  The
module uses a couple of \pkg{mathtools} functions, but does not need to
redefine or hook into anything, everything is handled on \pkg{zref-clever}'s
side.

\DescribeOption{breqn} %
This compatibility module only sets proper \opt{currentcounter} values for the
environments \env{dgroup}, \env{dmath}, \env{dseries}, and \env{darray}, and
uses environment hooks for the purpose.  Note that these environments offer a
\opt{label} option for label setting, but implements it in a way that is
somewhat tricky to grab for our purposes, so we don't do it.  However,
\pkg{breqn}'s documentation says the following about the use of \cs{label}
inside its environments: \textquote{Use of the normal \cs{label} command
  instead of the \opt{label} option works, I think, most of the time
  (untested)}.  My light testing suggests the same is true for \cs{zlabel},
which can then be used directly in these environments.  But the ``second
class'' status for this use is the one granted by \pkg{breqn}, there's not
much we can do here.  If you have any trouble with this, you may wish to check
\zcref{wkrnd:breqn}.

\DescribeOption{listings} %
Being \env{lstlisting}s environments what they are, one cannot simply place a
label inside them without special treatment.  \pkg{listings} arranges to this
by providing a \opt{label} option for setting a label for the whole
environment, and a properly escaped label command inside the environment can
be used to refer to the line number.  While the later can also be used to set
a \cs{zlabel} to make line number references, the \opt{label} option is
catered to the standard labels exclusively.  Hence, this compatibility module
uses the same label name -- which luckily and atypically is stored in a
variable -- and sets a \cs{zlabel} as well.  This is done by using
\pkg{listings}' \texttt{PreInit} hook, se we don't have to redefine or tamper
with anything for the purpose.  Besides this, the module also sets appropriate
\opt{countertype}, \opt{counterresetby} and \opt{currentcounter} values for
the \pkg{listings}' counters: \texttt{lstlisting} and \texttt{lstnumber}. See
the \zcref{how:listings} for an usage example.

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

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

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


\section{Work-arounds}

\marginpar{\raggedleft\raisebox{-1.5ex}{\dbend}}As should be clear by now, the
use of \pkg{zref}'s \cs{zlabel} and thus of \pkg{zref-clever} may occasionally
require some adjustments, since it does not enjoy the universal support the
standard referencing system does.  The compatibility modules presented in
\zcref{sec:comp-modules} go a long way in ensuring the user has to worry very
little about it, but they cannot hopefully go all the way.  Not only because
this kind of support will never be exhaustive, but also since, sometimes,
given the way certain features are implemented by packages or document
classes, there may not be a reasonable way to provide this support, from our
side.  But, still, most of the time, it is still ``viable'' to get there, if
one really wishes to do so.  So, this section keeps track of some known
recipes, which I don't think belong in \pkg{zref-clever} itself, but which you
may choose to use.  Note that this list is intended to spare users from having
to reinvent the wheel every time someone needs something of the sort, but from
\pkg{zref-clever}'s perspective, their status is ``not supported''.


\subsection*{\pkg{breqn}}

As mentioned in \opt{breqn}'s compatibility module (\zcref{sec:comp-modules}),
\pkg{breqn}'s math environments \env{dgroup}, \env{dmath}, \env{dseries}, and
\env{darray} offer a \opt{label} option (plus \opt{labelprefix}) for the
purpose of label setting.  Setting a \cs{zlabel} alongside with a regular
\cs{label} based on that option requires redefining some of \pkg{breqn}
internals.  Also, \pkg{breqn} does not use \cs{refstepcounter} to increment
the equation counters and, as a result, fails to set \pkg{hyperref} anchors
for the equations (thus affecting standard labels too).  The example below
also provides to that.\footnote{The later work-around thanks to Heiko
  Oberdiek, at \url{https://tex.stackexchange.com/a/241150}.}


\begin{zcworkaround}[caption={\pkg{breqn}},label={wkrnd:breqn}]
\documentclass{article}
\usepackage{zref-clever}
\usepackage{breqn}
\makeatletter
\define@key{breqn}{label}{%
  \edef\next@label{%
    \noexpand\label{\next@label@pre#1}%
    \noexpand\zlabel{\next@label@pre#1}}%
  \let\next@label@pre\@empty}
\makeatother
\usepackage{hyperref}
\usepackage{etoolbox}
\makeatletter
\patchcmd\eq@setnumber{\stepcounter}{\refstepcounter}{}{%
  \errmessage{Patching \noexpand\eq@setnumber failed}}
\makeatother
\begin{document}
\section{Section 1}
\begin{dmath}[label={eq:1}]
  f(x)=\frac{1}{x} \condition{for $x\neq 0$}
\end{dmath}
\begin{dmath}[labelprefix={eq:},label={2}]
  H_2^2 = x_1^2 + x_1 x_2 + x_2^2 - q_1 - q_2
\end{dmath}
\zcref{eq:1, eq:2}
\end{document}
\end{zcworkaround}

Of course, you can always adapt things to your needs and, e.g., make the
\opt{label} option set just \cs{zlabel} instead of both labels, or create a
separate \opt{zlabel} option.


\section{Acknowledgments}

\pkg{zref-clever} would not be possible without other people's previous work
and help.

Heiko Oberdiek's \pkg{zref}, now maintained by the Oberdiek Package Support
Group, is the underlying infrastructure of this package.  The potential of its
basic concept and the solid implementation were certainly among the reasons
I've chosen to venture into these waters, to start with.  And I believe they
will remain one of the main assets of \pkg{zref-clever} as it matures.

The name of the package makes no secret that a major inspiration for the kind
of ``feel'' I strove to achieve has been Toby Cubitt's \pkg{cleveref}.
Indeed, I have been an user of \pkg{cleveref} for several years, and a happy
one at that.  But the role \pkg{cleveref} played in the development of
\pkg{zref-clever} extends beyond the visible influence in the design of user
facing functionality.  Some technical solutions and, specially, the handling
of support for other packages were a valuable reference.  Hence, the
accumulated experience of \pkg{cleveref} allowed for \pkg{zref-clever} to
start on a more solid foundation than would otherwise be the case.

The long term efforts of the \LaTeX3 \cs{Team} around \pkg{expl3} and
\pkg{xparse} have also left their marks in this package.  By implementing
powerful tools and smoothing several regular programming tasks, they have
certainly reduced my entry barrier to \LaTeX{} programming and enabled me to
develop this package with a significantly reduced effort.  And, given the
constraints of my abilities, the result is no doubt much better than it would
be in their absence.

Besides these more general acknowledgments, a number of people have
contributed to \pkg{zref-clever}, whether they are aware of it or not.
Suggestions, ideas, solutions to problems, bug reports or even encouragement
were generously provided by (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
  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
  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.
  Frank Mittelbach,
  % 2021-10-14: https://github.com/latex3/latex2e/issues/687
  `\texttt{samcarter}',
  % 2021-10-14: https://chat.stackexchange.com/transcript/message/59361777#59361777
  % 2021-10-21: https://chat.stackexchange.com/transcript/message/59418309#59418309
  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
  and `\texttt{niluxv}'.
  % 2022-01-05: https://github.com/gusbrs/zref-clever/issues/4
  % 2022-01-05: https://github.com/gusbrs/zref-clever/pull/5

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
  and `\texttt{niluxv}' (Dutch).
  % 2022-01-09: https://github.com/gusbrs/zref-clever/pull/5

If I have inadvertently left anyone off the list I apologize, and please let
me know, so that I can correct the oversight.

Thank you all very much!


\section{Change history}

A change log with relevant changes for each version, eventual upgrade
instructions, and upcoming changes, is maintained in the package's repository,
at \url{https://github.com/gusbrs/zref-clever/blob/main/CHANGELOG.md}.  An
archive of historical versions of the package is also kept at
\url{https://github.com/gusbrs/zref-clever/releases}.

\end{document}
