编写LaTeX宏包实现适合自己工作的特殊功能是一项极其重要的工作,在创建宏包时使用LaTeX2e语法和LaTeX3语法的风格并不相同,本文介绍两种语法。
LaTeX2e 语法创建宏包选项
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| \NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mypackage}[2024/01/01 v1.0 My Package]
% 布尔选项
\newif\ifmypackage@draft
\newif\ifmypackage@final
% 键值选项
\newcommand\mypackage@size{10pt}
\newcommand\mypackage@font{times}
% 声明选项
\DeclareOption{draft}{\mypackage@drafttrue}
\DeclareOption{final}{\mypackage@finaltrue}
\DeclareOption{11pt}{\renewcommand\mypackage@size{11pt}}
\DeclareOption{12pt}{\renewcommand\mypackage@size{12pt}}
\DeclareOption{times}{\renewcommand\mypackage@font{times}}
\DeclareOption{helvet}{\renewcommand\mypackage@font{helvet}}
% 未知选项传递给 article 类
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
% 处理选项
\ProcessOptions\relax
% 加载基础类
\LoadClass[\mypackage@size]{article}
% 根据选项执行操作
\ifmypackage@draft
\usepackage{draftwatermark}
\fi
|
LaTeX3 语法创建宏包选项
使用 l3keys 模块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| \RequirePackage{expl3}
\ProvidesExplPackage{mypackage}{2024/01/01}{1.0}{My Package}
% 定义键
\keys_define:nn { mypackage }
{
draft .bool_set:N = \l_mypackage_draft_bool,
draft .initial:n = false,
draft .default:n = false,
size .choices:nn =
{ 10pt, 11pt, 12pt }
{ \tl_set:Nn \l_mypackage_size_tl {#1} },
size .initial:n = 10pt,
font .tl_set:N = \l_mypackage_font_tl,
font .initial:n = times,
% 带代码的键
fancy .code:n =
{ \bool_set_true:N \l_mypackage_fancy_bool },
% 未知选项处理
unknown .code:n =
{ \msg_warning:nnn { mypackage } { unknown-option } { \l_keys_key_str } },
}
% 处理包选项
\ProcessKeysOptions { mypackage }
% 使用选项值
\bool_if:NT \l_mypackage_draft_bool
{
\RequirePackage{draftwatermark}
}
\tl_case:Nn \l_mypackage_font_tl
{
{times} { \RequirePackage{times} }
{helvet} { \RequirePackage{helvet} }
}
|
复杂键的定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
| \keys_define:nn { mypackage }
{
% 布尔键
show-answers .bool_set:N = \l_mypackage_show_answers_bool,
show-answers .initial:n = false,
% 选择键
mode .choice:,
mode / draft .code:n =
{ \bool_set_true:N \l_mypackage_draft_bool },
mode / final .code:n =
{ \bool_set_false:N \l_mypackage_draft_bool },
mode .initial:n = final,
% 带参数的键
width .dim_set:N = \l_mypackage_width_dim,
width .initial:n = 5cm,
width .min_dim_set:N = \c_zero_dim,
width .max_dim_set:N = \c_max_dim,
% 元键(meta key)
setup .meta:nn = { mypackage }
{ draft = true, width = 3cm },
}
% 处理类选项
\keys_define:nn { mypackage }
{
% 类选项传递
unknown .code:n =
{ \PassOptionsToClass { \l_keys_key_str } { article } },
}
\ProcessKeysPackageOptions { mypackage }
|
混合使用两种语法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| \RequirePackage{expl3}
\RequirePackage{xparse}
\ProvidesPackage{mypackage}[2024/01/01 v1.0]
\ExplSyntaxOn
% LaTeX3 键值定义
\keys_define:nn { mypackage }
{
option1 .bool_set:N = \l_mypackage_opt_one_bool,
option2 .tl_set:N = \l_mypackage_opt_two_tl,
}
% 处理选项
\ProcessKeysOptions { mypackage }
\ExplSyntaxOff
% 传统 LaTeX2e 代码
\ifdefined\l_mypackage_opt_one_bool
% 使用 LaTeX3 变量
\fi
|
注意:混合使用时需要调用expl3宏包,即
1
2
3
4
5
6
| % 在导言区加载 expl3
\RequirePackage{expl3}
\ExplSyntaxOn
% LaTeX3 代码
\ExplSyntaxOff
% 传统 LaTeX2e 代码
|
说明
两种语法都可以有效处理宏包选项,选择哪种取决于项目需求和个人偏好。LaTeX3 语法提供了更现代、更安全的编程范式,特别适合复杂的配置系统。