
Я хотел бы скрыть разделы моего документа в соответствии с датой их публикации.
Вот как я определяю свой раздел:
\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 цифр, иногда два года.
Я посчитал, что для этого необходимо предпринять следующие шаги:
- Извлеките все 4-символьные числа с помощью этого регулярного выражения
[0-9]{4}
и вставьте их в массив. - Отфильтруйте список, чтобы оставить только наибольшее значение (используя пузырьковую сортировку или аккумулятор).
- Определим это значение как
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
макрос (в обоих случаях вы получаете абсолютно одинаковые токены), я заменил его кодом, который показывает, какая ветвь выбрана.