1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
# then
then is a plain text calendar program inspired by [When](https://www.lightandmatter.com/when/when.html).
## Goals
- Recurring events
## Non-goals
- One line per event/day (might change this to how Remind works?)
- Nearest-weekday dates (e.g. the 'c' variable in `when`)
- Conditional recurrence like "Garbage day is every Tuesday except on Holidays" (I suggest [Remind](https://dianne.skoll.ca/projects/remind/) for this)
# `.then` file syntax
```
# COMMENT
DATE, EVENT
- DETAILS
```
- Lines beginning with `#` are comments used to annotate or group events together.
- Lines beginning with `-` are additional details attached to the above event.
- Blank lines are ignored.
- Otherwise, a line is an event. Everything before the first comma is interpreted as the date.
- Parameters in the date can be written in any order, whitespace delimited:
1. 4 digts is the year
2. A month can be written as a full word (January) or 3-character abbreviation (Jan)
3. Days can be full words or common abbreviations (R, Th, Thu, Thur, or Thurs, or Thursday are all acceptable)
4. NN:NN is the time. An end time can be given too as NN:NN-NN:NN with no space.
5. Nw is the Nth set of 7 days in a month, e.g. `2w`.
6. Nlw is the Nth-from-last set of 7 days in a month, e.g. `2lw`
```
# Simple Examples
2025 Jan 1 00:00-03:00, Work party
2025 Jan 1 04:00, Go to bed
Jan 1, New Year's Day (Jan 1 every year)
1, Mortgage due (1st of every month)
# `w` and `lw` parameters
May 2w Sun, Mother's Day (Second Sunday of May)
May 1lw Mon, Memorial Day (Last Monday of May)
# Logical Operators (`|` or, `!` not, `and` is implied by whitespace)
1 | 15, 1st OR 15th of month
Fri !(Dec 25), Every Friday, NOT December 25
1 2, 1st AND 2nd (i.e. never)
# Modified Julian Date Logic (`j` and `%`)
# We have to work on the syntax
!(j%14-5), Every other Saturday
# Details (Any lines prepended with - are attached to the above event)
2025 Jan 5 16:00, Doctor's Appointment
- 123 Gentoo Road, San Francisco, CA 12345
- Dr. Elias Berkins, +1 (555)-123-1234
```
Lines prefixed with `#` are comments and can be used to organize events into groups. When sorting events, all events under a comment will stay under that same comment.
# Why would I use this?
Calendars are some of the most integrated (yet privacy invasive) productivity applications. If you use Outlook or Google Calendar to share meetings and availability across a team or family, an offline, DIY-synced, text file with arcane syntax is not a suitable replacement.
For my personal calendar I used to use [Proton Calendar](https://proton.me/calendar), which by design is a hassle to share/export/automate. Rather than try to wrangle a third party calendar, I'm reinventing the wheel.
## Why would I use this *over When*?
I really like When (the Perl program) and then is objectively less powerful because it omits variables I never use. This let's me express days in a simpler syntax.
1. Parameter types are inferred. The only 4-digit `%d%d%d%d` string that can appear in a date is the year. `y=1984` in `when` is simplified to `1984` in `then`. This is possible by omiting the `e` (Easter), `z` (Day of year), and `c` (Nearest weekday) variables, and changing `a=1` and `b=2` to `1W` and `2LW`.
2. The `&` logical operator is implied by whitespace. `m=jan & d=1` in `when` is simplified to `Jan 1` in `then`.
In short, I think it looks nicer:
when: `m=dec & d=25, Christmas` or `* Dec 25, Christmas`
then: `Dec 25, Christmas`
when: `m=sep & w=mon & a=1, Labor Day`
then: `Sep Mon 1W, Labor Day`
# Alternatives
If you're interested in text file based calendars, the three GOATs are:
- [When](https://www.lightandmatter.com/when/when.html) - IMO, the simplest terminal calendar that's flexible enough for real world use.
- [Remind](https://dianne.skoll.ca/projects/remind/) - A **VERY** flexible, programmable calendar format. I can't imagine a scheduling case you couldn't cover. [(Better overview here.)](https://blog.thechases.com/posts/remind/)
- [Org Mode](https://orgmode.org) - The most flexible and expansive productivity playground for text (warning: endless time sink).
## See Also
- [Emacs Diary](https://www.gnu.org/software/emacs/manual/html_node/emacs/Format-of-Diary-File.html) - A single agenda/diary file.
- [Plain Text Personal Organizer](https://danlucraft.com/blog/2008/04/plain-text-organizer/)
- [Calendar.txt](https://terokarvinen.com/2021/calendar-txt/) - A one-day per line text calendar format inspired by [todo.txt](https://todotxt.org/). Very simple but high maintenence due to lack of repeating events, etc.
- Featureful TUI calendar/productivity apps like [Calcurse](https://calcurse.org/), [calcure](https://github.com/anufrievroman/calcure), [khal](https://github.com/pimutils/khal), and maybe [Taskwarrior](https://taskwarrior.org/). Often it's preferable to manage appointments via the program itself rather than directly editing a text file.
# License
MIT
|