개인 일지에 자동 날짜 표시

개인 일지에 자동 날짜 표시

나는 LaTeX를 사용하여 개인 일기를 작성합니다. 직접 입력할 필요 없이 모든 항목의 날짜를 자동으로 추적하는 환경을 만들고 싶습니다. 지금까지의 코드입니다

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

\ExplSyntaxOn

\iow_new:N \g_journal_stream
\seq_new:N \g_journal_seq

\NewDocumentEnvironment{ newday }{ o }{
  \addtocounter{day}{1}
  \seq_gput_right:Nx \g_journal_seq {
    { \arabic{day} }
    { \datedayname,~\today }
    { \IfValueTF{ #1 }{ #1 }{} }
  }
  \file_if_exist_input:n {\c_sys_jobname_str.jrn}
}{
  \int_compare:nNnT { \arabic{if_auxnewday_begun} } = { 1 }{
    \end{ auxnewday}
    \setcounter{if_auxnewday_begun}{0}
  }
}

\NewDocumentCommand{ \saveday }{ mmm }{
  \int_compare:nNnT { #1 } = { \arabic{day} }{
    \begin{ auxnewday }{#2}{#3}
    \setcounter{if_auxnewday_begun}{1}
  }
}

\NewDocumentEnvironment{ auxnewday } { mm }{
  \textbf{ #2 }
  \marginnote{ #1} \\
}{
  \vspace{0.5cm}
}

\AtEndDocument{
  \iow_open:Nn \g_journal_stream { \c_sys_jobname_str.jrn }
  \save_days:
  \iow_close:N \g_journal_stream
}

\cs_new_protected:Nn \save_days: {
  \seq_map_function:NN \g_journal_seq \__save_days:n
}

\cs_new_protected:Nn \__save_days:n {
  \iow_now:Nn \g_journal_stream {
    \saveday #1
  }
}

\ExplSyntaxOff

\begin{document}
\begin{newday}[A day]
\lipsum[1-5]
\end{newday}

\begin{newday}[Another day]
\lipsum[6-9]
\end{newday}
\end{document}

있는 그대로의 newday환경은 훨씬 단순한 버전보다 더 복잡한 버전일 뿐입니다.

\NewDocumentEnvironment{ newday }{ o }{
  \textbf{#1}
  \marginnote{ \datedayname,~\today } \\
}{
  \vspace{0.5cm}
}

제가 해결하고 싶은 문제는 다음과 같습니다. 오늘, 즉 2019년 2월 25일을 입력했다고 가정해 보겠습니다. newday해당 날짜가 끝날 때 코드가 해당 항목의 날짜를 변경하지 못하게 하려면 어떻게 해야 합니까?

나는 모든 날짜를 별도의 파일에 보관할 수 있다고 생각하면서 첫 번째 옵션을 코딩하기 시작했지만 .jrn컴파일할 때마다 파일을 덮어쓰게 되므로 쓸모가 없다는 것을 빨리 깨달았습니다.

이 문제를 해결하는 방법에 대한 아이디어가 있습니까?

편집하다문제가 있는 코드

\documentclass[justified, symmetric]{tufte-book}
\usepackage{ifoddpage, ifthen, xparse}
\usepackage[calc, showdow, english]{datetime2}
\DTMnewdatestyle{mydateformat}{%
  \renewcommand{\DTMdisplaydate}[4]{%
    \DTMshortweekdayname{##4},\space% short weekday,
    \DTMmonthname{##2}\nobreakspace%  (full) Month
    \number##3,\space% day,
    \number##1% year
  }%
  \renewcommand{\DTMDisplaydate}{\DTMdisplaydate}%
}
\DTMsetdatestyle{mydateformat}

\usepackage{lipsum}
\newcounter{day}
\title{Title}
\author{Author}
\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 exist 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 {\today}
  }
  % Now we have to save the chosen 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{\checkoddpage\ifoddpage \l_journal_date_tl \else\raggedleft \l_journal_date_tl \fi} \\
}{
  \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
\readjournaldates

\begin{document}
\maketitle
\pagenumbering{arabic}
\begin{newday}[A day]
  \lipsum[1]
\end{newday}

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

\begin{newday}[Ciao]
\lipsum[4]
\end{newday}

\begin{newday}[A day]
  \lipsum[1]
\end{newday}

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

\begin{newday}[Ciao]
\lipsum[4]
\end{newday}

\begin{newday}[A day]
  \lipsum[1]
\end{newday}

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

답변1

를 시작할 때마다 newday보조 파일에 이미 날짜가 설정되어 있는지 확인해야 합니다. 만약 있다면. 간단히 새 파일에 복사하면 됩니다. 그렇지 않으면 현재 날짜를 설정합니다.

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

맨 마지막에 쓰기 위해 파일만 열면 나머지 문서가 끝까지 해석된 경우에만 이전 파일을 덮어쓰게 되므로 컴파일이 실패하더라도 파일을 지우거나 정보를 잃어버리지 않습니다.

먼저 파일을 시퀀스로 읽는 대신 newday. 그러나 전체 실행 동안 하나의 파일 핸들을 점유해야 합니다. 한 블록의 파일을 읽으면 가능한 한 빨리 파일 핸들을 해제할 수 있습니다. 여기에 이미지 설명을 입력하세요

관련 정보