Estoy intentando escribir una validación básica de la entrada del usuario para un comando \noinsuit
que toma dos parámetros, un número entero en [0, 13] y una letra que indica el traje.
Entonces espero \noinsuit{1}{C}
ser válido y ambos \noinsuit{Q}{C}
y \noinsuit{1}{Q}
ser inválido. Eso funciona bien, pero tengo problemas al usar xstring
's \StrLeft{#1}{1}
para probar si el primer carácter es un número entero. El siguiente MWE imprime su valor correctamente pero si descomento la línea de prueba arroja
! Undefined control sequence.
\xs_StrLeft__ ...ef \xs_arg_ii {#2}\edef \xs_call
{\noexpand \xs_testopt {\n...
Un problema con la expansión, supongo.
\documentclass{article}
\usepackage{xparse}
\usepackage{xstring}
\newcommand{\singpl}{bad}
\newcommand{\test}{bad}
\NewDocumentCommand\noinsuit{mm}{%
\renewcommand{\test}{\StrLeft{#1}{1}}
% \IfInteger{\test}{\renewcommand{\singpl}{cards}}{[\PackageError{BridgeStyle : \noinsuit}{Invalid integer (#1)}{}]}%
\IfEqCase{#1}{%
{1}{\renewcommand{\singpl}{card}}%
}
\IfEqCase{#2}{%
{C}{#1 \singpl{}\quad\test in Clubs}%
{D}{#1 \singpl{} in Diamonds}%
{H}{#1 \singpl{} in Hearts}%
{S}{#1 \singpl{} in Spades}%
}[\PackageError{BridgeStyle : \noinsuit}{Unknown suit (#2)}{}]%
}%
\begin{document}
\noinsuit{1}{C}
\noinsuit{2}{C}
% \noinsuit{Q}{H}
% \noinsuit{3}{Q}
\end{document}
Respuesta1
No puedes usarlo \StrLeft
dentro del argumento to \IfInteger
. Estás pasando las instrucciones para construir una cadena en lugar de la cadena.
Más bien hazlo
\StrLeft{#1}{1}[\test]
\IfInteger{\test}
{\renewcommand{\singpl}{cards}}
{\PackageError{BridgeStyle : \noinsuit}{Invalid integer (#1)}{}}%
Por otro lado, puedes obtener más control usando expl3
.
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand\noinsuit{mm}
{
\bridgestyle_noinsuit_checknumber:nn { #1 } { #2 }
}
\cs_new_protected:Nn \bridgestyle_noinsuit_checknumber:nn
{
\regex_match:nnTF { \A [0-9]{1,2} \Z } { #1 }
{% we have one or two digits
\int_compare:nTF { #1 <= 13 }
{% the integer is between 0 and 13
\bridgestyle_noinsuit_checksuit:nn { #1 } { #2 }
}
{% error
\bridgestyle_noinsuit_invalid:nn { integer } { #1 }
}
}
{% invalid input for the integer
\bridgestyle_noinsuit_invalid:nn { integer } { #1 }
}
}
\cs_new_protected:Nn \bridgestyle_noinsuit_checksuit:nn
{
\regex_match:nnTF { \A [CDHS] \Z } { #2 }
{% valid suit
#1~card\int_compare:nF { #1=1 } {s}~in~\bridgestyle_suit:n { #2 }
}
{% invalid suit
\bridgestyle_noinsuit_invalid:nn { suit } { #2 }
}
}
\cs_new:Nn \bridgestyle_suit:n
{
\str_case:nn { #1 }
{
{C}{Clubs}
{D}{Diamonds}
{H}{Hearts}
{S}{Spades}
}
}
\cs_new_protected:Nn \bridgestyle_noinsuit_invalid:nn
{
\PackageError{bridgestyle}{(\string\noinsuit)~invalid~#1~(#2)}{}
}
\ExplSyntaxOff
\begin{document}
\noinsuit{0}{D}
\noinsuit{1}{C}
\noinsuit{2}{C}
\noinsuit{Q}{H}
\noinsuit{3}{Q}
\noinsuit{14}{H}
\end{document}
La salida de la consola es
! Package bridgestyle Error: (\noinsuit) invalid integer (Q).
See the bridgestyle package documentation for explanation.
Type H <return> for immediate help.
...
l.65 \noinsuit{Q}{H}
?
! Package bridgestyle Error: (\noinsuit) invalid suit (Q).
See the bridgestyle package documentation for explanation.
Type H <return> for immediate help.
...
l.67 \noinsuit{3}{Q}
?
! Package bridgestyle Error: (\noinsuit) invalid integer (14).
See the bridgestyle package documentation for explanation.
Type H <return> for immediate help.
...
l.69 \noinsuit{14}{H}
?
La salida impresa es