I would like to write a command \TransTM that expands, for example, \TransTM{a, x, R | b, y, L} to \shortstack{a;~x,~R \\ b;~y,~L}.
The MWE
\documentclass{article}
\usepackage{lmodern}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand \TransTM { m }
{ \edge_label:cn {edge_item_tm:nnn} {#1} }
\cs_new_protected:Npn \edge_label:cn #1 #2
{
\seq_set_split:Nnn \l_tmpa_seq { | } { #2 }
\seq_set_map:NNn \l_tmpb_seq \l_tmpa_seq { \edge_item:cn {#1} {##1} }
\shortstack{ \seq_use:Nn \l_tmpb_seq { \\ } }
}
\cs_new_protected:Npn \edge_item:cn #1 #2
{
\seq_set_split:Nnn \l_tmpa_seq { , } { #2 }
\seq_set_map:NNn \l_tmpb_seq \l_tmpa_seq { {##1} }
\use:c { #1 } x x x % \seq_use:Nn \l_tmpb_seq { }
}
\cs_new_protected:Npn \edge_item_tm:nnn #1 #2 #3
{
#1;~#2,~#3
}
\ExplSyntaxOff
\begin{document}
\TransTM{a, x, L | b, y, R}
\end{document}
works only partly, since I have managed to split the argument at | on the first level, but not at , on the second level. \seq_use:Nn in \edge_item:cn is commented out and replaced by the hard-coded x x x because it produces an error.
What is wrong in attempting to split the argument on the second level?
Note: There will be different variants in future. This is why I pass the name of the function edge_item_tm:nnn as an argument. Another document-level command \TransFA{a | b | c}, for example, is supposed to expand to \shortstack{a \\ b \\ c}. The difference will be only in the structure of the parts between the | tokens.
Addendum
It seems I oversimplified the above MWE. The following code
\documentclass{article}
\usepackage{lmodern}
\usepackage{xparse}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{relsize}
\ExplSyntaxOn
\NewDocumentCommand \Char { O{\width} m }
{
\makebox[#1]
{
\str_case_x:nnF { \tl_to_str:n {#2} }
{
{ } { $\varepsilon$ }
{ ## } { \texttt{\#} }
{ \c_tilde_str } { \textscale{.87}{$\Box$} }
}
{ \texttt{#2} }
}
}
\NewDocumentCommand \TransTM { m }
{ \__edge_label_tm:n {#1} }
\cs_new_protected:Npn \__edge_label_tm:n #1
{
\seq_set_split:Nnn \l_tmpa_seq { | } { #1 }
\seq_set_map:NNn \l_tmpb_seq \l_tmpa_seq { \SplitItemTM \exp_not:n { {##1} } }
\shortstack{ \seq_use:Nn \l_tmpb_seq { \\ } }
}
\NewDocumentCommand \SplitItemTM { >{\SplitArgument{2}{,}} m }
{ \__edge_item_tm:nnn #1 }
\cs_new_protected:Npn \__edge_item_tm:nnn #1 #2 #3
{
\Char[.63em]{#1};\;\Char[.63em]{#2},\,\Char{#3}
}
\ExplSyntaxOff
\begin{document}
\TransTM{a, x, L} \qquad
\TransTM{a, x, L | b, y, L} \qquad
\TransTM{a, x, L | b, y, L | ~, ~, R}
\end{document}
yields the desired result.
However, it misuses \NewDocumentCommand since \SplitItemTM belongs to the implementation and not to the user interface. What would be the right way to replace \SplitItemTM by an internal function?





\shortstackastackenginemacro? – Nov 14 '17 at 20:43\shortstackis the "built-in" version.\Shortstackand\Longstackare defined instackengine. However, the stacking part works as expected. – Matthias Nov 14 '17 at 20:45