
3 つのブランチを持つ\comparator
、拡張可能なコマンドを設計したいと思います。fpeval
- 真の枝比較が1に等しい場合
- 偽の枝比較がゼロに等しい場合
- 無効なブランチ比較が実行できない場合(コンパイルエラーを返す代わりに)
現在使用しているコードは次のとおりです。
\documentclass[preview = true, varwidth = true]{standalone}
\usepackage{xparse}
\usepackage{xfp}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\compare}{r[] m m m m m}{
\compare_evaluation:eeennn{#1}{#2}{#3}{#4}{#5}{#6}
}
\cs_new:Nn \compare_evaluation:nnnnnn{
\compare_result:ennn{\fpeval{#2 #1 #3}}{#4}{#5}{#6}
}
\cs_new:Nn \compare_result:nnnn{
\str_case:nnTF{#1}{
{0}{#3}
{1}{#2}
}{}{#4}
}
\cs_generate_variant:Nn \compare_evaluation:nnnnnn{eeennn}
\cs_generate_variant:Nn \compare_result:nnnn{ennn}
\ExplSyntaxOff
\begin{document}
\begin{tabular}{c}
\compare[<]{1.5}{2.5}{true}{false}{invalid} \\
\compare[<]{2.5}{1.5}{true}{false}{invalid} \\
\compare[<]{xx}{xx}{true}{false}{invalid} \\ % CRASHES
\end{tabular}
\end{document}
もちろん、テストの最後の行ではクラッシュします。
質問:コンパイル可能にして正しく分岐させるにはどうすればよいですか (ここで印刷しますinvalid
)?
答え1
拡張性が必須でない場合は、正規表現を使用して構文をチェックすることができます。
\documentclass[preview = true, varwidth = true]{standalone}
% These only needed in old latex releases
% \usepackage{xparse}
% \usepackage{xfp}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\compare}{r[] m m m m m}{
\compare_evaluation:eeennn{#1}{#2}{#3}{#4}{#5}{#6}
}
\cs_new:Nn \compare_evaluation:nnnnnn{
\regex_match:nnTF
{^[0-9]*(\.[0-9]*)?([eE][0-9]+)?@@@[0-9]*(\.[0-9]*)?([eE][0-9]+)?$}
{#2@@@#3}
{
\compare_result:ennn{\fpeval{#2 #1 #3}}{#4}{#5}{#6}
}
{#6}
}
\cs_new:Nn \compare_result:nnnn{
\str_case:nnTF{#1}{
{0}{#3}
{1}{#2}
}{}{#4}
}
\cs_generate_variant:Nn \compare_evaluation:nnnnnn{eeennn}
\cs_generate_variant:Nn \compare_result:nnnn{ennn}
\ExplSyntaxOff
\begin{document}
\begin{tabular}{c}
\compare[<]{1.5}{2.5}{true}{false}{invalid} \\
\compare[<]{2.5}{1.5}{true}{false}{invalid} \\
\compare[<]{2.5e2}{15e3}{true}{false}{invalid} \\
\compare[<]{xx}{xx}{true}{false}{invalid} \\ % CRASHES
\end{tabular}
\end{document}
ここでは、区切り文字として使用しても安全であると想定しました@@@
。2 つの引数に別々に正規表現を使用したり、カスタム コマンド トークンを使用したりすることもできますが、これは基本的な考え方を示しています。また、正規表現は、エッジ ケースでは l3fp とまったく同じ構文ではない可能性があります (fp 式はカバーされません) が、主要なリテラル構文をキャッチします。