The showlabels package^{∗}

Norman Gray

                 norman@astro.gla.ac.uk

1999/07/22

This package introduces no new commands, it just helps you keep track of all the labels by putting the name of the new label into the margin whenever either the \label command is used, or an equation is automatically numbered (by replacing the internal \@eqnnum command). There are therefore no usage instructions. You invoke this package with the command \usepackage{showlabels} in the preamble, and you may give the options inner or outer (the default) to have the labels placed in the inner or outer margin of the text. If you don’t use the twoside option, then all pages are ‘right-hand’ pages, and the ‘outer margin’ is the right hand one.

The package will also work in the presence of the twocolumn option. In this case, the options inner and outer will be ignored, and the label will be placed in the nearer margin.

In version 1.1, the package was modified to conform to the slightly different mechanism that amsmath uses to produce equation numbers. I don’t habitually use amsmath, so I won’t discover any bugs or weaknesses with its support here, and I’d consequently be glad to be informed of any that appear. Do note that the \usepackage{showlabels} command must appear after the \usepackage{amsmath}. Note also that, since these additions appeared, AMS-L^{A}TEX and the amstex package seem to have been declared ‘obsolete’ in favour of the amsmath package. This package now claims conformance with the amsmath package alone.

If you want to change the font the labels appear in, use something along the

lines of \renewcommand{\showlabelsfont}{\small\slfamily}.

For reasonably obvious reasons, this package will not work at all well with the multicol package, and for possibly less obvious reasons, it won’t work with the leqno option either (at some point it should be modified to at least recognise and warn of the conflict in either case, though it’s not obvious to me how to do that).

The package might still work with L^{A}TEX2.09, but that’s neither supported, nor even tested.

This software is copyright, 1999, Norman Gray. It is released under the terms of the GNU General Public Licence. See the copyright declaration at the top of file showlabels.dtx, and the file LICENCE for the licence conditions. You can find

an online copy of the GPL at <http://www.gnu.org/copyleft/gpl.html>.

∗This file has version number v1.3c, last revised 1999/07/22, documentation dated 1999/07/22

1 History and Credits

For version 1.3, I received comments and bug reports from: David R. Leal

Valmana <david@quijote.uc3m.es>, Sungmo Park <smp@dingo.etri.re.kr>,
Olivier Michel <Olivier.Michel@lri.fr>, Jiri Vesely <jvesely@karlin.mff.
cuni.cz>, Patrick Sibille <sibille@amoco.saclay.cea.fr>, Hagen Kleinert
<kleinert@physik.fu-berlin.de>, Francis M. C. Ching <fmcching@kingcong.
uwaterloo.ca>, Michael Friendly <friendly@hotspur.psych.yorku.ca>. Many

thanks to all.

Back in 29-Jan-92, Darrel Hankerson <hank@ducvax.auburn.edu>, made the update to NFSS, and changed the name to ‘showlabel.sty’.

Originally released 21-Sep-91 by me, under the name labels.sty.

2 Implementation

1 ⟨∗package⟩

Before we do anything else, find out if we’re using AMS-L^{A}TEX. … Note that, since these additions appeared, AMS-L^{A}TEX and the amstex package seem to have been declared ‘obsolete’. This package now claims conformance with the amsmath package.

 2 \newif\ifSL@AMS
 3 \expandafter\ifx\csname maketag@@@\endcsname\relax
 4 \SL@AMSfalse
 5 \else
 6 \SL@AMStrue
 7 \typeout{with AMS-LaTeX equation tags}
 8 \fi

\@eqnnum This replacement for \@eqnnum will produce a note, sticking into the margin beside the equation number, showing the equation’s label. \SL@labeln@me is initialised to \relax, redefined within the \label macro, and reset to \relax here. If it’s already equal to \relax here, the equation number hasn’t been labelled, and so ‘???’ is put in the margin. Don’t do this for the AMS-L^{A}TEX case as it artfully incorporates the \maketag@@@ mechanism into a redefined \@eqnnum.

 9 \ifSL@AMS

AMS-L^{A}TEXuses \maketag@@@, to form tags in equations. All we have to do is hook into the \maketag@@@ macro, and use \df@label, which is pre-defined with the current label name.

10 \let\@maketag@@@=\maketag@@@
11 \def\maketag@@@#1{\@maketag@@@{#1}%
12 \ifx\df@label\@empty
13 %    \SL@eqnlrtext{???}%
14 \else
15  \SL@eqnlrtext{\df@label}%
16 \fi}
17 \else

The ‘normal’ case, without AMS-LaTeX

18 \let\@@eqnnum=\@eqnnum
19 \def\@eqnnum{\@@eqnnum
20 \expandafter\ifx\SL@labeln@me\relax

21  \SL@eqnlrtext{???}%
22 \else
23  \SL@eqnlrtext{\SL@labeln@me}%
24  \global\def\SL@labeln@me{\relax}%
25 \fi}

And initialise the value of \labeln@me to \relax, so that \@eqnnum starts off behaving the right way.

26 \global\def\SL@labeln@me{\relax}
27 \fi

Labels are printed with the font specified by \showlabelfont, which can be overridden within the document:

28 \def\showlabelfont{\small\tt}

Leave this as \small\tt, to avoid a pointless incompatibility with L^{A}TEX2.09.

For the benefit of \prlabelname, define \SL@gobblethree to do nothing other than eat three tokens.

29 \def\SL@gobblethree#1#2#3{}

\prlabelname Expansion is label name with all catcodes ‘other’ (Appendix D trickery abounds!). Use \r@#1, rather then just \#1 to avoid defining any new control sequences.

30 \def\prlabelname#1{%
31 \expandafter\expandafter\expandafter\SL@gobblethree
32  \expandafter\string\csname r@#1\endcsname}

\@makecaption Simple replacement for the \@makecaption command. This simply issues the original \@makecaption command after redefining \label. This does not put the label name in the margin (that’s too complicated for the moment), but instead inserts it as part of the caption.

33 \let\SL@makecaption\@makecaption
34 \long\def\@makecaption#1#2{{\def\label##1{{\showlabelfont
35 \{\prlabelname{##1}\}\space}\SL@label{##1}}%

… and follows it with the original, saved, \@makecaption.

36 \SL@makecaption{#1}{#2}}}

\label This is the central bit of this package. Depending on the mode, put the current label name in the margin in one of a variety of ways. First of all, issue the saved

\SL@label command.
37 \let\SL@label\label
38 \def\label#1{\@bsphack\SL@label{#1}%

In maths mode, produce a label name alongside the equation number. If we’re not using AMS-L^{A}TEX, then save the label name in \SL@labelname. If we are using AMS-L^{A}TEX, then we don’t have to worry, because it’s saved in \df@label for us.

39 \ifmmode
40  \ifSL@AMS\else
41  \xdef\SL@labeln@me{\prlabelname{#1}}%
42  \fi

Otherwise, create a box with zero height and depth, and the same width as the page. Put all this in braces, to contain the setting of \box0 (which probably shouldn’t be necessary).

43 \else
44  {\setbox0=\vbox to 0pt{\vss
45  \hbox to \columnwidth{\SL@lrtext{#1}}}%
46  \dp0=0pt

and attach it below the last one, using \nointerlineskip if we’re in vertical mode, or \vadjust otherwise.

47  \ifvmode
48  \nointerlineskip\box0\nobreak
49  \else
50  \vadjust{\box0\nobreak}%
51  \fi}%

That’s it. Finish off the \ifmmode and give the partner to \@bsphack.

52 \fi
53 \@esphack}

\margintext Set the actual text of the label. Use \prlabelname here: without this, a label command given outside of an equation or a \caption will appear wrongly if the label has things like underscores within it.

54 \def\SL@margintext#1{{\showlabelfont\{\prlabelname{#1}\}}}

But where is the marginal text actually set? It can be in the left margin, the right one, or can alternate. \SL@lrtext, used in the \vbox above, is set, under

the control of \if@outerlabels below, to one of \SL@lefttext, \SL@righttext
or \SL@alternatetext.
\SL@righttext
\SL@lefttext
55 \def\SL@righttext#1{\hfill\rlap{\quad\SL@margintext{#1}}}
56 \def\SL@lefttext #1{\llap{\SL@margintext{#1}\quad}\hfill}

The code for \SL@alternatetext doesn’t work perfectly, as it sometimes manages to get things on the wrong side of the text near the top of a new page. This is a venial slip, however, as this package should never be used in a final version.

\SL@alternatetext
57 \def\SL@alternatetext{%
58 \if@outerlabels
59  \ifodd\c@page
60  \let\SL@next\SL@righttext\else
61  \let\SL@next\SL@lefttext\fi
62 \else
63  \ifodd\c@page
64  \let\SL@next\SL@lefttext\else
65  \let\SL@next\SL@righttext\fi
66 \fi
67 \SL@next}

The case where the twocolumn option is set is slightly different. There we have to switch between placing the note in the left and right margins, depending on whether we’re setting the first or second column. This macro, and \SL@eqntwocoltext below, uses the switch \if@firstcolumn to decide whether it’s in the first or the second column of the text (I suppose it’ll get terribly confused if we use multicol.sty along with this). This is defined and maintained in the base file ltoutput.dtx. It’s not part of the defined interface, however (there doesn’t seem to be one, grump), so I don’t suppose we should really rely on it. There isn’t an option, however.

\SL@twocoltext
68 \def\SL@twocoltext{%
69 \if@firstcolumn
70  \let\SL@next\SL@lefttext
71 \else
72  \let\SL@next\SL@righttext
73 \fi
74 \SL@next}

We have very similar things for equations, except that they are set in place, rather than within a zero depth box. This code ASSUMES that equation numbers are going to be on the right hand side of the page. It should probably check for the existence of the leqno option (how?).

\SL@eqnrighttext
\SL@eqnlefttext
75 \def\SL@eqnrighttext#1{\rlap{\quad\SL@margintext{#1}}}
76 \def\SL@eqnlefttext #1{\hbox to 0pt{\kern -\columnwidth
77 \llap{\SL@margintext{#1}\quad}\hss}}

Now do the analogues for the equation numbers, in the case of the alternate page selection…

\SL@eqnalternatetext
78 \def\SL@eqnalternatetext{%
79 \if@outerlabels
80  \ifodd\c@page
81  \let\SL@next\SL@eqnrighttext\else
82  \let\SL@next\SL@eqnlefttext\fi
83 \else
84  \ifodd\c@page
85  \let\SL@next\SL@eqnlefttext\else
86  \let\SL@next\SL@eqnrighttext\fi
87 \fi
88 \SL@next}

… and the twocolumn option

\SL@eqntwocoltext
89 \def\SL@eqntwocoltext{%
90 \if@firstcolumn
91  \let\SL@next\SL@eqnlefttext
92 \else
93  \let\SL@next\SL@eqnrighttext
94 \fi
95 \SL@next}

To keep track of things, declare the \if@outerlabels switch, and set it true by default.

96 \newif\if@outerlabels
97 \@outerlabelstrue

We select between the various possibilities using the outer and inner options and, implicitly, the twoside option.

 98 \DeclareOption{outer}{\@outerlabelstrue}
 99 \DeclareOption{inner}{\@outerlabelsfalse}

Process any options that have been set.

100 \ProcessOptions

and use the values of \if@outerlabels and if@twoside which may have been set by those options, to set \SL@lrtext to be the appropriate control sequence. The presence of the twocolumn option means that we ignore the inner and outer options.

101 \if@twocolumn
102 \let\SL@lrtext\SL@twocoltext
103 \let\SL@eqnlrtext\SL@eqntwocoltext
104 \else
105 \if@outerlabels
106  \if@twoside
107 \let\SL@lrtext\SL@alternatetext
108 \let\SL@eqnlrtext\SL@eqnalternatetext
109  \else
110  \let\SL@lrtext\SL@righttext
111  \let\SL@eqnlrtext\SL@eqnrighttext
112  \fi
113 \else
114  \if@twoside
115 \let\SL@lrtext\SL@alternatetext
116 \let\SL@eqnlrtext\SL@eqnalternatetext
117  \else
118  \let\SL@lrtext\SL@lefttext
119  \let\SL@eqnlrtext\SL@eqnlefttext
120  \fi
121 \fi
122 \fi

That’s us.

123 ⟨/package⟩