37

I would like to know if it is good practice, and if so how it can be achieved, to make references like: "as mentioned above...". Or am I going too far and should just type the word?

I've read something about varioref, but it seems to produce page or section numbers, but I can't find how you can just print if a section is above or below the reference.

0

3 Answers 3

21

You can also implement the labels yourself by having labels define a flag and references check the flag existence. Some additional bookkeeping is needed to warn about undefined labels.

\documentclass{article}

\makeatletter
\newcount\here@undef
\newcommand{\here}[1]{%
  \@ifundefined{here@#1@undef}{}{\advance\here@undef by -1}%
  \@namedef{here@#1}{}}
\newcommand{\where}[1]{%
  \@ifundefined{here@#1}{%
    below%
    \@ifundefined{here@#1@undef}{%
      \@namedef{here@#1@undef}{}%
      \advance\here@undef by 1
    }{}%
  }{%
    above%
  }%
}
\AtEndDocument{%
  \ifnum\here@undef>0
    \GenericWarning{}{There were undefined above/below labels}%
  \fi}
\makeatother

\begin{document}

As mentioned \where{test}, $2+2=4$.

We state that $2+2=4$.\here{test}

As mentioned \where{test}, $2+2=4$.

\end{document}

Result

6
  • 10
    I find it so strange that everything needs some extra programming and that such simple things that are easily found in word (shouldn't mention that here maybe ;)) are still undefined in Latex. This looks like a nice solution. Thanks.
    – Marnix
    Oct 22, 2011 at 9:50
  • 3
    @Marnix: This likely means that the feature is not widely used. Most people will not be arbitrarily moving text blocks after they write them, so there is no need for a programmatic choice: you write either above or below directly. Besides, such references are only useful at short distances, hence what varioref does in Daniel's answer. Oct 22, 2011 at 9:55
  • 1
    @Andrey: Would it not be better to just patch the label command (or use \myspeciallabel instead of `\label') and have that do what \here does now? Otherwise, you would need to add a \here command to many labels.
    – einpoklum
    Oct 28, 2011 at 8:07
  • 3
    Do you know why this doesn't work when the \here{...} command is put inside minipages, and where is used outside the minipage? Jun 24, 2013 at 7:13
  • 3
    @Marnix, conversely I suspect that one reason many prefer latex to word is precisely because they can write code like this to do just about anything, whereas in word it has to be a 'feature'. Jan 12, 2014 at 23:23
21

varioref can in fact do this you just need to give its \vpageref command a hint what to write to refer to an element on the same page. From the documentation:

But in fact \vpageref allows even more control. If has two optional arguments. With the first one, one can specify the text that should be used if label and reference fall on the same page. This is very helpful if both are near to each other, so that they may or may not be separated by a page break. In such a case we usually know (!) whether the reference is before or after the label so that we can say something like ... see the example \vpageref[above]{ex:foo} which shows ... which will then come out as “. . . see the example above which shows . . . ”

The point is that if there is a page break in between the label and the element, \vpageref will notice this and insert something like on the previous page instead.

4
  • 6
    After reading the documentation, it sounds quite certain that it will produce above when the page and the label are on the same page. But what if I always want to use above and below. This only seems to specify above assuming that the label is above the reference. I can't make this assumption.
    – Marnix
    Oct 21, 2011 at 23:22
  • 1
    I'd like to come back to this. What I'd like to achieve is that references to a chapter come with an arrow whose direction depends on whether the referenced chapter is above or below (←/→ chapter 2). Neither the accepted solution nor varioref does allow this kind of automatic switching between 'above' and 'below'.
    – Simifilm
    May 15, 2013 at 8:51
  • @Simifilm: Please consider asking this as a dedicated question, including a complete minimal working example (MWE) that illustrates your problem.
    – Daniel
    May 15, 2013 at 8:56
  • I have asked it as a dedicted question tex.stackexchange.com/questions/646462/… I was just referenced to this question/threads by a comment there...
    – kmindi
    Jun 2, 2022 at 12:40
6

You can check the y-coordinate of a mark on a page and perform a comparison to decide whether you should print above or below. zref's savepos module can help with that:

enter image description here

\documentclass{article}

\usepackage{zref-savepos}

\newcounter{whereq}
\newcommand{\location}[1]{\zsaveposy{#1}}
\newcommand{\where}[1]{%
  \stepcounter{whereq}% New "where" request
  \location{whereq-\thewhereq}% Mark location
  % Test location based on y-coordinate
  \ifdim\zposy{whereq-\thewhereq}sp<\zposy{#1}sp
    above%
  \else
    below%
  \fi}

\begin{document}

As mentioned \where{test}, $2+2=4$.

We state that $2+2=4$.\location{test}

As mentioned \where{test}, $2+2=4$.

\end{document}

Of course, the above doesn't really care what page you perform the \location and \where macros on. However, it could be extended to condition on the page number as well.

4
  • 2
    This answer has an important advantage over the accepted answer: it works even if what is referenced is in a float. For example, wrap We state that $2+2=4$.\location{test} in \begin{figure}[b] ... \end{figure} and it will say "below" in both cases. If you change the b to t or h it still behaves correctly.
    – banbh
    May 30, 2018 at 19:58
  • @Werner I hope, I am not lazy by asking you to write the full command \where and \location with the additional condition on the page number. It'd be so nice to have the full answer! :) Apr 1, 2021 at 12:28
  • @Werner It doesn't work when the figure/table is on the next page while the \where{} is at the bottom of the current page. It says that 'Table 1 above ...' while the table is located on the next page!
    – Fuji San
    Dec 21, 2022 at 16:15
  • @FujiSan: Indeed! My current solution just considered the y coordinate between the two references (the location of the reference and the location of the \where). It should also consider what page the references are on. What should the output be for a reference that occurs on some page before*/*after \where?
    – Werner
    Dec 21, 2022 at 21:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .