当 V 扩展不可用时,我们可以安全地使用 o 扩展吗?

当 V 扩展不可用时,我们可以安全地使用 o 扩展吗?

例如\exp_args:Nxo可用但 不可用\exp_args:NxV。我们可以安全地使用前者代替后者吗?

答案1

不,它们并不相同,即使在某些情况下它们确实会产生相同的结果。

\documentclass{article}

\ExplSyntaxOn

\tl_new:N \l_jl_test_tl
\int_new:N \l_jl_test_int

\tl_set:Nn \l_jl_test_tl { tokens }
\int_set:Nn \l_jl_test_int { 42 }

\exp_args_generate:n { xV }

\ExplSyntaxOff

\begin{document}

\ExplSyntaxOn

\exp_args:NxV \use_ii:nn { whatever } \l_jl_test_tl

\par

\exp_args:NxV \use_ii:nn { whatever } \l_jl_test_int

\par

\exp_args:Nxo \use_ii:nn { whatever } { \l_jl_test_tl }

\par

\exp_args:Nxo \use_ii:nn { whatever } { \l_jl_test_int }

\ExplSyntaxOff

\end{document}

在此处输入图片描述

你发现问题了吗?

您还会看到,如果某些\exp_args:N...组合不是现成的,您可以非常简单地生成它。

请注意一个o论点应该需要支撑,相反,V参数则不需要。TeX 可能无论如何都会做“正确”的事情,但这一事实无关紧要。

另一方面,很多\exp_args:N...当这种情况不止一次发生时,最好避免使用,实际上建议不要使用。如果您觉得有必要使用\exp_args:NxV,那么很可能您想定义合适的函数变体。

答案2

问题不在于和是否o等价V,显然情况并非如此,问题在于是否可以用来模拟Vo答案是肯定的,正如文档interface3.pdf(第 3 页)所建议的那样,但其中存在微妙之处。V参数说明符获取变量的内容,但事情取决于变量。

我们可以对变量进行分类

  1. 类似变量的标记列表:tl、str、seq、clist、prop、fp
  2. 类似 int 的变量:int、dim、skip、muskip
  3. 夸克
  4. intarray、fparray、cctab

对于类别 1 和 3,\foo:V <variable>替换为\foo:o { <variable> } 对于类别 2,\foo:V <variable>替换为\foo:o { \<type>_use:N <variable> } 对于类别 4,变量不适合作为参数V

int、dim、skip、muskip 的演示

\MyTest:nn如果两个参数作为标记列表相等,则打印 SUCCESS,否则打印 FAILURE。

% !TeX program = lualatex
\documentclass{article}
\begin{document}
\noindent
\ExplSyntaxOn
\cs_new:Nn \MyTest:nn {
  \tl_if_eq:nnTF { #1 } { #2 } { SUCCESS } { FAILURE } \\
}
\cs_generate_variant:Nn \MyTest:nn { Vo }

\int_set:Nn \l_tmpa_int { 1234 }
\MyTest:Vo \l_tmpa_int { \int_use:N \l_tmpa_int }

\dim_set:Nn \l_tmpa_dim { 1234pt }
\MyTest:Vo \l_tmpa_dim { \dim_use:N \l_tmpa_dim }

\skip_set:Nn \l_tmpa_skip { 1234pt plus 1cm minus 2mm }
\MyTest:Vo \l_tmpa_skip { \skip_use:N \l_tmpa_skip }

\muskip_set:Nn \l_tmpa_muskip { 1234mu }
\MyTest:Vo \l_tmpa_muskip { \muskip_use:N \l_tmpa_muskip }
\end{document}

tl、str、seq、clist、prop、fp 和 quark 的演示

对于\MyTest:Nn,#1 设置\My_var#2\MyTest:Vo使用适当的参数调用。

% !TeX program = lualatex
\documentclass{article}
\begin{document}
\noindent
\ExplSyntaxOn
\cs_new:Nn \MyTest:nn {
  \tl_if_eq:nnTF { #1 } { #2 } { SUCCESS } { FAILURE } \\
}
\cs_generate_variant:Nn \MyTest:nn { Vo }
\cs_new:Nn \MyTest:Nn {
  #1 \My_var { #2 }
  \MyTest:Vo \My_var { \My_var }
}
\MyTest:Nn \tl_set:Nn { \def\My#1{#1#1} }
\MyTest:Nn \str_set:Nn { \def\My#1{#1#1} }
\MyTest:Nn \seq_set_from_clist:Nn { \def, \My, #1, {#1#1} }
\MyTest:Nn \clist_set:Nn{ \def, \My, #1, {#1#1} }
\MyTest:Nn \prop_set_from_keyval:Nn {
  \def = \My,
  #1 = {#1#1},
}
\MyTest:Nn \fp_set:Nn { 3.14159 }
\quark_new:N \q_My
\MyTest:Vo \q_My { \q_My }
\end{document}

不太做作的例子

这说明了什么是可能的,但是不应该在生产代码中使用,因为它使用了不受支持的功能。

这里我们定义\foo:n从其参数构建属性列表,假设它是属性列表变量的原始内容并打印出项目。然后我们生成“o”和“V”变体以最终测试\foo:o\foo:V

% !TeX program = lualatex
\documentclass{article}
\begin{document}
\noindent
\ExplSyntaxOn
\cs_new:Nn \foo:n {
  \tl_set:Nn \l_tmpb_prop { #1 }
  \prop_map_inline:Nn \l_tmpb_prop {
    ##1$\to$##2\\
  }
}
\cs_generate_variant:Nn \foo:n { o, V }
\prop_set_from_keyval:Nn \l_tmpa_prop {
  KEY1=VALUE1,
  KEY2=VALUE2,
}
\foo:V \l_tmpa_prop
\prop_set_from_keyval:Nn \l_tmpa_prop {
  key1=value1,
  key2=value2,
}
\foo:o { \l_tmpa_prop }
\ExplSyntaxOff
\end{document}

它安全吗?

对于短时间使用来说,这是可以的,但对于部署代码来说,这绝对不行。如果 LaTeX 内部发生变化,这可能会在将来中断。

相关内容