The showlabels package^{∗}

Norman Gray

                 norman@astro.gla.ac.uk

1996/05/12

This is the showlabels class option.

This class option 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.

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.

The package has (finally) been modified to deal with the slightly different mechanism that AMS-L^{A}TEX uses to produce equation numbers. I don’t habitually use AMS-L^{A}TEX, 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. The \usepackage{showlabels} must appear after any AMS stuff is loaded.

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

1 The driver file

Nothing fancy.

1 ⟨∗driver⟩

 2 \documentclass{ltxdoc}
 3 \EnableCrossrefs

Some commonly used abbreviations for option names, filenames, counters and packages.

 4 \newcommand\Lopt[1]{\textsf {#1}}
 5 \newcommand\file[1]{\texttt {#1}}
 6 \newcommand\Lcount[1]{\textsl {\small#1}}
 7 \newcommand\pstyle[1]{\textsl {#1}}
 8 \date{\docdate}

∗This file has version number v1.2, last revised 1996/05/12, documentation dated 1996/05/12

The body of the style. Include all the details.

 9 \begin{document}
10 % \OnlyDescription %uncomment to suppress the source listing
11 \DocInput{showlabels.dtx}
12 \PrintIndex
13 \PrintChanges
14 \end{document}

15 ⟨/driver⟩

2 The package

16 ⟨∗package⟩

17 \NeedsTeXFormat{LaTeX2e}
18 \ProvidesPackage{showlabels}[\filedate\space\fileversion]
19 \typeout{Package: `showlabels' \fileversion\space<\filedate>}
20 \wlog{Documentation}

Before we do anything else, find out if we’re using AMS-L^{A}TEX…

21 \newif\ifSL@noAMS
22 \expandafter\ifx\csname maketag@@@\endcsname\relax
23 \SL@noAMStrue
24 \else
25 \SL@noAMSfalse
26 \typeout{with AMS-LaTeX equation tags}
27 \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.

28 \ifSL@noAMS
29 \let\@@eqnnum=\@eqnnum
30 \def\@eqnnum{\@@eqnnum
31 \ifx\SL@labeln@me\relax
32  \SL@eqnlrtext{???}%
33 \else
34  \SL@eqnlrtext{\SL@labeln@me}%
35  \global\def\SL@labeln@me{\relax}%
36 \fi}

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

37 \global\def\SL@labeln@me{\relax}

Otherwise do a similar thing for AMS-L^{A}TEX’s \maketag@@@, which is what it uses 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.

38 \else
39 \let\@maketag@@@=\maketag@@@
40 \def\maketag@@@#1{\@maketag@@@{#1}%

41 \ifx\df@label\@empty
42 %    \SL@eqnlrtext{???}%
43 \else
44  \SL@eqnlrtext{\df@label}%
45 \fi}
46 \fi

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

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

48 \def\prlabelname#1{%
49 \expandafter\expandafter\expandafter\SL@gobblethree
50  \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.

51 \let\@@makecaption\@makecaption
52 \long\def\@makecaption#1#2{{\def\label##1{{\small\tt
53 \{\prlabelname{##1}\}\space}\SL@label{##1}}%

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

54 \@@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.
55 \let\SL@label\label
56 \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.

57 \ifmmode
58  \ifSL@noAMS
59  \xdef\SL@labeln@me{\prlabelname{#1}}%
60  \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).

61 \else
62  {\setbox0=\vbox to 0pt{\vss
63  \hbox to \columnwidth{\SL@lrtext{#1}}}%
64  \dp0=0pt

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

65  \ifvmode
66  \nointerlineskip\box0\nobreak

67  \else
68  \vadjust{\box0\nobreak}%
69  \fi}%

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

70 \fi
71 \@esphack}

\margintext Set the actual text of the label.

72 \def\SL@margintext#1{{\small\sl\{#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
73 \def\SL@righttext#1{\hfill\rlap{\quad\SL@margintext{#1}}}
74 \def\SL@lefttext #1{\llap{\SL@margintext{#1}\quad}\hfill}

The code for \SK@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
75 \def\SL@alternatetext{%
76 \if@outerlabels
77  \ifodd\c@page
78  \let\SL@next\SL@righttext\else
79  \let\SL@next\SL@lefttext\fi
80 \else
81  \ifodd\c@page
82  \let\SL@next\SL@lefttext\else
83  \let\SL@next\SL@righttext\fi
84 \fi
85 \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
86 \def\SL@twocoltext{%
87 \if@firstcolumn
88  \let\SL@next\SL@lefttext
89 \else
90  \let\SL@next\SL@righttext
91 \fi
92 \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
 93 \def\SL@eqnrighttext#1{\rlap{\quad\SL@margintext{#1}}}
 94 \def\SL@eqnlefttext #1{\hbox to 0pt{\kern -\columnwidth
 95 \llap{\SL@margintext{#1}\quad}\hss}}

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

\SL@eqnalternatetext
 96 \def\SL@eqnalternatetext{%
 97 \if@outerlabels
 98  \ifodd\c@page
 99  \let\SL@next\SL@eqnrighttext\else
100  \let\SL@next\SL@eqnlefttext\fi
101 \else
102  \ifodd\c@page
103  \let\SL@next\SL@eqnlefttext\else
104  \let\SL@next\SL@eqnrighttext\fi
105 \fi
106 \SL@next}

… and the twocolumn option

\SL@eqntwocoltext
107 \def\SL@eqntwocoltext{%
108 \if@firstcolumn
109  \let\SL@next\SL@eqnlefttext
110 \else
111  \let\SL@next\SL@eqnrighttext
112 \fi
113 \SL@next}

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

114 \newif\if@outerlabels
115 \@outerlabelstrue

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

116 \DeclareOption{outer}{\@outerlabelstrue}
117 \DeclareOption{inner}{\@outerlabelsfalse}

Process any options that have been set.

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

119 \if@twocolumn

120 \let\SL@lrtext\SL@twocoltext
121 \let\SL@eqnlrtext\SL@eqntwocoltext
122 \else
123 \if@outerlabels
124  \if@twoside
125 \let\SL@lrtext\SL@alternatetext
126 \let\SL@eqnlrtext\SL@eqnalternatetext
127  \else
128  \let\SL@lrtext\SL@righttext
129  \let\SL@eqnlrtext\SL@eqnrighttext
130  \fi
131 \else
132  \if@twoside
133 \let\SL@lrtext\SL@alternatetext
134 \let\SL@eqnlrtext\SL@eqnalternatetext
135  \else
136  \let\SL@lrtext\SL@lefttext
137  \let\SL@eqnlrtext\SL@eqnlefttext
138  \fi
139 \fi
140 \fi

That’s us.

141 ⟨/package⟩