# [tex-eplain] \definexref problem

Tue Oct 11 15:14:06 CEST 2005

On Tue, Oct 11, 2005 at 06:57:44AM +0000, Adam Fenn wrote:
> When I put this into the following macro only the first reference to the
> first book appears in full whereas the first reference to each new book
> ought to be in full.

You have only one \iflongref, and it is set to true at the
first reference to the first book; any other references see
that it is already set to true, so they produce the short
ref.

What you need is some mechanism to record the fact that a
book was already referenced, and to do it per book.

One way to do this is to borrow from \xrefn itself.  For
each referenced book BOOK you can defined some marker'
macro, e.g., BOOK_x, to mark the book BOOK as referenced
(the underline prevents name clashes with other macros,
since normal macros would never have it in their names).
Eplain's macro which produces such a name is \xrlabel.  So
you can do something like the following:

\def\book#1#2#3{%
\definexref{#3:long}{#1}{}%
\definexref{#3:short}{#2}{}%
}

\def\bookref#1{%
\expandafter \ifx\csname\xrlabel{#1}\endcsname\relax % no marker defined
\global\expandafter\let\csname\xrlabel{#1}\endcsname\empty % define it
\csname\xrlabel{#1:long}\endcsname % produce the long ref
\else % the marker already defined
\csname\xrlabel{#1:short}\endcsname % produce the short ref
\fi
}

A few notes are in place.  First, use \global or \gdef when
defining such markers', otherwise they may be buried inside
a group, in which case the next reference outside the group
will not see it.

Second, if you always define a book before you refer to it,
there is no need in \definexref.  You can just define the
labels right away, without going through the .aux file:

\def\book#1#2#3{%
\expandafter\gdef\csname\xrlabel{#3:long}\endcsname{#1}%
\expandafter\gdef\csname\xrlabel{#3:short}\endcsname{#2}%
}%

(in this case, there's no need in \readauxfile in \bookref).

Third, to avoid any name clashes, it is best not to use the
colon (:') in your book labels because the colon is used
internally to separate the words long' and `short' from the
book label.  You can choose any other separator, but if it
has a non-letter category code, you'll have to play some
tricks with \catcode.  If you need this but can't get it to
work, or if you have further questions, don't hesitate to