# then Then is a minimalist plain text file calendar inspired by [When](https://www.lightandmatter.com/when/when.html). It aims to have simple syntax for the average scheduling case. Then supports recurring events at least as complex as average calendar apps. # .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, which is a list of conditions separated by whitespace. Parameters can be written in any order. ## Simple examples This syntax should cover the vast majority of events ``` 2025 Jan 1 00:00-03:00, Work party 2025 Jan 1 04:00, Go to bed 2025 Feb 13, Project due Jan 1, New Year's Day (Jan 1 every year) Tue, Taco night (Every Tuesday) 1, Mortgage due (1st of every month) Mon Wed Fri, Submit TPS Report (Every Monday, Wednesday, or Friday) 20:00 Fri, Friday Night Magic (Every Friday at 8pm) 09:00, Coffee (Every day at 9am) , Journal (Every day) ``` ## Adding details to events Any line starting with a `-` or `+` is attached to the nearest above event. This can be used for details about an event if you don't want to put everything on one line. ``` 2025 Jan 5 16:00, Doctor's Appointment - 123 Gentoo Road, San Francisco, CA 12345 - Dr. Elias Berkins, +1 (555)-123-1234 ``` ## Logical Operators (`|`, `!`) Parameters can be grouped with parentheses.\ `|` means or.\ `!` means not.\ `and` is always *implied* by whitespace ``` 1 | 15, Every 1st OR 15th Fri !13, Every Friday AND NOT the 13th Sun !(Dec 25), Every Sunday AND NOT December 25 2025 Aug 14, 2025 AND August AND the 14th 1 2, Every 1st AND 2nd (i.e. never) ``` ## Comparison Operators (`<`, `>`) `<` mean on or before.\ `>` mean on or after. This lets you express start and end dates. Note that these operators are **inclusive** of the date they operate on. I virtually always mean `<=` when writing `<` with a date, so the equals is omitted to reduce special characters. ``` Fri <(Sep 13 2024), Every Friday, ending September 13 2024 >(Jan 1 2025) <(Jan 15 2025), Every day from Jan 1 2025 through Jan 15 2025 2025 Jan >1 <15, Same as above expressed a different way >(Jul 15), All days from July 15 to Dec 31. ``` You can put a comparison operator in front of a group in these two cases: 1. The group includes a day, month, and year 2. The group includes a day and month For groups in parentheses if a day, month, and year is given, the date will be converted to a Modified Julian Date and works how you expect. ``` >(Dec 24 2025) <(Jan 4 2026), Christmas vacation ``` If groups have only a month and day, it will match every date from Jan 1 or until Dec 31. ``` >(Dec 24) <(Jan 4), Christmas vacation every year ``` ## First/last week(s) of Month (`W`, `L`) {N}W is the Nth set of 7 days of a month {N}L is the Nth-from-last set of 7 days of a month This is mostly useful for certain Holidays. ``` May 2W Sun, Mother's Day (Second Sunday of May) May 1L Mon, Memorial Day (Last Monday of May) ``` ## Modified Julian Date (`J%n+y`) Similar to When, Then supports using a Modified Julian Date as `J`. `J` is the number of days since midnight November 17, 1858. This can be used along with the modulo operator `%` to create more complex recurring events. ``` !(J%14-5), Every other Saturday !(J%14+2), Every other Saturday (on the other weeks) ``` Note, you can't put spaces in here like `!(J % 3)` because spaces are always interpreted as AND. This syntax sucks but is included because it's possible. It's on the outside edge of what Then is intended to support support while still meeting the primary goal of every parameter being a condition. It's included as a last resort to allow for "every N days" when necessary. You technically can express dates like "Repeat every 3 days between July 10-19 2025" as `>(Jul 10 2025) <(Jul 19 2025) !(J%3-2)`, but Then syntax is optimized for simple cases and gets klugey for complex recurring events. You should consider the much more powerful [Remind](https://dianne.skoll.ca/projects/remind/) instead if you're frequently making events like this. ## Deadline Recipe There is no distinction between a scheduled event and deadline but by using a less than operator `<` combined with some frequency you might create useful deadline reminders: ``` <(Aug 15 2025), Due 8/15 - Remind me every day <(Aug 15 2025) Mon, Due 8/15 - Remind me every Mon <(Aug 15 2025) J%2, Due 8/15 - Remind me every other day >(Aug 10 2025) <(Aug 15 2025), Due 8/15 - Start daily reminders on 8/10/2025 You technically could do this as well: <(Aug 15 2025) ((>(Aug 1 2025) J%2) | >(Aug 10 2025)), SomeProject - Due 8/15 - Bi-daily reminders starting 8/1 - Daily reminders starting 8/10 ``` # Why would I use this? 1. You live in an open source, offline, self-hosted cabin in the woods to escape the bloated, dystopian tech world 2. You want to manage your schedule directly in your text editor 3. It's fun Then is minimal and created to meet my personal use case. If your first thought was something about how the world runs on mobile phones or planning how to sync Then to *another* Calendar program to get so-and-so functionality, Then is the wrong tool and you'd probably be overcomplicating your workflow rather than simplifying it. ## Why would I use this over When? I love [When](https://www.lightandmatter.com/when/when.html)! 95% of my events are single dates or simple recurrences (e.g. bill due on 5th of month). Then was only created to slightly simplify When's syntax to remove special characters from average cases. 1. Parameter types in the date are inferred. The only 4-digit string that can appear in a date is the year. `y=1984` in `when` is simplified to `1984` in `then`. 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**: `* Dec 25, Christmas` or `m=dec & d=25, Christmas`\ **then**: `Dec 25, Christmas` **when**: `m=sep & w=mon & a=1, Labor Day`\ **then**: `Sep Mon 1W, Labor Day` ## Why would I use this over Remind? I love [Remind](https://dianne.skoll.ca/projects/remind/)! It is incredibly powerful! I am not a scheduling nerd and keep a very simple calendar. Then does 1% of what Remind does, *if that*. Particularly if you deal with events with unusual recurrence patterns, Remind is nicer than Then: Every 3 days between July 10-19 2025:\ **Remind**: `REM Jul 10 2025 *3 THROUGH Jul 19 2025`\ **then**: `>(Jul 10 2025) <(Jul 19 2025) !(J%3-2)` If you have any case on the edge of what Then supports, or far beyond, you should use Remind instead. # 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. [(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