7

I've just wanted to add some elements to an existing command/variable without success. There are many examples for different ways on how to achieve that goal, but none of them seem to work for me.

In the following minimal working example, I've tried to copy the solution from there https://tex.stackexchange.com/a/101694/109350

\documentclass{article}
\usepackage[utf8]{inputenc}

\title{MWS}
\author{r2p2}
\date{July 2016}

\newcommand{\features}[0]{}
\newcommand{\feature}[1] {
        \let\oldfeatures\features
        \renewcommand{\features}[0]{\oldfeatures, #1}
    }

\feature{one}
\feature{two}
\feature{three}

\begin{document}

\maketitle

\section{Introduction}

\features

\end{document}

But I get

TeX capacity exceeded, sorry [input stack size=5000].

\oldfeatures ->\oldfeatures 
                            , two

as error message, which should not happen, seince oldfeatures is just an old copy of features does not contain features itself. What do I miss?

Thanks in advance.

r2p2
  • 173
  • 1
    Welcome to TeX SX! What you want to obtain is not clear to me. Should it be \feature{one] -> one, \feature{two} -> one, two and \feature{three} -> one, two, three? – Bernard Jul 03 '16 at 13:33
  • Thanks. My idea is to list a bunch of features and bugfixes and let them be automatically grouped together. In the final version, this comma separated list will become itemized and I don't want to write \begin{itemize} \item myspecialfeature ... \end{itemize} everytime. Instead, I want to automate the list creation. Which makes it overall easier to read if you just see a list of \feature {this}. (Hope that makes sense.) – r2p2 Jul 03 '16 at 14:48
  • @r2p2: If you are after simpler list display, take a look on my answer here: http://tex.stackexchange.com/questions/317680/new-command-for-automatic-enumerate-generation/317682#317682 –  Jul 03 '16 at 16:01
  • So many answers.. thats amazingly overwhelming. – r2p2 Jul 03 '16 at 21:34

2 Answers2

7
\newcommand*\features{}
\newcommand*\feature[1]
  {\ifx\features\empty
     \def\features{#1}%
   \else
     \expandafter\def\expandafter\features\expandafter{\features, #1}%
   \fi}

In any case, LaTeX2e provides \g@addto@macro to deal with a general case.

\makeatletter
\newcommand*\features{}
\newcommand*\feature[1]
  {\ifx\features\empty
     \def\features{#1}%
   \else
     \g@addto@macro\features{, #1}%
   \fi}
\makeatother
Manuel
  • 27,118
  • Oh, now I see. Besides the renewcommand, I've also tried the \g@addto@macro but wrong: \g@addto@macro\features{\features, #1}. – r2p2 Jul 03 '16 at 15:01
  • For now, I ended up with this version. Don't know if it is the best one but I can understand it and that is most important for me for now. I also got the \ifx syntax for free, which I needed to solve another problem. So thank you for that. – r2p2 Jul 03 '16 at 21:44
4

You can't define a macro in terms of itself. There are several ways to do what you want, simple or complicated.

Here's the possibly simplest

\makeatletter
\let\features\@gobble
\makeatother
\newcommand{\feature}[1]{%
  \expandafter\def\expandafter\features\expandafter{\features,#1}%
}

After

\feature{one}
\feature{two}
\feature{three}

the expansion of \features will be

> \features=macro:
->one,two,three.

(you see there's no comma at the beginning).

However, this would behave badly if you try to use \features when nothing has been added yet. With etoolbox you can do better:

\usepackage{etoolbox}

\newcommand{\features}{}
\newcommand{\feature}[1]{%
  \ifdefempty{\features}
    {\appto\features{#1}}
    {\appto\features{,#1}}%
}
egreg
  • 1,121,712
  • (+1) Didn't you forget to type a final \features in the definition of \feature with etoolbox? Also, I'd write \features{, #1}}% with a space after the comma. – Bernard Jul 03 '16 at 15:31
  • @Bernard The space is at discretion of the OP, it depends on how the macro should be used. I don't understand where \features should be added: I don't think that printing the value each time \feature is called is wanted. – egreg Jul 03 '16 at 15:35
  • I tried your code, as I found it quite elegant, but it didn't print whatever. Adding \features just before the last closing bracket did print successfully. – Bernard Jul 03 '16 at 15:41
  • @Bernard Actually it is not meant to print anything. The macro \features will be used somewhere. – egreg Jul 03 '16 at 15:42
  • OK! I misunderstood the aim of the command. I thought it was supposed to add an item to a list and print the completed list. Sorry for having disturbed you. I'll delete my comments in a moment. – Bernard Jul 03 '16 at 15:46