Anidamiento de comandos de prueba (IfStrEq, IfSubStr, etc.) de xstring

Anidamiento de comandos de prueba (IfStrEq, IfSubStr, etc.) de xstring

El siguiente código no funciona:

\documentclass{article}

\usepackage{xstring}

\newcommand\checkempty[1]{
    \IfStrEq{#1}{}{%
        Empty
    }{%
        NonEmpty
    }
}

\begin{document}
    \checkempty{\IfStrEq{justadummyvalue}{justadummyvalue}{somevalue}{}}
\end{document}

[Editar: Lo que espero \checkempty{\IfStrEq{a}{a}{val}{}}es NonEmpty. Sin embargo, \checkempty{\IfStrEq{a}{b}{val}{}}resultará en Empty. ]

Sin embargo, recibo algunos errores como

Argument of \@xs@expand@and@assign has an extra }. \firstif{a}{b}{c} (followed by: )    document.tex    /test   line 19 Texlipse Build Error

y finalmente también esto

TeX capacity exceeded, sorry [input stack size=65000]. \firstif{a}{b}{c} (followed by: )    document.tex    /test   line 19 Texlipse Build Error

Básicamente, puedo adivinar el problema. \IfStrEqno se puede expandir (o como se llame exactamente este fenómeno) y no se puede anidar. Por lo tanto, la mayoría de los comandos xstringproporcionan una sintaxis como \StrLeft{xstring}{4}[\Result]. La cadena de resultados se almacena en \Resultthen.

Sin embargo, los comandos de prueba no proporcionan esta sintaxis y también supongo que no tendría sentido. Sin embargo, todavía espero que haya algunos ajustes para que mi ejemplo funcione.

Por favor, dígame si hay algún ajuste que pueda realizar \checkempty. Necesito determinar (a través de cualquier caso de if) dentro de un comando (aquí \checkempty), si el argumento pasado (expandido) está vacío o no. [Editar: ¡El exterior IfStrEqse expandirá antes!] Si no hay ningún ajuste, no puedo usarlo IfStrEq, ¿verdad?

En el pasado trabajé con el xifthenpaquete. Fue una completa molestia y no pude solucionar algún problema de expansión. Con xstringy IfSubStrtodo funcionó bien, excepto en el caso que muestro en mi ejemplo :(

Respuesta1

El xstringpaquete ofrece opciones adicionales (léase: avanzadas) para controlar la expansión de los argumentos. En realidad, esto no es para principiantes y una buena comprensión de cómo se amplían los argumentos es más que bienvenida.

En su caso, el código se puede modificar para compilar:

\documentclass{article}

\usepackage{xstring}

\newcommand\checkempty[1]{
    \normalexpandarg
    \exploregroups
    \IfStrEq{#1}{}{%
        Empty
    }{%
        NonEmpty
    }
}

\begin{document}
    \checkempty{\IfStrEq{justadummyvalue}{justadummyvalue}{somevalue}{}}
\end{document}

Observe las dos nuevas líneas en la declaración de \checkempty. El primero \normalexpandarggarantiza que los argumentos (las cadenas que se van a comparar) pasados \IfStrEq​​no estén completamente expandidos, como lo harían de forma predeterminada ( xstringestá configurado de forma predeterminada en fullexpandarg). Sin embargo, si su argumento contiene llaves, el xstringcomando invocado no buscará dentro de ese grupo. Como desea verificar si los argumentos pasados ​​a su comando están vacíos o no, esta verificación aún debe realizarse, de ahí la \exploregroupslínea. (Si no desea utilizar esta función, simplemente omita esa línea). Puede volver en cualquier momento al comportamiento predeterminado con \noexploregroups.

Estos conmutadores se pueden usar en cualquier lugar dentro de su código y se pueden hacer locales mediante el alcance.

Espero que ayude.:)

Respuesta2

Para completar, mencionaré que LaTeX3 hace uso de la \pdfstrcmpprimitiva (o equivalentes de XeTeXy LuaTeX) para comparar cadenas de manera expandible. Tenga en cuenta que xstringtiene una definición extraña de lo que es una cadena (que no quiero investigar ahora), por lo que si está utilizando funciones avanzadas, es posible que no sea posible traducir directamente a la jerga LaTeX3.

\documentclass{article}

\usepackage{expl3}
\ExplSyntaxOn
\cs_set_eq:NN \IfStrEq \str_if_eq:nnTF
\ExplSyntaxOff

\newcommand\checkempty[1]{
    \IfStrEq{#1}{}{%
        Empty
    }{%
        NonEmpty
    }
}

\begin{document}
    \checkempty{\IfStrEq{justadummyvalue}{justadummyvalue}{somevalue}{}}
\end{document}

EDITAR después de pensarlo un poco: en realidad, en el código anterior lo defino \IfStrEqcomo una copia de \str_if_eq:nnTF, pero probablemente sea mejor introducir un nuevo comando \expandableIfStrEq(o lo que sea), porque \IfStrEqofrece otras posibilidades (dependiendo de la presencia de una estrella).

información relacionada