# Problem with \SplitList in combination with \shortstack

I would like to achieve that a call to the user-defined command \FooTwo{a|b|c} expands to \shortstack{\texttt{a}\\\texttt{b}\\\texttt{c}}. Here is my MWE:

\documentclass{article}
\usepackage{xparse}

\makeatletter

\newcommand{\Bar}[1]{\ItemDelim\texttt{#1}}

\NewDocumentCommand{\FooOne}{>{\SplitList{|}}m}{%
\def\ItemDelim{\def\ItemDelim{,}}
(\ProcessList{#1}{\Bar})}

\NewDocumentCommand{\FooTwo}{>{\SplitList{|}}m}{%
\def\ItemDelim{\def\ItemDelim{\@stackcr}}
\shortstack{\ProcessList{#1}{\Bar}}}

\makeatother

\begin{document}

xxx

xxx \FooOne{a|b|c} xxx

xxx

xxx \FooTwo{a|b|c} xxx

xxx

\end{document}


The technique I employ seems to work well with \FooOne{a|b|c}, but not with \FooTwo{a|b|c}. The image below shows that the characters b and c are not placed in separate lines.

What is the reason for this?

Addendum: There may be a much better way to achieve the goal I stated in the first paragraph of this question. I am open to any suggestion with or without using the xparse package.

• You give no indication of the intended meaning but \def\ItemDelim{\def\ItemDelim{\@stackcr}} the first definition will happen inside the group of the first cell of the table so will be lost as soon as \stacckcr is executed. – David Carlisle Nov 11 '17 at 13:50
• @DavidCarlisle The nested \def is intended to defer the definition of the new delimiter until the first item of the list has occured. Without using this technique, \FooOne for example would produce (,a,b,c). – Matthias Nov 11 '17 at 14:03

The \def\ItemDelim{\def\ItemDelim{...}} trick doesn't work, because \shortstack is implemented with \halign and each cell forms a group.

Better using more powerful expl3 functions. With \seq_use:Nn, the \\ is inserted only between items.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\seq_new:N \l_matthias_foo_seq

\NewDocumentCommand{\Foo}{m}
{
\group_begin:
\ttfamily
\seq_set_split:Nnn \l_matthias_foo_seq { | } { #1 }
\shortstack
{
\seq_use:Nn \l_matthias_foo_seq { \\ }
}
\group_end:
}

\ExplSyntaxOff

\begin{document}

xxx \Foo{a|b|c} xxx

\end{document}


If this is just a toy problem and you want to process somehow the items, you can use a two-stage approach: first set a sequence with the “naked” items, then set another to one where the items are “dressed up”.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\Foo}{m}
{
\matthias_foo:n { #1 }
}

\seq_new:N \l_matthias_foo_in_seq
\seq_new:N \l_matthias_foo_out_seq

\cs_new_protected:Nn \matthias_foo:n
{
\seq_set_split:Nnn \l_matthias_foo_in_seq { | } { #1 }
\seq_set_map:NNn \l_matthias_foo_out_seq \l_matthias_foo_in_seq
{
\exp_not:n { \texttt { ##1 } }
}
\shortstack
{
\seq_use:Nn \l_matthias_foo_out_seq { \\ }
}
}

\ExplSyntaxOff

\begin{document}

xxx \Foo{a|b|c} xxx

\end{document}

• Your guess is correct. In the MWE, I stripped everything down to the shortstack{} problem that occured due to the groups. In real life, I apply some more processing to the items than just adding \texttt{} to them. Your second proposal looks quite flexible to me. It seems I have to get familiar with latex3 syntax. – Matthias Nov 11 '17 at 14:26

It works correctly with this definition:

\NewDocumentCommand{\FooTwo}{>{\SplitList{|}}m}{%
\def\ItemDelim{\gdef\ItemDelim{\\}}
\shortstack{\ProcessList{#1}{\Bar}}
}

• Does this not expand to \shortstack{\\\texttt{a}\\\texttt{b}\\\texttt{c}}, i.e., does this not produce an empty line on top of the stack? This is why I have tried to employ the "deferred \def". – Matthias Nov 11 '17 at 13:59
• I didn't see an empty line when I compiled it, do you see one? Maybe one of the packages you loaded changes the behavior. – Hood Chatham Nov 11 '17 at 14:06
• Okay I edited it. Now it doesn't include the first \\ . – Hood Chatham Nov 11 '17 at 14:08
• Without the "deferred definiton" the top of the stack is slightly shifted downwards. Your version using \gdef works correctly. Thank you very much for your help. – Matthias Nov 11 '17 at 14:11