我正在编写一个命令,它涉及检查几个参数以查看它们是否是颜色,并对那些是颜色的参数执行某些操作。我无法\tl_if_eq
识别匹配项。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\IsColour}{m}{
\clist_if_in:nnTF {
red,
orange,
yellow,
green,
blue,
purple,
white,
gray,
brown,
black
} { #1 } { TRUE } { FALSE }
}
\NewDocumentCommand{\TestA}{}{
\tl_set:Nn \l_test { TRUE }
\tl_if_eq:NnTF \l_test { TRUE } { TRUE } { FALSE }
}
\NewDocumentCommand{\TestB}{}{
\tl_set:Nn \l_test { \IsColour{red} }
\tl_if_eq:NnTF \l_test { TRUE } { TRUE } { FALSE }
}
\ExplSyntaxOff
\begin{document}
\TestA % works as desired
\hspace{1em}
\IsColour{red} % works as desired
\hspace{1em}
\TestB % doesn't work
\end{document}
编辑1响应 egreg 的更多细节请求。
最终目的是创建一个\Style
具有两个强制参数的函数,第一个参数是用逗号或分号分隔的参数列表,第二个参数是应应用样式的文本主体。
我对参数列表的无序语法的可能性很感兴趣,无需使用显式键值对。为此,我尝试检查每个参数以查看其参数类型(例如颜色、强调等)并相应地使用它,假设没有参数属于多个类别。
成品看起来会像这样:
\Style{red,italic}{hi} % returns \textit{\color{red}hi}
\Style{italic,red}{hi} % returns \textit{\color{red}hi}
我的具体问题也可以表述为:如何检查函数的输出是否与指定值匹配?
编辑2响应大卫卡莱尔的建议。
我猜我遗漏了一些东西因为我无法让它工作。
\documentclass{article}
\def\ZZred#1{\textcolor{red}{#1}}
\newcommand{\Style}[2]{
\csname ZZ#1\endcsname{#2}
}
\begin{document}
\Style{red}{hi}
\end{document}
答案1
我的具体问题也可以表述为:如何检查函数的输出是否与指定值匹配?
并非每个宏都会返回一个可以作为值进行测试的“输出”。有些宏会执行相当复杂的指令,如赋值、写入文件、选择字体或定义某些内容。在像您这样的测试中,您只能使用没有此类指令的“可扩展”宏。在 interface3.pdf 中,可扩展宏标有星号,或者您可以通过尝试自行扩展来测试:
\tl_set:Nx\l_tmpa_tl{\IsColour{red}}
\tl_show:N\l_tmpa_tl
如果输出错误或者出现错误,则无法扩展。
有时可以重写宏并使其可扩展,但通常不需要这样做。例如,您可以更改命令\IsColour
以设置布尔值(但像 David 一样,我认为最好避免过多测试和定义命令):
\documentclass{article}
\usepackage{xparse,color}
\ExplSyntaxOn
\bool_new:N \l__mjc_iscolour_bool
\tl_new:N \l__mjc_currentcolour_tl
\NewDocumentCommand{\IsColour}{m}{
\clist_if_in:nnTF {
red,
orange,
yellow,
green,
blue,
purple,
white,
gray,
brown,
black
} { #1 }
{
\bool_set_true:N \l__mjc_iscolour_bool
\tl_set:Nn \l__mjc_currentcolour_tl {#1}
}
{
\bool_set_false:N \l__mjc_iscolour_bool
\tl_set:Nn \l__mjc_currentcolour_tl {}
}
}
\NewDocumentCommand{\TestA}{}{
\tl_set:Nn \l_test { TRUE }
\tl_if_eq:NnTF \l_test { TRUE } { TRUE } { FALSE }
}
\NewDocumentCommand{\TestB}{m}{
\IsColour{#1}
\bool_if:NTF \l__mjc_iscolour_bool
{ \textcolor{\l__mjc_currentcolour_tl}{TRUE} }
{ FALSE}
}
\ExplSyntaxOff
\begin{document}
\TestB{red}
\TestB{violett}
\end{document}
答案2
您无需进行多次测试,只需将列表作为嵌套命令序列来执行即可。
\documentclass{article}
\usepackage{color}
\def\Style#1#2{\xStyle{#2}#1,STOP,}
\def\xStyle#1#2,{\csname Z#2\endcsname{#1}}
\def\Zred#1{\xStyle{\textcolor{red}{#1}}}
\def\Zgreen#1{\xStyle{\textcolor{green}{#1}}}
\def\Zitalic#1{\xStyle{\textit{#1}}}
\def\Zbold#1{\xStyle{\textbf{#1}}}
\def\ZSTOP#1{#1}
\begin{document}
\Style{red,italic}{hi}
\Style{italic,red}{hi}
\Style{italic,green,bold}{hi}
\end{document}
答案3
您可以选择使用functional
如果您想使函数组合像其他现代编程语言一样工作,例如Lua
:使用此包,复合函数的评估是从内到外的。
\documentclass{article}
\usepackage{functional}
\IgnoreSpacesOn
\PrgNewFunction \IsColour {m} {
\ClistIfInTF {
red,
orange,
yellow,
green,
blue,
purple,
white,
gray,
brown,
black
} { #1 } { \Result{TRUE} } { \Result{FALSE} }
}
\PrgNewFunction \TestA {} {
\TlSet \lTestTl { TRUE }
\TlIfEqTF { \Value\lTestTl } { TRUE } { \Result{TRUE} } { \Result{FALSE} }
}
\PrgNewFunction \TestB {} {
\TlSet \lTestTl { \IsColour{red} }
\TlIfEqTF { \Value\lTestTl } { TRUE } { \Result{TRUE} } { \Result{FALSE} }
}
\IgnoreSpacesOff
\begin{document}
\TestA % works as desired
\hspace{1em}
\IsColour{red} % works as desired
\hspace{1em}
\TestB % works as desired
\end{document}