在 LaTeX tikz 库“fadings”中,有一个名为 \tikzfading 的函数,允许定义自定义淡入淡出样式。例如,以下是一个 MWE,显示一条线从 (0,0) 向 8 个罗盘方向淡出:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fadings}
\tikzfading[name=myfade, outer color=transparent!100, inner color=transparent!0]
\begin{document}
\begin{tikzpicture}
\coordinate (A) at (0,0);
\foreach \theta in {0,...,7} {
\coordinate (B) at ({cos(45*\theta)},{sin(45*\theta)});
\draw[path fading=myfade, fit fading=false] (A) -- (B);
}
\end{tikzpicture}
\end{document}
代码编译后的结果如下:
现在,对于我的问题,我在将上述构造与 expl3 结合时遇到了麻烦。假设我想定义一个绘制上述图表的函数,但也允许用户将可选的附加选项传递给 tikz 淡入淡出样式。我的想法是创建一个名为 \set_fade:n 的函数,该函数通过按顺序存储用户指定的选项以及上述内部和外部选项来创建 tikz 淡入淡出样式,然后创建一个 tl 变量,其值是扩展序列,然后在淡入淡出样式的定义中使用该 tl。然后,我们可以创建一个带有可选参数的文档命令,如果用户未指定任何选项,则首先使用空的 {} 参数调用 \set_fade:n,如果用户指定了,则调用 \set_fade:n {#1}。然后函数 \foo 可以继续使用原始 MWE。如果我们这样做,我们会得到类似的东西:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fadings}
\ExplSyntaxOn
\cs_new:Npn \set_fade:n #1 {
\seq_clear:N \l_tmpa_seq
\seq_set_from_clist:Nn \l_tmpa_seq {#1}
\seq_put_left:Nn \l_tmpa_seq {inner~color=transparent!0}
\seq_put_left:Nn \l_tmpa_seq {outer~color=transparent!100}
\tl_set:Nx \l_tmpa_tl {\seq_use:Nn \l_tmpa_seq {,}}
\tikzfading[name=myfade, \l_tmpa_tl]
}
\NewDocumentCommand\foo{o}{
\IfNoValueTF{#1}{\set_fade:n {}}{\set_fade:n {#1}}
\begin{tikzpicture}
\coordinate (A) at (0,0);
\foreach \theta in {0,...,7} {
\coordinate (B) at ({cos(45*\theta)},{sin(45*\theta)});
\draw[path~fading=myfade, fit~fading=false] (A) -- (B);
}
\end{tikzpicture}
}
\ExplSyntaxOff
\begin{document}
\foo
\end{document}
但是,此代码无法正确编译。抛出的主要错误是
Package xcolor Error: Undefined color `outer color=transparent'.
经过一番阅读,我发现错误是由于 expl3 对 tl \l_tmpa_tl 值中的 ! 字符的解释方式造成的。如果我在 \l_tmpa_tl 上使用 \tl_show:N,我会得到正确的字符串:“outer color=transparent!100,inner color=transparent!0”,但似乎当我将 tl 输入 \tikzfading 时,\l_tmpa_tl 的扩展会在感叹号处停止,从而导致结果序列 \tikzfading[name=myfade,outer~color=transparent],这解释了错误。
我想象我需要对感叹号进行某种字符类控制,但我似乎找不到正确的方法来做到这一点。所以我的问题是:
- 这大致就是处理此类事情的正确想法吗?
- 如果没有,我还应该怎样尝试?
- 如果是,我该如何正确处理这个感叹号字符?
我找到了一个潜在的解决方案。如果我将 \set_fade:n 的定义更改为
\cs_new:Npn \set_fade:n #1 {
\seq_clear:N \l_tmpa_seq
\seq_set_from_clist:Nn \l_tmpa_seq {#1}
\seq_put_left:Nn \l_tmpa_seq {inner~color=transparent! 0}
\seq_put_left:Nn \l_tmpa_seq {outer~color=transparent! 100}
\seq_put_left:Nn \l_tmpa_seq {name=myfade}
\tl_set:Nx \l_tmpa_tl {\seq_use:Nn \l_tmpa_seq {,}}
\exp_args:NNV \tikzfading[ \l_tmpa_tl ]
}
那么整个事情现在就可以正常工作了。有人能向我解释一下为什么吗?这是最佳解决方案吗?