我相信我正在寻找一种LaTeX3
类型语法解决方案,以便更恰当地检测缺失的参数。对我来说,我本来期望key={}
这是一个无值、空白或空的参数键。在搜索了所有问题后,我期望\tl_if_blank:nF
这IfNoValueF
是我最好的选择,但我的键变量不是这些函数的兼容参数,或者键必须无法生成才能在这些函数上返回 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)
表示您可以使用TF
、T
或F
(或在某些情况下什么都不用,但在这种情况下不是)。
请注意,这\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
在使用时这样称呼它:
- 未指定密钥
- 您指定
foo
- 您指定
foo=...
为简单起见,我们假设您总是将键设置为一个组,就像您的示例一样。当您使用
foo .tl_set:N = \l_whatever_foo_tl,
(或另一个键定义命令),您还可以添加
foo .initial:n = INITIAL~VALUE,
foo .default:n = DEFAULT~VALUE,
右侧默认为空。有什么区别?
foo
在使用时未设置密钥:所使用的值\l_whatever_foo_tl
将为INITIAL~VALUE
。键
foo
没有出现等号:所使用的值\l_whatever_foo_tl
将为DEFAULT~VALUE
。用户执行的操作
foo=Something
:使用的值\l_whatever_foo_tl
将是Something
。
另一件需要注意的事情是:当你有
foo .tl_set:N = \l_whatever_foo_tl,
在 中\keys_define:nn
,右边的变量是自动声明的,因此不需要事先声明\tl_new:N
(但这也没有坏处)。