Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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".

share|improve this question
    
Has anyone already asked the mathtools' maintainers to include this in the package? –  Evpok Oct 8 '12 at 19:50
add comment

1 Answer

up vote 7 down vote accepted

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.

share|improve this answer
    
You're right. Thanks a lot :-) I've tried many different alternatives but never changed the position of the star. –  aulste Aug 9 '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 tex.ac.uk/cgi-bin/texfaq2html?label=cmdstar). –  Caramdir Aug 9 '11 at 18:01
    
@Caramdir: Thanks for this tip! –  aulste Aug 9 '11 at 18:10
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
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.