假设我想生成一个节点矩阵:
\documentclass{article}
\usepackage{expl3}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
\matrix
[
row sep=2mm,
] (matr)
{
\node[draw] (1) {1};\\
\node[draw] (2) {2};\\
\node[draw] (3) {3};\\
};
\end{tikzpicture}
\end{document}
我尝试使用 expl3for
循环来做到这一点:
\documentclass{article}
\usepackage{expl3}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
\matrix
[
row sep=2mm,
] (matr)
{
\ExplSyntaxOn
\tl_new:N \l__text_tl
\int_step_inline:nnnn { 1 } { 1 } { 3 }
{
\tl_put_right:Nn \l__text_tl {\node[draw] (#1) {#1};\\}
}
\l__text_tl
\ExplSyntaxOff
};
\end{tikzpicture}
\end{document}
编译器失败并显示以下消息:
! Missing } inserted. <inserted text>
}
l.21 \end{tikzpicture}
答案1
您不能在另一个命令的参数中更改 catcode,因此
\documentclass{article}
\usepackage{expl3}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\ExplSyntaxOn
\tl_new:N \l__text_tl
\int_step_inline:nnnn { 1 } { 1 } { 3 }
{
\tl_put_right:Nn \l__text_tl {\node[draw] (#1) {#1};\\}
}
\let\foo\l__text_tl
\ExplSyntaxOff
\begin{tikzpicture}
\matrix
[
row sep=2mm,
] (matr)
{
\foo
};
\end{tikzpicture}
\end{document}
这是 TeX 对文件字符进行标记方式的基本限制,,,\verb
都有\makeatletter
必须\ExplSyntaxOn
在顶层使用的限制。
答案2
这主要的需要注意的是,该expl3
语言从未打算用于文档级别,就像 LaTeX2e 的内部结构(@
其名称中包含)不应该出现在那里一样。相反,这些语言是为了支持软件包开发而开发的。
因此,在 LaTeX2e 包中,LaTeX2e 的约定会自动设置(基本上@
是一封信),而在 LaTeX3 包中,LaTeX3 的约定会自动启用。
然而,有时需要添加/更新代码在文件序言中并认识到这一点,LaTeX2e 提供\makeatletter
和,\makeatother
而 LaTeX3/expl3 提供\ExplSyntaxOn
和\ExplSyntaxOff
。但那些是供序言使用的,通常最好将此类代码放入包中,然后可以重复使用。
因此,您可以考虑提供一个命令来为您完成必要的工作,例如,\boxednumbers
它可以完成包括矩阵命令在内的所有工作,例如,
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usepackage{xparse}
\ExplSyntaxOn
\tl_new:N \l__text_tl
\NewDocumentCommand\boxednumbers{ O{2mm} m }
{
\tl_clear:N\l__text_tl
\int_step_inline:nnnn { 1 } { 1 } { #2 }
{ \tl_put_right:Nn \l__text_tl {\node[draw] (##1) {##1}; \\ } }
\matrix [row~ sep=#1] (matr)
{
\l__text_tl
};
}
\ExplSyntaxOff
\begin{document}
\begin{tikzpicture} \boxednumbers{5}; \end{tikzpicture}
\begin{tikzpicture} \boxednumbers[5mm]{3}; \end{tikzpicture}
\end{document}
这里有一个需要注意的重要点:
tikz
是在 2e 条件下设计的,它不知道expl3
惯例。
因此,tikz
在代码中间执行解析命令expl3
可能会引起麻烦,这就是为什么我们不能简单地\node
在循环中执行,而是构建一行代码以便稍后执行。出于同样的原因,我不得不说,row~ sep
而不是row sep
因为代码中的正常空间消失了expl3
。所以总而言之,2e 代码的混合搭配expl3
在某些地方有点棘手。