From 02f4c279c30f67d632317a8f0eac64bb3efcfc9b Mon Sep 17 00:00:00 2001 From: Historia Date: Wed, 26 Jun 2024 20:56:00 -0400 Subject: Updated README --- README.md | 125 ++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 86 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 0c2a7ae..e052221 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,8 @@ # then -then is a plain text calendar program inspired by [When](https://www.lightandmatter.com/when/when.html). +Then is a minimalist plain text calendar program inspired by [When](https://www.lightandmatter.com/when/when.html). It aims to have as simple as possible syntax for the average scheduling case rather than cover every possible edge case. Then supports recurring events at least as complex as average calendar apps. -## 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 +# .then file syntax ``` # COMMENT @@ -21,74 +13,129 @@ DATE, EVENT - 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` +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 in the date can be written in any order. -``` -# Simple Examples +## Simple examples + +This simple 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 Jan 1, New Year's Day (Jan 1 every year) 1, Mortgage due (1st of every month) +``` +## Adding details to events -# `w` and `lw` parameters +Any line starting with a `-` is attached to the nearest above event. This can be used for details about an event if you don't want to put everyting on one line (address, etc.) -May 2w Sun, Mother's Day (Second Sunday of May) -May 1lw Mon, Memorial Day (Last Monday of May) +``` +2025 Jan 5 16:00, Doctor's Appointment +- 123 Gentoo Road, San Francisco, CA 12345 +- Dr. Elias Berkins, +1 (555)-123-1234 +``` +## Logical Operators (`|`, `!`) -# Logical Operators (`|` or, `!` not, `and` is implied by whitespace) +Parameters can be grouped with parentheses. +`|` means or. +`!` means not. +`and` is **always implied** by whitespace +``` 1 | 15, 1st OR 15th of month -Fri !(Dec 25), Every Friday, NOT December 25 +Fri !13, Every Friday, NOT the 13th +Sun !(Dec 25), Every Sunday, NOT December 25 +2025 Aug 14, 2025 AND August AND the 14th 1 2, 1st AND 2nd (i.e. never) +``` + +## Comparison Operators (`<`, `>`) -# Modified Julian Date Logic (`j` and `%`) -# We have to work on the syntax +`<` and `<=` can be used to mean before. +`>` and `>=` can be used to mean after. -!(j%14-5), Every other Saturday +This lets you express start and end dates. +``` +Fri <=(Sep 13 2024), Every Friday, ending September 13 2024 +>(Jan 1 2025) <(Jan 15 2025), After Jan 1 2025, Before Jan 15 2025 +2025 Jan >1 <15, Same as above expressed a different way +>=(Jul 15), All days of year from July 15 to Dec 31. +``` -# Details (Any lines prepended with - are attached to the above event) +For groups in parentheses if a day, month, and year is given, the date will be converted to a Modified Julian Date and probably work how you expect. -2025 Jan 5 16:00, Doctor's Appointment -- 123 Gentoo Road, San Francisco, CA 12345 -- Dr. Elias Berkins, +1 (555)-123-1234 +``` +>=(Dec 24 2025) <=(Jan 4 2026), Christmas vacation - this works! +``` + +If groups do not include a day, month, and year, the comparison operator is applied to each parameter individually. I can't really think of a use case for this. + +``` +>=(Dec 24) >=(Jan 4), This would match months after December and before January (i.e. nothing) ``` -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. +## 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` (or `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) +``` + +This syntax sucks but is included because it's possible. It's on the outside edge of what Then can 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. # 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. +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 -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. +Then is minimal and created to meet my personal use case. If your first thought was planning how to sync your calendar to another program to get so-and-so functionality, Then is the wrong tool and you're probably overcomplicating your workflow rather than simplifying it. -## Why would I use this *over When*? +## 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. +I *really* like [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 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`. +1. Parameter types 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: `m=dec & d=25, Christmas` or `* Dec 25, Christmas` +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 *really* like [Remind](https://dianne.skoll.ca/projects/remind/)! It is incredibly powerful! I am personally 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 nice because you won't have to convert Julian dates: + +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 -- cgit v1.2.3