2

In the following MWE, I tried to create a command (but I also tried with a macro) that receives #1 argument. In this case, I am trying to create a comma separated list. However, as shown in the figure below, it seems that the argument works as just one element \x of the list when I call it via \printKW, as if the commas weren't actual commas. How do I create a command (or macro) that stores a comma separated list and how can I call it via another command (or macro)?. Thank you!

enter image description here

\documentclass{article}
\usepackage{pgf, tikz}
\setlength{\parskip}{0.5cm}

\newcommand\KeyWords[1]{\def\@KeyWords{#1}}
\newcommand\printKW{\@KeyWords}

\newcommand{\kwmacro}{Letter, Word, Phrase, Paragraph, Page, Book, Library}

\KeyWords{Letter, Word, Phrase, Paragraph, Page, Book, Library}

\begin{document}
\textbf{Comprehensive knowledge storage follows the evolutionary sequence given by}
\foreach \x [count=\n] in \kwmacro {(\n) \x, }
\textbf{while the access to it follows the reverse order.}

\textbf{Keywords:}
\foreach \x [count=\n] in \printKW {\n.~\x. }

\end{document}
1
  • It is not obvious what you want to do with the comma separated argument. If you want only save it, use \def. If you want to process all comma separated arguments by your own macro, I can show you how to do it. Or you want to cooperate comma separated lists with pgf macros like in your example? Why do you want to insert \printKW in the context of \foreach? You can use directly \kwmacro as shown above in your example. – wipet Jul 8 '20 at 8:13
4

Macros in PGF foreach loops are only expanded once but \printKW needs two steps to expand to the list. The can be fixed for all instances of the foreach loop by patching the internal macros. Here I introduce a check whether the macro is expandable and if it is perform a full expansion (expl3 f-type) on it.

You also want \makeatletter ... \makeatother around you definition, otherwise you are overriding the definition of \@ which might lead to mysterious errors later.

\documentclass{article}
\usepackage{tikz}

\makeatletter
\def\pgfutil@ifexpandable#1{%
    \expandafter\ifx\noexpand#1#1%
        \expandafter\pgfutil@firstoftwo
    \else
        \expandafter\pgfutil@secondoftwo
    \fi
}

\def\pgffor@macro@list#1{%
    \pgfutil@ifexpandable#1%
        {\expandafter\pgffor@normal@list\expandafter{\romannumeral-`0#1}}%
        {\expandafter\pgffor@normal@list\expandafter{#1}}}
\makeatother

\setlength{\parskip}{0.5cm}

\makeatletter
\newcommand\KeyWords[1]{\def\@KeyWords{#1}}
\newcommand\printKW{\@KeyWords}
\makeatother

\newcommand{\kwmacro}{Letter, Word, Phrase, Paragraph, Page, Book, Library}

\KeyWords{Letter, Word, Phrase, Paragraph, Page, Book, Library}

\begin{document}
\textbf{Comprehensive knowledge storage follows the evolutionary sequence given by}
\foreach \x [count=\n] in \kwmacro {(\n) \x, }
\textbf{while the access to it follows the reverse order.}

\textbf{Keywords:}
\foreach \x [count=\n] in \printKW {\n.~\x. }

\end{document}

Probably it even makes sense to just scrap the expandability check and just use

\def\pgffor@macro@list#1{%
    \expandafter\pgffor@normal@list\expandafter{\romannumeral-`0#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.