在 xparse 中定义一个宏来使用 SplitList 打印向量

在 xparse 中定义一个宏来使用 SplitList 打印向量

请看以下例子:

\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}

在此处输入图片描述

相关内容