carnet: a note taking logbook helper

Presentation

carnet(1) is a note taking logbook helper. It provides a way to record seamlessly journal entries, along automated recording of the time and date. As an option, it can also record all sorts of interesting information, like recorded calendar(1) activities, or what could be playing on music players like mocp(1).

The log book is a set of text files, one per week, made of entries separated by a time stamp, and specific markers to separate days of the week; this avoids exploding the file size of a long running log file typed for a while by a proficient writer, while also avoiding the explosion of file numbers that could appear with compulsive writers.

In a hurry? You can download the latest version at the bottom of this page, but you may want to go through the whole page if this is your first contact with the utility.

Warning: while the utility is now available to the public, there are several rough edges, several documented in the BUGS file, and probably many more that flown below my radar.

Use cases

Fulfill compulsive writing needs

The main purpose of carnet is to open a scratch pad in which to take notes that may be easily retrieved, without having to go through the hurdles of finding in which location to store the note, how to name the file, things like that. Just type in your prompt:

$ carnet

and boom! You can go ahead and type in your note in your favorite text editor:

2025-25.txt - semaine précédente
2025-27.txt - semaine suivante
2024-42.txt - première semaine

Journal de bord, an 2025, semaine 26

________________________________________________________________________
Date : dimanche (2025-06-29)

22:52 : sur fond de : Yes - Close To The Edge
J'aime bien le morceau en train de passer à la radio.  :)

carnet will try hard to pass the right options to start edition straight at the end of the file, after having appended all the timestamps and informations that give context to the entry. Only the last line, highlighted in the hard-copy here above, has been typed in. Of course, when a proficient writer fills thick entries, the decorum gives way to the content.

There also exists an option --activity which is purposed to gratify the writer with a sense of achievement after a well filled week:

$ carnet -a
       0   4   8  12  16  20  24  28  32  36  40  44  48  52  56  60  64  68  72  76  80  84  88
2024-42|===|===|===|===|===|===|===|===|===|===|===|=
2024-43|===|===|===|===|===|===
[…]
2025-25|===|===|===|===|===|===|===|===|===
2025-26|===|===|===|===|===|===|===|===|===|===|===|===|===|===|===|===|===|===|===|===|===
       0   4   8  12  16  20  24  28  32  36  40  44  48  52  56  60  64  68  72  76  80  84  88
Dist.: |        .O    |-------|=======#======|---------------|                            O    .
Deci.: |        -     -      - -   -  -   -  -  -            -                                 -
Perc.: |        ===   =+   ===## =+==#-+ #=# # +==  =    +   =                =           =    =
       0   4   8  12  16  20  24  28  32  36  40  44  48  52  56  60  64  68  72  76  80  84  88
Apparent size: 1233.9kiB  raw: 1300kiB  density: 94.91%
Mean apparent size per week: 33.3kiB  raw: 35.1kiB
Number of entries: 3117  of weeks: 37

The first part is the histogram per week, trimmed for the sake of brevity, showing the information stored in each week. Each character amounts for 1kiB. The second part paints a box-and-whiskers plot of the distribution of size of entries for each week, and the Deciles and Percentiles lines attempt to represent the same values with an ASCII heat map of activities per week. Yes, it takes some getting used to to notice that weekly activity happens following a pattern which resembles to a Poisson distribution; it will make more sense as entries are going to be added during day to day activities. Then some random information follows, with relation to the size occupancy of the carnet in the file system. The Deciles and Percentiles require the Perl variant of the carnet_activity script.

Fill a time sheet

I have found it tremendously beneficial to prepare time sheets thanks to the timestamped information stored in the carnet. As I work, I fire `carnet` to record what I do, for example :

________________________________________________________________________
Date : mardi (2025-06-24)

08:06 :
I arrived at the office.

10:13 :
Since I arrived, I worked on the foo project.

Date and timing information are automatically fed by carnet, I just have to write down what I was doing since the last entry. This can be especially useful if it is necessary to estimate time spent on given projects for whatever billing reason. This is where the --search function shines:

$ carnet -s '\<foo\>'
2025-25.txt : lundi (2025-06-17) : 10:01 :
I attended the kick-off meeting of the foo project.


________________________________________________________________________
2025-26.txt : mardi (2025-06-24) : 10:13 :
Since I arrived today, I worked on the foo project.

I note for myself an option to automatically calculate durations since last entry would be a plus for such use cases.

Information storage and retrieval

As seen above, the --search option takes regular expressions in argument that are directly fed to awk. This makes the retrieval of entries on a certain topics seamless to the extent that one is fluent with regular expressions. Let's say that I want to prepare a document summarising my activity of setting up and configuring my mail server; assuming I took good not of what I was doing, compulsively. Retrieving most of the information would look like:

$ carnet -s 'exim|mail'
[…]
________________________________________________________________________
2025-08.txt : vendredi (2025-02-21) : 19:31 :
En passant les mises à jour, j'ai vu passer des changements dans le
fichier de configuration de mon serveur mail motorisé par exim4.  J'ai
passé un peu de temps à faire le tri entre les nouveautés et mes propre
changements de configuration.
[…]

Note that this is an excerpt of the output. The full set of entries is actually much larger at the time of writing:

$ carnet -s 'exim|mail' | wc -l
936

Remark: assembling a Zettelkasten engine is not the goal of carnet, although it can contribute to the definition of slips upstream to their integration to a Zettelkasten. I may change my mind about this at some point, but I would first have to determine ways to flow through entries.

Dependencies

carnet presents itself as a shell script which, at t time, is mostly used on Debian 13 trixie and later. Portability issues are to be expected to other operating systems, having tested it on NetBSD 10 and witnessed several issues on that operating system level. The dependencies set is thus mostly usual, with a need for a Bourne compatible Shell like dash, coreutils, you name it.

carnet also requires a text editor and a pager, but one can bring one's own utilities. The idea is not to write a complete software suite, but glue together components appropriate to anyone's ergonomics.

carnet embeds a search function which works best with Gnu Awk, but alternate implementations like mawk proved to provide good enough search results too.

carnet also embeds a companion script written in Perl, to practically extract and report the activity in the carnet as weeks go on. Versions of carnet 1.0.y stuck to using shell scripting for the activity report if pulling the Perl interpreter is a big no-no. Note that carnet versions 1.1.y will need Perl for the activity report, but will otherwise run fine without it; this is merely a cosmetic option.

As mentioned above, certain utilities will enhance the content of the carnet, without impeding its usability when they are missing. A well maintained calendar(1) will be able to provide the schedule of the upcoming week when starting a new one, before listing the first entries. If playing music with MOC, the carnet will be capable of recording the track currently airing. None of these options are fundamental to the carnet, but are niceties to give context to some entries.

Installation

For the moment, carnet is rather confidential: I don't plan to provide operating system packages of it, unless there proves to be wide interest in carnet. To install it, download the latest version made available at the end of this page, verify its integrity and extract it. For example with the version 1.1.1:

$ gpg --verify carnet-1.1.1.tar.xz.asc 
gpg: assuming signed data in 'carnet-1.1.1.tar.xz'
gpg: Signature made Sun Jun 29 20:27:31 2025 CEST
gpg:                using RSA key 8F91B227C7D6F2B1948C8236793CF67E8F0D11DA
gpg: Good signature from "Étienne Mollier <emollier@emlwks999.eu>" [ultimate]
gpg:                 aka "Étienne Mollier <emollier@debian.org>" [ultimate]
gpg:                 aka "Étienne Mollier <etienne.mollier@mailoo.org>" [ultimate]
Primary key fingerprint: 8F91 B227 C7D6 F2B1 948C  8236 793C F67E 8F0D 11DA

$ tar xvf carnet-1.1.1.tar.xz 
carnet-1.1.1/
carnet-1.1.1/scripts/
carnet-1.1.1/scripts/gen_test_carnet.pl
carnet-1.1.1/BUGS
carnet-1.1.1/LICENSE
carnet-1.1.1/TODO
carnet-1.1.1/carnet_activity.pl
carnet-1.1.1/carnet
carnet-1.1.1/makefile
carnet-1.1.1/carnet.fodg

The carnet presents itself under the form of a shell script which may be installed, along companion script and manual page if applicable, using usual make targets:

$ make 
echo '[REPORTING BUGS]' > BUGS.roff
sed 's/^$/.PP/' BUGS >> BUGS.roff
help2man \
	--name 'note taking logbook helper' \
	--section 1 \
	--locale C.UTF-8 \
	--include BUGS.roff \
	--output carnet.1 \
	--no-info \
	./carnet
gzip --verbose --force --best --keep carnet.1
carnet.1:	50.5% -- created carnet.1.gz

$ sudo make install
mkdir -p /usr/local/bin
install carnet /usr/local/bin
chmod 0755 /usr/local/bin/carnet
install carnet_activity.pl /usr/local/bin
chmod 0755 /usr/local/bin/carnet_activity.pl
mkdir -p /usr/local/share/man/man1
install carnet.1.gz /usr/local/share/man/man1

But it can also be deployed by hand, to avoid the need to depend on html2man. The shell script carnet is mostly self sufficient, notably the argument --help provides most of the useful information transcribed automatically to the manual page. It is even useful even if its companion Perl script for the statistics activity page is not around; one would simply have to make without the --activity option.

Remark: carnet versions 1.0.y did not depend on the companion script for displaying activity statistics, at the cost of more difficult portability outside Debian, and a performance penalty of the shell script compared to the perl script.

Configuration

For now, most of the configurable options of the carnet are provided under the form of environment variables, but note that it has also been designed to avoid the need for extra configuration before getting started. Currently accounted environment variables are:

License

This software is copyright 2024-2025, Étienne Mollier. It is shipped under AGPL-3+, the Gnu Affero General Public License, at version 3 or any later version. See the LICENSE file for more details.

Download

Several versions are made available, to preserve history to some extent, especially while the git tree is not published. Note that each archive is signed with my gpg key 8F91 B227 C7D6 F2B1 948C 8236 793C F67E 8F0D 11DA advertised on my whoami page and also used for Debian Development purpose; thus it should be well known by multiple independent channels. Archives and signatures are available in the present directory:

[ICO]NameLast modifiedSize
[PARENTDIR]Parent Directory  -
[DIR]archives/2025-07-03 20:11 -
[   ]carnet-1.0.4.tar.xz2025-06-24 09:52 22K
[   ]carnet-1.0.4.tar.xz.asc2025-06-24 09:52 833
[   ]carnet-1.1.2.tar.xz2025-06-30 22:48 25K
[   ]carnet-1.1.2.tar.xz.asc2025-06-30 22:49 833
[   ]carnet-1.2.2.tar.xz2025-07-03 20:08 26K
[   ]carnet-1.2.2.tar.xz.asc2025-07-03 20:08 833
[   ]carnet-1.2.3.tar.xz2025-07-05 22:24 26K
[   ]carnet-1.2.3.tar.xz.asc2025-07-05 22:24 833
[   ]carnet-1.3.0.tar.xz2025-07-07 14:14 27K
[   ]carnet-1.3.0.tar.xz.asc2025-07-07 14:14 833
[IMG]carnet.svg2025-06-29 22:43 13K
Apache/2.4.63 (Debian) Server at 82.64.73.247 Port 80