30

In the definition of a command appears the declaration of \@dblarg, as follows: \def\title{\@dblarg\CJ@title}. What exactly does \@dblarg do?

1
  • 4
    It's a kernel command: \@dblarg{<command>}{<arg>} will expand to \{<command>}[<arg>]{<arg>}. May 17, 2012 at 23:02

2 Answers 2

30

It essentially checks if the token after \CJ@title is [ or not, in order to pass to the main command the same argument twice, if [ is not found. The command \CJ@title must be defined by

\def\CJ@title[#1]#2{...}

so that, with a call such as

\title{xyz}

the expansions will be (successively}

\@dblarg\CJ@title{xyz}
...<some complex action>...
\CJ@title[{xyz}]{xyz}

and with a call such as

\title[abc]{xyz}

the expansions will be (successively}

\@dblarg\CJ@title[abc]{xyz}
...<some complex action>...
\CJ@title[abc]{xyz}

One can follow ...<some complex action>... by looking at the definition of \@dblarg:

\long\def\@dblarg#1{\kernel@ifnextchar[{#1}{\@xdblarg{#1}}}
\long\def\@xdblarg#1#2{#1[{#2}]{#2}}

So with \title{xyz} one has (one step on each line, I omit the expansions of \kernel@ifnextchar that are irrelevant here)

\@dblarg\CJ@title{xyz}
\kernel@ifnextchar[{\CJ@title}{\@xdblarg{\CJ@title}}{xyz}
\@xdblarg{\CJ@title}{xyz}
\CJ@title[{xyz}]{xyz}

With \title[abc]{xyz} one has

\@dblarg\CJ@title{xyz}
\kernel@ifnextchar[{\CJ@title}{\@xdblarg{\CJ@title}}[abc]{xyz}
\CJ@title[abc]{xyz}

There's an extra pair of braces in the first case, but it will be removed by rule of TeX; it’s needed in case the title contains a ].

How to do the same with xparse

With the xparse package one can obtain the same functionality with a clearer syntax (I assume this is done in a class or package file)

\RequirePackage{xparse}

\NewDocumentCommand{\title}{om}{%
  \IfNoValueTF{#1}
    {\CJ@title{#2}{#2}}
    {\CJ@title{#1}{#2}}%
}
\newcommand{\CJ@title}[2]{...}

So no delimited argument is necessary.

With a recent version of xparse one can do even better:

\RequirePackage{xparse}

\NewDocumentCommand{\title}{O{#2}m}{%
  \CJ@title{#1}{#2}%
}
\newcommand{\CJ@title}[2]{...}

because with this code the value supplied for a missing optional argument is the same as the mandatory argument.

7
  • Instead of using the command \def by \newcommand, what would happen? Anything change?
    – osjerick
    May 17, 2012 at 23:22
  • 3
    @osjerick You can't define a command with delimited arguments with \newcommand, so \def is necessary.
    – egreg
    May 17, 2012 at 23:26
  • Thanks @egreg, now I'm learning all about creating classes, you could recommend me a manual or book about this, please?
    – osjerick
    May 17, 2012 at 23:31
  • 1
    @osjerick In the "LaTeX companion" there's material about this.
    – egreg
    May 17, 2012 at 23:34
  • 1
    @osjerick: These are typically package-specific notations. Within the .sty file, @ is treated like a letter. So, it could be that the package author prefix certain internal commands with their initials, or perhaps even an abbreviation of the package name. For example, the keyval package author (David Carlisle) decided to use a KV@ prefix, which was duplicated in the xkeyval package using XKV.
    – Werner
    May 18, 2012 at 5:26
13

This is an easy way of allowing optional arguments to some other function/macro.

For example, using your case of \def\title{\@dblarg\CJ@title}, you can either use

\title{some title}

without an optional argument, or use

\title[some optional title]{some title}

with an optional argument. "Easy" here refers to the fact that if you don't specify the optional component (like in the former example), it defaults to

\title[some title]{some title}

thereby converting single-argument responses into double-arguments. The macro \CJ@title is appropriately defined to manage both arguments and could have the form:

\def\CJ@title[#1]#2{%
  %...
}

This is typically the case with sectional commands that have an optional argument: \section[<ToC entry>]{<body entry>}. If you don't specify the optional argument, the <body entry> still makes its way into the ToC. How? \@dblarg.

Here are the formal definitions contained within latex.ltx - you'll find its use inside \@startsection, just as an example:

\long\def\@dblarg#1{\kernel@ifnextchar[{#1}{\@xdblarg{#1}}}
\long\def\@xdblarg#1#2{#1[{#2}]{#2}}
0

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.