Найдите самый высокий год в строке

Найдите самый высокий год в строке

Я хотел бы скрыть разделы моего документа в соответствии с датой их публикации.

Вот как я определяю свой раздел:

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

Эта команда определяется следующим образом:

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

Моя цель — заменить dueyearзначение команды primarySection, чтобы получить самый последний год строки в 4-м параметре.

В моем примере выше это Jan. 1930 - June 2023. Он не всегда имеет такую ​​форму, но всегда содержит как минимум один год из 4 цифр, иногда два года.

Я посчитал, что для этого необходимо предпринять следующие шаги:

  1. Извлеките все 4-символьные числа с помощью этого регулярного выражения [0-9]{4}и вставьте их в массив.
  2. Отфильтруйте список, чтобы оставить только наибольшее значение (используя пузырьковую сортировку или аккумулятор).
  3. Определим это значение как dueyearпеременную. В нашем примере это будет 2023.

Я начал работать с пакетом expl3, но поскольку я не очень хорошо знаю LaTeX, у меня возникли проблемы с получением желаемого результата...

На данный момент я могу извлечь только значения, соответствующие годам, но я не знаю, как создать с ними массив, и тем более, как их отсортировать и извлечь наибольшее значение...

Вот моя функция для определения и извлечения лет:

\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

Как мне изменить эту функцию так, чтобы она возвращала наибольший год из параметра, который я упомянул ранее?

Так что я могу вызвать его в своей primarySectionфункции и установить dueyearследующим образом:

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

Спасибо за помощь.

решение1

Год извлекается с помощью регулярного выражения [0-9]{4}. При этом \regex_extract_all:nnNвсе совпадения сохраняются в последовательности \l__Skay_dates_seq. Эта последовательность используется с \seq_use:Nnи ,между элементами. Затем maxвычисляется в пределах \fp_eval:n.

Результат присваивается макросу \dueyearс помощью \edef.

введите описание изображения здесь

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

решение2

Я бы с expl3этим согласился.

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

Поскольку я не могу понять ваш \secondarySectionмакрос (в обоих случаях вы получаете абсолютно одинаковые токены), я заменил его кодом, который показывает, какая ветвь выбрана.

введите описание изображения здесь

Связанный контент