# [tex-eplain] Warnings about redefinition of xref labels

Fri Mar 3 20:30:47 CET 2006

On Thu, Mar 02, 2006 at 04:51:55PM -0600, Karl Berry wrote:
>     I would suggest not checking the value, but only
>     the label to see if it was duplicated.
>
> This seems sensible.  The whole goal is to warn about
> \eqdef{foo}
> ...
> \eqdef{foo}
>
> And ditto for other xref defs.  And that's it.  Oleg ... ?

Sounds good to me.  What's more, basing the comparison on
the value is ACTUALLY BAD.  Imagine the user has an
\xrdef{ABC} defining ABC to 10, and \eqdef{ABC} also
defining ABC to 10.  So far no problem and no warning --
both \xref{ABC} and \eqref{ABC} produce the correct number,
10.  The happy unsuspecting user sends this file to the
editor, who, on the first nine pages, adds another page
(thus shifting page numbers) or moves an inline equation
into numbered display equation (thus shifting equation
numbers).  With the next compilation the editor gets an
ABC label.

And another minor point, about checking by \@definelabel:

> If it is duplicated, only warn if it is not empty.

It seems to me more logical the other way around:  not write
empty _equation_ labels into the aux file at all.  The
explicit purpose of an empty equation label is to define a
short-living cross-reference label which should not survive
past a single TeX run.  But an empty _non-equation_ label,
however weird, needs to pass through the aux file.

Turning the words into the code, I suggest the following
changes, if anybody cares to check:

\def\@definelabel#1{%
% Warn if we see that another label with the same name has been
% defined (remember, we are called when the aux file is read, which
% means that no labels have been defined yet except the ones which
% come earlier in this aux file).
\expandafter\ifx\csname\xrlabel{#1}\endcsname \relax
\else
\message{^^JLabel #1' multiply defined}%
\fi
% Define the control sequences.
\@definelabel at nocheck{#1}%
}%
%
\def\@definelabel at nocheck#1#2#3{%
% Define the control sequence.
\expandafter\gdef\csname\xrlabel{#1}\endcsname{#2}%
%
% Remember what kind of label this is, so \ref will know what to do.
%  \global\setproperty{\xrlabel{#1}}{class}{#3}%
\setpropertyglobal{\xrlabel{#1}}{class}{#3}%
}%
%
\def\@eqdefn#1#2{%
% Define hyperlink destination taking care of empty LABEL.
\hl at define@eqlabel{#1}%
\hldest at impl{eq}{\hl at eqlabel}%
% Write out the cross-reference into the aux file to allow
% forward references, but only if the label is not empty.
\ifempty{#1}%
% Read the auxfile anyway, so that \@definelabel's do the checks
% for multiple definitions before we define any cross-references.
\else
\begingroup
\@@hldestoff % Omit hyper dest (already defined above).
\definexref{#1}{#2}{eq}% Writes to the aux file.
\endgroup
\fi
% Define the LABEL but do not check for redefined labels.  The
% checking was done by \@definelabel when reading the aux file.
\@definelabel at nocheck{#1}{#2}{eq}%
}%

Also, since \hl at define@eqlabel also does the checking for
empty first parameter, I suggest moving its code inside
\@eqdefn and use just a single \ifempty{#1}.

As for the additional warning at the end of document, like
LaTeX's \end{document} does -- it would have been nice, but
unfortunately Eplain doesn't have any equivalent of
\end{document}.  And forcing the user to invoke some (new)
command at the end of the document or redefining \bye or
\end is IMHO a little too much :).

`