Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

varioref is a nice package as it will, when referencing, add "... on the [facing/next/preceding/following] page" if the reference and figure (or whatever object is being reference) are located on different pages. If there is more than a page in between, varioref will add "... on page XX".

However, I've noticed that all these "... on the [facing/next/etc] page" becomes a bit excessive; what I only really need is the "... on page XX" when the reference is far away. In my document, I've solved this by redefining the appropriate TeX definitions of varioref:

\makeatletter
\vref@addto\extrasenglish{%
  \def\reftextfaceafter{}
  \def\reftextfacebefore{}
  \def\reftextafter{}
  \def\reftextbefore{}
  \def\reftextcurrent{}
}
\makeatother

However, it doesn't feel very robust as this only works if english is selected as option. For american, I would have to copy-paste the same commands but replace extraenglish with extraamerican.

Is there some more efficient and "thorough" way of achieving the same thing, but for all language options? It is really not necessary in my case since I know I will be using english, but I'm interested out of curiosity. =)

share|improve this question
add comment

2 Answers 2

up vote 17 down vote accepted

As those commands are defined in any of the \extra... commands of babel (if babel is being used) one needs to either apply such changes for all languages in use or (the better alternative) one patches varioref itself. Fortunately the commands are used only in a single place namely \@@vpageref. So a general solution would be:

\documentclass{article}

\usepackage{varioref}
\usepackage{etoolbox}

\makeatletter
\patchcmd{\@@vpageref} {\reftextfacebefore}{\unskip}{\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}}
\patchcmd{\@@vpageref} {\reftextfaceafter}{\unskip}{\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}}

% for \reftextafter and \reftextbefore we have to patch twice

\patchcmd{\@@vpageref} {\reftextbefore}{\unskip}{\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}}
\patchcmd{\@@vpageref} {\reftextbefore}{\unskip}{\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}}

\patchcmd{\@@vpageref} {\reftextafter}{\unskip}{\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}}
\patchcmd{\@@vpageref} {\reftextafter}{\unskip}{\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}}

\show\@@vpageref  % have a look at the results
\makeatother

It is a bit crude as\@@vpageref now contains some absolutely useless code, ie a bunch of if-then-else statements without any code inside to execute. But who cares ;-)

The above also nicely works if you just want to disable the "face" ones but keep the ones where turning a page is required.

varioref + hyperref/nameref

If hyperref or nameref (a component of the hyperref bundle) is used in conjunction with varioref then the patching needs to be slightly different. In that case the macro that contains the calls is not \@@vpageref but \NR@vprageref. Furthermore it will get its definition only after \begin{document}, so the patch commands will look like this:

\makeatletter
\AtBeginDocument{%
\patchcmd{\NR@@vpageref} {\reftextfacebefore}{\unskip}{\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}}%
\patchcmd{\NR@@vpageref} {\reftextfaceafter}{\unskip}{\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}}%
\patchcmd{\NR@@vpageref} {\reftextbefore}{\unskip}{\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}}%
\patchcmd{\NR@@vpageref} {\reftextbefore}{\unskip}{\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}}%
\patchcmd{\NR@@vpageref} {\reftextafter}{\unskip}{\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}}%
\patchcmd{\NR@@vpageref} {\reftextafter}{\unskip}{\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}}}
\makeatother

Important: Even though this code is executed \AtBeginDocument it needs to be placed after hyperref was loaded, the reason being that hyperref also uses \AtBeginDocument to define \NR@@vpageref.

varioref + cleveref (+ hyperef)

If the cleveref package is used then some more/different patching is needed as this package unfortunately uses yet another "private" copy of parts of the varioref code, sigh. So in that case \cref@old@@vpageref needs to be patched, otherwise it is exactly the same approach:

\makeatletter

\patchcmd{\cref@old@@vpageref} {\reftextfacebefore}{\unskip}{\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}}
\patchcmd{\cref@old@@vpageref} {\reftextfaceafter}{\unskip}{\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}}

% for \reftextafter and \reftextbefore we have to patch twice

\patchcmd{\cref@old@@vpageref} {\reftextbefore}{\unskip}{\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}}
\patchcmd{\cref@old@@vpageref} {\reftextbefore}{\unskip}{\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}}

\patchcmd{\cref@old@@vpageref} {\reftextafter}{\unskip}{\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}}
\patchcmd{\cref@old@@vpageref} {\reftextafter}{\unskip}{\typeout{*** SUCCESS ***}}{\typeout{*** FAIL ***}}
\makeatletter

Update/Correction

As Gabriel pointed out, has initial idea as well as my generalization of it, i.e., patching the commands \reftextafterand friends to simply do nothing has the side effect that you will end up with an extra space. The reason for this is that this space is generated automatically by \vref after the first number with the assumption that some text (such as "on the next page") will follow. So the correct way to deal with this is to patch the commands not by taking the mout but by replacing them with \unskip thereby removing that extra space again.

In the above code that is already corrected!

share|improve this answer
    
A nice thing about this approach compared to mine is that I don't have the problem of possible trailing whitespace. However, this solution doesn't appear to work when hyperref is included in the document (the patch has no effect, although it says "SUCCESS" for all patches). –  gablin Feb 11 '12 at 13:20
    
That is most certainly the case (that it doesn't work I mean). As hyperref changes the definitions of the vairoref internals you need to apply the same approach to the definitions in hyperef whatever they are), i.e., find the commands that execute \reftextafterand friends and patch them by taking the call out. Might add the corrsponding defs later .. have to run –  Frank Mittelbach Feb 11 '12 at 14:26
    
added the patch for the hyperref case - not tested though –  Frank Mittelbach Feb 11 '12 at 17:18
    
Ah, now it seems to work. Thanks! –  gablin Feb 11 '12 at 17:29
1  
@LaRiFaRi loading order makes a difference! the patch has come after loading hyperref - I added a comment into the answer –  Frank Mittelbach Aug 8 '13 at 9:57
show 5 more comments

try:

\AtBeginDocument{\def\reftextfaceafter{\unskip}%
  \def\reftextfacebefore{\unskip}%
  \def\reftextafter{\unskip}%
  \def\reftextbefore{\unskip}%
  \def\reftextcurrent{\unskip}}
share|improve this answer
    
Does this also work when using multiple languages in the document? [Disclaimer: I haven't tested anything.] –  eldering Feb 11 '12 at 9:24
2  
This only works if babel is not used (or only used for a single language). The moment a language switch happens the definitions would get overwritten. –  Frank Mittelbach Feb 11 '12 at 10:02
    
It should also replace the string not with nothing but with \unskip to account for the extra space separating ref and pageref data –  Frank Mittelbach Aug 8 '13 at 6:35
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.