使用 \csname ... \endcsname 计算某些命令的星号版本

使用 \csname ... \endcsname 计算某些命令的星号版本

我想使用mathtoolsLaTeX 中的包定义一些声明成对分隔符的命令。例如,\paren{...}结果应为\left(...\right),而结果\paren[Big]{...}应为\Bigl(...\Bigr)

该命令几乎可以完成工作,但为了得到 ,\DeclarePairedDelimiter我必须写\paren*{...}而不是。因此,我在序言中添加了以下宏:\paren{...}\left(...\right)

\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

这意味着,有一个额外的命令,例如\parenTemp,由宏定义\DeclarePairedDelimiter。然后,所需的命令,例如\paren,由以下命令给出

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

虽然表格\paren[big]{...}\abs[Bigg]{...}可以正常工作,但\paren{...}只会给出...而不是\left(...\right)。因此,代码中的错误可能出现在以下行中

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

其应该扩展为\#1Temp*{##2},例如\parenTemp*{##2}

你知道出了什么问题吗?

编辑:感谢@Tsuyoshi Ito 的回答和这条信息,我能够优化上面的代码:

\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

这个新版本具有以下优点:

  • 用户可以自行选择“临时”命令的后缀;默认:Temp。
  • 同时支持\DeclarePairedDelimiterAND \DeclarePairedDelimiterX

用法:

  • \DeclarePairedDelimiterY{name}{leftDelim}{rightDelim}代替\DeclarePairedDelimiter{\name}{leftDelim}{rightDelim}
  • \DeclarePairedDelimiterXY{name}{N_args}{leftDelim}{rightDelim}{code}代替\DeclarePairedDelimiterX{\name}[N_args]{leftDelim}{rightDelim}{code}

{}请注意,如果\name使用拼写错误的可选参数调用,旧版本会返回结果。而新版本则会返回“ \left...\right-case”。

答案1

我认为你必须写\csname#1Temp\endcsname*而不是\csname#1Temp*\endcsname。换句话说,星号不应该是控制序列的一部分。

相关内容