83

As the title implies, I would like to use LaTeX to keep a personal diary. I've been dumping my entries in a single file which has become unwieldy over time. Ideally I'd find a package (or collection of shell scripts) which assists me in maintaining a consistent directory structure and automatically headlining entries with their respective date.

I haven't found anything relevant in the CTAN repository, so I'm turning to you for advice. If there's no readily available solution, I might sit down and learn how to create custom packages.

Thank you very much!

5
  • 2
    Do you want to just throw in some entries with a date and let LaTex order them, or do you just want some consistent look and are willing to take care of the ordering yourself? Aug 24, 2012 at 2:04
  • 1
    A consistent look is important to me. Ideally it would suffice to put an entry into files with a path matching the pattern /year/month/day.tex, and LaTeX would take care of putting the entries at the right place and include the date of writing in a pleasant-looking fashion. Aug 24, 2012 at 9:37
  • 6
    Depending on how comfortable you feel with Emacs, you might want to look at org-mode (orgmode.org), and then export to TeX when you want to "generate" a nicely typeset version of your journal.
    – mvarela
    Aug 24, 2012 at 14:40
  • 1
    \def\entry{\readthoughts{\today}}\par\entry Jul 18, 2013 at 9:49
  • 2
    I just read the question and thought "what you really want is Org-mode". But @mvarela beat me to it...
    – mbork
    Nov 17, 2013 at 19:47

4 Answers 4

69

As you can't comment yet, here's a proposition using the tufte-latex class and a custom environment. This is just what I made up, you could edit your question to specify what format and features you would like. The lipsum package is just used for some dummy text.

\documentclass{tufte-book}
\usepackage{lipsum}

\newenvironment{loggentry}[2]% date, heading
{\noindent\textbf{#2}\marginnote{#1}\\}{\vspace{0.5cm}}

\begin{document}


\begin{loggentry}{2009-Oct-31}{Snow}
    \lipsum[1]
\end{loggentry}

\begin{loggentry}{2010-Dez-31}{Water of Life}
    \lipsum[2]
\end{loggentry}

\begin{loggentry}{2011-Nov-15}{Cold}
    \lipsum[3-5]
\end{loggentry}

\begin{loggentry}{2012-Aug-24}{Sunrise}
    \lipsum[6-7]
\end{loggentry}

\end{document}

enter image description here


Edit 1: Here's an automated version. It assumes your directory to be of the form /Year/Month/Day.tex, formatted as e.g. 2012/Aug/24.tex, so the month is just the first three letters. The individual .tex files have only the requirement to have the first line as \mytitle{<The actual title here>}.

This solutions makes use of Peter Grill's answer to "How to iterate through the name of files in a folder".

The main file:

\documentclass{tufte-book}
\usepackage{lipsum}
\usepackage{tikz}
\usepackage{xifthen}

\newenvironment{loggentry}[2]% date, heading
{\noindent\textbf{#2}\marginnote{#1}\par}{\vspace{0.5cm}}

\def\?#1{}

\pgfmathtruncatemacro{\StartYear}{2008}
\pgfmathtruncatemacro{\EndYear}{2012}

\newcommand{\writetitle}{0}
\newcommand{\mytitle}[1]
{   \ifthenelse{\writetitle=1}{#1}{}
}

\newread\mysource

\begin{document}

\foreach \Year in {\StartYear,...,\EndYear}
{   \foreach \Month in {Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec}
    {   \foreach \Day in {1,...,31}
        {   \IfFileExists{\Year/\Month/\Day}
                {   \openin\mysource=\Year/\Month/\Day.tex
                    \read\mysource to \firstline
                    \closein\mysource
                    \xdef\writetitle{1}
                    \begin{loggentry}{\Year - \Month - \Day}{\firstline}    
                        \xdef\writetitle{0}
                        \input{\Year/\Month/\Day}
                    \end{loggentry} 
        }
        {   % files does not exist, so nothing to do
        }

        }  
    }
}

\end{document}

A sample log entry file:

\mytitle{Something happened}
\lipsum[3-5]

The Output:

enter image description here

10
  • 1
    The OP's question seems to imply that one problem s/he faces is that there are many entries, so keeping them in a single file is not practical. Your answer could be improved by replacing \lipsum by the appropriate \input commands, perhaps putting each logentry in a separate file as you see fit. Aug 24, 2012 at 8:50
  • 1
    Your sample looks very pretty, thank you very much. As I stated in a comment above, I would like to put entries in files /year/month/day.tex and having LaTeX do the labour of figuring out the right order and headlining every entry with the date of its writing (extracted from the path name). I might write a shell script, but perhaps you can think of some other means. Aug 24, 2012 at 9:44
  • 1
    It is very nice! The only problem is that it looks for all the possible files. I believe that \write18 (aka --shell-escape) could be used to get the list of really existing files. Something like ls */*/* | sed 's/^/\\input' > ls.tex. Sorry, I have no experience with sheel escape, as well it is OS-dependent.
    – yo'
    Aug 24, 2012 at 12:36
  • 1
    I don't know how that will be once you piled up 1000 files, but I was surprised how fast it compiled, given that in the given configuration it checks for 5*12*31=1860 files. Aug 24, 2012 at 12:41
  • 2
    Thank you - it helps me a lot in creating a personal journal template. Just want to mention that \marginpar works if you just want to use the article style instead of tufte-book..
    – M-V
    Oct 3, 2012 at 11:14
19

My new code for diaries is as follows. It adds a note on the side, but without a box because it uses the marginnote package.

The environment file input.tex

\usepackage[top=4cm, bottom=2cm, outer=5cm, inner=2cm, heightrounded, marginparwidth=3.5cm, marginparsep=0.75cm]{geometry}

\newcommand{\mybox}[1]{%
\marginnote{{\color{red}CAUTION!}\\{#1}}
}

\newlength\sidebar
 \newlength\envrule
 \newlength\envborder
 \setlength\sidebar{1.5mm}
 \setlength\envrule{0.4pt}
 \setlength\envborder{2mm}

\makeatletter
 \long\def\fboxs#1{%
   \leavevmode
   \setbox\@tempboxa\hbox{%
     \color@begingroup
       \kern\fboxsep{#1}\kern\fboxsep
     \color@endgroup}%
   \@frames@x\relax}
 \def\frameboxs{%
   \@ifnextchar(%)
     \@framepicbox{\@ifnextchar[\@frameboxs\fboxs}}
 \def\@frameboxs[#1]{%
   \@ifnextchar[%]
     {\@iframeboxs[#1]}%
     {\@iframeboxs[#1][c]}}
 \long\def\@iframeboxs[#1][#2]#3{%
   \leavevmode
   \@begin@tempboxa\hbox{#3}%
     \setlength\@tempdima{#1}%
     \setbox\@tempboxa\hb@xt@\@tempdima
          {\kern\fboxsep\csname bm@#2\endcsname\kern\fboxsep}%
     \@frames@x{\kern-\fboxrule}%
   \@end@tempboxa}
 \def\@frames@x#1{%
   \@tempdima\fboxrule
   \advance\@tempdima\fboxsep
   \advance\@tempdima\dp\@tempboxa
   \hbox{%
     \lower\@tempdima\hbox{%
       \vbox{%
         %\hrule\@height\fboxrule
         \hbox{%
          \vrule\@width\fboxrule
           #1%
           \vbox{%
             \vskip\fboxsep
             \box\@tempboxa
             \vskip\fboxsep}%
           #1%
           }%\vrule\@width\fboxrule}%
         }%\hrule\@height\fboxrule}%
                           }%
         }%
 }
 \def\esefcolorbox#1#{\esecolor@fbox{#1}}
 \def\esecolor@fbox#1#2#3{%
   \color@b@x{\fboxsep\z@\color#1{#2}\fboxs}{\color#1{#3}}}
 \makeatother


 \definecolor{exampleborder}{HTML}{FE642E}
 \definecolor{examplebg}{HTML}{CEF6EC}
 \definecolor{statementborder}{rgb}{.9,0,0}
 \definecolor{statementbg}{rgb}{1,1,1}

 \newenvironment{eseframed}{%
   \def\FrameCommand{\fboxrule=\the\sidebar  \fboxsep=\the\envborder%
   \esefcolorbox{exampleborder}{examplebg}}%
   \MakeFramed{\FrameRestore}}%
  {\endMakeFramed}

%\renewcommand\dateTurkish{\def\today{\number\day~%
 %\ifcase \month \or Ocak\or Şubat\or Mart\or Nisan\or Mayıs\or Haziran\or
 %  Temmuz\or Ağustos\or Eylül\or Ekim\or Kasım\or Aralık\fi\space
 %\number\year}}
%\dateTurkish

 \newcounter{diary}
%\numberwithin{uygulama}
\renewcommand{\thediary}{\arabic{diary}}

 %%% CODE ENVIRONMENT. PUT TEXT INTO COLORED FRAME %%%
 \newenvironment{diary}[2]
 {\par\medskip\refstepcounter{diary}%
 \hbox{%
 \fboxsep=\the\sidebar\hspace{-\envborder}\hspace{-.5\sidebar}%
 \colorbox{exampleborder}{%
 \hspace{\envborder}\footnotesize\sffamily\bfseries%
 \textcolor{white}{{#1}\ {#2}\enspace\hspace{\envborder}}
%\today
 }
 }
 \nointerlineskip\vspace{-\topsep}%
 \begin{eseframed}\noindent\ignorespaces%
 }
 {\end{eseframed}\vspace{-\baselineskip}\medskip}

The diary files are stored in a separate folder e.g 2013 and files are stored in it. An example of diary file 2013.tex:

%2013 Notes
\begin{diary}{Hello!}{07.18.2013}
\mybox{Put some text here for caution.}
 \lipsum[1]
\end{diary}


\begin{diary}{Second entry.}{07.19.2013}
\mybox{Put some text here for caution.}
 \lipsum[2]
\end{diary}

Main file

\documentclass[a4paper]{book}
\usepackage{lipsum}
\usepackage{xcolor}
\usepackage{framed}
\usepackage{datetime}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{fourier}
\usepackage{marginnote}
\usepackage{tikz}

\input{input}

\title{\Huge My Diary}
\author{Someone}
\date{}
\begin{document}
\maketitle

\include{./2013/2013}
\end{document}

Output

enter image description here

Addendum

To use orange sidebar on left instead right, the input.tex file rearranged as follows:

\usepackage[top=4cm, bottom=2cm, outer=5cm, inner=2cm, heightrounded, marginparwidth=3cm, marginparsep=0.75cm]{geometry}

\newcommand{\mybox}[1]{%
\marginnote{{\color{red}CAUTION!}\\{#1}}
}

\newlength\sidebar
 \newlength\envrule
 \newlength\envborder
 \setlength\sidebar{1.5mm}
 \setlength\envrule{0.4pt}
 \setlength\envborder{2mm}

\makeatletter
 \long\def\fboxs#1{%
   \leavevmode
   \setbox\@tempboxa\hbox{%
     \color@begingroup
       \kern\fboxsep{#1}\kern\fboxsep
     \color@endgroup}%
   \@frames@x\relax}
 \def\frameboxs{%
   \@ifnextchar(%)
     \@framepicbox{\@ifnextchar[\@frameboxs\fboxs}}
 \def\@frameboxs[#1]{%
   \@ifnextchar[%]
     {\@iframeboxs[#1]}%
     {\@iframeboxs[#1][c]}}
 \long\def\@iframeboxs[#1][#2]#3{%
   \leavevmode
   \@begin@tempboxa\hbox{#3}%
     \setlength\@tempdima{#1}%
     \setbox\@tempboxa\hb@xt@\@tempdima
          {\kern\fboxsep\csname bm@#2\endcsname\kern\fboxsep}%
     \@frames@x{\kern-\fboxrule}%
   \@end@tempboxa}
 \def\@frames@x#1{%
   \@tempdima\fboxrule
   \advance\@tempdima\fboxsep
   \advance\@tempdima\dp\@tempboxa
   \hbox{%
     \lower\@tempdima\hbox{%
       \vbox{%
        \hrule\@height\fboxrule
       %  \hbox{%
        %  \vrule\@width\fboxrule

           #1%
           \vbox{%
             \vskip\fboxsep
             \box\@tempboxa
             \vskip\fboxsep}%
           #1%
           }\vrule\@width\fboxrule}%
         }%\hrule\@height\fboxrule}%
                          % }%
        % }%
 }
 \def\esefcolorbox#1#{\esecolor@fbox{#1}}
 \def\esecolor@fbox#1#2#3{%
   \color@b@x{\fboxsep\z@\color#1{#2}\fboxs}{\color#1{#3}}}
 \makeatother


 \definecolor{exampleborder}{HTML}{FE642E}
 \definecolor{examplebg}{HTML}{CEF6EC}
 \definecolor{statementborder}{rgb}{.9,0,0}
 \definecolor{statementbg}{rgb}{1,1,1}

 \newenvironment{eseframed}{%
   \def\FrameCommand{\fboxrule=\the\sidebar  \fboxsep=\the\envborder%
   \esefcolorbox{exampleborder}{examplebg}}%
   \MakeFramed{\FrameRestore}}%
  {\endMakeFramed}


 \newcounter{diary}
%\numberwithin{uygulama}
\renewcommand{\thediary}{\arabic{diary}}

 %%% CODE ENVIRONMENT. PUT TEXT INTO COLORED FRAME %%%
 \newenvironment{diary}[2]
 {\par\medskip\refstepcounter{diary}%
 \hbox{%
 \fboxsep=\the\sidebar\hspace{-\envborder}\hspace{-0.5\sidebar}%
 \colorbox{exampleborder}{%
 \hspace{\envborder}\footnotesize\sffamily\bfseries%
 \textcolor{white}{{#1}\ {#2}\enspace\hspace{\envborder}}
%\today
 }
 }
 \nointerlineskip\vspace{-\topsep}%
 \begin{eseframed}\noindent\ignorespaces%
 }
 {\end{eseframed}\vspace{-\baselineskip}\medskip}

And the output is as:

enter image description here

21
  • Nice work there! I am trying to use your code, but I get the error file ended while scanning the use of \@newenv plus you have a } missing at diary.tex at the very last line.
    – Thanos
    Nov 14, 2013 at 10:43
  • 1
    Did you test it? It throws tens of errors.
    – egreg
    Nov 14, 2013 at 11:05
  • @egreg I added {} at the end of the diary.tex but I get that i.imgur.com/T68DD2h.png It produces 30 errors indeed...
    – Thanos
    Nov 14, 2013 at 11:10
  • I updated my answer.
    – user31034
    Nov 14, 2013 at 16:40
  • @ferahfeza: How can this be used with a different paper size, like a4 or b5?
    – Thanos
    Nov 15, 2013 at 16:07
2

This answer does not address the issue of file management, but offers a new way to keep diaries with LaTeX, so I posted it here anyway.

The package jwjournal

There is now a new document class jwjournal for keeping diaries, available on CTAN.

Its main principle is simplicity. It allows you to turn simple pure text entry like

2023-01-01 Sunny --- Botanical Garden

  Today I visited the botanical garden!

  [Food] And had ice-cream for lunch!

into colorful journal like this:

enter image description here

alternatively, with the class option color entry turned on:

enter image description here

For those who are used to other date formats like mm-dd-yyyy or dd-mm-yyyy, you may use the class option month-day-year or day-month-year, and write the date string as you usually do.

It is also OK to use / instead of - in the date string.

Notice that the conversion of 2023-01-01 to January 1, 2023 is automatic, and it will also calculate that this date is Sunday (the calculation, done by projlib-date, currently only works for modern dates, but this shouldn't be a problem here). This feature has multilingual support, thus if you write \UseLanguage{French} in the preamble, the result would be like:

enter image description here

And about the color, each day of the week has a corresponding color, which of course can be modified as your preference:

enter image description here

I have wrote detailed explanation in the README file, and there are also three demo documents in English, French and Chinese, respectively.


About daily usage

About daily usage, I prefer to keep each month's journals in separate files, so journal-2023-01.tex, journal-2023-02.tex, etc. (since I only write a few sentences each day).

Of course, it is also possible to write each day's journal in separate (sub)files and input them in the main catalog. This way each subfile would be as clean as

2023-01-01 Weather --- Location

  Some text...

...

And since it is important, I shall repeat here this point already noted in the README:

The main features are achieved with the power of LaTeX3's regex functionality. It scans the content paragraph by paragraph and converts recognized patterns into corresponding TeX commands. [...] However, this comes with a price: in order to scan the content, it is firstly stored in a macro \g_jwjournal_content_tl, which means that you cannot use commands like \verb in your main text.

However, if you really need to input code, \lstinline from the package listings seems to work finely.



About the class name, and acknowledgement

One may think that the class name comes from my own name Jinwen, but it is actually due to my college roommate Jiawei (this lucky coincidence motivated me to name this class jw...). He suggested me to make something with LaTeX to help keeping diaries, and suggested the current syntax (he also suggested that the day of the week should be calculated automatically once the date is given, which really got me thinking for quite some time). I would like thus to express my gratitude for him, without whom this project would not have been born.

1

Have a look at https://ankursinha.in/2016/03/05/calliope-helping-you-keep-a-diary-in-latex.html.

It is a simple bash script that makes it easy to use LaTeX for journal keeping - most useful for keeping research journals! The source code is on https://github.com/sanjayankur31/calliope .

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .