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. – David Carlisle Nov 20 '20 at 14:06
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? – likethevegetable Nov 20 '20 at 14:18
  • @likethevegetable that's what I did here (\xdef is global and I didn't use \label) – David Carlisle Nov 20 '20 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 – David Carlisle Nov 20 '20 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 ? – likethevegetable Nov 20 '20 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. – David Carlisle Nov 20 '20 at 14:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.