0

I'm trying to label items on a table. In my use, multiple labels may exist, so the initial location of the creation of the label is irrelevant (not trying to hyperlink). I want to use one command that will assign a label. So I thought the easy solution would be to check if the reference exists, if not, increment a counter and assign a new label, otherwise reference it.

I do notice that I get different results alternating compiles. I also notice that when testing the ifundefined part in isolation (i.e. print true or false), it takes two compiles. I believe this is because of the way TeX interacts with its .aux file ?

enter image description here

\documentclass{article}

\newcounter{myrefcnt}% my referene counter
\makeatletter
\newcommand\myref[1]{% my command
  \@ifundefined{r@#1}{%if reference doesnt exist
    \refstepcounter{myrefcnt}\themyrefcnt\label{#1}% create a label for reference
  }{%
    \ref{#1}% else reference it
  }%
}
\makeatother


\begin{document}

  \textbf{My Attempt:}

\begin{tabular}{lr}
  \hline
    Things & Applicable Things \\\hline
    Aardvark & \myref{fourlegs}, \myref{lookslikerat} \\
    Bat & \myref{lookslikerat} \\
    Cheetah & \myref{fourlegs} \\\hline
\end{tabular}

\myref{fourlegs} indicates speciment has four legs.
\myref{lookslikerat} indicates speciment looks like a rat.

  \textit{When I run the file, the labels are sometimes 1,2,3,4, but other times 5,6,6,5}

  \textbf{I want to produce the following:}

  \begin{tabular}{lr}
  \hline
    Things & Applicable Things \\\hline
    Aardvark & 1, 2 \\
    Bat & 2 \\
    Cheetah & 1 \\\hline
\end{tabular}

1 indicates speciment has four legs.
2 indicates speciment looks like a rat.

\end{document}
1
  • so that you can make forward references \label writes to the aux file which is read at begin document so all the r@.. macros are defined on the second run. you could make a global \my@'#1 macro that you don't record the the aux, but then test that in your macro in the same way. (You probably wouldn't need \label at all in that case. Commented Nov 20, 2020 at 14:06

1 Answer 1

1

enter image description here

so that you can make forward references \label writes to the aux file which is read at begin document so all the r@.. macros are defined on the second run. you could make a global \my@'#1 macro that you don't record the the aux, but then test that in your macro in the same way. (You probably wouldn't need \label at all in that case.

\documentclass{article}

\newcounter{myrefcnt}% my referene counter
\makeatletter
\newcommand\myref[1]{% my command
  \@ifundefined{myr@#1}{%if reference doesnt exist
    \stepcounter{myrefcnt}\themyrefcnt\expandafter\xdef\csname myr@#1\endcsname{\themyrefcnt}% create a label for reference
  }{%
    \csname myr@#1\endcsname% else reference it
  }%
}
\makeatother


\begin{document}

  \textbf{My Attempt:}

\begin{tabular}{lr}
  \hline
    Things & Applicable Things \\\hline
    Aardvark & \myref{fourlegs}, \myref{lookslikerat} \\
    Bat & \myref{lookslikerat} \\
    Cheetah & \myref{fourlegs} \\\hline
\end{tabular}

\myref{fourlegs} indicates speciment has four legs.
\myref{lookslikerat} indicates speciment looks like a rat.

  \textit{When I run the file, the labels are sometimes 1,2,3,4, but other times 5,6,6,5}

  \textbf{I want to produce the following:}

  \begin{tabular}{lr}
  \hline
    Things & Applicable Things \\\hline
    Aardvark & 1, 2 \\
    Bat & 2 \\
    Cheetah & 1 \\\hline
\end{tabular}

1 indicates speciment has four legs.
2 indicates speciment looks like a rat.

\end{document}

You may still have problems with environments that evaluate things more than once (amsmath alignments and tabularx for example) as you need to guard the test to so that the trial runs do not make every use seem to be not the first.

8
  • Interesting. I noticed that it is not printing references other than the first (I put a dummy text before and it is printing), so there I believe there is an error in \csname my@r#1\endcsname. Based on your comment about some environment evaluating things more than once, then would it perhaps be wiser to use the global definiton method (not requiring label at all) you mentioned? Commented Nov 20, 2020 at 14:18
  • @likethevegetable that's what I did here (\xdef is global and I didn't use \label) Commented Nov 20, 2020 at 14:36
  • @likethevegetable but your are right I have myr@ in one place and my@r in the other can be anything but needs to be consistent, I'll fix sorry Commented Nov 20, 2020 at 14:38
  • That's great, thank you very much! I'm still learning here. If I wanted to re-use this frame work, I suppose I could set the counter to 0, but would have to ensure that I use new reference names. If I wanted to allow the resuse of reference names, I could make another counter and somehow tie it's value to the myr ? Commented Nov 20, 2020 at 14:52
  • yes myr@ is just an arbitrary prefix so \myref{zzz} gets stored in \myr@zzz so if you had a different counter and a \myrefB command just use a different prefix myrB@ if you want to be consistent but zzzzz would work as well. Commented Nov 20, 2020 at 14:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .