带有可选参数的 LaTeX 命令

带有可选参数的 LaTeX 命令

在撰写统计物理学讲义时,我发现我经常写非常相似的长 LaTeX 序列,例如

\frac{\partial }{\partial <foo>}

\frac{\partial <bar>}{\partial <foo>}

\left( \frac{\partial <bar>}{\partial <foo>} \right)_{<baz>}

我想通过使用表格来简化我的生活

\dddfrac{<foo>}

\dddfrac{<foo>}{<bar>}, 和

\dddfrac{<foo>}{<bar>}{<baz>} 它们都有相同的名称,因此很容易记住。

我的一个朋友(现在无法提供帮助)帮助我完成了以下 TeX 黑客攻击:

%requires \usepackage{gmverb}
\fooatletter{%
  \def\dddfrac#1{%
    \relaxen\dddfrac@i
    \relaxen\dddfrac@ii
    \relaxen\dddfrac@iii
    \def\dddfrac@i{#1}%
    \@ifnextchar\bgroup\dddfrac@getii\dddfrac@typeset}%
  % 
  \def\dddfrac@getii#1{%
    \def\dddfrac@ii{#1}%
    \@ifnextchar\bgroup\dddfrac@getiii\dddfrac@typeset}%
  %
  \def\dddfrac@getiii#1{%
    \def\dddfrac@iii{#1}%
    \dddfrac@typeset}%
  %
  \def\dddfrac@typeset{%
    \@ifundefined{dddfrac@iii}{%
      \@ifundefined{dddfrac@ii}{% 1 argument only
        \frac{\partial }{\partial \dddfrac@i}
      }{% 2 arguments
        \frac{\partial \dddfrac@i}{\partial \dddfrac@ii}%
        }}{% 3 arguments
        \left( \frac{\partial \dddfrac@i}{\partial \dddfrac@ii} \right)_{\dddfrac@iii}%
      }}
}

我有使用 LaTeX 的经验,但不能用纯 TeX 书写(但我或多或少了解代码的作用)。

现在,虽然这可以正常工作,但如果我想要 20 个这样的命令,代码会写得非常长。对于一个人来说,是否有任何标准的方法来简化这种行为的实现?知道如何用纯 TeX 编程吗?也许有人已经为这种情况编写了包,类似于例如包suffix

第二个问题:LaTeX 有一个传统,即为具有一些额外功能的命令引入带星号的版本,而不是在名称后加上后缀,例如“Ex”(就像微软所做的那样)。是否可以遵循 \dddfrac 命令的这一传统,并使用另一组定义来定义 \dddfrac*,以适应不同数量的参数?

Matbesuffix会有帮助吗?毕竟,这个包允许定义带星号的命令版本,或者定义带有 1 个参数和不带有参数的命令版本。但文档相当短,需要 TeX 知识,我谦虚地希望没有 TeX 也能活下去。

答案1

xparse包已在其他答案中提及。这提供了一种通用方法来定义(类似 LaTeX2e)文档命令,而无需编程。有几种方法可以实现您想要的。一种方法是

\documentclass{article}

\usepackage{xparse}
\NewDocumentCommand{\dddfrac}{mG{}g}{%
  \IfNoValueTF{#3}
    {%
      \frac
        {\partial #2}
        {\partial #1}%
    }    
    {%
      \left (
      \frac{\partial #2}{\partial #1}
      \right )
      _{#3}
    }%
}

\begin{document}
$\dddfrac{x}$

$\dddfrac{y}{f_y}$

$\dddfrac{y}{f_y}{n}$
\end{document}

这将设置\dddfrac为需要一个强制参数(#1)和两个“可选组”参数。第一个设置为G{},这意味着默认值为零。第二个设置为g,如果没有给出,它将返回一个特殊标记\NoValue。我用它来测试最后一个参数,然后可以用它来判断我们是否需要\left (...\right )对。我已经做过一次测试:你可以做两次,而不需要重复\frac

答案2

使用xparse它可以轻松定义具有多个可选参数的命令。

\documentclass{scrartcl}

\usepackage{xparse}
\NewDocumentCommand{\dddfrac}{m O{} D(){}}{%
   \def\@tempa{#3}%
   \ifx\@tempa\@empty\else\left(\fi%
      \frac{%
         \partial #2
      }{%
         \partial #1
      }
   \ifx\@tempa\@empty\else\right)_{#3}\fi%
}

\begin{document}
$\dddfrac{x}$

$\dddfrac{y}[f_y]$

$\dddfrac{f(x)}(n)$

$\dddfrac{y}[f_y](n)$
\end{document}

解释

  • \NewDocumentCommand工作原理类似,\newcommand但将参数规范作为第二个参数。

  • 在参数规范中,我们使用 来m声明一个强制参数,O{<default>}定义一个可选参数,并D<delim 1><delim 2>{<default>}定义一个由<delim 1>和分隔的可选参数<delim 2>

    您可以替换D(){}O{}使用\dddfrac{<foo>}[<bar>][<baz>]

  • 我们将第三个参数存储#3\@tempa并通过\ifx与它进行比较\@empty,如果它为空,则我们不执行任何操作,否则(\else)我们打印括号。

  • \makatletter可以@成为控制序列的一部分

答案3

在 LaTeX 中,有一个名为 的命令\newcommand。你可以用它编写小宏。

该命令的语法\newcommand是:

\newcommand{\commandname}[numberOfArguments][defaultArgument]{implementation}

因此您可以按照以下方式编写宏:

\newcommand{\dddafrac}[1]{\ensuremath{\frac{\partial }{\partial #1}}}
\newcommand{\dddbfrac}[2]{\ensuremath{\frac{\partial #1}{\partial #2}}}
\newcommand{\dddcfrac}[3]{\ensuremath{\left( \frac{\partial #1}{\partial #2} \right)_{#3}}}

我认为这段代码的作用非常清楚。使用#1它检索第一个参数。

相关内容