文字列を読み取りからの cs と適切に比較するにはどうすればよいですか?

文字列を読み取りからの cs と適切に比較するにはどうすればよいですか?

シナリオ:yyyy-mm-ddファイルからフォームの日付を cs に読み込みます。この cs は後で「現在の日付」マクロと比較され、いくつかの引数を特定の方法で外部ファイルに書き込みます。現在の日付マクロは次のようになります。

% \def\TODAY{}
% \def\Today{\the\year-\TwoDigits{\the\month}-\TwoDigits{\the\day} }
\def\TODAY{\xdef\Today{\the\year-\TwoDigits{\the\month}-\TwoDigits{\the\day}}}

これはラベル付けには有効です\ref{yyyy-mm-dd}。意図したとおりに動作します。余分なものがなく\TODAY\def'd Today を使用すると、比較が機能しません。etoolbox's は\ifstrequal、以前使用したものではありません。日付が変更されるたびに、単一の を使用し\xdef、後でそのマクロを に渡しました\ifx。これを機能させるには、 を追加して日付を定義する必要がありました編集驚いたことに、読み上げられた内容の後に 1 つのスペースが挿入されます。

現在、私は修正中であるはずですが、何らかの理由でそれを壊してしまい、今ではまったく一致しません。最初の原因は、私のcmd が堅牢だったため、それを修正するのではなく、\TwoDigits元に戻したことです。後者はユーザー レベルのコマンド用なので、ここでは省略します。しかし、mwe の結果は私には明確ではありません。\def\NewDocumentCommand

0.txt2001-01-011 行が書き込まれて出力が閉じられたかのように、1 行の with とその後の 1 行の new が含まれます。

質問:

  1. 文字列に展開される(べきである)もの(マクロ、CS、コマンドなど)を比較する「正しい」方法は何ですか?
  2. なぜここでは機能しないのでしょうか\edef\xdef完全な拡張だと思っていましたが、実際以前は (バージョン管理がほとんどないため、これについて mwe を与えることはできません) 機能していました。
  3. 堅牢性の重要性は何ですか? 堅牢性が必要なとき、必須のとき、または無関係なときに関する簡単な経験則はありますか?
  4. xstringそれは'sと連携しています\IfStrEqual のみが比較の括弧内、つまり ではなくの定義内に挿入されている場合。なぜでしょうか?\datemacro{\datemacro }
  5. \ifstrequalおそらく展開されない - 引数が に等しいかどうかをテストするためにコマンドで一度使用しましたが&、これは機能します - #1 は入力されたものになり、展開としてカウントされませんか?

編集:\ifx区切り引数ではなくマクロに使用されることを忘れていました。申し訳ありません。

例1;

\documentclass{article}
\usepackage[top=1.5cm, bottom=0.6cm, hmargin=1.5cm]{geometry}
\usepackage{etoolbox}
\newread\periods
\openin\periods=0.txt
\begin{document}\setlength\parindent{0pt}\fontsize{20}{20}\selectfont
\def\testi{2001-01-01}
\edef\testii{2001-01-01}
\def\testiii{2001-01-01 }
\edef\testiiii{2001-01-01 }
\global\read\periods to \DDD

\ifstrequal{\testi}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\testii}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\testiii}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\testiiii}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\DDD}{2001-01-01}{T\\}{F\\}% F

\ifstrequal{\testi}{\DDD}{T\\}{F\\}% F
\ifstrequal{\testii}{\DDD}{T\\}{F\\}% F
\ifstrequal{\testiii}{\DDD}{T\\}{F\\}% F
\ifstrequal{\testiiii}{\DDD}{T\\}{F\\}% F
\ifstrequal{\DDD}{\DDD}{T\\}{F\\}% T

\ifx{\testi}{2001-01-01} T\\\else F\\\fi% F
\ifx{\testii}{2001-01-01} T\\\else F\\\fi% F
\ifx{\testiii}{2001-01-01} T\\\else F\\\fi% F
\ifx{\testiiii}{2001-01-01} T\\\else F\\\fi% F
\ifx{\DDD}{2001-01-01} T\\\else F\\\fi% F

\ifx{\testi}{\DDD} T\\\else F\\\fi% F
\ifx{\testii}{\DDD} T\\\else F\\\fi% F
\ifx{\testiii}{\DDD} T\\\else F\\\fi% F
\ifx{\testiiii}{\DDD} T\\\else F\\\fi% F
\ifx{\DDD}{\DDD} T\\\else F\\\fi% F

\ifcsequal{\testi}{\DDD}{T\\}{F\\}% F
\ifcsequal{\testii}{\DDD}{T\\}{F\\}% F
\ifcsequal{\testiii}{\DDD}{T\\}{F\\}% F
\ifcsequal{\testiiii}{\DDD}{T\\}{F\\}% F
\ifcsequal{\DDD}{\DDD}{T\\}{F\\}% F

\ifdefequal{\testi}{\DDD}{T\\}{F\\}% F
\ifdefequal{\testii}{\DDD}{T\\}{F\\}% F
\ifdefequal{\testiii}{\DDD}{T\\}{F\\}% T
\ifdefequal{\testiiii}{\DDD}{T\\}{F\\}% T
\ifdefequal{\DDD}{\DDD}{T\\}{F\\}% T
\end{document}

例2;

\documentclass{article}
\usepackage[top=1.5cm, bottom=0.6cm, hmargin=1.5cm]{geometry}
\usepackage{etoolbox,xstring}
\def\TwoDigits#1{\ifnum#1<10 0#1\else#1\fi}

\newcount\month
    \month 1\relax
\newcount\day
    \day 1\relax
\newread\periods
\openin\periods=0.txt
\global\read\periods to \DDD

\def\testi{2001-\TwoDigits{\the\month}-\TwoDigits{\the\day}}%
\edef\testii{2001-\TwoDigits{\the\month}-\TwoDigits{\the\day}}%
\def\testiii{2001-\TwoDigits{\the\month}-\TwoDigits{\the\day} }%
\edef\testiiii{2001-\TwoDigits{\the\month}-\TwoDigits{\the\day} }%

\begin{document}\setlength\parindent{0pt}
DDD is \DDD.% space between cs and .

\ifstrequal{\testi}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\testii}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\testiii}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\testiiii}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\DDD}{2001-01-01}{T\\}{F\\}% F

\ifstrequal{\testi}{\DDD}{T\\}{F\\}% F
\ifstrequal{\testii}{\DDD}{T\\}{F\\}% F
\ifstrequal{\testiii}{\DDD}{T\\}{F\\}% F
\ifstrequal{\testiiii}{\DDD}{T\\}{F\\}% F
\ifstrequal{\DDD}{\DDD}{T\\}{F\\}% T

\ifx\testi{2001-01-01} T\\\else F\\\fi% F
\ifx\testii{2001-01-01} T\\\else F\\\fi% F
\ifx\testiii{2001-01-01} T\\\else F\\\fi% F
\ifx\testiiii{2001-01-01} T\\\else F\\\fi% F
\ifx\DDD{2001-01-01} T\\\else F\\\fi% F

\ifx\testi\DDD T\\\else F\\\fi% F
\ifx\testii\DDD T\\\else F\\\fi% F
\ifx\testiii\DDD T\\\else F\\\fi% F
\ifx\testiiii\DDD T\\\else F\\\fi% T
\ifx\DDD\DDD T\\\else F\\\fi% T

\ifcsequal{\testi}{\DDD}{T\\}{F\\}% F
\ifcsequal{\testii}{\DDD}{T\\}{F\\}% F
\ifcsequal{\testiii}{\DDD}{T\\}{F\\}% F
\ifcsequal{\testiiii}{\DDD}{T\\}{F\\}% F
\ifcsequal{\DDD}{\DDD}{T\\}{F\\}% F

\ifdefequal{\testi}{\DDD}{T\\}{F\\}% F
\ifdefequal{\testii}{\DDD}{T\\}{F\\}% F
\ifdefequal{\testiii}{\DDD}{T\\}{F\\}% F
\ifdefequal{\testiiii}{\DDD}{T\\}{F\\}% T
\ifdefequal{\DDD}{\DDD}{T\\}{F\\}% T

\IfStrEq{\testi}{\DDD}{T\\}{F\\}% F
\IfStrEq{\testii}{\DDD}{T\\}{F\\}% F
\IfStrEq{\testi }{\DDD}{T\\}{F\\}% F
\IfStrEq{\testii }{\DDD}{T\\}{F\\}% F
\IfStrEq{\testiii}{\DDD}{T\\}{F\\}% T
\IfStrEq{\testiiii}{\DDD}{T\\}{F\\}% T
\IfStrEq{\DDD}{\DDD}{T\\}{F\\}% T

\end{document}

答え1

\ifstrequal

のドキュメントよりetoolbox:

\ifstrequal{⟨string⟩}{⟨string⟩}{⟨true⟩}{⟨false⟩}
2 つの文字列を比較し、等しい場合は ⟨true⟩ を実行し、そうでない場合は ⟨false⟩ を実行します。文字列はテストで展開されず、比較はカテゴリ コードに依存しません。いずれかの ⟨string⟩ 引数内の制御シーケンス トークンはトークン化解除され、文字列として扱われます。このコマンドは堅牢です。

したがって、正確に同じでない\ifstrequal{\testi}{...}限りはtrueを返しません。...\testi 文字列として

一方で、

\expandafter\ifstrequal\expandafter{\DDD}{2001-01-01 }{T}{F}

を返しますが、行末を検出しTて生成される末尾のスペースに注意してください。\read

\ifx

これはプリミティブな条件文であり、適切な構文で使用する必要があります。 は、\ifx ABトークンAとをB展開なしで比較します。 したがって、は と\ifx{\DDD}...比較されます。{\DDD

\ifcsequal

\ifcsequal{⟨csname⟩}{⟨csname⟩}{⟨true⟩}{⟨false⟩}
と同様ですが\ifdefequal、制御シーケンス名を引数として取る点が異なります。

したがって、はと\ifcsequal{\testi}{\DDD}の両方を展開するので、 を実行するのと同じになり、構築された 2 つの制御シーケンスはどちらも と同等であるため、 false を返します。\testi\DDD\ifcsequal{2001-01-01}{2001-01-01 }\relax

\ifdefequal

ここでようやくtrueを返すコードが出てきます。

\def\testiii{2001-\TwoDigits{\the\month}-\TwoDigits{\the\day} }%

その後\ifdefequal{\testiii}{\DDD}戻ってくる間違い、これは最初のレベルの拡張のみを参照するからです。一方、\edefバージョンは機能します。

\IfStrEq

これは引数を完全に展開します (通常の条件下で)。そのため、 または との比較が\testiiii機能\testiiiiします。

堅牢性

の堅牢性は\ifstrequalまったく関係ありません。まあ、実際にはまったく関係ありません。TeXエンジンがサポートしている場合\expanded(数週間以内にTeX Live 2019のリリースですべてサポートされます)、次のようなものになります。

\expanded{\ifstrequal}{\testiii}{\DDD}{T}{F}}

が戻ってきます。これが機能するには、Tの堅牢性が決定的な要素となります。\ifstrequal

動作テストを使用してください。

関連情報