% \iffalse % meta-comment
%
%% This is the showlabels package
%%
%%%% Copyright 1999, 2001-09, 2013-22, 2025, Norman Gray
%%
%% This work may be distributed and/or modified under the
%% conditions of the LaTeX Project Public Licence, either version 1.3c
%% of this licence or (at your option) any later version.
%% The latest version of this licence is in
%%   http://www.latex-project.org/lppl.txt
%% and version 1.3c or later is part of all distributions of LaTeX
%% version 2005/12/01 or later.
%%
%% This work has the LPPL maintenance status `maintained'.
%%
%% The Current Maintainer of this work is Norman Gray <https://nxg.me.uk>
%%
%% This work consists of the files showlabels.dtx and showlabels.ins,
%% and the derived file showlabels.sty.

%%%% File: showlabels.dtx
%%%% Source: 66d69fa049ab, 2025-08-20T22:15:23+01:00

% This is revision 66d69fa049ab, 2025-08-20T22:15:23+01:00.
%<+package>\NeedsTeXFormat{LaTeX2e}
%<+package>\ProvidesPackage{showlabels}[2025/08/20\space v1.9.3]
%<+package>\typeout{Package: `showlabels' v1.9.3\space<2025/08/20>}
%
%<*driver>
\documentclass{ltxdoc}
\EnableCrossrefs
%    \end{macrocode}
%    Some commonly used abbreviations for option names, filenames,
% counters and packages.
%    \begin{macrocode}
\newcommand\Lopt[1]{\textsf{#1}}                % package options
\newcommand\file[1]{\texttt{#1}}                % filename
%\newcommand\Lcount[1]{\textsl{\small#1}}
\newcommand\Lenv[1]{\textsl{\{#1\}}}
\newcommand\Lpackage[1]{\textsf{\{#1\}}}        % packages
%% \url macro (url.sty does this better, but we don't want extra dependencies)
\def\setpathdots{\discretionary{.}{}{.}}
\def\setpathslash{\discretionary{/}{}{/}}
{\catcode`\.=\active
 \catcode`\/=\active
  \gdef\pathcats{%
    \catcode`\%=12      \catcode`\~=12
    \catcode`\.=\active  \let.\setpathdots
    \catcode`\/=\active \let/\setpathslash
    \catcode`\#=12      \catcode`\_=12}%
    }
\def\setpath#1{\ttfamily <\nobreak #1\nobreak>\endgroup}
\def\url{\begingroup\pathcats\setpath}
\begin{document}
% \OnlyDescription
\DocInput{showlabels.dtx}
\PrintIndex
\end{document}
%</driver>
%
% \fi
%
%
% \title{The \texttt{showlabels} package}
% \author{Norman Gray\\https://nxg.me.uk}
% \date{Version 1.9.3, 2025 August 20}
%
% \maketitle
%
% This package helps you keep track of all the labels you define, by
% putting the name of new labels into the margin whenever the
% |\label| command is used.
%
% You can do the same thing for other commands (see below).
% The only one for which this is \emph{obviously} useful is the
% |\cite| command, but it is also reasonable to do it with, for example,
% the |\ref| or |\begin| commands.
%
% Invoke this package with the command |\usepackage{showlabels}| in
% the preamble, and you may give the following options:
% \begin{quotation}
% \begin{tabular}{lp{25em}}
%    \Lopt{outer}    & [default] all notes are placed in the text's outer
%                      margin\\
%    \Lopt{inner}    & \dots inner margin\\
%    \Lopt{left}     & \dots left margin\\
%    \Lopt{right}    & \dots right margin\\
%    \Lopt{marginal} & [default] put notes in the margin\\
%    \Lopt{inline}   & put notes inline, as much as possible, and ignore
%                      any of the margin-placement options above \\
%    \Lopt{nolabel}  & do not insert a marginal note for |\label| commands
%                      (see command |\showlabels| below)\\
%    \Lopt{draft}    & [default] does nothing, partner of\dots\\
%    \Lopt{final}    & turns off all the package's functionality
% \end{tabular}
% \end{quotation}
% If you don't use the \Lopt{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 \Lopt{twocolumn}
% option.  In this case, the options \Lopt{inner}, \Lopt{outer},
% \Lopt{left} and \Lopt{right} will be ignored, and the label will be
% placed in the nearer margin.
%
% Finally, we have the options \Lopt{final} and \Lopt{draft}.  The option
% \Lopt{final} turns off all the functionality of this package.  This
% is included so that if that
% option is given globally in the |\documentclass| declaration then this
% package does respect it.  The \Lopt{draft} option does nothing, and therefore
% simply continues the default behaviour of this package; it is here
% to partner the \Lopt{final} option.  Note that if any of the
% packages in your document preamble are loaded with a \Lopt{final}
% option, it will be set for all subsequent packages.
%
% \DescribeMacro{\showlabels}
% If you wish the package to do its magic with another command |\foo|
% which takes at least one argument (for example |\cite|),
% then give the command |\showlabels{foo}|.
% The default behaviour of the package is to give the command
% |\showlabels{label}| internally; if you don't want this to happen --
% perhaps because you \emph{only} want |\cite| commands highlighted --
% then give the option \Lopt{nolabel} to the |\usepackage| command:
% |\usepackage[nolabel]{showlabels}|.
%
% You can call |\showlabels{foo}| with commands which have starred
% forms, |\foo*{arg}|, or optional arguments, |\foo[opt]{arg}|.  A
% technical wrinkle is that, in each case, the |{arg}| is read with
% all of its characters being catcode `other'; I~can't think of a
% realistic case where this is a problem, since the commands typically
% given to |\showlabels| will almost certainly do something equivalent
% to this anyway, but it is a mild change from the default behaviour
% of the command |\foo|.
%
% You can do this |\showlabels| step even with commands that you
% invoke only implicitly.  If, for example, you want to label each of the
% entries in your bibliography, then |\showlabels{bibitem}|
% will do this for each of the items that appear in the
% \Lenv{thebibliography} environment, whether it is writen by you or
% by \BibTeX\ (if you use the `biblatex' package, then the
% corresponding command would be
% |\makeatletter\showlabels{blx@bibitem}\makeatother|, but notice that
% this is in principle an undocumented internal of the `biblatex'
% package, so may change).
%
% By default, the package displays labels in the margin of the
% document, but as an alternative, labels can be kept inline as much
% as possible; this is much more legible when there are multiple
% labels on a single line.  To select this, give the option
% \Lopt{inline}, and to select the default behaviour, use
% \Lopt{marginal}.
%
% \DescribeMacro{\showlabelsinline}
% It is sometimes convenient (for example when a document encounters a
% situation which this package mishandles) to force inline labels
% temporarily, within a block or environment.  Use the
% |\showlabelsinline| macro to do that.
% \DescribeMacro{\showlabelsmarginal}
% The corresponding |\showlabelsmarginal| command has the opposite
% effect (included for symmetry; it's less likely to be useful).
%
% \section{Formatting}
%
% If you want to change the font the labels appear in, redefine the
% |\showlabelfont| command, which by default expands to
% |\small\ttfamily|.  For example, to have labels in a slanted font,
% and green, you could include the definition
% \begin{quote}
% |\renewcommand{\showlabelfont}{\small\slshape\color{green}}|
% \end{quote}
% in the preamble of your document (as long as you have loaded the
% \Lpackage{color} package, of course).
%
% Alternatively, the |\showlabels| command has an optional argument containing
% formatting commands, which allows you to format |\cite| labels, for
% example, differently from |\label|.  Thus:
% \begin{quote}
% |\showlabels[\color{green}]{cite}|
% \end{quote}
% The optional formatting command can be either a font-changing
% command, as illustrated here, \emph{or} a command which takes a
% single argument, such as
% \begin{quote}
% |\showlabels[\fbox]{cite}|
% \end{quote}
%
% If, finally, you want complete control over the labels, you can
% instead override |\showlabelsetlabel|, which initially expands to
% just |\showlabelfont #1|.  You can use this mechanism to get a
% variety of effects.  For example, if you say
% \begin{quote}
% |\usepackage{showlabels,rotating}|\\
% |\renewcommand{\showlabelsetlabel}[1]|\\
% \null\qquad |{\begin{turn}{60}\showlabelfont #1\end{turn}}|\\
% \end{quote}
% then you end up with your labels at a jaunty angle in the margin.
%
% The command |\showlabeltype| will expand to the current label type
% (ie, `label' or `cite', etc), so it would be possible for
% |\showlabelsetlabel| to conditionalise on that, if you felt that
% were necessary.\footnote{The support for a one-argument command in
% $\backslash$\texttt{showlabels}, and the presence of the
% $\backslash$\texttt{showlabeltype} macro, were added in version 1.9.}
%
% If instead you want to adjust how inline markings are displayed, you
% can change the definition of the
% |\showlabelrefline| rule from its default.
% For example, defining this to be
% \begin{quote}
% |\color{red}\hrule width 0.1em height 1.5ex depth 0pt |
% \end{quote}
% produces a fattish red line, and defining it to be
% \begin{quote}
% |\hrule width 0pt height 1.5ex depth 0pt|
% \end{quote}
% suppresses the line but still positions the text between the lines.
%
% \section{Compatibility with other packages, and other problems}
%
% The \Lpackage{showlabels} package works by redefining the |\label|
% command, along with a few internal \LaTeX\ commands.  All the other commands it
% defines are `hidden' by prefixing them with `\texttt{SL@}', with
% the exception of the user commands |\showlabelfont| and
% |\showlabelsetlabel|.  Each of
% the three redefined commands carefully includes its previous
% definition.  The \Lpackage{showlabels} package should therefore come
% \emph{last} of the packages you include using |\usepackage|.
%
% In version 1.1, the package was modified to conform to the slightly
% different mechanism that \texttt{amsmath} uses to produce equation
% numbers.  Do note that the
% |\usepackage{showlabels}| command \emph{must} appear after the
% |\usepackage{amsmath}| if it is to detect that you are using the
% \Lpackage{amsmath} package.
%
% In version 1.3e, the package became compatible with the
% \Lpackage{hyperref} package in particular, and in general with other
% packages which themselves modify the |\label| command.  This will
% work, however, only if the \Lpackage{showlabels} package is loaded
% after other packages which do this.  Notwithstanding Sebastian
% Rahtz's excellent general advice on this, \Lpackage{showlabels} should
% be loaded after \Lpackage{hyperref}.
%
% In version 1.7, the package became compatible with the
% equation-numbering mechanism of the \Lpackage{IEEEtrantools}
% package.  As with \Lpackage{amsmath}, this involves a certain amount
% of special-casing.
%
% For reasonably obvious reasons, this package will not work at all
% well with the \Lpackage{multicol} package, and for possibly less obvious
% reasons, it won't work with the \Lopt{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 \emph{should} now work with \Lpackage{wrapfig}, though I'm not
% sure that I've exhausted that package's various clevernesses, and
% there might be some spacing and layout bugs which manifest
% themselves in that context.  Please report them; in the mean time,
% using option \Lopt{inline} should act as a workaround for any that
% appear.
%
% When labels appear in the margins, they sometimes appear on the
% `wrong' side in \Lopt{twoside} mode.  This is a fairly inevitable
% side-effect of the way that \TeX\ builds pages, and a specific
% symptom of the general problem described in
% \url{http://www.tex.ac.uk/cgi-bin/texfaq2html?label=oddpage}.
% As that answer suggests, there are bear-traps involved in the
% standard solutions.  Now, showlabels is (a)~permanently teetering
% on the edge of clashing with everything else that messes around with
% labels, and (b)~a draft-only package rather than anything that
% would appear in a final document.  (a)~means that I'm rather nervous
% about putting too much cleverness in there, and incidentally shy of
% putting any dependencies on other packages; (b)~means that I feel it
% doesn't really matter enough to be worth removing robustness.  So
% I'm afraid I don't plan to change this, and I simply put up with the
% occasional slip.  Again the \Lopt{inline} option is a possible
% workaround.
%
% The package might still work with \LaTeX2.09, but that's neither
% supported, nor even still tested.
%
% This software is copyright, 1999, 2001-09, 2013-22, 2025 Norman Gray.
% It is released under the terms of the \LaTeX\ Project Public Licence.
% See the copyright declaration at the top of file \texttt{showlabels.dtx},
% and the file \texttt{lppl.txt}, for the licence conditions.
%
% The canonical home page of the package is
% \url{https://purl.org/nxg/dist/showlabels}, and it is on CTAN at
% \url{https://ctan.org/pkg/showlabels}.  The source is in
% a repository online: \url{https://heptapod.host/nxg/showlabels}.
%
% \section{Other packages}
%
% The \Lpackage{showlabels} package has a large overlap in
% functionality with David Carlisle's \Lpackage{showkeys}, although
% the latter will only handle |\label| and |\cite| keys.  If
% \Lpackage{showlabels} fails in some particular situation, you might
% want to try using \Lpackage{showkeys}, but please do mention the
% problem, typically by email to me.
%
% \section{History and Credits}
%
% I've received bug reports, fixes, or implementable suggestions from many
% people, including
%   Andreas Balser,
%   bartgol (on Stackexchange),
%   Francesco Biccari,
%   Francis M. C. Ching,
%   Sven de Vries,
%   A L Dukeman,
%   Michael Friendly,
%   Guillermo Garza,
%   Romano Giannetti,
%   Tino G\"ortem\"oller,
%   Lester L. Helms,
%   Boris Kheyfets,
%   Hagen Kleinert,
%   David R. Leal Valmana,
%   Olivier Michel,
%   Aaron Montgomery,
%   Enno Nagel,
%   Sungmo Park,
%   Ignacy Sawicki,
%   Mike Schroeder,
%   Andrei Shelankov,
%   Patrick Sibille,
%   `Stirling' (on Stackexchange),
%   Mariano Su\'arez-Alvarez,
%   Ji\v ri Vesely,
%   Elmar Walhorn,
%   Alex Watson,
%   Ben William Carabelli,
%   Roland Winkler.
% Many thanks to all.  If I've missed your name out of this list
% (or indeed if I've alphabetised you incorrectly),
% please accept my apologies, and do let me know.
%
% The package was originally released by me on 1991 September 21, under the name
% \texttt{labels.sty}.
% On 1992 January 29, Darrel Hankerson
% \url{hank@ducvax.auburn.edu}, made the update to NFSS, and
% changed the name to `showlabel.sty'.
%
% \subsection{Release notes}
% \begingroup
% \iffalse the following are variously unsatisfactory
%   \def~{\texttt{\textasciitilde}}
%   \def~{$\sim$}
% \fi
% \catcode`\~=12
% \iffalse @RELEASENOTES@ \fi
% \begin{description}\item[1.9.3, 2025 August 20]\relax Feedback suggests the reported problems seems resolved in practice.
%       No changes from 1.9.3-b1, beyond some minor documentation and
%       bundling adjustments.\par \item[1.9.3-b1, 2025 August 10]\relax   \P\thinspace Fixed an (invisible) duplication in the amsmath support.
%         Thanks to the discussion on a
%         LaTeX3 issue\footnote{\url{https://github.com/latex3/latex2e/issues/118}}
%         for the clue here.  \P\thinspace Fix: handling of colours
%         (issue 3\footnote{\url{https://heptapod.host/nxg/showlabels/-/issues/3}};
%         thanks to Aaron Montgomery for reporting).  \P\thinspace Fix: when marking non-|\label| commands, if
%         these were found within non-display maths mode, then they didn't
%         appear as shown labels
%         (issue 4\footnote{\url{https://heptapod.host/nxg/showlabels/-/issues/4}};
%         thanks to Mike Schroeder for reporting).  \P\thinspace Fix: labels were being spuriously reported when using
%         amsmath's |\eqref| command
%         (issue 6\footnote{\url{https://heptapod.host/nxg/showlabels/-/issues/6}};
%         thanks to Tamas Lakoba for reporting)\par\item[1.9.2, 2022 July 18]\relax No code changes from 1.9.2-b1, but the documentation notes a new home repository.\par \item[1.9.2-b1, 2022 June 11]\relax   \P\thinspace Fixed a spacing bug when used with the |wrapfig| package
%         (issue 2\footnote{\url{https://heptapod.host/nxg/showlabels/-/issues/2}};.
%         Thanks to Romano Giannetti for the report).  \P\thinspace Added a |\showlabelsmarginal| command.  \P\thinspace The code has moved (again) to
%         heptapod.host\footnote{\url{https://heptapod.host}}: the new
%         repository is
%         https://heptapod.host/nxg/showlabels\footnote{\url{https://heptapod.host/nxg/showlabels}}.
%        The issues links in the list below are therefore broken.\par\item[1.9.1, 2021 October 27]\relax Commands with optional arguments, such as
%       |\bibitem[P\'olya]{polya_54}| are now handled with the
%       correct catcodes.
%       Fixes issue 1\footnote{\url{https://heptapod.host/nxg/showlabels/-/issues/1}}
%       (\emph{Note:} new sequencing for issues, after a repo change).
%       Thanks to Michael Levitin for the report here.\par \item[1.9, 2021 October 9]\relax   \P\thinspace Robustness fix: macros in arguments are now handled, so that
%   (after |\showlabel{index}|),
%   |\index{Poincar\'e}| doesn't cause an error.  \P\thinspace The |\showlabel[optarg]{command}| optional argument
%   can now take a one-argument command.  \P\thinspace The macro |\showlabeltype| expands to the current
%   label type, for possible use in |\showlabelsetlabel|.\par\item[1.8, 2016 June 9]\relax The |ntheorem| package exposed an apparently
% long-standing incompleteness in the handling of |amsmath|
% documents.
% Fixes issue 9\footnote{\url{https://bitbucket.org/nxg/showlabels/issues/9/}}.\par \item[1.7, 2015 December 8]\relax Release v1.7.\par \item[1.7b2, 2015 December 7]\relax Make the combination of amsmath and [inline] mode work
% (fixes issue 8\footnote{\url{https://bitbucket.org/nxg/showlabels/issue/8/}}
% – thanks to A L Dukeman for the report;
% what is it about showlabels and 6 December?!).\par \item[1.7b1, 2014 December 6]\relax This is a much-delayed bugfix release (by coincidence
% \emph{exactly} a year after the previous release!).\par   \P\thinspace Give |\showlabels| an optional formatting argument
% (implements issue 1\footnote{\url{https://bitbucket.org/nxg/showlabels/issue/1/}}
% – thanks to Francesco Biccari for the suggestion).  \P\thinspace Special-case the IEEEtrantools package
% (fixes issue 2\footnote{\url{https://bitbucket.org/nxg/showlabels/issue/2/}}
% – thanks to Boris Kheyfets for the report and test case, and to
% Ben William Carabelli for additional analysis and a draft fix).  \P\thinspace The |[final]| option now works with the
% |{amsmath}| package
% (fixes issue 3\footnote{\url{https://bitbucket.org/nxg/showlabels/issue/3/}}
% – thanks to Guillermo Garza and Enno Nagel for the report, and to
% Guillermo for the test case).  \P\thinspace Handle the hyperref package's |\ref*{label}| variant
% (fixes issue 4\footnote{\url{https://bitbucket.org/nxg/showlabels/issue/4/}}
% – thanks to Alex Watson for the report and test case).  \P\thinspace Handle the case where a label is in a display, but not in maths mode
% (fixes issue 5\footnote{\url{https://bitbucket.org/nxg/showlabels/issue/5/}}
% – thanks to ‘bartgol’ on Stackexchange for the report and test case).\par\item[1.6.6, 2013 December 6]\relax   \P\thinspace Add configuration interface |\showlabelrefline| and
% ensure that |\color| works in
% |\showlabelfont|.  \P\thinspace Various documentation tweaks.  \P\thinspace Change licence from GPL to LPPL.  \P\thinspace Fix link to repository.\par\item[1.6.5, 2009 May 27]\relax Fixed a bug in the way that labels including underscores (and
% other ‘exotic’ characters) were displayed.\par \item[1.6.4, 2008 October 10]\relax Fixed another poor interaction between eqnarray and amsart.  Now
% we get equation labels in eqnarray, and we don't get marginal notes
% about |\eqref| (which is good; might this finally be fixed?).\par \item[1.6.3, 2008 July 24]\relax Release 1.6.2 broke compatibility with the \emph{rest} of
% amsmath (|eqnarray| became the only thing that worked
% within amsmath)!  Fixed.  Doh!\par \item[1.6.2, 2008 June 27]\relax The reimplementation of eqnarray within amsart was such that
% equation labels disappeared in that case.  Fixed.\par \item[1.6.1, 2007 June 17]\relax Fix an errant test, which mangled equation labels starting
% with two identical letters.\par \item[1.6, 2006 May 26]\relax The |\showlabels| command will now work with commands
%   (such as |\cite| or |\includegraphics|) which
%   take an optional argument.\par \item[1.5a, 2005 March 17]\relax Defined |\showlabelfont| using
% |\ttfamily| rather than |\tt| (I'd
% avoided doing this before to avoid a seemingly pointless
% incompatibility with LaTeX 2.09, but (a) I imagine the
% package is incompatible with that for other reasons, and (b)
% it's really not worth the hassle...).\par \item[1.5, 2004 October 8]\relax Added |\showlabelfont| and
% |\showlabelsetlabel| commands, allowing
% customisation of the printed labels.  Added and documented
% options [final], [draft] (the former makes this package do
% nothing; the latter is the default behaviour).\par \item[1.4a, 2003 January 28]\relax Acquired the |[left]| and
% |[right]| options, and fixed a bug which affected
% |\label| commands in captions.\par \item[1.4, 2001 July 24]\relax Became (more) compatible with the
% wrapfig package.  Also, I added the
% |\showlabels| command, to have the package display
% references to commands other than |\label|
% (|\cite| and |\ref| are obvious ones),
% and an |[inline]| option to have labels (etc.)
% displayed inline where possible, rather than always in the
% margin.\par \item[1.3e, 2001 May 30]\relax Became compatible with the hyperref package in
% particular, and in general with other packages which
% themselves modify the |\label| command.  This will
% work, however, only if the showlabels package is loaded after
% other packages which do this.  Notwithstanding Sebastian
% Rahtz's excellent general advice on this, showlabels should
% indeed be loaded after hyperref.\par \item[1.3e, 2001 May 31]\relax After a long delay, here is an updated version of my showlabels
% package.  It corrects all the reported bugs which I could reproduce,
% namely:\par   \P\thinspace The package now formats labels correctly when the
% |\label| command appears outside either an equation or a
% |\caption| (silly of me).  \P\thinspace A couple of people reported problems in the interaction with the
% amsmath package.  Either these were confined to that package's earlier
% incarnations as AMS-LaTeX or the amstex package, or else there's some
% arcane circumstance I can't reproduce, so I haven't found anything to
% fix on this matter.  Note that the
% |\usepackage{showlabels}| command must come \emph{after}
% the |\usepackage{amsmath}| command.  Bug-sightings here
% will be warmly appreciated.  \P\thinspace I haven't worried too much about the precise formatting of the
% labels – this is, after all, supposed to be a draft-only
% package.\par\item[1.1, 2001 January 1]\relax 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 \emph{must} appear
% after the |\usepackage{amsmath}| if it is to detect that
% you are using the amsmath package.  Note also that, since these
% additions appeared, AMS-LaTeX 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, though it will probably work with
% older versions in fact.\par This is the first version of the package to be distributed under
% the name |showlabels|.\par \item[Updated, 1992 January 29]\relax On 1992 January 29, Darrel Hankerson
% (|hank@ducvax.auburn.edu|), made the update to NFSS, and
% changed the name to |showlabel.sty|.\par \item[Original, 1991 September 21]\relax The package was originally released by me on 1991 September 21, under the name
% |labels.sty|.\par \end{description}% \endgroup
%
% \MaybeStop
%
% \section{Implementation}
%    \begin{macrocode}
%<*package>
%    \end{macrocode}%
% \iffalse
% Update history:
% October 94: Norman Gray (gray@nxg.name). Modified to be a
% \LaTeX2e package.
% 29-Jan-92 Darrel Hankerson (hank@ducvax.auburn.edu)
%  Update to NFSS. Change name to `showlabel.sty'. Substitute
%       \nintt -> \small\tt
%       \sevit -> \scriptsize\it
% 21-Sep-91 Norman Gray  no_gray@vax.acs.open.ac.uk
%  Original release of labels.sty
% \fi
%
% The principle command is |\SL@wrap@labeller|, which monkeypatches a
% command |\foo| by creating a command |\SL@origfoo| with the original
% definition, and (re)defining |\foo| to call that original version,
% while immediately including a call of a macro |\SL@set@text| which
% sets the argument of |\foo| appropriately.
%
% Without \Lpackage{amsmath}, the only thing remaining is to ensure
% (by default) a call |\SL@wrap@labeller{@eqnnum}|, to ensure that
% this happens to equation labels, too.
%
% \emph{With} \Lpackage{amsmath}, however, things are more
% complicated, since that package has an independent mechanism for
% setting equation labels.  Almost all of the relevant
% \Lpackage{amsmath} code paths run through the command |\maketag@@@|,
% enough that this is really the only macro we need to patch.  Most of
% the intricacy below comes from (i)~the slightly different sequence
% of the commands when labelling an equation in \Lpackage{amsmath},
% and (ii)~the fact that calls to |\maketag@@@| are not quite
% restricted to this case.
%
% Before we do anything else, find out if we're using \Lpackage{amsmath}.
%    \begin{macrocode}
\newif\ifSL@AMS
\@ifundefined{maketag@@@}
  \SL@AMSfalse
  {\SL@AMStrue\typeout{with amsmath equation tags}}
%    \end{macrocode}
%
% \begin{macro}{\SL@set@text}
% The command which sets equation text is |\SL@set@text|, which tests
% whether the content should be inline or not.
%    \begin{macrocode}
\def\SL@set@text{%
  \ifSL@labelsinline
    \let\@tempa\SL@interlinetextleft
  \else
    \let\@tempa\SL@set@lrtext
  \fi
  \@tempa
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\SL@wrap@labeller}
% The |\SL@wrap@labeller| macro wraps the given macro in such a way
% that we display the label.
% |\SL@labelname| is initialised to |\relax|, redefined within the
% |\label| macro, and reset to |\relax| after use here.  If it's
% already equal to |\relax| in this macro, the equation number hasn't
% been labelled, and so we avoid putting anything in the margin.
%    \begin{macrocode}
\def\SL@wrap@labeller#1{%
  \expandafter\let\csname SL@orig@#1\expandafter\endcsname\csname #1\endcsname
  \expandafter\def\csname #1\endcsname{%
    \csname SL@orig@#1\endcsname
    \ifx\SL@labelname\relax
      % do nothing
    \else
      \SL@set@text{\SL@labelname}%
    \fi
    \global\let\SL@labelname\relax}}
%    \end{macrocode}
% \end{macro}
%
% First, deal with the case where the document uses the
% \Lpackage{amsmath} macros.
%    \begin{macrocode}
\ifSL@AMS
%    \end{macrocode}
%
% \begin{macro}{\maketag@@@}
% \Lpackage{amsmath} redefines |\label| to set the macro |\df@label|,
% and then uses |\maketag@@@{\df@label}| or |\tagform@| to form tags
% (ie, equation labels) in equations.  The command |\tagform@| wraps
% |\maketag@@@|, so we needn't wrap both.  Indeed, we \emph{mustn't}
% wrap both, or else we duplicate any side-effects that happen in
% there, such as typesetting the label!  As discussed in a similar
% bugreport for \Lpackage{showkeys}
% (see \url{https://github.com/latex3/latex2e/issues/118} and test t/t21.tex),
% monkeypatching both commands ends up double-setting the equation
% label, which is invisible, but still wrong.
%
% If the |\df@label| is empty
% (almost certainly because the user has used the
% \Lenv{eqnarray} environment within \Lpackage{amsmath}),
% then fall back on the |\SL@labelname| contents instead.
% \iffalse See tests t2, t11 and t18. \fi
% We must make sure to leave |\SL@labelname| equal to |\relax| at the
% end of this macro, otherwise a |{eqnarray}| followed by an (amsmath)
% |\eqref| can end up with the wrong label being referred to by the
% |\maketag@@@| within |\eqref| (or something like that).
%
% The test here must be |\ifx\SL@labelname\relax| with
% |\global\let\SL@labelname\relax|, not |\expandafter\ifx\SL@...| and
% |\global\def\SL@labelname{\relax}| (as it once was), since the
% latter evaluates to true when |\SL@...| is |\relax| \emph{and} when
% |\SL@...| starts with two identical characters, which is wrong (it
% took embarrassingly many goes to get this right).
%
% The following is
% similar to the effect of |\SL@wrap@labeller|, but is not quite identical,
% because (a) |\maketag@@@| and |\tagform@| take an argument,
% and (b) we also have to check |\df@label|.
%
% This is happening \emph{before} we expand the |\label| that we have
% patched.  That means that, at the time the equation text is set in
% |\SL@set@text|, we have not set the |\SL@fmt@| appropriately.
% Therefore, as part of the general special-casing of
% \Lpackage{amsmath} labels, we must do this explicitly here (see test t23).
%
% The final wrinkle here is that we must distinguish between this
% being called when |\displaywidth| is 0pt, and when it is non-zero.
% In the latter case, we are in a display, setting the equation
% number.  The former case occurs because \Lpackage{amsmath}'s
% |\eqref| calls |\maketag@@@| via |\tagform@|, and if we don't detect
% this (by detecting that this is being called outside a display) then
% we get a spurious appearance of the printed label obscuring the text
% (see tests t2 and t17, and heptapod issue \#6).
%
% The \Lpackage{amsmath} package includes support for the
% \Lpackage{showkeys} package, by including hooks |\SK@...| for a few
% package functions.  It might be reasonable, at some point, to
% examine these more closely, and possibly start monkeypatching \emph{these}.
% \begin{macro}{\SL@setlabel@ams}
%    \begin{macrocode}
  \def\SL@setlabel@ams{%
    \let\SL@fmt@\SL@fmt@label
    \ifdim\displaywidth>0pt
      \ifx\df@label\@empty
        \ifx\SL@labelname\relax
          % do nothing
        \else
          \SL@set@text{\SL@labelname}%
        \fi
      \else
        \SL@set@text{\df@label}%
      \fi
    \fi
    \global\let\SL@labelname\relax
  }
  \let\SL@orig@maketag@@@=\maketag@@@
  \def\SL@maketag@@@#1{%
    \SL@orig@maketag@@@{#1}%
    \SL@setlabel@ams
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@eqnnum}
% Next, deal with the `normal' case, without \Lpackage{amsmath}.
% Package \Lpackage{amsmath} redefines |\@eqnnum| in terms of
% |\maketag@@@|, so we should avoid touching this in the
% non-\Lpackage{amsmath} case.
%    \begin{macrocode}
\else
  \SL@wrap@labeller{@eqnnum}
\fi
%    \end{macrocode}
% \end{macro}
% And initialise the value of |\SL@labelname| to |\relax|, so that
% |\@eqnnum| starts off behaving the right way.
%    \begin{macrocode}
\global\let\SL@labelname\relax
%    \end{macrocode}
%
% Labels are printed with the font specified by |\showlabelfont|, which
% can be overridden within the document:
% Define this using |\ttfamily|, unless we're still using \LaTeX 2.09
% (surprising it still works!), in which case stick with |\tt|.
%    \begin{macrocode}
\@ifundefined{ttfamily}
  {\providecommand{\showlabelfont}{\small\tt}}
  {\providecommand{\showlabelfont}{\small\ttfamily}}
%    \end{macrocode}
%
% \begin{macro}{\showlabelsetlabel}
% If you want slightly more general control over the labels, you can
% instead override |\showlabelsetlabel|.
%    \begin{macrocode}
\providecommand{\showlabelsetlabel}[1]{{\normalfont\showlabelfont\SL@fmt@{#1}}}
%    \end{macrocode}
% \end{macro}
%
% For the benefit of |\SL@prlabelname|, define |\SL@gobblethree| to do nothing
% other than eat three tokens.
%    \begin{macrocode}
\def\SL@gobblethree#1#2#3{}
%    \end{macrocode}
%
% \begin{macro}{\SL@prlabelname}
% Expansion is label name with all catcodes `other' (Appendix~D trickery
% abounds!).  Use |\r@#1| (defined by |\ref|), rather then just |\#1|
% to avoid defining any new control sequences.
%
% Note that this catcode magic, and the |\@sanitize| in
% |\SL@showlabels| below, are doing much the same job, and indeed are
% almost redundant with each other.  But this |\SL@prlabelname|
% doesn't cope with eg |\index{Poincar\'e}|, and the |\@sanitize|
% below doesn't cope with |\section{\label{a_b}Foo}| (see tests t4 and t19).
%    \begin{macrocode}
\def\SL@prlabelname#1{%
\expandafter\expandafter\expandafter\SL@gobblethree
    \expandafter\string\csname r@#1\endcsname}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\showlabels}
% Define the |\showlabels| command which allows us to redefine
% commands which are to have their arguments highlighted.
% That is, |\showlabels{foo}| means that the command |\foo{bar}| will
% write `bar' in the margin, as well as executing whatever |\foo| does
% normally.
%
% The net result of all this is that a |\showlabels{foo}| command
% arranges things so that, after |\begin{document}|, the original
% version of |\foo| is saved in |\SL@origfoo|, and |\foo{bar}| expands into
% |\SL@setlabel{bar}\SL@origfoo{bar}|.
%
% First, define a command |\SL@initfoo|, which, when executed, will
% save the current (at that time) behaviour of the command |\foo| as
% |\@SL@origfoo|, and then set |\foo| to be equivalent to |\SL@foo|,
% which does the magic; we will
% shortly give this command to |\AtBeginDocument|, so that it is
% switched on at the correct time, when other packages have done
% \emph{their} redefinitions of |\foo| (this makes it compatible with
% the \Lpackage{hyperref} package, which does its own wholesale redefinitions of
% things like |\label|).  Below, the locution
% |\the\@temptokena| causes the token contents of |\@temptokena| to be
% included unexpanded in the definition, despite the |\edef|.
%
% If the optional |\showlabels| argument is present, then use this as per-command
% formatting, so that, for example |\cite| instances may be formatted
% distinctively from |\label|.
%    \begin{macrocode}
\def\showlabels{\@ifnextchar[\showlabels@{\showlabels@[]}}
\def\showlabels@[#1]#2{%
  \@temptokena=\expandafter{\csname #2\endcsname}
  \def\@tempa{#1}%
  \ifx\@tempa\@empty
    \expandafter\let\csname SL@fmt@#2\endcsname\relax
  \else
    \expandafter\def\csname SL@fmt@#2\endcsname{#1}%
  \fi
  \expandafter\edef\csname SL@init@#2\endcsname{%
    \let\csname SL@orig#2\endcsname\the\@temptokena
    \let\the\@temptokena\csname SL@#2\endcsname}
  \AtBeginDocument{\csname SL@init@#2\endcsname}%
%    \end{macrocode}
% \emph{Now} define |\SL@foo| -- it must be undefined when we define
% |\SL@initfoo| above, so that it isn't expanded in the |\edef|.
%    \begin{macrocode}
  \expandafter\def\csname SL@#2\endcsname{%
    \expandafter\let\expandafter\SL@fmt@\csname SL@fmt@#2\endcsname
    \SL@showlabels{#2}}
}
%    \end{macrocode}
%
% We need a default definition of |\SL@fmt@| for the cases (some
% equation formatting) where we don't get to the formatting via this
% mechanism.
%    \begin{macrocode}
\let\SL@fmt@\relax
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\SL@showlabels}
% Now we get to the command which does the main processing.  The
% |\SL@showlabels| command calls |\SL@setlabel| to format the label
% (putting it in the margin, for example), then calls the original
% |\foo| command (namely |\SL@origfoo|) with the original argument.
%
% The command takes a single argument, namely the name of the command
% being wrapped (for example, `label').  We set |\@tempa| to be the
% original version of that command (stored in |\SL@orig#1|), and then
% take one of two similar paths, depending on whether the command has
% an optional argument or not.
%
% We have to be somewhat careful about the positioning of the
% |\@bsphack| and |\@esphack| commands.  The |\@esphack| command should
% \emph{not} come after the call to |\SL@origfoo|, since that would
% confuse things terribly if that command took any other arguments, or
% otherwise messed with the token stream (there's actually no problem
% in the most common case where we're replacing |\label|, and calling
% |\SL@origlabel|, but there are problems when we try to replace
% |\begin| or |\ref| in this way).  Instead, adapt the contents
% of |\@esphack|, but instead of calling |\ignorespaces| when
% |\@savsk| is positive, add an |\hskip| of 1~scaled point (equal to
% $1/65536\mathrm{pt}=5.363\times10^{-9}\mathrm{m}$).  This will be
% invisible, but it \emph{is} greater than zero, so that if
% |\SL@origfoo| itself uses a |\@bsphack|\dots|\@esphack| pair then
% the saved |\@savsk| will be positive, and that future |\@esphack|
% will correctly invoke |\ignorespaces|; that pair will also pick up
% the |\spacefactor| we restore here.  The net result is that the
% |\SL@setlabel| is invisible, and |\SL@origfoo| is able to make
% itself invisible, too.  Command sequence |\SL@setlabel| is what does
% the work -- this is |\let| equal to either |\SL@margtext| or
% |\SL@inlinetext| below.
%
% We must declare |\SL@showlabels| to be a robust command, or else we
% get confusing expansion problems when, for example, we do
% |\showlabels{ref}| and use |\ref| in a caption (see test case t3).
% We actually handle three distinct cases here, for |\foo{label}|,
% |\foo[opt]{label}| and |\foo*{label}| (the last is to handle the
% \Lpackage{hyperref} package's |\ref*{label}| variant; see test case
% t14).
%
% Note that in each case, the |label| is read with sanitised
% catcodes.  That is, I think, always an acceptable thing to do, in
% the sense that I can't think of cases where this breaks anything.
%
% We open a group in order to call |\@sanitize|; we're able to close
% it immediately, within the called macros.  We call |\@sanitize| in
% order to cope with eg |\index{Poincar\'e}| (see discussion of
% |\SL@prlabelname| above).  We carefully \emph{avoid} calling
% |\@sanitize| before reading an optional argument: this is so that
% we read that argument with the existing catcode
% assignments, so that eg |\bibitem[P{\'o}lya]{polya54}| works as
% expected (see test t20).
%
% We declare |\showlabeltype| to be the `current' label type.  It
% would be good to put this inside a group, so that it's only visible
% locally, but we would then have to be careful exactly when we closed
% the group: if we put it inside the group that's opened for
% |\@sanitize|, it would be closed too early to have an effect; if we
% open another group for |\showlabeltype|, then we'd have to close it
% \emph{after} |\SL@orig@@next|, where we risk colliding with whatever
% comes after it (and see above).  It might be possible to be cleverer
% about this, but it's at least harmless to have the command defined
% globally.
%    \begin{macrocode}
\DeclareRobustCommand\SL@showlabels[1]{%
  \@bsphack
  \expandafter\let\expandafter\SL@orig@@next\csname SL@orig#1\endcsname
  \def\showlabeltype{#1}%
  \begingroup
  \@ifstar
    {\@sanitize\SL@showlabelsplainstar}
    {\@ifnextchar[
       {\SL@showlabelsopt}
       {\@sanitize\SL@showlabelsplain}}}
\def\SL@showlabelsopt[#1]{% #1 is read before \@sanitize
  \@sanitize
  \SL@showlabelsopt@ii{#1}}
\def\SL@showlabelsopt@ii#1#2{%
  \endgroup
  \SL@setlabel{#2}\relax
  \ifhmode \spacefactor\@savsf \ifdim\@savsk>\z@ \hskip1sp \fi\fi
  \SL@orig@@next[#1]{#2}}
\def\SL@showlabelsplain#1{%
  \endgroup
  \SL@setlabel{#1}\relax
  \ifhmode \spacefactor\@savsf \ifdim\@savsk>\z@ \hskip1sp \fi\fi
  \SL@orig@@next{#1}}
\def\SL@showlabelsplainstar#1{%
  \endgroup
  \SL@setlabel{#1}\relax
  \ifhmode \spacefactor\@savsf \ifdim\@savsk>\z@ \hskip1sp \fi\fi
  \SL@orig@@next*{#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@makecaption}
% The |\@makecaption| command needs special treatment.  The
% |\SL@margtext| command doesn't work in figure captions, so we need
% to force the layout commands to use |\SL@inlinetext| instead, for
% all label types, and irrespective of whether we're using the
% \Lopt{inline} option.  The code here is independent of that in
% |\showlabels|, but imitates it, for consistency.
%    \begin{macrocode}
\def\SL@initmakecaption{%
  \let\SL@origmakecaption\@makecaption
  \def\@makecaption##1##2{{%
    \let\SL@setlabel\SL@inlinetext
    \SL@origmakecaption{##1}{##2}}}}
\AtBeginDocument{\SL@initmakecaption}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\SL@margtext}
% This is the central bit of this package, used by |\SL@showlabels|.
% The argument is the argument of the |\foo| command which we're
% processing (for example, the argument to a |\label| command).
%
% Depending on the mode, put the
% current label name in the margin in one of a variety of ways.
%    \begin{macrocode}
\def\SL@margtext#1{%
%    \end{macrocode}
%
% There are three cases here:
% \begin{enumerate}
% \item We are in maths mode, setting an equation.
%   We need to distinguish (1a) being in a display, when we \emph{assume}
%   we're processing a |\label|, and (1b) not, when we should act more like
%   case~3.  Note that case 1a is somewhat heuristic, and will go
%   wrong if someone uses the |\showlabels{foo}| mechanism to show
%   some different command within a maths display.
% \item We are not in maths mode but we \emph{are} within a display
% (this can happen in, for example, the \Lenv{cases} environment from
% the \Lpackage{cases} package).
% \item We are in text.
% \end{enumerate}
% There are two outcomes:
% \begin{enumerate}
%   \item we print a label name alongside the equation number
%   (cases~1a and~2), or
%   \item we produce a zero-height box in the vertical list (cases~1b
%   and~3).
% \end{enumerate}
%
% Case 1:
% In maths mode, and \emph{if} we're in a display (case~1a), produce a
% label name alongside the equation number; if we're not in a display
% (case~1b), then act like case~3.
%    \begin{macrocode}
  \ifmmode
    \ifdim\displaywidth>0pt
      \@tempswatrue
    \else
      \@tempswafalse
    \fi
%    \end{macrocode}
%
% Case 2:
% Check if we're within a display equation,
% and if so act as if we are in maths mode (ie, as above).
% Note: most contexts which match case~1 would also be caught by this
% test, since |\label| is used almost exclusively within displays,
% but it seems clearer to separate the two cases explicitly, as well
% as probably dealing better with cases where the package is used for
% non-|\label| commands.
%    \begin{macrocode}
  \else\ifdim\displaywidth>0pt
    \@tempswatrue
%    \end{macrocode}
%
% Case 3:
% Otherwise, create an inter-line zero-height box.
%    \begin{macrocode}
  \else
    \@tempswafalse
  \fi\fi
%    \end{macrocode}
% Now, |\@tempswa| is true if we are to make a label, and false if
% we're to include an interline box.
%
% True case first:
% Save the label name in |\SL@labelname|, so we can use it later
% (this is redundant in most \Lpackage{amsmath} contexts, because that
% style generally saves this in |\df@label|, but sometimes -- for
% example when using the traditional \Lenv{eqnarray} environment
% within \Lpackage{amsart} -- |\df@label| can end up unset).
%    \begin{macrocode}
  \if@tempswa
    \xdef\SL@labelname{\SL@prlabelname{#1}}%
%    \end{macrocode}
% 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
% |\box\@tempboxa| (which probably shouldn't be necessary).  The box
% here we set to be the width of |\hsize|.  This is \emph{probably}
% best, though there's always the worry that |\linewidth| would be the
% more \LaTeX-ish thing to do -- using |\columnwidth| is almost
% certainly wrong, since |\linewidth| can sometimes be changed without
% |\columnwidth| changing with it (for example, in package
% \Lpackage{wrapfig}), causing \Lpackage{showlabels} to fail badly.
%    \begin{macrocode}
  \else
    \setbox\@tempboxa=\vbox to 0pt{%
      \vss
      \hbox to \hsize{\SL@lrtext{#1}}}%
    \dp\@tempboxa\z@
%    \end{macrocode}
% Attach this box below the last one, using |\nointerlineskip| if we're in
% vertical mode, or |\vadjust| otherwise.  We need to save and restore
% the value of |\prevdepth| (which has the sentinel value -1000pt if we're
% adding this box at the beginning of a vertical list, and
% |\nointerlineskip| sets |\prevdepth| to this same value).  If we don't
% do this, we get extra (`interline') vertical space added in this
% case (it might be thought smart to use |\marginpar| here, and so
% avoid some of this nonsense, but that's not possible since this
% might be called within boxes, which |\marginpar| objects to).
%
% We don't always get the vertical spacing right here,
% but that's perhaps a problem for another day.
%    \begin{macrocode}
    \ifvmode
      \@tempdima=\prevdepth
      \nointerlineskip\box\@tempboxa\nobreak
      \prevdepth=\@tempdima
    \else
      \vadjust{\box\@tempboxa\nobreak}%
    \fi
  \fi
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\SL@inlinetext}
% This is an alternative way of formatting the label, which puts it
% inline as much as possible, and avoids straying into the margins.
% We just use the same mechanism as for |\SL@margtext|, but do the
% inline-or-not testing there.
%
% If |\df@label| is non-empty, then we are setting an (AMS) equation
% label, and the display of the label text has been done in
% |\SL@setlabel@ams|, so we mustn't repeat it here.
% \iffalse see test t17\fi
%    \begin{macrocode}
\def\SL@inlinetext#1{%
  \ifx\df@label\@empty
    \SL@interlinetextright{\SL@prlabelname{#1}}%
  \fi
}
%    \end{macrocode}
% In vmode, put the label between lines.  Set the box depth to zero to
% make sure that descenders don't mess up the spacing.
%    \begin{macrocode}
\def\SL@interlinetextleft{\SL@setlefttrue\SL@interlinetext}
\def\SL@interlinetextright{\SL@setleftfalse\SL@interlinetext}
\def\SL@interlinetext#1{%
  \setbox\@tempboxa=\hbox{\showlabelsetlabel{\SL@prlabelname{#1}}}\dp\@tempboxa\z@
  \ifvmode
    \@tempdima=\prevdepth
    \nointerlineskip\vbox to 0pt{\vss
      \hbox to \hsize{\hss \box\@tempboxa}}\nobreak
    \prevdepth=\@tempdima
%    \end{macrocode}
% And in horizontal mode, squeeze it between the lines, at the current point,
% carefully taking up no space.
%    \begin{macrocode}
  \else
    \ifSL@setleft
      \hbox to 0pt{%
        \hss
        \vbox to 0pt{\vss
          \hbox to 0pt{\hss\box\@tempboxa}%
          \showlabelrefline
        }}%
    \else
      \hbox to 0pt{%
        \vbox to 0pt{\vss
          \box\@tempboxa
          \showlabelrefline
        }\hss}%
    \fi
    \penalty10000
  \fi
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\showlabelrefline}
% Set a short line which indicates the point where a label is
% attached, when producing inline labels.  This additionally positions
% the label up above the line.
%    \begin{macrocode}
\def\showlabelrefline{\hrule width 0.05em height 1.5ex depth 0pt }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\SL@margintext}
% Set the actual text of the label.  Use |\SL@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.
%    \begin{macrocode}
\def\SL@margintext#1{{\showlabelsetlabel{\{\SL@prlabelname{#1}\}}}}
%    \end{macrocode}
% \end{macro}
%
% 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 |\SL@labelposition| below, to
% one of |\SL@lefttext|, |\SL@righttext| or |\SL@alternatetext|.
% \begin{macro}{\SL@righttext}
% \begin{macro}{\SL@lefttext}
%    \begin{macrocode}
\def\SL@righttext#1{\hfill\rlap{\quad\SL@margintext{#1}}}
\def\SL@lefttext #1{\llap{\SL@margintext{#1}\quad}\hfill}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\SL@setLR}
% Define a switch which allows us to state whether we've decided to
% set a particular label to the left or the right, and a macro
% |\SL@setLR| to set it.  After |\SL@setLR|, |\ifSL@setleft| is true
% if a label should be set to the left, and is false if it should go
% to the right.
%    \begin{macrocode}
\newif\ifSL@setleft
\def\SL@setLR{%
  \ifcase\SL@labelposition
    % 0=outer margin
    \ifodd\c@page
      \SL@setleftfalse
    \else
      \SL@setlefttrue
    \fi
  \or
    % 1=inner margin
    \ifodd\c@page
      \SL@setlefttrue
    \else
      \SL@setleftfalse
    \fi
  \or
    % 2=left margin
    \SL@setlefttrue
  \or
    % 3=right margin
    \SL@setleftfalse
  \else
    \SL@canthappen{Impossible labelposition \the\SL@labelposition}
    \SL@labelposition=3 % put everything in the right-margin for now
    \SL@setleftfalse
  \fi
}
%    \end{macrocode}
% \end{macro}
%
% 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.
% \begin{macro}{\SL@alternatetext}
%    \begin{macrocode}
\def\SL@alternatetext{%
  \SL@setLR
  \ifSL@setleft
    \let\SL@next\SL@lefttext
  \else
    \let\SL@next\SL@righttext
  \fi
  \SL@next
}
%    \end{macrocode}
% \end{macro}
% The case where the \Lopt{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@set@twocoltext| 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
% \file{multicol.sty} along with this).  This is defined and maintained in
% the base file \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.
% \begin{macro}{\SL@twocoltext}
%    \begin{macrocode}
\def\SL@twocoltext{%
  \if@firstcolumn
    \let\SL@next\SL@lefttext
  \else
    \let\SL@next\SL@righttext
  \fi
  \SL@next}
%    \end{macrocode}
% \end{macro}
%
% We have very similar things for equations, except that they are set in
% place, rather than within a zero depth box.  This code \emph{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 \Lopt{leqno} option (how?).
%
% Note that we \emph{do} want this to be |\columnwidth| rather than
% |\hsize|.  The \Lpackage{wrapfig} package retains the former as the
% width of the whole column, even though it carefully changes the
% latter to be the width of the \Lenv{wrapfigure} environment.  In the
% (unlikely) event we want numbered equations in such an environment
% \emph{and} this label ends up on the left, we do want the
% label right out in the left margin, rather than on the left of the
% \Lenv{wrapfigure} environment.
% \begin{macro}{\SL@set@righttext}
% \begin{macro}{\SL@set@lefttext}
%    \begin{macrocode}
\def\SL@set@righttext#1{\rlap{\quad\SL@margintext{#1}}}
\def\SL@set@lefttext #1{\hbox to 0pt{\kern -\columnwidth
        \llap{\SL@margintext{#1}\quad}\hss}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% Now do the analogues for the equation numbers, in the case of the
% alternate page selection\dots
% \begin{macro}{\SL@set@alternatetext}
%    \begin{macrocode}
\def\SL@set@alternatetext{%
  \SL@setLR
  \ifSL@setleft
    \let\SL@next\SL@set@lefttext
  \else
    \let\SL@next\SL@set@righttext
  \fi
  \SL@next
}
%    \end{macrocode}
% \end{macro}
% \dots and the twocolumn option
% \begin{macro}{\SL@set@twocoltext}
%    \begin{macrocode}
\def\SL@set@twocoltext{%
  \if@firstcolumn
    \let\SL@next\SL@set@lefttext
  \else
    \let\SL@next\SL@set@righttext
  \fi
  \SL@next}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\SL@canthappen}
% Issues a |\PackageError| command, and solicits bug reports.
%    \begin{macrocode}
\def\SL@canthappen#1{%
    \PackageError{showlabels}{#1}
        {This shouldn't happen -- the package showlabels has a bug.
        \MessageBreak
        Please report this, if possible with a sample document which
        \MessageBreak
        demonstrates the problem, to \filemaintainer.  Thanks.}}
%    \end{macrocode}
% \end{macro}
%
% To control the positioning of labels, set the |\SL@labelposition|
% switch, which can take values 0, 1, 2, 3, meaning outer, inner,
% left, right margin respectively.
%    \begin{macrocode}
\newcount\SL@labelposition
\SL@labelposition=0
%    \end{macrocode}
%
% We select between the various possibilities using the \Lopt{outer} and
% \Lopt{inner} options and, implicitly, the \Lopt{twoside} option.
%    \begin{macrocode}
\DeclareOption{outer}{\SL@labelposition=0}
\DeclareOption{inner}{\SL@labelposition=1}
\DeclareOption{left}{\SL@labelposition=2}
\DeclareOption{right}{\SL@labelposition=3}
%    \end{macrocode}
%
% Labels can be set either in the margins or inline, by switching
% between definitions of |\SL@setlabel|.
%    \begin{macrocode}
\newif\ifSL@labelsinline
\SL@labelsinlinefalse
\DeclareOption{marginal}{\SL@labelsinlinefalse}
\DeclareOption{inline}{\SL@labelsinlinetrue}
%    \end{macrocode}
% \begin{macro}{\SL@setlabel}
%
% Macro |\SL@setlabel| is where we switch between inline and marginal labels.
%    \begin{macrocode}
\def\SL@setlabel{%
  \ifSL@labelsinline
    \let\@tempa\SL@inlinetext
  \else
    \let\@tempa\SL@margtext
  \fi
  \@tempa
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\showlabelsinline}
% It is sometimes convenient (for example when a document encounters a
% situation which this package mishandles) to force inline labels
% temporarily, within a block or environment.  Use this macro to do
% that.
%    \begin{macrocode}
\def\showlabelsinline{\SL@labelsinlinetrue}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\showlabelsmarginal}
% Add the complementary macro for symmetry, even though this is not
% likely to be useful.
%    \begin{macrocode}
\def\showlabelsmarginal{\SL@labelsinlinefalse}
%    \end{macrocode}
% \end{macro}
% By default, we run |\showlabels{label}|.  The option \Lopt{nolabel}
% turns this off.
%    \begin{macrocode}
\newif\ifSL@labellabel
\SL@labellabeltrue
\DeclareOption{nolabel}{\SL@labellabelfalse}
%    \end{macrocode}
%
% Define the options \Lopt{final} and \Lopt{draft}.  The option
% \Lopt{final} turns off all the functionality of this package by
% disabling the command |\showlabels|, including the implicit
% |\showlabels| command which the package issues as long as the
% \Lopt{nolabel} option has not been given.  This is included so that if that
% option is given in the |\documentclass| declaration then this
% package does respect it.  \Lopt{draft} does nothing, and therefore
% simply continues the default behaviour of this package; it is here
% purely to partner the \Lopt{final} option.
%    \begin{macrocode}
\DeclareOption{final}{\let\showlabels\@gobble}
\DeclareOption{draft}{}
%    \end{macrocode}
%
% Process any options that have been set.
%    \begin{macrocode}
\ProcessOptions
%    \end{macrocode}
% and use the values of |\SL@labelposition| 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 \Lopt{twocolumn} option
% means that we ignore the \Lopt{inner} and \Lopt{outer} options.
%    \begin{macrocode}
\if@twocolumn
  \let\SL@lrtext\SL@twocoltext
  \let\SL@set@lrtext\SL@set@twocoltext
\else
  \ifcase\SL@labelposition
    % 0=outer margin
    \if@twoside
      \let\SL@lrtext\SL@alternatetext
      \let\SL@set@lrtext\SL@set@alternatetext
    \else
      \let\SL@lrtext\SL@righttext
      \let\SL@set@lrtext\SL@set@righttext
    \fi
  \or
    % 1=inner margin
    \if@twoside
      \let\SL@lrtext\SL@alternatetext
      \let\SL@set@lrtext\SL@set@alternatetext
    \else
      \let\SL@lrtext\SL@lefttext
      \let\SL@set@lrtext\SL@set@lefttext
    \fi
  \or
    % 2=left margin
    \let\SL@lrtext\SL@lefttext
    \let\SL@set@lrtext\SL@set@lefttext
  \or
    % 3=right margin
    \let\SL@lrtext\SL@righttext
    \let\SL@set@lrtext\SL@set@righttext
  \else
    \SL@canthappen{Impossible labelposition \the\SL@labelposition}
    \SL@labelposition=3 % put everything in the right-margin for now
    \let\SL@lrtext\SL@righttext
    \let\SL@set@lrtext\SL@set@righttext
  \fi
\fi
%    \end{macrocode}
%
% Finally, label all the |\label| commands
% (default behaviour),
% unless this has been suppressed through the \Lopt{nolabel} option.
%    \begin{macrocode}
\ifSL@labellabel
  \showlabels{label}
  \ifSL@AMS
    \ifx\showlabels\@gobble
      % do nothing -- we're in [final] mode (see test case t13)
    \else
      \AtBeginDocument{\let\maketag@@@\SL@maketag@@@}
    \fi
  \fi
  \@ifundefined{theIEEEsubequationdis}\relax % and \theequationdis
    {\SL@wrap@labeller{theIEEEsubequationdis}
     \SL@wrap@labeller{theequationdis}}
\fi
%    \end{macrocode}
%
% That's us.
%
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
% \Finale
\endinput
