Encuentra el año más alto en una cadena

Encuentra el año más alto en una cadena

Me gustaría ocultar secciones de mi documento según su fecha de publicación.

Así defino mi sección:

\primarySection
  {Data 1} 
  {Data 2}
  {Data 3}
  {Jan. 1930 - June 2023} % Dates
  {Data 4}

Este comando se define de la siguiente manera:

\newcommand*{\primarySection}[6][primary]{

  \def\dueyear{2018} % Value to be replaced.

  \ifnum\the\numexpr\year-5>\dueyear
    \secondarySection[primary]{#2}{#3}{#4}{#5}{#6}
  \else 
    \secondarySection[#1]{#2}{#3}{#4}{#5}{#6}
  \fi
}

Mi objetivo es reemplazar el dueyearvalor del primarySectioncomando para obtener el año más reciente de la cadena en el cuarto parámetro.

En mi ejemplo anterior es Jan. 1930 - June 2023. No siempre tiene esta forma, pero siempre contiene al menos un año de 4 dígitos, en ocasiones dos años.

Para hacer esto, pensé que los pasos necesarios serían:

  1. Extraiga todos los números de 4 caracteres con esta expresión regular [0-9]{4}e insértelos en una matriz.
  2. Filtre la lista para conservar solo el valor más grande (usando una clasificación de burbujas o un acumulador).
  3. Defina este valor como la dueyearvariable. En nuestro ejemplo, sería 2023.

Empecé a trabajar con el paquete expl3, pero como no conozco muy bien LaTeX, tengo problemas para obtener el resultado que quiero...

Por el momento solo puedo extraer los valores correspondientes a los años pero no sé como crear un array con ellos y menos como ordenarlos y extraer el valor mayor...

Aquí está mi función para detectar y extraer años:

\ExplSyntaxOn
  \NewDocumentCommand{\extractMostRecentDate}{m}{
    \tl_set:Nn \l_tmpa_tl {#1}
    \regex_extract_once:nnN {([0-9]{4})} {#1} \l_uiy_result_seq
    \seq_map_inline:Nn \l_uiy_result_seq {#1 - ##1}
  }
\ExplSyntaxOff

¿Cómo puedo modificar esta función para que devuelva el año más grande del parámetro que mencioné anteriormente?

Para poder llamarlo en mi primarySectionfunción para configurarlo dueyearasí:

\def\dueyear{\extractMostRecentDate{#4}}

Gracias por su ayuda.

Respuesta1

El año se extrae con la expresión regular [0-9]{4}. Con \regex_extract_all:nnNtodas las coincidencias se almacenan en la secuencia \l__Skay_dates_seq. Esta secuencia se utiliza con \seq_use:Nny ,entre los elementos. Luego maxse calcula dentro de \fp_eval:n.

El resultado se asigna a la macro \dueyearusando \edef.

ingrese la descripción de la imagen aquí

\documentclass[border=6pt]{standalone}
\newcommand{\dueyear}{}
\ExplSyntaxOn
\seq_new:N \l__Skay_dates_seq
\NewDocumentCommand { \extractMostRecentDate } { m }
  {
    \regex_extract_all:nnN { [0-9]{4} } {#1} \l__Skay_dates_seq
    \edef \dueyear { \fp_eval:n { max ( \seq_use:Nn \l__Skay_dates_seq { , } ) } }
  }
\ExplSyntaxOff
\begin{document}
\extractMostRecentDate{Jan. 1930 - June 2023}\dueyear;
\extractMostRecentDate{01/02/1934 - 05/06/1978}\dueyear
\end{document}

Respuesta2

Yo iría con expl3todo el tiempo.

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\primarySection}{O{primary}mmmmm}
 {
  \__sky_year_extract:n { #5 }
  \int_compare:nTF { \c_sys_year_int - 5 > \l__sky_year_recent_int }
   % replace the two following branches
   { not~recent~year~(\int_use:N \l__sky_year_recent_int) }
   { recent~year~(\int_use:N \l__sky_year_recent_int) }
 }

\int_new:N \l__sky_year_recent_int
\seq_new:N \l__sky_year_all_seq

\cs_new_protected:Nn \__sky_year_extract:n
 {
  \regex_extract_all:nnN { [0-9]{4} } { #1 } \l__sky_year_all_seq
  \seq_sort:Nn \l__sky_year_all_seq
   {
    \int_compare:nNnTF { ##1 } > { ##2 } { \sort_return_same: } { \sort_return_swapped: }
   }
  \int_set:Nn \l__sky_year_recent_int { \seq_item:Nn \l__sky_year_all_seq { 1 } }
 }

\ExplSyntaxOff

\begin{document}

\primarySection
  {Data 1} 
  {Data 2}
  {Data 3}
  {Jan. 1930 - June 2023} % Dates
  {Data 4}

\primarySection
  {Data 1} 
  {Data 2}
  {Data 3}
  {Jan. 1930 - June 2001} % Dates
  {Data 4}

\end{document}

Como no puedo encontrarle sentido a tu \secondarySectionmacro (terminas con exactamente los mismos tokens en ambos casos), la reemplacé con un código que muestra qué rama se toma.

ingrese la descripción de la imagen aquí

información relacionada