Вложенность тестовых команд (IfStrEq, IfSubStr и т.д.) xstring

Вложенность тестовых команд (IfStrEq, IfSubStr и т.д.) xstring

Следующий код не работает:

\documentclass{article}

\usepackage{xstring}

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

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

[Изменить: Я ожидаю, что \checkempty{\IfStrEq{a}{a}{val}{}}с NonEmpty. Однако, \checkempty{\IfStrEq{a}{b}{val}{}}должно получиться Empty. ]

Однако я получаю некоторые ошибки, такие как

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

и наконец также это

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

В принципе, я могу предположить, в чем проблема. \IfStrEqне может быть расширен (или как это явление называется точно) и не может быть вложенным. Поэтому большинство команд в xstringпредоставляют синтаксис типа \StrLeft{xstring}{4}[\Result]. Результирующая строка сохраняется в \Resultthen.

Однако тестовые команды не предоставляют этот синтаксис, и я также предполагаю, что это не будет иметь смысла. Однако я все еще надеюсь, что есть некоторые хитрости, которые заставят мой пример работать.

Пожалуйста, скажите, есть ли твик, который я могу поместить внутрь \checkempty. Мне нужно определить (через любой случай if) внутри команды (здесь \checkempty), является ли переданный аргумент (развернутый) пустым или нет. [Изменить: внешний аргумент IfStrEqдолжен быть развернут до этого!] Если твика нет, я не могу использовать IfStrEq, верно?

Раньше я работал с xifthenпакетом. Это была сплошная боль, и я не мог справиться с некоторыми проблемами расширения. С xstringи IfSubStrвсе работало отлично, за исключением случая, который я показываю в своем примере :(

решение1

Пакет xstringпредлагает дополнительные (читай: расширенные) опции для управления расширением аргументов. Это действительно не предназначено для новичков, и хорошее понимание того, как расширяются аргументы, более чем приветствуется.

В вашем случае код можно подправить для компиляции:

\documentclass{article}

\usepackage{xstring}

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

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

Обратите внимание на две новые строки в объявлении \checkempty. Первая \normalexpandargгарантирует, что аргументы (строки для сравнения), переданные в , \IfStrEqне будут полностью развернуты, как это было бы по умолчанию ( xstringпо умолчанию установлено значение fullexpandarg). Однако, если ваш аргумент содержит фигурные скобки, вызванная xstringкоманда не будет искать внутри этой группы. Поскольку вы хотите проверить, являются ли аргументы, переданные вашей команде, пустыми или нет, эта проверка все равно должна быть выполнена, отсюда и строка \exploregroups. (Если вы не хотите использовать эту функцию, просто пропустите эту строку.) Вы можете в любое время вернуться к поведению по умолчанию с помощью \noexploregroups.

Эти переключатели можно использовать в любом месте кода и сделать их локальными с помощью области действия.

Надеюсь, это поможет.:)

решение2

Для полноты картины я упомяну, что LaTeX3 использует \pdfstrcmpпримитив (или эквиваленты для XeTeXи LuaTeX) для расширяемого сравнения строк. Обратите внимание, что xstringу него странное определение того, что такое строка (которое я не хочу сейчас исследовать), поэтому, если вы используете расширенные функции, прямой перевод на жаргон 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}

EDIT после некоторых раздумий: На самом деле, в коде выше я определяю \IfStrEqкак копию \str_if_eq:nnTF, но, вероятно, лучше ввести новую команду \expandableIfStrEq(или что-то еще), поскольку \IfStrEqона дает другие возможности (в зависимости от наличия звездочки).

Связанный контент