3

The \additem command appends an item to a comma-separated list, and \mylist typesets that list.

Works:

\documentclass {article}
\newcommand\mylist {\relax}

\newcommand\additem [1]
{\edef\mylist
 {\mylist
  \if\mylist\relax\else
   ,
  \fi
  #1}}

\begin {document}
\additem {a}
\additem {b}
\additem {c}
\mylist
\end {document}

Now, I want to make each item bold, but not the comma. However, if I replace #1 with, say, \textbf{#1}, I get this error:

! Undefined control sequence.
\GenericError  ...                                
                                                    #4  \errhelp \@err@     ...
l.15 \additem {a}

What is wrong with my code? How can I make each item bold?

Doesn't work:

\documentclass{article}

\newcommand\mylist{\relax}

\newcommand\additem [1]
{\edef\mylist
 {\mylist
  \if\mylist\relax\else
   ,
  \fi
  \textbf{#1}}}

\begin {document}

\additem {a}
\additem {b}
\additem {c}

\mylist

\end {document}
3

You have to use \protected@edef (and fix the test for emptyness)

\documentclass{article}

\newcommand\mylist{}

\makeatletter
\newcommand\additem [1]
{\protected@edef\mylist
 {\mylist
  \if\relax\detokenize\expandafter{\mylist}\relax\else
   ,
  \fi
  \textbf{#1}}}
\makeatother

\begin {document}

\additem {a}
\additem {b}
\additem {c}

\mylist

\end {document}

Commands like \textbf don't survive \edef, because they must perform assignments. You could use \noexpand\textbf, but adding more complex items to your list would lead to the same problem (try \additem{\'a}).

Using \protected@edef neutralizes the problems with such commands. Moreover, the test \if\mylist\relax is wrong to begin with: in your original version (without \textbf), doing \additem{aa}\additem{b} would give funny results. Here I use a test for emptyness derived from How to check if a macro value is empty or will not create text with plain TeX conditionals? (with the change that we need to look at the first level expansion of \mylist).

Another version with xparse that allows for more than one list and is free from this problem because it doesn't use \edef.

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\additem}{O{default}m}
 {
  \clist_if_exist:cF { l_eduardo_list_#1_clist }
   {
    \clist_new:c { l_eduardo_list_#1_clist }
   }
  \clist_put_right:cn { l_eduardo_list_#1_clist } { \textbf { #2 } }
 }
\NewDocumentCommand{\printlist}{O{default}}
 {
  \clist_use:cn { l_eduardo_list_#1_clist } { ,~ }
 }
\ExplSyntaxOff

\begin{document}

\additem{a}
\additem{b}
\additem{c}

\printlist

\additem[new]{A}
\additem[new]{B}
\additem[new]{C}

\printlist[new]

\end{document}

enter image description here

0

Your problem is that the adding of new item is done via \edef but the macro \textbf is not simply expandable in \edef. It is much better to do adding new items to a list without \edef. Then all curious macros can be as parameter of \additem, i.e. an added item. You can correct your definition in such way:

\def\mylist{}
\def\additem#1{\ifx\mylist\empty \def\mylist{#1}\else
   \expandafter\def\expandafter\mylist\expandafter{\mylist, #1}\fi
}

Of course, if you need to have items in bold then you can replace #1 to {\bf#1} at two places in the macro body (or, if you really use LaTeX then you can use LaTeX specific \textbf{#1}).

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.