\tl_if_blank:e 的替代方案

\tl_if_blank:e 的替代方案

最近我开始检查我刚开始学习 时写的代码expl3。我发现 有很多 的用法用于\tl_if_blank:e...测试宏的内容是否为空。但现在我意识到这对于一般的用户输入来说可能不安全(例如,如果用户输入包含 之类的内容\color{red},它将停止工作)。

我认为我选择使用的原因\tl_if_blank:e...可能是因为\tl_if_blank:n...\str_if_empty:n...没有按预期工作。例如,\@date如果您将其输出到 pdf,某些宏可能看起来是空的,但是当您使用n-variant 命令测试它时,它并不反映为空。

\documentclass{article}
\begin{document}
\date{}
% \date{\color{red}}
\makeatletter
\ExplSyntaxOn
\tl_if_blank:eTF { \@date } {EMPTY} {SOMETHING}
\par
\tl_if_blank:nTF { \@date } {EMPTY} {SOMETHING}
\par
\str_if_empty:nTF { \@date } {EMPTY} {SOMETHING}
\ExplSyntaxOff
\end{document}

因此我想问一下,我应该如何以安全的方式修改我的代码同时仍然获得正确的结果?

答案1

由于你对排版输出,我会测试一下:

\hbox_set:Nn \l_tmpa_box { \@date }
\dim_compare:nNnTF { \box_wd:N \l_tmpa_box } > \c_zero_dim
  { FALSE CODE }
  { TRUE CODE }

可以使用以下方法将其变成独立测试\prg_new_protected_conditional:Npnn

\prg_new_protected_conditional:Npn \jinwin_if_outout_blank:n #1 { T , F, TF }
  {
    \group_begin:
      \hbox_set:Nn \l_tmpa_box {#1}
      \dim_compare:nNnTF { \box_wd:N \l_tmpa_box } > \c_zero_dim
        { \group_end: \prg_return_false: }
        { \group_end: \prg_return_true: }
  }

如果你想知道用户输入的扩展是否为空,如果可以使用非扩展\protected@edef

\protected@edef \@tempa {\@date}
\tl_if_empty:NTF \@tempa
  { TRUE CODE }
  { FALSE CODE }

如果你需要可扩展的结果输入应该大致是“文本”,你可以使用\text_expand:n

\tl_if_blank:eTF { \text_expand:n { \@date } }
  { TRUE CODE }
  { FALSE CODE }

这将像\text_expand:n作品一样仔细地接近\protected@edef但通过扩展 - 但它确实是为“类似文本”的材料而设计的。

相关内容