定义、重新定义和提供命令

定义、重新定义和提供命令

我已经使用 LaTeX 很长时间了,我发现自己经常去这个网站解决问题。这通常包括复制粘贴包含和 的代码。我想是时候开始学习如何使用它们了\newcommand,这样我就可以自己解决问题了!如果你真的知道代码里发生了什么,那就更好了。\newenvironment\def

我想知道是否有任何教程或书籍介绍如何使用这些命令。或者最好的学习方法是随意处理一个文件?

提前致谢!

(这也是我使用这个网站这么长时间后第一次在这里发帖,我真的很感谢在这里发帖并试图帮助其他人的每个人!)

答案1

用于定义自定义命令和环境的 LaTeX 宏包括:

  • \newcommand
  • \newcommand*
  • \renewcommand
  • \renewcommand*
  • \providecommand
  • \providecommand*
  • \newenvironment
  • \newenvironment*
  • \renewenvironment
  • \renewenvironment*

最好从这些开始,因为您应该更喜欢它们而不是 TeX 宏,例如\def。但是,有时只有 TeX 宏才有效。\def一旦您很好地理解了 LaTeX 宏的工作原理,就会更容易理解何时以及为什么需要和朋友。

定义、重新定义和提供命令

\newcommand[<n>][<default>]{<definition>}

其中<n>是参数的总数,<definition>是命令的定义。如果<n>没有指定,LaTeX 会假定命令不能接受参数。如果<default>给出了,第一个参数是可选的,如果缺失,则<default>使用。

例如,这是\tableofcontents在 中的定义article.cls

\newcommand\tableofcontents{%
    \section*{\contentsname
        \@mkboth{%
           \MakeUppercase\contentsname}{\MakeUppercase\contentsname}}%
    \@starttoc{toc}%
    }

该命令不接受任何参数,无论是强制的还是可选的,因此只给出宏名称\tableofcontents和宏的定义。

下面是一个具有单个强制参数的示例\ltnews.cls

\newcommand\cs[1]{\texttt{\textbackslash#1}}

#1的是第一个参数。

这是定义新命令的示例latex.ltx,该命令需要 2 个参数,一个是必需的,一个是可选的。如果未提供可选参数,0则将使用的默认值#1

\newcommand\qbezier[2][0]{\bezier{#1}#2}

参数数量不得超过 9 个,并且使用 不能指定超过一个可选参数\newcommand。所有其他参数都必须是必需的。此外,如果有可选参数,则必须先指定它,并且定义命令的语法始终是\mycommand[optional]{mandatory}{mandatory}{mand...

\newcommand检查是否存在同名的现有命令,如果找到则产生错误。因此有一个内置检查可以防止意外覆盖现有命令。

\newcommand*就像\newcommand,但是它的参数不能包含段落分隔符。

要重新定义现有命令,可以使用\renewcommand\renewcommand*。在这种情况下,LaTeX 会检查该命令是否已存在,如果不存在则会产生错误。

如果仅当命令不存在时才定义该命令,则可以使用\providecommand\providecommand*

定义和重新定义环境

\newenvironment{<env name>}[<n>][<default>]{<begin env>}{<end env>}

其中<env name>是新环境的名称,<n>是参数的数量(如果未指定则为 0),<default>如果第一个参数是可选的,则为第一个参数的默认值(如果未指定,则所有参数都是必需的)。<begin env><end env>指定在环境开始和结束时要执行的代码。

这很像\newcommand<n>不能超过 9,只有一个参数可以是可选的,并且它必须是第一个参数,并且如果已经存在同名的环境,LaTeX 会抱怨。#1,...#9如果适用,请参考给予环境的参数。

下面是一个包含 3 个参数的示例cuisine.sty,所有参数都是必需的:

\newenvironment{recipe}[3]{%
  \stepcounter{r@cipenumber}
  \let\newstep\m@thodend
  \let\recipen@wpage\newpage
  \let\newpage\r@cipen@wpage
  \let\0\d@grees
  \let\degrees\d@grees
  \let\fr\fr@ction
  \let\ing\ingr@dient
  \let\ingredient\ingr@dient
  \let\freeform\fr@eform
  \n@wpagingfalse%
  \setlength{\parindent}{0pt}
  \savebox{\st@pingrbox}[\R@cipeIQUWidth]{}
  \savebox{\st@pmethodbox}[\R@cipeMethodWidth]{}
  \ifind@xing
     \addcontentsline{toc}{subsection}{#1}
  \fi
  \r@cipetitle{#1}{#2}{#3}
  \vskip0.2cm%
  \p@stingred%
}%
{%
  \pr@ingred%
  \ifnum\value{st@pnumber}=0%  then complain!
    \PackageWarning{cuisine}{The recipe did not have any steps}%
  \fi%

  \pagebreak[0]%
  \medskip%
  \@endpetrue%
}%

\newenvironment*就像\newenvironment,但是它的参数不能包含段落分隔符。

要重新定义现有环境,请使用\renewenvironment\renewenvironment*。同样,如果环境不存在,LaTeX 会在这种情况下发出警告。

超越 LaTeX 2e

当您熟悉这些自定义方法后,您会发现自己所能做的事情是有限的。此时,开始查看\def和朋友。在此阶段,您可能还应该查看xparse它提供了比开发 LaTeX 3 的工作更强大和更灵活的选项。但是,一旦您熟悉了 LaTeX 2e 宏提供的可能性,这些方法将更有意义。

相关内容