xstring のテスト コマンド (IfStrEq、IfSubStr など) のネスト

xstring のテスト コマンド (IfStrEq、IfSubStr など) のネスト

次のコードは機能しません:

\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

ただし、テスト コマンドではこの構文は提供されておらず、意味がないとも考えられます。ただし、私の例が機能するようにいくつかの調整を加えることができればと期待しています。

内部に調整を加えることができるかどうか教えてください\checkemptyifコマンド (ここでは ) の内部で ( の任意のケースを介して) \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}

の宣言にある 2 つの新しい行に注目してください\checkempty。最初の は、\normalexpandargに渡される引数 (比較する文字列) が、デフォルト (はデフォルトで に設定されています)\IfStrEqのように完全に展開されないようにします。ただし、引数に中括弧が含まれている場合、呼び出されたコマンドはそのグループ内を検索しません。コマンドに渡される引数が空かどうかをチェックしたいので、このチェックは実行する必要があります。そのため、 行があります。(この機能を使用しない場合は、その行を省略するだけです。) を使用すると、いつでもデフォルトの動作に戻すことができます。xstringfullexpandargxstring\exploregroups\noexploregroups

これらのトグルはコード内の任意の場所で使用でき、スコープを設定することでローカルにすることができます。

お役に立てれば幸いです。:)

答え2

完全を期すために、LaTeX3 では文字列を拡張的に比較するために\pdfstrcmpプリミティブ (またはXeTeXとの同等のもの) を使用していることを述べておきます。には文字列の定義が奇妙であるため (今は調べません)、高度な機能を使用している場合は LaTeX3 用語に直接翻訳できない可能性があります。LuaTeXxstring

\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}

少し考えた後の編集: 実際、上記のコードでは を\IfStrEqのコピーとして定義していますが、 は他の可能性も提供するため (星印の有無に応じて) 、新しいコマンド (または何でも)\str_if_eq:nnTFを導入する方がよいでしょう。\expandableIfStrEq\IfStrEq

関連情報