Aninhamento de comandos de teste (IfStrEq, IfSubStr etc.) de xstring

Aninhamento de comandos de teste (IfStrEq, IfSubStr etc.) de xstring

O código a seguir não funciona:

\documentclass{article}

\usepackage{xstring}

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

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

[Editar: O que eu espero \checkempty{\IfStrEq{a}{a}{val}{}}é NonEmpty. No entanto, \checkempty{\IfStrEq{a}{b}{val}{}}resultará em Empty. ]

No entanto, recebo alguns erros como

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

e finalmente também isso

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

Basicamente, posso adivinhar o problema. \IfStrEqnão pode ser expandido (ou como esse fenômeno é chamado exatamente) e não pode ser aninhado. Portanto, a maioria dos comandos xstringfornece uma sintaxe como \StrLeft{xstring}{4}[\Result]. A string de resultado é armazenada em \Resultthen.

No entanto, os comandos de teste não fornecem essa sintaxe e também acho que não seria significativo. No entanto, ainda espero que haja alguns ajustes para fazer meu exemplo funcionar.

Por favor, diga-me se há um ajuste que eu possa colocar dentro do arquivo \checkempty. Preciso determinar (por meio de qualquer caso if) dentro de um comando (aqui \checkempty), se o argumento passado (expandido) está vazio ou não. [Editar: O exterior IfStrEqdeve ser expandido antes!] Se não houver ajuste, não posso usar IfStrEq, certo?

No passado trabalhei com o xifthenpacote. Foi uma dor total e não consegui resolver algum problema de expansão. Com xstringe IfSubStrtudo funcionou bem, exceto no caso que estou mostrando no meu exemplo :(

Responder1

O xstringpacote oferece opções extras (leia-se: avançadas) para controlar a expansão dos argumentos. Na verdade, isso não se destina a iniciantes e uma boa compreensão de como os argumentos são expandidos é mais que bem-vinda.

No seu caso, o código pode ser ajustado 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 as duas novas linhas na declaração de \checkempty. O primeiro \normalexpandarggarante que os argumentos (as strings a serem comparadas) passados \IfStrEq​​não sejam totalmente expandidos, como seriam por padrão ( xstringé definido por padrão como fullexpandarg). No entanto, se o seu argumento contiver colchetes, o xstringcomando invocado não procurará dentro desse grupo. Como você deseja verificar se os argumentos passados ​​para o seu comando estão vazios ou não, esta verificação ainda deve ser feita, daí a \exploregroupslinha. (Se você não quiser usar esse recurso, simplesmente omita essa linha.) Você pode reverter a qualquer momento para o comportamento padrão com \noexploregroups.

Essas alternâncias podem ser usadas em qualquer lugar do seu código e podem ser tornadas locais por meio do escopo.

Espero que ajude.:)

Responder2

Para completar, mencionarei que o LaTeX3 faz uso do \pdfstrcmpprimitivo (ou equivalentes para XeTeXe LuaTeX) para comparar strings de forma expansível. Observe que xstringhá uma definição estranha do que é uma string (que não quero investigar agora); portanto, se você estiver usando recursos avançados, pode não ser possível traduzir diretamente para a linguagem 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 depois de pensar um pouco: Na verdade, no código acima eu defino \IfStrEqcomo uma cópia de \str_if_eq:nnTF, mas provavelmente é melhor introduzir um novo comando, \expandableIfStrEq(ou qualquer outro), porque \IfStrEqdá outras possibilidades (dependendo da presença de uma estrela).

informação relacionada