2

I've defined a command that uses square brackets, and when I use it within a matrix environment, the command is not parsed. I stumbled upon a solution to my problem here:

"[" Square bracket Curiosities in an array environment

which is to place {} around my command. But I'm not understanding why \\[] is the issue since I am not even using it. Note however, that if I load amsmath then the fix no longer works.

  1. What is the explanation for all this? And why does amsmath break the fix?
  2. Why am I able to use my command without issue within an align environment?
  3. What other environments, besides matrix, will be affected?
  4. Can I adjust my definition (while keeping the square brackets) so that it is more robust?

About the coding style: This is actually a much simplied version of another macro I have written. For that macro, valid inputs are: \func \func[A] \func[A][B] \func[A][] \func[][B]. So I have multiple optional arguments. The actual macro also makes use of parenthesis as a way of specifying additional information. All of this is quite involved and it is why I turned to http://www.ctan.org/tex-archive/support/newcommand to help me generate the code. So the style of this macro follows generated output from newcommand.py, and that is why I'd like a fix for the code I presented rather than a completely new solution.

Demonstration:

\documentclass{minimal}
\usepackage{amsmath} % loading this actual causes the solution to fail
\makeatletter
\def\democmdr{%
  \@ifnextchar[{\csname democmdr@i\endcsname}
               {\csname democmdr@i\endcsname[]}
    }%
\expandafter\def\csname democmdr@i\endcsname[#1]{%
  0#10
}%
\makeatother
\begin{document}
\setlength{\parindent}{0pt}
$\democmdr[5] \qquad \begin{matrix}\democmdr[5]\end{matrix}$ \\ % does not work
$\democmdr[5] \qquad \begin{matrix}{\democmdr[5]}\end{matrix}$ % works
\begin{align*}
\democmdr[5] % works even though \\ can be used in this environment
\end{align*}
\end{document}

Quick update: It turns out that loading amsmath breaks the solution I mentioned.

  • What is \democmdr without [] supposed to do? I think, you get into trouble, because \demcmdr tries to read [...] or should do nothing? – user31729 Oct 17 '14 at 4:22
  • Aha. But isn't this a common way to deal with optional arguments? newcommand.py generates output like this. Seems like #1 should just be empty and not cause an issue. – Tom Oct 17 '14 at 4:51
  • Basically it is, but in most cases, there are non-optional arguments after [] such that TeX is not confused – user31729 Oct 17 '14 at 4:53
  • So more to the point, I have a function where all of the following are acceptable inputs and produce slightly different outputs: \func \func[A] \func[A][B] \func[A][] \func[][B]. It sounds like I might have to rethink how I've defined the macro and shift to something closer to what you defined, but it looks like your way would be clunkier since I'd repeat myself a bit more. – Tom Oct 17 '14 at 5:00
  • If you have macros with two [] optional arguments, the whole affair is more difficult. In such a case, I recommend to use more appropiate packages, such as xparse, which can with definitions of such macros (i.e. allows them) – user31729 Oct 17 '14 at 5:02
3

Your problem is not the square brackets: it's the definition of the matrix environment. If you do \show\matrix you get

> \matrix=macro:
#1->\null \,\vcenter {\normalbaselines \m@th \ialign {\hfil $##$\hfil &&\quad \
hfil $##$\hfil \crcr \mathstrut \crcr \noalign {\kern -\baselineskip } #1\crcr 
\mathstrut \crcr \noalign {\kern -\baselineskip }}}\,.
l.14 \show\matrix

where the important thing is the #1. The underlying \matrix macro grabs one argument, so in your case \democmdr. That isolates the macro from any following arguments (notice it is followed by \crcr) and so they are never found.

The amsmath bundle redefines \matrix such that this problem goes away. That then reveals the bug in your code: you've got a stray space. In

\def\democmdr{%
  \@ifnextchar[{\csname democmdr@i\endcsname}
               {\csname democmdr@i\endcsname[]}
    }%

there is a space inserted after the third argument of \@ifnextchar as you've not terminated the line with a %

\def\democmdr{%
  \@ifnextchar[%]
    {\csname democmdr@i\endcsname}
    {\csname democmdr@i\endcsname[]}%
 }

(I've reformatted a bit to make the arguments clearer.) This shows up with the amsmath package loaded as it redefines \@ifnextchar to not ignore spaces. That's done because of the \\[] business but applies to other cases. When you have the kernel definition of \@ifnextchar, which skips spaces, your bug is 'invisible`.

So I'd suggest you remove that stray space and require the amsmath package.

  • I was so close! Haha. Clearly, still learning. Thanks for the formatting suggestions too. – Tom Oct 17 '14 at 6:25

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.