The showkeys package^{∗}

David Carlisle carlisle@cs.man.ac.uk

1994/09/09

1 Introduction

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

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. Works with fleqn.sty.

The only other similar package that I could find in the macro index, ^{\underline{DMJ:mi}} [3], was 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.

2. This has the \label at the end. e^2

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

1. m&e^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}} 1, and the item ^{\underline{e^1}} 1.

∗This file has version number v3.01, last revised 1994/09/09.

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, amstex.

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 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.

2 The Macros

1 ⟨∗package⟩

\SK@label \SK@bibitem \SK@lbibitem The saved original definitions
 2 \let\SK@label\label
 3 \let\SK@bibitem\@bibitem
 4 \let\SK@lbibitem\@lbibitem

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

 5 \def\label#1{\@bsphack\SK@\SK@@label{#1}\SK@label{#1}\@esphack}
 6 \def\@bibitem#1{\SK@\SK@@label{#1}\SK@bibitem{#1}\ignorespaces}
 7 \def\@lbibitem[#1]#2{%
 8 \SK@\SK@@label{#2}\SK@lbibitem[#1]{#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.

 9 \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.

10 \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.

11 \gdef\SK@lab{\smash{\fbox{\reset@font\small\ttfamily#2}}}%
12 \ifvmode
13  \ifinner

Because of the contortions of the list environment, we might be in inner vertical mode if the \label immediately follows an \item. The code for inner vertical mode is mainly optimised for the \caption command, and would fail miserably here, so use \mbox to get into horizontal mode, and to give a ⟨box⟩ for \lastbox to get hold of. Did any one say ‘kludge’?

14  \if@inlabel
15  \mbox{}\let\@tempa\SK@lab
16  \def\SK@lab{\llap{\@tempa\kern\leftmargin}}%
17  \let\SK@temp\@gobble
18  \else
19  \skip@=\lastskip\unskip
20  \let\SK@temp\vskip
21  \fi

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.)

22  \skip@=\lastskip\unskip
23  \setbox\z@=\lastbox
24  \ifvoid\z@
25  \nointerlineskip\SK@labx
26  \else
27  \hbox{\box\z@\SK@labx}%

28  \fi
29  \SK@temp\skip@
30  \else

In outer vertical mode, use a \marginpar.

31  \marginpar{\SK@lab}\SK@lab@relax
32  \fi
33 \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.

34  \csname SK@\@currenvir\endcsname
35  \ifSK@equation\else\SK@labx\fi
36 \fi}

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

37 \AtBeginDocument{%
38 \let\SK@eqnnum\@eqnnum
39 \def\@tempa{\let\iftagsleft@\iffalse}%
40 \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.

41 \let\SK@tagform@\tagform@
42 \iftagsleft@
43  \def\tagform@#1{\llap{\SK@lab\kern\marginparsep}%
44  \SK@lab@relax\SK@tagform@{#1}}%
45  \def\@eqnnum{\llap{\SK@lab\kern\displaywidth\kern\marginparsep}%
46  \SK@lab@relax\SK@eqnnum}%
47 \else
48  \def\tagform@#1{\SK@tagform@{#1}%
49  \rlap{\kern\marginparsep\SK@lab}\SK@lab@relax}%
50  \def\@eqnnum{\SK@eqnnum\rlap{\kern\marginparsep\SK@lab}%
51  \SK@lab@relax}%
52 \fi}

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

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

\SK@lab@relax Clear the label.

54 \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 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…

55 \newif\ifSK@equation

56 \let\SK@equation\SK@equationtrue
57 \let\SK@eqnarray\SK@equationtrue
58 \let\SK@align\SK@equationtrue
59 \let\SK@alignat\SK@equationtrue
60 \let\SK@xalignat\SK@equationtrue
61 \let\SK@xxalignat\SK@equationtrue
62 \let\SK@gather\SK@equationtrue
63 \let\SK@multline\SK@equationtrue

\cite \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.

64 \AtBeginDocument{%
65 \let\SK@ref\ref
66 \let\SK@pageref\pageref
67 \DeclareRobustCommand\ref[1]{\SK@\SK@@ref{#1}\SK@ref{#1}}%
68 \DeclareRobustCommand\pageref[1]{\SK@\SK@@ref{#1}\SK@pageref{#1}}%
69 \ifx\vpageref\@undefined\else

varioref support.

70  \let\SK@@@vpageref\@@vpageref
71  \def\@@vpageref#1[#2]#3{{%
72  \let\label\SK@label\let\ref\SK@ref\let\pageref\SK@pageref
73  \leavevmode\unskip\SK@\SK@@ref{#3}\SK@@@vpageref#1[#2]{#3}}}%
74  \DeclareRobustCommand\vref[1]{%
75  \unskip~\ref{#1}%
76  {\let\label\SK@label\let\ref\SK@ref\let\pageref\SK@pageref
77  \SK@@@vpageref\unskip[\unskip\space]{#1}}}%
78 \fi
79 \ifx\HAR@checkdef\@undefined

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

80  \let\SK@cite\cite
81  \def\cite#1#{\SK@citea{#1}}%
82  \let\SK@citeauthor\citeauthor
83  \def\citeauthor#1{\SK@\SK@@ref{#1}\SK@citeauthor{#1}}%
84  \let\SK@citefullauthor\citefullauthor
85  \def\citefullauthor#1{\SK@\SK@@ref{#1}\SK@citefullauthor{#1}}%
86  \let\SK@citeyear\citeyear
87  \def\citeyear#1{\SK@\SK@@ref{#1}\SK@citeyear{#1}}%
88 \else

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

89  \let\SK@HAR@checkdef\HAR@checkdef
90  \def\HAR@checkdef#1#2{%
91  \expandafter\SK@\expandafter\SK@@ref\expandafter{#1}%
92  \SK@HAR@checkdef{#1}{#2}}%
93  \expandafter\let\expandafter
94  \SK@HAR@bi\csname\string\harvarditem\endcsname
95  \expandafter\def\csname\string\harvarditem\endcsname[#1]#2#3#4{%

96  \SK@\SK@@label{#4}\SK@HAR@bi[#1]{#2}{#3}{#4}}%
97 \fi}
98 \def\SK@citea#1#2{%
99 \SK@\SK@@ref{#2}\SK@cite#1{#2}}

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

100 \def\SK@@ref#1>#2\SK@{%
101 \leavevmode\vbox to \z@{\vss
102  \rlap{\vrule\raise .75em
103  \hbox{\underbar{\reset@font\footnotesize\ttfamily#2}}}}}

104 ⟨/package⟩