GeneralError for new Command with default Argument

LaTeX specific issues not fitting into one of the other forums of this category.
Post Reply
abakus
Posts: 3
Joined: Thu Aug 30, 2012 10:30 am

Error for new Command with default Argument

Post by abakus »

Hi there,

I have an error I do not understand. I'm running TeX Live 2009 on a Linux Debian. The following is a minimal example. The log file is attached.

Combining the new command \aaa with \testa brings the error message below. What I do not understand is that it works with \bbb, \ccc and \testb where the only differences are
either the parenthesis (\ccc) or the missing default argument (\bbb, \testb).

I've read that this error sometimes is related to "robust" and "fragile" so I tested using \DeclareRobustCommand, \protect and \newrobustcmd (from the etoolbox package) but it did not changed a thing.

Code: Select all

\documentclass[10pt,a4paper]{article}
\usepackage[latin1]{inputenc}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}

\newcommand{\aaa}[1][]{{#1}}
\newcommand{\bbb}[1]{{#1}}
\newcommand{\ccc}[1][]{#1}

\newcommand{\testa}[1][]{#1}
\newcommand{\testb}[1]{#1}

\begin{document}
%Don't work
$\aaa[ \testa[1] ]$
$\aaa[ \protect\testa[1] ]$

%Works
$\aaa[ \testa ]$
$\bbb{ \testa[1] }$
$\ccc[ \testa[1] ]$

$\aaa[ \testb{1} ]$
$\bbb{ \testb{1} }$
$\ccc[ \testb{1} ]$
\end{document}
In my use case I need the brackets because I have a subscript, something like \newcommand{\aaa}[1][]{A_{#1}}.
Attachments
test.log
(7.16 KiB) Downloaded 243 times
Last edited by localghost on Thu Aug 30, 2012 11:03 am, edited 1 time in total.

Recommended reading 2024:

LaTeXguide.org • LaTeX-Cookbook.net • TikZ.org

NEW: TikZ book now 40% off at Amazon.com for a short time.

Stefan Kottwitz
Site Admin
Posts: 10347
Joined: Mon Mar 10, 2008 9:44 pm

Error for new Command with default Argument

Post by Stefan Kottwitz »

Hi,

welcome to the board!

Nested square brackets can be a problem for the parsing of arguments. You can fix it by putting braces around the inner expression. This works:

Code: Select all

$\aaa[ {\testa[1]} ]$
$\aaa[ {\protect\testa[1]} ]$
Stefan
LaTeX.org admin
abakus
Posts: 3
Joined: Thu Aug 30, 2012 10:30 am

Error for new Command with default Argument

Post by abakus »

Hi Stefan,

many thanks for the solution.
Why does it make a difference if the new command has a default argument like \ccc?
User avatar
sommerfee
Posts: 503
Joined: Mon Apr 09, 2007 4:20 pm

Error for new Command with default Argument

Post by sommerfee »

abakus wrote:Why does it make a difference if the new command has a default argument like \ccc?
It does not make a difference but this one needs an adaption as well:

Not working:

Code: Select all

\ccc[ \testa[1] ]
Working:

Code: Select all

\ccc[{ \testa[1] }]
The problem is that TeX pay attention to nested curly braces like {..{..}..} (and therefore handles them correctly), but not to other brace types. So actually [..[..]..] will be read as "[..[..]" (from the starting brace until the very first(!) closing brace, i.e. "..[.." inside square braces) plus "..]" (the rest), which will result in a parsing error.

To work around this problem one can use extra curly braces to "protect" the argument, i.e. [{..[..]..}], since this one will be read as "..[..].." inside square braces.
User avatar
cgnieder
Site Moderator
Posts: 2000
Joined: Sat Apr 16, 2011 7:27 pm

Error for new Command with default Argument

Post by cgnieder »

Just as an addendum: commands defined by the xparse packages are a “more intelligent” and handle nested square brackets:

Code: Select all

\documentclass[10pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{xparse}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}

\NewDocumentCommand{\aaa}{O{}}{{a:#1}}
\NewDocumentCommand{\bbb}{m}{{b:#1}}
\NewDocumentCommand{\ccc}{O{}}{c:#1}

\NewDocumentCommand{\testa}{O{}}{A:#1}
\NewDocumentCommand{\testb}{m}{B:#1}

\begin{document}
%Don't work
$\aaa[ \testa[1] ]$
$\aaa[ \protect\testa[1] ]$

%Works
$\aaa[ \testa ]$
$\bbb{ \testa[1] }$
$\ccc[ \testa[1] ]$

$\aaa[ \testb{1} ]$
$\bbb{ \testb{1} }$
$\ccc[ \testb{1} ]$
\end{document}
It's still probably not a fact one should always rely on.

Regards
site moderator & package author
abakus
Posts: 3
Joined: Thu Aug 30, 2012 10:30 am

Error for new Command with default Argument

Post by abakus »

sommerfee wrote:
abakus wrote:Why does it make a difference if the new command has a default argument like \ccc?
It does not make a difference but this one needs an adaption as well:

Not working:

Code: Select all

\ccc[ \testa[1] ]
Its working for me, so I do not need the curly braces here. That's what confused me in the first place.
sommerfee wrote: The problem is that TeX pay attention to nested curly braces like {..{..}..} (and therefore handles them correctly), but not to other brace types. So actually [..[..]..] will be read as "[..[..]" (from the starting brace until the very first(!) closing brace, i.e. "..[.." inside square braces) plus "..]" (the rest), which will result in a parsing error.

To work around this problem one can use extra curly braces to "protect" the argument, i.e. [{..[..]..}], since this one will be read as "..[..].." inside square braces.
Makes sense. "[" and "]" are not special characters like curly braces. Still I do not see why the \ccc example works (at least for me).
cgnieder wrote:Just as an addendum: commands defined by the xparse packages are a “more intelligent” and handle nested square brackets:
thanks for the hint. After a look at the manual, it seem that xparse can help me with some other stuff as well :P.

Originally, I was using \newcommandx from the xargs package but is has the same problem as \newcommand.

ciao
abakus
Post Reply