7

I want to define some commands declaring paired delimiters using the mathtools package in LaTeX. For example, \paren{...} should result in \left(...\right), whereas \paren[Big]{...} should give \Bigl(...\Bigr).

The command \DeclarePairedDelimiter almost does the job, but I would have to write \paren*{...} instead of \paren{...} in order to get \left(...\right). So I added the following macro to my preamble:

\usepackage{mathtools}
\usepackage{ifthen}
...
\makeatletter
\newcommand{\DeclarePairedDelimiterY}[3]{%
    \expandafter\DeclarePairedDelimiter\csname#1Temp\endcsname{#2}{#3}
    \expandafter\newcommand\csname#1\endcsname[2][leftright]{%
        \ifthenelse{\equal{##1}{leftright}}%
        {\csname#1Temp*\endcsname{##2}}%
        {%
            \ifthenelse{\equal{##1}{normal}}{\csname#1Temp\endcsname{##2}}{}%
            \ifthenelse{\equal{##1}{big}}{\csname#1Temp\endcsname[\big]{##2}}{}%
            \ifthenelse{\equal{##1}{Big}}{\csname#1Temp\endcsname[\Big]{##2}}{}%
            \ifthenelse{\equal{##1}{bigg}}{\csname#1Temp\endcsname[\bigg]{##2}}{}%
            \ifthenelse{\equal{##1}{Bigg}}{\csname#1Temp\endcsname[\Bigg]{##2}}{}%
        }%
    }%
}
\makeatother

This means, there is an additional command, e.g. \parenTemp, which is defined by the macro \DeclarePairedDelimiter. The desired commands, e.g. \paren, are then given by

\DeclarePairedDelimiterY{paren}{(}{)}
\DeclarePairedDelimiterY{brac}{[}{]}
\DeclarePairedDelimiterY{set}{\{}{\}}
\DeclarePairedDelimiterY{abs}{\lvert}{\rvert}
\DeclarePairedDelimiterY{norm}{\lVert}{\rVert}

While the forms \paren[big]{...}, \abs[Bigg]{...} etc. are working, \paren{...} just gives ... instead of \left(...\right). So the error in the code is probably in the line

        {\csname#1Temp*\endcsname{##2}}%

which is supposed to expand as \#1Temp*{##2}, e.g. \parenTemp*{##2}.

Do you have an idea what is going wrong?

EDIT: Thanks to @Tsuyoshi Ito's answer and this piece of information, I was able to optimize the above code:

\usepackage{mathtools}
\usepackage{etextools}
\usepackage{ifthen}
...
\makeatletter
    \newcommand{\DeclarePairedDelimiterCase}[2]{%
        \newcommand#1[1][]{%
            \ifthenelse{\equal{##1}{normal}}%
            {#2}%
            {%
                \ifthenelse{\equal{##1}{big}\OR\equal{##1}{Big}\OR\equal{##1}{bigg}\OR\equal{##1}{Bigg}}%
                {\expandnext{#2[}{\csname##1\endcsname}]}%
                {#2*}%        % standard case using \left and \right
            }%
        }%
    }
    \newcommand{\DeclarePairedDelimiterY}[4][Temp]{%
        \expandafter\DeclarePairedDelimiter\csname#2#1\endcsname{#3}{#4}%
        \expandnext{\expandnext{\DeclarePairedDelimiterCase}{\csname#2\endcsname}}{\csname#2#1\endcsname}%
    }
    \newcommand{\DeclarePairedDelimiterXY}[6][Temp]{%
        \expandafter\DeclarePairedDelimiterX\csname#2#1\endcsname[#3]{#4}{#5}{#6}%
        \expandnext{\expandnext{\DeclarePairedDelimiterCase}{\csname#2\endcsname}}{\csname#2#1\endcsname}%
    }
\makeatother

This new version has the following advantages:

  • Users may choose the suffix of the "temporary" command on their own; default: Temp.
  • Supports both \DeclarePairedDelimiter AND \DeclarePairedDelimiterX.

Usage:

  • \DeclarePairedDelimiterY{name}{leftDelim}{rightDelim} instead of \DeclarePairedDelimiter{\name}{leftDelim}{rightDelim}
  • \DeclarePairedDelimiterXY{name}{N_args}{leftDelim}{rightDelim}{code} instead of \DeclarePairedDelimiterX{\name}[N_args]{leftDelim}{rightDelim}{code}

Note that the old version returned {} if \name was called with a misspelled optional argument. Instead, the new version then gives the "\left...\right-case".

aulste
  • 309

1 Answers1

8

I think that you have to write \csname#1Temp\endcsname* instead of \csname#1Temp*\endcsname. In other words, the star should not be part of a control sequence.

  • You're right. Thanks a lot :-)

    I've tried many different alternatives but never changed the position of the star.

    – aulste Aug 09 '11 at 17:46
  • 4
    @wueaul: In (La)TeX, the * is never part of the actual command name, but is read as an argument (see http://www.tex.ac.uk/cgi-bin/texfaq2html?label=cmdstar). – Caramdir Aug 09 '11 at 18:01
  • 3
    As @Caramdir said, the * is not part of the macro name, but read as a form of optional argument (mostly using \@ifstar). However, it is part of the environment name for starred environments. Not that environments are defines using macros with the same name (env foo => \foo ... \endfoo), so there are in fact some macros which have the star as part of there names. – Martin Scharrer Aug 11 '11 at 15:00