我正在使用spalign
用于排版矩阵和方程组的包。
基本上,它只是允许您在输入矩阵和基于数组的类似内容时使用空格(或逗号)和分号而不是&
and 。\\
我想垂直对齐一些矩阵或方程组,就好像它们的基线是第一行(或方程)的基线而不是垂直居中,就像在环境中array
使用该[t]
选项一样。
MWE 是:
\documentclass[12pt]{report}
\usepackage{spalign}
\usepackage{amsmath}
\begin{document}
Normal matrix vertically aligned so that it is vertically centered:
\[
A=\spalignmat{1 2 3;4 5 6;7 8 9}
\]
The same matrix using amsmath environments:
\[
A=\begin{pmatrix}
1&2&3\\
4&5&6\\
7&8&9
\end{pmatrix}
\]
I would like it to vertically align with baseline at the baseline of the first row, like you can do with an array:
\[
A=\begin{array}[t]{ccc}
1&2&3\\
4&5&6\\
7&8&9
\end{array}
\]
A system using spalign:
$\spalignsys{2x + 3y = 1;x - y = 10}$
\end{document}
我希望能够像数组对齐一样对齐矩阵(和系统)。该spalign
软件包有工具可以创建您自己的快捷命令(所以我知道如何创建使用spalign
快捷方式的顶部对齐数组环境),但我不知道如何让它自动处理分隔符和列对齐。同样,我可以使用数组环境来排版系统,但最好能像在 中一样自动处理变量的数量等spalign
。
如果无法在中完成spalign
,那么使用环境的解决方案pmatrix
将是次佳选择(但是,正如您在示例中看到的那样,数组和分隔符之间的间距略有不同,所以对我来说并不理想,因为它看起来与我的其他矩阵不同)。
谢谢你的帮助!
答案1
这不受支持spalign
。
这是一个不同的实现。
\documentclass[12pt]{report}
\usepackage{xparse}
\usepackage{amsmath}
\usepackage{delarray}
\ExplSyntaxOn
\NewDocumentCommand{\extraalign}{O{}m}
{
\group_begin:
\keys_set:nn { extraalign } { #1 }
\extraalign_make:n { #2 }
\group_end:
}
\NewDocumentCommand{\extraalignset}{m}
{
\keys_set:nn { extraalign } { #1 }
}
\tl_new:N \l__extraalign_cols_tl
\tl_new:N \l__extraalign_row_tl
\seq_new:N \l__extraalign_rows_in_seq
\seq_new:N \l__extraalign_rows_out_seq
\seq_new:N \l__extraalign_row_seq
\int_new:N \l__extraalign_cols_int
\keys_define:nn { extraalign }
{
h .code:n = \tl_set:Nn \l__extraalign_cols_tl { *{\l__extraalign_cols_int}{#1} },
h .initial:n = c,
v .tl_set:N = \l__extraalign_vertical_tl,
v .initial:n = c,
p .code:n = \tl_set:Nn \l__extraalign_cols_tl { #1 },
l .tl_set:N = \l__extraalign_left_tl,
l .initial:n = (,
r .tl_set:N = \l__extraalign_right_tl,
r .initial:n = ),
}
\cs_new_protected:Nn \extraalign_make:n
{
\__extraalign_body:n { #1 }
\__extraalign_preamble:VVVV
\l__extraalign_vertical_tl % vertical alignment
\l__extraalign_left_tl % left delimiter
\l__extraalign_right_tl % right delimiter
\l__extraalign_cols_tl % column spec
% deliver the matrix
\seq_use:Nn \l__extraalign_rows_out_seq { \\ }
\end{array}
}
\cs_new_protected:Nn \__extraalign_preamble:nnnn
{
\begin{array}[#1]#2{@{}#4@{}}#3
}
\cs_generate_variant:Nn \__extraalign_preamble:nnnn { VVVV }
\cs_new_protected:Nn \__extraalign_body:n
{
\seq_set_split:Nnn \l__extraalign_rows_in_seq { ; } { #1 }
\seq_clear:N \l__extraalign_rows_out_seq
\seq_map_variable:NNn \l__extraalign_rows_in_seq \l__extraalign_row_tl
{
\__extraalign_makerow:V \l__extraalign_row_tl
}
}
\cs_new_protected:Nn \__extraalign_makerow:n
{
\seq_set_split:Nnn \__extraalign_row_seq { ~ } { #1 }
\int_compare:nT { \l__extraalign_cols_int = 0 }
{
\int_set:Nn \l__extraalign_cols_int { \seq_count:N \__extraalign_row_seq }
}
\seq_put_right:Nx \l__extraalign_rows_out_seq
{ \seq_use:Nn \__extraalign_row_seq { & } }
}
\cs_generate_variant:Nn \__extraalign_makerow:n { V }
\ExplSyntaxOff
\begin{document}
\begin{gather*}
A=\begin{pmatrix}1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9\end{pmatrix}
\quad
A=\extraalign{1 2 3;4 5 6;7 8 9}
\\
A=\extraalign[v=t]{1 2 3;4 5 6;7 8 9}
\quad
A=\extraalign[p=rcl,v=t]{-1 2 3;4 5 66;700 8 9000}
\\
A=\extraalign[l=\{,r=.,h=l]{aaaa ; bbb ; c}
\end{gather*}
\end{document}
可选参数\extraalign
包含选项的键值列表
h
对于列的一般格式(默认c
),列数根据需要p
对于特殊前导,指定所有列v
对于垂直对齐,t
或c
(b
默认c
)l
表示左分隔符(默认(
);.
不使用分隔符r
表示右分隔符(默认)
);.
表示无分隔符
如果您想要更改默认值,请使用\extraalignset
您想要的值。例如,如果您这样做
\extraalignset{ l = [, r = ] }
所有矩阵(在当前范围内或在序言中完成的全局范围内)都将使用括号,除非本地被撤销。
为了完整性,下面介绍如何执行增广矩阵。
\extraalignset{l=[,r=]}
\begin{gather*}
A=\extraalign[p=cccc|cc]{1 2 3 4 5 6;4 5 6 7 8 9;7 8 9 1 2 3}
\quad
A=\extraalign[p=cccc|cc,v=t]{1 2 3 4 5 6;4 5 6 7 8 9;7 8 9 1 2 3}
\\
A=\extraalign[p=ccc|ccc]{1 2 3 4 5 6;4 5 6 7 8 9;7 8 9 1 2 3}
\quad
A=\extraalign[p=ccc|ccc,v=t]{1 2 3 4 5 6;4 5 6 7 8 9;7 8 9 1 2 3}
\end{gather*}
答案2
\documentclass{article}
\usepackage{tabstackengine,scalerel}
\TABstackMath
\setstacktabbedgap{1ex}
\strutlongstacks{T}
\begin{document}
\[
A = \tabbedLongunderstack{1&2&3\\4&5&6\\7&8&9}
\]
\[
A = \scaleleftright[1.5ex]{\Biggl(}
{\tabbedLongunderstack{1&2&3\\4&5&6\\7&8&9}}{\Biggr)}
\]
\[
\savestack\mysystem{\setstacktabbedgap{0pt}%
\tabbedCenterstack[r]{2x +& 3y =& 1\\x -& y =& 10}}
\renewcommand\stackalignment{r}
\stackunder[10pt]
{$A = \tabbedLongunderstack{1&2&3\\4&5&6\\7&8&9}$}
{A system using tabstackengine: $\biggl\{\mysystem$}
\]
\end{document}
答案3
我很感谢其他的回答。这个问题困扰了我一段时间,而且由于这个问题很久都没有得到解答(我认为它太具体了,除了我之外显然没有人需要这样做),我找到了一种通过修补命令来实现的方法spalign
。为了防止其他人想知道如何做到这一点,我会在这里发布我的答案。
我不得不深入研究spalign
一下现有代码。矩阵array
按预期使用 s 构建,所以我最初想到只需用 替换\begin{align}
。\begin{align}[t]
然而,这会产生一个问题,即分隔符也位于顶行的中心:
为了解决这个问题,我delarray
按照这个建议使用了回答(正如egreg回答这个问题时再次建议的那样)。
但是,这需要在现有的 代码中进行更为复杂的查找和替换spalign
,因为该包中的宏将分隔符放在环境之外array
(不使用 时通常如此)delarray
。无论如何,我有点痴迷于解决这个问题,并通过xpatch
反复试验解决了它。我认为这有点混乱(部分原因是*
中 s 的处理方式spalign
),但以下代码会创建几个spalign
环境的副本,与它们的顶行对齐,所有可选参数和带星号的版本均完好无损:
\documentclass[12pt]{report}
\usepackage{amsmath}
\usepackage[delims={[}{]},sysdelims={.}{.}]{spalign} %set to square brackets on matrices and no delimiters on systems
\usepackage{letltxmacro}
\usepackage{delarray}
\usepackage{xpatch}
\makeatletter
\let\tmat=\spalignmat
\let\tmatx=\spalignmat@x
\LetLtxMacro\tmatstar\spalignmat@star
\xpatchcmd{\tmat}{\spalignmat@x}{\tmatx}{}{}
\xpatchcmd{\tmatx}{\spalignmat@star}{\tmatstar}{}{}
\xpatchcmd{\tmatstar}{\spalign@maybedelim}{\spalignenv}{}{}
\xpatchcmd{\tmatstar}{\begin{array}{\spalign@repeated}}%
{\begin{array}[t]\ifspalign@star\else\spalign@leftdelim\fi%
{@{\spalignmatdelimskip}\spalign@repeated @{\spalignmatdelimskip}}%
\ifspalign@star\else\spalign@rightdelim\fi}{}{}
\xpatchcmd{\tmatstar}{{\hskip-\arraycolsep\spalignmatdelimskip}}{}{}{}
\providecommand{\dtmat}[2][r]{{\detm \tmat[#1]{#2}}}
\let\tamatn=\spalignaugmatn
\let\tamatnx=\spalignaugmatn@x
\LetLtxMacro\tamatnstar\spalignaugmatn@star
\xpatchcmd{\tamatn}{\spalignaugmatn@x}{\tamatnx}{}{}
\xpatchcmd{\tamatnx}{\spalignaugmatn@star}{\tamatnstar}{}{}
\xpatchcmd{\tamatnstar}{\spalign@maybedelim}{\spalignenv}{}{}
\xpatchcmd{\tamatnstar}{\begin{array}{\spalign@repeated@one|\spalign@repeated@two}}%
{\begin{array}[t]\ifspalign@star\else\spalign@leftdelim\fi%
{@{\spalignmatdelimskip}\spalign@repeated@one|\spalign@repeated@two @{\spalignmatdelimskip}}\ifspalign@star\else\spalign@rightdelim\fi}{}{}
\xpatchcmd{\tamatnstar}{{\hskip-\arraycolsep\spalignmatdelimskip}}{}{}{}
\providecommand{\tamat}[1][r]{%
\tamatn[#1]{1}%
}%
\let\tamath=\spalignaugmathalf
\let\tamathx=\spalignaugmathalf@x
\LetLtxMacro\tamathstar\spalignaugmathalf@star
\xpatchcmd{\tamath}{\spalignaugmathalf@x}{\tamathx}{}{}
\xpatchcmd{\tamathx}{\spalignaugmathalf@star}{\tamathstar}{}{}
\xpatchcmd{\tamathstar}{\spalign@maybedelim}{\spalignenv}{}{}
\xpatchcmd{\tamathstar}{\begin{array}{\spalign@repeated@one|\spalign@repeated@two}}%
{\begin{array}[t]\ifspalign@star\else\spalign@leftdelim\fi%
{@{\spalignmatdelimskip}\spalign@repeated@one|\spalign@repeated@two @{\spalignmatdelimskip}}\ifspalign@star\else\spalign@rightdelim\fi}{}{}
\xpatchcmd{\tamathstar}{{\hskip-\arraycolsep\spalignmatdelimskip}}{}{}{}
\let\tsys=\spalignsys
\let\tsysx=\spalignsys@x
\let\tsysstar=\spalignsys@star
\xpatchcmd{\tsys}{\spalignsys@x}{\tsysx}{}{}
\xpatchcmd{\tsysx}{\spalignsys@star}{\tsysstar}{}{}
\xpatchcmd{\tsysstar}{\vcenter}{\vtop}{}{}
\makeatother
\begin{document}
\[
A=\spalignmat{1 2 3;4 5 6;7 8 9}. \quad A=\tmat{1 2 3;4 5 6;7 8 9}.
\]
\[
A=\spalignaugmat{1 2 3;4 5 6;7 8 9}. \quad A=\tamat{1 2 3;4 5 6;7 8 9}.
\]
\[
A=\spalignaugmatn{2}{1 2 3 4 5 6;4 5 6 7 8 9;7 8 9 1 2 3}. \quad A=\tamatn{2}{1 2 3 4 5 6;4 5 6 7 8 9;7 8 9 1 2 3}.
\]
\[
A=\spalignaugmathalf{1 2 3 4 5 6;4 5 6 7 8 9;7 8 9 1 2 3}. \quad A=\tamath{1 2 3 4 5 6;4 5 6 7 8 9;7 8 9 1 2 3}.
\]
System of equations:
$\spalignsys{2x + 3y = 1;x - y = 10}$.\quad
Top aligned:
$\tsys{2x + 3y = 1;x - y = 10}$.
\end{document}
这些就是我所需要的,所以我只修补了它们。其他的也可以类似地做。
ed*
版本省略了分隔符,矩阵采用可选参数来指定列对齐。这两个功能仍可像原始版本一样工作spalign
。
也许重新定义我想要的宏比使用 更简单\xpatchcmd
,但我发现这样做很有启发性。我xpatch
以前从未使用过,在第一次尝试中学到了很多东西。
我无法让方程组的分隔符顶部对齐,因为spalign
使用的halign
是该系统而不是array
环境。对我来说,这不是问题,因为我所教的书无论如何都不在系统上使用分隔符,而且我想使用一致的符号。
答案4
{bNiceMatrix}
的环境为受启发的语法nicematrix
提供了一个键,并为顶行对齐提供了一个键,如。light-syntax
spalign
t
{array}
因此,可以直接编写一个命令来\MyMatrix
执行您希望的操作。
\documentclass[12pt]{article}
\usepackage{nicematrix}
\NewDocumentCommand { \MyMatrix } { m }
{
\begin{bNiceMatrix}[t,light-syntax]
#1
\end{bNiceMatrix}
}
\begin{document}
\[ A=\MyMatrix{1 2 3;4 5 6;7 8 9} \]
\end{document}
您需要多次编译(因为nicematrix
在后台使用 PGF/Tikz 节点)。