3

I found some sort of a list online and got it to work as intended The command "addtoaliste" is adding a parameter to the list "aliste". It's defined by newcommands, so I have problems getting it to work within environments such as enumerate, as any changes are only done locally.

I'll try to change my implemented list to be working with global definitions (gdef). But first my "command-code":

\documentclass{scrartcl}
\usepackage{ifthen}

\newcommand{\aliste}[1]{\empty}
\def\zaliste#1\relax{\def\aliste##1{#1}}
\newcommand{\addtoaliste}[1]{%
    \ifthenelse{\equal{\aliste{}}{}}{
    \expandafter\zaliste\aliste{##1}#1\relax}
    {\expandafter\zaliste\aliste{##1},#1\relax}
}

\begin{document}
    Value: \aliste{}\\ %Returns empty list
    \addtoaliste{1}
    Value: \aliste{} %Returns 1
    \begin{enumerate}
        \item First Point. 
        \addtoaliste{2}
    \end{enumerate}
    Value: \aliste{} %shall return 1,2, but still returns 1
\end{document}

I tried some changes and got to the following, but it still didn't work as intended:

\documentclass{scrartcl}
\usepackage{ifthen}

\gdef\aliste#1{}
\gdef\zaliste#1{\relax{\gdef\aliste##1{#1}}}
\gdef\addtoaliste#1{%
    \ifthenelse{\equal{\aliste{}}{}}{
    \expandafter\zaliste\aliste{##1}#1\relax}
    {\expandafter\zaliste\aliste{##1},#1\relax}
}

\begin{document}
Value: \aliste{}\\ %Returns empty list
\addtoaliste{1}
Value: \aliste{}\\ %Returns 1
\begin{enumerate}
    \item First Point. 
    \addtoaliste{2}
\end{enumerate}
Value: \aliste{}
\end{document}
  • Take your first code and replace one \def by a \gdef: \def\zaliste#1\relax{\gdef\aliste##1{#1}}. – user194703 Sep 23 '19 at 22:37
  • Great thanks seems to work right now. Any thoughts or suggestions why it's not working with both or even more gdef? – WuaghhhhXMA Sep 23 '19 at 22:47
  • It has not directly to do with the \gdefs but with the fact that the first code has \newcommand{\aliste}[1]{\empty}, which is not the same as \def\aliste#1{}, and thus the "globalization" to `\gdef\aliste#1{}" does not work. – user194703 Sep 23 '19 at 22:52
3

Using \gdef does not really change the code: \gdef means “globally define”, but it's the code inside the macro that should do a global definition. So

\def\zaliste#1\relax{\gdef\aliste##1{#1}}

would be the solution, provided the macros work to begin with, which they don't.

The problem is in

\def\zaliste#1{\relax{\gdef\aliste##1{#1}}}

where an extra pair of braces ruins everything: it should be

\def\zaliste#1\relax{\gdef\aliste##1{#1}}

so the argument is delimited by \relax. Indeed

\documentclass{scrartcl}
\usepackage{ifthen}

\def\aliste#1{}
\def\zaliste#1\relax{\gdef\aliste##1{#1}}
\def\addtoaliste#1{%
    \ifthenelse{\equal{\aliste{}}{}}{%
    \expandafter\zaliste\aliste{##1}#1\relax}%
    {\expandafter\zaliste\aliste{##1},#1\relax}%
}

\begin{document}

Value: \aliste{} %Returns empty list

\addtoaliste{1}
Value: \aliste{} %Returns 1

\begin{enumerate}
    \item First Point.
    \addtoaliste{2}
\end{enumerate}
Value: \aliste{}

\end{document}

produces

enter image description here

I'm not sure why you define \aliste with an argument, which just complicates things. In the following, I also changed \gdef to \xdef so as to expand the value, in case you want to use something like \addtoalist{\arabic{enumi}}

\documentclass{scrartcl}
\usepackage{ifthen}

\def\aliste{}
\def\zaliste#1\relax{\xdef\aliste{#1}} % \xdef for full expansion
\def\addtoaliste#1{%
  \ifthenelse{\equal{\aliste}{}}{%
    \expandafter\zaliste\aliste#1\relax
  }{\expandafter\zaliste\aliste,#1\relax
  }%
}

\begin{document}

Value: \aliste %Returns empty list

\addtoaliste{1}
Value: \aliste %Returns 1

\begin{enumerate}
    \item First Point.
    \addtoaliste{2}
\end{enumerate}
Value: \aliste

\end{document}

will produce exactly the same.

I propose a different approach that supports as many lists as you want.

\documentclass{scrartcl}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\startlist}{m}
 {
  \clist_clear_new:c { g_wuagh_list_#1_clist }
 }
\NewDocumentCommand{\addtolist}{mm}
 {
  % add the item
  \clist_gput_right:cx { g_wuagh_list_#1_clist } { #2 }
 }
\NewExpandableDocumentCommand{\uselist}{om}
 {
  \IfNoValueTF { #1 }
   {
    \clist_use:cn { g_wuagh_list_#2_clist } { , }
   }
   {
    \clist_item:cn { g_wuagh_list_#2_clist } { #1 }
   }
 }
\ExplSyntaxOff

\startlist{a}

\begin{document}

Value: \uselist{a} %Returns empty list

\addtolist{a}{A}
Value: \uselist{a} %Returns 1

\begin{enumerate}
    \item First Point.\addtolist{a}{\arabic{enumi}}
    \item Second Point.\addtolist{a}{\arabic{enumi}}
\end{enumerate}
Value: \uselist{a}

Item: \uselist[1]{a} % returns A

Item: \uselist[2]{a} % returns 1


\end{document}

enter image description here

As you see, you can also access list items by their index.

  • Great clarifications, will look into your own list-thingy, as it's more flexible. – WuaghhhhXMA Sep 23 '19 at 23:23
  • @WuaghhhhXMA It would be possible to abstract also your code in order to support more lists, but as expl3 already provides the infrastructure, I see no need to. – egreg Sep 23 '19 at 23:28
  • Just one additional question: When adding the enumi-counter from the environment to the list, it's always adding the last counter (no matter when added). Any quick tip? – WuaghhhhXMA Sep 24 '19 at 0:04
  • @WuaghhhhXMA Just change to \xdef instead of \gdef. I changed the expl3 version to show how to do it in the more flexible setup. – egreg Sep 24 '19 at 9:02
0

You can use etoolbox to manage the list for you (addition and processing/printing):

enter image description here

\documentclass{article}

\usepackage{etoolbox}

% https://tex.stackexchange.com/a/89187/5764
% \printlist[<separator>]{<list>}
\newcommand{\printlist}[2][,]{%
  \def\itemdelim{\def\itemdelim{#1}}% Item delimiter delayed by one cycle
  \renewcommand*{\do}[1]{\itemdelim##1}% How each item is processed
  \dolistcsloop{#2}}% Process CSV list
\newcommand{\addtoaliste}{\listcsgadd{aliste}}

\begin{document}

Value: \printlist{aliste} % Returns empty list

\addtoaliste{1}

Value: \printlist{aliste} % Returns 1
\begin{enumerate}
  \item First Point. 
  \addtoaliste{2}
\end{enumerate}
Value: \printlist{aliste} % Returns 1,2

\end{document}

The list printing uses a cunning (La)TeX trick.

  • Thanks, I'll look into this package. – WuaghhhhXMA Sep 23 '19 at 22:51

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.