1

I want to make a macro that will take \testfunc{1,2,3}{4,5,6} and generate

\begin{bmatrix}
        1 & 2 & 3\\
        4 & 5 & 6
    \end{bmatrix}

Here's the code:

\def\testfunc#1{
    \ExplSyntaxOn
    \NewDocumentCommand \countItems { m } {
        \clist_count:N #1
    }
\ExplSyntaxOff
    \begin{bmatrix}
        \foreach #1 \do {
            \def\length{\countItems{##1}}
            \foreach \col [count=\i] in {##1} {
                \ifx\i\length
                \col
                \else
                \col &
                \fi
                \ifx&##1&  \else \\ \fi
            }
        }
    \end{bmatrix}
}

However, I keep getting Paragraph ended before \pgffor@@vars was complete., though if I add a new line before the \end{document} a lot more errors pop up.

  • \ifx\i\length is always false as \i never has the same definition as \length – David Carlisle Aug 25 '22 at 20:06
  • please always provide code examples in a form that can be run you don't say how you define \foreach but if that is from pgf each iteration is in a group so you can not insert & within the loop – David Carlisle Aug 25 '22 at 20:08

1 Answers1

2

It cannot work, because each \foreach cycle is processed in a group.

And you can't use #1 as the variable in \foreach.

It's much simpler: with \clist_use:nn you can insert a list of tokens (here &) between items.

\documentclass{article}
\usepackage{amsmath}

\ExplSyntaxOn

\NewDocumentCommand{\testfunc}{mm} { \begin{bmatrix} \clist_use:nn { #1 } { & } \ \clist_use:nn { #2 } { & } \end{bmatrix} }

\ExplSyntaxOff

\begin{document}

[ \testfunc{1,2,3}{4,5,6} ]

\end{document}

enter image description here

More generally

\documentclass{article}
\usepackage{amsmath}

\ExplSyntaxOn

\NewDocumentCommand{\testfunc}{m} { \begin{bmatrix} \tl_map_function:nN { #1 } \drownedsuccess_row:n \end{bmatrix} }

\cs_new:Nn \drownedsuccess_row:n { \clist_use:nn { #1 } { & } \ }

\ExplSyntaxOff

\begin{document}

[ \testfunc{{1,2,3}{4,5,6}{7,8,9}} ]

\end{document}

enter image description here

With a different syntax, you can use as many rows as you want.

\documentclass{article}
\usepackage{amsmath}

\ExplSyntaxOn

\NewDocumentCommand{\testfunc}{m} { \begin{bmatrix} \seq_set_split:Nnn \l_tmpa_seq { ; } { #1 } \seq_map_function:NN \l_tmpa_seq \drownedsuccess_row:n \end{bmatrix} }

\cs_new:Nn \drownedsuccess_row:n { \clist_use:nn { #1 } { & } \ }

\ExplSyntaxOff

\begin{document}

[ \testfunc{1,2,3;4,5,6;7,8,9} ]

\end{document}

egreg
  • 1,121,712
  • But I got my \foreach solution from https://tex.stackexchange.com/a/597961/278882, which says it should work. – DrownedSuccess Aug 25 '22 at 21:15
  • @DrownedSuccess No, that's for OpTeX, which is definitely not LaTeX; most of wipet's answers are not usable with LaTeX. – egreg Aug 25 '22 at 21:16
  • Ah, I was wondering why it wasn't working. Is there no way for you to use arguments, instead of arguments within an argument (I don't need any more than 10 rows at any time, so a loop that goes up to 10 will be good enough). It's not a dealbreaker though, but it would be a littler simpler to write out (I have to deal with a lot of matrices). – DrownedSuccess Aug 25 '22 at 21:25
  • @DrownedSuccess “variable number of arguments” is a no-no. You can use a single argument in the form \testfunc{1,2,3;4,5,6} with an easy modification of the code. I added it. – egreg Aug 25 '22 at 21:37
  • Ah, that's what I feared. Thanks anyway! – DrownedSuccess Aug 25 '22 at 21:40