可扩展性:LaTeX3 VS LaTeX

可扩展性:LaTeX3 VS LaTeX

可扩展性是宏/函数的核心。我想知道:

  1. 如果LaTeX3只有通过对 的可扩展性的良好了解才能更好地理解 的可扩展性LaTeX,那么它们在多大程度上可以被视为独立的?
  2. 更准确地说,如果 提供的功能l3expan足以满足所有可扩展性需求。换句话说,在 内LaTeX3,支持“LaTeX可扩展性”,但可以完全替換的。
  3. 有没有办法在执行可扩展性过程时检查中间的步骤(即一些输出文件、分析选项等)

答案1

expl3我自己没有这样做过,我认为对于一个新的 LaTeX 程序员来说,从加载定义的函数(也称为 LaTeX3 内核,或l3kernel)开始比先学习基本的 TeX 编程然后再升级要容易得多。

这样做的原因是它为expl3您提供了一个非常出色、功能强大且内部一致的抽象层。使用 TeX 编程,您很快就必须学习“技巧”来完成相当简单的事情。

例如,如果你正在讨论两个命令\foo\baz,为了复制\foo\baz写的

\let\foo\baz

但是如果你需要通过名称而不是控制序列来引用它们怎么办?例如,你可能定义一些东西来做这样的事情:

\defineacronym{baz}{BAZ}
\useacronym{baz} % => \textsc{\MakeLowercase{BAZ}}

这可以定义为

\makeatletter
\newcommand\defineacronym[2]{%
  \@namedef{acronym@#1}{\textsc{\MakeLowercase{BAZ}}}%
}
\newcommand\useacronym[1]{%
  \@nameuse{acronym@#1}%
}
\makeatother

到目前为止一切顺利。但要定义像这样的命令\copyacronym{foo}{baz},你必须这样写:

\newcommand\copyacronym[2]{%
  \expandafter\let\csname acronym@#1\expandafter\endcsname\csname acronym@#2\endcsname
}

对于经验丰富的 TeX 程序员来说,这很容易理解,但对于新手来说,就不太好了。

可以expl3写成:

\ExplSyntaxOn
\newcommand\copyacronym[2]{
  \cs_set_eq:cc {acronym@#1} {acronym@#2}
}
\ExplSyntaxOff

的目标expl3是让 TeX 编程更加结构化,从而更加容易。我们希望对于新 TeX 程序员来说,这种情况比对于老 TeX 程序员来说更严重。


对于你的最后一个问题,答案是有点。 Bruno Le Floch 编写了这个unravel软件包,它肯定可以向你展示扩展的情况。在编写之后

\usepackage{unravel}
\def\baz{BAZ}
\unravel{\expandafter\let\csname foo\expandafter\endcsname\csname baz\endcsname}

它返回以下内容:

======== Welcome to the unravel package ========
    "<|" denotes the output to TeX's stomach.
    "||" denotes tokens waiting to be used.
    "|>" denotes tokens that we will act on.
    Press <enter> to continue; 'h' <enter> for help.

|| 
|> \expandafter \let \csname foo\expandafter \endcsname \csname baz\endcsname 

[===== Step 1 =====] \expandafter \let 

[===== Step 2 =====] \csname = \csname
|| \expandafter \let 
|| \csname 
|> foo\expandafter \endcsname \csname baz\endcsname 

[===== Step 3 =====] \expandafter \endcsname 
|| \expandafter \let 
|| \csname foo
|| \expandafter \endcsname 
|> \csname baz\endcsname 

[===== Step 4 =====] \csname = \csname
|| \expandafter \let 
|| \csname foo
|| \expandafter \endcsname 
|| \csname 
|> baz\endcsname 

[===== Step 5 =====] \endcsname 
|| \expandafter \let 
|| \csname foo
|| \expandafter \endcsname 
|| \csname baz\endcsname 
|> 

[===== Step 6 =====] \csname baz\endcsname =\baz 
|| \expandafter \let 
|| \csname foo
|| \expandafter \endcsname 
|> \baz 

[===== Step 7 =====] back_input: \expandafter \endcsname 
|| \expandafter \let 
|| \csname foo
|> \endcsname \baz 

[===== Step 8 =====] \endcsname 
|| \expandafter \let 
|| \csname foo\endcsname 
|> \baz 

[===== Step 9 =====] \csname foo\endcsname =\foo 
|| \expandafter \let 
|> \foo \baz 

[===== Step 10 =====] back_input: \expandafter \let 
|| 
|> \let \foo \baz 

[===== Step 11 =====] \let \foo 
|| \let \foo 
|> \baz 

[===== Step 12 =====] Set \foo=macro:->BAZ
|| 
|> 

[===== End =====]

正如您所见,即使是一个简单的案例,它也给您带来了很多困惑。(虽然容易理解,但仍然如此。)尤其是expl3作为新用户进行调试时,这可能仅在某些情况下有用。

相关内容