4

please look at the following example:

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

I tried to define a macro to typeset vectors comfortably. But something went wrong as you can see on the picture.

enter image description here

Any ideas how to solve the problem?

  • The \vv command is also used by the \esvect package, by the way. – user31729 Mar 23 '17 at 20:39
7

The \@firstitemfalse command is done within a array cell, which is a group and will never be false outside, so use \global\@firstitemfalse, but a better solution is to use an expl3 approach with `\seq at the end of this answer...

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

Alternate solution with 'direct' usage of expl3 features, so there's no need of \if@firstitem at all, since \seq_use:Nn ... {\\} cares for this.

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

enter image description here

  • +1 for the seq-use version (-1 for the global setting:-) – David Carlisle Mar 23 '17 at 20:54
  • @DavidCarlisle: Desparate times require desperate measures ;-) – user31729 Mar 23 '17 at 20:56
  • Thank you. I tried your first solution. I had to add \global also in the definition of the macro to make it work properly mor than once. :) – user125730 Mar 23 '17 at 20:56
  • The second solution seems to be very clever but I don't know how to use the ExplSyntax. I tried to read the Manual but I did not help. Do you know another source to learn it? – user125730 Mar 23 '17 at 20:58
  • @user125730: The interface3 manual is rather a reference than a description how to use expl3. There is no clear introduction yet. – user31729 Mar 24 '17 at 13:23
5

enter image description here

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

each table cell is a local group so your boolean flag setting was being lost as soon as you did \\

  • Oh, I did not know that each table cell is a local group. Thank you. – user125730 Mar 23 '17 at 20:47
3

There's no need for a conditional: pmatrix is perfectly happy when the last row ends with \\.

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

enter image description here

If the *-variant is meant for printing row vectors, then you have a small problem, so a different strategy is needed: first, split the argument at the first ;, then apply \SplitList to the second part (if it exists). However this would require too many macros.

An approach based on expl3 is therefore preferable:

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

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.