Le package varioref^{∗}

Frank Mittelbach Traduit de l’anglais par : Jean-Pierre Drucbert

1999/12/02

Résumé Ce package définit les commandes \vref, \vpageref, \vrefrange et \vpagerefrange pour L^{A}TEX 2ε. \vref est similaire à \ref mais ajoute une référence supplémentaire à la page, du type « on the facing page » ou « on page 27 » chaque fois que le \label correspondant n’est pas sur la même page. La commande \vpageref est une variante de \pageref avec une fonctionnalité similaire. Les commandes \v...range prennent deux labels en arguments et produisent des chaînes dépendant du fait que ces labels tombent sur la même page ou sur des pages différentes. Les textes engendrés sont adaptables pour que ces commandes puissent être utilisées dans d’autres langues.

1 Introduction

Dans de nombreux cas il est pratique lorsque l’on fait référence à une figure ou à une table de mettre à la fois une commande \ref et une commande \pageref dans le document, en particulier lorsqu’il y a une ou plusieurs pages entre la référence et l’objet référencé. Donc certains utilisateurs utilisent une commande du genre

  \newcommand{\fullref}[1]{\ref{#1} on page~\pageref{#1}}

qui réduit la frappe nécessaire pour faire une telle référence complète. Mais puisque nous ne savons jamais où l’objet référencé se trouvera finalement, utiliser un tel artifice peut résulter en une référence de page vers la page courante, ce qui est déroutant et doit donc être évité.

2 Interface utilisateur

\vref La commande \vref ne produit que l’équivalent de \ref lorsque la référence et le \label sont sur la même page. Elle produira en plus l’une des chaînes « on the facing page », « on the preceding page » ou « on the following page », si label et référence sont à une page de distance et elle produira à la fois \ref et \pageref lorsque l’écart est plus grand. Le mot « facing » est utilisé lorsque le label et la référence sont tous deux sur une paire de pages se faisant face. Cependant, si un type spécial de numérotation des pages est utilisé (par exemple, des nombres en chiffres romains) au lieu de la numérotation habituelle en chiffres arabes, il n’y aura pas de distinction entre des pages distantes de une ou de plusieurs pages.

\vpageref Parfois vous voulez faire référence seulement au numéro de page et ici encore une telle référence doit normalement être supprimée si la référence concerne la page courante. Dans ce but, ce package définit la commande \vpageref. Elle produira les mêmes textes que \vref mais ne commencera pas par une \ref et elle produira le texte qui est conservé dans \reftextcurrent si label et référence sont sur la même page. En définissant \reftextcurrent pour produire « on this page » ou un texte similaire, nous pouvons facilement éviter que

∗Ce fichier a le numéro de version v1.2c, dernière mise à jour le 1999/12/02.

   ... see the example \vpageref{ex:foo} which shows ...

produise « … see the example which shows … »^{1}, ce qui peut être trompeur.

Vous pouvez mettre un espace devant \vpageref, il sera ignoré si la commande ne produit absolument aucun texte.

Mais en fait \vpageref offre encore plus de contrôle. Cette commande a deux arguments optionnels. Avec le premier, vous pouvez spécifier le texte à utiliser si label et référence sont sur la même page. Ceci est très utile s’ils sont très proches l’un de l’autre, et qu’ils peuvent donc être ou ne pas être séparés par un saut de page. Dans un tel cas nous savons en général ( !) si la référence est avant ou après le label et nous pouvons donc dire quelque chose comme

   ... see the example \vpageref[above]{ex:foo} which shows ...

qui donne alors « … see the example above which shows … » si nous somme encore sur la même page, mais donnera « … see the example on the page before which shows … » (ou quelque chose de similaire selon les définitions des commandes \reftext..before) lorqu’il y a un saut de page entre temps. Un avertissement, cependant : si vous utilisez \vpageref avec l’argument optionnel pour référencer une figure ou une table, gardez à l’esprit que selon les paramètres de placement des corps mobiles, la figure ou la table peut apparaître en haut de la page courante et donc avant la référence même si elle vient après dans le fichier source.

Mais peut-être préférez-vous dire « … see the above example » si l’exemple et la référence tombent sur la même page, c’est-à-dire changer l’ordre des mots. En fait, dans certaines langues l’ordre des mots change automatiquement dans ce cas. Pour permettre cette variation, le second argument optionnel peut être utilisé. Il spécifie le texte précédant la référence engendrée si objet et référence ne tombent pas sur la même page. Donc on écrirait

   ... see the \vpageref[above example][example]{ex:foo}
       which shows ...

pour obtenir l’effet désiré.

2.1 Ajouts en 1998

\vrefrange La commande \vrefrange est similaire à \vref mais elle prend deux arguments obligatoires désignant un intervalle auquel référence est faite (par exemple, une suite de figures ou une suite d’équations, etc.) Donc si fig+a est votre première figure dans la suite et fig+c la dernière, vous pouvez écrire :

    ... voir les figures \vrefrange{fig+a}{fig+c} ...

qui sera alors mis en page sous la forme

… voir les figures 3.4 à 3.6 pages 23–24 … ou, s’il se trouve qu’elles sont toutes sur la page suivante, sous la forme :

… voir les figures 3.4 à 3.6 sur la page suivante … c’est-à-dire que c’est la commande qui décide de ce qu’il faut écrire selon les endroits où les deux labels sont placés relativement l’un à l’autre ; cette commande est essentiellement bâtie sur la commande \vpagerefrange décrite ci-dessous. L’argument optionnel que la commande accepte est le texte à utiliser dans le cas où les deux labels sont finalement sur la même page.

1« … voir l’exemple qui montre … »

\vpagerefrange Cette commande est similaire à \vpageref mais prend deux arguments obligatoires qui sont les deux labels définissant un intervalle. Si les deux labels tombent sur la même page, la commande agit exactement comme \vpageref (avec un seul label), sinon elle produit quelque chose comme « on pages 15–18 » (voir les possibilités d’adaptation ci-dessous). L’argument optionnel qui est permis est le texte à utiliser dans le cas où les deux labels sont placés sur la page courante.

\vrefpagenum La commande \vrefpagenum est fournie pour permettre à l’utilisateur d’écrire ses propres petites commandes qui implémentent des fonctions similaires à celles fournies par les deux commandes précédentes. Elle prend deux arguments : le second est un label (c’est-à-dire utilisé comme dans \label ou un \ref) et le premier est un nom de commande arbitraire (assurez-vous que vous êtes seul à utiliser ce nom) qui reçoit le numéro de page lié à ce label. Si vous avez deux (ou plus) labels, vous pourriez retrouver leus numéros de page, les comparer et ensuite décider de ce qu’il faut imprimer. Par exemple, voici une définition qui n’est pas très sérieuse (elle utilise aussi le package ifthen)

 \newcommand\amusingversion[2]{%
   \vrefpagenum\firstnum{#1}%
   \vrefpagenum\secondnum{#2}%
   \ifthenelse{\equal\firstnum\secondnum}%
     {les définitions de \ref{#1} et \ref{#2} \vpageref{#1}}%
     {la définition de \ref{#1} \vpageref{#1} et de \ref{#2} \vpageref{#2}}%
 }
 ... \amusingversion{foo}{bar}

imprimera quelque chose comme

… les définitions de 3 et 4 sur la page précédente dans le cas où les deux labels sont sur la même page mais quelque chose comme

… la définition de 3 sur la page suivante et de 4 sur la page 13 au cas où ils sont sur des pages différentes.

3 Adaptation

Ce package supporte toutes les options définies par le package babel pour traduire les textes fixes vers des langues autres que l’anglais (certaines langues ont cependant besoin d’une mise à jour). Il supporte aussi quelques langues qui ne sont pas encore dans babel ; voyez la section sur les options plus loin^{2}. Vous pouvez aussi modifier certaines (ou toutes) des chaînes en redéfinissant les commandes

\reftextbefore suivantes : les références vers l’arrière utilisent \reftextbefore si le label est

\reftextfacebefore
\reftextafter
\reftextfaceafter

sur la page précédente mais invisible et \reftextfacebefore s’il est sur la page qui fait face (c’est-à-dire si le numéro de la page courante est impair). De même \reftextafter est utilisé lorsque le label vient sur la page suivante mais qu’il faut tourner la page et \reftextfaceafter s’il est sur la page suivante qui fait face.

2NdT : Si babel est utilisé, varioref sera cité après babel.

En fait, \reftextface... n’est utilisée que si l’usager a demandé une impression recto-verso.

\reftextfaraway Nous avons \reftextfaraway qui est utilisée chaque fois que le label et la référence sont distants de plus d’une page ou qu’ils ne sont pas numériques. Cette commande est un peu différente car elle a un argument, la chaîne de référence symbolique pour que l’on puisse utiliser \pageref dans son texte de remplacement.

\vreftextvario Enfin la commande \vreftextvario permet un peu de variation dans les textes engendrés. Cette commande, qui s’utilise à l’intérieur des macros produisant ces textes, prend deux arguments et choisit l’un des deux pour l’impression selon le nombre de commandes \vref ou \vpageref déjà rencontrées. Comme exemple, voyez les définitions de \reftextbefore etc. on page 7.

3.1 Ajouts en 1998

Les commandes \vrefrange et \vpagerefrange produisent leur texte en utilisant deux macros décrites ci-dessous. En les redéfinissant, on peut modifier les résultats pour s’adapter à des exigences particulières.

Elles ont toutes deux deux arguments obligatoires désignant le premier et le dernier label de l’intervalle.

\reftextpagerange Cette macro produit du texte qui décrit l’intervalle de pages des deux labels, par exemple en anglais, la forme par défaut est :

« on pages~\pageref{#1}--\pageref{#2}} ».

\reftextlabelrange Cette macro produit le texte qui décrit l’intervalle de figures, tables, ou de tout ce à quoi font référence les labels ; la forme par défaut en anglais est :

« \ref{#1} to~\ref{#2} ».

4 Options

Comme indiqué plus haut, ce package supporte toutes les options standard offertes par le système Babel pour adapter les chaînes produites. De plus, il offre l’option draft pour transformer les messages d’erreur en simples avertissements durant la phase de développement. L’option par défaut final produit un message d’erreur lorsqu’une chaîne engendrée tombe sur une frontière de page (voir la secction suivante).

5 Quelques avertissements

La définition de commandes telles que celles décrites ci-dessus pose quelques problèmes intéressants. Supposons, par exemple, qu’un texte généré tel que « on the next page » soit, par hasard, coupé par une fin de page. Si ceci se produit, il est très difficile de trouver une solution acceptable et en fait on peut même avoir un document qui oscille entre deux états (c’est-à-dire qu’une certaine chaîne est insérée, mais elle est inexacte à cause d’une telle coupure, ce qui fait insérer une autre chaîne lors de l’exécution suivante, qui fait que la première chaîne serait exacte de nouveau, ce qui fait insérer …). La réalisation actuelle de ce package émet donc un message d’erreur chaque fois que le texte engendré est coupé par une rupture de page, par exemple :

table 5 on the current ⟨page break⟩ page provoquerait une erreur, qui devrait être résolue par l’utilisateur en remplaçant la commande \vref par une \ref ordinaire juste avant l’exécution finale. Ceci n’est pas complètement satisfaisant mais dans un tel cas il n’y a pas vraiment de

\vrefwarning solution. Durant la préparation du document, alors que l’auteur modifie encore le texte, de tels messages d’erreur peuvent être assimilés à de simples avertissements en plaçant une commande \vrefwarning dans le préambule du document.

\vrefshowerrors Ceci équivaut à spécifier « draft » comme option de ce package. La commande \vrefshowerrors garantit que varioref s’arrête lorsqu’il détecte une boucle possible. C’est l’option par défaut et équivaut à spécifier « final » comme option.

Et enfin un dernier avertissement : chaque utilisation de \vref engendrera de manière interne deux noms de macros pour garder trace des positions des chaînes dans le document. En conséquence, vous pouvez épuiser l’espace des noms en mémoire si vous faites une utilisation trop forte de cette commande avec une petite

\fullref configuration TEX. Pour cette raison, la commande plus primitive \fullref est également disponible. Cette commande peut être utilisée chaque fois que vous êtes sûrs que le label et la référence ne peuvent pas apparaître sur des pages voisines.

6 Documentation du fichier driver (section non traduite)

The next bit of code contains the documentation driver file for TEX, i.e., the file that will produce the documentation you are currently reading. It will be extracted from this file by the docstrip program.

1 ⟨∗driver⟩

 2 \documentclass{ltxdoc}

3 ⟨/driver⟩

4 ⟨∗driver⟩

 5 \usepackage[english,french]{varioref}
 6 \GetFileInfo{varioref.sty}
 7 \setlength\hfuzz{1pt}    % ignore slight overfulls
 8 \EnableCrossrefs
 9 %\DisableCrossrefs   % Say \DisableCrossrefs if index is ready

10

11 \RecordChanges       % Gather update information
12 %\OnlyDescription    % comment out for implementation details
13 \begin{document}
14 \DocInput{f-varioref.dtx}
15 \end{document}

16 ⟨/driver⟩

7 The implementation

The main implementation idea is to generate an internal label command for every \vpageref and compare the page reference of this label with the page reference of the user-requested label. Since this means one additional macro name for each use of \vpageref or vref (which is implemented in terms of \vpageref) the memory requirements of this package may be high in terms of main and macro name memory. Since the information held in the internal labels is used only once one could envision a different scheme if suitable primitives for this kind of “one place information” would be provided by L^{A}TEX. This type of data structure is planned for L^{A}TEX3 but for the moment we have to live with the memory restrictions.

We start by checking if this file was already loaded. If not we identify the current version. This is actually done at the top of the file, so we comment it out here

17 ⟨∗package⟩

18 %\NeedsTeXFormat{LaTeX2e}[1994/06/01]
19 %\ProvidesPackage{varioref}[\filedate\space\fileversion\space
20 %                     LaTeX2e package for extended references (FMi)]

\vref@addto To support the use of babel we want to add the additional strings to the \extras⟨language⟩ commands. Since \addto in the current implementation of babel has a bug that does not allow to use arguments containing hashmarks we do this by hand.

21 \def\vref@addto#1#2{%
22 #2%
23 \@temptokena{#2}%
24 \ifx#1\undefined
25  \edef#1{\the\@temptokena}%
26 \else
27  \toks@\expandafter{#1}%
28  \edef#1{\the\toks@\the\@temptokena}%
29 \fi
30 \@temptokena{}\toks@\@temptokena

31 }

32 \@onlypreamble\vref@addto

7.1 Options

\vref@excuse Excuse that we don’t know the strings for a certain language.

33 \def\vref@excuse#1{%
34 \PackageWarningNoLine{varioref}{Sorry, language `#1'
35  not supported%
36  \MessageBreak
37  by in this version.
38  English strings used by default.
39  \MessageBreak
40  Please modify \protect\reftext... commands manually.%
41  \MessageBreak\MessageBreak
42  If you can suggest translations for
43  this language,%
44  \MessageBreak
45  please mail them
46  to the author of this package}}
47 \@onlypreamble\vref@excuse

\vref@stringwarning And we sometimes just don’t know some strings …

48 \def\vref@stringwarning#1{%
49 \PackageWarningNoLine{varioref}{Sorry, there is no proper
50  translation for the string\MessageBreak

51  produced by \protect#1\on@line.\MessageBreak
52  English string used instead.\MessageBreak
53  \MessageBreak
54  If you can suggest translations for
55  the current\MessageBreak
56  language, please mail them
57  to the author of this\MessageBreak package}}
\reftextfaceafter \reftextfacebefore \reftextafter \reftextbefore \reftextcurrent The options do set the the macros that generate the textual strings. Note, that

they do not start with a space, the space is already added in the main macro below.

58 \DeclareOption{american}
59 {\vref@addto\extrasamerican{%
60  \def\reftextfaceafter {on the \reftextvario{facing}{next} page}%
61  \def\reftextfacebefore{on the \reftextvario{facing}{preceding}
62  page}%
63  \def\reftextafter     {on the \reftextvario{following}{next} page}%
64  \def\reftextbefore    {on the \reftextvario{preceding page}{page
65  before}}%
66  \def\reftextcurrent   {on \reftextvario{this}{the current} page}%
67  \def\reftextfaraway#1{on page~\pageref{#1}}%
68  \def\reftextpagerange#1#2{on pages~\pageref{#1}--\pageref{#2}}%
69  \def\reftextlabelrange#1#2{\ref{#1} to~\ref{#2}}%
70 }}

The austrian defaults are the same as the german ones.

71 \DeclareOption{austrian}
72 {\vref@addto\extrasaustrian{%
73  \def\reftextfaceafter {auf der n\"achsten Seite}%
74  \def\reftextfacebefore{auf der vorherigen Seite}%
75  \let\reftextafter     \reftextfaceafter
76  \let\reftextbefore    \reftextfacebefore
77  \def\reftextcurrent   {auf dieser Seite}%
78  \def\reftextfaraway#1{auf Seite~\pageref{#1}}%
79  \def\reftextpagerange#1#2{auf Seiten~\pageref{#1}--\pageref{#2}}%
80  \def\reftextlabelrange#1#2{\ref{#1} bis~\ref{#2}}%
81 }}

Text for brazil defaults was contributed by Alcino Dall Igna Junior

(adij@di.ufpe.br).
82 \DeclareOption{brazil}
83 {\vref@addto\extrabrazil{%
84  \def\reftextfaceafter {na \reftextvario{p\'agina oposta}{pr\'oxima
85  p\'agina}}%
86  \def\reftextfacebefore{na p\'agina \reftextvario{oposta}{anterior}}%
87  \def\reftextafter     {na \reftextvario{p\'agina seguinte}{pr\'oxima
88  p\'agina}}%
89  \def\reftextbefore{na p\'agina \reftextvario{anterior}{precedente}}%
90  \def\reftextcurrent   {\reftextvario{nesta p\'agina}{na p\'agina
91  corrente}}%
92  \def\reftextfaraway#1{na p\'agina~\pageref{#1}}%
93  \def\reftextpagerange#1#2{\vref@stringwarning\reftextpagerange
94  on pages~\pageref{#1}--\pageref{#2}}%
95  \def\reftextlabelrange#1#2{\vref@stringwarning\reflabelpagerange
96  \ref{#1} to~\ref{#2}}%

 97 }}

Text for Breton defaults was contributed by Christian ROLLAND

 (Christian.Rolland@univ-brest.fr).
 98 \DeclareOption{breton}
 99 {\vref@excuse{breton}%
100 \vref@addto\extrasbreton{%
101  \def\reftextfaceafter {war ar bajenn \reftextvario{a-dal}{da heul}}%
102  \def\reftextfacebefore{war ar bajenn \reftextvario{a-dal}{a-raok}}%
103  \def\reftextafter     {war ar bajenn da heul}%
104  \def\reftextbefore    {war ar bajenn a-raok}%
105  \def\reftextcurrent   {war ar \reftextvario{bajenn-ma\~n}%
106  {bajenn war-wel}}%
107  \def\reftextfaraway#1{war ar bajenn~\pageref{#1}}%
108  \def\reftextpagerange#1#2{\vref@stringwarning\reftextpagerange
109  on pages~\pageref{#1}--\pageref{#2}}%
110  \def\reftextlabelrange#1#2{\vref@stringwarning\reflabelpagerange
111  \ref{#1} to~\ref{#2}}%

112 }}

Text for catalan defaults was contributed by Robert Fuster (rfuster@mat.upv.es).

113 \DeclareOption{catalan}
114 {\vref@addto\extrascatalan{%
115  \def\reftextfaceafter {a la p\`agina seg\"uent}%
116  \def\reftextfacebefore{a la p\`agina anterior}%
117  \let\reftextafter     \reftextfaceafter
118  \let\reftextbefore    \reftextfacebefore
119  \def\reftextcurrent   {en aquesta p\`agina}%
120  \def\reftextfaraway#1{a la p\`agina~\pageref{#1}}%
121  \def\reftextpagerange#1#2{\vref@stringwarning\reftextpagerange
122  on pages~\pageref{#1}--\pageref{#2}}%
123  \def\reftextlabelrange#1#2{\vref@stringwarning\reflabelpagerange
124  \ref{#1} to~\ref{#2}}%

125 }}

126 \DeclareOption{croatian}
127 {\vref@excuse{croatian}%
128 \vref@addto\extrascroatian{%
129  \def\reftextfaceafter {on the \reftextvario{facing}{next} page}%
130  \def\reftextfacebefore{on the \reftextvario{facing}{preceding}
131  page}%
132  \def\reftextafter     {on the \reftextvario{following}{next} page}%
133  \def\reftextbefore    {on the \reftextvario{preceding page}{page
134  before}}%
135  \def\reftextcurrent   {on \reftextvario{this}{the current} page}%
136  \def\reftextfaraway#1{on page~\pageref{#1}}%
137  \def\reftextpagerange#1#2{on pages~\pageref{#1}--\pageref{#2}}%
138  \def\reftextlabelrange#1#2{\ref{#1} to~\ref{#2}}%

139 }}

140 \DeclareOption{czech}
141 {\vref@excuse{czech}%
142 \vref@addto\extrasczech{%
143  \def\reftextfaceafter {on the \reftextvario{facing}{next} page}%
144  \def\reftextfacebefore{on the \reftextvario{facing}{preceding}
145  page}%

146  \def\reftextafter     {on the \reftextvario{following}{next} page}%
147  \def\reftextbefore    {on the \reftextvario{preceding page}{page
148  before}}%
149  \def\reftextcurrent   {on \reftextvario{this}{the current} page}%
150  \def\reftextfaraway#1{on page~\pageref{#1}}%
151  \def\reftextpagerange#1#2{on pages~\pageref{#1}--\pageref{#2}}%
152  \def\reftextlabelrange#1#2{\ref{#1} to~\ref{#2}}%

153 }}

Defaults for Danish provided by Torsten Martinsen (tmar91@kom.auc.dk).

154 \DeclareOption{danish}
155 {\vref@addto\extrasdanish{%
156  \def\reftextfaceafter {p\aa{} \reftextvario{modst\aa ende}%
157  {n\ae ste} side}%
158  \def\reftextfacebefore{p\aa{} \reftextvario{modst\aa ende}%
159  {forrige} side}%
160  \def\reftextafter     {p\aa{} \reftextvario{den f\o lgende}%
161  {n\ae ste} side}%
162  \def\reftextbefore    {p\aa{} \reftextvario{forrige side}
163  {foreg\aa ende side}}%
164  \def\reftextcurrent   {p\aa{} denne side}%
165  \def\reftextfaraway#1{p\aa{} side~\pageref{#1}}%
166  \def\reftextpagerange#1#2{\vref@stringwarning\reftextpagerange
167  on pages~\pageref{#1}--\pageref{#2}}%
168  \def\reftextlabelrange#1#2{\vref@stringwarning\reflabelpagerange
169  \ref{#1} to~\ref{#2}}%

170 }}

Default string for dutch have been contributed by Frank Poppe (POPPE@SWOV.NL). This option currently supports one additional string macro \refpagename so that you can easily change to bladzijde instead of pagina if you prefer this word for “page”. However, I will not guarantee that this will survive future versions of this package, so use it on your own risk (you can always update the full strings to be on the safe side).

171 \DeclareOption{dutch}
172 {\vref@addto\extrasdutch{%
173  \def\refpagename{pagina}%
174  \def\reftextfaceafter {op de \reftextvario{rechter \refpagename}%
175  {\refpagename\ hiernaast}}%
176  \def\reftextfacebefore{op de \reftextvario{linker \refpagename}%
177  {\refpagename\ hiernaast}}%
178  \def\reftextafter     {op de \reftextvario{volgende \refpagename}%
179  {\refpagename\ hierna}}%
180  \def\reftextbefore    {op de \reftextvario{vorige \refpagename}%
181  {\refpagename\ hiervoor}}%
182  \def\reftextcurrent   {op deze \refpagename}%
183  \def\reftextfaraway#1{op \refpagename~\pageref{#1}}%
184  \def\reftextpagerange#1#2{op pagina's~\pageref{#1} t/m~\pageref{#2}}%
185  \def\reftextlabelrange#1#2{\ref#1 t/m~\ref{#2}}%

186 }}

187 \DeclareOption{english}
188 {\vref@addto\extrasenglish{%
189  \def\reftextfaceafter {on the \reftextvario{facing}{next} page}%
190  \def\reftextfacebefore{on the \reftextvario{facing}{preceding}

191  page}%
192  \def\reftextafter     {on the \reftextvario{following}{next} page}%
193  \def\reftextbefore    {on the \reftextvario{preceding page}{page
194  before}}%
195  \def\reftextcurrent   {on \reftextvario{this}{the current} page}%
196  \def\reftextfaraway#1{on page~\pageref{#1}}%
197  \def\reftextpagerange#1#2{on pages~\pageref{#1}--\pageref{#2}}%
198  \def\reftextlabelrange#1#2{\ref{#1} to~\ref{#2}}%

199 }}

200 \DeclareOption{esperanto}
201 {\vref@excuse{esperanto}%
202 \vref@addto\extrasesperanto{%
203  \def\reftextfaceafter {on the \reftextvario{facing}{next} page}%
204  \def\reftextfacebefore{on the \reftextvario{facing}{preceding}
205  page}%
206  \def\reftextafter     {on the \reftextvario{following}{next} page}%
207  \def\reftextbefore    {on the \reftextvario{preceding page}{page
208  before}}%
209  \def\reftextcurrent   {on \reftextvario{this}{the current} page}%
210  \def\reftextfaraway#1{on page~\pageref{#1}}%
211  \def\reftextpagerange#1#2{on pages~\pageref{#1}--\pageref{#2}}%
212  \def\reftextlabelrange#1#2{\ref{#1} to~\ref{#2}}%

213 }}

The finnish strings were suggested by Matti Rintala (bitti@cs.tut.fi).

214 \DeclareOption{finnish}
215 {\vref@addto\extrasfinnish{%
216  \def\reftextfaceafter {\reftextvario{viereisell\"a}%
217  {seuraavalla} sivulla}%
218  \def\reftextfacebefore{\reftextvario{viereisell\"a}%
219  {edellisell\"a} sivulla}%
220  \def\reftextafter     {seuraavalla sivulla}%
221  \def\reftextbefore    {edellisell\"a sivulla}%
222  \def\reftextcurrent   {t\"all\"a sivulla}%
223  \def\reftextfaraway#1{sivulla~\pageref{#1}}%
224  \def\reftextpagerange#1#2{\vref@stringwarning\reftextpagerange
225  on pages~\pageref{#1}--\pageref{#2}}%
226  \def\reftextlabelrange#1#2{\vref@stringwarning\reflabelpagerange
227  \ref{#1} to~\ref{#2}}%

228 }}

French defaults are provided by Daniel Flippo (Daniel.Flipo@univ-lille1.fr).

229 \DeclareOption{french}
230 {\vref@addto\extrasfrench{%
231  \def\reftextfaceafter {page \reftextvario{ci-contre}{suivante}}%
232  \def\reftextfacebefore{page \reftextvario{ci-contre}%
233  {pr\'ec\'edente}}%
234  \def\reftextafter     {page suivante}%
235  \def\reftextbefore    {page pr\'ec\'edente}%
236  \def\reftextcurrent   {de la pr\'esente page}%
237  \def\reftextfaraway#1{page~\pageref{#1}}%
238  \def\reftextpagerange#1#2{pages~\pageref{#1}--\pageref{#2}}%
239  \def\reftextlabelrange#1#2{\ref{#1} \`a~\ref{#2}}%

240 }}

Galician defaults are provided by Matthias Moebius

 (Matthias.Moebius@uni-konstanz.de).
241 \DeclareOption{galician}
242 {\vref@excuse{galician}%
243 \vref@addto\extrasgalician{%
244  \def\reftextfaceafter {na seguinte p\'axina}%
245  \def\reftextfacebefore{na p\'agina anterior}%
246  \let\reftextafter     \reftextfaceafter
247  \let\reftextbefore    \reftextfacebefore
248  \def\reftextcurrent   {nesta p\'axina}%
249  \def\reftextfaraway#1{na p\'axina~\pageref{#1}}%
250  \def\reftextpagerange#1#2{\vref@stringwarning\reftextpagerange
251  on pages~\pageref{#1}--\pageref{#2}}%
252  \def\reftextlabelrange#1#2{\vref@stringwarning\reflabelpagerange
253  \ref{#1} to~\ref{#2}}%

254 }}

There are no good variants for German (I think and still think but this is a matter of taste :-). The following definitions were recently suggested to me but since the original are in for a long time i don’t want to change them now since that could make a lot of documents change their formatting. If you fancy them, add a redefinition of the corresponding macro(s) to the preamble of your document.

     \def\reftextfaceafter {auf der \reftextvario
           {gegen\"uberliegenden}{anderen} Seite}%
     \def\reftextfacebefore {auf der \reftextvario
           {gegen\"uberliegenden}{anderen} Seite}%
     \def\reftextafter     {auf der \reftextvario
           {n\"achsten}{folgenden} Seite}%
     \def\reftextbefore    {auf der \reftextvario
           {vorigen}{vorhergehenden} Seite}%
     \def\reftextcurrent   {\reftextvario
           {auf dieser}{diese} Seite}%
255 \DeclareOption{german}
256 {\vref@addto\extrasgerman{%
257  \def\reftextfaceafter {auf der n\"achsten Seite}%
258  \def\reftextfacebefore{auf der vorherigen Seite}%
259  \let\reftextafter     \reftextfaceafter
260  \let\reftextbefore    \reftextfacebefore
261  \def\reftextcurrent   {auf dieser Seite}%
262  \def\reftextfaraway#1{auf Seite~\pageref{#1}}%
263  \def\reftextpagerange#1#2{auf Seiten~\pageref{#1}--\pageref{#2}}%
264  \def\reftextlabelrange#1#2{\ref{#1} bis~\ref{#2}}%

265 }}

Defaults for greek suggested by Apostolos Syropoulos

 (apostolo@obelix.ee.duth.gr).
266 \DeclareOption{greek}
267 {\vref@addto\extrasgreek{%
268  \def\reftextfaceafter {sthn \reftextvario{paro'usa}%
269  {ep'omenh} sel'ida}%
270  \def\reftextfacebefore{sthn \reftextvario{paro'usa}{prohgo'umenh}
271  sel'ida}%
272  \def\reftextafter     {sthn ep'omenh sel'ida}%

273  \def\reftextbefore    {sthn prohgo'umenh sel'ida}%
274  \def\reftextcurrent   {s'' aut'h th sel'ida}%
275  \def\reftextfaraway#1{sth sel'ida\nobreakspace\pageref{#1}}%
276  \def\reftextpagerange#1#2{stis sel'ides\nobreakspace
277  \pageref{#1}---\pageref{#2}}%
278  \def\reftextlabelrange#1#2{\ref{#1} ws\nobreakspace\ref{#2}}%

279 }}

Defaults for Italian suggested by Giovanni Pensa (pensa@dsi.unimi.it) with iTEXnici.

280 \DeclareOption{italian}
281 {\vref@addto\extrasitalian{%
282  \def\reftextfaceafter {\reftextvario{a fronte}%
283  {nella pagina successiva}}%
284  \def\reftextfacebefore{\reftextvario{a fronte}%
285  {nella pagina precedente}}%
286  \def\reftextafter     {nella pagina \reftextvario{seguente}%
287  {successiva}}%
288  \def\reftextbefore    {nella pagina precedente}%
289  \def\reftextcurrent   {in questa pagina}%
290  \def\reftextfaraway#1{a pagina~\pageref{#1}}%
291  \def\reftextpagerange#1#2{\vref@stringwarning\reftextpagerange
292  on pages~\pageref{#1}--\pageref{#2}}%
293  \def\reftextlabelrange#1#2{\vref@stringwarning\reflabelpagerange
294  \ref{#1} to~\ref{#2}}%

295 }}

Defaults for Hungarian by Jeff Goldberg (J.goldberg@Cranfield.ac.uk). There is a problem with the use of the definite article a or az in Hungarian before expansions of \vref or \ref. The problem is that the the word should be az if the number following would begin with a vowel if spelled out, and a if the number would begin with a consonant.

The option assumes that there is a command \aza defined which helps resolving this problem.^{3}

296 \DeclareOption{magyar}
297 {\vref@addto\extrasmagyar{%
298  \def\reftextfaceafter {a k\"o\-vet\-kez\H{o} ol\-da\-lon}%
299  \def\reftextfacebefore{az el\H{o}\-z\H{o} ol\-da\-lon}%
300  \def\reftextafter     {a k\"o\-vet\-kez\H{o} ol\-da\-lon}%
301  \def\reftextbefore    {az el\H{o}\-z\H{o} ol\-da\-lon}%
302  \def\reftextcurrent   {ezen az ol\-da\-lon}%
303  \def\reftextfaraway#1{\aza{\pageref{#1}} \pageref{#1}.~ol\-da\-lon}%
304  \def\reftextpagerange#1#2{\vref@stringwarning\reftextpagerange
305  on pages~\pageref{#1}--\pageref{#2}}%
306  \def\reftextlabelrange#1#2{\vref@stringwarning\reflabelpagerange
307  \ref{#1} to~\ref{#2}}%
308  \AtBeginDocument{\providecommand\aza[1]{a/az%
309  \PackageError{varioref}{%
310  Proper definition for command \noexpand\aza missing}%
311  {You need to (re)define the command \noexpand\aza that
312  takes one argument (a number or a \noexpand\pageref command)
313  and produces the string `a' or `az' depending on the argument

3This information is actually quite old but unfortunately never made it into varioref. In case any work has been undertaken to resolve this please inform the author about it.

314  value. It should also accept an optional argument (default `l')
315  to denote whether or not the string should be lowercase or
316  uppercase.}}}%

317 }}

The Norwegian and ‘nynorsk translations have been provided by Dag F Langmyhr

 <dag@ifi.uio.no>.
318 \DeclareOption{norsk}
319 {\vref@addto\extrasnorsk{%
320  \def\reftextfaceafter {p\aa{} neste side}%
321  \def\reftextfacebefore{p\aa{} forrige side}%
322  \def\reftextafter     {p\aa{} neste side}%
323  \def\reftextbefore    {p\aa{} forrige side}%
324  \def\reftextcurrent   {p\aa{} denne siden}%
325  \def\reftextfaraway#1{p\aa{} side~\pageref{#1}}%
326  \def\reftextpagerange#1#2{p\aa{} side~\pageref{#1}--\pageref{#2}}%
327  \def\reftextlabelrange#1#2{\ref{#1} til~\ref{#2}}%

328 }}

329 \DeclareOption{nynorsk}
330 {\vref@addto\extrasnynorsk{%
331  \def\reftextfaceafter {p\aa{} den neste sida}%
332  \def\reftextfacebefore{p\aa{} den f\o{}rre sida}%
333  \def\reftextafter     {p\aa{} \reftextvario{sida etter}%
334  {den neste sida}}%
335  \def\reftextbefore    {p\aa{} \reftextvario{sida f\o{}r}%
336  {den f\o{}rre sida}}%
337  \def\reftextcurrent   {p\aa{} denne sida}%
338  \def\reftextfaraway#1{p\aa{} side~\pageref{#1}}%
339  \def\reftextpagerange#1#2{p\aa{} side~\pageref{#1}--\pageref{#2}}%
340  \def\reftextlabelrange#1#2{\ref{#1} til~\ref{#2}}%

341 }}

The polish translations have been provided by Tomasz Michniewski <tomekm@ias.wat.waw.pl>. The use of the command \eob and aob etc. requires appropriate definitions as provided, for example, by the babel system. This should probably be handled differently but it would require modifications in babel’s language support.

342 \DeclareOption{polish}
343 {\vref@addto\extraspolish{%
344  \def\reftextfaceafter {na \reftextvario{s\aob{}siedniej}%
345  {nast\eob{}pnej} stronie}%
346  \def\reftextfacebefore{na \reftextvario{s\aob{}siedniej}%
347  {poprzedniej} stronie}%
348  \def\reftextafter     {na nast\eob{}pnej stronie}%
349  \def\reftextbefore    {na poprzedniej stronie}%
350  \def\reftextcurrent   {na \reftextvario{tej
351  samej}{bie\zkb{}\aob{}cej} stronie}%
352  \def\reftextfaraway#1{na \pageref{#1}~stronie}%
353  \def\reftextpagerange#1#2{na stronach~\pageref{#1}--\pageref{#2}}%
354  \def\reftextlabelrange#1#2{od~\ref{#1} do~\ref{#2}}%

355 }}

356 \DeclareOption{portuges}
357 {\vref@excuse{portuges}%
358 \vref@addto\extrasportuges{%
359  \def\reftextfaceafter {on the \reftextvario{facing}{next} page}%

360  \def\reftextfacebefore{on the \reftextvario{facing}{preceding}
361  page}%
362  \def\reftextafter     {on the \reftextvario{following}{next} page}%
363  \def\reftextbefore    {on the \reftextvario{preceding page}{page
364  before}}%
365  \def\reftextcurrent   {on \reftextvario{this}{the current} page}%
366  \def\reftextfaraway#1{on page~\pageref{#1}}%
367  \def\reftextpagerange#1#2{on pages~\pageref{#1}--\pageref{#2}}%
368  \def\reftextlabelrange#1#2{\ref{#1} to~\ref{#2}}%

369 }}

370 \DeclareOption{romanian}
371 {\vref@excuse{romanian}%
372 \vref@addto\extrasromanian{%
373  \def\reftextfaceafter {on the \reftextvario{facing}{next} page}%
374  \def\reftextfacebefore{on the \reftextvario{facing}{preceding}
375  page}%
376  \def\reftextafter     {on the \reftextvario{following}{next} page}%
377  \def\reftextbefore    {on the \reftextvario{preceding page}{page
378  before}}%
379  \def\reftextcurrent   {on \reftextvario{this}{the current} page}%
380  \def\reftextfaraway#1{on page~\pageref{#1}}%
381  \def\reftextpagerange#1#2{on pages~\pageref{#1}--\pageref{#2}}%
382  \def\reftextlabelrange#1#2{\ref{#1} to~\ref{#2}}%

383 }}

The text for russian was taken from the book in Russian by I. A. Kotelnikov and P. Z. Chebotaev, and adapted to the encoding-independent form by Vladimir

 Volovich (vvv@vvv.vsu.ru).
384 \DeclareOption{russian}
385 {\vref@addto\extrasrussian{%
386  \def\reftextfaceafter{\cyrn\cyra\ \reftextvario{\cyrp\cyrr\cyro
387  \cyrt\cyri\cyrv\cyro\cyrp\cyro\cyrl\cyro\cyrzh\cyrn\cyro\cyrishrt}%
388  {\cyrs\cyrl\cyre\cyrd\cyru\cyryu\cyrshch\cyre\cyrishrt}\ \cyrs\cyrt
389  \cyrr\cyra\cyrn\cyri\cyrc\cyre}%
390  \def\reftextfacebefore{\cyrn\cyra\ \reftextvario{\cyrp\cyrr\cyro
391  \cyrt\cyri\cyrv\cyro\cyrp\cyro\cyrl\cyro\cyrzh\cyrn\cyro\cyrishrt}%
392  {\cyrp\cyrr\cyre\cyrd\cyrery\cyrd\cyru\cyrshch\cyre\cyrishrt}\
393  \cyrs\cyrt\cyrr\cyra\cyrn\cyri\cyrc\cyre}%
394  \def\reftextafter{\cyrn\cyra\ \cyrs\cyrl\cyre\cyrd\cyru\cyryu\cyrshch
395  \cyre\cyrishrt\ \cyrs\cyrt\cyrr\cyra\cyrn\cyri\cyrc\cyre}%
396  \def\reftextbefore{\cyrn\cyra\ \reftextvario{\cyrp\cyrr\cyre\cyrd
397  \cyrsh\cyre\cyrs\cyrt\cyrv\cyru\cyryu\cyrshch\cyre\cyrishrt}%
398  {\cyrp\cyrr\cyre\cyrd\cyrery\cyrd\cyru\cyrshch\cyre\cyrishrt}%
399  \ \cyrs\cyrt\cyrr\cyra\cyrn\cyri\cyrc\cyre}%
400  \def\reftextcurrent{\cyrn\cyra\ \reftextvario{\cyrerev\cyrt\cyro
401  \cyrishrt}{\cyrd\cyra\cyrn\cyrn\cyro\cyrishrt}\ \cyrs\cyrt\cyrr
402  \cyra\cyrn\cyri\cyrc\cyre}%
403  \def\reftextfaraway#1{\cyrn\cyra\ \cyrs.~\pageref{#1}}%
404  \def\reftextpagerange#1#2{\cyrn\cyra\ \cyrs\cyrt\cyrr\cyra\cyrn
405  \cyri\cyrc\cyra\cyrh~\pageref{#1}--\pageref{#2}}%
406  \def\reftextlabelrange#1#2{\cyrs~\ref{#1}\ \cyrp\cyro~\ref{#2}}%

407 }}

408 \DeclareOption{slovak}
409 {\vref@excuse{slovak}%

410 \vref@addto\extrasslovak{%
411  \def\reftextfaceafter {on the \reftextvario{facing}{next} page}%
412  \def\reftextfacebefore{on the \reftextvario{facing}{preceding}
413  page}%
414  \def\reftextafter     {on the \reftextvario{following}{next} page}%
415  \def\reftextbefore    {on the \reftextvario{preceding page}{page
416  before}}%
417  \def\reftextcurrent   {on \reftextvario{this}{the current} page}%
418  \def\reftextfaraway#1{on page~\pageref{#1}}%
419  \def\reftextpagerange#1#2{on pages~\pageref{#1}--\pageref{#2}}%
420  \def\reftextlabelrange#1#2{\ref{#1} to~\ref{#2}}%

421 }}

422 \DeclareOption{slovene}
423 {\vref@excuse{slovene}%
424 \vref@addto\extrasslovene{%
425  \def\reftextfaceafter {on the \reftextvario{facing}{next} page}%
426  \def\reftextfacebefore{on the \reftextvario{facing}{preceding}
427  page}%
428  \def\reftextafter     {on the \reftextvario{following}{next} page}%
429  \def\reftextbefore    {on the \reftextvario{preceding page}{page
430  before}}%
431  \def\reftextcurrent   {on \reftextvario{this}{the current} page}%
432  \def\reftextfaraway#1{on page~\pageref{#1}}%
433  \def\reftextpagerange#1#2{on pages~\pageref{#1}--\pageref{#2}}%
434  \def\reftextlabelrange#1#2{\ref{#1} to~\ref{#2}}%

435 }}

Text for spanish defaults was contributed by Julio Sanchez (jsanchez@gmv.es).

436 \DeclareOption{spanish}
437 {\vref@addto\extrasspanish{%
438  \def\reftextfaceafter {en la p\'agina siguiente}%
439  \def\reftextfacebefore{en la p\'agina anterior}%
440  \let\reftextafter     \reftextfaceafter
441  \let\reftextbefore    \reftextfacebefore
442  \def\reftextcurrent   {en esta p\'agina}%
443  \def\reftextfaraway#1{en la p\'agina~\pageref{#1}}%
444  \def\reftextpagerange#1#2{on pages~\pageref{#1}--\pageref{#2}}%
445  \def\reftextlabelrange#1#2{\ref{#1} to~\ref{#2}}%

446 }}

The text for swedish was contributed by Mats Dahlgren (matsd@sssk.se).

447 \DeclareOption{swedish}
448 {\vref@addto\extrasswedish{%
449  \def\reftextfaceafter {p\aa\ \reftextvario{motst\aa ende}%
450  {n\"{a}sta} sida}%
451  \def\reftextfacebefore{p\aa\ \reftextvario{motst\aa ende}%
452  {f\"{o}reg\aa ende} sida}%
453  \def\reftextafter     {p\aa\ \reftextvario{f\"{o}ljande}%
454  {n\"{a}sta} sida}%
455  \def\reftextbefore    {p\aa\ f\"{o}reg\aa ende sida}%
456  \def\reftextcurrent   {p\aa\ denna sida}%
457  \def\reftextfaraway#1{p\aa\ sidan~\pageref{#1}}%
458  \def\reftextpagerange#1#2{p\aa\
459  sidorna~\pageref{#1}--\pageref{#2}}%
460  \def\reftextlabelrange#1#2{\ref{#1} till~\ref{#2}}%

461 }}

462 \DeclareOption{turkish}
463 {\vref@excuse{turkish}%
464 \vref@addto\extrasturkish{%
465  \def\reftextfaceafter {on the \reftextvario{facing}{next} page}%
466  \def\reftextfacebefore{on the \reftextvario{facing}{preceding}
467  page}%
468  \def\reftextafter     {on the \reftextvario{following}{next} page}%
469  \def\reftextbefore    {on the \reftextvario{preceding page}{page
470  before}}%
471  \def\reftextcurrent   {on \reftextvario{this}{the current} page}%
472  \def\reftextfaraway#1{on page~\pageref{#1}}%
473  \def\reftextpagerange#1#2{on pages~\pageref{#1}--\pageref{#2}}%
474  \def\reftextlabelrange#1#2{\ref{#1} to~\ref{#2}}%

475 }}

We support francais as an alternative to french since people might be used to it, but we discurrage it.

476 \DeclareOption{francais}{%
477 \typeout{Please use `french' instead of `francais'}%
478 \ExecuteOptions{french}}
479 \DeclareOption{germanb}{%
480 \typeout{Please use `german' instead of `germanb'}%
481 \ExecuteOptions{german}}

During document preparation errors due to \vref are usually of not much interest. For this reason the draft option turns them into warnings by issuing a \vrefwarning command. The final option (default) stops with an error message when varioref detects a possible loop.

482 \DeclareOption{draft}{\AtEndOfPackage\vrefwarning}
483 \DeclareOption{final}{\AtEndOfPackage\vrefshowerrors} % the default

After all options are declared we execute the default option english to set up the defaults and then call \ProcessOptions* to handle any option passed to the package. The star form is used since we want to execute the options in the order they are given (in case this isn’t used together with the babel package).

484 \ExecuteOptions{english,final}
485 \ProcessOptions*

7.2 Defining the main macros

\vr@cnt To generate new labels we use a counter and construct the internal label names by prefixing the current counter value with the string vr@. We need a L^{A}TEX counter to get \includes handled correctly.

486 \newcounter{vrcnt}

\vpageref \@vpageref The command \vpageref generates the appropriate string by first parsing the optional arguments (if any) and then compares the internal and the user label. This command should be robust since the user might put it anywhere.

487 \DeclareRobustCommand\vpageref{\@ifnextchar[%

The default for the first optional argument is the string hidden in the macro

 \reftextcurrent.

488 \@vpageref{\@vpageref[\reftextcurrent]}%

489 }

490 \def\@vpageref[#1]{\@ifnextchar[%

The default for the second optional argument is a space which is prefixed by \unskip to get rid of any leading space inserted already.

491 {\@@vpageref{#1}}{\@@vpageref{#1}[\unskip\space]}}

\@@vpageref The \@@vpageref macro finally generates the references by comparing the value of an internal label with the value of the user label.

492 \def\@@vpageref#1[#2]#3{%

First it switches to horizontal mode if necessary and also removes any leading space.

493 \leavevmode\unskip

Then it advances the counter \c@vrcnt by one which is used to generate internal label names.

494 \global\advance\c@vrcnt\@ne

Then it checks if for the current value of \c@vrcnt a label command was issued in the last run. If not it pretends that there was one with the value {??}{??}. Thereafter it stores the the pageref value for this label in the macro \@tempa.

495 \vref@pagenum\@tempa{\the\c@vrcnt @vr}%

Here we check that the generated text is not going across a page boundary.

496 \vref@pagenum\@tempb{\the\c@vrcnt @xvr}%
497 {\let\@currentlabel\@empty

In version 1.0l the label string has been turned around so that the number comes first. This was done to allow easy explicit expansion of the number before it is passed to the \label command. In the babel system the argument of label was not expanded with the result that wrong label strings have been generated. This is a general problem that might need a completely different solution in babel but for now the change below (and in some other places in the code) should solve the problem for this special combination of packages.

498 \expandafter\label\expandafter{\the\c@vrcnt @xvr}}%

Inside displays of the amsmath package the \label command is redefined which makes the test for loops incorrect if a \vref is used in, say, \intertext. So we test this condition first and only do the test if \label doesn’t have a special meaning.

499 \ifx\label\label@in@display\else
500  \ifx\@tempa\@tempb\else

If both points do not fall onto the same page with either issue an error or a warning message.

501  \vref@err{\noexpand\vref at page boundary
502  \@tempb-\@tempa\space (may loop)%

503 }%

504  \fi
505 \fi

Same game for the user requested label; this time the page reference is saved in

\@tempb.
506 \vrefpagenum\@tempb{#3}%

Now after the internal label has served its purpose if would be nice to free the memory it occupies by using something like

 \global\expandafter\let
        \csname r@\the\c@vrcnt @vr\endcsname\@empty

But this is not possible because it would result in getting ‘Labels may have changed… ’ warnings for every run. Now we are ready to produce the textual strings. Since we have removed any leading space we now insert a space and then compare the two page references.

507 \space
508 \ifx\@tempa\@tempb

If they are the same we insert the first argument into the input stream. Otherwise we insert the second argument. Recall that those are the two optional arguments

of ....
509  #1%
510 \else
511  #2%

Now we check if the page number of the referenced object (stored in \@tempb is a single positive number.

512  \is@pos@number\@tempb

513 {%

If so, we check if the current position (stored in \@tempa) is a positive number. If this is the case we assign this number to the counter register \@tempcnta and add one to it.

514  \is@pos@number\@tempa
515  {\@tempcnta\@tempa
516  \advance\@tempcnta\@ne

517 }%

If it is not a positive number we assign the largest possible number to \@tempcnta and thereby pretending that label and reference are miles away from each other.

518  {\@tempcnta\maxdimen}%

Now we are ready to check if reference and object are on nearby pages. \@tempb will expand to the page number of the object (and we know that this is a number) and \@tempcnta is either one higher than the reference page or completely out of bounds. So if both represend the same value then the object lies one page after its reference.

519  \ifnum \@tempb =\@tempcnta

Thus if the object falls onto an odd page then the reference is on the facing even page (and so we insert \reftextfaceafter), otherwise the object can not be seen from the reference (and we in insert \reftextafter). Don’t be surprised if we are not using \@tempb in the check. Since \@tempcnta has the same value it is faster to use the register instead of parsing the macro contents anew.

520  \ifodd\@tempcnta

In fact we are going to use \reftextfaceafter only if we are doing two-sided printing, otherwise \reftextafter is always used. Since the value of \if@twoside is evaluated before reading in packages we could do better (saving some tokens) by defining the current macro in dependence of this boolean.

521  \if@twoside
522  \reftextfaceafter
523  \else
524  \reftextafter
525  \fi
526  \else
527  \reftextafter
528  \fi

If the object is not on the page following the reference we check if it is on the page before the reference. In L^{A}TEX this situation is not too common, for example with floats it normally does not occur, but of course it isn’t impossible if you more than one reference to the same object, or if you have back references to sections, theorems, etc. To test this we now substract two from the current value of \@tempcnta (which was set to one higher as the reference page number). Note, that substraction is also possible if the value was \maxdimen — we still get something that is much larger than any sensible page number.

529  \else
530  \advance\@tempcnta-2

If now \@tempb and \@tempcnta have the same value then the object lies one page before the reference.

531  \ifnum \@tempb =\@tempcnta

Again we have to check for odd or even pages to distinguish between the facing and the non-facing situation.

532  \ifodd\@tempcnta
533  \reftextbefore
534  \else

Again the \reftextfacebefore only if @twoside evaluates to true.

535  \if@twoside
536  \reftextfacebefore
537  \else
538  \reftextbefore
539  \fi
540  \fi

If the above test also returns false then we have object and references on pages which are far away or don’t contain simple page numbers. Therefore we generate the \reftextfaraway string. Recall that this is a macro which has the user label as an argument.

541  \else
542  \reftextfaraway{#3}%
543  \fi
544  \fi

545 }%

We do the same if our first test (that the page with the object has a positive page number) turns out to be false.

546  {\reftextfaraway{#3}}%
547 \fi

Finally we generate the internal label so that it can be check on the next run. This means that we compare the position after the string with the position of the referenced object. There is one thing to note: to conserve space we locally make \@currentlabel empty since we are only interested in the page number value of this internal label.

548 {\let\@currentlabel\@empty

The setting of \df@label is a concession to the amsmath package which might redefine \label and expects this macro to be empty in certain circumstances.

549 \let\df@label\@empty
550 \expandafter\label\expandafter{\the\c@vrcnt @vr}}%

551 }

\vrefwarning \vrefshowerrors \vref@err When the \vref command detects a possible crossing over a page boundary it will call \vref@err to generate an error message. During document preparation one can turn such errors into warnings by issuing a \vrefwarning declaration.

552 \def\vrefwarning{\def\vref@err{\PackageWarning{varioref}}}
553 \def\vrefshowerrors{\def\vref@err##1{\PackageError{varioref}{##1}%
554  {Please check the pages in question. You might need to replace
555  the \string\vref\MessageBreak
556  or \noexpand\vpageref by a normal \noexpand\(page)ref to
557  stop LaTeX running forever.}}}
\vref
558 \DeclareRobustCommand\vref[1]{%

The use of\nobreakspace or ~ after the \unskip means that this command will always produce a normal space while something like \nobreak\space will react to settings of \nonfrenchspacing. Unfortunately the latter will also act in cases where one really wants a normal space, e.g., in Fig.~\vref{..}, resulting in a large extra space after the dot. For this reason the first solution is used.

559 \leavevmode\unskip\nobreakspace
560 \ref{#1}%
561 \@vpageref[\unskip]{#1}}

\is@pos@number The utility macro \is@pos@number takes three arguments: a string that is tested for being a valid integer and the actions to be taken in case the test comes out true or false.

We start by passing the string to the macro \is@pos@num after prefixing it with a 0 and adding a space after it. To have a well defined ending point we also add \@nil at the end.

562 \def\is@pos@number#1{\is@pos@num0#1\space\@nil}

Now we parse the enlarged string into a counter register. To get control back after everything that is regarded by TEX as a number is put into that register we assign \is@pos@num@ to the \afterassignment token. Since the string started with 0, we can be sure that the register assignment will be carried out without an error message. In case of counter assignments leading zeros are discarded.

563 \def\is@pos@num{\afterassignment\is@pos@num@ \count@}

Now we have to check whether or not the whole string was parsed into that register or some remainder was left over. Since we have added a \@nil token at the very end we can use that to delimit the argument of \is@pos@num@. Note, that the added space in \is@pos@number above gets parsed away by the counter assignment. If it would be missing, and the full string would consist of a number, TEXwould try to replace \@nil by its definition to see if it would contain additional digits and thus we would be in trouble at this point.

564 \def\is@pos@num@#1\@nil{%

Now we have to check if the argument is empty. We can do this with an \if test (i.e., in an expandable way) since we know for sure that it can not start with a digit

565 \if0#10%

Depending on the result we execute the second or third argument of the command \is@pos@number using a technique that removes the \else or \fi from the input stream first, so that in principle input stream parsing could be done from within the arguments.

566  \expandafter\@firstoftwo \else
567  \expandafter\@secondoftwo  \fi}

\reftextvario This macro gives a little bit of random variation in the text because the outcome depends on the number of \vref commands seen before.

568 \def\reftextvario#1#2{\ifodd\c@vrcnt #1\else#2\fi}

\fullref And here is the primitive command that always produces a \ref and a \pageref.

569 \def\fullref#1{\ref{#1} \reftextfaraway{#1}}

7.2.1 Supporting ranges

\vref@pagenum This command takes a label as #1 extracts the page number associated with it and saves the result in a csname which is passed as #1. If the label isn’t associates with a page number it essentially associates it with ?? for both the label number and the page, thus defining the label this way. This means that no label warning is generated for this label in case it is undefined.

570 \def\vref@pagenum#1#2{%
571 \@ifundefined{r@#2}{\@namedef{r@#2}{{??}{??}}}{}%
572 \edef#1{\expandafter\expandafter\expandafter
573  \@cdr\csname r@#2\endcsname
574  \@nil}%

575 }

\vrefpagenum Same as the above but this time we generate a warning for undefined labels.

576 \def\vrefpagenum#1#2{%
577 \@ifundefined{r@#2}%
578  {\G@refundefinedtrue
579  \@latex@warning{Reference `#2' on page \thepage \space
580  undefined}}{}%
581 \vref@pagenum{#1}{#2}}

\vpagerefrange If both labels refer to the same page then we produce a \vpageref. Otherwise we

produce the result of \reftextpagerange.

One could think of making this command even more clever by producing a special string if the difference between the two page number is one (but this is not done).

582 \newcommand\vpagerefrange[3][\reftextcurrent]{%
583 \vrefpagenum\@tempa{#2}%

584 \vrefpagenum\@tempb{#3}%
585 \ifx\@tempa\@tempb
586  \vpageref[#1]{#2}%
587 \else
588  \reftextpagerange{#2}{#3}%
589 \fi

590 }

\vrefrange
591 \newcommand\vrefrange[3][\reftextcurrent]
592 {\reftextlabelrange{#2}{#3} \vpagerefrange[#1]{#2}{#3}}

593 ⟨/package⟩

Change History

v0.1e

\vr@cnt: use LaTeX counter … 16 v0.1f

\@@vpageref: Add another label to

catch cross-overs . . . . . . . . . . 17 v0.1g

\vref@err: Macro added . . . . . . 20 \vrefwarning: Macro added …. 20

v0.1h

General: Small documentation

changes . . . . . . . . . . . . . . . . . 6 v1.0a

General: Upgrade to LaTeX2e … 1 v1.0b

\reftextcurrent: Replace in incor-

rect ‘def by ‘let . . . . . . . . . . . 11 \vref@addto: Avoid using babel

‘addto . . . . . . . . . . . . . . . . . . 6 The babel commands are starting with extras . . . . . . . . . . . . . . . 6

v1.0f

\reftextcurrent: Inserted missing

hash mark . . . . . . . . . . . . . . 15 v1.0g

\@@vpageref: Looping pages shown

in wrong order . . . . . . . . . . . 17

General: Use \DeclareRobustCommand

. . . . . . . . . . . . . . . . . . . . . . . . 1

\reftextcurrent: Brazil defaults

added. . . . . . . . . . . . . . . . . . . 7 \vref@err: Macro added . . . . . . 20

v1.0h

\@@vpageref: Change internal in-

terface . . . . . . . . . . . . . . . . . 17 \@vpageref: Pass first argument in

both cases . . . . . . . . . . . . . . 17 v1.0i

\@vpageref: Do it correctly …. 17 v1.0j

                                       \reftextcurrent: Added french

defaults . . . . . . . . . . . . . . . . 10 v1.0k

                                       \reftextcurrent: Corrected mis-

spelled cmd ‘extrasspanish … 15 v1.0l

\@@vpageref: Explicitly expand \label argument for babel . . 20 Explicitly expand ‘label argument for babel . . . . . . . . . . . 17

                                       \reftextcurrent: Added dutch de-

faults . . . . . . . . . . . . . . . . . . . 9 v1.0m

                                       \reftextcurrent: Added finnish

strings . . . . . . . . . . . . . . . . . 10 v1.0n

                                       \reftextcurrent: Added Danish

defaults . . . . . . . . . . . . . . . . . 9 v1.0o

                                       \reftextcurrent: Added defaults

for breton . . . . . . . . . . . . . . . . 8 v1.0p

                                       \reftextcurrent: Added swedish

strings . . . . . . . . . . . . . . . . . 15 v1.0q

                                       \reftextcurrent: Added defaults

for norsk . . . . . . . . . . . . . . . 13 Added defaults for nynorsk … 13

\vref@excuse: Use ‘PackageWarn-

ing . . . . . . . . . . . . . . . . . . . . . 6 v1.1b

                                       \reftextcurrent: Added defaults

for Italian . . . . . . . . . . . . . . . 12 v1.1c

\reftextcurrent: Added defaults

for catalan . . . . . . . . . . . . . . . 8 v1.1d

\reftextcurrent: Added defaults

for polish . . . . . . . . . . . . . . . 13 v1.1e

\vref: Don’t use \nobreakspace

(pr/1866) . . . . . . . . . . . . . . . 20 v1.1f

\reftextcurrent: Added galician

defaults . . . . . . . . . . . . . . . . 11 v1.1g

\@@vpageref: Support for AMS display (pr2175) . . . . . . . . . . . . 20 Test if inside AMS display (pr2175) . . . . . . . . . . . . . . . . 17

v1.1h

General: Added draft and final op-

tions . . . . . . . . . . . . . . . . . . 16

\vrefshowerrors: Macro added . 20

v1.2a

\reftextcurrent: Added american
defaults for \reftextpagerange
and \reftextlabelrange . . . . 7

Added austrian defaults (identical to german) . . . . . . . . . . . . 7

Added defaults for \reftextpagerange
and \reftextlabelrange . . . 14

Added defaults for greek . . . . . 11 Added defaults for magyar … 12 Added dutch defaults for

\reftextpagerange  and
\reftextlabelrange . . . . . . . . 9

Added english defaults for

\reftextpagerange  and
\reftextlabelrange . . . . . . . . 9

Added french defaults for

\reftextpagerange  and
\reftextlabelrange . . . . . . . 10

Added norsk defaults for

\reftextpagerange  and
\reftextlabelrange . . . . . . . 13

Added nynorsk defaults for

\reftextpagerange  and
\reftextlabelrange . . . . . . . 13

Added polish defaults for

\reftextpagerange  and
\reftextlabelrange . . . . . . . 13

Added russion strings . . . . . . . 14 Added swedish defaults for

\reftextpagerange  and
\reftextlabelrange . . . . . . . 15

Removed incorrect warning . . 12 Updated defaults for norsk … 13 Updated defaults for nynorsk . 13

\vpagerefrange: Macro added . . 21

\vref: Add \leavevmode . . . . . . 20

Use \nobreakspace (pr/2909) . 20 \vref@pagenum: Macro added … 21

\vref@stringwarning:  Macro

added . . . . . . . . . . . . . . . . . . . 6 \vrefpagenum: Macro added …. 21 \vrefrange: Macro added . . . . . 22