Como comparar uma string com um cs de uma leitura corretamente?

Como comparar uma string com um cs de uma leitura corretamente?

O cenário: lendo uma data em um yyyy-mm-ddformulário de um arquivo para um cs. Posteriormente, esse cs é comparado a uma macro de 'data atual' para gravar alguns argumentos de uma maneira específica em um arquivo externo. A macro do dia atual segue as linhas de

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

Isso funciona para rotular coisas, pois \ref{yyyy-mm-dd}funciona conforme o esperado. Não tendo nenhum extra \TODAYe depois usando \def'd Today, é a comparação que não está funcionando. etoolbox's \ifstrequalnão é o que eu usei antes. Sempre que a data mudava eu ​​usava um single \xdefe depois passava essa macro para a \ifx, e para que funcionasse tive que definir a data com um anexo.editarLeia, para minha surpresa, insere um único espaço depois de tudo o que foi lido.

Atualmente supostamente estou consertando as coisas, mas quebrei de alguma forma e agora não combina mais. O primeiro culpado foi que meu \TwoDigitscmd era robusto, mudando-o de volta para \defem vez de \NewDocumentCommandcorrigi-lo. O último é para comandos em nível de usuário, então deixarei isso escapar. Mas os resultados do mwe não são claros para mim.

0.txtcontém uma linha with 2001-01-01e uma linha new depois, como se uma linha tivesse sido escrita nele e a saída tivesse sido fechada.

As questões:

  1. Qual é a maneira 'certa' de comparar coisas (macro, cs, comando?) que (deveria) expandir para strings?
  2. Por que não \edef, \xdeftrabalhe aqui, pensei que fosse uma expansão completa e, de fato, antes (meu controle de versão está quase ausente, então não posso dar a mínima para isso) funcionou.
  3. Qual é o significado da robustez? Existe uma regra simples quando é necessário, obrigatório ou irrelevante?
  4. Está funcionando com xstring's\IfStrEqual apenasse the for inserido na definição de \datemacro, e não nos colchetes da comparação, ou seja, {\datemacro }. Por que?
  5. \ifstrequalsupostamente não se expande - usei uma vez em um comando para testar se um argumento é igual a &, isso funciona - o número 1 está se tornando o que foi inserido e não conta como uma expansão?

editar: esqueci \ifxque era usado para macros, não para argumentos delimitados, desculpe.

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

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

Responder1

\ifstrequal

Da documentação de etoolbox:

\ifstrequal{⟨string⟩}{⟨string⟩}{⟨true⟩}{⟨false⟩}
Compara duas strings e executa ⟨true⟩ se forem iguais, e ⟨false⟩ caso contrário. As strings não são expandidas no teste e a comparação é independente do código de categoria. Os tokens de sequência de controle em qualquer um dos argumentos ⟨string⟩ serão destokenizados e tratados como strings. Este comando é robusto.

Portanto, \ifstrequal{\testi}{...}não retornará verdadeiro, a menos que ...seja exatamente igual a\testi como cordas.

Por outro lado,

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

retornará T, mas observe o espaço de traling, que é gerado ao \readver um fim de linha.

\ifx

Esta é uma condicional primitiva e deve ser usada com sua sintaxe adequada: \ifx ABcompara os tokens Ae Bsem expansão. Então \ifx{\DDD}...vou comparar {com \DDD.

\ifcsequal

\ifcsequal{⟨csname⟩}{⟨csname⟩}{⟨true⟩}{⟨false⟩}
Semelhante a, \ifdefequalexceto que usa nomes de sequências de controle como argumentos.

Assim \ifcsequal{\testi}{\DDD}, expandirá ambos \testie \DDD, portanto, é o mesmo que fazer, \ifcsequal{2001-01-01}{2001-01-01 }o que retorna falso porque as duas sequências de controle construídas são equivalentes a \relax.

\ifdefequal

É aqui que você finalmente faz com que o código retorne verdadeiro. Observe que se você usar

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

então \ifdefequal{\testiii}{\DDD}retornaráfalso, porque analisa apenas a expansão de primeiro nível. Por outro lado, a \edefversão é o que funciona.

\IfStrEq

Isso expande totalmente seus argumentos (sob condições normais), portanto a comparação com \testiiiiou \testiiiifunciona.

Robustez

A robustez de \ifstrequalé completamente irrelevante. Bem, não completamente, na verdade. Se o seu mecanismo TeX suportar \expanded(tudo será em algumas semanas, com o lançamento do TeX Live 2019), algo como

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

retornará Te a robustez \ifstrequalé decisiva para que isso funcione.

Use o teste de trabalho.

informação relacionada