我想将参数重命名#1
为类似的名字,\ies@firstStar
这样编程时就不会出错,在更改函数参数时也无需重命名变量。但是执行类似操作\def\ies@firstStar{#1}
会失败,您知道哪里出了问题吗?
\documentclass{article}
\usepackage{xparse}
\makeatletter
\NewDocumentCommand{\myTest}{s}{
\bgroup% make definitions local
\def\ies@firstStar{#1}%
\IfBooleanTF{\ies@firstStar}{%
One star
}{%
No star
}
\egroup
}
\makeatother
\begin{document}
\myTest
\end{document}
答案1
使用\let
代替来\def
避免使用\expandafter
s。在\def
,替换文本是\ies@firstStar
或。在\BooleanFalse
的\BooleanTrue
情况下\let
,\ies@firstStar
实际上等价于至\BooleanFalse
或\BooleanTrue
。
正如 Gaussler 所指出的,\let
只能分配一个标记。因此,这种方法是有效的,因为s
参数永远不会超过一个标记。
\documentclass{article}
\usepackage{xparse}
\makeatletter
\NewDocumentCommand{\myTest}{s}{%
\begingroup% make definitions local
\let\ies@firstStar=#1%
\IfBooleanTF{\ies@firstStar}{%
One star%
}{%
No star%
}%
\endgroup
}
\makeatother
\begin{document}
\myTest
\myTest*
\end{document}
答案2
在内部,我不确定具体是如何\IfBooleanTF
工作的,但下面的方法解决了这个问题。然而,至少在这个简单的例子里,我看不出这如何使代码更具可读性。
\documentclass{article}
\usepackage{xparse}
\makeatletter
\NewDocumentCommand{\myTest}{s}{
\begingroup% better to use this than \bgroup...\egroup
\def\ies@firstStar{#1}%
\expandafter\IfBooleanTF\expandafter{\ies@firstStar}{%
One star
}{%
No star
}
\endgroup
}
\makeatother
\begin{document}
\myTest
\myTest*
\end{document}
答案3
很难理解这种间接性的必要性。
无论如何,当前的参数类型的实现s
是,如果是第一个参数,则在没有 的情况下分配s
给 的值,如果有。#1
*
\BooleanFalse
\BooleanTrue
*
然后当前的的实现\IfBooleanTF{#1}{True}{False}
根据是否#1
为\BooleanTrue
或来选择真或假分支\BooleanFalse
。接下来你可能想知道现在 \BooleanTrue
和\BooleanFalse
是\chardef
令牌,所以它们不可扩展。
但用户/程序员应该不是依赖这一点。在未来的版本中,这可能会改变;不太可能发生,但是,嘿!谁知道呢?
此外,我看不出 比 有什么优势\IfBooleanTF{\ies@FirstStar}
。\IfBooleanTF{#1}
相反,我看到了几个缺点,例如,您需要分组以避免时间扩展或宏破坏。
为什么你的代码不起作用\def
?因为与或\ies@FirstStar
不同:它是一个扩展到它们任何一个的宏(和用于检查,而不是不起作用,因此不执行扩展)。如果你按照建议使用而不是代码\BooleanTrue
\BooleanFalse
expl3
\ifx
\if
\let
\def
似乎可以工作,但可能会在 的未来版本中停止工作expl3
。相反,\IfBooleanTF{#1}
保证永远有效。