Ramifique para algo quando uma expressão não puder ser avaliada por fpeval

Ramifique para algo quando uma expressão não puder ser avaliada por fpeval

Eu gostaria de projetar um \comparatorcomando expansível que dependa de fpevaltrês ramificações:

  • ramo verdadeiroquando a comparação é igual a 1
  • ramo falsoquando a comparação é igual a zero
  • filial inválidaquando a comparação não pode ser realizada (em vez de retornar um erro de compilação)

Aqui está o código atual que uso:

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

que, é claro, trava na última linha do teste.

PERGUNTA:Como torná-lo compilável e ramificar corretamente (aqui para imprimir invalid)?

Responder1

Se a capacidade de expansão não for um requisito, você poderá verificar a sintaxe usando um regex

insira a descrição da imagem aqui

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

aqui presumi @@@que era seguro usar como separador, você poderia usar regex nos dois argumentos separadamente ou usar um comando personalizado tken, mas isso mostra a ideia básica. Além disso, o regex pode não ser exatamente a mesma sintaxe que l3fp em casos extremos (e não cobre expressões fp), mas captura as principais sintaxes literais.

informação relacionada