7

I am trying to define a command which takes as an argument a string containing ampersands, and replaces every ampersand by a space. Following the ideas in Replacing characters in argument strings, I defined my command as follows:

\DeclareRobustCommand\colvec[1]{%
    \saveexpandmode\expandarg
    \StrSubstitute{\noexpand#1}&\ [\vectorentries]%
    \restoreexpandmode[\vectorentries]^T}

This works great, except in align environments, where the ampersands get recognized as column markers and latex gets confused. How should I fix my code to work in align environments as well?

Here is a minimum-non-working-example:

\documentclass{article}

\usepackage{xstring}
\usepackage{amsmath}

\DeclareRobustCommand\colvec[1]{%
    \saveexpandmode\expandarg
    \StrSubstitute{\noexpand#1}&\ [\vectorentries]%
    \restoreexpandmode[\vectorentries]^T}

\begin{document}

\begin{align}
x = \colvec{3 & 3}
\end{align}

\end{document}
4
  • Why don't you use a different token?
    – cgnieder
    May 8, 2012 at 17:42
  • Because i'm using it in a 500-page book and the command shows up many many times. But maybe you're right; I should use some regular expression search and replace to change the token... I thought there might be a simple answer to my question.
    – yori
    May 8, 2012 at 17:46
  • 3
    At second thought -- there is: place the interior of the command between {...}. This should hide the & from align's scanning mechansim.
    – cgnieder
    May 8, 2012 at 17:51
  • Awesome! That's what I meant by "simple solution"! :)
    – yori
    May 8, 2012 at 17:54

2 Answers 2

7

Transforming my comment into an answer: you need to hide the ampersand from align's scanning mechanism.

The easiest way to do this is placing the command in braces:

\begin{align}
 x = {\colvec{3 & 3}}
\end{align}

To have a more comfortable syntax one can add the braces to the definition of \colvec:

\documentclass{article}

\usepackage{xstring}
\usepackage{amsmath}

\DeclareRobustCommand\colvec[1]{%
    {\saveexpandmode\expandarg
    \StrSubstitute{\noexpand#1}&\ [\vectorentries]%
    \restoreexpandmode[\vectorentries]^T}}

\begin{document}

\begin{align}
 x &= \colvec{3 & 3} \\
 E &= mc^2 % to show that alignment still works
\end{align}

\end{document}
1
  • 1
    Thanks, and looking back, I regret having asked the question because the solution is embarrassingly simple. I expected that it was going to take catcodes etc. Pfew!
    – yori
    May 8, 2012 at 21:22
4

Why not using a simpler strategy?

\newcommand{\colvec}[1]{
  {
   \setlength{\arraycolsep}{.16667em}
   [\begin{matrix}#1\end{matrix}]^T
  }
}

A different way of replacing the & with a space is with xparse and expl3:

\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\colvec}{m}
 {
  \tl_set:Nn \l_tmpa_tl {#1}
  \tl_replace_all:Nnn \l_tmpa_tl { & } { \  }
  [\tl_use:N \l_tmpa_tl]^T
 }
\ExplSyntaxOff

This doesn't even require the extra braces.

3
  • Thanks for the idea, but this is what I used before. The problem with it is that if you use this in a sentence, the vertical alignment does not always come out correctly. Also, if there are subscripts or superscripts, the brackets become bigger than necessary.
    – yori
    May 8, 2012 at 21:38
  • I changed the macro; can you show a place where the alignment is not correct? Just curious.
    – egreg
    May 8, 2012 at 21:50
  • see my next question, tex.stackexchange.com/questions/55007/matrix-vertical-alignment . it's driving me crazy!
    – yori
    May 9, 2012 at 1:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .