在个人日记中计算日子和年份

在个人日记中计算日子和年份

下面的代码取自这个帖子。是否可以创建一个包含所有不同年份的序列/数组,以及另一个包含每年有多少个条目的序列/数组?

\documentclass{tufte-book}
\usepackage{datenumber, ifthen, xparse}
\usepackage{lipsum}
\setstartyear{2000}
\newcounter{day}

\ExplSyntaxOn

% Declare variables
\seq_new:N \g_journal_seq
\seq_new:N \g_journal_out_seq
\iow_new:N \g_journal_stream
\tl_new:N \l_journal_date_tl

% At the beginning of the run, read the lines of the `.jrn` file into a sequence.
% These are the dates. If the file can not be opened, it probably does not exists
% and we treat it as empty.
\cs_new:Npn \readjournaldates {
  \ior_open:NnT \g_journal_stream { \c_sys_jobname_str.jrn } {
    \ior_map_inline:Nn \g_journal_stream {
      \seq_gput_right:Nn \g_journal_seq { ##1 }
    }
    \ior_close:N \g_journal_stream
  }
}

% The main environment:
\NewDocumentEnvironment{ newday }{ O{} }{
  \stepcounter{day}
  % If the sequence \g_journal_seq is not empty yet, then we already saved a date
  % for the current day. Save this day in `\l_journal_date_tl` and delete it from
  % the sequence. Otherwise we have not saved anything yet, so we choose the current
  % date.
  \seq_gpop_left:NNF \g_journal_seq \l_journal_date_tl {
    \tl_set:Nx \l_journal_date_tl {\datedayname,~\today}
  }
  % Now we have to save the choosen date for the next run. First, only store it in the
  % sequence `\g_journal_out_seq`, we only write it to the file at the end to avoid
  % overwriting the file if something fails:
  \seq_gput_right:NV \g_journal_out_seq \l_journal_date_tl
  \textbf{ #1 }
  \marginnote{ \l_journal_date_tl } \\
}{
  \vspace{0.5cm}
}

% At the end of the document, iterate over `\g_journal_out_seq` and write every entry
% into a line
\AtEndDocument{
  \iow_open:Nn \g_journal_stream { \c_sys_jobname_str.jrn }
  \seq_map_inline:Nn \g_journal_out_seq {
    \iow_now:Nn \g_journal_stream { #1 }
  }
  \iow_close:N \g_journal_stream
}

\ExplSyntaxOff

\makeatletter
\readjournaldates
\makeatother
% ---------------
\begin{document}
\begin{newday}[A day]
  \lipsum[1]
\end{newday}

\begin{newday}[Yet another day]
  \lipsum[2]
\end{newday}
\begin{newday}
  \lipsum[3]
\end{newday}
\end{document}

比如说,我们将两个数组分别命名为\years\entriesperyear,假设一共输入了四天,其中三天是2018年,一天是2019年。那么应该是:

\years(1) = 2018, \years(2) = 2019, \entriesperyear(1) = 3, \entriesperyear(2) = 1

答案1

这个答案实际上并没有使用数组,而是使用属性列表。这是一个 expl3 数据结构,允许使用 迭代条目,\prop_map_inline:Nn或使用 访问单个条目\prop_get:NnN。作为演示,我们将在日记的末尾打印一个列表,其中包含每年的条目数:

\documentclass{tufte-book}
\usepackage{datenumber, ifthen, xparse}
\usepackage{lipsum}
\setstartyear{2000}
\newcounter{day}

\ExplSyntaxOn

\cs_generate_variant:Nn \prop_get:NnNF { NfNF }
\cs_generate_variant:Nn \prop_gput:Nnn { Nff }
% Declare variables
\seq_new:N \g_journal_seq
\seq_new:N \g_journal_out_seq
\iow_new:N \g_journal_stream
\tl_new:N \l_journal_date_tl
\prop_new:N \g_journal_years_prop

% At the beginning of the run, read the lines of the `.jrn` file into a sequence.
% These are the dates. If the file can not be opened, it probably does not exists
% and we treat it as empty.
\cs_new:Npn \readjournaldates {
  \ior_open:NnT \g_journal_stream { \c_sys_jobname_str.jrn } {
    \ior_map_inline:Nn \g_journal_stream {
      \seq_gput_right:Nn \g_journal_seq { ##1 }
      \prop_get:NfNF \g_journal_years_prop { \tl_head:n { ##1 } } \l_tmpa_tl {
        \tl_set:Nn \l_tmpa_tl { 0 }
      }
      \prop_gput:Nff \g_journal_years_prop { \tl_head:n { ##1 } } {
        \int_eval:n { \l_tmpa_tl + 1 }
      }
    }
    \ior_close:N \g_journal_stream
  }
}

% The main environment:
\NewDocumentEnvironment{ newday }{ O{} }{
  \stepcounter{day}
  % If the sequence \g_journal_seq is not empty yet, then we already saved a date
  % for the current day. Save this day in `\l_journal_date_tl` and delete it from
  % the sequence. Otherwise we have not saved anything yet, so we choose the current
  % date.
  \seq_gpop_left:NNF \g_journal_seq \l_journal_date_tl {
    \tl_set:Nx \l_journal_date_tl { { \int_use:N \c_sys_year_int } \datedayname,~\today}
    \prop_get:NfNF \g_journal_years_prop { \int_use:N \c_sys_year_int } \l_tmpa_tl {
      \tl_set:Nn \l_tmpa_tl { 0 }
    }
    \prop_gput:Nff \g_journal_years_prop { \int_use:N \c_sys_year_int } {
      \int_eval:n { \l_tmpa_tl + 1 }
    }
  }
  % Now we have to save the choosen date for the next run. First, only store it in the
  % sequence `\g_journal_out_seq`, we only write it to the file at the end to avoid
  % overwriting the file if something fails:
  \seq_gput_right:NV \g_journal_out_seq \l_journal_date_tl
  \textbf{ #1 }
  \marginnote{ \tl_tail:N \l_journal_date_tl } \\
}{
  \vspace{0.5cm}
}

% At the end of the document, iterate over `\g_journal_out_seq` and write every entry
% into a line
\AtEndDocument{
  \iow_open:Nn \g_journal_stream { \c_sys_jobname_str.jrn }
  \seq_map_inline:Nn \g_journal_out_seq {
    \iow_now:Nn \g_journal_stream { #1 }
  }
  \iow_close:N \g_journal_stream
}

\ExplSyntaxOff

\makeatletter
\readjournaldates
\makeatother
% ---------------
\begin{document}
\begin{newday}[A day]
  \lipsum[1]
\end{newday}

\begin{newday}[Yet another day]
  \lipsum[1]
\end{newday}
\begin{newday}
  Today I couldn't even think about a title.
\end{newday}

\begin{newday}[Yet another day]
  Some very interesting text.
\end{newday}

\ExplSyntaxOn
\prop_map_inline:Nn \g_journal_years_prop {
  During~#1~there~have~been~#2~entries.~
}

% If you really want two "arrays"
\seq_new:N \g_journal_years_seq
\seq_new:N \g_journal_yearentries_seq
\prop_map_inline:Nn \g_journal_years_prop {
  \seq_gput_right:Nn \g_journal_years_seq { #1 }
  \seq_gput_right:Nn \g_journal_yearentries_seq { #2 }
}
\cs_new:Npn \years #1 {
  \seq_item:Nn \g_journal_years_seq { #1 }
}
\cs_new:Npn \entriesperyear #1 {
  \seq_item:Nn \g_journal_yearentries_seq { #1 }
}
\ExplSyntaxOff

In \years{2} we got \entriesperyear{2} entries.
\end{document}

在此处输入图片描述

相关内容