3

I want a command that will create an unevaluated bit of LaTeX/TeX code (to be evaluated at the end of an environment, but this is not necessary information) that has been created using an evaluated command.

Here is an attempt at a working example created from my work:

\newcommand{\myNotes}{\protect\item apple}
\newcounter{noteCnt}
\newcommand{\TblMark}[1]{
  \stepcounter{noteCnt}
  \alph{noteCnt} %in this example, this is just printing a character at this location
  \makeatletter
  \g@addto@macro\myNotes{ \protect\item \alph{noteCnt} #1} %creating item list
  \makeatother}

%elsewhere in the latex file...
Hello, I am feeling very \TblMark{frustrated} about my lack of \Tex \TblMark{knowledge}.

Here is a list:

\myNotes

The problem is that when myNotes is expanded, the current value of noteCnt is used in the item list. I want the item list to use the noteCnt value at the time when \TblMark was expanded.

My intention was to create something like:

Hello, I am feeling very a about my lack of TeX b.

Here is a list:

  • a frustrated
  • b knowledge

Instead, I get something like:

Hello, I am feeling very a about my lack of TeX b.

Here is a list:

  • b frustrated
  • b knowledge
1

1 Answer 1

7

Some remarks first:

  1. \makeatletter is required before code containing an @ is read for the first time, so I don't really believe you code works as-is (it doesn't in my test ;-)
  2. As the macro \g@addto@macro does not expand its input (as you noted), \protect\item has no use here (and might make trouble elsewhere).
  3. I corrected some minor errors. Feel free to ask if you have further questions.
  4. I replaced your \g@addto@macro (which globally adds unexpanded tokens to the end of a macro) by the construct \xdef\myNotes{\unexpanded\expandafter{\myNotes}...} which does the same, but expands the token list.
  5. Now \item really needs to be protected (by \noexpand).
  6. \unexpanded{#1} makes sure no unwanted expansions take place in the text argument.

Here's the modified MWE:

\documentclass[12pt]{article}

\newcommand{\myNotes}{\protect\item apple}
\newcounter{noteCnt}
\newcommand{\TblMark}[1]
{%
  \stepcounter{noteCnt}%
  \alph{noteCnt}%in this example, this is just printing a character at this location
  \xdef\myNotes{%
    \unexpanded\expandafter{\myNotes}% previous contents of \myNotes, expanded once
    \noexpand\item % \item, unexpanded (one token)
    \alph{noteCnt} % expansion of counter `noteCnt' with space afterwards
    \unexpanded{#1}% argument #1, not expanded (several tokens)
  }% 
}


\begin{document}

%elsewhere in the latex file...
Hello, I am feeling very \TblMark{frustrated} about my lack of \TeX\ \TblMark{knowledge}.

Here is a list:

\begin{itemize}
\myNotes
\end{itemize}

\end{document}

result

3
  • @heikooberdiek Thanks for adding the code comments. Commented Nov 27, 2012 at 13:07
  • Thank you for the excellent response and @HeikoOberdiek for the comments. One question about the \unexpanded\expandafter{\myNotes} line. Does the \expandafter cause \myNotes to be expanded while the \unexpanded cause the { to remain? Commented Nov 27, 2012 at 15:57
  • @danelliottster More or less. \unexpanded{...tokens...} expands to ...tokens... without any expansion. But we want \myNotes to be expanded exactly once, hence the \expandafter. Commented Nov 27, 2012 at 16:49

You must log in to answer this question.

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