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

news/2025/2/8 22:41:29/文章来源:https://www.cnblogs.com/Invinc-Z/p/18705538

08_\(\LaTeX{}\) 之自定义\(\LaTeX{}\)命令和功能

目录
  • 08_\(\LaTeX{}\) 之自定义\(\LaTeX{}\)命令和功能
    • 自定义命令和环境
      • 定义新命令
      • 定义环境
      • xparse 宏包简介
    • 编写自己的宏包和文档类
      • 编写简单的宏包
      • 在宏包中调用其它宏包
      • 编写自己的文档类
    • 计数器
      • 定义和修改计数器
      • 计数器的输出格式
      • \(\LaTeX{}\) 中的计数器
        • \(\textbf{secnumdepth}\)
        • \(\textbf{tocdepth}\)
    • \(LaTeX{}\) 可定制的一些命令和参数

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

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

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

自定义命令和环境

定义新命令

使用如下命令可以定义你自己的命令:
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

\(\texttt{-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 命令来调用自定义的宏包。

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

image-20250207202115559

这个命令应该放在你的宏包的最前面,并且一定要注意:\(\textbf{<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 Introductionto \LaTeXe}
\newcommand{\txsit}[1]{The \emph{#1} ShortIntroduction to \LaTeXe}
\newenvironment{king}{\begin{quote}}{\end{quote}}

在宏包中调用其它宏包

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

编写自己的文档类

当你更进一步,需要编写自己的文档类,如论文模板等,问题就稍稍麻烦了一些。首先,自己的文档类以 \(\texttt{.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 将数值加一,并\(\textbf{将所有下级计数器归零}\)
image-20250207220543336

计数器的输出格式

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

\renewcommand\theequation{\Alph{equation}}

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

image-20250207223910065

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

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

\(\LaTeX{}\) 中的计数器

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

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

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

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

\(\textbf{secnumdepth}\)

\(\LaTeX{}\) 标准文档类对章节划分了层级:

  • \(\textrm{article}\) 文档类里 \(\textrm{part}\) 为 0,\(\textrm{section}\) 为 1,依此类推;
  • \(\textrm{report}\)\(\textrm{book}\) 文档类里\(\textrm{part}\)为 -1,\(\textrm{chapter}\) 为 0,\(\textrm{section}\) 为 1,等等。

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

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

\(\textrm{secnumdepth}\) 计数器在 \(\textrm{article}\) 文档类里默认为 3(\(\textrm{subsubsection}\) 一级);在 \(\textrm{report}\)\(\textrm{book}\) 文档类里默认为 2(\(\textrm{subsection}\) 一级)。

\(\textbf{tocdepth}\)

\(\texttt{tocdepth}\) 计数器控制目录的深度,如果章节的层级大于 \(\texttt{tocdepth}\),那么章节将不会自动写入目录项。默认值同 \(\textrm{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 $\epsilon $ for class and package writers. CTAN://macros/latex/base/clsguide.pdf (texdoc clsguide) ↩︎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/881012.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024FJ省队集训 - 笔记 游记

Day 0 火车上写了两道可爱小清新数学题。题没写多少bug还一堆。 我们住的是福建省团校,据说是福州有演唱会导致各种酒店房间紧张。 和 wzh,zzp 口胡了一些题目就去睡觉了。 团校的住宿条件确实不错,睡得挺香。 Day 1 T1 提交答案题就是依托美味的构式,你T2T3费劲心思骗个五分…

Stern-Brocot 树

Stern-Brocot 树由两个初始值 \(0\over 1\) 和 \(1\over0\),由两个相邻的数 \(a\over b\) 和 \(c\over d\) 会生成数 \(a + c\over b + d\)。这由图片可以非常直观地看出。形态类似于一棵树。 每个点上有一个"三元组"\((a,b,c)\),\(\left(\dfrac{0}{1},\dfrac{1}{1…

电影解析之虾米解析

我们通常会因为看电影但是需要vip却没有足够生活费去支持的困扰 我就在想有没有白嫖的方法呢(bushi 就在我苦恼的时候我发现了一个方法————就是被称为:解析 的技术这玩意就是最好的选择 但是可能部分人在刚刚接触的时候不会用的于是我就写了一个小软件来支持(只支持wind…

【AI+安全】基于大模型在流量分析领域应用的实践

一、内容概要 随着网络攻击手段的不断进化,流量分析已经成为确保网络安全的关键环节。传统的基于规则和机器学习的方法在一定程度上帮助我们识别和防范攻击,但随着网络攻击形式的多样化和复杂性增加,如何利用更强大的技术手段来分析网络流量,成为了当今网络安全领域的研究热…

RocketMQ实战—7.生产集群部署和生产参数

大纲 1.RocketMQ生产集群部署和生产参数分析 2.RocketMQ生产集群10wTPS压测 3.RocketMQ生产级故障案例1.RocketMQ生产集群部署和生产参数分析 (1)服务器数量 4C8G阿⾥云⾼配服务器共四台,公⽹IP假设如下: 139.224.217.92,106.15.250.248,47.102.152.14,139.224.212.58 (2)…

十二、MyBatis分页插件

十二、MyBatis分页插件@目录十二、分页插件12.1 分页插件使用步骤12.2 分页插件的使用12.3 测试案例本人其他相关文章链接 十二、分页插件 12.1 分页插件使用步骤 1. 添加依赖 <dependency><groupId>com.github.pagehelper</groupId><artifactId>page…

htb Nunchucks walkthrough ssti + shebang绕过apparmor限制

注册发现注册失败扫描子域名 ffuf -u https://nunchucks.htb/ -w /usr/share/dirb/wordlists/common.txt -H "Host: FUZZ.nunchucks.htb" -fs 30589访问看看有啥随便输入个邮箱抓包看看 尝试ssti 注入发现确实存在在hacktrick上搜索payload https://book.hacktricks.…

P1551 亲戚

并查集还是不熟,还得练 #include<iostream> #include<set> #include<map> #include<algorithm> #include<vector> #define int long long const int N = 1e6; using namespace std; char* p1, * p2, buf[100000]; #define nc() (p1==p2 &&a…

推荐一些程序员常逛的开发者社区

前言 在信息技术日新月异的今天,程序员作为推动技术进步的重要力量,始终在探索、学习和交流的道路上不断前行。为了帮助程序员们更好地拓宽视野、提升技能,本文大姚将给大家推荐12个程序员常逛的开发者社区。 GitHub GitHub是一个功能强大、易于使用的代码托管平台。拥有庞大…

为飞牛OS基于FRP的内网穿透开启HTTPS加密

前言 玩NAS的朋友应该有比较多只是在家庭局域网使用,比如日常看看电影、备份手机照片什么的,这属于家庭局域网的使用场景。 当然了,如果你经常出差,或者过年回家不想把NAS也背回去,或者是想上班摸鱼,或者是NAS搭建游戏服务器之类的能公网访问就很有必要了。 公网访问我自…

0208《XEduHub + PySimpleGUI + PySimpleGUIWeb:在行空板上部署模型的全解析》【模型部署】

- 2月8日,晚上,19:30~21:00(主讲老师:邱奕盛)实验内容: 【模型部署】利用统一推理框架实现模型部署。 在训练好的模型基础上,设计简洁的体验界面, 最终尝试在行空板上实现完整效果的呈现,涉及 XEduHub、PySimpleGUI、PySimpleGUIWeb等工具。 import PySimpleGUI as …

DeepSeek 不再卡顿,从此告别服务器繁忙,请稍后再试(建议收藏!)

大家好,我是六哥。 由于DeepSeek真的太火了,也许你也跟我一样,常会遇到这样的情况:真的让人抓狂,10条回复里常常有9条是“服务器blabla,请稍后重试”,看到这话,就问你,谁能不崩溃? 其实仔细想想,DeepSeek的目标是AGI,算力资源更多用在探索模型上,很难兼顾几亿用户…