% \iffalse meta-comment % % File: zref-clever.tex % % This file is part of the LaTeX package "zref-clever". % % Copyright (C) 2021 Gustavo Barros % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this % license or (at your option) any later version. The latest version % of this license is in the file: % % https://www.latex-project.org/lppl.txt % % and version 1.3 or later is part of all distributions of LaTeX % version 2005/12/01 or later. % % % This work is "maintained" (as per LPPL maintenance status) by % Gustavo Barros. % % This work consists of the files zref-clever.dtx, % zref-clever.ins, % zref-clever.tex, % zref-clever-code.tex, % and the derived files listed in MANIFEST.md. % % The released version of this package is available from CTAN. % % ----------------------------------------------------------------------- % % The development version of the package can be found at % % https://github.com/gusbrs/zref-clever % % for those people who are interested. % % ----------------------------------------------------------------------- % % \fi \documentclass{l3doc} % The package itself *must* be loaded so that \GetFileInfo can pick up date % and version data. Naturally, we also use it. \usepackage[cap,check,titleref]{zref-clever} \usepackage[T1]{fontenc} \usepackage[sc]{mathpazo} \linespread{1.05} \usepackage[scale=.88]{tgheros} % sans \usepackage[varqu,scaled=1.03]{inconsolata} % tt \usepackage{listings} \usepackage{microtype} \hypersetup{hidelinks} \NewDocumentCommand\opt{m}{\texttt{#1}} \definecolor{reffmtbox}{gray}{0.15} \definecolor{reffmtback}{gray}{0.85} \NewDocumentCommand\reffmt{m}{% \fcolorbox{reffmtbox}{reffmtback}{% \rule[-0.2\baselineskip]{0pt}{0.8\baselineskip}\texttt{#1}}} \newlist{refformat}{itemize}{1} \setlist[refformat]{label={}, beginpenalty=500, midpenalty=500} \NewDocumentCommand\zctask{m}{% \begin{description} \item[Task] #1 \end{description}} \lstdefinestyle{code}{ language=[LaTeX]TeX, moretexcs={ AddToHook, define@key, patchcmd, eq@setnumber, DeclareFloatingEnvironment, newlist, setlist, zexternaldocument, next@label, next@label@pre, @empty, tag, text, lstset, condition, } } \lstdefinestyle{zrefclever}{ style=code, moretexcs={ zcref, zcpageref, zlabel, zcsetup, zcLanguageSetup, zcRefTypeSetup, zcheck, } } \lstset{ style=zrefclever, basicstyle=\ttfamily\small, columns=fullflexible, keepspaces, xleftmargin=\leftmargin, xrightmargin=.5\leftmargin, } % Setup inspired by https://tex.stackexchange.com/a/4068. For how to use these % environments in a .dtx context see https://tex.stackexchange.com/a/31026. \newcounter{zchowto} \lstnewenvironment{zchowto}[1][]{% \renewcommand{\lstlistingname}{How-to}% \lstset{#1}% \setcounter{lstlisting}{\value{zchowto}}% }{} \newcounter{zcworkaround} \lstnewenvironment{zcworkaround}[1][]{% \renewcommand{\lstlistingname}{Work-around}% \lstset{#1}% \setcounter{lstlisting}{\value{zcworkaround}}% }{} \lstnewenvironment{zcexample}[1][]{% \renewcommand{\lstlistingname}{Example}% \lstset{#1}% }{} \ExplSyntaxOn \makeatletter \lst@AddToHook { PreInit } { \cs_if_exist:cT { c@ \lstenv@name } { \exp_args:Nx \refstepcounter { \lstenv@name } } } \makeatother \ExplSyntaxOff \zcRefTypeSetup{zchowto}{ Name-sg = {How-to}, name-sg = {how-to}, Name-pl = {How-tos}, name-pl = {how-tos}, } \zcRefTypeSetup{zcworkaround}{ Name-sg = {Work-around}, name-sg = {work-around}, Name-pl = {Work-arounds}, name-pl = {work-arounds}, } \begin{document} \GetFileInfo{zref-clever.sty} \title{% The \pkg{zref-clever} package% \thanks{This file describes \fileversion, released \filedate.}% } \author{% Gustavo Barros% \thanks{\url{https://github.com/gusbrs/zref-clever}}% } \date{\filedate} \maketitle \begin{abstract} \pkg{zref-clever} provides an user interface for making \LaTeX{} cross-references which automates some of their typical features, thus easing their input in the document and improving the consistency of typeset results. A reference made with \cs{zcref} includes a ``name'' according to its ``type'' and lists of multiple labels can be automatically sorted and compressed into ranges when due. The reference format is highly and easily customizable, both globally and locally. \pkg{zref-clever} is based on \pkg{zref}'s extensible referencing system. \end{abstract} \begin{center} \small \textbf{EXPERIMENTAL} Please read \zcref{sec:warning} carefully. \end{center} \tableofcontents \section{Introduction} Cross-referencing is an area which lends itself quite naturally to automation. Not only for input convenience but also, and most importantly, for end results consistency. Indeed, the standard \LaTeX{} cross-referencing system -- with \cs{label}, \cs{ref}, and \cs{pageref} -- is already a form of automation, by relieving us from checking the number of the referenced object, and the page where it lies. But the plethora of existing features, packages and document classes which, in one way or another, extends this basic functionality is a clear indication of a demand for more automation. Just to name the most popular: \pkg{cleveref}, \pkg{hyperref}, \pkg{titleref}, \pkg{nameref}, \pkg{varioref}, \pkg{fancyref}, and the kernel's \cs{labelformat}. However, the standard cross-referencing system stores two, and only two, properties with the label: the printed representation of the counter last incremented with \cs{refstepcounter} and the page. Of course, out of the mentioned desire to automate more, the need arose to store more information about the label to support this: the title or caption of the referenced object; its counter or, even better, its ``type'', that is, whether it is a section, chapter, figure, etc.; its hyperlink anchor, and so on. Thus those two property ``fields'' of the standard label became quite a disputed real state. And the packages in this area of functionality were bound to step on each other's toes as a result. Out of this conundrum, Heiko Oberdiek eventually developed \pkg{zref}, which implements an extensible referencing system, making the labels store a property list of flexible length, so that new properties can be easily added and queried. However, even when \pkg{zref} can rightfully boast this powerful basic concept and is really quite featureful, with several different modules available, it is fair to say that, for the average user, the package may appear to be somewhat raw. Indeed, for someone who ``just wants to make a cross-reference'', the user interface of the \pkg{zref-user} module is akin to the standard \LaTeX{} cross-referencing system, and even requires some extra work if you want to have a hyperlinked reference. In other words, \pkg{zref} seems to have focused on infrastructure and on performing a number of specialized tasks with different modules, and a large part of the landscape of automation features available for the standard referencing system was not carried over to \pkg{zref}, neither by the \pkg{zref} itself nor by other packages. \pkg{zref-clever} tries to cover this gap, by bringing a number of existing features available for the standard referencing system to \pkg{zref}, and hopefully making \pkg{zref} more accessible, and interesting, to the average user. And the package's name makes it clear that the core of the envisaged feature set is that of \pkg{cleveref}, even though the attempt was less one of replicating functionality per se than that of having it as a successful point of reference, from where we could then try to tap into \pkg{zref}'s potential. Indeed, although there is a significant intersection, the features of \pkg{zref-clever} are neither a superset nor a subset of those of \pkg{cleveref}. There are things either of them can do that the other can't. There are also important differences in user interface design. In particular, \pkg{zref-clever} relies heavily on \texttt{key=value} interfaces both for general configuration and for centering in a single user command, \cs{zcref}, as the main entrance for reference making, whose behavior can be modulated by local options. Considering that \pkg{zref} itself offers the \pkg{zref-titleref} module, and that the integration with \pkg{zref-check} allows \pkg{zref-clever} to make context sensitive references, akin to those of \pkg{varioref}, a significant part of the most prominent automation features available to the standard referencing system is thus brought to \pkg{zref}, working under a single consistent underlying infrastructure and user interface. Alas, there are limitations, of course (see \zcref{sec:limitations}). Still, all in all, hopefully \pkg{zref-clever} can be the missing piece for \pkg{zref} to fulfill the promise insinuated by the ``z'' in its name, and be your ``last ref''. \subsection{Warning} \zlabel{sec:warning} This package is in its early days, and should be considered experimental. By this I don't mean I expect it to be ``edgy'', indeed quite a lot of effort has been put into it so that this is not the case. However, during the initial development, I had to make a number of calls for which I felt I had insufficient information: in relation to features, packages, or classes I don't use much, or to languages I don't know well, user needs I found hard to anticipate etc. Hence, the package needs some time, and some use by more adventurous people, until it can settle down with more conviction. In the meantime, polishing the user interface and the infrastructure have a clear priority over backward compatibility. So, if you choose to use this package, you should be ready to accommodate to eventual upstream changes. \section{Loading the package} \zlabel{sec:loading-package} As usual: \begin{zcexample}[escapeinside=`'] \usepackage`\oarg{options}'{zref-clever} \end{zcexample} \subsection{Dependencies} \pkg{zref-clever} requires \pkg{zref}, and \LaTeX{} kernel 2021-11-15, or newer. It also needs \pkg{l3keys2e} and \pkg{ifdraft}. Some packages are leveraged by \pkg{zref-clever} if they are present, but are not loaded by default or required by it, namely: \pkg{hyperref}, \pkg{zref-check}, and \pkg{zref}'s \pkg{zref-titleref}, \pkg{zref-hyperref}, and \pkg{zref-xr} modules. \section{User interface} \zlabel{sec:user-interface} \begin{function}{\zcref} \begin{syntax} \cs{zcref}\meta{*}\oarg{options}\marg{labels} \end{syntax} \end{function} Typesets references to \meta{labels}, given as a comma separated list. When \pkg{hyperref} support is enabled, references will be hyperlinked to their respective anchors, according to options. The starred version of the command does the same as the plain one, just does not form links. The \meta{options} are (mostly) the same as those of the package, and can be given to local effect. The \meta{labels} argument is protected by \pkg{zref}'s \cs{zref@wrapper@babel}, so that it enjoys the same support for \pkg{babel}'s active characters as \pkg{zref} itself does. \begin{function}{\zcpageref} \begin{syntax} \cs{zcpageref}\meta{*}\oarg{options}\marg{labels} \end{syntax} \end{function} Typesets page references to \meta{labels}, given as a comma separated list. It is equivalent to calling \cs{zcref} with the \opt{ref=page} option: \cs{zcref}\texttt{\meta{*}[}\meta{options}\texttt{,ref=page]}\marg{labels}. \begin{function}{\zcsetup} \begin{syntax} \cs{zcsetup}\marg{options} \end{syntax} \end{function} Sets \pkg{zref-clever}'s general options (see \zcref{sec:options, sec:reference-format}). The settings performed by \cs{zcsetup} are local, within the current group. But, of course, it can also be used to global effects if ungrouped, e.g.\ in the preamble. \begin{function}{\zcRefTypeSetup} \begin{syntax} \cs{zcRefTypeSetup}\marg{type}\marg{options} \end{syntax} \end{function} Sets type-specific reference format options (see \zcref{sec:ref-format-opts}). Just as for \cs{zcsetup}, the settings performed by \cs{zcRefTypeSetup} are local, within the current group. \bigskip{} Besides these, user facing commands related to \zcref*[ref=title, noname]{sec:internationalization} are presented in \zcref{sec:internationalization}. Note still that all user commands are defined with \cs{NewDocumentCommand}, which translates into the usual handling of arguments by it and/or processing by \pkg{l3keys}, particularly with regard to brace-stripping and space-trimming. Furthermore, \pkg{zref-clever} loads \pkg{zref}'s \pkg{zref-user} module by default. So you also have its user commands available out of the box, notably \cs{zlabel}, but also \cs{zref} and \cs{zpageref} themselves. \subsection{Options} \zlabel{sec:options} \pkg{zref-clever} is highly configurable, offering a lot of flexibility in typeset results of the references, but it also tries to keep these ``handles'' as convenient and user friendly as possible. To this end, most of what one can do with \pkg{zref-clever} (pretty much all of it), can be achieved directly through the standard and familiar ``comma separated list of \texttt{key=value} options''. There are two main groups of options in \pkg{zref-clever}: ``general options'', which affect the overall behavior of the package, or the reference as a whole; and ``reference format options'', which control the detail of reference formatting, including type-specific and language-specific settings. This section covers the first group (for the second one, see \zcref{sec:ref-format-opts}). General options can be set globally either as package options at load-time (see \zcref{sec:loading-package}) or by means of \cs{zcsetup} in the preamble (see \zcref{sec:user-interface}). They can also be set locally with \cs{zcsetup} along the document or through the optional argument of \cs{zcref} (see \zcref{sec:user-interface}). Most general options can be used in any of these contexts, but that is not necessarily true for all cases, some restrictions may apply, as described in each option's documentation. \bigskip{} \DescribeOption{ref} % \DescribeOption{page} % The \opt{ref} option controls the label property to which \cs{zcref} refers to. It can receive \pkg{zref} properties, as long as they are declared, but notably \texttt{default}, \texttt{page}, \texttt{thecounter} and, if \pkg{zref-titleref} is loaded, \texttt{title}. The package's default is, well, \texttt{default}, which is our standard reference. \texttt{thecounter} is a property set by \pkg{zref-clever} and is similar to \pkg{zref}'s \texttt{default} property, except that it is not affected by the kernel's \cs{labelformat}.\footnote{Technical note: the \texttt{default} property stores \cs{@currentlabel}, while the \texttt{thecounter} property stores \cs{the}\cs{@currentcounter}. The later is exactly what \cs{refstepcounter} uses to build \cs{@currentlabel}, except for the \cs{labelformat} prefix and, hence, has the advantage of being unaffected by it. But the former is \emph{more reliable} since \cs{@currentlabel} is expected to be correct pretty much anywhere whereas, although \cs{refstepcounter} does set \cs{@currentcounter}, it is not everywhere that uses \cs{refstepcounter} for the purpose. In the cases where the references from these two do diverge, \pkg{zref-clever} will likely misbehave (reference type, sorting and compression inevitably depend on a correct \opt{currentcounter}), but using \texttt{default} at least ensures that the reference itself is correct. That said, if you do set \cs{labelformat} for some reason, \texttt{thecounter} may be useful.} By default, reference formatting, sorting, and compression are done according to information inferred from the \emph{current counter} (see \opt{currentcounter} option below). Special treatment in these areas is provided for \texttt{page}, but not for any other properties. The \opt{page} option is a convenience alias for \texttt{ref=page}. \DescribeOption{typeset} % \DescribeOption{noname} % \DescribeOption{noref} % When \cs{zcref} typesets a set of references, each group of references of the same type can be, and by default are, preceded by the type's ``name'', and this is indeed an important feature of \pkg{zref-clever}. This is optional however, and the \opt{typeset} option controls this behavior. It can receive values \texttt{ref}, in which case it typesets only the reference(s), \texttt{name}, in which case it typesets only the name(s), or \texttt{both}, in which case it typesets, well, both of them. Note that, when value \texttt{name} is used, the name is still typeset according to the set of references given to \cs{zcref}. For example, for multiple references, the plural form is used, capitalization options are honored, etc. Also hyperlinking behaves just \emph{as if} the references were present and, depending on the corresponding options, the name may be linked to the first reference of the type group. The \opt{noname} and \opt{noref} options are convenience aliases for \texttt{typeset=ref} and \texttt{typeset=name}, respectively. \DescribeOption{sort} % \DescribeOption{nosort} % The \opt{sort} option controls whether the list of \meta{labels} received as argument by \cs{zcref} should be sorted or not. It is a boolean option, and defaults to \texttt{true}. The \opt{nosort} option is a convenience alias for \texttt{sort=false}. \DescribeOption{typesort} % \DescribeOption{notypesort} % Sorting references of the same type can be done with well defined logical criteria. They either have the same counter or their counters share a clear hierarchical relation (in the resetting behavior), such that a definite sorting rule can be inferred from the label's data. The same is not true for sorting of references of different types. Should ``tables'' come before or after ``figures''? The \pkg{typesort} option allows to specify the sorting priority of different reference types. It receives as value a comma separated list of reference types, specifying that their sorting is to be done in the order of that list. But \opt{typesort} does not need to receive \emph{all} possible reference types. The special value \texttt{\{\{othertypes\}\}} (yes, double braced, one for \pkg{l3keys}, so that the second can make the list) can be placed anywhere along the list, to specify the sort priority of any type not included explicitly. If \texttt{\{othertypes\}} is not present in the list, it is presumed to be at the end of it. Any unspecified types (that is, those falling implicitly or explicitly into the \texttt{\{othertypes\}} category) get sorted between themselves in the order of their first appearance in the label list given as argument to \cs{zcref}. I presume the common use cases will not need to specify \texttt{\{othertypes\}} at all but, for the sake of example, if you just really dislike equations, you could use \texttt{typesort=\{\{\{othertypes\}\}, equation\}}. \opt{typesort}'s default value is \texttt{\{part, chapter, section, paragraph\}}, which places the sectioning reference types first in the list, in their hierarchical order, and leaves everything else to the order of appearance of the labels. The \opt{notypesort} option behaves like \texttt{typesort=\{\{\{othertypes\}\}\}} would do, that is, it sorts all types in the order of the first appearance in the labels' list. \DescribeOption{comp} % \DescribeOption{nocomp} % \cs{zcref} can automatically compress a set of references of the same type into a range, when they occur in immediate sequence. The \opt{comp} controls whether this compression should take place or not. It is a boolean option, and defaults to \texttt{true}. The \opt{nocomp} option is a convenience alias for \texttt{comp=false}. Of course, for better compression results the \opt{sort} is recommended, but the two options are technically independent. \DescribeOption{range} % By default (that is, when the \opt{range} option is not given), \cs{zcref} typesets a complete list of references according to the \meta{labels} it received as argument, and only compresses some of them into ranges if the \opt{comp} option is enabled and if references of the same type occur in immediate sequence. The \opt{range} option makes \cs{zcref} behave differently. Sorting is implied by this option (the \opt{sort} option is disregarded) and, for each reference type group in \meta{labels}, \cs{zcref} builds a range from the first to the last reference in it, even if references in between do not occur in immediate sequence. \cs{zcref} is smart enough, though, to recognize when the first and last references of a type do happen to be contiguous, in which case it typesets a ``pair'', instead of a ``range''. It is a boolean option, and the package's default is \texttt{range=false}. The option given without a value is equivalent to \texttt{range=true} (in the \pkg{l3keys}' jargon, the \emph{option}'s default is \texttt{true}). \DescribeOption{cap} % \DescribeOption{nocap} % \DescribeOption{capfirst} % The \opt{cap} option controls whether the reference type names should be capitalized or not. It is a boolean option, and the package's default is \texttt{cap=false}. The option given without a value is equivalent to \texttt{cap=true}. The \opt{nocap} option is a convenience alias for \texttt{cap=false}. The \opt{capfirst} option ensures that the reference type name of the \emph{first} type block is capitalized, even when \opt{cap} is set to \texttt{false}. \DescribeOption{abbrev} % \DescribeOption{noabbrev} % \DescribeOption{noabbrevfirst} % The \opt{abbrev} option controls whether to use abbreviated reference type names when they are available. It is a boolean option, and the package's default is \texttt{abbrev=false}. The option given without a value is equivalent to \texttt{abbrev=true}. The \opt{noabbrev} option is a convenience alias for \texttt{abbrev=false}. The \opt{noabbrevfirst} ensures that the reference type name of the \emph{first} type block is never abbreviated, even when \opt{abbrev} is set to \texttt{true}. \DescribeOption{S} % \opt{S} for ``Sentence''. The \opt{S} option is a convenience alias for \texttt{capfirst=true, noabbrevfirst=true}, and is intended to be used in references made at the beginning of a sentence. It is highly recommended that you make a habit of using the \opt{S} option for beginning of sentence references. Even if you do happen to be currently using \texttt{cap=true, abbrev=false}, proper semantic markup will ensure you get expected results even if you change your mind in that regard later on. For that reason, it was made short and mnemonic, it can't get any easier. \DescribeOption{hyperref} % The \opt{hyperref} option controls the use of \pkg{hyperref} by \pkg{zref-clever} and takes values \opt{auto}, \opt{true}, \opt{false}. The default value, \opt{auto}, makes \pkg{zref-clever} use \pkg{hyperref} if it is loaded, meaning that references made with \cs{zcref} get hyperlinked to the anchors of their respective \meta{labels}. \opt{true} does the same thing, but warns if \pkg{hyperref} is not loaded (\pkg{hyperref} is never loaded for you). In either of these cases, if \pkg{hyperref} is loaded, module \pkg{zref-hyperref} is also loaded by \pkg{zref-clever}. \opt{false} means not to use \pkg{hyperref} regardless of its availability. This is a preamble only option, but \cs{zcref} provides granular control of hyperlinking by means of its starred version. \DescribeOption{nameinlink} % The \opt{nameinlink} option controls whether the type name should be included in the reference hyperlink or not (provided there is a link, of course). Naturally, the name can only be included in the link of the \emph{first} reference of each type block. \opt{nameinlink} can receive values \texttt{true}, \texttt{false}, \texttt{single}, and \texttt{tsingle}. When the value is \texttt{true} the type name is always included in the hyperlink. When it is \texttt{false} the type name is never included in the link. When the value is \texttt{single}, the type name is included in the link only if \cs{zcref} is typesetting a single reference (not necessarily having received a single label as argument, as they may have been compressed), otherwise, the name is left out of the link. When the value is \texttt{tsingle}, the type name is included in the link for each type block with a single reference, otherwise, it isn't. An example: suppose you make a couple of references to something like \cs{zcref}\texttt{\{chap:chapter1\}} and \cs{zcref}\texttt{\{chap:chapter1, sec:section1, fig:figure1, fig:figure2\}}. The ``figure'' type name will only be included in the hyperlink if \opt{nameinlink} option is set to \texttt{true}. If it is set to \texttt{tsingle}, the first reference will include the name in the link for ``chapter'', as expected, but also in the second reference the ``chapter'' and ``section'' names will be included in their respective links, while that of ``figure'' will not. If the option is set to \texttt{single}, only the name for ``chapter'' in the first reference will be included in the link, while in the second reference none of them will. The package's default is \texttt{nameinlink=tsingle}, and the option given without a value is equivalent to \texttt{nameinlink=true}. \DescribeOption{preposinlink} % The \opt{preposinlink} option controls whether the \opt{refpre} and \opt{refpos} reference format options (see \zcref{sec:ref-format-opts}) are included in the reference hyperlink or not. It is a boolean option. The package's default is \texttt{preposinlink=false}, and the option given without a value is equivalent to \texttt{preposinlink=true}. \DescribeOption{lang} % The \opt{lang} option controls the language used by \cs{zcref} when looking for language-specific reference format options (see \zcref{sec:ref-format-opts}). The default value, \texttt{current}, uses the current language, as defined by \pkg{babel} or \pkg{polyglossia} (or \texttt{english} if none of them is loaded). Value \texttt{main} uses the main document language, as defined by \pkg{babel} or \pkg{polyglossia} (or \texttt{english} if none of them is loaded). The \opt{lang} option also accepts that the language be specified directly by its name, as long as it's a language known by \pkg{zref-clever}. For more details on \zcref*[ref=title,noname]{sec:internationalization}, see \zcref{sec:internationalization}. \DescribeOption{d} % The \opt{d} option sets the declension case, and affects the type name used for typesetting the reference. Whether this option is operative, and which values it accepts, depends on the declared setup for each language. For details, see \zcref{sec:internationalization}. \DescribeOption{nudge} % \DescribeOption{nudgeif} % \DescribeOption{nonudge} % \DescribeOption{sg} % \DescribeOption{g} % This set of options revolving around \opt{nudge} aims to offer some guard against mischievous automation on the part of \pkg{zref-clever} by providing a number of ``nudges'' (compilation time messages) for cases in which you may wish to revise material \emph{surrounding} the reference -- an article, a preposition -- according to the reference typeset results. Useful mainly for languages which inflect the preceding article to gender and/or number, but may be used generally to fine-tune the language and style around the cross-references made with \cs{zcref}. The \opt{nudge} option is the main entrance to this feature and takes values \texttt{true}, \texttt{false}, \texttt{ifdraft}, or \texttt{iffinal}. The first two, respectively, enable or disable the ``nudging'' unconditionally. With \texttt{ifdraft}, \opt{nudge} keeps quiet when option \texttt{draft} is given to \cs{documentclass}, while with \texttt{iffinal}, nudging is only enabled when option \texttt{final} is (explicitly) passed to \cs{documentclass}. The option given without a value is equivalent to \texttt{nudge=true} and the package's default is \texttt{nudge=false}. \opt{nonudge} is a convenience alias for \texttt{nudge=false}, and can be used to silence individual references. The \opt{nudgeif} option controls the events which may trigger a nudge. It takes a comma separated list of elements, and recognizes values \texttt{multitype}, \texttt{comptosing}, \texttt{gender}, and \texttt{all}. The \texttt{multitype} nudge warns when the reference is composed by multiple type blocks (see \zcref{sec:ref-format-opts}). The \texttt{comptosing} nudge let's you know when multiple labels of the same type have been compressed to a singular type name form. It can be combined with the \opt{sg} option, which is the way to tell \cs{zcref} you know it's a singular and so not to nudge if a compression to singular occurs, but to nudge if the contrary occurs, that is, when a plural type name form is employed. The \texttt{gender} nudge must be combined with option \opt{g}, and depends on the language having support for it. In essence language dictionaries can store the gender of each type name (this is done for built-in dictionaries, but can also be done with \cs{zcLanguageSetup} for languages declared to support it). The \opt{g} option let's you specify the gender you expect for that particular reference and the nudge is triggered if there is a mismatch between \opt{g} and the gender for the type name in the dictionary. Both the \texttt{comptosing} and the \texttt{gender} nudges have a type block as its scope. See \zcref{sec:internationalization} for more details and intended use cases of the ``nudging'' feature. \DescribeOption{font} % The \opt{font} option can receive font styling commands to change the appearance of the whole reference list (see also the \opt{namefont} and \opt{reffont} reference format options in \zcref{sec:ref-format-opts}). It does not affect the content of the \opt{note}, however. The option is intended exclusively for commands that only change font attributes: style, family, shape, weight, size, color, etc. Anything else, particularly commands that may generate typeset output, is not supported. Given how package options are handled by \LaTeX{}, the fact that this option receives commands as value means this option \emph{can't} be set at load time, as a package option. If you want to set it globally, use \cs{zcsetup} instead. \DescribeOption{titleref} % The \opt{titleref} option receives no value and, when given, loads \pkg{zref}'s \pkg{zref-titleref} module. This is a preamble only option. \DescribeOption{note} % The \opt{note} option receives as value some text to be typeset at the end of the whole reference list. It is separated from it by \opt{notesep} (see \zcref{sec:ref-format-opts}). \DescribeOption{check} % Provides integration of \pkg{zref-clever} with the \pkg{zref-check} package. In the preamble, the \opt{check} option receives no value and, when given, loads \pkg{zref-check}. In the document body, \opt{check} requires a value, which works exactly like the optional argument of \cs{zcheck}, and can receive both checks and \cs{zcheck}'s options. And the checks are performed for each label in \marg{labels} received as argument by \cs{zcref}. See the User manual of \pkg{zref-check} for details. The checks done by the \opt{check} option in \cs{zcref} comprise the complete reference, including the \opt{note} (see \zcref{sec:ref-format-opts}). If \pkg{zref-check} was not loaded in the preamble, at begin document the option is made no-op and issues a warning. \DescribeOption{countertype} % The \opt{countertype} option allows to specify the ``reference type'' of each counter, which is stored as a label property when the label is set. This ``reference type'' is what determines how a reference to this label will eventually be typeset when it is referred to (see \zcref{sec:reference-types}). A value like \texttt{countertype = \{foo = bar\}} sets the \texttt{foo} counter to use the reference type \texttt{bar}. There's only need to specify the \opt{countertype} for counters whose name differs from that of their type, since \pkg{zref-clever} presumes the type has the same name as the counter, unless otherwise specified. Also, the default value of the option already sets appropriate types for basic \LaTeX{} counters, including those from the standard classes. Setting a counter type to an empty value removes any (explicit) type association for that counter, in practice, this means it then uses a type equal to its name. Since this option only affects how labels are set, it is not available in \cs{zcref}. \DescribeOption{\raisebox{-.2em}{\dbend}\ counterresetters} % \DescribeOption{counterresetby} % The sorting and compression of references done by \cs{zcref} requires that we know the counter associated with a particular label but also information on any counter whose stepping may trigger its resetting, or its ``enclosing counters''. This information is not easily retrievable from the counter itself but is (normally) stored with the counter that does the resetting. The \opt{counterresetters} option adds counter names, received as a comma separated list, to the list of counters \pkg{zref-clever} uses to search for ``enclosing counters'' of the counter for which a label is being set. Unfortunately, not every counter gets reset through the standard machinery for this, including some \LaTeX{} kernel ones (e.g. the \texttt{enumerate} environment counters). For those, there is really no way to retrieve this information directly, so we have to just tell \pkg{zref-clever} about them. And that's what the \opt{counterresetby} option is made for. It receives a comma separated list of \texttt{key=value} pairs, in which \texttt{key} is the counter, and \texttt{value} is its ``enclosing counter'', that is, the counter whose stepping results in its resetting. This is not really an ``option'' in the sense of ``user choice'', it is more of a way to inform \pkg{zref-clever} of something it cannot know or automatically find in general. One cannot place arbitrary information there, or \pkg{zref-clever} can be thoroughly confused. The setting must correspond to the actual resetting behavior of the involved counters. \opt{counterresetby} has precedence over the search done in the \opt{counterresetters} list. The default value of \opt{counterresetters} includes the counters for sectioning commands of the standard classes which, in most cases, should be the relevant ones for cross-referencing purposes. The default value of \opt{counterresetby} includes the \texttt{enumerate} environment counters. So, hopefully, you don't need to ever bother with either of these options. But, if you do, they are here. Use them with caution though. Since these options only affect how labels are set, they are not available in \cs{zcref}. \DescribeOption{\raisebox{.4em}{\dbend}\ currentcounter} % \LaTeX{}'s \cs{refstepcounter} sets two variables which potentially affect the \cs{zlabel} set after it: \cs{@currentlabel} and \cs{@currentcounter}. Actually, traditionally, only the current label was thus stored, the current counter was added to \cs{refstepcounter} somewhat recently (with the 2020-10-01 kernel release). But, since \pkg{zref-clever} relies heavily on the information of what the current counter is, it must set \pkg{zref} to store that information with the label, as it does. As long as the document element we are trying to refer to uses the standard machinery of \cs{refstepcounter} we are on solid ground and can retrieve the correct information. However, it is not always ensured that \cs{@currentcounter} is kept up to date. For example, packages which handle labels specially, for one reason or another, may or may not set \cs{@currentcounter} as required. Considering the addition of \cs{@currentcounter} to \cs{refstepcounter} itself is not that old, it is likely that in a good number of places a reliable \cs{@currentcounter} is not really in place. Therefore, it may happen we need to tell \pkg{zref-clever} what the current counter is in certain circumstances, and that's what \opt{currentcounter} does. The same as with the previous two options, this is not really an ``user choice'' kind of option, but a way to tell \pkg{zref-clever} a piece of information it has no means to retrieve automatically. The setting must correspond to the actual ``current counter'', meaning here ``the counter underlying \cs{@currentlabel}'' in a given situation. Also, when using the \opt{currentcounter} option, make sure the setting is duly grouped because, if set, it has precedence over \cs{@currentcounter} and, contrary to the later, the former is not reset the next time \cs{refstepcounter} runs. Its default value is, quite naturally, \cs{@currentcounter}. Since this option only affects how labels are set, it is not available in \cs{zcref}. \DescribeOption{nocompat} % Some packages, document classes, or LaTeX features may require specific support to work with \pkg{zref-clever} (see \zcref{sec:limitations}). \pkg{zref-clever} tries to make things smoother by covering some of them. Depending on the case, this can take the form of some simple setup for \pkg{zref-clever}, or may involve the use of hooks to external environments or commands and, eventually, a patch or redefinition. By default, all the available compatibility modules are enabled. Should this be undesired or cause any problems in your environment, the option \opt{nocompat} can selectively or completely inhibit their loading. \opt{nocompat} receives a comma separated list of compatibility modules to disable (for the list of available modules and details about each of them, see \zcref{sec:comp-modules}). You can disable all modules by setting \opt{nocompat} without a value (or an empty one). This is a preamble only option. \section{Reference format} \zlabel{sec:reference-format} \subsection{Reference types} \zlabel{sec:reference-types} A ``reference type'' is the basic \pkg{zref-clever} setup unit for specifying how a cross-reference group of a certain kind is to be typeset. Though, usually, it will have the same name as the underlying \LaTeX{} \emph{counter}, they are conceptually different. \pkg{zref-clever} sets up \emph{reference types} and an association between each \emph{counter} and its \emph{type}, it does not define the counters themselves, which are defined by your document. One \emph{reference type} can be associated with one or more \emph{counters}, and a \emph{counter} can be associated with different \emph{types} at different points in your document. But each label is stored with only one \emph{type}, as specified by the counter-type association at the moment it is set, and that determines how the reference to that label is typeset. References to different \emph{counters} of the same \emph{type} are grouped together, and treated alike by \cs{zcref}. A \emph{reference type} may be known to \pkg{zref-clever} when the \emph{counter} it is associated with is not actually defined, and this inconsequential. In practice, the contrary may also happen, a \emph{counter} may be defined but we have no \emph{type} for it, but this must be handled by \pkg{zref-clever} as an error (at least, if we try to refer to it), usually a ``missing name'' error. \pkg{zref-clever} provides default settings for the following reference types: \texttt{part}, \texttt{chapter}, \texttt{section}, \texttt{paragraph}, \texttt{appendix}, \texttt{subappendix}, \texttt{page}, \texttt{line}, \texttt{figure}, \texttt{table}, \texttt{item}, \texttt{footnote}, \texttt{endnote}, \texttt{note}, \texttt{equation}, \texttt{theorem}, \texttt{lemma}, \texttt{corollary}, \texttt{proposition}, \texttt{definition}, \texttt{proof}, \texttt{result}, \texttt{remark}, \texttt{example}, \texttt{algorithm}, \texttt{listing}, \texttt{exercise}, and \texttt{solution}. Therefore, if you are using a language for which \pkg{zref-clever} has built-in support (see \zcref{sec:internationalization}), these reference types are available for use out of the box.\footnote{There may be slight availability differences depending on the language, but \pkg{zref-clever} strives to keep this complete list available for the languages it has built-in dictionaries.} And, in any case, it is always easy to setup custom reference types with \cs{zcRefTypeSetup} or \cs{zcLanguageSetup} (see \zcref{sec:user-interface, sec:reference-format, sec:internationalization}). The association of a \emph{counter} to its \emph{type} is controlled by the \opt{countertype} option. As seen in its documentation, \pkg{zref-clever} presumes the \emph{type} to be the same as the \emph{counter} unless instructed otherwise by that option. This association, as determined by the local value of the option, affects how the \emph{label} is set, which stores the type among its properties. However, when it comes to typesetting, that is from the perspective of \cs{zcref}, only the \emph{type} matters. In other words, how the reference is supposed to be typeset is determined at the point the \emph{label} gets set. In sum, they may be namesakes (or not), but type is type and counter is counter. Indeed, a reference type can be associated with multiple counters because we may want to refer to different document elements, with different \emph{counters}, as a single \emph{type}, with a single name. One prominent case of this are sectioning commands. \cs{section}, \cs{subsection}, and \cs{subsubsection} have each their counter, but we'd like to refer to all of them by ``sections'' and group them together. The same for \cs{paragraph} and \cs{subparagraph}. There are also cases in which we may want to use different \emph{reference types} to refer to document objects sharing the same \emph{counter}. Notably, the environments created with \LaTeX{}'s \cs{newtheorem} command and the \cs{appendix}. One more observation about ``reference types'' is due here. A \emph{type} is not really ``defined'' in the sense a variable or a function is. It is more of a ``string'' which \pkg{zref-clever} uses to look for a whole set of type-specific reference format options (see \zcref{sec:ref-format-opts}). Each of these options individually may be ``set'' or not, ``defined'' or not. And, depending on the setup and the relevant precedence rules for this, some of them may be required and some not. In practice, \pkg{zref-clever} uses the \emph{type} to look for these options when it needs one, and issues a compilation warning when it cannot find a suitable value. \subsection{Reference format options} \zlabel{sec:ref-format-opts} Formatting how the reference is to be typeset is, quite naturally, a big part of the user interface of \pkg{zref-clever}. In this area, we tried to balance ``flexibility'' and ``user friendliness''. But the former does place a big toll overall, since there are indeed many places where tweaking may be desired, and the settings may depend on at least two important dimensions of variation: the reference type and the language. Combination of those necessarily makes for a large set of possibilities. Hence, the attempt here is to provide a rich set of ``handles'' for fine tuning the reference format but, at the same time, do not \emph{require} detailed setup by the users, unless they really want it. With that in mind, we have settled with an user interface for reference formatting which allows settings to be done in different scopes, with more or less overarching effects, and some precedence rules to regulate the relation of settings given in each of these scopes. There are four scopes in which reference formatting can be specified by the user, in the following precedence order: i) as \emph{general options}; ii) as \emph{type-specific options}; iii) as \emph{language-specific and type-specific translations}; and iv) as \emph{default translations} (that is, language-specific but not type-specific). Besides those, there's a fifth \emph{internal} scope, with the least priority of all, a ``fallback'', for the cases where it is meaningful to provide some value, even for an unknown language. The package itself places the default setup for reference formatting at low precedence levels, and the users can easily and conveniently override them as desired. ``General options'' (i) can be given by the user in the optional argument of \cs{zcref}, but also set through \cs{zcsetup} or even, depending on the case, as package options at load-time (see \zcref{sec:options}).\footnote{The use of \cs{zcsetup} for global reference format settings is recommended though. Whether you can use load-time options or not depends on the values of the options: due to how \LaTeX{} handles package options, if the values of the options you are setting include \emph{commands} you can't set them at load-time, and rather \emph{must} use \cs{zcsetup}.} ``Type-specific options'' (ii) are handled by \cs{zcRefTypeSetup} (see \zcref{sec:user-interface}). ``Language-specific translations'', be they ``type-specific'' (iii) or ``default'' (iv) have their user interface in \cs{zcLanguageSetup}, and have their values populated by the package's built-in dictionaries (see \zcref{sec:internationalization}). Not all reference format specifications can be given in all of these scopes, though. Some of them can't be type-specific, others must be type-specific, so the set available in each scope depends on the pertinence of the case. \zcref{tab:reference-format} introduces the available reference format options, which will be discussed in more detail soon, and lists the scopes in which each is available. \begin{table}[htb] \centering \begin{tabular}{l>{\ttfamily}lcccc} \toprule & & General & Type & Type-specific & Default \\ & & options & options & translations & translations \\ & & (i) & (ii) & (iii) & (iv) \\ \midrule Necessarily not & tpairsep & $\bullet$ & & & $\bullet$ \\ type-specific & tlistsep & $\bullet$ & & & $\bullet$ \\ & tlastsep & $\bullet$ & & & $\bullet$ \\ & notesep & $\bullet$ & & & $\bullet$ \\ \addlinespace Possibly & namesep & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ type-specific & pairsep & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ & listsep & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ & lastsep & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ & rangesep & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ & refpre & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ & refpos & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ \addlinespace Necessarily & Name-sg & & $\bullet$ & $\bullet$ & \\ type-specific & name-sg & & $\bullet$ & $\bullet$ & \\ & Name-pl & & $\bullet$ & $\bullet$ & \\ & name-pl & & $\bullet$ & $\bullet$ & \\ & Name-sg-ab & & $\bullet$ & $\bullet$ & \\ & name-sg-ab & & $\bullet$ & $\bullet$ & \\ & Name-pl-ab & & $\bullet$ & $\bullet$ & \\ & name-pl-ab & & $\bullet$ & $\bullet$ & \\ \addlinespace Font & namefont & $\bullet$ & $\bullet$ & & \\ options & reffont & $\bullet$ & $\bullet$ & & \\ \bottomrule \end{tabular} \caption{Reference format options and their scopes} \zlabel{tab:reference-format} \end{table} Understanding the role of each of these reference format options is likely eased by some visual schemes of how \pkg{zref-clever} builds a reference based on the labels' data and the value of these options. Take a \texttt{ref} to be that which a standard \LaTeX{} \cs{ref} would typeset. A \pkg{zref-clever} ``reference block'', or \texttt{ref-block}, is constructed as: \begin{refformat} \item \reffmt{ref-block} \(\equiv\) \item \reffmt{refpre} \reffmt{ref} \reffmt{refpos} \end{refformat} A \texttt{ref-block} is built for \emph{each} label given as argument to \cs{zcref}. When the \meta{labels} argument is comprised of multiple labels, each ``reference type group'', or \texttt{type-group} is potentially made from the combination of single reference blocks, ``reference block pairs'', ``reference block lists'', or ``reference block ranges'', where each is respectively built as: \begin{refformat} \item \reffmt{type-group} is a combination of: \item \reffmt{ref-block} \item \reffmt{ref-block1} \reffmt{pairsep} \reffmt{ref-block2} \item \reffmt{ref-block1} \reffmt{listsep} \reffmt{ref-block2} \reffmt{listsep} \reffmt{ref-block3} \dots{} \par \qquad \dots{}\reffmt{ref-blockN-1} \reffmt{lastsep} \reffmt{ref-blockN} \item \reffmt{ref-block1} \reffmt{rangesep} \reffmt{ref-blockN} \end{refformat} To complete a ``type-block'', a \texttt{type-group} only needs to be accompanied by the ``type name'': \begin{refformat} \item \reffmt{type-block} \(\equiv\) \item \reffmt{type-name} \reffmt{namesep} \reffmt{type-group} \end{refformat} The \texttt{type-name} is determined not by one single reference format option but by the appropriate one among the \opt{[Nn]ame-} options according to the composition of \texttt{type-group} and the general options. The reference format name options are eight in total: \opt{Name-sg}, \opt{name-sg}, \opt{Name-pl}, \opt{name-pl}, \opt{Name-sg-ab}, \opt{name-sg-ab}, \opt{Name-pl-ab}, and \opt{name-pl-ab}. The initial uppercase ``\texttt{N}'' signals the capitalized form of the type name. The \texttt{-sg} suffix stands for singular, while \texttt{-pl} for plural. The \texttt{-ab} is appended to the abbreviated type name form options. When setting up a type, not necessarily all forms need to be provided. \pkg{zref-clever} will always use the non-abbreviated form as a fallback to the abbreviated one, if the later is not available. Hence, if a reference type is not intended to be used with abbreviated names (the most common case), only the basic four forms are needed. Besides that, if you are using the \opt{cap} option, only the capitalized forms will ever be required by \cs{zcref}, so you can get away setting only \opt{Name-sg} and \opt{Name-pl}. You should not do the contrary though, and provide only the non-capitalized forms because, even if you are using the \opt{nocap} option, the capitalized forms will be still required for \opt{capfirst} and \opt{S} options to work. Whatever the case may be, you need not worry too much about being remiss in this area: if \cs{zcref} does lack a name form in any given reference, it will let you know with a compilation warning (and will typeset the usual missing reference sign: ``\textbf{??}''). A complete reference typeset by \cs{zcref} may be comprised of multiple \texttt{type-block}s, in which case the ``type-block-group'' can also be made of single type blocks, ``type block pairs'' or ``type block lists'', where each is respectively built as: \begin{refformat} \item \reffmt{type-block-group} is one of: \item \reffmt{type-block} \item \reffmt{type-block1} \reffmt{tpairsep} \reffmt{type-block2} \item \reffmt{type-block1} \reffmt{tlistsep} \reffmt{type-block2} \reffmt{tlistsep} \reffmt{type-block3} \dots{} \par \qquad \dots{} \reffmt{type-blockN-1} \reffmt{tlastsep} \reffmt{type-blockN} \end{refformat} Finally, since \cs{zcref} can also receive an optional \opt{note}, its full typeset output is built as: \begin{refformat} \item A complete \reffmt{\cs{zcref}} reference: \item \reffmt{type-block-group} \reffmt{notesep} \reffmt{note} \end{refformat} Reference format options can yet be divided in two general categories: i) ``string'' options, the ones which we have seen thus far, as ``building blocks'' of the reference; and ii) ``font'' options, which control font attributes of parts of the reference, namely \opt{namefont} and \opt{reffont}. These options set the font, respectively, for the \texttt{type-name} and for \texttt{ref} (to set the font for the whole reference, see the \opt{font} option in \zcref{sec:options}). ``String'' options is not really a strict denomination for the first category, but this set of options is intended exclusively for typesetting material: things you expect to see in the output of your references. The ``font'' options, on the other hand, are intended exclusively for commands that only change font attributes: style, family, shape, weight, size, color, etc. In either case, anything other than their intended uses is not supported. Finally, a comment about the internal ``fallback'' reference format values mentioned above. These ``last resort'' option values are required by \pkg{zref-clever} for a clear particular case: if the user loads either \pkg{babel} or \pkg{polyglossia}, or explicitly sets a language, with a language that \pkg{zref-clever} does not know and has no dictionary for, it cannot guess what language that is, and thus has to provide some reasonable ``language agnostic'' default, at least for the options for which this makes sense (all the ``string'' options, except for the \texttt{[Nn]ame-} ones). Users do not need to have access to this scope, since they know the language of their document, or know the values they want for those options, and can set them as general options, type-specific options, or language options through the user interface provided for the purpose. But the ``fallback'' options are documented here so that you can recognize when you are getting these values and change them appropriately as desired. Though hopefully reasonable, they may not be what you want. The ``fallback'' option values are the following: \begin{zcexample}[escapeinside=`'] tpairsep = {,`\textvisiblespace{}'} , tlistsep = {,`\textvisiblespace{}'} , tlastsep = {,`\textvisiblespace{}'} , notesep = {`\textvisiblespace{}'} , namesep = {\nobreakspace} , pairsep = {,`\textvisiblespace{}'} , listsep = {,`\textvisiblespace{}'} , lastsep = {,`\textvisiblespace{}'} , rangesep = {\textendash} , refpre = {} , refpos = {} , \end{zcexample} \section{Internationalization} \zlabel{sec:internationalization} \pkg{zref-clever} provides internationalization facilities and integrates with \pkg{babel} and \pkg{polyglossia} to adapt to the languages in use by either of these language packages, or to a language specified directly by the user. This is primarily relevant for reference format options, particularly reference type \emph{names} (though not only, since most reference format options can have language-specific values, or ``translations'', see \zcref{sec:ref-format-opts}). But other features of the package also cater for language specific needs. As far as language selection is concerned, if the language is declared and \pkg{zref-clever} has a built-in ``dictionary'' for it, most use cases will likely be covered by the \opt{lang} option (see \zcref{sec:options}), and its values \texttt{current} and \texttt{main}. When the \opt{lang} option is set to \texttt{current} or \texttt{main}, \pkg{zref-check} will use, respectively, the \emph{current} or \emph{main} language of the document, as defined by \pkg{babel} or \pkg{polyglossia}.\footnote{Technically, \pkg{zref-clever} uses \cs{languagename} and \cs{bbl@main@language} for \pkg{babel}, and \cs{babelname} and \cs{mainbabelname} for \pkg{polyglossia}, which boils down to \pkg{zref-clever} always using \emph{\pkg{babel} names} internally, regardless of which language package is in use. Indeed, an acquainted user will note that \zcref{tab:languages-and-aliases} contains only \pkg{babel} language names.} Users can also set \opt{lang} to a specific language directly, in which case \pkg{babel} and \pkg{polyglossia} are disregarded. \pkg{zref-clever} provides a number of built-in ``dictionaries'', for the languages listed in \zcref{tab:languages-and-aliases}, which also includes the declared aliases to those languages. \pkg{zref-clever}'s ``dictionaries'' are loaded sparingly and lazily. A dictionary for a single language -- that specified by user options in the preamble, which by default is the current document language -- is loaded at \texttt{begindocument}. If any other dictionary is needed, it is loaded on the fly, if and when required. Of course, in either case, conditioned on availability. In sum, \pkg{zref-clever} loads as little as possible, but allows for convenient on the fly loading of dictionaries if the values are indeed required, without users having to worry about it at all. \begin{table} \centering \begin{tabular}{ll} \toprule Language & Aliases \\ \midrule english & american \\ & australian \\ & british \\ & canadian \\ & newzealand \\ & UKenglish \\ & USenglish \\ french & acadian \\ & canadien \\ & francais \\ & frenchb \\ \bottomrule \end{tabular} \quad \begin{tabular}{ll} \toprule Language & Aliases \\ \midrule german & austrian \\ & germanb \\ & ngerman \\ & naustrian \\ & nswissgerman \\ & swissgerman \\ portuguese & brazilian \\ & brazil \\ & portuges \\ spanish & \\ & \\ \bottomrule \end{tabular} \caption{Declared languages and aliases} \zlabel{tab:languages-and-aliases} \end{table} But if the built-in dictionaries do not cover your language, or if you'd like to adjust some of the default language-specific options, this can be done with \cs{zcDeclareLanguage}, \cs{zcDeclareLanguageAlias}, and \cs{zcLanguageSetup}.\footnote{Needless to say, if you'd like to contribute a dictionary or improve an existing one, that is much welcome at \url{https://github.com/gusbrs/zref-clever/issues}.} \begin{function}{\zcDeclareLanguage} \begin{syntax} \cs{zcDeclareLanguage}\oarg{options}\marg{language} \end{syntax} \end{function} Declare a new language for use with \pkg{zref-clever}. If \meta{language} has already been declared, just warn. The \meta{options} argument receives the usual \texttt{key=value} list and recognizes three keys: \opt{declension}, \opt{gender}, and \opt{allcaps}. \opt{declension} receives a coma separated list of valid declension cases for \meta{language}. The first element of the list is considered to be the default case, both for the \opt{d} option in \cs{zcref} and for the \opt{case} option in \cs{zcLanguageSetup}. Similarly, \opt{gender} receives a comma separated list of genders for \meta{language}. The elements in this list are those which are recognized as valid for the language for both the \opt{g} option in \cs{zcref} and the \opt{gender} option in \cs{zcLanguageSetup}. There is no default presumed in this case. Finally, \opt{allcaps} can be used with languages for which nouns must be always capitalized for grammatical reasons. For a language declared with the \opt{allcaps} option, the \opt{cap} reference option (see \zcref{sec:options}) is disregarded, and \cs{zcref} always uses the capitalized type name forms. This means that dictionaries for languages with such a trait can be halved in size, and that user customization for them is simplified, only requiring the capitalized name forms. On the other hand, the non-capitalized \texttt{name-} reference format options are rendered no-op for the language in question. \zcref[S]{tab:language-options} presents an overview of the options in effect for the languages declared by \pkg{zref-clever}. \cs{zcDeclareLanguage} is preamble only. \begin{table} \centering \begin{tabular}{l>{\ttfamily}c>{\ttfamily}c>{\ttfamily}c} \toprule Language & declension & gender & allcaps \\ \midrule english & -- & -- & -- \\ french & -- & f,m & -- \\ german & N,A,D,G & f,m,n & yes \\ portuguese & -- & f,m & -- \\ spanish & -- & f,m & -- \\ \bottomrule \end{tabular} \caption{Options for declared languages} \zlabel{tab:language-options} \end{table} \begin{function}{\zcDeclareLanguageAlias} \begin{syntax} \cs{zcDeclareLanguageAlias}\marg{language alias}\marg{aliased language} \end{syntax} \end{function} Declare \meta{language alias} to be an alias of \meta{aliased language}. \meta{aliased language} must be already known to \pkg{zref-clever}. Once set, the \meta{language alias} is treated by \pkg{zref-clever} as completely equivalent to the \meta{aliased language} for any language specification by the user. \cs{zcDeclareLanguageAlias} is preamble only. \begin{function}{\zcLanguageSetup} \begin{syntax} \cs{zcLanguageSetup}\marg{language}\marg{options} \end{syntax} \end{function} Sets language-specific reference format options for \meta{language} (see \zcref{sec:ref-format-opts}), be they type-specific or not. \meta{language} must be already known to \pkg{zref-clever}. Besides reference format options, \cs{zcLanguageSetup} knows three other keys: \opt{type}, \opt{case}, and \opt{gender}. The first two work like a ``switch'' affecting the options \emph{following} it. For example, if \texttt{type=foo} is given in \meta{options} the options following it will be set as type-specific options for reference type \texttt{foo}. Similarly, after \texttt{case=X} (provided \texttt{X} is a valid declension case for \meta{language}), the following \texttt{[Nn]ame-} options will set values for the \texttt{X} declension case (other reference format options are not affected by \opt{case}). Before the first occurrence of either \opt{type} or \opt{case} default values are set. For \opt{case} this means the default declension case, which is the first element of the list provided to the \opt{declension} option in \cs{zcDeclareLanguage}. For \opt{type} this means ``default translations'', which are language-specific but not type-specific option values (see \zcref{sec:ref-format-opts}). An empty valued \texttt{type=} key can also ``unset'' the type. The \opt{gender} key sets the gender of the current \texttt{type} (provided the value it receives is one of the declared genders for \meta{language}). \cs{zcLanguageSetup} is preamble only. A couple of examples to illustrate the syntax of \cs{zcLanguageSetup}: \begin{zcexample} \zcLanguageSetup{french}{ type = section , gender = f , Name-sg = Section , name-sg = section , Name-pl = Sections , name-pl = sections , } \zcLanguageSetup{german}{ type = section , gender = m , case = N , Name-sg = Abschnitt , Name-pl = Abschnitte , case = A , Name-sg = Abschnitt , Name-pl = Abschnitte , case = D , Name-sg = Abschnitt , Name-pl = Abschnitten , case = G , Name-sg = Abschnitts , Name-pl = Abschnitte , } \end{zcexample} \bigskip{} As already noted, \pkg{zref-clever} has some support for languages with declension. This means mainly the declension of \emph{nouns}, which is used for the reference type names. But some tools are also provided to support the user in getting better results for the text surrounding a reference, particularly for numbered and gendered articles, even if those don't have their typeset output automated. For reference type names, the declension cases for each language must be declared with \cs{zcDeclareLanguage}, and the name reference format options must be provided for each case, which is done for built-in dictionaries of languages which have noun declension, and can be done by the user with \cs{zcLanguageSetup}, as we've seen. \pkg{zref-clever} does not try to guess or infer the case though, you must tell it to \cs{zcref}. And this is done by means of the \opt{d} option (see \zcref{sec:options}). So you may write something like ``\texttt{nach den \cs{zcref}[d=D]\{sec:section-1,sec:section-2\}}'' to get ``nach den Abschnitten 1 und 2''. Or ``\texttt{trotz des \cs{zcref}[d=G]\{eq:theorem-1\}}'' to get ``trotz des Theorems 1''. Regarding the text surrounding the reference -- the inflected article, the passing preposition, etc.\ --, the issue is more delicate. \pkg{zref-clever} cannot and intends not to typeset those for you. But, depending on the language, it is true that the kind of automation provided by \pkg{zref-clever} may betray your best efforts to get a proper surrounding text. Multiple labels passed to \cs{zcref} may result in singular type names, either because the labels are of different types, or because they got compressed into a single reference. References comprised of multiple type blocks may have each a name with a different gender. Or, worse, \opt{tpairsep}, \opt{tpairsep}, and \opt{tlastsep} may not provide a general enough way to separate different type blocks in your language altogether. You may change something in your document that causes a label to change its type, and hence the gender of the type name. A page reference to a couple of floats which were by chance on the same page and all of a sudden no longer are. And so on. In this area, the approach taken by \pkg{zref-clever} is to identify some typical situations in which your attention may be required in reviewing the surrounding text, and signal it at compilation time. Just like bad boxes, for example. This feature can be enabled by the \opt{nudge} option (which is opt-in, see \zcref{sec:options}). There are three ``nudges'' available for this purpose which trigger messages at different events: \opt{multitype}, \opt{comptosing}, and \opt{gender}. \opt{multitype} nudges when a reference is comprised of multiple type blocks. \opt{comptosing} when multiple labels of the same type block have been compressed into a single one and, hence, the type name used is singular. Finally, \opt{gender} nudges when there is a mismatch between the gender specified in \cs{zcref} with the \opt{g} option and the gender of the type name, as stored in the dictionary or language settings, for each type block. Which nudges to use is configurable with the option \opt{nudgeif}. And, if you're sure of the results for a particular \cs{zcref} call, you can always silence the nudges locally with the \opt{nonudge} option. The main reason to watch for multiple type references with the \opt{multitype} nudge is that bundling together automatically a list of type blocks is less smooth an operation than it is for a single reference type. While it arguably works reasonably well for English, even there it is not always flawless, and depending on the language, results may range from ``poor style'' to outright wrong. A typical case would be of that of a language with inflected articles and a reference with multiple types of different genders or numbers. For example, in French, with a standard ``\texttt{au \cs{zcref}\{cha:chapter-3, sec:section-3.1\}}'' we get ``au chapitre 3 et section 3.1'' which sounds ugly, at best. So we may be better off writing instead ``\texttt{au \cs{zcref}\{cha:chapter-3\} et à la \cs{zcref}\{sec:section-3.1\}}''. Or something else, of course. But the general point is that, depending on circumstances and on the language, the results of automating the grouping of multiple reference types, as \pkg{zref-clever} is able to do, may leave things to be desired for. Hence it lets you know when one such case occurs, so that you can review it for best results. The case of the \opt{comptosing} and \opt{gender} nudges is more objective in nature, they respectively signal mismatches of number and gender. When a reference is made with \cs{zcref} to a single label we are sure the type name will be a singular form. However, when \cs{zcref} receives multiple labels of the same type, the type name will normally be a plural, but not necessarily so, since the labels may be compressed into a single one (see the \opt{comp} option in \zcref{sec:options}), in which case the singular is used. The compression of multiple labels into a single reference should be an exception for default references, but not so for \opt{page} references, where it is easy to conceive practical situations where it may occur. Suppose, for example, you have two contiguous floats in your document and make a page reference to both of them. Will they end up in the same page or not? Maybe we know what the current state is, but we cannot know what may happen as the document keeps being edited. As a consequence, we don't know whether that reference will end up having a plural or a singular type name. That given, the logic of the \opt{comptosing} nudge is the following. If we are giving multiple labels to \cs{zcref}, we can \emph{presume} a plural type name, but we get a nudge in case the compression of the labels results in a singular type name form. If one such compression did happen to one of your references, you can use a singular article and then tell \cs{zcref} you did so with option \opt{sg}. The effect of the \opt{sg} option is to inhibit the nudge when a compression to singular occurs, but to do it instead when the compression \emph{ceases} to occur, that is, if we get a plural type name again at some point. The \opt{gender} nudge aims to guard against one particular situation: possible changes of a reference's type. This does not occur by reason of any internal behavior of \pkg{zref-clever}, but it may be caused by changes in the document. You may wish to change one \texttt{theorem} into a \texttt{proposition} and, if you're writing in French or Portuguese, for example, that implies that the reference to it changes gender and the likely preceding article will no longer pass to the reference. The \opt{gender} nudge requires that the gender of each type name and of each reference be explicitly specified. For the type names, this is done for the built-in dictionaries of languages were this matters, and can be done with \cs{zcLanguageSetup} as well. For the references, that is the purpose of the \opt{g} option. When there is a mismatch between the two for any type block, the nudge is triggered. Of couse, this means that the gender markup has to be supplied in the document at each reference. And considering such type changes may not be frequent for you, or considered not particularly problematic, you'll have to balance if doing so is worth it. Still, the feature is available, and it's up to you. \section{How-tos} This section gathers some usage examples, or ``how-tos'', of cases which may require some \pkg{zref-clever} setup, or usage adjustments, and each item is set around a cross-reference ``task'' we'd like to perform with \pkg{zref-clever}. \subsection{Context sensitive references} \zctask{Make cross-references which are sensitive to the relative position between the reference and the label being referred to, à la \pkg{varioref}.} \pkg{varioref}'s \cs{vref} provides for varied references for three different basic cases: when the reference and the label are on the same page, it typesets a plain reference; when the reference and the label are in contiguous pages (next, previous, or facing), it typesets the reference and a fixed string corresponding to the relative position; when the reference and the label are in different non-contiguous pages, it typesets a regular reference and a page reference. The same end result, but with a different user interface concept can be achieved through \pkg{zref-clever}'s integration with \pkg{zref-check}. For this, the later must be loaded, which can be most conveniently done with the \opt{check} option in the preamble. With that in place, the different cases could be covered by the following examples: \begin{zcexample} \zcref[check=thispage]{fig:1} \zcref[check=nextpage,note={on the following page}]{fig:1} \zcref[check=prevpage,note={on the preceding page}]{fig:1} \zcref[check=facing,note={on the facing page}]{fig:1} \zcref[check=pagegap]{fig:1} on \zcpageref{fig:1} \end{zcexample} And, similarly for the cases of \cs{vpageref}: \begin{zcexample} \zcref[noref,check=thispage,note={on this page}]{fig:1} \zcref[noref,check=nextpage,note={on the following page}]{fig:1} \zcref[noref,check=prevpage,note={on the preceding page}]{fig:1} \zcref[noref,check=facing,note={on the facing page}]{fig:1} \zcref[noref,check=pagegap]{fig:1} on \zcpageref{fig:1} \end{zcexample} Since \cs{zcref} can receive multiple labels, and make ranges out of them, it is not difficult to extend these examples to the functionality of \cs{vrefrange} and \cs{vpagerefrange}. Evidently, this does not fully automate the typeset results, but it does automate the checking that the reference context is the intended one. If the relation between the reference and the label does not correspond to the specified one, a compilation warning is issued (according to the options given to \pkg{zref-check}), so that the problem can be easily identified and corrected. See \pkg{zref-check}'s documentation for details, and further available checks. \subsection{\cs{newtheorem}} Since \LaTeX{}'s \cs{newtheorem} allows users to create arbitrary numbered environments, with respective arbitrary counters, the most \pkg{zref-clever} can do in this regard is to provide some ``typical'' built-in reference types to smooth user setup but, in the general case, some user setup may be indeed required. The examples below are equaly valid for \pkg{amsthm}'s \cs{newtheorem} since, even it provides features beyond those available in the kernel, its syntax and underlying relation with counters is pretty much the same. The same for \pkg{ntheorem}. For \pkg{thmtools}' \cs{declaretheorem}, though some adjustments to the examples below may be required, the basic logic is the same (there is no integration with the \opt{Refname}, \opt{refname}, and \opt{label} options, which are targeted to the standard reference system, but you don't actually need them to get things working conveniently). \subsubsection*{Simple case} \zctask{Setup up a new theorem environment created with \cs{newtheorem} to be referred to with \cs{zcref}. The theorem environment does not share its counter with other theorem environments, and one of \pkg{zref-clever} built-in reference types is adequate for my needs.} Suppose you set a ``Lemma'' environment with: \begin{zcexample} \newtheorem{lemma}{Lemma}[section] \end{zcexample} In this case, since \pkg{zref-clever} provides a built-in \texttt{lemma} type (for supported languages) and presumes the reference type to be the same name as the counter, there is no need for setup, and things just work out of the box. So, you can go ahead with: \begin{zchowto}[caption={\cs{newtheorem}, simple case}] \documentclass{article} \usepackage{zref-clever} \newtheorem{lemma}{Lemma}[section] \begin{document} \section{Section 1} \begin{lemma}\zlabel{lemma-1} A lemma. \end{lemma} \zcref{lemma-1} \end{document} \end{zchowto} If, however, you had chosen an environment name which did not happen to coincide with the built-in reference type, all you'd need to do is instruct \pkg{zref-clever} to associate the counter for your environment to the desired type with the \opt{countertype} option: \begin{zchowto}[caption={\cs{newtheorem}, simple case}] \documentclass{article} \usepackage{zref-clever} \zcsetup{countertype={lem=lemma}} \newtheorem{lem}{Lemma}[section] \begin{document} \section{Section 1} \begin{lem}\zlabel{lemma-1} A lemma. \end{lem} \zcref{lemma-1} \end{document} \end{zchowto} \subsubsection*{Shared counter} \zctask{Setup up two new theorem environments created with \cs{newtheorem} to be referred to with \cs{zcref}. The theorem environments share the same counter, and the available \pkg{zref-clever} built-in reference types are adequate for my needs.} In this case, we need to set the \opt{countertype} option in the appropriate contexts, so that the labels of each environment get set with the expected reference type. As we've seen (at \zcref{sec:user-interface}), \cs{zcsetup} has local effects, so it can be issued inside the respective environments for the purpose. Even better, we can leverage the kernel's new hook management system and just set it for all occurrences with \cs{AddToHook}\texttt{\{env/\meta{myenv}/begin\}}. \begin{zchowto}[caption={\cs{newtheorem}, shared counter}] \documentclass{article} \usepackage{zref-clever} \AddToHook{env/mytheorem/begin}{% \zcsetup{countertype={mytheorem=theorem}}} \AddToHook{env/myproposition/begin}{% \zcsetup{countertype={mytheorem=proposition}}} \newtheorem{mytheorem}{Theorem}[section] \newtheorem{myproposition}[mytheorem]{Proposition} \begin{document} \section{Section 1} \begin{mytheorem}\zlabel{theorem-1} A theorem. \end{mytheorem} \begin{myproposition}\zlabel{proposition-1} A proposition. \end{myproposition} \zcref{theorem-1, proposition-1} \end{document} \end{zchowto} \subsubsection*{Custom type} \zctask{Setup up a new theorem environment created with \cs{newtheorem} to be referred to with \cs{zcref}. The theorem environment does not share its counter with other theorem environments, but none of \pkg{zref-clever} built-in reference types is adequate for my needs.} In this case, we need to provide \pkg{zref-clever} with settings pertaining to the custom reference type we'd like to use. Unless you need to typeset your cross-references in multiple languages, in which case you'd require \cs{zcLanguageSetup}, the most convenient way to setup a reference type is \cs{zcRefTypeSetup}. In most cases, what we really need to provide for a custom type are the ``type names'' and other reference format options can rely on default translations already provided by the package (assuming the language is supported). \begin{zchowto}[caption={\cs{newtheorem}, custom type}] \documentclass{article} \usepackage{zref-clever} \newtheorem{myconjecture}{Conjecture}[section] \zcRefTypeSetup{myconjecture}{ Name-sg = Conjecture , name-sg = conjecture , Name-pl = Conjectures , name-pl = conjectures , } \begin{document} \section{Section 1} \begin{myconjecture}\zlabel{conjecture-1} A conjecture. \end{myconjecture} \zcref{conjecture-1} \end{document} \end{zchowto} \subsection{\pkg{newfloat}} \zctask{Setup a new float environment created with \pkg{newfloat} to be referred to with \cs{zcref}. None of \pkg{zref-clever} built-in reference types is adequate for my needs.} The case here is pretty much the same as that for \cs{newtheorem} with a custom type. Hence, we need to setup a corresponding type, for which providing the ``type names'' should normally suffice. Note that, as far as \pkg{zref-clever} is concerned, there's nothing specific to the \pkg{newfloat} package in the setup, the same procedure can be used with \cls{memoir}'s \cs{newfloat} command or with the \pkg{float}, \pkg{floatrow}, and \pkg{trivfloat} packages. \begin{zchowto}[caption={\pkg{newfloat}}] \documentclass{article} \usepackage{newfloat} \DeclareFloatingEnvironment{diagram} \usepackage{zref-clever} \zcRefTypeSetup{diagram}{ Name-sg = Diagram , name-sg = diagram , Name-pl = Diagrams , name-pl = diagrams , } \begin{document} \section{Section 1} \begin{diagram} A diagram. \caption{A diagram} \zlabel{diagram-1} \end{diagram} \zcref{diagram-1} \end{document} \end{zchowto} \subsection{\pkg{amsmath}} \zctask{Make references to \pkg{amsmath} display math environments with \cs{zcref}.} Given how \pkg{amsmath}'s display math environments work, they need to handle \cs{label} specially, and this support is quite hard-wired into the environments, but it is not extended to \cs{zlabel}. \pkg{zref-clever}'s \opt{amsmath} compatibility module provides that a \cs{label} used inside these environments set both a regular \cs{label} and a \cs{zlabel}, so that we can refer to the equations with both referencing systems. Note the use of \cs{zlabel} for \env{subequations} though. For more details, see the description of the \opt{amsmath} compatibility module at \zcref{sec:comp-modules}. \begin{zchowto}[caption={\pkg{amsmath}},label={how:amsmath}] \documentclass{article} \usepackage{amsmath} \usepackage{zref-clever} \usepackage{hyperref} \begin{document} \section{Section 1} \begin{equation}\label{eq:1} A^{(1)}_l =\begin{cases} n!,&\text{if }l =1\\ 0,&\text{otherwise}.\end{cases} \end{equation} \begin{equation*} \tag{foo}\label{eq:2} A^{(1)}_l =\begin{cases} n!,&\text{if }l =1\\ 0,&\text{otherwise}.\end{cases} \end{equation*} \begin{subequations}\zlabel{eq:3} \begin{align} A+B&=B+A\\ C&=D+E\label{eq:3b}\\ E&=F \end{align} \end{subequations} \zcref{eq:1, eq:2, eq:3, eq:3b} \end{document} \end{zchowto} \subsection{\pkg{listings}} \zctask{Make references to a \env{lstlisting} environment from the \pkg{listings} package with \cs{zcref}.} Being \env{lstlisting} a verbatim environment, setting labels inside it requires special treatment. \pkg{zref-clever}'s \opt{listings} compatibility module provides that a label given to the \opt{label} option gets set with both a regular \cs{label} and a \cs{zlabel}, so that we can refer to it with both referencing systems. Setting labels for specific lines of the environment can be done with \cs{zlabel} directly, subject to the same escaping as for the standard \cs{label}. For more details, see the description of the \opt{listings} compatibility module at \zcref{sec:comp-modules}. \begin{zchowto}[caption={\pkg{listings}},label={how:listings},escapeinside=`'] \documentclass{article} \usepackage{listings} \usepackage{zref-clever} \usepackage{hyperref} \begin{document} \section{Section 1} \lstset{escapeinside={(*@}{@*)}, numbers=left, numberstyle=\tiny} \begin{lstlisting}[caption={Useless code}, label=lst:1] for i:=maxint to 0 do begin { do nothing }(*@\zlabel{ln:1.1}@*) end; \end{lstlisting} \zcref{lst:1, ln:1.1} \end{document} \end{zchowto} \subsection{\pkg{enumitem}} \zctask{Setup a custom enumerate environment created with \pkg{enumitem} to be referred to with \cs{zcref}.} Since the \texttt{enumerate} environment's counters are reset at each nesting level, but not with the standard machinery, we have to inform \pkg{zref-clever} of this resetting behavior with the \opt{counterresetby} option. Also, given the naming of the underlying counters is tied with the environment's name and the level's number, we cannot really rely on an implicit counter-type association, and have to set it explicitly with the \opt{countertype} option. \begin{zchowto}[caption={\pkg{enumitem}}] \documentclass{article} \usepackage{zref-clever} \zcsetup{ countertype = { myenumeratei = item , myenumerateii = item , myenumerateiii = item , myenumerateiv = item , } , counterresetby = { myenumerateii = myenumeratei , myenumerateiii = myenumerateii , myenumerateiv = myenumerateiii , } } \usepackage{enumitem} \newlist{myenumerate}{enumerate}{4} \setlist[myenumerate,1]{label=(\arabic*)} \setlist[myenumerate,2]{label=(\Roman*)} \setlist[myenumerate,3]{label=(\Alph*)} \setlist[myenumerate,4]{label=(\roman*)} \begin{document} \begin{myenumerate} \item An item.\zlabel{item-1} \begin{myenumerate} \item An item.\zlabel{item-2} \begin{myenumerate} \item An item.\zlabel{item-3} \begin{myenumerate} \item An item.\zlabel{item-4} \end{myenumerate} \end{myenumerate} \end{myenumerate} \end{myenumerate} \zcref{item-1, item-2, item-3, item-4} \end{document} \end{zchowto} \subsection{\pkg{zref-xr}} \zctask{Make references to labels set in an external document with \cs{zcref}.} \pkg{zref} itself offers this functionality with module \pkg{zref-xr}, and \pkg{zref-clever} is prepared to make use of it. Just a couple of details have to be taken care of, for it to work as intended: i) \pkg{zref-clever} must be loaded in both the main document and the external document, so that the imported labels also contain the properties required by \pkg{zref-clever}; ii) since \cs{zexternaldocument} defines any properties it finds in the labels from the external document when it imports them, it must be called after \pkg{zref-clever} is loaded, otherwise the later will find its own internal properties already defined when it does get loaded, and will justifiably complain. Note as well that the starred version of \cs{zexternaldocument*}, which imports the standard labels from the external document, is not sufficient for \pkg{zref-clever}, since the imported labels will not contain all the required properties. Assuming here \file{documentA.tex} as the main file and \file{documentB.tex} as the external one, and also assuming we just want to refer in ``\texttt{A}'' to the labels from ``\texttt{B}'', and not the contrary, a minimum setup would be the following. \begin{zchowto}[caption={\pkg{zref-xr}},escapeinside=`'] `\hspace*{-1em}\file{documentA.tex}:\vspace{1ex}' \documentclass{article} \usepackage{zref-clever} \usepackage{zref-xr} \zexternaldocument[B-]{documentB} \usepackage{hyperref} \begin{document} \section{Section A1} \zlabel{sec:section-a1} \zcref{sec:section-a1, B-sec:section-b1} \end{document} `\vspace{-1ex}' `\hspace*{-1em}\file{documentB.tex}:\vspace{1ex}' \documentclass{article} \usepackage{zref-clever} \usepackage{hyperref} \begin{document} \section{Section B1} \zlabel{sec:section-b1} \end{document} \end{zchowto} \section{Compatibility} \zlabel{sec:compatibility} \subsection{Limitations} \zlabel{sec:limitations} Being based on \pkg{zref} entails one quite sizable advantage for \pkg{zref-clever}: the extensible referencing system of the former allows \pkg{zref-clever} to store and retrieve the information it needs to work without having to redefine some core \LaTeX{} commands. This alone makes for reduced compatibility problems and less load order issues than the average package in this functionality area. On the other hand, being based on \pkg{zref} also does impair the supported scope of \pkg{zref-clever}. Not because of any particular limitation of either, but because any class or package which implements some special handling for reference labels universally does so aiming at the standard referencing system, and whether specific support for \pkg{zref} is included, or whether things work by spillover of the particular technique employed, is not guaranteed. The limitation here is less one of \pkg{zref-clever} than that of a potencial lack of support for \pkg{zref} itself. Broadly speaking, what \pkg{zref-clever} does is setup \pkg{zref} so that its \cs{zref@newlabel}s contains the information we need using \pkg{zref}'s API. Once the \cs{zlabel} is set correctly, there is little in the way of \pkg{zref-clever}, it can just extract the label's information, again using \pkg{zref}'s API, and do its job. Therefore, the problems that may arise are really in \emph{label setting}. For \cs{zlabel} to be able to set a label with everything \pkg{zref-clever} needs, some conditions must be fulfilled, most of which are pretty much the same as that of a regular label, but not only. As far as my experience goes, the following label setting requirements can be potentially problematic and are not necessarily granted for \cs{zlabel}: \begin{enumerate} \item One must be able to call \cs{zlabel}, directly or indirectly, at the appropriate scope/location so as to set the label. \item When \cs{zlabel} is set, it must see a correct value of \cs{@currentcounter}. \end{enumerate} As to the first, it is not everywhere we technically can set a (z)label. On verbatim-like environments it depends on how they are defined and whether they provide a proper place or option to do so. But other places may be problematic too, for example, \pkg{amsmath} display math environments also handle \cs{label} specially and the same work is not done for \cs{zlabel}. Regarding the second, a correctly set \cs{@currentcounter} is critical for the task of \pkg{zref-clever}: the reference type will depend on that and, consequently, sorting and compression as well, counter resetting behavior information is also retrieved based on it, and so on. Since the 2020-10-01 \LaTeX{} release, \cs{@currentcounter} is set by \cs{refstepcounter} alongside \cs{@currentlabel} and, since the 2021-11-15 release, the support for \cs{@currentcounter} has been further extended in the kernel. Hence, as long as kernel features are involved, or as long as \cs{refstepcounter} is the tool used for the purpose of reference setting, \cs{zlabel} will tend to have all information within its grasp at label setting time. But that's not always the case. For this reason, \pkg{zref-clever} has the option \opt{currentcounter} which at least allows for some viable work-arounds when the value of \cs{@currentcounter} cannot be relied upon. Whether we have a proper opening to set it, depends on the case. Still, \cs{refstepcounter} is ubiquitous enough a tool that we can count on \cs{@currentcounter} most of the time. All in all, most things work, but some things don't. And if the later will eventually work depends essentially on whether support for \pkg{zref} is provided by the relevant packages and classes or not. Or, failing that, whether \pkg{zref-clever} is able to provide some specific support when a reasonable way to do so is within reach. \subsection{Compatibility modules} \zlabel{sec:comp-modules} This section gives a description of each compatibility module provided by \pkg{zref-clever}. These modules intend to smooth the interaction of \LaTeX{} features, document classes, and packages with \pkg{zref-clever} and \pkg{zref}, and they can be selectively or completely disabled with the option \opt{nocompat} (see \zcref{sec:options}). This set is not to be confused with ``the list of packages or classes supported by \pkg{zref-clever}''. In most circumstances, things should just work out of the box, and need no specific handling. These are just the ones for which some special treatment was required. Of course, this effort is bound to be incomplete (see \zcref{sec:limitations}). The purpose of outlining to some extend what the compatibility modules do is twofold. First, some of them require usage adjustments for label setting, which must be somehow conveyed in this documentation. Second, the kind and degree of intervention in external code varies significantly for each module, and since this is an area of potential friction, a minimum of information for the users to judge whether they want to leave these modules enabled or not is due. For this reason, this is also a little technical, but for full details, see the code documentation. \bigskip{} \DescribeOption{appendix} % The \cs{appendix} command provided by many document classes is normally used to change the behavior of the sectioning commands after that point. Usually, depending on the class, the changes that interest us involve using \cs{@Alph} for numbering and \cs{appendixname} for chapter's names. In sum, we'd like to refer to the appendix sectioning commands as ``appendices'' rather than ``chapters'' or ``sections''. Since the sectioning commands are the same as before \cs{appendix}, and so are their underlying counters, we must configure the counter type of the sectioning counters to \texttt{appendix}. And this is what this compatibility module does, and it uses a \pkg{ltcmdhooks} hook on \cs{appendix} for the purpose. Hence, this module applies to any document class or package which provides that command. \DescribeOption{appendices} % This module implements support for the \env{appendices} and \env{subappendices} environments provided by the \pkg{appendix} package, and also by \cls{memoir}. The task is the same as for the \texttt{appendix} module: set proper counter types for the sectioning counters. This module employs environment hooks to \env{appendices} and \env{subappendices} and a command hook to \cs{appendix} for the purpose. \DescribeOption{memoir} % The \cls{memoir} class implements several features with one or another implication for cross-referencing, usually bearing just the standard referencing system in mind, and related mainly to captions, subfloats, and notes. This compatibility module tries to adjust \pkg{zref-clever} to these features with support for the following: i) set counter types for counters \texttt{subfigure}, \texttt{subtable}, and \texttt{poemline} (used in the \env{verse} environment); ii) configure resetting behavior (\opt{counterresetby} option) for \texttt{subfigure} and \texttt{subtable} counters; iii) provide that the \meta{label} arguments to environments \env{sidecaption} and \env{sidecontcaption} and commands \cs{bitwonumcaption}, \cs{bionenumcaption}, and \cs{bicaption} \emph{also} set a \cs{zlabel} of the same name; iv) provide the \pkg{zref} property ``\texttt{subcaption}'' so that we can refer to, for example, \texttt{\cs{zcref}[ref=subcaption]\{subcap-1\}} to emulate the functionality of \cls{memoir}'s \cs{subcaptionref}; v) provide that \cs{footnote}, \cs{verbfootnote}, \cs{sidefootnote}, and \cs{pagenote} get a proper \opt{currentcounter} set; and v) set counter types for counters \texttt{sidefootnote} and \texttt{pagenote}. Naturally, the sheer number of features that required some specific support implies that some gymnastics were needed here. But the most sensitive changes are: i) a local redefinition of \cs{label} inside the environments \env{sidecaption} and \env{sidecontcaption} and the commands \cs{bitwonumcaption}, \cs{bionenumcaption}, and \cs{bicaption}; and ii) the use of \pkg{ltcmdhooks} command hooks on \cs{bitwonumcaption}, \cs{bionenumcaption}, \cs{bicaption}, \cs{@memsubcaption}, \cs{@makefntext}, and \cs{@makesidefntext}. \DescribeOption{KOMA} % The \cls{KOMA-Script} document classes are much more strict than \cls{memoir} in using standard mechanisms for cross-reference related features, so that very little adjustment is needed here. Only the environments \env{captionbeside} and \env{captionofbeside} require special treatment. And, though they do use \cs{refstepcounter} under the hood, since they are environments, we don't get to see reference variables outside them. \cs{@currentlabel} is smuggled out of the group, but not \cs{@currentcounter}, so we must arrange for the later to have a correct value outside the caption environments too. Environment hooks are used for the purpose, essentially setting \cs{@currentcounter} to \cs{@captype}, which would be the value the captioning infrastructure would set for it. \DescribeOption{amsmath} % \pkg{amsmath}'s display math environments have their contents processed twice, once for measuring and the second does the final typesetting. Hence, \pkg{amsmath} needs to handle \cs{label} specially inside these environments, otherwise we'd have duplicate labels all around, and indeed it does redefine \cs{label} locally inside them. Alas, the same treatment is not granted to \cs{zlabel}. However, \cs{label} is set basically to \emph{store} the value of the argument inside the environments, and its global meaning is kept in \cs{ltx@label} which is called at the appropriate time to actually set the label. So, what \pkg{zref-clever} does is redefine \cs{ltx@label} to set \texttt{both} a regular \cs{label} and a \cs{zlabel} for the same \meta{label} (which does not generate a duplicate label problem since the referencing systems are independent). Therefore, you must use \cs{label} (not \cs{zlabel}) inside \pkg{amsmath}'s display math environments, and this compatibility module arranges that you can also refer to that label with \pkg{zref} and, thus, with \cs{zcref} as well. The following environments are subject to this usage restriction: \env{equation}, \env{align}, \env{alignat}, \env{flalign}, \env{xalignat}, \env{gather}, \env{multline}, and their respective starred versions. In particular, the same is not the case for the \env{subequations} environment, inside which \cs{zlabel} works as usual (to refer to the main equation number, that is, right after \texttt{\cs{begin}\{subequations\}}). See the \zcref{how:amsmath} for an usage example. The module also ensures proper \opt{currentcounter} values are in place for the display math environments, for which it uses environment hooks, and sets the font of equation references to \cs{upshape}, following \pkg{amsmath}'s \cs{eqref}. Note, however, that \pkg{zref-clever} is not the only package to redefine \cs{ltx@label}, and compatibility problems may arise if this module is used with such packages or with document classes that do the same. In case of trouble, you can load \pkg{zref-clever} with option \texttt{nocompat=amsmath} and either use the standard referencing system's facilities to refer to \pkg{amsmath}'s equations or check the code documentation for the technique used for this (which is pretty standard) and adapt it to your case. Given that any trouble that may arise here is one of the proper ``timing'' of the redefinition, it should not be particularly complicated to make such adjustments. \DescribeOption{mathtools} % \pkg{mathtools} has a feature to show the numbers only for those equations actually referenced (with \cs{eqref} or \cs{refeq}), which is enabled by the \opt{showonlyrefs} option. This compatibility module adds support for this feature, such that equation references made with \cs{zcref} also get marked as ``referenced'' for \pkg{mathtools}, when the option is active, of course. The module uses a couple of \pkg{mathtools} functions, but does not need to redefine or hook into anything, everything is handled on \pkg{zref-clever}'s side. \DescribeOption{breqn} % This compatibility module only sets proper \opt{currentcounter} values for the environments \env{dgroup}, \env{dmath}, \env{dseries}, and \env{darray}, and uses environment hooks for the purpose. Note that these environments offer a \opt{label} option for label setting, but implements it in a way that is somewhat tricky to grab for our purposes, so we don't do it. However, \pkg{breqn}'s documentation says the following about the use of \cs{label} inside its environments: \textquote{Use of the normal \cs{label} command instead of the \opt{label} option works, I think, most of the time (untested)}. My light testing suggests the same is true for \cs{zlabel}, which can then be used directly in these environments. But the ``second class'' status for this use is the one granted by \pkg{breqn}, there's not much we can do here. If you have any trouble with this, you may wish to check \zcref{wkrnd:breqn}. \DescribeOption{listings} % Being \env{lstlisting}s environments what they are, one cannot simply place a label inside them without special treatment. \pkg{listings} arranges to this by providing a \opt{label} option for setting a label for the whole environment, and a properly escaped label command inside the environment can be used to refer to the line number. While the later can also be used to set a \cs{zlabel} to make line number references, the \opt{label} option is catered to the standard labels exclusively. Hence, this compatibility module uses the same label name -- which luckily and atypically is stored in a variable -- and sets a \cs{zlabel} as well. This is done by using \pkg{listings}' \texttt{PreInit} hook, se we don't have to redefine or tamper with anything for the purpose. Besides this, the module also sets appropriate \opt{countertype}, \opt{counterresetby} and \opt{currentcounter} values for the \pkg{listings}' counters: \texttt{lstlisting} and \texttt{lstnumber}. See the \zcref{how:listings} for an usage example. \DescribeOption{enumitem} % \LaTeX{}'s \env{enumerate} environment requires some special treatment from \pkg{zref-clever}, since its resetting behavior is not stored in the standard way, and the counters' names, given they are numbered by level, do not map to the reference type naturally. This is done by default for the up to four levels of nested \env{enumerate} environments the kernel offers. \pkg{enumitem}, though, allows one to increase this maximum list depth for \env{enumerate} and, if this is done, setup for these deeper nesting levels have also to be taken care of, and that's what this compatibility module does. All settings here are internal to \pkg{zref-clever}, no hooks or redefinitions are needed, we just check the existing pertinent counters at \texttt{begindocument}, and supply settings for them. Of course, this means that only \pkg{enumitem}'s settings done in the preamble will be visible to the module and provided for. \DescribeOption{subcaption} % This compatibility module sets appropriate \opt{countertype} and \opt{counterresetby} for the \texttt{subfigure} and \texttt{subtable} counters, and provides the \pkg{zref} property ``\texttt{subref}'' so that we can refer to, for example, \texttt{\cs{zcref}[ref=subref]\{\meta{label}\}} to emulate the functionality of \cls{subcaption}'s \cs{subref}. The later feature uses the \cs{caption@subtypehook} provided by \pkg{caption} to locally add the \texttt{subref} property to \pkg{zref}'s main property list. \DescribeOption{subfig} % This module just sets appropriate \opt{countertype} and \opt{counterresetby} for the \texttt{subfigure} and \texttt{subtable} counters. \subsection{Work-arounds} \marginpar{\raggedleft\raisebox{-1.5ex}{\dbend}}As should be clear by now, the use of \pkg{zref}'s \cs{zlabel} and thus of \pkg{zref-clever} may occasionally require some adjustments, since it does not enjoy the universal support the standard referencing system does. The compatibility modules presented in \zcref{sec:comp-modules} go a long way in ensuring the user has to worry very little about it, but they cannot hopefully go all the way. Not only because this kind of support will never be exhaustive, but also since, sometimes, given the way certain features are implemented by packages or document classes, there may not be a reasonable way to provide this support, from our side. But, still, most of the time, it is still ``viable'' to get there, if one really wishes to do so. So, this section keeps track of some known recipes, which I don't think belong in \pkg{zref-clever} itself, but which you may choose to use. Note that this list is intended to spare users from having to reinvent the wheel every time someone needs something of the sort, but from \pkg{zref-clever}'s perspective, their status is ``not supported''. \subsection*{\pkg{breqn}} As mentioned in \opt{breqn}'s compatibility module (\zcref{sec:comp-modules}), \pkg{breqn}'s math environments \env{dgroup}, \env{dmath}, \env{dseries}, and \env{darray} offer a \opt{label} option (plus \opt{labelprefix}) for the purpose of label setting. Setting a \cs{zlabel} alongside with a regular \cs{label} based on that option requires redefining some of \pkg{breqn} internals. Also, \pkg{breqn} does not use \cs{refstepcounter} to increment the equation counters and, as a result, fails to set \pkg{hyperref} anchors for the equations (thus affecting standard labels too). The example below also provides to that.\footnote{The later work-around thanks to Heiko Oberdiek, at \url{https://tex.stackexchange.com/a/241150}.} \begin{zcworkaround}[caption={\pkg{breqn}},label={wkrnd:breqn}] \documentclass{article} \usepackage{zref-clever} \usepackage{breqn} \makeatletter \define@key{breqn}{label}{% \edef\next@label{% \noexpand\label{\next@label@pre#1}% \noexpand\zlabel{\next@label@pre#1}}% \let\next@label@pre\@empty} \makeatother \usepackage{hyperref} \usepackage{etoolbox} \makeatletter \patchcmd\eq@setnumber{\stepcounter}{\refstepcounter}{}{% \errmessage{Patching \noexpand\eq@setnumber failed}} \makeatother \begin{document} \section{Section 1} \begin{dmath}[label={eq:1}] f(x)=\frac{1}{x} \condition{for $x\neq 0$} \end{dmath} \begin{dmath}[labelprefix={eq:},label={2}] H_2^2 = x_1^2 + x_1 x_2 + x_2^2 - q_1 - q_2 \end{dmath} \zcref{eq:1, eq:2} \end{document} \end{zcworkaround} Of course, you can always adapt things to your needs and, e.g., make the \opt{label} option set just \cs{zlabel} instead of both labels, or create a separate \opt{zlabel} option. \section{Acknowledgments} \pkg{zref-clever} would not be possible without other people's previous work and help. Heiko Oberdiek's \pkg{zref}, now maintained by the Oberdiek Package Support Group, is the underlying infrastructure of this package. The potential of its basic concept and the solid implementation were certainly among the reasons I've chosen to venture into these waters, to start with. And I believe they will remain one of the main assets of \pkg{zref-clever} as it matures. The name of the package makes no secret that a major inspiration for the kind of ``feel'' I strove to achieve has been Toby Cubitt's \pkg{cleveref}. Indeed, I have been an user of \pkg{cleveref} for several years, and a happy one at that. But the role \pkg{cleveref} played in the development of \pkg{zref-clever} extends beyond the visible influence in the design of user facing functionality. Some technical solutions and, specially, the handling of support for other packages were a valuable reference. Hence, the accumulated experience of \pkg{cleveref} allowed for \pkg{zref-clever} to start on a more solid foundation than would otherwise be the case. The long term efforts of the \LaTeX3 \cs{Team} around \pkg{expl3} and \pkg{xparse} have also left their marks in this package. By implementing powerful tools and smoothing several regular programming tasks, they have certainly reduced my entry barrier to \LaTeX{} programming and enabled me to develop this package with a significantly reduced effort. And, given the constraints of my abilities, the result is no doubt much better than it would be in their absence. Besides these more general acknowledgments, a number of people have contributed to \pkg{zref-clever}, whether they are aware of it or not. Suggestions, ideas, solutions to problems, bug reports or even encouragement were generously provided by: Ulrike Fischer, Frank Mittelbach, Phelype Oleinik, Jonathan P.\ Spratte, Enrico Gregorio, Steven B.\ Segletes, \texttt{@samcarter}, Alan Munn, Florent Rougon, and David Carlisle. If I have inadvertently left anyone off the list I apologize, and please let me know, so that I can correct the oversight. Thank you all very much! \section{Change history} A change log with relevant changes for each version, eventual upgrade instructions, and upcoming changes, is maintained in the package's repository, at \url{https://github.com/gusbrs/zref-clever/blob/main/CHANGELOG.md}. An archive of historical versions of the package is also kept at \url{https://github.com/gusbrs/zref-clever/releases}. \end{document}