请看以下例子:
\documentclass{book}
\usepackage{xparse}
\usepackage{amsmath}
\makeatletter
\NewDocumentCommand{\vv}{ s > { \SplitList { ; } } m }%
{\begin{pmatrix}%
\ProcessList{#2}{\@vv}%
\end{pmatrix}%
\@firstitemtrue}
\newif\if@firstitem
\@firstitemtrue
\NewDocumentCommand{\@vv}{ m }%
{\if@firstitem%
\@firstitemfalse%
\else%
\\%
\fi%
#1}
\makeatother
\begin{document}
The vector is printend wrong:
\begin{equation}
\vv{a;b;c;d;e;f;g}
\end{equation}
It should look like:
\begin{equation}
\begin{pmatrix}
a \\ b \\ c \\ d \\ e \\ f \\ g
\end{pmatrix}
\end{equation}
\end{document}
我尝试定义一个宏来轻松地排版矢量。但正如您在图片上看到的那样,出现了问题。
有什么办法可以解决这个问题吗?
答案1
该\@firstitemfalse
命令是在数组单元格内完成的,该单元格是一个组并且永远不会false
在外面,因此使用\global\@firstitemfalse
,但更好的解决方案是使用expl3
在这个答案末尾带有“\seq”的方法……
\documentclass{book}
\usepackage{xparse}
\usepackage{amsmath}
\makeatletter
\NewDocumentCommand{\vv}{ s > { \SplitList { ; } } m }%
{\begin{pmatrix}%
\ProcessList{#2}{\@vv}%
\end{pmatrix}%
\@firstitemtrue}
\newif\if@firstitem
\@firstitemtrue
\NewDocumentCommand{\@vv}{ m }%
{\if@firstitem%
\global\@firstitemfalse%
\else%
\\%
\fi%
#1}
\makeatother
\begin{document}
The vector is printend wrong:
\begin{equation}
\vv{a;b;c;d;e;f;g}
\end{equation}
It should look like:
\begin{equation}
\begin{pmatrix}
a \\ b \\ c \\ d \\ e \\ f \\ g
\end{pmatrix}
\end{equation}
\end{document}
采用“直接”使用功能的替代解决方案,因此根本expl3
不需要,因为关心这一点。\if@firstitem
\seq_use:Nn ... {\\}
\documentclass{book}
\usepackage{xparse}
\usepackage{amsmath}
\makeatletter
\ExplSyntaxOn
\cs_new:Nn \split_vector_list:n {%
\seq_set_split:Nnn \l_tmpa_seq {;} {#1}
\seq_use:Nn \l_tmpa_seq {\\}
}
\NewDocumentCommand{\vv}{ sm }{%
\begin{pmatrix}%
\split_vector_list:n {#2}
\end{pmatrix}%
}
\ExplSyntaxOff
\begin{document}
The vector is printend wrong:
\begin{equation}
\vv{a;b;c;d;e;f;g}
\end{equation}
It should look like:
\begin{equation}
\begin{pmatrix}
a \\ b \\ c \\ d \\ e \\ f \\ g
\end{pmatrix}
\end{equation}
\end{document}
答案2
\documentclass{book}
\usepackage{xparse}
\usepackage{amsmath}
\makeatletter
\NewDocumentCommand{\vv}{ s > { \SplitList { ; } } m }%
{\begin{pmatrix}%
\ProcessList{#2}{\@vv}%
\end{pmatrix}%
\@firstitemtrue}
\newif\if@firstitem
\@firstitemtrue
\NewDocumentCommand{\@vv}{ m }%
{#1\\}
\makeatother
\begin{document}
The vector is printend wrong:
\begin{equation}
\vv{a;b;c;d;e;f;g}
\end{equation}
\end{document}
每个表格单元格都是一个本地组,因此你的布尔标志设置一旦丢失\\
答案3
不需要条件:pmatrix
当最后一行以 结束时,就非常满意\\
。
\documentclass{book}
\usepackage{xparse}
\usepackage{amsmath}
\NewDocumentCommand{\vv}{ s > { \SplitList { ; } } m }{%
\begin{pmatrix}%
\ProcessList{#2}{\innervv}%
\end{pmatrix}%
}
\NewDocumentCommand{\innervv}{ m }{#1\\}
\begin{document}
\begin{equation}
\vv{a;b;c;d;e;f;g}
=
\begin{pmatrix}
a \\ b \\ c \\ d \\ e \\ f \\ g
\end{pmatrix}
\end{equation}
\end{document}
如果 *-variant 是用于打印行向量的,那么您会遇到一个小问题,因此需要采用不同的策略:首先,在第一个 处拆分参数;
,然后应用于\SplitList
第二部分(如果存在)。但是这需要太多宏。
expl3
因此,最好采用以下方法:
\documentclass{book}
\usepackage{xparse}
\usepackage{amsmath}
\ExplSyntaxOn
\NewDocumentCommand{\vv}{ sm }
{
\IfBooleanTF{#1}
{ \vv_rowcol:nn { #2 } { & } } % row vector
{ \vv_rowcol:nn { #2 } { \\ } } % column vector
}
\cs_new_protected:Nn \vv_rowcol:nn
{
\begin{pmatrix}
% split the input at semicolons
\seq_set_split:Nnn \l_vv_rowcol_seq { ; } { #1 }
% deliver the items separated by & or \\
\seq_use:Nn \l_vv_rowcol_seq { #2 }
\end{pmatrix}
}
\seq_new:N \l_vv_rowcol_seq
\ExplSyntaxOff
\begin{document}
\begin{equation}
\vv{a;b;c;d;e;f;g}
=
\begin{pmatrix}
a \\ b \\ c \\ d \\ e \\ f \\ g
\end{pmatrix}
\end{equation}
\begin{equation}
\vv*{a;b;c;d;e;f;g}
=
\begin{pmatrix}
a & b & c & d & e & f & g
\end{pmatrix}
\end{equation}
\end{document}