LaTeX3 系列教程之二:基本语法一

文摘   2025-01-08 21:32   浙江  
点击👇LaTeX工作室” 关注公众号
精致美好科研生活从 LaTeX 开始!


一、注释与空白

LaTeX3 仍以 % 为注释符,% 至行未的所有内容都会被忽略。dtx 格式注释规则较复杂,但规则仍与 LaTeX2e 一样。

除了少量殊情况外,LaTeX3忽略所有空白(包括空格、制表、换行符等)。而 ~ 和 '\ ' 可以用来生成空白,不会被忽略(行首除外)。

如下示例:

\documentclass{article}
\begin{document}
\ExplSyntaxOn

\cs_new:Npn\my_funa:nn#1 #2

  {    #1    #2    #1    }

\my_funa:nn{ Hello World! }{~}{ Hello World! }

\ExplSyntaxOff
\end{document}

等效于:

\documentclass{article}
\begin{document}
\ExplSyntaxOn
\cs_new:Npn \my_funa:nn #1#2
  { #1 #2 #1 }
\my_funa:nn { Hello World! } { ~ }
{ Hello World! }
\ExplSyntaxOff
\end{document}

将输出:HelloWorld! HelloWorld!HelloWorld!。(接下来的内容解释原因)

二、函数

LaTeX3 内置了一系列的预定义函数,同时还支持用户自定义新函数。

函数是简单的带参或不带参宏,函数会展开(Expand)则为置换文本(Replacement Text)。

2.1 特殊的函数

LaTeX3 预定义的函数中,几乎大部分都符合上一节介绍的命名规则。但因功能需要,还是有少量的函数不符合命名规则。所幸,这些函数并不多,而且很容易识别。

前面介绍的\ExplSyntaxOn\ExplSyntaxOff就是两个典型的例子。更多的函数将在后续章节中介绍。

启用与禁用 L3 语法

由于 L3 使用了 _: 符号来提供结构,这与 LaTeX2e 本身的语法不兼容。所有要使用 L3 语法时,必须先用\ExplSyntaxOn 来启用;而要用恢复 LaTeX2e 语法时,则需要使用 \ExplSyntaxOff 来禁用。

(如果你写过 LaTeX2e 宏包,可以把它们看作和\makeatletter\makeatother 的功能“类似”。)

后面讲解示例时,不再解释这两个命令了。

2.2 参数

函数可以带参数,也可以不带参数。使用标准命名规则的函数,其参数会由参数说明符指示出来,包含参数数量及参数类型等。

在函数定义时,可以使用 #1#2 等符号来引用参数(其它语言中的形参)。LaTeX3 最多支持 9 个参数。

在执行(展开)函数时,会从函数后面的输入流中吸收参数(其它语言中的实参),并按顺序被传递给函数。

2.3 使用已有函数

在示例中,首先使用了\cs_new:Npn函数来定义一个新函数,它需要三个参数:函数名(N)、函数参数(p)和置换文本(n)。

实际执行时,会按如下方式传递参数:

  1. \my_funa:nn 传递给第一个参数(N类型,吸收一个凭据);
  2. #1#2 传递给第二个参数(p类型,吸收一个参数列表);
  3. { #1 #2 #1 } 传递给第三个参数(n类型,吸收一个凭据表)。

这个函数只起声明函数的作用,并不会输出任何内容。

接下来,使用了\my_funa:nn函数,它会按如下方式传递参数:

  1. { Hello World! } 传递给第一个参数(n类型,#1);
  2. { ~ } 传递给第二个参数(n类型,#2)。

这个函数将输出HelloWorld! HelloWorld!。(原理见下一节)

最后,还直接使用了{ Hello World! },它和 LaTeX2e 一样,直接输出HelloWorld!

上面三个命令的的最终输出结果为:HelloWorld! HelloWorld!HelloWorld!。请注意,第2个感叹号后面是没有空白的。

从上面两个函数的使用中可以看出,

  1. N类型参数会吸收一个凭据(不被{} 包裹的单个内容);
  2. n类型参数会吸收一个凭据表(由 {} 包裹的多个内容)。

这里大概理解就行,后面会有更精确的定义。

2.4 定义新的函数

如前面所介绍的,\cs_new:Npn函数用于定义新的函数。\cs_new:Npn函数有三个参数:

参数1:用于指定新函数的名称;

在本例中,它定义的函数名为\my_funa:nn,这个函数名中的签名为nn,表示这个新函数将接收两个参数,且参数类型均为凭据表。

参数2:用于指定新函数使用的参数列表;

在本例中,新的函数的使用的参数为#1#2,表明这个新函数接收的两个参数分别用#1#2表示。

参数3:用于指定新函数的函数体(它的内容就是前面讲的置换文本)。

在本例中,函数体为{ #1 #2 #1 },表明函数将被替换为“由参数2分隔的两个参数1”。即由{ ~ } 分隔的两个{ Hello World! }

前面讲到,空白会被忽略,所以输出结果中HelloWorld!不会有任何空白,而它们之间会有一个空白(由~产生)。所以最终生成HelloWorld! HelloWorld!

2.5 定义新函数时推断参数列表

由于函数名本身指示了其使用的参数,因此可以推断出其使用的参数。所以可以考虑省略参数列表。

为此,expl3 提供了\cs_new:Nn函数,它与\cs_new:Npn函数类似,但它只接收两个参数:

  1. 用于指定新函数的名称;
  2. 用于指定新函数的函数体。

2.6 定义无参函数

对于无参函数,其参数限定符应为空(但: 不应省略)。除了不使用参数外,其余规则与有参函数一样。

2.7 【补更】LaTeX3 函数与 LaTeX2e 函数(命令)

在 LaTeX3 中,定义函数时要考虑新函数的目标用户:

  • 如果函数是给LaTeX3用户使用,则函数名应当遵守 LaTeX3 的命名规则,即上篇所介绍的规则;
  • 如果函数是给LaTeX2e用户使用,则函数名应当遵守 LaTeX2e的命名规则(以便在LaTeX2e环境中直接使用)。

注:

  1. 除特别注明外,本教程介绍的定义函数的方法都是 LaTeX3 函数。
  2. \cs_new:Npn 函数可以用于定义 LaTeX2e 命令,即其第一个参数可以不遵守L3命名规则。但推荐使用后面介绍的 \NewDocumentCommand 等命令来创建 LaTeX2e 命令。
  3. 上一小节所讲,无参函数的":"不能省略仅针对 LaTeX3 函数。
  4. 定义函数的方法还很多,这些将在后续的内容介绍。

选自:https://zhuanlan.zhihu.com/p/10992221850



点击👇LaTeX工作室” 关注公众号
从 LaTeX 开始即刻享受科研精致美好生活
 关注公众号回复1进本硕博脱单群

成为 LaTeX 会员,尽享精致科研!

开通 LaTeX VIP 地址:

https://www.latexstudio.net/index/recharge/choice.html


LaTeX工作室
精致科研生活从 LaTeX 开始! 模版定制 | 培训 | 排版 | 答疑 加VX:t314159265
 最新文章