08_LaTeX之自定义LaTeX命令和功能

08_LATEX 之自定义LATEX命令和功能

本文主体内容来自一份 (不太) 简短的 LATEX2ε 介绍

如何制作一个简单但像样的毕业论文/书籍/简历模板,每次可以直接套用,而不是再在导言区写一堆代码?

本章的内容将有助于你实现这一个目标,让你能编写可重复利用的模块——宏包和文档类,并在其中自己定义命令和环境。
不过作为入门手册,这些知识仍是不全面的。如果你不满足于此,需要参考更多资料,比如

自定义命令和环境

定义新命令

使用如下命令可以定义你自己的命令:
image-20250131110507497
\newcommand 的基本用法需要两个必选参数,第一个参数 <name> 是要定义的命令名称(带反斜线),第二个参数 <definition> 是命令的具体定义。方括号里的参数 <num> 是可选的,用于指定新命令所需的参数数目(最多 9 个)。如果缺省可选参数,默认就是 0,也就是新定义的命令不带任何参数。

接下来的两个例子有助于理解。第一个例子定义了一个新的命令 \tnss。这个命令是本手册英文名称“The Not So Short Introduction to \LaTeXe” 的简写。如果需要在文档中多次使用本手册的名称,那么使用这个命令是一个非常方便的办法。

image-20250131111926918

第二个例子演示了如何定义一个带参数的命令。在命令的定义中,标记 #1代表指定的参数。如果想使用多个参数,可以依次使用 #2、……、#9等标记。

image-20250131112252163

LATEX 不允许使用 \newcommand 定义一个与现有命令重名的命令。如果需要修改命令定义的话,使用 renewcommand 命令。它使用与命令\newcommand 相同的语法。

在某些情况之下,使用 \providecommand 命令是一种比较理想的方案:在命令未定义时,它相当于 newcommand;在命令已定义时,沿用已有的定义。

定义环境

\newcommand 命令类似,可以用 \newenvironment 定义新的环境。它的语法如下所示:

image-20250131141432124

同样地,\newenvironment 命令有一个可选的参数。在 <before> 中的内容将在此环境包含的文本之前处理,而在 <after> 中的内容将在遇到 \end{<name>} 命令时处理。

下面的例子演示了 \newenvironment 命令的用法:

image-20250131142005221

参数 <num> 的使用方式与 \newcommand 命令相同。LATEX 还同样保证你不会不小心新建重名的环境。如果你确实希望改变一个现有的环境,你可以使用命令 \renewenvironment,它使用和命令 \newenvironment 相同的语法。

xparse 宏包简介

通过 \newcommand\newenvironment 定义的命令或环境格式比较固定。如果需要定义带有多个可选参数、或者带星号的命令或环境,可以使用 xparse 宏包,它提供了 \NewDocumentCommand\NewDocumentEnvironment 等命令,具体语法如下:

image-20250131142701900

相比 \newcommand\newenvironmentxparse 通过{<arg spec>} 来指定参数的个数和格式。基本的参数格式见下表。注意{<arg spec>} 中的空格可以忽略。

image-20250131142942039

不同输入值在解析后的结果可以见 下表 中的示例。

image-20250131143046148

-NoValue- 标记可以用 \IfNoValueTF 等命令来判断:

image-20250131143150139

举例如下:

image-20250131143225242

\BooleanTrue\BooleanFalse 则可以用 \IfBooleanTF 等命令来判断:

image-20250131143936824

举例如下:

image-20250131143954655

需要注意的是,与命令不同,环境在定义时名字里面可以包含 *

\NewDocumentEnvironment {mytabular}  { o +m } {...} {...}
\NewDocumentEnvironment {mytabular*} { m o +m } {...} {...}

s 标记的 * 则应该放在\begin{<env>} 的后面:

\NewDocumentEnvironment { envstar } { s }
  {\IfBooleanTF {#1} {star} {no star}} {}
\begin{envstar}*
\end{envstar}

\renewcommand\providecommand 等命令类似,xparse 宏包也允许在命令或环境已有定义时做出相应的处理,具体见 下表。

image-20250206211617053

编写自己的宏包和文档类

编写简单的宏包

如果定义了很多新的环境和命令,文档的导言区将变得很长,在这种情况下,可以建立一个新的 LATEX 宏包来存放所有你自己定义的命令和环境,然后在文档中使用 \usepackage 命令来调用自定义的宏包。

写一个宏包的基本工作就是将原本在文档导言区里很长的内容拷贝到另一个文件中去,这个文件需要以 .sty 作扩展名。还需要加入一个宏包专用的命令:

image-20250207202115559

这个命令应该放在你的宏包的最前面,并且一定要注意:<package name> 需要和宏包的文件名一致。\ProvidesPackage 是 LaTeX 中用于声明宏包名称和版本信息的命令,通常放在宏包文件的顶部。它的作用是:

  1. 声明宏包名称:告诉 LaTeX 当前文件的宏包名称。
  2. 版本信息:提供宏包的版本号和日期,便于用户了解更新情况。
  3. 避免重复加载:LaTeX 会检查宏包是否已加载,防止重复加载。
\ProvidesPackage{<宏包名称>}[<版本信息>]
  • <宏包名称>:宏包的名字,通常与文件名一致。
  • <版本信息>:可选,包含版本号和日期。
\ProvidesPackage{mypackage}[2023/10/01 v1.0 My custom package]

这表示宏包 mypackage 的版本是 1.0,发布于 2023 年 10 月 1 日。

下面的源代码 给出了一个小的宏包示例,其中包含了之前定义的一些命令。

% Demo Package by Tobias Oetiker
\ProvidesPackage{demopack}
\newcommand{\tnss}{The not so Short Introduction
                   to \LaTeXe}
\newcommand{\txsit}[1]{The \emph{#1} Short
                       Introduction to \LaTeXe}
\newenvironment{king}{\begin{quote}}{\end{quote}}

在宏包中调用其它宏包

如果想进一步把各种宏包的功能汇总到一个文件里,而不是在文档的导言区罗列一大堆宏包的话,LATEX 允许你在自己编写的宏包中调用其它宏包,命令为 \RequirePackage,用法和 \usepackage一致:
image-20250207204212557

编写自己的文档类

当你更进一步,需要编写自己的文档类,如论文模板等,问题就稍稍麻烦了一些。首先,自己的文档类以 .cls 作扩展名,开头使用 \ProvidesClass 命令:
image-20250207210745704
{<class name>}也需要和文档类的文件名一致。

但是有了上述命令和和你之前学到的 \newcommand 等,还并不能完成一个文档类的编写,因为诸如 \chapter\section 等等许多常用的命令都是在文档类中定义的。事实上,许多时候我们只需要像调用宏包那样调用一个基本的文档类,省去许多不必要的麻烦。在你的文档类中调用其它文档类的命令是 \LoadClass,用法和 \documentclass 十分相像:
image-20250207211020811

计数器

我们早就见识到了 LATEX 对文档元素自动计数的能力:章节符号、列表、图表……它们都是依靠 LATEX 提供的计数器功能完成的。

定义和修改计数器

定义一个计数器的方法为:
image-20250207214349670

{<counter name>} 为计数器的名称。计数器可以有上下级的关系,可选参数 [<parent counter name>] 定义为 {<counter name>} 的上级计数器。

以下命令修改计数器的数值,\setcounter 将数值设为 <number>\addtocounter 将数值加上 <number>\stepcounter 将数值加一,并将所有下级计数器归零
image-20250207220543336

计数器的输出格式

计数器<counter> 的输出格式由 \the<counter> 表示。这个值默认以阿拉伯数字形式输出,如果想改成其它形式,需要重定义 \the<counter>,如将 equation 计数器的格式定义为大写字母:

\renewcommand\theequation{\Alph{equation}}

命令 \Alph 控制计数器 <counter> 的值以大写字母形式显示。下表列出所有可用于修改计数器格式的命令。注意:这些命令只能用于计数器,不能直接用于数字,如\roman{1} 这样的命令会出错。

image-20250207223910065

计数器的输出格式还可以利用其它字符,甚至其它计数器的输出格式与之组合。如标准文档类里对 \subsection 相关的计数器的输出格式的定义相当于:

\renewcommand\thesubsection{\thesection.\arabic{subsection}}

LATEX 中的计数器

  • 所有章节命令 \chapter\section 等分别对应计数器 chaptersection 等等,而且有上下级的关系。而计数器 part 是独立的。
  • 有序列表 enumerate 的各级计数器为 enumi, enumii, enumiii, enumiv,也有上下级的关系。
  • 图表浮动体的计数器就是 tablefigure;公式的计数器为 equation。这些计数器在 article 文档类中是独立的,而在reportbook 中以chapter 为上级计数器。
  • 页码、脚注的计数器分别是 pagefootnote

我们可以利用前面介绍过的命令,修改计数器的样式以达到想要的效果,比如把页码修改成大写罗马数字,左右加横线,或是给脚注加上方括号:

\renewcommand\thepage{--~\Roman{page}~--}
\renewcommand\thefootnote{[\arabic{footnote}]}
\end{verbatim}

最后介绍两个有用的计数器:

secnumdepth

LATEX 标准文档类对章节划分了层级:

  • article 文档类里 part 为 0,section 为 1,依此类推;
  • reportbook 文档类里part为 -1,chapter 为 0,section 为 1,等等。

secnumdepth 计数器控制章节编号的深度,如果章节的层级大于 secnumdepth,那么章节的标题、在目录和页眉页脚的标题都不编号(照常生成目录和页眉页脚),章节计数器也不计数。

可以用 \setcounter 命令设置 secnumdepth 为较大的数使得层级比较深的章节也编号,如设置为 4 令 \paragraph 也编号;或者设置一个较小的数以取消编号,如设置为 -1 令 \chapter 不编号。后者是生成不编号的章节的一个妙招,免去了手动使用 \addcontentsline\markboth 的麻烦。

secnumdepth 计数器在 article 文档类里默认为 3(subsubsection 一级);在 reportbook 文档类里默认为 2(subsection 一级)。

tocdepth

tocdepth 计数器控制目录的深度,如果章节的层级大于 tocdepth,那么章节将不会自动写入目录项。默认值同 secnumdepth

LaTeX 可定制的一些命令和参数

LATEX 事实上有相当一些可以定制的命令和参数,不过对于修改样式或者开发宏包来说,这些定制项还远远不够。

对于用户来讲,容易定制的是这一些项目:

  • 标题名称/前后缀等。 下表 列出了标准文档类里可定制的项目, 表中所有的 LATEX 命令都可以用 \renewcommand 来修改。

    image-20250208210859903
  • 长度。前文在叙述各种排版元素时已经介绍过一些,现归纳于 下表。表中所有的长度命令可用 \setlength 来修改。

    image-20250208211426192

  1. Frank Mittelbach, Michel Goossens, Johannes Braams, David Carlisle, Chris Rowley. The LATEX Companion, 2nd edition. Addison-Wesley, Reading, Massachusetts, 2004, ISBN 0-201-36299-6. ↩︎

  2. LATEX Project Team. LATEX 2 ϵ for class and package writers. CTAN://macros/latex/base/clsguide.pdf (texdoc clsguide) ↩︎

posted @   Invinc-Z  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示