For answering a question yesterday I wanted to define a shortcut for creating a matrix inside a tikzpicture. As a minimal example, consider

        \matrix[matrix of math nodes] {#1};

which would then be used as

    a & b \\
    e & f \\

But LaTeX complains about Package pgfbasematrix Error: Single ampersand used with wrong catcode at the line with the closing brace of \amatrix{}. Why does it do that and how can I avoid it?


TikZ cannot make the ampersand given in the argument to an active character. You could

use \pgfmatrixnextcell instead of & and perhaps define a shortcut for it,

or use the ampersand replacement option:

        \matrix[ampersand replacement=\&,matrix of math nodes] {#1};
    a \& b \\
    e \& f \\

From p179 of the manual (emphasis added, one minor but significant error corrected):

Even though TikZ seems to use & to separate cells, pgf actually uses a different command to separate cells, namely the command \pgfmatrixnextcell and using a normal & character will normally fail. What happens is that, TikZ makes & an active character and then defines this character to be equal to \pgfmatrixnextcell. In most situations this will work nicely, but sometimes & cannot be made active; for instance because the matrix is used in an argument of some macro or the matrix contains nodes that contain normal {tabular} environments. In this case you can use the following option to avoid having to type \pgfmatrixnextcell each time:

/tikz/ampersand replacement= macro name or empty          (no default)

If a macro name is provided, this macro will be defined to be equal to \pgfmatrixnextcell inside matrices and & will not be made active. For instance, you could say ampersand replacement=\& and then use \& to separate columns as in the following example:

\matrix [ampersand replacement=\&]
\draw (0,0) circle (4mm); \& \node[rotate=10] {Hello}; \\
\draw (0.2,0) circle (2mm); \& \fill[red] (0,0) circle (3mm); \\

There is presumably some horrendously complicated way to turn on the active nature of the ampersand again inside the macro argument, but the above would seem the cleanest way.

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.