當 fpeval 無法計算表達式時分支到某處

當 fpeval 無法計算表達式時分支到某處

我想設計一個\comparator可擴展的命令,它依賴fpeval有 3 個分支:

  • 真分支當比較等於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}

這裡我假設@@@可以安全地用作分隔符,您可以分別在兩個參數上使用正規表示式,或使用自訂命令 tken,但這顯示了基本思想。此外,在邊緣情況下,正規表示式可能與 l3fp 的語法不完全相同(並且不涵蓋 fp 表達式),但捕獲主要的文字語法。

相關內容