1

Is there a way to pass an arrays like {\sin{x},0,0,1} to a lua function. Numbers work perfectly fine but it seems to fail when using \sin, \cos, \tan, \sum, \int,...

Commands with arguments (e.g. \sin{x}) cause 2 errors

  • Argument of \@gobble has an extra }.
  • Argument of \reserved@b has an extra }.

and the passed array will be empty.

Commands without arguments (e.g. \pm) don't cause an error, but the passed array will also be empty. The same behaviour happens when there are spaces in the argument.

This is my code:

\begin{luacode}
    function buildMatrix(x,y,arr)
        for i=1, #arr do
            tex.sprint(arr[i])
            if math.fmod(i,x)==0 then
                tex.sprint("\\\\")
            else
                tex.sprint("&")
            end
        end
    end
\end{luacode}

\newcommand{\mat}[3]{%
    \ensuremath{%
        \def\args{{#3}}
        \begin{pmatrix}
            \directlua{
                buildMatrix(#2,#1,\args)
            }
        \end{pmatrix}
    }
}

% This is a 2D Identity matrix
\mat{2}{2}{1,0,0,1}

% This fails + 2 errors
\mat{2}{2}{\sin{x},0,0,1}

% This also fails
\mat{2}{2}{1 1,0,0,1}
\mat{2}{2}{\pm,0,0,1}

Any idea how to fix this? Also the 'readarray' package has the same issue.

Here is a test file with surrounding structure: https://gist.github.com/michihupf/1f51e8a09871ae389f04b5a168990655

3
  • 1
    Welcome to TeX.SE!
    – Mensch
    Commented Mar 19, 2022 at 20:08
  • 1
    it's a lot easier to help if you provide a test file not a fragment that can't be used without gussing undefined commands, but probably some combination of \unexpanded and ``\luaescapestring` will do what you need Commented Mar 19, 2022 at 20:12
  • I edited the question to include the testfile
    – michihupf
    Commented Mar 19, 2022 at 20:28

1 Answer 1

1

You can do it without Lua and its quirks.

\documentclass{article}
\usepackage{amsmath}

\ExplSyntaxOn

\NewDocumentCommand{\mat}{O{p}mm}
 {
  % #1 = delimiter, default p
  % #2 = number of columns
  % #3 = entries
  \michihupf_mat:nnn { #1 } { #2 } { #3 }
 }

\seq_new:N \l_michihupf_mat_seq
\int_new:N \l_michihupf_mat_cols_int

\cs_new_protected:Nn \michihupf_mat:nnn
 {
  \seq_set_split:Nnn \l_michihupf_mat_seq { , } { #3 }
  \int_set:Nn \l_michihupf_mat_cols_int { #2 }
  \begin{#1matrix}
  \seq_map_indexed_function:NN \l_michihupf_mat_seq \__michihupf_mat_entry:nn
  \end{#1matrix}
 }

\cs_new_protected:Nn \__michihupf_mat_entry:nn
 {% #1 = index, #2 = entry
  #2 \int_compare:nTF { \int_mod:nn { #1 } { \l_michihupf_mat_cols_int } == 0 } { \\ } { & }
 }

\ExplSyntaxOff
  

\begin{document}

$\mat{2}{1,0,0,1}$

$\mat{2}{\sin x,0,0,1}$

$\mat{2}{1 1,0,0,1}$

$\mat{2}{\pm,0,0,1}$

$\mat{3}{a,b,c,d,e,f}$

$\mat[b]{2}{a,b,c,d,e,f}$

\end{document}

enter image description here

I removed the “rows” argument that's unneeded, but added an optional argument to change the delimiters with the usual amsmath characters. I also removed \ensuremath, which serves no purpose, because matrices will always appear in math.

The code actually parallels what you want to do in Lua. The sequence is the analog of an array and we map the entries using also their index.

Another implementation, where rows are separated by semicolons, which is common in computer algebra systems:

\documentclass{article}
\usepackage{amsmath}

\ExplSyntaxOn

\NewDocumentCommand{\mat}{O{p}m}
 {
  % #1 = delimiter, default p
  % #2 = entries
  \michihupf_mat:nn { #1 } { #2 }
 }

\seq_new:N \l_michihupf_mat_seq

\cs_new_protected:Nn \michihupf_mat:nn
 {
  \seq_set_split:Nnn \l_michihupf_mat_seq { ; } { #2 }
  \begin{#1matrix}
  \seq_map_function:NN \l_michihupf_mat_seq \__michihupf_mat_row:n
  \end{#1matrix}
 }

\cs_new_protected:Nn \__michihupf_mat_row:n
 {
  \clist_use:nn { #1 } { & } \\
 }

\ExplSyntaxOff
  

\begin{document}

$\mat{1,0;0,1}$

$\mat{\sin x,0;0,1}$

$\mat{1 1,0;0,1}$

$\mat{\pm,0;0,1}$

$\mat{a,b,c;d,e,f}$

$\mat[b]{a,b;c,d;e,f}$

\end{document}

The output is the same. The big advantage of these implementations is that they run on every TeX engine (except Knuthian TeX).

6
  • That looks great. I need to read more into this because to be honest this looks like magic. I am going to try this tomorrow, thanks for your help :)
    – michihupf
    Commented Mar 20, 2022 at 3:49
  • When I paste this into a blank tex file it works but when I add this to my class file it fails with the error: Undefined control sequence \michihupf_mat:nnn ...seq_map_indexed_function:NN and a few more. I am using expl3 in my class file already, maybe this could be the problem?
    – michihupf
    Commented Mar 20, 2022 at 14:22
  • @michihupf Did you add \ExplSyntaxOn?
    – egreg
    Commented Mar 20, 2022 at 14:47
  • yes I did, in fact it does compile with the setup of a friend of mine. I guess my setup is just fucked. It also compiles on Overleaf...
    – michihupf
    Commented Mar 20, 2022 at 15:21
  • I just realised the default version i get to download with apt is TexLive 2019 not 2021. It doesn't work with 2019 (verified with overleaf). I am going to see how to install 2021. Thanks for your help this is something I can resolve I guess.
    – michihupf
    Commented Mar 20, 2022 at 15:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .