我正在尝试\l_tmpa_tl
在align
环境中使用。要求是设置变量里面并align
使用&
。当前结果显示x=
等号右侧留空。如果变量在环境之外分配align
,或者&
被省略,它会按预期工作。请问为什么会发生这种情况以及如何修复?
\documentclass{article}
\usepackage{amsmath}
\ExplSyntaxOn
\NewDocumentCommand{\mycmd}{}{
\begin{align}
\tl_set:Nn \l_tmpa_tl {1}
x &=\l_tmpa_tl
\end{align}
}
\ExplSyntaxOff
\begin{document}
\mycmd
\end{document}
答案1
该指令\tl_set:Nn \l_tmpa_tl {xyz}
是任务, 就像\int_incr:N \l_tmpa_int
,\dim_set:Nn \l_tmpa_dim { 1pt }
。
有很多种任务,实际上知道如何expl3
处理它们并不重要。当然,它们最终将通过一种原始的 TeX 任务来完成。
作业可以是全球的或者当地的并且编程指南expl3
非常苛刻,要求变量声明时必须使用g
或l
前缀,以指定变量是用于局部赋值还是全局赋值。但名称只是一个名称,程序员负责使用正确的赋值命令。
上面的前三个例子是当地的作业,但我还要添加一个
\tl_set:Nn \l_tmpa_tl {xyz}
\int_incr:N \l_tmpa_int`
\dim_set:Nn \l_tmpa_dim { 1pt }
\tl_set_eq:NN \l_tmpa_tl \g_tmpb_tl
所有变量都应该在设置之前声明。我添加了最后一个例子来说明全局变量\g_tmpb_tl
可以在局部赋值的上下文中使用:变量\l_tmpa_tl
是本地使等于\g_tmpb_tl
。
相应的全球的任务将是
\tl_gset:Nn \g_tmpa_tl {xyz}
\int_gincr:N \g_tmpa_int`
\dim_gset:Nn \g_tmpa_dim { 1pt }
\tl_gset_eq:NN \g_tmpa_tl \g_tmpb_tl
但问题仍然存在:有什么区别?
局部赋值只会影响当前组中变量的值,当组结束时,该值将重置为上一个值。全局赋值不会发生这种情况:该值将在所有组级别设置。
什么是组?这需要一些 TeX 基本概念的知识。组可以以 开始,{
并以匹配项结束}
(但 TeX 查找宏的参数时除外);或以 开始,并以匹配项结束(即);或以 开始\group_begin:
,以匹配项结束(或,基本上实现为)。\begingroup
\group_end:
\endgroup
\left
\right
\middle
\right.\left
LaTeX 环境以 开头,\begin
将发出\group_begin:
;相应的\end
发出匹配的\group_end:
,这就是 LaTeX 环境形成组的原因。
但团体也是在其他情况下发起的,最重要的是盒子。当你开始收集材料放在一个框中时,无论是还是\hbox:n
,但当 和 类似函数时,TeX 将打开一个组,当扫描到集合结束时结束它。所以用\vbox:n
\vtop:n
\hbox_set:Nn
}
\tl_set:Nn \l_tmpa_tl {a}
\hbox:n { \tl_set:Nn \l_tmpa_tl {b} \tl_use:N \l_tmpa_tl }
\tl_use:N \l_tmpa_tl
你会得到“ba”。在框内,标记列表变量设置为“b”,但当框结束时,会恢复先前的值。相反,使用
\tl_gset:Nn \g_tmpa_tl {a}
\hbox:n { \tl_gset:Nn \g_tmpa_tl {b} \tl_use:N \g_tmpa_tl }
\tl_use:N \g_tmpa_tl
你会得到“bb”,因为框内的分配是全局的。
但这和你的问题有什么关系呢?它与比对有关。你可以认为,当 TeX 为比对中的单元格收集材料时(无论是、、、、等等tabular
),它会执行一个特殊操作array
align
split
aligned
cases
\hbox_set_ALIGNMENT:n { ... }
不,没有这样的函数:真正的函数对用户来说是不可访问的,并且只在排版的深层 TeX 级别可用。虚构的名字只是为了强调这一点每个对齐单元位于群组内部。
\begin{align}
现在您知道问题出在哪里了: up to之后的材料&
位于一个组内,\tl_set:Nn \l_tmpa_tl {1}
一旦&
扫描并构建对齐框,就会忘记分配。
附加位
声明变量也是一种赋值。例如
\tl_new:N \l_jumaily_foo_tl
\int_const:Nn \c_jumaily_foo_int { 42 }
你可以把前者想象成创建一个指针到变量。指针和变量都是创建的全球,因此在第一次声明之后,标记列表变量\l_jumaily_foo_tl
将在所有级别可用,但对其赋值应该是局部的。第二条指令全局创建常量并全局为其赋值。
答案2
你的问题是:为什么&
会破坏这种模式?答案就在这里。
对齐环境基于\halign
TeX 基元。 的数据部分\halign
(以 分隔&
)中的每个项目都被打包到 TeX 组中\hbox
并打开 TeX 组,读取水平列表并关闭 TeX 组。这就是为什么之间的每个部分都在单个组中处理的\hbox
原因。每个分配(包括除了基元之外的其他分配)都是本地的,即值仅在组的范围内设置。&
\tl_set:Nn
\def
请注意,\tl_gset:Nn
等于\gdef
原始的,并且此分配是全局的,与组无关。
答案3
像这样吗?
\documentclass{article}
\usepackage{amsmath}
\ExplSyntaxOn
\NewDocumentCommand{\mycmd}{}{
\begin{align}
\tl_gset:Nn \g_tmpa_tl {1+k^2}
x &= \tl_use:N \g_tmpa_tl
\end{align}
}
\ExplSyntaxOff
\begin{document}
\mycmd
\end{document}