From 98810f6d7d064e61186d0ce674c4ee9de47a1f55 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Tue, 8 Feb 2022 03:01:03 +0000 Subject: CTAN sync 202202080301 --- macros/latex/contrib/zref-clever/CHANGELOG.md | 12 +- macros/latex/contrib/zref-clever/MANIFEST.md | 30 + .../latex/contrib/zref-clever/zref-clever-code.pdf | Bin 1175713 -> 1248656 bytes macros/latex/contrib/zref-clever/zref-clever.dtx | 1442 ++++++++++++++++++-- macros/latex/contrib/zref-clever/zref-clever.pdf | Bin 310423 -> 312992 bytes macros/latex/contrib/zref-clever/zref-clever.tex | 250 ++-- 6 files changed, 1511 insertions(+), 223 deletions(-) (limited to 'macros/latex/contrib/zref-clever') diff --git a/macros/latex/contrib/zref-clever/CHANGELOG.md b/macros/latex/contrib/zref-clever/CHANGELOG.md index 74fdc04b4e..66d7e69c3d 100644 --- a/macros/latex/contrib/zref-clever/CHANGELOG.md +++ b/macros/latex/contrib/zref-clever/CHANGELOG.md @@ -1,6 +1,16 @@ # Changelog -## [Unreleased](https://github.com/gusbrs/zref-clever/compare/v0.2.0-alpha...HEAD) +## [Unreleased](https://github.com/gusbrs/zref-clever/compare/v0.2.1-alpha...HEAD) + +## [v0.2.1-alpha](https://github.com/gusbrs/zref-clever/compare/v0.2.0-alpha...v0.2.1-alpha) (2022-02-07) + +### Added +- Option `endrange` for typesetting terse ranges. +- Option `rangetopair` to control behavior of `range` option when a pair + results from building a range. +- Option `vario` to load package `zref-vario`. +- Reference property `subeq` for the `amsmath` and `breqn` compatibility + modules. ## [v0.2.0-alpha](https://github.com/gusbrs/zref-clever/compare/v0.1.2-alpha...v0.2.0-alpha) (2022-01-28) diff --git a/macros/latex/contrib/zref-clever/MANIFEST.md b/macros/latex/contrib/zref-clever/MANIFEST.md index 0c7f6e4af5..50b246d870 100644 --- a/macros/latex/contrib/zref-clever/MANIFEST.md +++ b/macros/latex/contrib/zref-clever/MANIFEST.md @@ -66,8 +66,10 @@ different engines (pdfTeX, XeTeX, LuaTeX, etc.). * zc-LanguageSetup01.lvt * zc-LanguageSetup02.lvt +* zc-LanguageSetup03.lvt * zc-RefTypeSetup01.lvt * zc-RefTypeSetup02.lvt +* zc-RefTypeSetup03.lvt * zc-class-article01.lvt * zc-class-book01.lvt * zc-class-memoir01.lvt @@ -98,6 +100,7 @@ different engines (pdfTeX, XeTeX, LuaTeX, etc.). * zc-howto-newtheorem02.lvt * zc-howto-newtheorem03.lvt * zc-howto-newtheorem04.lvt +* zc-howto-zref-vario01.lvt * zc-howto-zref-xr01.lvt * zc-label-options01.lvt * zc-langfile-dutch01.lvt @@ -127,12 +130,14 @@ different engines (pdfTeX, XeTeX, LuaTeX, etc.). * zc-opt-ref01.lvt * zc-opt-ref02.lvt * zc-opt-titleref01.lvt +* zc-opt-vario01.lvt * zc-precedence-rules01.lvt * zc-sort01.lvt * zc-typeset01.lvt * zc-workaround-breqn01.lvt * zc-zcref-options01.lvt * zc-zcref-options02.lvt +* zc-zcref-options03.lvt * zc-LanguageSetup01.luatex.tlg * zc-LanguageSetup01.luatexdev.tlg * zc-LanguageSetup01.tlg @@ -143,6 +148,11 @@ different engines (pdfTeX, XeTeX, LuaTeX, etc.). * zc-LanguageSetup02.tlg * zc-LanguageSetup02.xetex.tlg * zc-LanguageSetup02.xetexdev.tlg +* zc-LanguageSetup03.luatex.tlg +* zc-LanguageSetup03.luatexdev.tlg +* zc-LanguageSetup03.tlg +* zc-LanguageSetup03.xetex.tlg +* zc-LanguageSetup03.xetexdev.tlg * zc-RefTypeSetup01.luatex.tlg * zc-RefTypeSetup01.luatexdev.tlg * zc-RefTypeSetup01.tlg @@ -153,6 +163,11 @@ different engines (pdfTeX, XeTeX, LuaTeX, etc.). * zc-RefTypeSetup02.tlg * zc-RefTypeSetup02.xetex.tlg * zc-RefTypeSetup02.xetexdev.tlg +* zc-RefTypeSetup03.luatex.tlg +* zc-RefTypeSetup03.luatexdev.tlg +* zc-RefTypeSetup03.tlg +* zc-RefTypeSetup03.xetex.tlg +* zc-RefTypeSetup03.xetexdev.tlg * zc-class-article01.luatex.tlg * zc-class-article01.luatexdev.tlg * zc-class-article01.tlg @@ -303,6 +318,11 @@ different engines (pdfTeX, XeTeX, LuaTeX, etc.). * zc-howto-newtheorem04.tlg * zc-howto-newtheorem04.xetex.tlg * zc-howto-newtheorem04.xetexdev.tlg +* zc-howto-zref-vario01.luatex.tlg +* zc-howto-zref-vario01.luatexdev.tlg +* zc-howto-zref-vario01.tlg +* zc-howto-zref-vario01.xetex.tlg +* zc-howto-zref-vario01.xetexdev.tlg * zc-howto-zref-xr01.luatex.tlg * zc-howto-zref-xr01.luatexdev.tlg * zc-howto-zref-xr01.tlg @@ -408,6 +428,11 @@ different engines (pdfTeX, XeTeX, LuaTeX, etc.). * zc-opt-titleref01.tlg * zc-opt-titleref01.xetex.tlg * zc-opt-titleref01.xetexdev.tlg +* zc-opt-vario01.luatex.tlg +* zc-opt-vario01.luatexdev.tlg +* zc-opt-vario01.tlg +* zc-opt-vario01.xetex.tlg +* zc-opt-vario01.xetexdev.tlg * zc-precedence-rules01.luatex.tlg * zc-precedence-rules01.luatexdev.tlg * zc-precedence-rules01.tlg @@ -434,6 +459,11 @@ different engines (pdfTeX, XeTeX, LuaTeX, etc.). * zc-zcref-options02.tlg * zc-zcref-options02.xetex.tlg * zc-zcref-options02.xetexdev.tlg +* zc-zcref-options03.luatex.tlg +* zc-zcref-options03.luatexdev.tlg +* zc-zcref-options03.tlg +* zc-zcref-options03.xetex.tlg +* zc-zcref-options03.xetexdev.tlg ## TDS manifest diff --git a/macros/latex/contrib/zref-clever/zref-clever-code.pdf b/macros/latex/contrib/zref-clever/zref-clever-code.pdf index 033edad2dc..9e8212f083 100644 Binary files a/macros/latex/contrib/zref-clever/zref-clever-code.pdf and b/macros/latex/contrib/zref-clever/zref-clever-code.pdf differ diff --git a/macros/latex/contrib/zref-clever/zref-clever.dtx b/macros/latex/contrib/zref-clever/zref-clever.dtx index d850476b4c..e6c175d33f 100644 --- a/macros/latex/contrib/zref-clever/zref-clever.dtx +++ b/macros/latex/contrib/zref-clever/zref-clever.dtx @@ -162,7 +162,7 @@ % % Identify the package. % \begin{macrocode} -\ProvidesExplPackage {zref-clever} {2022-01-28} {0.2.0-alpha} +\ProvidesExplPackage {zref-clever} {2022-02-07} {0.2.1-alpha} {Clever LaTeX cross-references based on zref} % \end{macrocode} % @@ -607,6 +607,11 @@ Option~'ref=#1'~requested~\msg_line_context:.~ But~the~property~'#1'~is~not~declared,~falling-back~to~'default'. } +\msg_new:nnn { zref-clever } { endrange-property-undefined } + { + Option~'endrange=#1'~requested~\msg_line_context:.~ + But~the~property~'#1'~is~not~declared,~'endrange'~not~set. + } \msg_new:nnn { zref-clever } { hyperref-preamble-only } { Option~'hyperref'~only~available~in~the~preamble~\msg_line_context:.~ @@ -667,7 +672,7 @@ % exactly twice, but no further to retrieve the proper value. In case the % property is not found, set \meta{tl var} with \meta{default}. % \begin{syntax} -% \cs{@@_extract_default:Nnnn} \Arg{tl val} +% \cs{@@_extract_default:Nnnn} \Arg{tl var} % ~~\Arg{label} \Arg{prop} \Arg{default} % \end{syntax} % \begin{macrocode} @@ -676,7 +681,7 @@ \exp_args:NNNo \exp_args:NNo \tl_set:Nn #1 { \zref@extractdefault {#2} {#3} {#4} } } -\cs_generate_variant:Nn \@@_extract_default:Nnnn { NVnn } +\cs_generate_variant:Nn \@@_extract_default:Nnnn { NVnn , Nnvn } % \end{macrocode} % \end{macro} % @@ -1103,16 +1108,22 @@ % \contributor{Jonathan P.\ Spratte}, aka `Skillmon', and some discussion % about it, including further insights by \contributor{Phelype Oleinik}, see % \url{https://tex.stackexchange.com/q/614690} and -% \url{https://github.com/latex3/latex3/pull/988}. For booleans, the -% situation is different, since they cannot meaningfully receive an empty -% value and the ``key with no value'' is a handy and expected shorthand for +% \url{https://github.com/latex3/latex3/pull/988}. However, Joseph Wright +% seems to particularly dislike this use and the general idea of a ``key with +% no value'' being somehow meaningful for \pkg{l3keys} (e.g. his comments on +% the previous question, and +% \url{https://tex.stackexchange.com/q/632157/#comment1576404_632157}), which +% does make it somewhat risky to rely on this. For booleans, the situation is +% different, since they cannot meaningfully receive an empty value and the +% ``key with no value'' is a handy and expected shorthand for % \texttt{key=true}. Therefore, for reference format option booleans, we use -% a third value ``\texttt{unset}'' for this purpose. In the language files -% the ``unsetting'' behavior is less meaningful, since they only change any -% variable if it is unset to start with, so that unsetting an unset variable -% would be redundant. However, for UI symmetry also in the language files -% keys with no value should not be considered ``empty'' and boolean -% \texttt{unset} values should exist. They are just no-op. +% a third value ``\texttt{unset}'' for this purpose. And similarly for +% ``choice'' options. In the language files the ``unsetting'' behavior is +% less meaningful, since they only change any variable if it is unset to start +% with, so that unsetting an unset variable would be redundant. However, for +% UI symmetry also in the language files keys with no value should not be +% considered ``empty'' and boolean \texttt{unset} values should exist. They +% are just no-op. % % % \begin{macro} @@ -1191,6 +1202,7 @@ { cap , abbrev , + rangetopair , } % \end{macrocode} % Only ``type names'' are ``necessarily type-specific'', which makes them @@ -1880,6 +1892,225 @@ } , } } +\keys_define:nn { zref-clever/langfile } + { + endrange .code:n = + { + \str_case:nnF {#1} + { + { ref } + { + \tl_if_empty:NTF \l_@@_setup_type_tl + { + \@@_opt_tl_gset_if_new:cn + { + \@@_opt_varname_lang_default:enn + { \l_@@_setup_language_tl } + { endrangefunc } { tl } + } + { } + \@@_opt_tl_gset_if_new:cn + { + \@@_opt_varname_lang_default:enn + { \l_@@_setup_language_tl } + { endrangeprop } { tl } + } + { } + } + { + \@@_opt_tl_gset_if_new:cn + { + \@@_opt_varname_lang_type:eenn + { \l_@@_setup_language_tl } + { \l_@@_setup_type_tl } + { endrangefunc } { tl } + } + { } + \@@_opt_tl_gset_if_new:cn + { + \@@_opt_varname_lang_type:eenn + { \l_@@_setup_language_tl } + { \l_@@_setup_type_tl } + { endrangeprop } { tl } + } + { } + } + } + + { stripprefix } + { + \tl_if_empty:NTF \l_@@_setup_type_tl + { + \@@_opt_tl_gset_if_new:cn + { + \@@_opt_varname_lang_default:enn + { \l_@@_setup_language_tl } + { endrangefunc } { tl } + } + { @@_get_endrange_stripprefix } + \@@_opt_tl_gset_if_new:cn + { + \@@_opt_varname_lang_default:enn + { \l_@@_setup_language_tl } + { endrangeprop } { tl } + } + { } + } + { + \@@_opt_tl_gset_if_new:cn + { + \@@_opt_varname_lang_type:eenn + { \l_@@_setup_language_tl } + { \l_@@_setup_type_tl } + { endrangefunc } { tl } + } + { @@_get_endrange_stripprefix } + \@@_opt_tl_gset_if_new:cn + { + \@@_opt_varname_lang_type:eenn + { \l_@@_setup_language_tl } + { \l_@@_setup_type_tl } + { endrangeprop } { tl } + } + { } + } + } + + { pagecomp } + { + \tl_if_empty:NTF \l_@@_setup_type_tl + { + \@@_opt_tl_gset_if_new:cn + { + \@@_opt_varname_lang_default:enn + { \l_@@_setup_language_tl } + { endrangefunc } { tl } + } + { @@_get_endrange_pagecomp } + \@@_opt_tl_gset_if_new:cn + { + \@@_opt_varname_lang_default:enn + { \l_@@_setup_language_tl } + { endrangeprop } { tl } + } + { } + } + { + \@@_opt_tl_gset_if_new:cn + { + \@@_opt_varname_lang_type:eenn + { \l_@@_setup_language_tl } + { \l_@@_setup_type_tl } + { endrangefunc } { tl } + } + { @@_get_endrange_pagecomp } + \@@_opt_tl_gset_if_new:cn + { + \@@_opt_varname_lang_type:eenn + { \l_@@_setup_language_tl } + { \l_@@_setup_type_tl } + { endrangeprop } { tl } + } + { } + } + } + + { pagecomp2 } + { + \tl_if_empty:NTF \l_@@_setup_type_tl + { + \@@_opt_tl_gset_if_new:cn + { + \@@_opt_varname_lang_default:enn + { \l_@@_setup_language_tl } + { endrangefunc } { tl } + } + { @@_get_endrange_pagecomptwo } + \@@_opt_tl_gset_if_new:cn + { + \@@_opt_varname_lang_default:enn + { \l_@@_setup_language_tl } + { endrangeprop } { tl } + } + { } + } + { + \@@_opt_tl_gset_if_new:cn + { + \@@_opt_varname_lang_type:eenn + { \l_@@_setup_language_tl } + { \l_@@_setup_type_tl } + { endrangefunc } { tl } + } + { @@_get_endrange_pagecomptwo } + \@@_opt_tl_gset_if_new:cn + { + \@@_opt_varname_lang_type:eenn + { \l_@@_setup_language_tl } + { \l_@@_setup_type_tl } + { endrangeprop } { tl } + } + { } + } + } + + { unset } + { } + } + { + \tl_if_empty:nTF {#1} + { + \msg_info:nnn { zref-clever } + { endrange-property-undefined } {#1} + } + { + \zref@ifpropundefined {#1} + { + \msg_info:nnn { zref-clever } + { endrange-property-undefined } {#1} + } + { + \tl_if_empty:NTF \l_@@_setup_type_tl + { + \@@_opt_tl_gset_if_new:cn + { + \@@_opt_varname_lang_default:enn + { \l_@@_setup_language_tl } + { endrangefunc } { tl } + } + { @@_get_endrange_property } + \@@_opt_tl_gset_if_new:cn + { + \@@_opt_varname_lang_default:enn + { \l_@@_setup_language_tl } + { endrangeprop } { tl } + } + {#1} + } + { + \@@_opt_tl_gset_if_new:cn + { + \@@_opt_varname_lang_type:eenn + { \l_@@_setup_language_tl } + { \l_@@_setup_type_tl } + { endrangefunc } { tl } + } + { @@_get_endrange_property } + \@@_opt_tl_gset_if_new:cn + { + \@@_opt_varname_lang_type:eenn + { \l_@@_setup_language_tl } + { \l_@@_setup_type_tl } + { endrangeprop } { tl } + } + {#1} + } + } + } + } + } , + endrange .value_required:n = true , + } \seq_map_inline:Nn \c_@@_rf_opts_tl_type_names_seq { @@ -2167,7 +2398,9 @@ % branch if it is not (insightful comments by \contributor{Ulrike Fischer} at % \url{https://github.com/ho-tex/zref/issues/13}). Therefore, before adding % anything to \cs{l_@@_ref_property_tl}, check if first here with -% \cs{zref@ifpropundefined}: close it at the door. +% \cs{zref@ifpropundefined}: close it at the door. We must also control for +% an empty value, since ``empty'' passes both \cs{zref@ifpropundefined} and +% \cs{zref@ifrefcontainsprop}. % % % \begin{macrocode} @@ -2176,12 +2409,21 @@ { ref .code:n = { - \zref@ifpropundefined {#1} + \tl_if_empty:nTF {#1} { - \msg_warning:nnn { zref-clever } { zref-property-undefined } {#1} + \msg_warning:nnn { zref-clever } + { zref-property-undefined } {#1} \tl_set:Nn \l_@@_ref_property_tl { default } } - { \tl_set:Nn \l_@@_ref_property_tl {#1} } + { + \zref@ifpropundefined {#1} + { + \msg_warning:nnn { zref-clever } + { zref-property-undefined } {#1} + \tl_set:Nn \l_@@_ref_property_tl { default } + } + { \tl_set:Nn \l_@@_ref_property_tl {#1} } + } } , ref .initial:n = default , ref .value_required:n = true , @@ -2286,7 +2528,443 @@ % % % -% \subsubsection*{\opt{range} option} +% \subsubsection*{\opt{endrange} option} +% +% The working of \opt{endrange} option depends on two underlying option values +% / variables: \texttt{endrangefunc} and \texttt{endrangeprop}. +% \texttt{endrangefunc} is the more general one, and \texttt{endrangeprop} is +% used when the first is set to \cs{@@_get_endrange_property:VVN}, which is +% the case when the user is setting \opt{endrange} to an arbitrary \pkg{zref} +% property, instead of one of the \cs{str_case:nn} matches. +% +% \texttt{endrangefunc} \emph{must} receive three arguments and, more +% specifically, its signature \emph{must} be \texttt{VVN}. For this reason, +% \texttt{endrangefunc} should be stored without the signature, which is +% added, and hard-coded, at the calling place. The first argument is +% \meta{beg range label}, the second \meta{end range label}, and the last +% \meta{tl var to set}. Of course, \meta{tl var to set} must be set to a +% proper value, and that's the main task of the function. +% \texttt{endrangefunc} must also handle the case where +% \cs{zref@ifrefcontainsprop} is false, since \cs{@@_get_ref_endrange:nnN} +% cannot take care of that. For this purpose, it may set \meta{tl var to set} +% to the special value \texttt{zc@missingproperty}, to signal a missing +% property for \cs{@@_get_ref_endrange:nnN}. +% +% An empty \texttt{endrangefunc} signals that no processing is to be made to +% the end range reference, that is, that it should be treated like any other +% one, as defined by the \opt{ref} option. This may happen either because +% \opt{endrange} was never set for the reference type, and empty is the value +% ``returned'' by \cs{@@_get_rf_opt_tl:nnnN} for options not set, or because +% \opt{endrange} was set to \texttt{ref} at some scope which happens to get +% precedence. +% +% One thing I was divided about in this functionality was whether to +% (x-)expand the references before processing them, when such processing is +% required. At first sight, it makes sense to do so, since we are aiming at +% ``removing common parts'' as close as possible to the printed representation +% of the references (\pkg{cleveref} does expand them in \cs{crefstripprefix}). +% On the other hand, this brings some new challenges: if a fragile command +% gets there, we are in trouble; also, if a protected one gets there, though +% things won't break as badly, we may ``strip'' the macro and stay with +% different arguments, which will then end up in the input stream. I think +% \pkg{biblatex} is a good reference here, and it offers \cs{NumCheckSetup}, +% \cs{NumsCheckSetup}, and \cs{PagesCheckSetup} aimed at locally redefining +% some commands which may interfere with the processing. This is a good idea, +% thus we offer a similar hook for the same purpose: \texttt{endrange-setup}. +% +% \begin{macrocode} +\NewHook { zref-clever/endrange-setup } +% \end{macrocode} +% +% +% \begin{macrocode} +\keys_define:nn { zref-clever/reference } + { + endrange .code:n = + { + \str_case:nnF {#1} + { + { ref } + { + \tl_clear:c + { + \@@_opt_varname_general:nn + { endrangefunc } { tl } + } + \tl_clear:c + { + \@@_opt_varname_general:nn + { endrangeprop } { tl } + } + } + + { stripprefix } + { + \tl_set:cn + { + \@@_opt_varname_general:nn + { endrangefunc } { tl } + } + { @@_get_endrange_stripprefix } + \tl_clear:c + { + \@@_opt_varname_general:nn + { endrangeprop } { tl } + } + } + + { pagecomp } + { + \tl_set:cn + { + \@@_opt_varname_general:nn + { endrangefunc } { tl } + } + { @@_get_endrange_pagecomp } + \tl_clear:c + { + \@@_opt_varname_general:nn + { endrangeprop } { tl } + } + } + + { pagecomp2 } + { + \tl_set:cn + { + \@@_opt_varname_general:nn + { endrangefunc } { tl } + } + { @@_get_endrange_pagecomptwo } + \tl_clear:c + { + \@@_opt_varname_general:nn + { endrangeprop } { tl } + } + } + + { unset } + { + \@@_opt_tl_unset:c + { + \@@_opt_varname_general:nn + { endrangefunc } { tl } + } + \@@_opt_tl_unset:c + { + \@@_opt_varname_general:nn + { endrangeprop } { tl } + } + } + } + { + \tl_if_empty:nTF {#1} + { + \msg_warning:nnn { zref-clever } + { endrange-property-undefined } {#1} + } + { + \zref@ifpropundefined {#1} + { + \msg_warning:nnn { zref-clever } + { endrange-property-undefined } {#1} + } + { + \tl_set:cn + { + \@@_opt_varname_general:nn + { endrangefunc } { tl } + } + { @@_get_endrange_property } + \tl_set:cn + { + \@@_opt_varname_general:nn + { endrangeprop } { tl } + } + {#1} + } + } + } + } , + endrange .value_required:n = true , + } +% \end{macrocode} +% +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_get_endrange_property:nnN #1#2#3 + { + \tl_if_empty:NTF \l_@@_endrangeprop_tl + { + \zref@ifrefcontainsprop {#2} { \l_@@_ref_property_tl } + { + \@@_extract_default:Nnvn #3 + {#2} { l_@@_ref_property_tl } { } + } + { \tl_set:Nn #3 { zc@missingproperty } } + } + { + \zref@ifrefcontainsprop {#2} { \l_@@_endrangeprop_tl } + { +% \end{macrocode} +% If the range came about by normal compression, we already know the beginning +% and the end references share the same ``form'' and ``prefix'' (this is +% ensured at \cs{@@_labels_in_sequence:nn}), but the same is not true if the +% \opt{range} option is being used, in which case, we have to check the +% replacement \cs{l_@@_ref_property_tl} by \cs{l_@@_endrangeprop_tl} is really +% granted. +% \begin{macrocode} + \bool_if:NTF \l_@@_typeset_range_bool + { + \group_begin: + \bool_set_false:N \l_tmpa_bool + \exp_args:Nxx \tl_if_eq:nnT + { + \@@_extract_unexp:nnn + {#1} { externaldocument } { } + } + { + \@@_extract_unexp:nnn + {#2} { externaldocument } { } + } + { + \tl_if_eq:NnTF \l_@@_ref_property_tl { page } + { + \exp_args:Nxx \tl_if_eq:nnT + { + \@@_extract_unexp:nnn + {#1} { zc@pgfmt } { } + } + { + \@@_extract_unexp:nnn + {#2} { zc@pgfmt } { } + } + { \bool_set_true:N \l_tmpa_bool } + } + { + \exp_args:Nxx \tl_if_eq:nnT + { + \@@_extract_unexp:nnn + {#1} { zc@counter } { } + } + { + \@@_extract_unexp:nnn + {#2} { zc@counter } { } + } + { + \exp_args:Nxx \tl_if_eq:nnT + { + \@@_extract_unexp:nnn + {#1} { zc@enclval } { } + } + { + \@@_extract_unexp:nnn + {#2} { zc@enclval } { } + } + { \bool_set_true:N \l_tmpa_bool } + } + } + } + \bool_if:NTF \l_tmpa_bool + { + \@@_extract_default:Nnvn \l_tmpb_tl + {#2} { l_@@_endrangeprop_tl } { } + } + { + \zref@ifrefcontainsprop + {#2} { \l_@@_ref_property_tl } + { + \@@_extract_default:Nnvn \l_tmpb_tl + {#2} { l_@@_ref_property_tl } { } + } + { \tl_set:Nn \l_tmpb_tl { zc@missingproperty } } + } + \exp_args:NNNV + \group_end: + \tl_set:Nn #3 \l_tmpb_tl + } + { + \@@_extract_default:Nnvn #3 + {#2} { l_@@_endrangeprop_tl } { } + } + } + { + \zref@ifrefcontainsprop {#2} { \l_@@_ref_property_tl } + { + \@@_extract_default:Nnvn #3 + {#2} { l_@@_ref_property_tl } { } + } + { \tl_set:Nn #3 { zc@missingproperty } } + } + } + } +\cs_generate_variant:Nn \@@_get_endrange_property:nnN { VVN } +% \end{macrocode} +% +% +% +% For the technique for smuggling the assignment out of the group, see +% \contributor{Enrico Gregorio}'s answer at +% \url{https://tex.stackexchange.com/a/56314}. +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_get_endrange_stripprefix:nnN #1#2#3 + { + \zref@ifrefcontainsprop {#2} { \l_@@_ref_property_tl } + { + \group_begin: + \UseHook { zref-clever/endrange-setup } + \tl_set:Nx \l_tmpa_tl + { + \@@_extract:nnn + {#1} { \l_@@_ref_property_tl } { } + } + \tl_set:Nx \l_tmpb_tl + { + \@@_extract:nnn + {#2} { \l_@@_ref_property_tl } { } + } + \bool_set_false:N \l_tmpa_bool + \bool_until_do:Nn \l_tmpa_bool + { + \exp_args:Nxx \tl_if_eq:nnTF + { \tl_head:V \l_tmpa_tl } { \tl_head:V \l_tmpb_tl } + { + \tl_set:Nx \l_tmpa_tl { \tl_tail:V \l_tmpa_tl } + \tl_set:Nx \l_tmpb_tl { \tl_tail:V \l_tmpb_tl } + \tl_if_empty:NT \l_tmpb_tl + { \bool_set_true:N \l_tmpa_bool } + } + { \bool_set_true:N \l_tmpa_bool } + } + \exp_args:NNNV + \group_end: + \tl_set:Nn #3 \l_tmpb_tl + } + { \tl_set:Nn #3 { zc@missingproperty } } + } +\cs_generate_variant:Nn \@@_get_endrange_stripprefix:nnN { VVN } +% \end{macrocode} +% +% +% \begin{macro}{\@@_is_integer_rgx:n} +% Test if argument is composed only of digits (adapted from +% \url{https://tex.stackexchange.com/a/427559}). +% \begin{macrocode} +\prg_new_protected_conditional:Npnn + \@@_is_integer_rgx:n #1 { F , TF } + { + \regex_match:nnTF { \A\d+\Z } {#1} + { \prg_return_true: } + { \prg_return_false: } + } +\prg_generate_conditional_variant:Nnn + \@@_is_integer_rgx:n { V } { F , TF } +% \end{macrocode} +% \end{macro} +% +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_get_endrange_pagecomp:nnN #1#2#3 + { + \zref@ifrefcontainsprop {#2} { \l_@@_ref_property_tl } + { + \group_begin: + \UseHook { zref-clever/endrange-setup } + \tl_set:Nx \l_tmpa_tl + { + \@@_extract:nnn + {#1} { \l_@@_ref_property_tl } { } + } + \tl_set:Nx \l_tmpb_tl + { + \@@_extract:nnn + {#2} { \l_@@_ref_property_tl } { } + } + \bool_set_false:N \l_tmpa_bool + \@@_is_integer_rgx:VTF \l_tmpa_tl + { + \@@_is_integer_rgx:VF \l_tmpb_tl + { \bool_set_true:N \l_tmpa_bool } + } + { \bool_set_true:N \l_tmpa_bool } + \bool_until_do:Nn \l_tmpa_bool + { + \exp_args:Nxx \tl_if_eq:nnTF + { \tl_head:V \l_tmpa_tl } { \tl_head:V \l_tmpb_tl } + { + \tl_set:Nx \l_tmpa_tl { \tl_tail:V \l_tmpa_tl } + \tl_set:Nx \l_tmpb_tl { \tl_tail:V \l_tmpb_tl } + \tl_if_empty:NT \l_tmpb_tl + { \bool_set_true:N \l_tmpa_bool } + } + { \bool_set_true:N \l_tmpa_bool } + } + \exp_args:NNNV + \group_end: + \tl_set:Nn #3 \l_tmpb_tl + } + { \tl_set:Nn #3 { zc@missingproperty } } + } +\cs_generate_variant:Nn \@@_get_endrange_pagecomp:nnN { VVN } +% \end{macrocode} +% +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_get_endrange_pagecomptwo:nnN #1#2#3 + { + \zref@ifrefcontainsprop {#2} { \l_@@_ref_property_tl } + { + \group_begin: + \UseHook { zref-clever/endrange-setup } + \tl_set:Nx \l_tmpa_tl + { + \@@_extract:nnn + {#1} { \l_@@_ref_property_tl } { } + } + \tl_set:Nx \l_tmpb_tl + { + \@@_extract:nnn + {#2} { \l_@@_ref_property_tl } { } + } + \bool_set_false:N \l_tmpa_bool + \@@_is_integer_rgx:VTF \l_tmpa_tl + { + \@@_is_integer_rgx:VF \l_tmpb_tl + { \bool_set_true:N \l_tmpa_bool } + } + { \bool_set_true:N \l_tmpa_bool } + \bool_until_do:Nn \l_tmpa_bool + { + \exp_args:Nxx \tl_if_eq:nnTF + { \tl_head:V \l_tmpa_tl } { \tl_head:V \l_tmpb_tl } + { + \bool_lazy_or:nnTF + { \int_compare_p:nNn { \l_tmpb_tl } > { 99 } } + { \int_compare_p:nNn { \tl_head:V \l_tmpb_tl } = { 0 } } + { + \tl_set:Nx \l_tmpa_tl { \tl_tail:V \l_tmpa_tl } + \tl_set:Nx \l_tmpb_tl { \tl_tail:V \l_tmpb_tl } + } + { \bool_set_true:N \l_tmpa_bool } + } + { \bool_set_true:N \l_tmpa_bool } + } + \exp_args:NNNV + \group_end: + \tl_set:Nn #3 \l_tmpb_tl + } + { \tl_set:Nn #3 { zc@missingproperty } } + } +\cs_generate_variant:Nn \@@_get_endrange_pagecomptwo:nnN { VVN } +% \end{macrocode} +% +% +% +% \subsubsection*{\opt{range} and \opt{rangetopair} options} +% +% The \opt{rangetopair} option is being handled with other reference format +% option booleans at \cs{c_@@_rf_opts_bool_maybe_type_specific_seq}. % % \begin{macrocode} \bool_new:N \l_@@_typeset_range_bool @@ -2753,6 +3431,28 @@ % \end{macrocode} % % +% \subsubsection*{\opt{vario} option} +% +% \begin{macrocode} +\keys_define:nn { zref-clever/reference } + { + vario .code:n = { \RequirePackage { zref-vario } } , + vario .value_forbidden:n = true , + } +\AddToHook { begindocument } + { + \keys_define:nn { zref-clever/reference } + { + vario .code:n = + { + \msg_warning:nnn { zref-clever } + { option-preamble-only } { vario } + } + } + } +% \end{macrocode} +% +% % \subsubsection*{\opt{note} option} % % \begin{macrocode} @@ -3244,6 +3944,7 @@ { \tl_set:Nn \l_@@_setup_type_tl {#1} \keys_set:nn { zref-clever/typesetup } {#2} + \tl_clear:N \l_@@_setup_type_tl } % \end{macrocode} % \end{macro} @@ -3271,24 +3972,136 @@ #1 .default:x = \c_novalue_tl , #1 .code:n = { - \tl_if_novalue:nTF {##1} + \tl_if_novalue:nTF {##1} + { + \@@_opt_tl_unset:c + { + \@@_opt_varname_type:enn + { \l_@@_setup_type_tl } {#1} { tl } + } + } + { + \tl_set:cn + { + \@@_opt_varname_type:enn + { \l_@@_setup_type_tl } {#1} { tl } + } + {##1} + } + } , + } + } +\keys_define:nn { zref-clever/typesetup } + { + endrange .code:n = + { + \str_case:nnF {#1} + { + { ref } + { + \tl_clear:c + { + \@@_opt_varname_type:enn + { \l_@@_setup_type_tl } { endrangefunc } { tl } + } + \tl_clear:c + { + \@@_opt_varname_type:enn + { \l_@@_setup_type_tl } { endrangeprop } { tl } + } + } + + { stripprefix } + { + \tl_set:cn + { + \@@_opt_varname_type:enn + { \l_@@_setup_type_tl } { endrangefunc } { tl } + } + { @@_get_endrange_stripprefix } + \tl_clear:c + { + \@@_opt_varname_type:enn + { \l_@@_setup_type_tl } { endrangeprop } { tl } + } + } + + { pagecomp } + { + \tl_set:cn + { + \@@_opt_varname_type:enn + { \l_@@_setup_type_tl } { endrangefunc } { tl } + } + { @@_get_endrange_pagecomp } + \tl_clear:c + { + \@@_opt_varname_type:enn + { \l_@@_setup_type_tl } { endrangeprop } { tl } + } + } + + { pagecomp2 } + { + \tl_set:cn + { + \@@_opt_varname_type:enn + { \l_@@_setup_type_tl } { endrangefunc } { tl } + } + { @@_get_endrange_pagecomptwo } + \tl_clear:c + { + \@@_opt_varname_type:enn + { \l_@@_setup_type_tl } { endrangeprop } { tl } + } + } + + { unset } + { + \@@_opt_tl_unset:c + { + \@@_opt_varname_type:enn + { \l_@@_setup_type_tl } { endrangefunc } { tl } + } + \@@_opt_tl_unset:c + { + \@@_opt_varname_type:enn + { \l_@@_setup_type_tl } { endrangeprop } { tl } + } + } + } + { + \tl_if_empty:nTF {#1} { - \@@_opt_tl_unset:c - { - \@@_opt_varname_type:enn - { \l_@@_setup_type_tl } {#1} { tl } - } + \msg_warning:nnn { zref-clever } + { endrange-property-undefined } {#1} } { - \tl_set:cn + \zref@ifpropundefined {#1} { - \@@_opt_varname_type:enn - { \l_@@_setup_type_tl } {#1} { tl } + \msg_warning:nnn { zref-clever } + { endrange-property-undefined } {#1} + } + { + \tl_set:cn + { + \@@_opt_varname_type:enn + { \l_@@_setup_type_tl } + { endrangefunc } { tl } + } + { @@_get_endrange_property } + \tl_set:cn + { + \@@_opt_varname_type:enn + { \l_@@_setup_type_tl } + { endrangeprop } { tl } + } + {#1} } - {##1} } - } , - } + } + } , + endrange .value_required:n = true , } \keys_define:nn { zref-clever/typesetup } { @@ -3625,6 +4438,247 @@ } , } } +\keys_define:nn { zref-clever/langsetup } + { + endrange .code:n = + { + \str_case:nnF {#1} + { + { ref } + { + \tl_if_empty:NTF \l_@@_setup_type_tl + { + \tl_gclear:c + { + \@@_opt_varname_lang_default:enn + { \l_@@_setup_language_tl } + { endrangefunc } { tl } + } + \tl_gclear:c + { + \@@_opt_varname_lang_default:enn + { \l_@@_setup_language_tl } + { endrangeprop } { tl } + } + } + { + \tl_gclear:c + { + \@@_opt_varname_lang_type:eenn + { \l_@@_setup_language_tl } + { \l_@@_setup_type_tl } + { endrangefunc } { tl } + } + \tl_gclear:c + { + \@@_opt_varname_lang_type:eenn + { \l_@@_setup_language_tl } + { \l_@@_setup_type_tl } + { endrangeprop } { tl } + } + } + } + + { stripprefix } + { + \tl_if_empty:NTF \l_@@_setup_type_tl + { + \tl_gset:cn + { + \@@_opt_varname_lang_default:enn + { \l_@@_setup_language_tl } + { endrangefunc } { tl } + } + { @@_get_endrange_stripprefix } + \tl_gclear:c + { + \@@_opt_varname_lang_default:enn + { \l_@@_setup_language_tl } + { endrangeprop } { tl } + } + } + { + \tl_gset:cn + { + \@@_opt_varname_lang_type:eenn + { \l_@@_setup_language_tl } + { \l_@@_setup_type_tl } + { endrangefunc } { tl } + } + { @@_get_endrange_stripprefix } + \tl_gclear:c + { + \@@_opt_varname_lang_type:eenn + { \l_@@_setup_language_tl } + { \l_@@_setup_type_tl } + { endrangeprop } { tl } + } + } + } + + { pagecomp } + { + \tl_if_empty:NTF \l_@@_setup_type_tl + { + \tl_gset:cn + { + \@@_opt_varname_lang_default:enn + { \l_@@_setup_language_tl } + { endrangefunc } { tl } + } + { @@_get_endrange_pagecomp } + \tl_gclear:c + { + \@@_opt_varname_lang_default:enn + { \l_@@_setup_language_tl } + { endrangeprop } { tl } + } + } + { + \tl_gset:cn + { + \@@_opt_varname_lang_type:eenn + { \l_@@_setup_language_tl } + { \l_@@_setup_type_tl } + { endrangefunc } { tl } + } + { @@_get_endrange_pagecomp } + \tl_gclear:c + { + \@@_opt_varname_lang_type:eenn + { \l_@@_setup_language_tl } + { \l_@@_setup_type_tl } + { endrangeprop } { tl } + } + } + } + + { pagecomp2 } + { + \tl_if_empty:NTF \l_@@_setup_type_tl + { + \tl_gset:cn + { + \@@_opt_varname_lang_default:enn + { \l_@@_setup_language_tl } + { endrangefunc } { tl } + } + { @@_get_endrange_pagecomptwo } + \tl_gclear:c + { + \@@_opt_varname_lang_default:enn + { \l_@@_setup_language_tl } + { endrangeprop } { tl } + } + } + { + \tl_gset:cn + { + \@@_opt_varname_lang_type:eenn + { \l_@@_setup_language_tl } + { \l_@@_setup_type_tl } + { endrangefunc } { tl } + } + { @@_get_endrange_pagecomptwo } + \tl_gclear:c + { + \@@_opt_varname_lang_type:eenn + { \l_@@_setup_language_tl } + { \l_@@_setup_type_tl } + { endrangeprop } { tl } + } + } + } + + { unset } + { + \tl_if_empty:NTF \l_@@_setup_type_tl + { + \@@_opt_tl_gunset:c + { + \@@_opt_varname_lang_default:enn + { \l_@@_setup_language_tl } + { endrangefunc } { tl } + } + \@@_opt_tl_gunset:c + { + \@@_opt_varname_lang_default:enn + { \l_@@_setup_language_tl } + { endrangeprop } { tl } + } + } + { + \@@_opt_tl_gunset:c + { + \@@_opt_varname_lang_type:eenn + { \l_@@_setup_language_tl } + { \l_@@_setup_type_tl } + { endrangefunc } { tl } + } + \@@_opt_tl_gunset:c + { + \@@_opt_varname_lang_type:eenn + { \l_@@_setup_language_tl } + { \l_@@_setup_type_tl } + { endrangeprop } { tl } + } + } + } + } + { + \tl_if_empty:nTF {#1} + { + \msg_warning:nnn { zref-clever } + { endrange-property-undefined } {#1} + } + { + \zref@ifpropundefined {#1} + { + \msg_warning:nnn { zref-clever } + { endrange-property-undefined } {#1} + } + { + \tl_if_empty:NTF \l_@@_setup_type_tl + { + \tl_gset:cn + { + \@@_opt_varname_lang_default:enn + { \l_@@_setup_language_tl } + { endrangefunc } { tl } + } + { @@_get_endrange_property } + \tl_gset:cn + { + \@@_opt_varname_lang_default:enn + { \l_@@_setup_language_tl } + { endrangeprop } { tl } + } + {#1} + } + { + \tl_gset:cn + { + \@@_opt_varname_lang_type:eenn + { \l_@@_setup_language_tl } + { \l_@@_setup_type_tl } + { endrangefunc } { tl } + } + { @@_get_endrange_property } + \tl_gset:cn + { + \@@_opt_varname_lang_type:eenn + { \l_@@_setup_language_tl } + { \l_@@_setup_type_tl } + { endrangeprop } { tl } + } + {#1} + } + } + } + } + } , + endrange .value_required:n = true , + } \keys_define:nn { zref-clever/langsetup } { refpre .code:n = @@ -4207,7 +5261,7 @@ \bool_set_false:N \l_@@_sort_decided_bool % First we check if there's any "external document" difference (coming - % from 'zref-xr') and, if so, sort based on that. + % from `zref-xr') and, if so, sort based on that. \tl_if_eq:NNF \l_@@_label_extdoc_a_tl \l_@@_label_extdoc_b_tl @@ -4589,6 +5643,8 @@ % \l_@@_range_count_int , % \l_@@_range_same_count_int , % \l_@@_range_beg_label_tl , +% \l_@@_range_beg_is_first_bool , +% \l_@@_range_end_ref_tl , % \l_@@_next_maybe_range_bool , % \l_@@_next_is_same_bool , % } @@ -4597,6 +5653,8 @@ \int_new:N \l_@@_range_count_int \int_new:N \l_@@_range_same_count_int \tl_new:N \l_@@_range_beg_label_tl +\bool_new:N \l_@@_range_beg_is_first_bool +\tl_new:N \l_@@_range_end_ref_tl \bool_new:N \l_@@_next_maybe_range_bool \bool_new:N \l_@@_next_is_same_bool % \end{macrocode} @@ -4614,8 +5672,11 @@ % \l_@@_rangesep_tl , % \l_@@_namefont_tl , % \l_@@_reffont_tl , +% \l_@@_endrangefunc_tl , +% \l_@@_endrangeprop_tl , % \l_@@_cap_bool , % \l_@@_abbrev_bool , +% \l_@@_rangetopair_bool , % } % Auxiliary variables for \cs{@@_typeset_refs:} separators, and font and % other options. @@ -4630,8 +5691,11 @@ \tl_new:N \l_@@_rangesep_tl \tl_new:N \l_@@_namefont_tl \tl_new:N \l_@@_reffont_tl +\tl_new:N \l_@@_endrangefunc_tl +\tl_new:N \l_@@_endrangeprop_tl \bool_new:N \l_@@_cap_bool \bool_new:N \l_@@_abbrev_bool +\bool_new:N \l_@@_rangetopair_bool % \end{macrocode} % \end{macro} % @@ -4692,11 +5756,13 @@ \tl_clear:N \l_@@_type_first_label_tl \tl_clear:N \l_@@_type_first_label_type_tl \tl_clear:N \l_@@_range_beg_label_tl + \tl_clear:N \l_@@_range_end_ref_tl \int_zero:N \l_@@_label_count_int \int_zero:N \l_@@_type_count_int \int_zero:N \l_@@_ref_count_int \int_zero:N \l_@@_range_count_int \int_zero:N \l_@@_range_same_count_int + \bool_set_false:N \l_@@_range_beg_is_first_bool \bool_set_false:N \l_@@_type_first_refbounds_set_bool % Get type block options (not type-specific). @@ -4771,9 +5837,9 @@ } % Handle warnings in case of reference or type undefined. - % Test: 'zc-typeset01.lvt': "Typeset refs: warn ref undefined" + % Test: `zc-typeset01.lvt': "Typeset refs: warn ref undefined" \zref@refused { \l_@@_label_a_tl } - % Test: 'zc-typeset01.lvt': "Typeset refs: warn missing type" + % Test: `zc-typeset01.lvt': "Typeset refs: warn missing type" \zref@ifrefundefined { \l_@@_label_a_tl } {} { @@ -4825,6 +5891,14 @@ { \l_@@_label_type_a_tl } { \l_@@_ref_language_tl } \l_@@_reffont_tl + \@@_get_rf_opt_tl:nxxN { endrangefunc } + { \l_@@_label_type_a_tl } + { \l_@@_ref_language_tl } + \l_@@_endrangefunc_tl + \@@_get_rf_opt_tl:nxxN { endrangeprop } + { \l_@@_label_type_a_tl } + { \l_@@_ref_language_tl } + \l_@@_endrangeprop_tl \@@_get_rf_opt_bool:nnxxN { cap } { false } { \l_@@_label_type_a_tl } { \l_@@_ref_language_tl } @@ -4833,6 +5907,10 @@ { \l_@@_label_type_a_tl } { \l_@@_ref_language_tl } \l_@@_abbrev_bool + \@@_get_rf_opt_bool:nnxxN { rangetopair } { true } + { \l_@@_label_type_a_tl } + { \l_@@_ref_language_tl } + \l_@@_rangetopair_bool \@@_get_rf_opt_seq:nxxN { refbounds-first } { \l_@@_label_type_a_tl } { \l_@@_ref_language_tl } @@ -4910,7 +5988,7 @@ { % It is the last label of its type, but also the first one, and that's % what matters here: just store it. - % Test: 'zc-typeset01.lvt': "Last of type: single" + % Test: `zc-typeset01.lvt': "Last of type: single" { 0 } { \tl_set:NV \l_@@_type_first_label_tl @@ -4923,7 +6001,7 @@ } % The last is the second: we have a pair (if not repeated). - % Test: 'zc-typeset01.lvt': "Last of type: pair" + % Test: `zc-typeset01.lvt': "Last of type: pair" { 1 } { \int_compare:nNnTF { \l_@@_range_same_count_int } = { 1 } @@ -4951,7 +6029,7 @@ \int_case:nnF { \l_@@_range_count_int } { % There was no range going on. - % Test: 'zc-typeset01.lvt': "Last of type: not range" + % Test: `zc-typeset01.lvt': "Last of type: not range" { 0 } { \int_compare:nNnTF { \l_@@_ref_count_int } < { 2 } @@ -4973,15 +6051,15 @@ } } % Last in the range is also the second in it. - % Test: 'zc-typeset01.lvt': "Last of type: pair in sequence" + % Test: `zc-typeset01.lvt': "Last of type: pair in sequence" { 1 } { \int_compare:nNnTF { \l_@@_range_same_count_int } = { 1 } { - % We know `range_beg_label' is not empty, since this is the - % second element in the range, but the third or more in the - % type list. + % We know `range_beg_is_first_bool' is false, since this is + % the second element in the range, but the third or more in + % the type list. \tl_put_right:Nx \l_@@_typeset_queue_curr_tl { \exp_not:V \l_@@_pairsep_tl @@ -5017,13 +6095,13 @@ } { % Repetition, not a range. - % Test: 'zc-typeset01.lvt': "Last of type: range to one" + % Test: `zc-typeset01.lvt': "Last of type: range to one" { 0 } { - % If `range_beg_label' is empty, it means it was also the - % first of the type, and hence its typesetting was already - % handled, and we just have to set refbounds. - \tl_if_empty:VTF \l_@@_range_beg_label_tl + % If `range_beg_is_first_bool' is true, it means it was also + % the first of the type, and hence its typesetting was + % already handled, and we just have to set refbounds. + \bool_if:NTF \l_@@_range_beg_is_first_bool { \seq_set_eq:NN \l_@@_type_first_refbounds_seq \l_@@_refbounds_first_sg_seq @@ -5055,11 +6133,11 @@ } % A `range', but with no skipped value, treat as pair if range % started with first of type, otherwise as list. - % Test: 'zc-typeset01.lvt': "Last of type: range to pair" + % Test: `zc-typeset01.lvt': "Last of type: range to pair" { 1 } { % Ditto. - \tl_if_empty:VTF \l_@@_range_beg_label_tl + \bool_if:NTF \l_@@_range_beg_is_first_bool { \seq_set_eq:NN \l_@@_type_first_refbounds_seq \l_@@_refbounds_first_pb_seq @@ -5091,9 +6169,9 @@ } { % An actual range. - % Test: 'zc-typeset01.lvt': "Last of type: range" + % Test: `zc-typeset01.lvt': "Last of type: range" % Ditto. - \tl_if_empty:VTF \l_@@_range_beg_label_tl + \bool_if:NTF \l_@@_range_beg_is_first_bool { \seq_set_eq:NN \l_@@_type_first_refbounds_seq \l_@@_refbounds_first_rb_seq @@ -5127,11 +6205,30 @@ } } } - \tl_put_right:Nx \l_@@_typeset_queue_curr_tl + \bool_lazy_and:nnTF + { ! \tl_if_empty_p:N \l_@@_endrangefunc_tl } + { \cs_if_exist_p:c { \l_@@_endrangefunc_tl :VVN } } { - \exp_not:V \l_@@_rangesep_tl - \@@_get_ref:VN \l_@@_label_a_tl - \l_@@_refbounds_last_re_seq + \use:c { \l_@@_endrangefunc_tl :VVN } + \l_@@_range_beg_label_tl + \l_@@_label_a_tl + \l_@@_range_end_ref_tl + \tl_put_right:Nx \l_@@_typeset_queue_curr_tl + { + \exp_not:V \l_@@_rangesep_tl + \@@_get_ref_endrange:VVN + \l_@@_label_a_tl + \l_@@_range_end_ref_tl + \l_@@_refbounds_last_re_seq + } + } + { + \tl_put_right:Nx \l_@@_typeset_queue_curr_tl + { + \exp_not:V \l_@@_rangesep_tl + \@@_get_ref:VN \l_@@_label_a_tl + \l_@@_refbounds_last_re_seq + } } } } @@ -5154,15 +6251,18 @@ } { \bool_set_false:N \l_@@_next_maybe_range_bool - \zref@ifrefundefined { \l_@@_type_first_label_tl } - { } + \bool_if:NT \l_@@_rangetopair_bool { - \@@_labels_in_sequence:nn - { \l_@@_type_first_label_tl } - { \l_@@_label_a_tl } + \zref@ifrefundefined { \l_@@_type_first_label_tl } + { } + { + \@@_labels_in_sequence:nn + { \l_@@_type_first_label_tl } + { \l_@@_label_a_tl } + } } - % Test: 'zc-typeset01.lvt': "Last of type: option range" - % Test: 'zc-typeset01.lvt': "Last of type: option range to pair" + % Test: `zc-typeset01.lvt': "Last of type: option range" + % Test: `zc-typeset01.lvt': "Last of type: option range to pair" \bool_if:NTF \l_@@_next_maybe_range_bool { \tl_set:Nx \l_@@_typeset_queue_curr_tl @@ -5176,11 +6276,34 @@ \bool_set_true:N \l_@@_type_first_refbounds_set_bool } { - \tl_set:Nx \l_@@_typeset_queue_curr_tl + \bool_lazy_and:nnTF + { ! \tl_if_empty_p:N \l_@@_endrangefunc_tl } + { \cs_if_exist_p:c { \l_@@_endrangefunc_tl :VVN } } { - \exp_not:V \l_@@_rangesep_tl - \@@_get_ref:VN \l_@@_label_a_tl - \l_@@_refbounds_last_re_seq + % We must get `type_first_label_tl' instead of + % `range_beg_label_tl' here, since it is not necessary + % that the first of type was actually starting a range for + % the `range' option to be used. + \use:c { \l_@@_endrangefunc_tl :VVN } + \l_@@_type_first_label_tl + \l_@@_label_a_tl + \l_@@_range_end_ref_tl + \tl_set:Nx \l_@@_typeset_queue_curr_tl + { + \exp_not:V \l_@@_rangesep_tl + \@@_get_ref_endrange:VVN + \l_@@_label_a_tl + \l_@@_range_end_ref_tl + \l_@@_refbounds_last_re_seq + } + } + { + \tl_set:Nx \l_@@_typeset_queue_curr_tl + { + \exp_not:V \l_@@_rangesep_tl + \@@_get_ref:VN \l_@@_label_a_tl + \l_@@_refbounds_last_re_seq + } } \seq_set_eq:NN \l_@@_type_first_refbounds_seq \l_@@_refbounds_first_rb_seq @@ -5210,7 +6333,7 @@ { \bool_if:NTF \l_@@_typeset_ref_bool { - % Test: 'zc-typeset01.lvt': "Last of type: option typeset ref" + % Test: `zc-typeset01.lvt': "Last of type: option typeset ref" \tl_put_left:Nx \l_@@_typeset_queue_curr_tl { \@@_get_ref:VN \l_@@_type_first_label_tl @@ -5220,14 +6343,14 @@ { \bool_if:NTF \l_@@_typeset_name_bool { - % Test: 'zc-typeset01.lvt': "Last of type: option typeset name" + % Test: `zc-typeset01.lvt': "Last of type: option typeset name" \tl_set:Nx \l_@@_typeset_queue_curr_tl { \bool_if:NTF \l_@@_name_in_link_bool { \exp_not:N \group_begin: \exp_not:V \l_@@_namefont_tl - % It's two '@s', but escaped for DocStrip. + % It's two `@s', but escaped for DocStrip. \exp_not:N \hyper@@@@link { \@@_extract_url_unexp:V @@ -5254,7 +6377,7 @@ % it should not occur, given that the options are set up to % typeset either "ref" or "name". Still, leave here a % sensible fallback, equal to the behavior of "both". - % Test: 'zc-typeset01.lvt': "Last of type: option typeset none" + % Test: `zc-typeset01.lvt': "Last of type: option typeset none" \tl_put_left:Nx \l_@@_typeset_queue_curr_tl { \@@_get_ref_first: } } @@ -5280,11 +6403,11 @@ \int_case:nnF { \l_@@_type_count_int } { % Single type. - % Test: 'zc-typeset01.lvt': "Last of type: single type" + % Test: `zc-typeset01.lvt': "Last of type: single type" { 0 } { \l_@@_typeset_queue_curr_tl } % Pair of types. - % Test: 'zc-typeset01.lvt': "Last of type: pair of types" + % Test: `zc-typeset01.lvt': "Last of type: pair of types" { 1 } { \l_@@_tpairsep_tl @@ -5293,7 +6416,7 @@ } { % Last in list of types. - % Test: 'zc-typeset01.lvt': "Last of type: list of types" + % Test: `zc-typeset01.lvt': "Last of type: list of types" \l_@@_tlastsep_tl \l_@@_typeset_queue_curr_tl } @@ -5314,11 +6437,13 @@ \tl_clear:N \l_@@_type_first_label_tl \tl_clear:N \l_@@_type_first_label_type_tl \tl_clear:N \l_@@_range_beg_label_tl + \tl_clear:N \l_@@_range_end_ref_tl \int_zero:N \l_@@_label_count_int \int_zero:N \l_@@_ref_count_int \int_incr:N \l_@@_type_count_int \int_zero:N \l_@@_range_count_int \int_zero:N \l_@@_range_same_count_int + \bool_set_false:N \l_@@_range_beg_is_first_bool \bool_set_false:N \l_@@_type_first_refbounds_set_bool } } @@ -5356,13 +6481,16 @@ \l_@@_label_type_a_tl \int_incr:N \l_@@_ref_count_int - % If the next label may be part of a range, we set `range_beg_label' - % to "empty" (we deal with it as the "first", and must do it there, to - % handle hyperlinking), but also step the range counters. - % Test: 'zc-typeset01.lvt': "Not last of type: first is range" + % If the next label may be part of a range, signal it (we deal with it + % as the "first", and must do it there, to handle hyperlinking), but + % also step the range counters. + % Test: `zc-typeset01.lvt': "Not last of type: first is range" \bool_if:NT \l_@@_next_maybe_range_bool { - \tl_clear:N \l_@@_range_beg_label_tl + \bool_set_true:N \l_@@_range_beg_is_first_bool + \tl_set:NV \l_@@_range_beg_label_tl + \l_@@_label_a_tl + \tl_clear:N \l_@@_range_end_ref_tl \int_incr:N \l_@@_range_count_int \bool_if:NT \l_@@_next_is_same_bool { \int_incr:N \l_@@_range_same_count_int } @@ -5379,6 +6507,7 @@ % There was no range going, we are starting one. \tl_set:NV \l_@@_range_beg_label_tl \l_@@_label_a_tl + \tl_clear:N \l_@@_range_end_ref_tl \int_incr:N \l_@@_range_count_int \bool_if:NT \l_@@_next_is_same_bool { \int_incr:N \l_@@_range_same_count_int } @@ -5396,7 +6525,7 @@ \int_case:nnF { \l_@@_range_count_int } { % There was no range going on. - % Test: 'zc-typeset01.lvt': "Not last of type: no range" + % Test: `zc-typeset01.lvt': "Not last of type: no range" { 0 } { \int_incr:N \l_@@_ref_count_int @@ -5410,11 +6539,11 @@ % Last is second in the range: if `range_same_count' is also % `1', it's a repetition (drop it), otherwise, it's a "pair % within a list", treat as list. - % Test: 'zc-typeset01.lvt': "Not last of type: range pair to one" - % Test: 'zc-typeset01.lvt': "Not last of type: range pair" + % Test: `zc-typeset01.lvt': "Not last of type: range pair to one" + % Test: `zc-typeset01.lvt': "Not last of type: range pair" { 1 } { - \tl_if_empty:VTF \l_@@_range_beg_label_tl + \bool_if:NTF \l_@@_range_beg_is_first_bool { \seq_set_eq:NN \l_@@_type_first_refbounds_seq \l_@@_refbounds_first_seq @@ -5456,10 +6585,10 @@ \l_@@_range_same_count_int } { - % Test: 'zc-typeset01.lvt': "Not last of type: range to one" + % Test: `zc-typeset01.lvt': "Not last of type: range to one" { 0 } { - \tl_if_empty:VTF \l_@@_range_beg_label_tl + \bool_if:NTF \l_@@_range_beg_is_first_bool { \seq_set_eq:NN \l_@@_type_first_refbounds_seq @@ -5478,10 +6607,10 @@ } } } - % Test: 'zc-typeset01.lvt': "Not last of type: range to pair" + % Test: `zc-typeset01.lvt': "Not last of type: range to pair" { 1 } { - \tl_if_empty:VTF \l_@@_range_beg_label_tl + \bool_if:NTF \l_@@_range_beg_is_first_bool { \seq_set_eq:NN \l_@@_type_first_refbounds_seq @@ -5509,8 +6638,8 @@ } } { - % Test: 'zc-typeset01.lvt': "Not last of type: range" - \tl_if_empty:VTF \l_@@_range_beg_label_tl + % Test: `zc-typeset01.lvt': "Not last of type: range" + \bool_if:NTF \l_@@_range_beg_is_first_bool { \seq_set_eq:NN \l_@@_type_first_refbounds_seq @@ -5529,15 +6658,34 @@ } } % For the purposes of the serial comma, and thus for the - % distinction of 'lastsep' and 'pairsep', a "range" counts - % as one. Since 'range_beg' has already been counted + % distinction of `lastsep' and `pairsep', a "range" counts + % as one. Since `range_beg' has already been counted % (here or with the first of type), we refrain from - % incrementing 'ref_count_int'. - \tl_put_right:Nx \l_@@_typeset_queue_curr_tl + % incrementing `ref_count_int'. + \bool_lazy_and:nnTF + { ! \tl_if_empty_p:N \l_@@_endrangefunc_tl } + { \cs_if_exist_p:c { \l_@@_endrangefunc_tl :VVN } } { - \exp_not:V \l_@@_rangesep_tl - \@@_get_ref:VN \l_@@_label_a_tl - \l_@@_refbounds_mid_re_seq + \use:c { \l_@@_endrangefunc_tl :VVN } + \l_@@_range_beg_label_tl + \l_@@_label_a_tl + \l_@@_range_end_ref_tl + \tl_put_right:Nx \l_@@_typeset_queue_curr_tl + { + \exp_not:V \l_@@_rangesep_tl + \@@_get_ref_endrange:VVN + \l_@@_label_a_tl + \l_@@_range_end_ref_tl + \l_@@_refbounds_mid_re_seq + } + } + { + \tl_put_right:Nx \l_@@_typeset_queue_curr_tl + { + \exp_not:V \l_@@_rangesep_tl + \@@_get_ref:VN \l_@@_label_a_tl + \l_@@_refbounds_mid_re_seq + } } } } @@ -5599,7 +6747,8 @@ % \begin{macro}{\@@_get_ref:nN} % Handles a complete reference block to be accumulated in the ``queue'', % including refbounds, and hyperlinking. For use with all labels, except -% the first of its type, which is done by \cs{@@_get_ref_first:}. +% the first of its type, which is done by \cs{@@_get_ref_first:}, and the +% last of a range, which is done by \cs{@@_get_ref_endrange:nnN}. % \begin{syntax} % \cs{@@_get_ref:nN} \Arg{label} \Arg{refbounds} % \end{syntax} @@ -5648,6 +6797,53 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\@@_get_ref_endrange:nnN} +% \begin{syntax} +% \cs{@@_get_ref_endrange:nnN} \Arg{label} \Arg{reference} \Arg{refbounds} +% \end{syntax} +% \begin{macrocode} +\cs_new:Npn \@@_get_ref_endrange:nnN #1#2#3 + { + \str_if_eq:nnTF {#2} { zc@missingproperty } + { \@@_ref_default: } + { + \bool_if:nTF + { + \l_@@_hyperlink_bool && + ! \l_@@_link_star_bool + } + { + \exp_not:N \group_begin: + \exp_not:V \l_@@_reffont_tl + \seq_item:Nn #3 { 1 } + % It's two `@s', but escaped for DocStrip. + \exp_not:N \hyper@@@@link + { \@@_extract_url_unexp:n {#1} } + { \@@_extract_unexp:nnn {#1} { anchor } { } } + { + \seq_item:Nn #3 { 2 } + \exp_not:n {#2} + \seq_item:Nn #3 { 3 } + } + \seq_item:Nn #3 { 4 } + \exp_not:N \group_end: + } + { + \exp_not:N \group_begin: + \exp_not:V \l_@@_reffont_tl + \seq_item:Nn #3 { 1 } + \seq_item:Nn #3 { 2 } + \exp_not:n {#2} + \seq_item:Nn #3 { 3 } + \seq_item:Nn #3 { 4 } + \exp_not:N \group_end: + } + } + } +\cs_generate_variant:Nn \@@_get_ref_endrange:nnN { VVN } +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\@@_get_ref_first:} % Handles a complete reference block for the first label of its type to be % accumulated in the ``queue'', including ``pre'' and ``pos'' elements, @@ -5738,7 +6934,7 @@ \exp_not:V \l_@@_reffont_tl \seq_item:Nn \l_@@_type_first_refbounds_seq { 1 } - % It's two '@s', but escaped for DocStrip. + % It's two `@s', but escaped for DocStrip. \exp_not:N \hyper@@@@link { \@@_extract_url_unexp:V @@ -6071,14 +7267,9 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_labels_in_sequence:nn #1#2 { - \@@_extract_default:Nnnn \l_@@_label_extdoc_a_tl - {#1} { externaldocument } { } - \@@_extract_default:Nnnn \l_@@_label_extdoc_b_tl - {#2} { externaldocument } { } - - \tl_if_eq:NNT - \l_@@_label_extdoc_a_tl - \l_@@_label_extdoc_b_tl + \exp_args:Nxx \tl_if_eq:nnT + { \@@_extract_unexp:nnn {#1} { externaldocument } { } } + { \@@_extract_unexp:nnn {#2} { externaldocument } { } } { \tl_if_eq:NnTF \l_@@_ref_property_tl { page } { @@ -6123,8 +7314,14 @@ = { \@@_extract:nnn {#2} { zc@cntval } { -1 } } { - \bool_set_true:N - \l_@@_next_maybe_range_bool +% \end{macrocode} +% If \texttt{zc@counter}s are equal, \texttt{zc@enclval}s are equal, and +% \texttt{zc@enclval}s are equal, but the references themselves are different, +% this means that \cs{@currentlabel} has somehow been set manually (e.g. by an +% \pkg{amsmath}'s \cs{tag}), in which case we have no idea what's in there, +% and we should not even consider this is still a range. If they are equal, +% though, of course it is a range, and it is the same. +% \begin{macrocode} \exp_args:Nxx \tl_if_eq:nnT { \@@_extract_unexp:nvn {#1} @@ -6135,6 +7332,8 @@ { l_@@_ref_property_tl } { } } { + \bool_set_true:N + \l_@@_next_maybe_range_bool \bool_set_true:N \l_@@_next_is_same_bool } @@ -6720,9 +7919,10 @@ % and subsequent discussion. So, for \env{subequations}, we really must % specify manually \opt{currentcounter} and the resetting. Note that, for % \env{subequations}, \cs{zlabel} works just fine (that is, if given -% immediately after \texttt{\\begin\{subequations\}}, to refer to the -% parent equation). +% immediately after \texttt{\textbackslash{}begin\{subequations\}}, to refer +% to the parent equation). % \begin{macrocode} + \bool_new:N \l_@@_amsmath_subequations_bool \AddToHook { env / subequations / begin } { \@@_zcsetup:x @@ -6736,6 +7936,7 @@ currentcounter = parentequation , countertype = { parentequation = equation } , } + \bool_set_true:N \l_@@_amsmath_subequations_bool } % \end{macrocode} % \pkg{amsmath} does use \cs{refstepcounter} for the \texttt{equation} counter @@ -6750,8 +7951,12 @@ % environments ``must appear within an enclosing math environment''. Same % logic applies to other environments defined or redefined by the package, % like \env{array}, \env{matrix} and variations. Finally, \env{split} too can -% only be used as part of another environment. +% only be used as part of another environment. We also arrange, at this +% point, for the provision of the \texttt{subeq} property, for the convenience +% of referring to them directly or to build terse ranges with the +% \opt{endrange} option. % \begin{macrocode} + \zref@newprop { subeq } { \alph { equation } } \clist_map_inline:nn { equation , @@ -6771,7 +7976,11 @@ } { \AddToHook { env / #1 / begin } - { \@@_zcsetup:n { currentcounter = equation } } + { + \@@_zcsetup:n { currentcounter = equation } + \bool_if:NT \l_@@_amsmath_subequations_bool + { \zref@localaddprop \ZREF@mainlist { subeq } } + } } % \end{macrocode} % And a last touch of care for \pkg{amsmath}'s refinements: make the equation @@ -6867,6 +8076,7 @@ % for incrementing the equation counters (see % \url{https://tex.stackexchange.com/a/241150}). % \begin{macrocode} + \bool_new:N \l_@@_breqn_dgroup_bool \AddToHook { env / dgroup / begin } { \@@_zcsetup:x @@ -6880,7 +8090,11 @@ currentcounter = parentequation , countertype = { parentequation = equation } , } + \bool_set_true:N \l_@@_breqn_dgroup_bool } + \zref@ifpropundefined { subeq } + { \zref@newprop { subeq } { \alph { equation } } } + { } \clist_map_inline:nn { dmath , @@ -6889,7 +8103,11 @@ } { \AddToHook { env / #1 / begin } - { \@@_zcsetup:n { currentcounter = equation } } + { + \@@_zcsetup:n { currentcounter = equation } + \bool_if:NT \l_@@_breqn_dgroup_bool + { \zref@localaddprop \ZREF@mainlist { subeq } } + } } \msg_info:nnn { zref-clever } { compat-package } { breqn } } @@ -7154,6 +8372,7 @@ type = page , Name-pl = Pages , name-pl = pages , rangesep = {\textendash} , + rangetopair = false , type = line , Name-sg = Line , @@ -7436,6 +8655,7 @@ type = page , Name-sg = Seite , Name-pl = Seiten , rangesep = {\textendash} , + rangetopair = false , type = line , gender = f , @@ -7853,6 +9073,7 @@ type = page , Name-pl = Pages , name-pl = pages , rangesep = {-} , + rangetopair = false , type = line , gender = f , @@ -8094,6 +9315,7 @@ type = page , Name-pl = Páginas , name-pl = páginas , rangesep = {\textendash} , + rangetopair = false , type = line , gender = f , @@ -8333,6 +9555,7 @@ type = page , Name-pl = Páginas , name-pl = páginas , rangesep = {\textendash} , + rangetopair = false , type = line , gender = f , @@ -8566,6 +9789,7 @@ type = page , Name-pl = Pagina's , name-pl = pagina's , rangesep = {\textendash} , + rangetopair = false , type = line , gender = m , diff --git a/macros/latex/contrib/zref-clever/zref-clever.pdf b/macros/latex/contrib/zref-clever/zref-clever.pdf index 99292b0570..f623839df6 100644 Binary files a/macros/latex/contrib/zref-clever/zref-clever.pdf and b/macros/latex/contrib/zref-clever/zref-clever.pdf differ diff --git a/macros/latex/contrib/zref-clever/zref-clever.tex b/macros/latex/contrib/zref-clever/zref-clever.tex index 64d5028f62..3079e6384a 100644 --- a/macros/latex/contrib/zref-clever/zref-clever.tex +++ b/macros/latex/contrib/zref-clever/zref-clever.tex @@ -105,6 +105,11 @@ zcLanguageSetup, zcRefTypeSetup, zcheck, + zvref, + zvpageref, + zvrefrange, + zvpagerefrange, + zfullref, } } \lstset{ @@ -266,14 +271,14 @@ 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, 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. There are some limitations, of course (see -\zcref{sec:limitations}), and it may be your cup of tea or not. Still, all in -all, hopefully \pkg{zref-clever} can make \pkg{zref} more accessible, and -interesting, to the average user. +that \pkg{zref-vario} offers integration of \pkg{zref-clever} with +\pkg{varioref}, a significant part of the most prominent automation features +available to the standard referencing system is thus brought to \pkg{zref}, +working under a single consistent underlying infrastructure and user +interface. Alas, there are some limitations (see \zcref{sec:limitations}), +and it may be your cup of tea or not. Still, all in all, hopefully +\pkg{zref-clever} can make \pkg{zref} more accessible to the average user, and +more interesting to users in general. \section{Warning} @@ -501,7 +506,43 @@ and defaults to \texttt{true}. The \opt{nocomp} option is a convenience alias for \texttt{comp=false}. Of course, for better compression results the \opt{sort} is recommended, but the two options are technically independent. +\DescribeOption{endrange} % +The \opt{endrange} option provides additional control over how the end +reference of a range is typeset, so as to achieve terse ranges. The option +can operate in two technically different ways. It may receive one of a number +of predefined values, which can process the end reference of the range, +comparing it with the beginning reference, to achieve a given end +result.\footnote{For the \TeX{}nically inclined: those values that perform + some processing -- namely \texttt{stripprefix}, \texttt{pagecomp}, and + \texttt{pagecomp2} -- fully expand the references (\texttt{x}-type + expansion) before comparing them, since it makes sense to perform this task + as close as possible to the printed representation of the references. I + don't expect this to be a problem in normal use cases, but it does represent + a limitation on what the references can contain. In case some control over + this is needed, check the \texttt{zref-clever/endrange-setup} hook in the + code documentation.} Or, it can specify a label property to be used +directly, without any processing. The available predefined values are: +\texttt{ref}, \texttt{stripprefix}, \texttt{pagecomp}, and \texttt{pagecomp2}. +\texttt{ref} corresponds to the default behavior, and instructs \cs{zcref} to +use whatever property was set at the \opt{ref} option for the end of range +reference. \texttt{stripprefix} strips the common part at the start of each +reference from the end one. \texttt{pagecomp} is the equivalent of +\texttt{stripprefix} for page numbers, it does the same thing, but only if the +references are comprised exclusively of Arabic numerals. \texttt{pagecomp2} +is a variant of \texttt{pagecomp} that leaves at least two digits at the end +reference (except for a leading zero). If values other than the predefined +ones are given to \opt{endrange} they are considered as label properties, as +long as they are declared. This property is used to typeset the end of range +reference if the label contains it, and if both references would be +``compressible'' according to the \opt{comp} option, otherwise the property +specified by the \opt{ref} option is used. This is useful for things like +sub-elements for which we can build a proper abbreviated sub-reference and +populate the label with it (some compatibility modules already provide a +number of such properties, but other ones can be built with \pkg{zref}, as +needed). + \DescribeOption{range} % +\DescribeOption{rangetopair} % By default (that is, when the \opt{range} option is not given), \cs{zcref} typesets a complete list of references according to the \meta{labels} it received as argument, and only compresses some of them into ranges if the @@ -510,12 +551,14 @@ 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}). +in between do not occur in immediate sequence. It is a boolean option, and +the package's default is \texttt{range=false}. The option given without a +value is equivalent to \texttt{range=true} (in the \pkg{l3keys}' jargon, the +\emph{option}'s default is \texttt{true}). \cs{zcref} is smart enough to +recognize when the first and last references of a type do happen to be +contiguous, in which case it typesets a ``pair'', instead of a ``range''. But +this behavior can be disabled by setting the \opt{rangetopair} option to +\texttt{false}. \DescribeOption{cap} % \DescribeOption{nocap} % @@ -666,8 +709,14 @@ means this option \emph{can't} be set at load time, as a package option. If you want to set it globally, use \cs{zcsetup} instead. \DescribeOption{titleref} % +\DescribeOption{vario} % The \opt{titleref} option receives no value and, when given, loads -\pkg{zref}'s \pkg{zref-titleref} module. This is a preamble only option. +\pkg{zref}'s \pkg{zref-titleref} module. Similarly, the \opt{vario} option +loads the \pkg{zref-vario} package. These are a preamble only options. Note +that \pkg{zref-vario} loads \pkg{varioref}, which has known load order +interaction with other packages, prominently with \pkg{hyperref}. Hence, +depending on your document, you may wish to load \pkg{zref-vario} separately, +instead of through the option. \DescribeOption{note} % The \opt{note} option receives as value some text to be typeset at the end of @@ -847,7 +896,7 @@ 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 +of a ``name'' which \pkg{zref-clever} uses to look for a whole set of type-specific reference format options (see \zcref{sec:reference-format}). Each of these options individually may be ``set'' or not, ``defined'' or not. And, depending on the setup and the relevant precedence rules for this, some @@ -908,42 +957,44 @@ more detail soon, and lists the scopes in which each is available. \centering \begin{tabular}{l>{\ttfamily}lcccc} \toprule - & & General & Type & \multicolumn{2}{c}{Language} \\ - \cmidrule(lr){5-6} - & & & & Type & Default \\ - & & (i) & (ii) & (iii) & (iv) \\ + & & General & Type & \multicolumn{2}{c}{Language} \\ + \cmidrule(lr){5-6} + & & & & Type & Default \\ + & & (i) & (ii) & (iii) & (iv) \\ \midrule - Typesetting & tpairsep & $\bullet$ & & & $\bullet$ \\ - (necessarily not & tlistsep & $\bullet$ & & & $\bullet$ \\ - type-specific) & tlastsep & $\bullet$ & & & $\bullet$ \\ - & notesep & $\bullet$ & & & $\bullet$ \\ + Typesetting & tpairsep & $\bullet$ & & & $\bullet$ \\ + (necessarily not & tlistsep & $\bullet$ & & & $\bullet$ \\ + type-specific) & tlastsep & $\bullet$ & & & $\bullet$ \\ + & notesep & $\bullet$ & & & $\bullet$ \\ \addlinespace - Typesetting & namesep & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ - (possibly & pairsep & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ - type-specific) & listsep & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ - & lastsep & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ - & rangesep & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ - & refbounds & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ + Typesetting & namesep & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ + (possibly & pairsep & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ + type-specific) & listsep & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ + & lastsep & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ + & rangesep & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ + & refbounds & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ \addlinespace - Typesetting & Name-sg & & $\bullet$ & $\bullet$ & \\ - (necessarily & name-sg & & $\bullet$ & $\bullet$ & \\ - type-specific) & Name-pl & & $\bullet$ & $\bullet$ & \\ - & name-pl & & $\bullet$ & $\bullet$ & \\ - & Name-sg-ab & & $\bullet$ & $\bullet$ & \\ - & name-sg-ab & & $\bullet$ & $\bullet$ & \\ - & Name-pl-ab & & $\bullet$ & $\bullet$ & \\ - & name-pl-ab & & $\bullet$ & $\bullet$ & \\ + Typesetting & Name-sg & & $\bullet$ & $\bullet$ & \\ + (necessarily & name-sg & & $\bullet$ & $\bullet$ & \\ + type-specific) & Name-pl & & $\bullet$ & $\bullet$ & \\ + & name-pl & & $\bullet$ & $\bullet$ & \\ + & Name-sg-ab & & $\bullet$ & $\bullet$ & \\ + & name-sg-ab & & $\bullet$ & $\bullet$ & \\ + & Name-pl-ab & & $\bullet$ & $\bullet$ & \\ + & name-pl-ab & & $\bullet$ & $\bullet$ & \\ \addlinespace - Font & namefont & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ - & reffont & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ + Font & namefont & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ + & reffont & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ \addlinespace - Other & cap & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ - & abbrev & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ + Other & cap & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ + & abbrev & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ + & endrange & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ + & rangetopair & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\ \bottomrule \end{tabular} \caption{Reference format options and their scopes} @@ -1490,71 +1541,40 @@ set around a cross-reference ``task'' we'd like to perform with \pkg{zref-clever}. -\subsection{Context sensitive page references} +\subsection{Extended page references (\pkg{varioref})} \zctask{Make cross-references to pages which are sensitive to the relative - position between the reference and the label being referred to.} - -It is frequently useful to make a reference to both a document element and its -page. For example: -\begin{zcexample} -\zcref{fig:1} on \zcpageref{fig:1} -\end{zcexample} - -However, while this works well when the object and the reference are somewhat -distant, we may want to adjust this to something different when the label and -the reference are close to each other. If both are on the same page, we may -want to drop the \cs{zcpageref}, or replace it with ``above'' or ``below''. -And, if both are on contiguous pages, then something like ``on the following -page'' or ``on the preceding page'' may be preferred. Since we don't usually -know the relative position of the reference to the label, particularly for -floats, making these kinds of adjustments manually is an uphill battle, and -error prone, in the absence of some support for it. - -\pkg{zref-clever}'s integration with \pkg{zref-check} offers some assistance -in making these kinds of references, by providing checks for the relation -between the reference and the label. For example, you may use: -\begin{zcexample} -\zcref[check=nextpage,note={on the following page}]{fig:1} -\end{zcexample} -and if \texttt{fig:1} is not on the next page relative to the reference, a -compilation warning can be issued by \pkg{zref-check} (according to the -package's options), so that the problem can be easily identified and -corrected. Evidently, this does not fully automate the typeset results, but -it does automate the checking that the reference context is the intended one. - -And to make use of this feature, one does not need to rely on compiling the -document, make the reference according to the current state of things, and -then adjusting it over and over, as the document gets edited. This feature is -best used within a certain workflow, which starts by making a standard -reference with a page reference, but adding the \texttt{pagegap} check to it: -\begin{zcexample} -\zcref{fig:1} on \zcpageref[check=pagegap]{fig:1} -\end{zcexample} + position between the reference and the label being referred to using + \pkg{varioref}.} -During the initial editing of the document, this reference will be formally -correct, even if less than ideal in certain cases. At a certain point, when -you choose to give finishing touches to your document, then you can cater for -\pkg{zref-check}'s warnings (the package has options to control them, for -example, enabling warnings only when the \opt{draft} option is not in use). -The \texttt{pagegap} check will pass if there's one or more pages between the -reference and the label, in which case, that reference is already what we -want. However, if the referenced object lies in the previous page, the same -page, or the next page, the \texttt{pagegap} check will issue a warning. Thus -telling us if there's an opportunity, or need, to adjust the context -information of the reference. Then we can go with one of the below, according -to the situation: -\begin{zcexample} -\zcref[check=thispage]{fig:1} -\zcref[check=above,note={above}]{fig:1} -\zcref[check=below,note={below}]{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} -\end{zcexample} +\pkg{zref-vario}, which can be enabled with package option \opt{vario}, offers +a layer of compatibility with \pkg{varioref} and provides +\texttt{\textbackslash{}z}\dots{} counterparts for the latter's main reference +commands. -See \pkg{zref-check}'s documentation for details, and further available -checks. +\begin{zchowto}[caption={\pkg{zref-vario}}] +\documentclass{article} +\usepackage[vario]{zref-clever} +\begin{document} +\section{Section 1} +\zlabel{sec:section-1} +\begin{figure} + A figure. + \caption{Figure 1} + \zlabel{fig:figure-1} +\end{figure} +\begin{figure} + Another figure. + \caption{Figure 2} + \zlabel{fig:figure-2} +\end{figure} +\zvref[S]{sec:section-1} +\zvpageref{fig:figure-1} +\zvrefrange{fig:figure-1}{fig:figure-2} +\zvpagerefrange{fig:figure-1}{fig:figure-2} +\zfullref{fig:figure-1} +\end{document} +\end{zchowto} \subsection{\cs{newtheorem}} @@ -2087,16 +2107,20 @@ refer to the main equation number, that is, right after 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. +\pkg{amsmath}'s \cs{eqref}. Finally, the module also provides a +\texttt{subeq} property, for display math environments used inside the +\env{subequations} environment, which can be used to refer to them directly +with the \opt{ref} option, or to build terse ranges with the \opt{endrange} +option. Note that \pkg{zref-clever} is not the only package to redefine +\cs{ltx@label}, and compatibility problems may arise if this module is used +with such packages or with document classes that do the same. In case of +trouble, you can load \pkg{zref-clever} with option \texttt{nocompat=amsmath} +and either use the standard referencing system's facilities to refer to +\pkg{amsmath}'s equations or check the code documentation for the technique +used for this (which is pretty standard) and adapt it to your case. Given +that any trouble that may arise here is one of the proper ``timing'' of the +redefinition, it should not be particularly complicated to make such +adjustments. \DescribeOption{mathtools} % \pkg{mathtools} has a feature to show the numbers only for those equations -- cgit v1.2.3