¿Cómo comparar correctamente una cadena con un cs de una lectura?

¿Cómo comparar correctamente una cadena con un cs de una lectura?

El escenario: leer una fecha en un yyyy-mm-ddformulario de un archivo a un cs. Este CS luego se compara con una macro de 'fecha actual' para escribir algunos argumentos de una manera específica en un archivo externo. La macro del día actual está en la línea 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}}}

Esto funciona para etiquetar cosas, ya que \ref{yyyy-mm-dd}funciona según lo previsto. Al no tener extra \TODAYy luego usar \def'd Today, es la comparación la que no funciona. No etoolboxes \ifstrequallo que usé antes. Cada vez que cambiaba la fecha, usaba una sola \xdefy luego pasaba esa macro a a \ifx, y para que funcionara tenía que definir la fecha con un adjunto.editarLeer para mi asombro inserta un solo espacio después de lo que se ha leído.

Actualmente supuestamente estoy arreglando cosas, pero lo rompí de alguna manera y ahora no coincide en absoluto. El primer culpable fue que mi \TwoDigitscmd era robusto, cambiándolo de nuevo \defen lugar de \NewDocumentCommandarreglarlo. Este último es para comandos a nivel de usuario, así que lo dejaré escapar. Pero los resultados del mwe no me quedan claros.

0.txtcontiene una línea con 2001-01-01y una línea nueva después, como si se hubiera escrito una línea y se hubiera cerrado la salida.

Las preguntas:

  1. ¿Cuál es la forma "correcta" de comparar cosas (macro, cs, comando?) que (debería) expandirse a cadenas?
  2. ¿Por qué no \edeftrabajar \xdefaquí? Pensé que era una expansión completa y, de hecho, antes (mi control de versiones está casi ausente, así que no puedo dar un mwe por esto) funcionó.
  3. ¿Cuál es el significado de la robustez? ¿Existe una regla general sencilla sobre cuándo es necesario, obligatorio o irrelevante?
  4. Está trabajando con xstring's\IfStrEqual solosi se inserta en la definición de \datemacro, en lugar de entre corchetes de comparación, es decir, {\datemacro }. ¿Por qué?
  5. \ifstrequalsupuestamente no se expande; lo usé una vez en un comando para probar si un argumento es igual a &, esto funciona. ¿Se está convirtiendo el número 1 en lo que sea que se ingresó y no cuenta como una expansión?

editar: Olvidé \ifxque se usaba para macros, no para argumentos delimitados, lo siento.

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

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

Respuesta1

\ifstrequal

De la documentación de etoolbox:

\ifstrequal{⟨string⟩}{⟨string⟩}{⟨true⟩}{⟨false⟩}
Compara dos cadenas y ejecuta ⟨true⟩ si son iguales y ⟨false⟩ en caso contrario. Las cadenas no se expanden en la prueba y la comparación es independiente del código de categoría. Los tokens de secuencia de control en cualquiera de los argumentos ⟨string⟩ se detokenizarán y se tratarán como cadenas. Este comando es robusto.

Por lo tanto, \ifstrequal{\testi}{...}no devolverá verdadero a menos que ...sea exactamente igual que\testi como cuerdas.

Por otro lado,

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

volverá T, pero observe el espacio de seguimiento, que se genera al \readver un final de línea.

\ifx

Este es un condicional primitivo y debe usarse con su sintaxis adecuada: \ifx ABcompara los tokens Ay Bsin expansión. Entonces \ifx{\DDD}...se comparará {con \DDD.

\ifcsequal

\ifcsequal{⟨csname⟩}{⟨csname⟩}{⟨true⟩}{⟨false⟩}
Similar a \ifdefequalexcepto que toma nombres de secuencias de control como argumentos.

Por lo tanto, \ifcsequal{\testi}{\DDD}se expandirán ambos \testiy \DDD, por lo que es lo mismo que hacer \ifcsequal{2001-01-01}{2001-01-01 }que devuelve falso porque las dos secuencias de control construidas son equivalentes a \relax.

\ifdefequal

Aquí es donde finalmente obtienes que el código sea verdadero. Tenga en cuenta que si utiliza

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

entonces \ifdefequal{\testiii}{\DDD}regresaráFALSO, porque solo mira la expansión del primer nivel. Por otro lado, la \edefversión es la que funciona.

\IfStrEq

Esto amplía completamente sus argumentos (en condiciones normales), por lo que la comparación con o \testiiiifunciona \testiiii.

Robustez

La robustez de \ifstrequales completamente irrelevante. Bueno, en realidad no del todo. Si su motor TeX es compatible \expanded(todo lo será en unas pocas semanas, con el lanzamiento de TeX Live 2019), algo como

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

El retorno Ty la robustez \ifstrequalson decisivos para que esto funcione.

Utilice la prueba de trabajo.

información relacionada