当提供键时检测空键值

当提供键时检测空键值

我相信我正在寻找一种LaTeX3类型语法解决方案,以便更恰当地检测缺失的参数。对我来说,我本来期望key={}这是一个无值、空白或空的参数键。在搜索了所有问题后,我期望\tl_if_blank:nFIfNoValueF是我最好的选择,但我的键变量不是这些函数的兼容参数,或者键必须无法生成才能在这些函数上返回 TRUE。在下面的 MWE 中,我可以看出它仍在执行,因为其中包含了额外的行。

我知道如果可以避免在空白时包含键会更好,但目前这超出了我的控制范围,因为其他人负责将数据库解析为下面模拟的内容填充语法块的脚本\SampleBlock。所以我试图检测一个空的键值,但它没有像我预期的那样工作。

梅威瑟:

\documentclass[10pt]{article}

\usepackage{xparse}

%--------------------New Commands for consistent formatting ---------------
\ExplSyntaxOn

% define the variable before using it:
\tl_new:N \l_heading_tl
\tl_new:N \l_subheading_tl
\tl_new:N \l_paragraph_tl

% define key:    
\keys_define:nn { Sample }
{
    key-heading                 .tl_set:N = \l_heading_tl
,   key-subheading              .tl_set:N = \l_subheading_tl
,   key-paragraph               .tl_set:N = \l_paragraph_tl
}


\DeclareDocumentCommand{\SampleBlock}{ o }
{
    %TODO some residual debugging may be needed for omitted keys
    \group_begin:% start a group to keep key setting local:
    % set keys if optional argument #1 is given:
    \IfNoValueF {#1} { \keys_set:nn {Sample} {#1} }

    \IfNoValueF{\l_heading_tl}{\noindent\textbf{\l_heading_tl} \\} 
    \IfNoValueF{\l_subheading_tl}{\emph{\l_subheading_tl} \\}    

    \tl_if_blank:nF{\l_paragraph_tl}{\l_paragraph_tl}

    \group_end:
}

\ExplSyntaxOff

%--------------------BEGIN DOCUMENT----------------------
\begin{document}

\SampleBlock[%
key-heading={Title here},
key-subheading={Sub Heading here},
key-paragraph={A paragraph of text will go here.  Maybe I will say hello world, maybe I will describe how the quick brown fox jumped over the lazy brown dog.  Really, the possibilities are endless.  Oh wait, I could have used lipsum.  Doh!}]   

\medskip \medskip\medskip \medskip\medskip \medskip

\SampleBlock[%
key-heading={No subheading but there will still be a space for it on the next line...},
key-subheading={},
key-paragraph={A paragraph of text will go here.  Maybe I will say hello world, maybe I will describe how the quick brown fox jumped over the lazy brown dog.  Really, the possibilities are endless.  Oh wait, I could have used lipsum.  Doh!}]   

\end{document}

答案1

\IfNoValue(TF)用于测试参数是否存在o。它与检查标记列表变量是否为空无关,对于后者,您必须使用\tl_if_blank:V(TF)。该符号(TF)表示您可以使用TFTF(或在某些情况下什么都不用,但在这种情况下不是)。

请注意,这\tl_if_blank:nTF { \l_tmpa_tl }将始终返回 false,因为给定的标记列表不为空,因为它包含非空格标记。当你这样做时

\tl_clear:Nn \l_tmpa_tl
\tl_if_blank:VTF \l_tmpa_tl {TRUE} {FALSE}

将返回 true。

\documentclass[10pt]{article}

\usepackage{xparse}

%--------------------New Commands for consistent formatting ---------------
\ExplSyntaxOn

% define the variable before using it (not really necessary)
%\tl_new:N \l_engbird_heading_tl
%\tl_new:N \l_engbird_subheading_tl
%\tl_new:N \l_engbird_paragraph_tl

% define key:    
\keys_define:nn { Sample }
 {
  key-heading    .tl_set:N = \l_engbird_heading_tl,
  key-subheading .tl_set:N = \l_engbird_subheading_tl,
  key-paragraph  .tl_set:N = \l_engbird_paragraph_tl,
}

\DeclareDocumentCommand{\SampleBlock}{ O{} }
 {
  %TODO some residual debugging may be needed for omitted keys
  \group_begin:% start a group to keep key setting local:
  % set keys if optional argument #1 is given:
  \keys_set:nn {Sample} {#1}

  \tl_if_blank:VF \l_engbird_heading_tl {\noindent\textbf{\l_engbird_heading_tl} \\} 
  \tl_if_blank:VF \l_engbird_subheading_tl {\emph{\l_engbird_subheading_tl} \\}    

  \tl_if_blank:VF \l_engbird_paragraph_tl {\l_engbird_paragraph_tl}

  \group_end:
 }

\ExplSyntaxOff

%--------------------BEGIN DOCUMENT----------------------
\begin{document}

\SampleBlock[%
key-heading={Title here},
key-subheading={Sub Heading here},
key-paragraph={A paragraph of text will go here.  Maybe I will say hello world, maybe I will describe 
how the quick brown fox jumped over the lazy brown dog.  Really, the possibilities are endless.  Oh 
wait, I could have used lipsum.  Doh!}]

\bigskip

\SampleBlock[%
key-heading={No subheading but there will still be a space for it on the next line...},
key-subheading={},
key-paragraph={A paragraph of text will go here.  Maybe I will say hello world, maybe I will describe 
how the quick brown fox jumped over the lazy brown dog.  Really, the possibilities are endless.  Oh 
wait, I could have used lipsum.  Doh!}]

\end{document}

请注意,\IfNoValueF{#1}设置密钥是多余的:不设置密钥就等于什么都不做。


进一步说明

一个密钥可以有三种情况,我们foo在使用时这样称呼它:

  1. 未指定密钥
  2. 您指定foo
  3. 您指定foo=...

为简单起见,我们假设您总是将键设置为一个组,就像您的示例一样。当您使用

foo .tl_set:N = \l_whatever_foo_tl,

(或另一个键定义命令),您还可以添加

foo .initial:n = INITIAL~VALUE,
foo .default:n = DEFAULT~VALUE,

右侧默认为空。有什么区别?

  1. foo在使用时未设置密钥:所使用的值\l_whatever_foo_tl将为INITIAL~VALUE

  2. foo没有出现等号:所使用的值\l_whatever_foo_tl将为DEFAULT~VALUE

  3. 用户执行的操作foo=Something:使用的值\l_whatever_foo_tl将是Something

另一件需要注意的事情是:当你有

foo .tl_set:N = \l_whatever_foo_tl,

在 中\keys_define:nn,右边的变量是自动声明的,因此不需要事先声明\tl_new:N(但这也没有坏处)。

相关内容