The showkeys package^{∗}

David Carlisle

1995/04/25

1 Introduction

showkeys.sty modifies the \label, \ref, \pageref, \cite, and \bibitem com-
sec:intro

mands so that the ‘internal’ key is printed. The package tries hard to position these labels so that the formatting of the rest of the document is unchanged. \label and \bibitem cause the key to appear in a box either in the margin, or in a TEX box of zero width, which may possibly over-print other text. The \ref, \pageref and \cite commands print their arguments in small type, raised just above the line, like this: ^{\underline{sec:intro}} 1. This package works with the fleqn package, and the packages in the AMS-L^{A}TEX collection.

2 Package Options

Some people have commented that the printing of the \ref and \cite keys is less

options

useful than the printing of the \label keys and so showkeys now supports two options that can be given in the \usepackage command.:

notref to stop the redefinition of \ref and \pageref, and related commands from the varioref package.

notcite to stop the redefinition of \cite and related commands from the harvard and natbib packages.

   So if the package is loaded with \usepackage[notref]{showkeys} then \ref

will have its standard definition, but \label will print its key argument (usually in the margin).

3 More Examples

The only other similar package that I could find in the macro index, ^{\underline{DMJ:mi}} [3], was

examples

showlabels.sty, ^{\underline{GN:sl}} [1]. After the first draft of this package was written, I found ^{\underline{anon:sk}} [2] on my local installation! I think the current package is more robust than ^{\underline{anon:sk}} [2], but I thought that showkeys was rather a good name, so I have stolen it for this file.

e^1 1. This has \label immediately after \item.

∗This file has version number v3.03, last revised 1995/04/25.

2. This has the \label at the end.

e^2

A minipage :- Within environments like this minipage, We can not use \marginpar^{1}, so the appearance is slightly different. Here is that enumerate environment again:

m&e^1 1. This has \label immediately after \item.

2. This has the \label at the end.

              m&e^2

Displayed math (without equation counter).

                                0 = 0 disp

Some text refering to the maths on page ^{\underline{disp}} 2, and the item ^{\underline{e^1}} 1.

If showkeys thinks that the current environment is going to produce an “equation number”, then it does not show the label where the \label command occurs, but tries to put it in the margin, as shown with equation ^{\underline{eq:xx}} 1. The package ‘knows’ about the standard equation and eqnarray environments, and also all the numbered alignment environments offered by the AMSL^{A}TEX package, amsmath.

1 = 1  (1) eq:xx

                              2 = 2  (2) eqnar:a

3 = 3

                              4 = 4  (3) eqnar:b

Within a figure environment, the \label must not come before the \caption command. If you place \label inside the argument of \caption the label will be shown like this:

Figure 1: Within the caption argument. cap:a

If you place \label immediately after the \caption command it will be shown like this:

Figure 2: Immediately after the caption argument. cap:b

If you place the \label command at some random point after the \caption command, it may be shown like:

Figure 3: In vertical mode not immediately after a box.

 cap:c

References

GN:sl [1] Gil Neiger, showlabels.sty, Undated package, similar to this one, but shows labels inline, affecting the formating of the document. anon:sk [2] Annonymous, showkeys.sty, Package, dated 14 May 1988. Very similar to this

1Actually \marginpar is not used at all in this package now.

one, also uses \marginpar in outer vertical mode.

DMJ:mi [3] David M. Jones, TEX Macro Index, A catalogue of TEX macros, including L^{A}TEX packages, available from all good TEX archives.

4 The Macros

1 ⟨∗package⟩

First we handle the options. Normally all related comands are defined to show there ‘keys’. But since v3.03 one can specify:

notref to stop the redefinition of \ref (and \pageref, and related commands from varioref package)

notcite to stop the redefinition of \cite and related commands from the harvard and natbib packages.

 2 \DeclareOption{notref}{\let\SK@ref\@empty}
 3 \DeclareOption{notcite}{\let\SK@cite\@empty}
 4 \ProcessOptions
\SK@label \SK@bibitem \SK@lbibitem The saved original definitions
 5 \let\SK@label\label
 6 \let\SK@bibitem\@bibitem
 7 \let\SK@lbibitem\@lbibitem

\label The new definition, print the argument, and then do the old definition.

 8 \def\label#1{\@bsphack\SK@\SK@@label{#1}\SK@label{#1}\@esphack}

\@bibitem \@lbibitem For \bibitem, position the showkeys code as for a standard list with \item and

\label.
 9 \def\@bibitem#1{%
10 \SK@bibitem{#1}\SK@\SK@@label{#1}\ignorespaces}
11 \def\@lbibitem[#1]#2{%
12 \SK@lbibitem[#1]{#2}\SK@\SK@@label{#2}\ignorespaces}

\SK@ Grab hold of #2 via \meaning so characters like & and ^do not cause problems later, and pass the result on to the command #1.

13 \def\SK@#1#2{\def\@tempa{#2}\expandafter#1\meaning\@tempa\SK@}

\SK@@label Strip off the initial segment of the \meaning output, and then put the rest either in a \marginpar or in a box of size 0pt, hopefully not disturbing the surrounding text.

14 \def\SK@@label#1>#2\SK@{%

Need to work globally as in some cases like alignments, and fleqn, the counter will be printed in a different group to the \label command.

15 \gdef\SK@lab{\smash{\fbox{\reset@font\small\ttfamily#2}}}%
16 \ifvmode
17  \if@inlabel

If the \label is straight after \item (\bibitem is handled by this case as well) then the item label has not been added to the page yet. It is hanging around in the box \@labels waiting for the paragraph to start. So just need to attatch the label to this box.

18  \global\setbox\@labels\hbox{%
19  \llap{\SK@lab\SK@lab@relax
20  \kern\@totalleftmargin\kern\marginparsep}%
21  \box\@labels}%

The inner vertical mode cases are mainly designed to do the right thing with float captions, but seem to work OK in other cases as well.

22  \else
23  \ifinner
24  \skip@=\lastskip\unskip

In inner vertical mode, attach the label to the right of the immediately preceding box, if it is a box before the current point. Otherwise just put it in a box of zero dimensions, with no interline skip. (This may slightly move the surrounding text.)

25  \skip@\lastskip\unskip
26  \setbox\z@\lastbox
27  \ifvoid\z@
28  \nointerlineskip\SK@labx
29  \else
30  \hbox{\box\z@\SK@labx}%
31  \fi
32  \vskip\skip@
33  \else

In outer vertical mode, use a \vadjust at the start of the next paragraph (previously used \marginpar).

34  \everypar\expandafter{\the\everypar
35  \vadjust{\llap{\SK@lab\kern\marginparsep}}\SK@lab@relax}%
36  \fi
37  \fi
38 \else

If we are in an numbered equation-style environment, do nothing as the code to print the number will also print the label, otherwise just stick the label at the current point, in a box of zero dimensions.

39  \csname SK@\@currenvir\endcsname
40  \ifSK@equation\else
41  \ifmmode
42  \SK@labx
43  \else

Inner horizontal mode. Not much we can do, just stick it here.

44  \ifinner
45  \rlap\SK@lab
46  \else

In outer horizontal mode use \vadjust to get to the margin.

47  \vadjust{\llap{\SK@lab\kern\marginparsep}}%
48  \fi
49  \SK@lab@relax
50  \fi

51  \fi
52 \fi}

\iftagsleft@ Make sure that this AMSL^{A}TEX command really is an \if..

53 \AtBeginDocument{%
54 \let\SK@eqnnum\@eqnnum
55 \def\@tempa{\let\iftagsleft@\iffalse}%
56 \ifx\iftagsleft@\undefined\@tempa\fi%

\tag@form@ \eqnnum Perhaps if leqno is operative, I should define \@eqnnum with the ‘left’ version, but it does not really matter.

57 \let\SK@tagform@\tagform@
58 \iftagsleft@
59  \def\tagform@#1{%
60  \ifx\df@label\@empty
61  \SK@lab@relax
62  \else
63  \expandafter\SK@@label\meaning\df@label\SK@
64  \fi
65  \llap{\SK@lab\kern\marginparsep}%
66  \SK@lab@relax\SK@tagform@{#1}}%
67  \def\@eqnnum{%
68  \llap{\SK@lab\kern\displaywidth\kern\marginparsep}%
69  \SK@lab@relax\SK@eqnnum}%
70 \else
71  \def\tagform@#1{%
72  \ifx\df@label\@empty
73  \SK@lab@relax
74  \else
75  \expandafter\SK@@label\meaning\df@label\SK@
76  \fi
77  \SK@tagform@{#1}
78  \rlap{\kern\marginparsep\SK@lab}\SK@lab@relax}%
79  \def\@eqnnum{\SK@eqnnum\rlap{\kern\marginparsep\SK@lab}%
80  \SK@lab@relax}%
81 \fi}

\SK@labx Print the label, and then globally reset the print command to \relax.

82 \def\SK@labx{\rlap\SK@lab\global\let\SK@lab\relax}

\SK@lab@relax Clear the label.

83 \def\SK@lab@relax{\global\let\SK@lab\relax}\SK@lab@relax
\SK@equation \SK@eqnaray \SK@align \SK@alignat \SK@xalignat \SK@xxalignat \SK@gather \SK@multline \SK@flalign The following environments print an equation number, so \label should not print

its argument at the point where it appears. Note this will fail to show the label if you are in an eqnarray environment, and use \label together with \nonumber This might just about make sense if you are going to use \pageref, but that is too bad…

84 \newif\ifSK@equation
85 \let\SK@equation\SK@equationtrue
86 \let\SK@eqnarray\SK@equationtrue
87 \let\SK@align\SK@equationtrue
88 \let\SK@alignat\SK@equationtrue

 89 \let\SK@xalignat\SK@equationtrue
 90 \let\SK@xxalignat\SK@equationtrue
 91 \let\SK@gather\SK@equationtrue
 92 \let\SK@multline\SK@equationtrue
 93 \let\SK@flalign\SK@equationtrue

The next section redefines \ref and \pageref (unless the notref otption was given).

 94 \ifx\SK@ref\@empty\else

\ref \pageref Save the redefinition to \begin{document} so that this package can work with packages that redefine \cite. Tested with harvard and natbib packages. Also add code at this point to support varioref.

 95 \AtBeginDocument{%
 96 \let\SK@ref\ref
 97 \let\SK@pageref\pageref
 98 \DeclareRobustCommand\ref[1]{\SK@\SK@@ref{#1}\SK@ref{#1}}%
 99 \DeclareRobustCommand\pageref[1]{\SK@\SK@@ref{#1}\SK@pageref{#1}}%
100 \ifx\vpageref\@undefined\else

varioref support.

101  \let\SK@@@vpageref\@@vpageref
102  \def\@@vpageref#1[#2]#3{{%
103  \let\label\SK@label\let\ref\SK@ref\let\pageref\SK@pageref
104  \leavevmode\unskip\SK@\SK@@ref{#3}\SK@@@vpageref#1[#2]{#3}}}%
105  \DeclareRobustCommand\vref[1]{%
106  \unskip~\ref{#1}%
107  {\let\label\SK@label\let\ref\SK@ref\let\pageref\SK@pageref
108  \SK@@@vpageref\unskip[\unskip\space]{#1}}}%
109 \fi}
110 \fi

Now redefine \cite unless notcite option given.

111 \ifx\SK@cite\@empty\else
\cite
112 \AtBeginDocument{%
113 \ifx\HAR@checkdef\@undefined

Standard (non-harvard) support, including extra cite commands from natbib.

114  \let\SK@cite\cite
115  \def\cite#1#{\SK@citea{#1}}%
116  \let\SK@citeauthor\citeauthor
117  \def\citeauthor#1{\SK@\SK@@ref{#1}\SK@citeauthor{#1}}%
118  \let\SK@citefullauthor\citefullauthor
119  \def\citefullauthor#1{\SK@\SK@@ref{#1}\SK@citefullauthor{#1}}%
120  \let\SK@citeyear\citeyear
121  \def\citeyear#1{\SK@\SK@@ref{#1}\SK@citeyear{#1}}%
122 \else

In the harvard style do not redefine individual cite commands. Just redefine one internal command that is used in all the citation forms.

123  \let\SK@HAR@checkdef\HAR@checkdef
124  \def\HAR@checkdef#1#2{%

125  \expandafter\SK@\expandafter\SK@@ref\expandafter{#1}%
126  \SK@HAR@checkdef{#1}{#2}}%
127  \expandafter\let\expandafter
128  \SK@HAR@bi\csname\string\harvarditem\endcsname
129  \expandafter\def\csname\string\harvarditem\endcsname[#1]#2#3#4{%
130  \SK@\SK@@label{#4}\SK@HAR@bi[#1]{#2}{#3}{#4}}%
131 \fi}
132 \def\SK@citea#1#2{%
133 \SK@\SK@@ref{#2}\SK@cite#1{#2}}
134 \fi

\SK@@ref This is much simpler than the printing of the label, as we know that we can be in horizontal mode.

135 \def\SK@@ref#1>#2\SK@{%
136 \leavevmode\vbox to \z@{\vss
137  \rlap{\vrule\raise .75em
138  \hbox{\underbar{\reset@font\footnotesize\ttfamily#2}}}}}

139 ⟨/package⟩