32.13.10 Sexp Entries and the Fancy Diary Display

Sexp diary entries allow you to do more than just have complicated conditions under which a diary entry applies. Sexp entries should be preceded by diary-sexp-entry-symbol (default ‘%%’) in the diary file. With the fancy diary display, sexp entries can generate the text of the entry depending on the date itself.

For example, an anniversary diary entry can insert the number of years since the anniversary date into the text of the diary entry. Thus the ‘%d’ in this diary entry:

%%(diary-anniversary 10 31 1948) Arthur's birthday (%d years old)

gets replaced by the age, so on October 31, 1990 the entry appears in the fancy diary buffer like this:

Arthur's birthday (42 years old)

If the diary file instead contains this entry:

%%(diary-anniversary 10 31 1948) Arthur's %d%s birthday

the entry in the fancy diary buffer for October 31, 1990 appears like this:

Arthur's 42nd birthday

Similarly, cyclic diary entries can interpolate the number of repetitions that have occurred:

%%(diary-cyclic 50 1 1 2012) Renew medication (%d%s time)

looks like this:

Renew medication (5th time)

in the fancy diary display on September 7, 2012.

There is an early-reminder diary sexp that includes its entry in the diary not only on the date of occurrence, but also on earlier dates. For example, if you want a reminder a week before your anniversary, you can use

%%(diary-remind '(diary-anniversary 12 22 1968) 7) Ed's anniversary

and the fancy diary will show ‘Ed's anniversary’ both on December 15 and on December 22.

The function diary-date applies to dates described by a month, day, year combination, each of which can be an integer, a list of integers, or t (meaning all values). For example,

%%(diary-date '(10 11 12) 22 t) Rake leaves

causes the fancy diary to show

Rake leaves

on October 22, November 22, and December 22 of every year.

The function diary-float allows you to describe diary entries that apply to dates like the third Friday of November, or the last Tuesday in April. The parameters are the month, dayname, and an index n. The entry appears on the nth dayname after the first day of month, where dayname=0 means Sunday, 1 means Monday, and so on. If n is negative it counts backward from the end of month. The value of month can be a list of months, a single month, or t to specify all months. You can also use an optional parameter day to specify the nth dayname on or after/before day of month; the value of day defaults to 1 if n is positive and to the last day of month if n is negative. For example,

%%(diary-float t 1 -1) Pay rent

causes the fancy diary to show

Pay rent

on the last Monday of every month.

The generality of sexp diary entries lets you specify any diary entry that you can describe algorithmically. A sexp diary entry contains an expression that computes whether the entry applies to any given date. If its value is non-nil, the entry applies to that date; otherwise, it does not. The expression can use the variable date to find the date being considered; its value is a list (month day year) that refers to the Gregorian calendar.

The sexp diary entry applies to a date when the expression’s value is non-nil, but some values have more specific meanings. If the value is a string, that string is a description of the event which occurs on that date. The value can also have the form (mark . string); then mark specifies how to mark the date in the calendar, and string is the description of the event. If mark is a single-character string, that character appears next to the date in the calendar. If mark is a face name, the date is displayed in that face. If mark is nil, that specifies no particular highlighting for the date.

Suppose you get paid on the 21st of the month if it is a weekday, and on the Friday before if the 21st is on a weekend. Here is how to write a sexp diary entry that matches those dates:

&%%(let ((dayname (calendar-day-of-week date))
         (day (cadr date)))
      (or (and (= day 21) (memq dayname '(1 2 3 4 5)))
          (and (memq day '(19 20)) (= dayname 5)))
         ) Pay check deposited

The following sexp diary entries take advantage of the ability (in the fancy diary display) to concoct diary entries whose text varies based on the date:

%%(diary-sunrise-sunset)

Make a diary entry for today’s local times of sunrise and sunset.

%%(diary-lunar-phases)

Make a diary entry for the phases (quarters) of the moon.

%%(diary-day-of-year)

Make a diary entry with today’s day number in the current year and the number of days remaining in the current year.

%%(diary-iso-date)

Make a diary entry with today’s equivalent ISO commercial date.

%%(diary-julian-date)

Make a diary entry with today’s equivalent Julian calendar date.

%%(diary-astro-day-number)

Make a diary entry with today’s equivalent astronomical (Julian) day number.

%%(diary-bahai-date)

Make a diary entry with today’s equivalent Bahá’í calendar date.

%%(diary-chinese-date)

Make a diary entry with today’s equivalent Chinese calendar date.

%%(diary-coptic-date)

Make a diary entry with today’s equivalent Coptic calendar date.

%%(diary-ethiopic-date)

Make a diary entry with today’s equivalent Ethiopic calendar date.

%%(diary-french-date)

Make a diary entry with today’s equivalent date on the French Revolutionary calendar.

%%(diary-hebrew-date)

Make a diary entry with today’s equivalent Hebrew calendar date.

%%(diary-islamic-date)

Make a diary entry with today’s equivalent Islamic calendar date.

%%(diary-mayan-date)

Make a diary entry with today’s equivalent Mayan calendar date.

%%(diary-persian-date)

Make a diary entry with today’s equivalent Persian calendar date.

For example, including the diary entry

&%%(diary-hebrew-date)

causes every day’s diary display to contain the equivalent date on the Hebrew calendar, if you are using the fancy diary display. (With simple diary display, the literal line ‘&%%(diary-hebrew-date)’ appears in the diary for any date.)

This function has been used to construct certain standard Hebrew sexp diary entries:

%%(diary-hebrew-rosh-hodesh)

Make a diary entry that tells the occurrence and ritual announcement of each new Hebrew month.

%%(diary-hebrew-parasha)

Make a Saturday diary entry that tells the weekly synagogue scripture reading.

%%(diary-hebrew-sabbath-candles)

Make a Friday diary entry that tells the local time of Sabbath candle lighting.

%%(diary-hebrew-omer)

Make a diary entry that gives the omer count, when appropriate.

%%(diary-hebrew-yahrzeit month day year) name

Make a diary entry marking the anniversary of a date of death. The date is the Gregorian (civil) date of death. The diary entry appears on the proper Hebrew calendar anniversary and on the day before. (The order of the parameters changes according to the calendar date style; for example in the European style to day, month, year.)

%%(diary-hebrew-birthday month day year)

Make a diary entry for a birthday on the Hebrew calendar.

All the functions documented above take an optional argument mark which specifies how to mark the date in the calendar display. If one of these functions decides that it applies to a certain date, it returns a value that contains mark, as described above.