有没有办法像 lua 函数那样传递数组{\sin{x},0,0,1}
。数字工作得很好,但使用时似乎失败了\sin, \cos, \tan, \sum, \int,...
带参数的命令(例如\sin{x}
)导致 2 个错误
Argument of \@gobble has an extra }.
Argument of \reserved@b has an extra }.
并且传递的数组将为空。
没有参数的命令(例如\pm
)不会导致错误,但传递的数组也将为空。当参数中有空格时也会发生相同的行为。
这是我的代码:
\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}
知道如何修复此问题吗?'readarray' 包也存在同样的问题。
这是一个具有周围结构的测试文件: https://gist.github.com/michihupf/1f51e8a09871ae389f04b5a168990655
答案1
即使没有 Lua 及其特性你也可以做到这一点。
\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}
我删除了不需要的“rows”参数,但添加了一个可选参数,用于将分隔符更改为常用amsmath
字符。我还删除了\ensuremath
,因为它毫无用处,因为矩阵总是会出现在数学中。
该代码实际上与您想要在 Lua 中执行的操作类似。序列类似于数组,我们还使用它们的索引来映射条目。
另一种实现方式是,行之间用分号分隔,这在计算机代数系统中很常见:
\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}
输出是相同的。这些实现的一大优势是它们可以在每个 TeX 引擎上运行(Knuthian TeX 除外)。