下面的代码解析出参数的逗号分隔位,然后将该位作为标记列表变量传递给函数。它通过使用 来工作\exp_args:Neee
,但我怀疑有更好的方法。
\documentclass[10pt]{article}
\ExplSyntaxOn
\NewDocumentEnvironment{intfig} {
> { \SplitArgument { 1 } { , } } m O{} }
{
\group_begin:
% Certain things are hard to do using a clist, so it's held as a seq too.
\clist_set:Nn \l_intfig_optclist_clist { #2 }
\seq_set_from_clist:NN \l_intfig_optseq_seq { \l_intfig_optclist_clist }
% The first of the optional arguments might be a length.
\seq_get_left:NN \l_intfig_optseq_seq \l_intfig_firstvalue_tl
\exp_args:Neee \iflengthTF \l_intfig_firstvalue_tl {TRUE}{FALSE} \\
\group_end:
}{}
% Taken from
% https://tex.stackexchange.com/questions/498976/testing-for-a-length
\NewDocumentCommand{\iflengthTF}{mmm}
{
will\ regexp\ #1 \\
\regex_match:nnTF
{ \A [+\-]? ((\d+(\.\d*)?)|(\.\d+)) \s* (pt|pc|in|bp|cm|mm|dd|cc|sp|ex|em) \Z} % regex
{ #1 } % test string
{ #2 } % true text
{ #3 } % false text
}
\ExplSyntaxOff
\begin{document}
\begin{intfig}{blather,1.2in}[14pt,more,another]
random body
\end{intfig}
\end{document}
诚然,我对这里发生的事情的理解有限,但 中有一个标记列表变量\l_int_fig_firstvalue_tl
。该变量不能按原样传递给 ,\iflengthTF
因为它是“未展开的”,如果这是正确的术语(它是装箱的或包装的或伪指针)。
使用\exp_args:Neee
扩展参数可以解决问题,但有没有更直接的方法将变量转换为其内容?
答案1
您应该定义自己的条件及其变体,而不是使用文档级命令。
\documentclass[10pt]{article}
\ExplSyntaxOn
\NewDocumentEnvironment{intfig} { > { \SplitArgument { 1 } { , } } m O{} }
{
% Certain things are hard to do using a clist, so it's held as a seq too.
\clist_set:Nn \l_intfig_optclist_clist { #2 }
\seq_set_from_clist:Nn \l_intfig_optseq_seq { #2 }
% The first of the optional arguments might be a length.
\seq_get_left:NN \l_intfig_optseq_seq \l_intfig_firstvalue_tl
\intfig_if_length:VTF \l_intfig_firstvalue_tl {TRUE}{FALSE} \\
}
{}
% Taken from
% https://tex.stackexchange.com/questions/498976/testing-for-a-length
\prg_new_protected_conditional:Nnn \intfig_if_length:n { T, F, TF }
{
\regex_match:nnTF
{ \A [+\-]? ((\d+(\.\d*)?)|(\.\d+)) \s* (pt|pc|in|bp|cm|mm|dd|cc|sp|ex|em) \Z} % regex
{ #1 } % test string
{ \prg_return_true: }
{ \prg_return_false: }
}
\prg_generate_conditional_variant:Nnn \intfig_if_length:n { V } { T, F, TF }
\ExplSyntaxOff
\begin{document}
\begin{intfig}{blather,1.2in}[14pt,more,another]
random body
\end{intfig}
\begin{intfig}{blather,1.2in}[oops,more,another]
random body
\end{intfig}
\end{document}
使用稍微不同的方法可以得到相同的结果,直接使用#2
via\clist_item:nn
和e
-expansion 来进行条件检查:
\documentclass[10pt]{article}
\ExplSyntaxOn
\NewDocumentEnvironment{intfig} { > { \SplitArgument { 1 } { , } } m O{} }
{
% Certain things are hard to do using a clist, so it's held as a seq too.
%\clist_set:Nn \l_intfig_optclist_clist { #2 }
%\seq_set_from_clist:Nn \l_intfig_optseq_seq { #2 }
\intfig_if_length:eTF { \clist_item:nn { #2 } { 1 } } {TRUE}{FALSE} \\
}
{}
% Taken from
% https://tex.stackexchange.com/questions/498976/testing-for-a-length
\prg_new_conditional:Nnn \intfig_if_length:n { T, F, TF }
{
\regex_match:nnTF
{ \A [+\-]? ((\d+(\.\d*)?)|(\.\d+)) \s* (pt|pc|in|bp|cm|mm|dd|cc|sp|ex|em) \Z} % regex
{ #1 } % test string
{ \prg_return_true: }
{ \prg_return_false: }
}
\prg_generate_conditional_variant:Nnn \intfig_if_length:n { V,e } { T, F, TF }
\ExplSyntaxOff
\begin{document}
\begin{intfig}{blather,1.2in}[14pt,more,another]
random body
\end{intfig}
\begin{intfig}{blather,1.2in}[oops,more,another]
random body
\end{intfig}
\end{document}