Следующий код не работает:
\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]
. Результирующая строка сохраняется в \Result
then.
Однако тестовые команды не предоставляют этот синтаксис, и я также предполагаю, что это не будет иметь смысла. Однако я все еще надеюсь, что есть некоторые хитрости, которые заставят мой пример работать.
Пожалуйста, скажите, есть ли твик, который я могу поместить внутрь \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
она дает другие возможности (в зависимости от наличия звездочки).