
Ich habe einen Befehl mit einem optionalen Argument und möchte Code ausführen, je nachdem, ob das Argument true
oder ist false
(ich bin sicher, dass dieser Befehl immer ein Argument haben wird, das in einen Booleschen Wert konvertierbar ist, da es sich um einen privaten Befehl und nicht um einen Benutzerbefehl handelt). Mit meinem Code erhalte ich diesen Fehler:
! Missing number, treated as zero.
<to be read again>
t
l.8 \test{
}
?
Vielen Dank an alle für jede Hilfe.
\documentclass{article}
\usepackage{expl3}
\begin{document}
\ExplSyntaxOn
\newcommand{\test}[1][true]{
\bool_if:NTF{#1}{\message{true}}{\message{false}}
}
\test{}
\ExplSyntaxOff
\end{document}
Antwort1
Beachten Sie zunächst, dass als Argument \bool_if:N(TF)
ein einzelnes Token (der -Typ) erwartet wird und daher syntaktisch ungültig ist. Sie benötigen das -Typ-Argument: . Dies funktioniert jedoch auch nicht, da die Booleschen Funktionen von die Literale und nicht verstehen . Sie müssen also nachhelfen, was Sie meinen.N
\bool_if:NTF {true} {T}{F}
n
\bool_if:nTF {true} {T}{F}
expl3
true
false
Sie können beispielsweise verwenden, \str_case:nnF
um das Eingabeargument mit einer Reihe vordefinierter Fälle zu vergleichen und, falls keine Übereinstimmung besteht, über den F
Zweig auszusteigen, der \bool_if:n(TF)
die Analyse durchführt:
\documentclass{article}
\usepackage{xparse}
\begin{document}
\ExplSyntaxOn
\NewDocumentCommand \test { O{true} }
{
\bool_if:nTF
{
\str_case:nnF {#1}
{ % Known cases
{ true } { \c_true_bool }
{ T } { \c_true_bool }
{ 1 } { \c_true_bool }
%
{ false } { \c_false_bool }
{ F } { \c_false_bool }
{ 0 } { \c_false_bool }
}
{#1} % Otherwise
}
{ \iow_term:n {true} }
{ \iow_term:n {false} }
}
%
\test % no argument
\test[true] \test[1] \test[T] \test[\c_true_bool] % true input
\test[false] \test[0] \test[F] \test[\c_false_bool] % false input
\test[\int_compare_p:n { 2+2>4 } && !\c_false_bool] % expressions
%
\ExplSyntaxOff
\end{document}
Es wird gedruckt:
true
true
true
true
true
false
false
false
false
false
Beachten Sie, dass dies nicht vor beliebig schlechten Eingaben schützt, sondern nur einige zusätzliche Fälle abdeckt, sodass Sie nicht verwenden könnenirgendetwasals Eingabe. Außerdem werden die Literale true
und false
nur erkannt, wenn sie allein verwendet werden. Das heißt, \test[true]
und \test[false]
funktionieren wie erwartet, \test[!true]
werden es aber nicht, weil !true
von nicht erkannt wird \str_case:nn(TF)
und das Literal true
dann direkt an geht \bool_if:n(TF)
, was dann wie zuvor fehlschlägt.
Wenn es sich außerdem um einen Befehl zur privaten Verwendung handelt und Sie können sicher sein, dass dieser ein Argument hat, dann macht es keinen Sinn, das Argument optional zu machen, da dies die Verarbeitung nur verlangsamen würde.
Antwort2
Sie haben nicht viele Details dazu angegeben, was Ihr Befehl tun soll. Aber anstatt die Argumente „true“ und „false“ zu verwenden und dann einen Zeichenfolgenvergleich damit durchzuführen, ist es normalerweise besser, im Argument die Schlüsselwertsyntax zu verwenden und damit echte Boolesche Werte festzulegen:
\documentclass{article}
\usepackage{expl3}
\begin{document}
\ExplSyntaxOn
\keys_define:nn { alek }
{
dothis .bool_set:N = \l__alex_dothis_bool
}
\newcommand{\test}[1][]
{
\keys_set:nn {alek}{dothis=true,#1}
\bool_if:NTF\l__alex_dothis_bool
{true}
{false}
}
\ExplSyntaxOff
\test{}
\test[dothis]
\test[dothis=false]
\test[]
\end{document}