% \iffalse meta-comment % % File: zref-clever.tex % % This file is part of the LaTeX package "zref-clever". % % Copyright (C) 2021-2023 gusbrs % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this % license or (at your option) any later version. The latest version % of this license is in the file: % % https://www.latex-project.org/lppl.txt % % and version 1.3 or later is part of all distributions of LaTeX % version 2005/12/01 or later. % % % This work is "maintained" (as per LPPL maintenance status) by gusbrs. % % This work consists of the files zref-clever.dtx, % zref-clever.ins, % zref-clever-doc.tex, % zref-clever-code.tex, % and the files generated from them. % % The released version of this package is available from CTAN. % % ----------------------------------------------------------------------- % % The development version of the package can be found at % % https://github.com/gusbrs/zref-clever % % for those people who are interested. % % ----------------------------------------------------------------------- % % \fi \documentclass{l3doc} % The package itself *must* be loaded so that \GetFileInfo can pick up date % and version data. Naturally, we also use it. \usepackage{zref-clever} \zcsetup{cap} \usepackage{zref-check} \usepackage{zref-titleref} \usepackage[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}} \NewDocumentCommand\username{m}{`\texttt{#1}'} \makeatletter \newcommand{\zcrequiredkernel}{\zrefclever@required@kernel} \makeatother \setlength{\marginparsep}{2\labelsep} \definecolor{reffmtbox}{gray}{0.15} \definecolor{reffmtback}{gray}{0.85} \NewDocumentCommand\reffmt{m}{% \fcolorbox{reffmtbox}{reffmtback}{% \rule[-0.2\baselineskip]{0pt}{0.8\baselineskip}\texttt{#1}}} \newlist{refformat}{itemize}{1} \setlist[refformat]{label={}, beginpenalty=500, midpenalty=500} \NewDocumentCommand\zctask{m}{% \begin{description} \item[Task] #1 \end{description}} \lstdefinestyle{code}{ language=[LaTeX]TeX, moretexcs={ AddToHook, define@key, patchcmd, eq@setnumber, DeclareFloatingEnvironment, newlist, setlist, zexternaldocument, next@label, next@label@pre, @empty, tag, text, lstset, condition, RenewDocumentCommand, NewCommandCopy, ltx@gobble, @currentcounter, zref@label, zref@wrapper@babel, zref@ifpropundefined, zref@setcurrent, zref@newprop, zref@addprop, beamer@old@zref@label, alt, beamer@nameslide, beamer@dummynameslide, ordinal, tcbuselibrary, tcbset, newtcolorbox, newtcbtheorem, } } \lstdefinestyle{zrefclever}{ style=code, moretexcs={ zcref, zcpageref, zlabel, zcsetup, zcLanguageSetup, zcRefTypeSetup, zcheck, zvref, zvpageref, zvrefrange, zvpagerefrange, zfullref, } } \lstset{ style=zrefclever, basicstyle=\ttfamily\small, columns=fullflexible, keepspaces, xleftmargin=\leftmargin, xrightmargin=.5\leftmargin, } % Setup inspired by https://tex.stackexchange.com/a/4068. For how to use these % environments in a .dtx context see https://tex.stackexchange.com/a/31026. \newcounter{zchowto} \lstnewenvironment{zchowto}[1][]{% \renewcommand{\lstlistingname}{How-to}% \renewcommand*\theHlstlisting{ht.\thelstlisting}% \zcsetup{countertype={lstlisting=zchowto}}% \lstset{#1}% \stepcounter{zchowto}% \setcounter{lstlisting}{\value{zchowto}}% }{} \newcounter{zcworkaround} \lstnewenvironment{zcworkaround}[1][]{% \renewcommand{\lstlistingname}{Work-around}% \renewcommand*\theHlstlisting{wa.\thelstlisting}% \zcsetup{countertype={lstlisting=zcworkaround}}% \lstset{#1}% \stepcounter{zcworkaround}% \setcounter{lstlisting}{\value{zcworkaround}}% }{} \lstnewenvironment{zcexample}[1][]{% \renewcommand{\lstlistingname}{Example}% \lstset{#1}% }{} \zcRefTypeSetup{zchowto}{ Name-sg = {How-to}, name-sg = {how-to}, Name-pl = {How-tos}, name-pl = {how-tos}, } \zcRefTypeSetup{zcworkaround}{ Name-sg = {Work-around}, name-sg = {work-around}, Name-pl = {Work-arounds}, name-pl = {work-arounds}, } \begin{document} \GetFileInfo{zref-clever.sty} \title{% The \pkg{zref-clever} package% \texorpdfstring{\\{}\medskip{}}{ - }% User manual% \texorpdfstring{\medskip{}}{}% } \author{% \texorpdfstring{\texttt{gusbrs}\\[0.8em] \url{https://github.com/gusbrs/zref-clever}\\ \url{https://www.ctan.org/pkg/zref-clever}}{gusbrs}} \date{Version \fileversion\ -- \filedate} \maketitle \begin{center} {\bfseries \abstractname\vspace{-.5em}\vspace{0pt}} \end{center} \begin{quotation} \pkg{zref-clever} provides a user interface for making \LaTeX{} cross-references which automates some of their typical features, thus easing their input in the document and improving the consistency of typeset results. A reference made with \cs{zcref} includes a ``name'' according to its ``type'' and lists of multiple labels can be automatically sorted and compressed into ranges when due. The reference format is highly and easily customizable, both globally and locally. \pkg{zref-clever} is based on \pkg{zref}'s extensible referencing system. \end{quotation} \bigskip{} \begin{center} \textbf{EXPERIMENTAL} Please read \zcref{sec:warning} carefully. \end{center} \clearpage{} \tableofcontents \clearpage{} \section{Introduction} Cross-referencing is an area which lends itself quite naturally to automation. Not only for input convenience but also, and most importantly, for end results consistency. Indeed, the standard \LaTeX{} cross-referencing system -- with \cs{label}, \cs{ref}, and \cs{pageref} -- is already a form of automation, by relieving us from checking the number of the referenced object, and the page where it lies. But the plethora of existing features, packages and document classes which, in one way or another, extends this basic functionality is a clear indication of a demand for more automation. Just to name the 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{\pkg{zref-clever} for the impatient} \pkg{zref-clever} is based on \pkg{zref}'s referencing system which, though independent of the standard one, is very similar to it in its user interface. Indeed, to use \pkg{zref}, instead of setting a \cs{label} and making a \cs{ref}, one would set a \cs{zlabel} and make \cs{zref}s to it, in pretty much the same way as for the standard system. \pkg{zref-clever} introduces the more featureful \cs{zcref} for making references, but relies on \pkg{zref}'s \cs{zlabel} for label setting. \pkg{zref-clever} provides that a \cs{label} also sets a \cs{zlabel} with the same name using the kernel's \texttt{label} hook (see the \opt{labelhook} option in \zcref{sec:options}), so that you can use it too with standard \cs{label}s (see the \zcref{sec:label-or-zlabel} for discussion). A basic document using \pkg{zref-clever} is shown in \zcref{how:basic} which, despite the small necessary adjustments, should feel very familiar to any \LaTeX{} user acquainted with the standard referencing system: \begin{zchowto}[caption={Basic usage},label={how:basic}] \documentclass{article} \usepackage{zref-clever} \usepackage{hyperref} \begin{document} \section{Section 1} \zlabel{sec:section-1} \begin{figure} A figure. \caption{Figure 1} \zlabel{fig:figure-1} \end{figure} A reference to \zcref{sec:section-1}. \zcref[S]{fig:figure-1} shows some interesting information. A page reference can be done with either \zcpageref{sec:section-1} or with \zcref[page]{sec:section-1}. A reference can also be made to multiple labels, as in \zcref{sec:section-1, fig:figure-1}. \end{document} \end{zchowto} The references in the document of \zcref{how:basic} illustrate one of the main features of \pkg{zref-clever}, which is to include an appropriate ``type name'' of the reference, alongside of the reference itself. The document renders its references as: \begin{quote} A reference to section 1. Figure 1 shows some interesting information. A page reference can be done with either page 1 or with page 1. A reference can also be made to multiple labels, as in section 1 and figure 1. \end{quote} \zcref[S]{how:basic} also illustrates the use the optional argument of \cs{zcref} to modulate the behavior of the reference. In particular, the \opt{S} option is one you should get acquainted with from the start, as it ensures that the type name of a reference is properly capitalized and not abbreviated, and it is meant to be used in references made at the beginning of a sentence. But \pkg{zref-clever} is highly customizable, and several other options exist, and multiple places where you can set them: \begin{itemize} \item The optional argument of \cs{zcref}: for individual references. \item \cs{zcsetup}: for settings meant to affect all references. \item \cs{zcRefTypeSetup}: to customize the behavior of each reference type. \item \cs{zcLanguageSetup}: for language-specific settings. \end{itemize} For the list of available options, and for these different scopes in which they can be used, see \zcref{sec:user-interface, sec:options, sec:reference-format, sec:internationalization}. Other usage examples are available at \zcref{sec:how-tos}. \section{Loading the package} \zlabel{sec:loading-package} \pkg{zref-clever} can be loaded with the usual: \begin{zcexample} \usepackage{zref-clever} \end{zcexample} The package does not accept load-time options, package options must be set using \cs{zcsetup} (see \zcref{sec:user-interface}). \subsection{Dependencies} \pkg{zref-clever} requires \pkg{zref}, particularly its \pkg{zref-base}, \pkg{zref-user} and \pkg{zref-abspage} modules, and the \LaTeX{} kernel \zcrequiredkernel{}, or newer. It requires UTF-8 input encoding, which has been the kernel's default for some time. It also needs \pkg{ifdraft}. Some packages are leveraged by \pkg{zref-clever} if they are present, but are not loaded by default or required by it, namely: \pkg{hyperref}, \pkg{zref-check}, and \pkg{zref}'s \pkg{zref-hyperref} and \pkg{zref-xr} modules. \section{User interface} \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{\cs{label} or \cs{zlabel}?} \zlabel{sec:label-or-zlabel} Technically, \pkg{zref}'s referencing system, and thus also \pkg{zref-clever}, require a label set with \cs{zlabel} to make a reference. However, the \opt{labelhook} option (see \zcref{sec:options}) leverages the kernel's \texttt{label} hook to also set a \cs{zlabel} when a standard \cs{label} is called, so that we can simply use \cs{label}s in our document and refer to them with either referencing system. Indeed, in some places the use of \cs{label} this way may be required (see \zcref{sec:limitations,sec:comp-modules}). That given, which is to be preferred: use \cs{label} all around or normally use \cs{zlabel} and, occasionally resort to \cs{label} where required? I guess it depends, but we can reason the pros and cons of both alternatives. Simply using \cs{label} across your document clearly speaks for convenience. You don't have to worry with the exceptional case where a \cs{zlabel} may not work or setting it is not possible. You can use either referencing system for your labels as desired. Your favorite editor may have some facilities to ease the insertion of labels, but does not support \cs{zlabel}. And so on. The only disadvantage I can see with this approach is that two labels end up in the \file{.aux} file which, arguably, may be seen as a redundancy, or waste. It is probably fair to consider this redundancy, in most use cases, as a negligible cost. But you may disagree, or the size of your document or your requirements may say otherwise, in which case you may prefer the second approach and use \cs{zlabel} normally, with some occasional \cs{label} where needed. Known relevant cases where \cs{label} is required are documented in the manual (see \zcref{sec:how-tos,sec:limitations,sec:comp-modules}), but some trial and error can easily cover the gap for the remaining cases. They are also rare cases. So finding out where \cs{label} is required should not be much of a trouble either. I think the first approach does deserve the status of ``recommended'' for normal use cases and documents. Despite that, note that the examples of this manual typically use the second approach. There's a historic reason for this, since most of them were created before the kernel's \texttt{label} hook was available, so that it was really the only approach. However, I'll keep the examples this way, notwithstanding this recommendation, because it is also important to document the limitations of directly using \cs{zlabel}, for those who may want to use the second approach. \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 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. \DescribeOption{note} % The \opt{note} option receives as value some text to be typeset at the end of the whole reference list. It is separated from it by \opt{notesep} (see \zcref{sec:reference-format}). \DescribeOption{check} % Provides integration of \pkg{zref-clever} with the \pkg{zref-check} package. The option is only functional in the document body and if \pkg{zref-check} has been loaded. \opt{check} requires a value, which works exactly like the optional argument of \cs{zcheck}, and can receive both checks and \cs{zcheck}'s options. And the checks are performed for each label in \marg{labels} received as argument by \cs{zcref}. See the User manual of \pkg{zref-check} for details. The checks done by the \opt{check} option in \cs{zcref} comprise the complete reference, including the \opt{note} (see \zcref{sec:reference-format}). \DescribeOption{countertype} % \DescribeOption{reftype} % The \opt{countertype} option allows to specify the ``reference type'' of each counter, which is stored as a label property when the label is set. This reference type is what determines how a reference to this label will eventually be typeset when it is referred to (see \zcref{sec:reference-types}). A value like \texttt{countertype = \{foo = bar\}} sets the \texttt{foo} counter to use the reference type \texttt{bar}. There's only need to specify the \opt{countertype} for counters whose name differs from that of their type, since \pkg{zref-clever} presumes the type has the same name as the counter, unless otherwise specified. Also, the 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. The \opt{reftype} option allows one to specify the reference type manually, regardless of the current counter. This can be used to locally override any \opt{countertype} settings of the package and, for those acquainted with it, is the equivalent of \pkg{cleveref}'s optional argument to \cs{label}. Normally, you'd want to use this option within a group, but if you must do otherwise, the default value can be restored by setting the option without a value. Since these options only affect how labels are set, they are not available in \cs{zcref}. \DescribeOption{\raisebox{-.2em}{\dbend}\ counterresetters} % \DescribeOption{counterresetby} % The sorting and compression of references done by \cs{zcref} requires that we know the counter associated with a particular label but also information on any counter whose stepping may trigger its resetting, or its ``enclosing counters''. This information is not easily retrievable from the counter itself but is (normally) stored with the counter that does the resetting. The \opt{counterresetters} option 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, take care that the setting is duly grouped because, if set, it has precedence over \cs{@currentcounter} and, contrary to the later, the former is not reset the next time \cs{refstepcounter} runs. Its default value is, quite naturally, \cs{@currentcounter}. The default value can be reset by calling the option with no value. Since this option only affects how labels are set, it is not available in \cs{zcref}. \DescribeOption{\raisebox{.4em}{\dbend}\ labelhook} % \opt{labelhook} is a boolean option which controls whether \pkg{zref-clever} uses the kernel's \texttt{label} hook to, whenever a standard \cs{label} is called, also set a \cs{zlabel} with the same name. The package's default value is \texttt{true} so that one can use \cs{label}s along the document and refer to them (also) with \pkg{zref} and \pkg{zref-clever} reference commands. This value is not only the default, but also a recommended value. Disabling this option means you are on your own to handle cases where \cs{zlabel} does not work, which are not many, but can be tricky to deal with where they occur. Since this option only affects how labels are set, it is not available in \cs{zcref}. See \zcref{sec:label-or-zlabel} for some discussion of different labeling approaches this options allows for. \DescribeOption{nocompat} % Some packages, document classes, or LaTeX features may require specific support to work with \pkg{zref-clever} (see \zcref{sec:limitations}). \pkg{zref-clever} tries to make things smoother by covering some of them. Depending on the case, this can take the form of some simple setup for \pkg{zref-clever}, or may involve the use of hooks to external environments or commands and, eventually, a patch or redefinition. By default, all the available compatibility modules are enabled. Should this be undesired or cause any problems in your environment, the option \opt{nocompat} can selectively or completely inhibit their loading. \opt{nocompat} receives a comma separated list of compatibility modules to disable (for the list of available modules and details about each of them, see \zcref{sec:comp-modules}). You can disable all modules by setting \opt{nocompat} without a value (or an empty one). This is a preamble only option. \section{Reference types} \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 a user interface for reference formatting which allows settings to be done in different scopes, with more or less overarching effects, and some precedence rules to regulate the relation of settings given in each of these scopes. There are four scopes in which reference formatting can be specified by the user, in the following precedence order: i) as \emph{general options}; ii) as \emph{type-specific options}; iii) as \emph{language- and type-specific options}; and iv) as \emph{language-specific default options}. Besides those, there's a fifth \emph{internal} scope, with the least priority of all, a ``fallback'', for the cases where it is meaningful to provide some value, even for an unknown language. The package itself places the default setup for reference formatting at low precedence levels, and the users can easily and conveniently override them as desired. ``General'' options (i) can be given by the user in the optional argument of \cs{zcref}, but also set through \cs{zcsetup} (see \zcref{sec:options}). ``Type'' specific options (ii) are handled by \cs{zcRefTypeSetup} (see \zcref{sec:user-interface}). ``Language'' options, whether ``type'' specific (iii) or ``default'' (iv) have their user interface in \cs{zcLanguageSetup}, and have their values populated by the package's built-in language files (see \zcref{sec:internationalization}). Not all reference format specifications can be given in all of these scopes, though. Some of them can't be type-specific, others must be type-specific, so the set available in each scope depends on the pertinence of the case. \zcref{tab:reference-format} introduces the available reference format options, which will be discussed in more detail soon, and lists the scopes in which each is available. \begin{table}[htb] \centering \begin{tabular}{l>{\ttfamily}lcccc} \toprule & & General & Type & \multicolumn{2}{c}{Language} \\ \cmidrule(lr){5-6} & & & & Type & Default \\ & & (i) & (ii) & (iii) & (iv) \\ \midrule Typesetting & tpairsep & $\bullet$ & & & $\bullet$ \\ (necessarily not & tlistsep & $\bullet$ & & & $\bullet$ \\ type-specific) & tlastsep & $\bullet$ & & & $\bullet$ \\ & notesep & $\bullet$ & & & $\bullet$ \\ \addlinespace Typesetting & namesep & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ (possibly & pairsep & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ type-specific) & listsep & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ & lastsep & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ & rangesep & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ & refbounds & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ \addlinespace Typesetting & Name-sg & & $\bullet$ & $\bullet$ & \\ (necessarily & name-sg & & $\bullet$ & $\bullet$ & \\ type-specific) & Name-pl & & $\bullet$ & $\bullet$ & \\ & name-pl & & $\bullet$ & $\bullet$ & \\ & Name-sg-ab & & $\bullet$ & $\bullet$ & \\ & name-sg-ab & & $\bullet$ & $\bullet$ & \\ & Name-pl-ab & & $\bullet$ & $\bullet$ & \\ & name-pl-ab & & $\bullet$ & $\bullet$ & \\ \addlinespace Font & namefont & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ & reffont & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ \addlinespace Other & cap & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ & abbrev & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ & endrange & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ & rangetopair & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ \bottomrule \end{tabular} \caption{Reference format options and their scopes} \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 receives as value a comma separated list of four items in the form \texttt{\{preref*,preref,postref,postref*\}}, just like \opt{refbounds}. The base options are mutually exclusive, which means, for example, that it is not sufficient to set \opt{refbounds-first} to define the behavior of all first references of a type block. \opt{refbounds-first} is the value used for the first reference when not single, not the beginning of a pair, and not the beginning of a range. Setting a group of them is the purpose of the derived options. Each of these sets all options under it. Some examples. \opt{+refbounds-first} sets \opt{refbounds-first}, \opt{refbounds-first-sg}, \opt{refbounds-first-pb}, and \opt{refbounds-first-rg}. In turn, \opt{+refbounds-rb} sets \opt{refbounds-first-rb} and \opt{refbounds-mid-rb}. And quite conveniently, \opt{+refbounds} sets \opt{+refbounds-first}, \opt{+refbounds-mid}, and \opt{+refbounds-last}, it is hence sufficient to set it to define the behavior of what is typeset around all references for the whole type-block. As you probably guessed by now, the \opt{refbounds} option presented in \zcref{tab:reference-format} is an alias of \opt{+refbounds}. Given that base and derived options are actually setting the same group of underlying options (the base ones), the order in which they are given is relevant: the last one prevails. The idea here is to use first the derived options to set some general defaults, and then change one or another base option to handle exceptions as needed. Of course, how best to use them depends on the case. \section{Internationalization} \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 dutch & \\ english & american \\ & australian \\ & british \\ & canadian \\ & newzealand \\ & UKenglish \\ & USenglish \\ french & acadian \\ & \\ \bottomrule \end{tabular} \quad \begin{tabular}{ll} \toprule Language & Aliases \\ \midrule german & ngerman \\ & austrian \\ & naustrian \\ & swissgerman \\ & nswissgerman \\ italian & \\ portuguese & brazilian \\ & brazil \\ & portuges \\ spanish & \\ \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 dutch & -- & f,m,n & -- \\ english & -- & -- & -- \\ french & -- & f,m & -- \\ german & N,A,D,G & f,m,n & yes \\ italian & -- & f,m & -- \\ portuguese & -- & f,m & -- \\ spanish & -- & f,m & -- \\ \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} \zlabel{sec:how-tos} This section gathers some usage examples, or ``how-tos'', of cases which may require some \pkg{zref-clever} setup, or usage adjustments, and each item is set around a cross-reference ``task'' we'd like to perform with \pkg{zref-clever}. \subsection{Extended page references (\pkg{varioref})} \zctask{Make cross-references to pages which are sensitive to the relative position between the reference and the label being referred to using \pkg{varioref}.} The \pkg{zref-vario} package offers a layer of compatibility with \pkg{varioref} and provides \texttt{\textbackslash{}z}\dots{} counterparts for the latter's main reference commands. \begin{zchowto}[caption={\pkg{zref-vario}}] \documentclass{article} \usepackage{zref-clever} \usepackage{zref-vario} \begin{document} \section{Section 1} \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.} \pkg{amsmath}'s display math environments have their contents processed twice, once for measuring and the second does the final typesetting. Hence, \pkg{amsmath} needs to handle \cs{label} specially inside these environments, otherwise we'd have duplicate labels all around, and indeed it does redefine \cs{label} locally inside them. Alas, the same treatment is not granted to \cs{zlabel}. Therefore, you must use \cs{label} (not \cs{zlabel}) inside \pkg{amsmath}'s display math environments, and the \opt{labelhook} option provides that a \cs{label} sets both a regular \cs{label} and a \cs{zlabel}, so that we can refer to the equations with both referencing systems. 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. 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}\label{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{Overriding the reference type} \zctask{Make references to a system of equations, which should be referred to in the plural.} Though, usually, setting the \opt{countertype} option may provide a more general and convenient way to set the reference type of a given counter, sometimes we just need to do it for a particular label or set of labels. The \opt{reftype} option allows us to do so and set the reference type directly, regardless of what the current counter is. \begin{zchowto}[caption={Overriding the reference type}] \documentclass{article} \usepackage{amsmath} \usepackage{zref-clever} \usepackage{hyperref} \zcRefTypeSetup{pluralequation}{ Name-sg = Equations , name-sg = equations , Name-pl = Equations , name-pl = equations , } \begin{document} \section{Section 1} \begin{equation} \zcsetup{reftype=pluralequation} \zlabel{eq:1} \begin{aligned} A+B&=B+A\\ C&=D+E\\ E&=F \end{aligned} \end{equation} \zcref{eq:1} \end{document} \end{zchowto} \subsection{\pkg{listings}} \zctask{Make references to a \env{lstlisting} environment from the \pkg{listings} package.} Being \env{lstlisting} a verbatim environment, setting labels inside it requires special treatment. \pkg{zref-clever}'s \opt{labelhook} option provides that a label given to the \opt{label} 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.} 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.} \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} \subsection{\pkg{tcolorbox}} \zctask{Make references to boxes from the \pkg{tcolorbox} package.} Since version 6.0.0, \pkg{tcolorbox} has support for \pkg{zref} and \pkg{zref-clever}, through the \opt{label is zlabel} option. With this option enabled, the \opt{label} option sets a \cs{zlabel}, which can be referred to from \cs{zref} or \cs{zcref}. If you are using the \opt{auto counter}, or some other custom counter, you can set the reference type for the box's labels with the \opt{label type} option. \begin{zchowto}[caption={\pkg{tcolorbox}}] \documentclass{article} \usepackage{zref-clever} \usepackage{zref-titleref} \usepackage{tcolorbox} \tcbuselibrary{theorems} \tcbset{label is zlabel} \usepackage{hyperref} \newtcolorbox[auto counter,number within=section]{pabox}[2][]{% label type=example, title=Example~\thetcbcounter: #2,#1} \newtcolorbox[use counter from=pabox,number within=section]{pabox2}[2][]{% label type=solution, title=Solution~\thetcbcounter: #2,#1} \newtcbtheorem[number within=section]{mytheo}{My Theorem}{% label type=mytheorem}{th} \zcRefTypeSetup{mytheorem}{ Name-sg=Mytheorem, name-sg=mytheorem, Name-pl=Mytheorems, name-pl=mytheorems, } \begin{document} \section{Section 1} \zlabel{sec:section-1} \begin{pabox}[label={box:1}]{Title text} This is tcolorbox \zcref{box:1} on \zcpageref{box:1}. \end{pabox} \begin{pabox2}[label={box:2}]{Title text} This is tcolorbox \zcref{box:2} on \zcpageref{box:2}. \end{pabox2} \begin{mytheo}{This is my title}{theo} This is \zcref{th:theo} on \zcpageref{th:theo} and it is titled ``\zcref[noname,ref=title]{th:theo}''. \end{mytheo} \end{document} \end{zchowto} \subsection{\pkg{breqn}} \zctask{Make references to \pkg{breqn} math environments.} \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. \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. Either way, given the \opt{labelhook} option, we can just use \pkg{breqn}'s \opt{label} option and be at ease. 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). You may wish to use the work-around provided by Heiko Oberdiek at \url{https://tex.stackexchange.com/a/241150}. \begin{zchowto}[caption={\pkg{breqn}},label={how:breqn}] \documentclass{article} \usepackage{zref-clever} \usepackage{breqn} \usepackage{hyperref} % From https://tex.stackexchange.com/a/241150. \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{zchowto} \subsection{Ordinal references} \zctask{Typesetting the references as ordinal numbers.} This example is intended as an illustration of the flexibility \pkg{zref}'s extensible referencing system grants us.\footnote{Though clearly simplified, the example is less than academic. See \url{https://tex.stackexchange.com/a/670088} for an application to add a reference suffix needed in Turkish.} Getting references as ordinal numbers, something that would be normally a tricky task, can be handled with a simple custom \pkg{zref} property, which we then use to set \pkg{zref-clever}'s \opt{ref} option. \begin{zchowto}[caption={Ordinal references}] \documentclass{article} \usepackage{zref-clever} \usepackage{fmtcount} \makeatletter \zref@newprop{ordref}{\ordinal{\@currentcounter}} \zref@addprop{main}{ordref} \makeatother \zcsetup{ref=ordref} \begin{document} \section{Section 1} \zlabel{sec:section-1} \begin{figure} A figure. \caption{Figure 1} \zlabel{fig:figure-1} \end{figure} \zcref{sec:section-1,fig:figure-1} \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}. Classes and packages may offer label setting by means of arguments or options, and those usually only cater for the standard referencing system, etc. Fortunately for us, the \texttt{label} hook introduced by the \LaTeX{} kernel in the 2023-06-01 release improves the situation considerably. \pkg{zref-clever} makes use of it with the \opt{labelhook} option, enabled by default, so that a standard \cs{label} also sets a \cs{zlabel} with the same name, thus providing a very general and reliable way to deal with these places where setting a \cs{zlabel} directly is problematic: just set a standard label. 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 may not. 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} % This compatibility module provides support for some of \cls{memoir}'s cross-referencing features. Namely, it: i) sets counter types for counters \texttt{subfigure}, \texttt{subtable}, \texttt{poemline} (used in the \env{verse} environment), \texttt{sidefootnote}, and \texttt{pagenote}; ii) configures resetting behavior (\opt{counterresetby} option) for \texttt{subfigure} and \texttt{subtable} counters; iii) provides the \pkg{zref} property ``\texttt{subcaption}'' so that we can refer to, for example, \texttt{\cs{zcref}[ref=subcaption]\{subcap-1\}} to emulate the functionality of \cls{memoir}'s \cs{subcaptionref}. \DescribeOption{amsmath} % The module ensures proper \opt{currentcounter} values are in place for the display math environments, for which it uses environment hooks. The module also provides a \texttt{subeq} property, for display math environments used inside the \env{subequations} environment, which can be used to refer to them directly with the \opt{ref} option, or to build terse ranges with the \opt{endrange} option. \DescribeOption{mathtools} % \pkg{mathtools} has a feature to show the numbers only for those equations actually referenced (with \cs{eqref} or \cs{refeq}), which is enabled by the \opt{showonlyrefs} option. This compatibility module adds support for this feature, such that equation references made with \cs{zcref} also get marked as ``referenced'' for \pkg{mathtools}, when the option is active, of course. The module uses 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. See the \zcref{how:breqn} for an usage example. \DescribeOption{listings} % The module 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 be expected to go all the way. Not only because this kind of support will never be exhaustive, but also since, sometimes, given the way certain features are implemented 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*{\cls{beamer}} \cls{beamer} does some really atypical things with regard to cross-references. To start with, it redefines \cs{label} to receive an optional \texttt{<\meta{overlay specification}>} argument. Then, presumably to support overlays, it goes on and hijacks \pkg{hyperref}'s anchoring system, sets anchors (\cs{hypertarget}s) to each \emph{label} in the \file{.snm} file, while letting every standard label's anchor in the \file{.aux} file default to \texttt{Doc-Start}. Of course, having rendered useless \pkg{hyperref}'s anchoring, it has to redefine \cs{ref} so that it uses its own \file{.snm} provided ``label anchors'' to make hyperlinks. In particular, from our perspective, there is no support at all for \pkg{zref} provided by \cls{beamer}. Which is specially unfortunate since the above procedures also appear to break \pkg{cleveref}.\footnote{See, for example, \url{https://tex.stackexchange.com/q/266080}, \url{https://tex.stackexchange.com/q/668998}, and \url{https://github.com/josephwright/beamer/issues/750}. The workaround provided at \url{https://tex.stackexchange.com/a/266109} is not general enough since it breaks \pkg{cleveref}'s ability to receive a list of labels as argument.} Adding proper support for this is the business of \cls{beamer}, \pkg{zref}, and/or \pkg{hyperref}. Likely the former's really. But, taking advantage of \pkg{zref}'s flexibility, as a user, you can have a work-around in the meantime. \begin{zcworkaround}[caption={\cls{beamer}}] \documentclass{beamer} \usepackage{zref-clever} \makeatletter \RenewDocumentCommand{\zlabel}{ D<>{1} m }{% \ifx\label\ltx@gobble \else \zref@wrapper@babel{\zref@label<#1>}{#2}% \fi } \NewCommandCopy\beamer@old@zref@label\zref@label \RenewDocumentCommand{\zref@label}{ D<>{1} m }{% \alt<#1>{% \zref@ifpropundefined{anchor}{}{\zref@setcurrent{anchor}{#2}}% \beamer@old@zref@label{#2}% \beamer@nameslide{#2}% }{% \beamer@dummynameslide% }% } \makeatother \begin{document} \begin{frame} \begin{table} \begin{tabular}{cc} 1 & 2 \\ 3 & 4 \\ \end{tabular} \caption{Table 1} \zlabel{tab:1} \end{table} \end{frame} \begin{frame} \begin{figure} \rule{5cm}{5cm} \caption{Figure 1} \zlabel{fig:1} \end{figure} \end{frame} \begin{frame} \zcref{tab:1,fig:1} \end{frame} \end{document} \end{zcworkaround} This work-around redefines \cs{zlabel} so that it takes an overlay specification argument, and provides that the work done by \cls{beamer} for the standard \cs{label} is also done for it. And it works by setting the \texttt{anchor} to the \emph{label} so as to be able to speak the ``\cls{beamer}-lingo'' of anchors. A couple of caveats though. First, there's probably still some work to be done there in defining and setting reference types for \cls{beamer} specific document objects, e.g. overlays. But it can be done by the standard user interface of \pkg{zref-clever}. Second, since \cls{beamer}'s anchoring system does not provide for uniqueness of anchors as \pkg{hyperref} does, if you (need to) use \cs{label} to set both \cs{label} and \cs{zlabel}, relying on the \opt{labelhook} option, this will result in duplicate anchors for labels set in them, with corresponding \pkg{hyperref} warnings of ``destination with the same identifier has been already used, duplicate ignored''. The warning is actually harmless in this case, since both labels are set in the same place, and thus have identical anchors, it is nevertheless there. \section{Acknowledgments} \pkg{zref-clever} would not be possible without other people's previous work and help. Heiko Oberdiek's \pkg{zref}, now maintained by the Oberdiek Package Support Group, is the underlying infrastructure of this package. The potential of its basic concept and the solid implementation were certainly among the reasons I've chosen to venture into these waters, to start with. And I believe they will remain one of the main assets of \pkg{zref-clever} as it matures. The name of the package makes no secret that a major inspiration for the kind of ``feel'' I strove to achieve has been Toby Cubitt's \pkg{cleveref}. Indeed, I have been a user of \pkg{cleveref} for several years, and a happy one at that. But the role \pkg{cleveref} played in the development of \pkg{zref-clever} extends beyond the visible influence in the design of user facing functionality. Some technical solutions and, specially, the handling of support for other packages were a valuable reference. Hence, the accumulated experience of \pkg{cleveref} allowed for \pkg{zref-clever} to start on a more solid foundation than would otherwise be the case. The long term efforts of the \LaTeX{} Project Team around \pkg{expl3} and \pkg{xparse} have also left their marks in this package. By implementing powerful tools and smoothing several regular programming tasks, they have certainly reduced my entry barrier to \LaTeX{} programming and enabled me to develop this package with a significantly reduced effort. And, given the constraints of my abilities, the result is no doubt much better than it would be in their absence. Besides these more general acknowledgments, a number of people have contributed to \pkg{zref-clever}, whether they are aware of it or not. Suggestions, ideas, solutions to problems, bug reports or even encouragement were generously provided by (in chronological order): Ulrike Fischer, % 2021-07-03: It's Ulrike's fault :-) : https://tex.stackexchange.com/questions/603514/#comment1513982_603514 % 2021-08-20: https://tex.stackexchange.com/q/611424/105447 (comments) % 2021-09-06: https://github.com/ho-tex/zref/issues/13 % 2021-10-26: https://github.com/latex3/latex2e/issues/687 % 2022-01-12: https://chat.stackexchange.com/transcript/message/60129233#60129233 % 2022-04-09: https://github.com/latex3/hyperref/issues/229#issuecomment-1093870142 % 2023-01-02: https://tex.stackexchange.com/q/670399 (comments) % 2023-06-01: https://github.com/latex3/latex2e/pull/956 % 2023-07-27: https://chat.stackexchange.com/transcript/message/64067726#64067726 Phelype Oleinik, % 2021-08-20: https://tex.stackexchange.com/q/611370 (comments) % 2021-09-09: https://tex.stackexchange.com/a/614704 % 2021-10-06: https://tex.stackexchange.com/a/617998 % 2021-10-21: https://github.com/latex3/latex2e/pull/699 % 2022-01-12: https://tex.stackexchange.com/questions/629946/#comment1571118_629946 % 2022-01-11: https://tex.stackexchange.com/questions/633341/#comment1579825_633347 % 2023-06-01: https://github.com/latex3/latex2e/pull/1020 Enrico Gregorio, % 2021-08-20: https://tex.stackexchange.com/a/611385 % 2021-08-20: https://tex.stackexchange.com/q/611370/#comment1529282_611385 Steven B.\ Segletes, % 2021-08-20: https://tex.stackexchange.com/a/611373 Jonathan P.\ Spratte, % 2021-09-09: https://tex.stackexchange.com/a/614719 % 2021-09-09: https://github.com/latex3/latex3/pull/988 David Carlisle, % 2021-10-10: https://tex.stackexchange.com/questions/618434/#comment1544401_618439 % 2022-01-12: https://chat.stackexchange.com/transcript/message/60129096#60129096 % and following discussion. % 2022-12-26: https://chat.stackexchange.com/transcript/message/62644791#62644791 % and following discussion. % 2023-01-02: https://chat.stackexchange.com/transcript/message/62684358#62684358 % and following discussion. % 2023-02-10: https://tex.stackexchange.com/a/674846 % 2023-07-27: https://chat.stackexchange.com/transcript/message/64067575#64067575 Frank Mittelbach, % 2021-10-14: https://github.com/latex3/latex2e/issues/687 \username{samcarter}, % 2021-10-14: https://chat.stackexchange.com/transcript/message/59361777#59361777 % 2021-10-21: https://chat.stackexchange.com/transcript/message/59418309#59418309 Alan Munn, % 2021-10-14: https://chat.stackexchange.com/transcript/message/59364073#59364073 % 2021-10-21: https://chat.stackexchange.com/transcript/message/59418189#59418189 Florent Rougon, % https://github.com/frougon/xcref has been an useful reference for % declension support. Denis Bitouzé, % 2021-11-25: https://github.com/gusbrs/zref-clever/issues/1 Marcel Krüger, % 2021-11-26: https://github.com/latex3/l3build/issues/215 Jürgen Spitzmüller, % 2021-11-28: https://github.com/gusbrs/zref-clever/issues/2 \username{niluxv}, % 2022-01-05: https://github.com/gusbrs/zref-clever/issues/4 Joseph Wright, % 2023-01-02: https://chat.stackexchange.com/transcript/message/62684358#62684358 % and following discussion. Thomas F. Sturm, % 2023-02-09: https://github.com/T-F-S/tcolorbox/issues/206 % 2023-05-12: https://github.com/T-F-S/tcolorbox/issues/230 Yukai Chou, % 'muzimuzhi' % 2023-02-18: https://github.com/gusbrs/zref-clever/pull/14 % 2023-02-18: https://github.com/gusbrs/zref-clever/pull/15 % 2023-05-11: https://github.com/T-F-S/tcolorbox/issues/230 % 2023-11-09: https://github.com/gusbrs/zref-clever/issues/20 % 2024-01-20: https://github.com/gusbrs/zref-clever/pull/25 and Lars Madsen. % 2023-07-24: https://chat.stackexchange.com/transcript/message/64039717#64039717 % and following discussion. % 2023-07-26: https://chat.stackexchange.com/transcript/message/64057725#64057725 % 2023-07-31: https://chat.stackexchange.com/transcript/message/64105457#64105457 % and following discussion. % 2023-08-08: Improved 'zref' and 'zref-clever' support for 'memoir' with % v3.8. Email exchange "Subject: [FR] Improve support for zref % in memoir", starting with % rfc822msgid:CAM9ALR84v=nUTO14moPhbuDjQx9EJ1pcWAku5FdwOo9hbadwYA@mail.gmail.com. The package's language files have been provided or improved thanks to: Denis Bitouzé (French), % 2021-11-25: https://github.com/gusbrs/zref-clever/issues/1 François Lagarde (French), % 'flagarde' % 2021-12-09: discussion at https://github.com/gusbrs/zref-clever/issues/1 \username{niluxv} (Dutch), % 2022-01-09: https://github.com/gusbrs/zref-clever/pull/5 % 2022-12-27: https://github.com/gusbrs/zref-clever/pull/12 % 2022-12-27: https://github.com/gusbrs/zref-clever/pull/13 and Matteo Ferrigato (Italian). % 'matteo339' % 2022-12-12: https://github.com/gusbrs/zref-clever/issues/11 If I have inadvertently left anyone off the list I apologize, and please let me know, so that I can correct the oversight. Thank you all very much! \section{Change history} A change log with relevant changes for each version, eventual upgrade instructions, and upcoming changes, is maintained in the package's repository, at \url{https://github.com/gusbrs/zref-clever/blob/main/CHANGELOG.md}. The change log is also distributed with the package's documentation through CTAN upon release so, most likely, \texttt{texdoc zref-clever/changelog} should provide easy local access to it. An archive of historical versions of the package is also kept at \url{https://github.com/gusbrs/zref-clever/releases}. \end{document}