calendar.el 119 KB
Newer Older
1
;;; calendar.el --- Calendar functions.
Eric S. Raymond's avatar
Eric S. Raymond committed
2

3 4
;;; Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994 Free Software
;;; Foundation, Inc.
Eric S. Raymond's avatar
Eric S. Raymond committed
5

Eric S. Raymond's avatar
Eric S. Raymond committed
6
;; Author: Edward M. Reingold <reingold@cs.uiuc.edu>
Eric S. Raymond's avatar
Eric S. Raymond committed
7 8 9 10
;; Keywords: calendar
;; Human-Keywords: calendar, Gregorian calendar, Julian calendar, 
;;	Hebrew calendar, Islamic calendar, ISO calendar, Julian day number,
;;	diary, holidays
Eric S. Raymond's avatar
Eric S. Raymond committed
11

Richard M. Stallman's avatar
Richard M. Stallman committed
12 13
;; This file is part of GNU Emacs.

Richard M. Stallman's avatar
Richard M. Stallman committed
14 15 16 17 18
;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.

Richard M. Stallman's avatar
Richard M. Stallman committed
19
;; GNU Emacs is distributed in the hope that it will be useful,
Richard M. Stallman's avatar
Richard M. Stallman committed
20 21 22 23 24 25 26
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING.  If not, write to
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
Richard M. Stallman's avatar
Richard M. Stallman committed
27

Eric S. Raymond's avatar
Eric S. Raymond committed
28 29
;;; Commentary:

Jim Blandy's avatar
Jim Blandy committed
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
;; This collection of functions implements a calendar window.  It
;; generates a calendar for the current month, together with the previous
;; and coming months, or for any other three-month period.  The calendar
;; can be scrolled forward and backward in the window to show months in
;; the past or future; the cursor can move forward and backward by days,
;; weeks, or months, making it possible, for instance, to jump to the
;; date a specified number of days, weeks, or months from the date under
;; the cursor.  The user can display a list of holidays and other notable
;; days for the period shown; the notable days can be marked on the
;; calendar, if desired.  The user can also specify that dates having
;; corresponding diary entries (in a file that the user specifies) be
;; marked; the diary entries for any date can be viewed in a separate
;; window.  The diary and the notable days can be viewed independently of
;; the calendar.  Dates can be translated from the (usual) Gregorian
;; calendar to the day of the year/days remaining in year, to the ISO
;; commercial calendar, to the Julian (old style) calendar, to the Hebrew
;; calendar, to the Islamic calendar, to the French Revolutionary calendar,
;; to the Mayan calendar, and to the astronomical (Julian) day number.
;; When floating point is available, times of sunrise/sunset can be displayed,
49
;; as can the phases of the moon.  Appointment notification for diary entries
Jim Blandy's avatar
Jim Blandy committed
50 51 52 53
;; is available.

;; The following files are part of the calendar/diary code:

54
;;       cal-menu.el                   Menu support
55
;;       cal-x.el                      X-windows dedicated frame functions
56
;;       diary-lib.el, diary-ins.el    Diary functions
Jim Blandy's avatar
Jim Blandy committed
57 58 59
;;       holidays.el                   Holiday functions
;;       cal-french.el                 French Revolutionary calendar
;;       cal-mayan.el                  Mayan calendars
60
;;       cal-dst.el                    Daylight savings time rules
Jim Blandy's avatar
Jim Blandy committed
61 62 63
;;       solar.el                      Sunrise/sunset, equinoxes/solstices
;;       lunar.el                      Phases of the moon
;;       appt.el                       Appointment notification
Richard M. Stallman's avatar
Richard M. Stallman committed
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

;; Comments, corrections, and improvements should be sent to
;;  Edward M. Reingold               Department of Computer Science
;;  (217) 333-6733                   University of Illinois at Urbana-Champaign
;;  reingold@cs.uiuc.edu             1304 West Springfield Avenue
;;                                   Urbana, Illinois 61801

;; GNU Emacs users too numerous to list pointed out a variety of problems
;; with earlier forms of the `infinite' sliding calendar and suggested some
;; of the features included in this package.  Especially significant in this
;; regard was the suggestion of mark-diary-entries and view-diary-entries,
;; together ideas for their implementation, by
;;  Michael S. Littman		     Cognitive Science Research Group
;;  (201) 829-5155                   Bell Communications Research
;;  mlittman@wind.bellcore.com       445 South St. Box 1961 (2L-331)
;;                                   Morristown, NJ  07960

;; The algorithms for the Hebrew calendar are those of the Rambam (Rabbi Moses
;; Maimonides), from his Mishneh Torah, as implemented by
;;  Nachum Dershowitz                Department of Computer Science
;;  (217) 333-4219                   University of Illinois at Urbana-Champaign
;;  nachum@cs.uiuc.edu               1304 West Springfield Avenue
;;                                   Urbana, Illinois 61801

;; Technical details of all the calendrical calculations can be found in
Jim Blandy's avatar
Jim Blandy committed
89

Richard M. Stallman's avatar
Richard M. Stallman committed
90 91
;; ``Calendrical Calculations'' by Nachum Dershowitz and Edward M. Reingold,
;; Software--Practice and Experience, Volume 20, Number 9 (September, 1990),
Jim Blandy's avatar
Jim Blandy committed
92 93
;; pages 899-928.  ``Calendrical Calculations, Part II: Three Historical
;; Calendars'' by E. M. Reingold,  N. Dershowitz, and S. M. Clamen,
94 95
;; Software--Practice and Experience, Volume 23, Number 4 (April, 1993),
;; pages 383-404.
Jim Blandy's avatar
Jim Blandy committed
96 97 98 99

;; Hard copies of these two papers can be obtained by sending email to
;; reingold@cs.uiuc.edu with the SUBJECT "send-paper-cal" (no quotes) and
;; the message BODY containing your mailing address (snail).
Richard M. Stallman's avatar
Richard M. Stallman committed
100

Eric S. Raymond's avatar
Eric S. Raymond committed
101
;;; Code:
Richard M. Stallman's avatar
Richard M. Stallman committed
102

Richard M. Stallman's avatar
Richard M. Stallman committed
103 104 105 106
(defun calendar-version ()
  (interactive)
  (message "Version 5.3, January 25, 1994"))

107 108 109 110 111
;;;###autoload
(defvar calendar-week-start-day 0
  "*The day of the week on which a week in the calendar begins.
0 means Sunday (default), 1 means Monday, and so on.")

112 113 114 115 116 117 118
;;;###autoload
(defvar calendar-offset 0
  "*The offset of the principal month from the center of the calendar window.
0 means the principal month is in the center (default), -1 means on the left,
+1 means on the right.  Larger (or smaller) values push the principal month off
the screen.")

Jim Blandy's avatar
Jim Blandy committed
119
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
120
(defvar view-diary-entries-initially nil
Richard M. Stallman's avatar
Richard M. Stallman committed
121
  "*Non-nil means display current date's diary entries on entry.
Richard M. Stallman's avatar
Richard M. Stallman committed
122 123 124 125
The diary is displayed in another window when the calendar is first displayed,
if the current date is visible.  The number of days of diary entries displayed
is governed by the variable `number-of-diary-entries'.")

Jim Blandy's avatar
Jim Blandy committed
126
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
127 128 129 130 131 132
(defvar number-of-diary-entries 1
  "*Specifies how many days of diary entries are to be displayed initially.
This variable affects the diary display when the command M-x diary is used,
or if the value of the variable `view-diary-entries-initially' is t.  For
example, if the default value 1 is used, then only the current day's diary
entries will be displayed.  If the value 2 is used, then both the current
Richard M. Stallman's avatar
Richard M. Stallman committed
133 134 135 136 137 138 139 140 141 142
day's and the next day's entries will be displayed.

The value can also be a vector such as [0 2 2 2 2 4 1]; this value
says to display no diary entries on Sunday, the display the entries
for the current date and the day after on Monday through Thursday,
display Friday through Monday's entries on Friday, and display only
Saturday's entries on Saturday.

This variable does not affect the diary display with the `d' command
from the calendar; in that case, the prefix argument controls the
Richard M. Stallman's avatar
Richard M. Stallman committed
143 144
number of days of diary entries displayed.")

Jim Blandy's avatar
Jim Blandy committed
145
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
146
(defvar mark-diary-entries-in-calendar nil
Richard M. Stallman's avatar
Richard M. Stallman committed
147
  "*Non-nil means mark dates with diary entries, in the calendar window.
Richard M. Stallman's avatar
Richard M. Stallman committed
148 149
The marking symbol is specified by the variable `diary-entry-marker'.")

150 151 152 153 154
(defvar diary-entry-marker
  (if (not window-system)
      "+"
    (require 'faces)
    (make-face 'diary-face)
155 156 157
    (cond ((face-differs-from-default-p 'diary-face))
          ((x-display-color-p) (set-face-foreground 'diary-face "red"))
          (t (copy-face 'bold 'diary-face)))
158 159 160 161 162 163 164 165 166
    'diary-face)
  "*Used to mark dates that have diary entries.
Can be either a single-character string or a face.")

(defvar calendar-today-marker
  (if (not window-system)
      "="
    (require 'faces)
    (make-face 'calendar-today-face)
167 168
    (if (not (face-differs-from-default-p 'calendar-today-face))
        (set-face-underline-p 'calendar-today-face t))
169 170 171 172 173 174 175 176 177
    'calendar-today-face)
  "*Used to mark today's date.
Can be either a single-character string or a face.")

(defvar calendar-holiday-marker
  (if (not window-system)
      "*"
    (require 'faces)
    (make-face 'holiday-face)
178 179 180 181
    (cond ((face-differs-from-default-p 'holiday-face))
          ((x-display-color-p) (set-face-background 'holiday-face "pink"))
          (t (set-face-background 'holiday-face "black")
             (set-face-foreground 'holiday-face "white")))
182 183 184
    'holiday-face)
  "*Used to mark notable dates in the calendar.
Can be either a single-character string or a face.")
Richard M. Stallman's avatar
Richard M. Stallman committed
185

Jim Blandy's avatar
Jim Blandy committed
186
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
187
(defvar view-calendar-holidays-initially nil
Richard M. Stallman's avatar
Richard M. Stallman committed
188
  "*Non-nil means display holidays for current three month period on entry.
189 190
The holidays are displayed in another window when the calendar is first
displayed.")
Richard M. Stallman's avatar
Richard M. Stallman committed
191

Jim Blandy's avatar
Jim Blandy committed
192
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
193
(defvar mark-holidays-in-calendar nil
Richard M. Stallman's avatar
Richard M. Stallman committed
194
  "*Non-nil means mark dates of holidays in the calendar window.
Richard M. Stallman's avatar
Richard M. Stallman committed
195 196
The marking symbol is specified by the variable `calendar-holiday-marker'.")

Jim Blandy's avatar
Jim Blandy committed
197
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
198
(defvar all-hebrew-calendar-holidays nil
199
  "*If nil, show only major holidays from the Hebrew calendar.
Richard M. Stallman's avatar
Richard M. Stallman committed
200
This means only those Jewish holidays that appear on secular calendars.
201

Richard M. Stallman's avatar
Richard M. Stallman committed
202
If t, show all the holidays that would appear in a complete Hebrew calendar.")
Richard M. Stallman's avatar
Richard M. Stallman committed
203

Jim Blandy's avatar
Jim Blandy committed
204
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
205
(defvar all-christian-calendar-holidays nil
206
  "*If nil, show only major holidays from the Christian calendar.
Richard M. Stallman's avatar
Richard M. Stallman committed
207
This means only those Christian holidays that appear on secular calendars.
208

Richard M. Stallman's avatar
Richard M. Stallman committed
209 210
If t, show all the holidays that would appear in a complete Christian
calendar.")
Richard M. Stallman's avatar
Richard M. Stallman committed
211

Jim Blandy's avatar
Jim Blandy committed
212
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
213
(defvar all-islamic-calendar-holidays nil
214
  "*If nil, show only major holidays from the Islamic calendar.
Richard M. Stallman's avatar
Richard M. Stallman committed
215
This means only those Islamic holidays that appear on secular calendars.
216

Richard M. Stallman's avatar
Richard M. Stallman committed
217 218
If t, show all the holidays that would appear in a complete Islamic
calendar.")
Richard M. Stallman's avatar
Richard M. Stallman committed
219

Jim Blandy's avatar
Jim Blandy committed
220 221 222
;;;###autoload
(defvar calendar-load-hook nil
  "*List of functions to be called after the calendar is first loaded.
Richard M. Stallman's avatar
Richard M. Stallman committed
223
This is the place to add key bindings to `calendar-mode-map'.")
Jim Blandy's avatar
Jim Blandy committed
224 225

;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
226 227 228 229 230 231
(defvar initial-calendar-window-hook nil
  "*List of functions to be called when the calendar window is first opened.
The functions invoked are called after the calendar window is opened, but
once opened is never called again.  Leaving the calendar with the `q' command
and reentering it will cause these functions to be called again.")

Jim Blandy's avatar
Jim Blandy committed
232
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
233 234 235 236 237
(defvar today-visible-calendar-hook nil
  "*List of functions called whenever the current date is visible.
This can be used, for example, to replace today's date with asterisks; a
function `calendar-star-date' is included for this purpose:
    (setq today-visible-calendar-hook 'calendar-star-date)
Richard M. Stallman's avatar
Richard M. Stallman committed
238
It can also be used to mark the current date with `calendar-today-marker';
239
a function is also provided for this:
Richard M. Stallman's avatar
Richard M. Stallman committed
240 241 242 243 244 245 246 247 248 249
    (setq today-visible-calendar-hook 'calendar-mark-today)

The corresponding variable `today-invisible-calendar-hook' is the list of
functions called when the calendar function was called when the current
date is not visible in the window.

Other than the use of the provided functions, the changing of any
characters in the calendar buffer by the hooks may cause the failure of the
functions that move by days and weeks.")

Jim Blandy's avatar
Jim Blandy committed
250
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
251 252 253 254 255 256 257 258 259 260 261
(defvar today-invisible-calendar-hook nil
  "*List of functions called whenever the current date is not visible.

The corresponding variable `today-visible-calendar-hook' is the list of
functions called when the calendar function was called when the current
date is visible in the window.

Other than the use of the provided functions, the changing of any
characters in the calendar buffer by the hooks may cause the failure of the
functions that move by days and weeks.")

Jim Blandy's avatar
Jim Blandy committed
262
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
(defvar diary-file "~/diary"
  "*Name of the file in which one's personal diary of dates is kept.

The file's entries are lines in any of the forms

            MONTH/DAY
            MONTH/DAY/YEAR
            MONTHNAME DAY
            MONTHNAME DAY, YEAR
            DAYNAME

at the beginning of the line; the remainder of the line is the diary entry
string for that date.  MONTH and DAY are one or two digit numbers, YEAR is
a number and may be written in full or abbreviated to the final two digits.
If the date does not contain a year, it is generic and applies to any year.
DAYNAME entries apply to any date on which is on that day of the week.
MONTHNAME and DAYNAME can be spelled in full, abbreviated to three
characters (with or without a period), capitalized or not.  Any of DAY,
MONTH, or MONTHNAME, YEAR can be `*' which matches any day, month, or year,
respectively.

The European style (in which the day precedes the month) can be used
instead, if you execute `european-calendar' when in the calendar, or set
`european-calendar-style' to t in your .emacs file.  The European forms are

            DAY/MONTH
            DAY/MONTH/YEAR
            DAY MONTHNAME
            DAY MONTHNAME YEAR
            DAYNAME

To revert to the default American style from the European style, execute
`american-calendar' in the calendar.

Richard M. Stallman's avatar
Richard M. Stallman committed
297 298 299 300
A diary entry can be preceded by the character
`diary-nonmarking-symbol' (ordinarily `&') to make that entry
nonmarking--that is, it will not be marked on dates in the calendar
window but will appear in a diary window.
Richard M. Stallman's avatar
Richard M. Stallman committed
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320

Multiline diary entries are made by indenting lines after the first with
either a TAB or one or more spaces.

Lines not in one the above formats are ignored.  Here are some sample diary
entries (in the default American style):

     12/22/1988 Twentieth wedding anniversary!!
     &1/1. Happy New Year!
     10/22 Ruth's birthday.
     21: Payday
     Tuesday--weekly meeting with grad students at 10am
              Supowit, Shen, Bitner, and Kapoor to attend.
     1/13/89 Friday the thirteenth!!
     &thu 4pm squash game with Lloyd.
     mar 16 Dad's birthday
     April 15, 1989 Income tax due.
     &* 15 time cards due.

If the first line of a diary entry consists only of the date or day name with
Richard M. Stallman's avatar
Richard M. Stallman committed
321 322
no trailing blanks or punctuation, then that line is not displayed in the
diary window; only the continuation lines is shown.  For example, the
Richard M. Stallman's avatar
Richard M. Stallman committed
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342
single diary entry

     02/11/1989
      Bill Blattner visits Princeton today
      2pm Cognitive Studies Committee meeting
      2:30-5:30 Lizzie at Lawrenceville for `Group Initiative'
      4:00pm Jamie Tappenden
      7:30pm Dinner at George and Ed's for Alan Ryan
      7:30-10:00pm dance at Stewart Country Day School

will appear in the diary window without the date line at the beginning.  This
facility allows the diary window to look neater, but can cause confusion if
used with more than one day's entries displayed.

Diary entries can be based on Lisp sexps.  For example, the diary entry

      %%(diary-block 11 1 1990 11 10 1990) Vacation

causes the diary entry \"Vacation\" to appear from November 1 through November
10, 1990.  Other functions available are `diary-float', `diary-anniversary',
Jim Blandy's avatar
Jim Blandy committed
343 344 345 346 347 348
`diary-cyclic', `diary-day-of-year', `diary-iso-date', `diary-french-date',
`diary-hebrew-date', `diary-islamic-date', `diary-mayan-date',
`diary-yahrzeit', `diary-sunrise-sunset', `diary-phases-of-moon',
`diary-parasha', `diary-omer', `diary-rosh-hodesh', and
`diary-sabbath-candles'.  See the documentation for the function
`list-sexp-diary-entries' for more details.
Richard M. Stallman's avatar
Richard M. Stallman committed
349 350 351 352 353 354 355 356 357 358

Diary entries based on the Hebrew and/or the Islamic calendar are also
possible, but because these are somewhat slow, they are ignored
unless you set the `nongregorian-diary-listing-hook' and the
`nongregorian-diary-marking-hook' appropriately.  See the documentation
for these functions for details.

Diary files can contain directives to include the contents of other files; for
details, see the documentation for the variable `list-diary-entries-hook'.")

Jim Blandy's avatar
Jim Blandy committed
359
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
360
(defvar diary-nonmarking-symbol "&"
361
  "*Symbol indicating that a diary entry is not to be marked in the calendar.")
Richard M. Stallman's avatar
Richard M. Stallman committed
362

Jim Blandy's avatar
Jim Blandy committed
363
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
364
(defvar hebrew-diary-entry-symbol "H"
365
  "*Symbol indicating a diary entry according to the Hebrew calendar.")
Richard M. Stallman's avatar
Richard M. Stallman committed
366

Jim Blandy's avatar
Jim Blandy committed
367
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
368
(defvar islamic-diary-entry-symbol "I"
369
  "*Symbol indicating a diary entry according to the Islamic calendar.")
Richard M. Stallman's avatar
Richard M. Stallman committed
370

Jim Blandy's avatar
Jim Blandy committed
371
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
372
(defvar diary-include-string "#include"
373 374
  "*The string indicating inclusion of another file of diary entries.
See the documentation for the function `include-other-diary-files'.")
Richard M. Stallman's avatar
Richard M. Stallman committed
375

Jim Blandy's avatar
Jim Blandy committed
376
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
377 378 379 380
(defvar sexp-diary-entry-symbol "%%"
  "*The string used to indicate a sexp diary entry in diary-file.
See the documentation for the function `list-sexp-diary-entries'.")

Jim Blandy's avatar
Jim Blandy committed
381
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
382
(defvar abbreviated-calendar-year t
383 384 385
  "*Interpret a two-digit year DD in a diary entry as either 19DD or 20DD.
For the Gregorian calendar; similarly for the Hebrew and Islamic calendars.
If this variable is nil, years must be written in full.")
Richard M. Stallman's avatar
Richard M. Stallman committed
386

Jim Blandy's avatar
Jim Blandy committed
387
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
388
(defvar european-calendar-style nil
389 390 391
  "*Use the European style of dates in the diary and in any displays.
If this variable is t, a date 1/2/1990 would be interpreted as February 1,
1990.  The accepted European date styles are
Richard M. Stallman's avatar
Richard M. Stallman committed
392 393 394 395 396 397 398 399 400 401

            DAY/MONTH
            DAY/MONTH/YEAR
            DAY MONTHNAME
            DAY MONTHNAME YEAR
            DAYNAME

Names can be capitalized or not, written in full, or abbreviated to three
characters with or without a period.")

Jim Blandy's avatar
Jim Blandy committed
402
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
403 404 405 406 407 408 409
(defvar american-date-diary-pattern
  '((month "/" day "[^/0-9]")
    (month "/" day "/" year "[^0-9]")
    (monthname " *" day "[^,0-9]")
    (monthname " *" day ", *" year "[^0-9]")
    (dayname "\\W"))
  "*List of pseudo-patterns describing the American patterns of date used.
Richard M. Stallman's avatar
Richard M. Stallman committed
410
See the documentation of `diary-date-forms' for an explanation.")
Richard M. Stallman's avatar
Richard M. Stallman committed
411

Jim Blandy's avatar
Jim Blandy committed
412
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
413 414 415 416 417 418 419
(defvar european-date-diary-pattern
  '((day "/" month "[^/0-9]")
    (day "/" month "/" year "[^0-9]")
    (backup day " *" monthname "\\W+\\<[^*0-9]")
    (day " *" monthname " *" year "[^0-9]")
    (dayname "\\W"))
  "*List of pseudo-patterns describing the European patterns of date used.
Richard M. Stallman's avatar
Richard M. Stallman committed
420
See the documentation of `diary-date-forms' for an explanation.")
Richard M. Stallman's avatar
Richard M. Stallman committed
421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444

(defvar diary-date-forms
  (if european-calendar-style
      european-date-diary-pattern
    american-date-diary-pattern)
  "*List of pseudo-patterns describing the forms of date used in the diary.
The patterns on the list must be MUTUALLY EXCLUSIVE and must should not match
any portion of the diary entry itself, just the date component.

A pseudo-pattern is a list of regular expressions and the keywords `month',
`day', `year', `monthname', and `dayname'.  The keyword `monthname' will
match the name of the month, capitalized or not, or its three-letter
abbreviation, followed by a period or not; it will also match `*'.
Similarly, `dayname' will match the name of the day, capitalized or not, or
its three-letter abbreviation, followed by a period or not.  The keywords
`month', `day', and `year' will match those numerical values, preceded by
arbitrarily many zeros; they will also match `*'.

The matching of the diary entries with the date forms is done with the
standard syntax table from Fundamental mode, but with the `*' changed so
that it is a word constituent.

If, to be mutually exclusive, a pseudo-pattern must match a portion of the
diary entry itself, the first element of the pattern MUST be `backup'.  This
Jim Blandy's avatar
Jim Blandy committed
445 446 447
directive causes the date recognizer to back up to the beginning of the
current word of the diary entry, so in no case can the pattern match more than
a portion of the first word of the diary entry.")
Richard M. Stallman's avatar
Richard M. Stallman committed
448

Jim Blandy's avatar
Jim Blandy committed
449
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
450
(defvar european-calendar-display-form
Jim Blandy's avatar
Jim Blandy committed
451
  '((if dayname (concat dayname ", ")) day " " monthname " " year)
452
  "*Pseudo-pattern governing the way a date appears in the European style.
453
See the documentation of calendar-date-display-form for an explanation.")
Richard M. Stallman's avatar
Richard M. Stallman committed
454

Jim Blandy's avatar
Jim Blandy committed
455
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
456
(defvar american-calendar-display-form
Jim Blandy's avatar
Jim Blandy committed
457
  '((if dayname (concat dayname ", ")) monthname " " day ", " year)
458
  "*Pseudo-pattern governing the way a date appears in the American style.
Richard M. Stallman's avatar
Richard M. Stallman committed
459
See the documentation of `calendar-date-display-form' for an explanation.")
Richard M. Stallman's avatar
Richard M. Stallman committed
460 461 462 463 464

(defvar calendar-date-display-form
  (if european-calendar-style
      european-calendar-display-form
    american-calendar-display-form)
465 466 467 468 469 470
  "*Pseudo-pattern governing the way a date appears.

Used by the function `calendar-date-string', a pseudo-pattern is a list of
expressions that can involve the keywords `month', `day', and `year', all
numbers in string form, and `monthname' and `dayname', both alphabetic
strings.  For example, the ISO standard would use the pseudo- pattern
Richard M. Stallman's avatar
Richard M. Stallman committed
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501

       '(year \"-\" month \"-\" day)

while a typical American form would be

       '(month \"/\" day \"/\" (substring year -2))

and

       '((format \"%9s, %9s %2s, %4s\" dayname monthname day year))

would give the usual American style in fixed-length fields.

See the documentation of the function `calendar-date-string'.")

(defun european-calendar ()
  "Set the interpretation and display of dates to the European style."
  (interactive)
  (setq european-calendar-style t)
  (setq calendar-date-display-form european-calendar-display-form)
  (setq diary-date-forms european-date-diary-pattern)
  (update-calendar-mode-line))

(defun american-calendar ()
  "Set the interpretation and display of dates to the American style."
  (interactive)
  (setq european-calendar-style nil)
  (setq calendar-date-display-form american-calendar-display-form)
  (setq diary-date-forms american-date-diary-pattern)
  (update-calendar-mode-line))

Jim Blandy's avatar
Jim Blandy committed
502 503
;;;###autoload
(defvar print-diary-entries-hook 'lpr-buffer
504 505 506 507 508
  "*List of functions called after a temporary diary buffer is prepared.
The buffer shows only the diary entries currently visible in the diary
buffer.  The default just does the printing.  Other uses might include, for
example, rearranging the lines into order by day and time, saving the buffer
instead of deleting it, or changing the function used to do the printing.")
Richard M. Stallman's avatar
Richard M. Stallman committed
509

Jim Blandy's avatar
Jim Blandy committed
510
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
511
(defvar list-diary-entries-hook nil
512 513
  "*List of functions called after diary file is culled for relevant entries.
It is to be used for diary entries that are not found in the diary file.
Richard M. Stallman's avatar
Richard M. Stallman committed
514 515 516

A function `include-other-diary-files' is provided for use as the value of
this hook.  This function enables you to use shared diary files together
Richard M. Stallman's avatar
Richard M. Stallman committed
517
with your own.  The files included are specified in the diary file by lines
Richard M. Stallman's avatar
Richard M. Stallman committed
518 519 520 521 522 523 524 525
of the form

        #include \"filename\"

This is recursive; that is, #include directives in files thus included are
obeyed.  You can change the \"#include\" to some other string by changing
the variable `diary-include-string'.  When you use `include-other-diary-files'
as part of the list-diary-entries-hook, you will probably also want to use the
Richard M. Stallman's avatar
Richard M. Stallman committed
526
function `mark-included-diary-files' as part of `mark-diary-entries-hook'.
Richard M. Stallman's avatar
Richard M. Stallman committed
527 528 529 530

For example, you could use

     (setq list-diary-entries-hook
Jim Blandy's avatar
Jim Blandy committed
531
       '(include-other-diary-files sort-diary-entries))
Richard M. Stallman's avatar
Richard M. Stallman committed
532 533
     (setq diary-display-hook 'fancy-diary-display)

Richard M. Stallman's avatar
Richard M. Stallman committed
534
in your `.emacs' file to cause the fancy diary buffer to be displayed with
Richard M. Stallman's avatar
Richard M. Stallman committed
535 536 537
diary entries from various included files, each day's entries sorted into
lexicographic order.")

Jim Blandy's avatar
Jim Blandy committed
538
;;;###autoload
539 540 541 542 543 544
(defvar diary-hook nil
  "*List of functions called after the display of the diary.
Can be used for appointment notification.")

;;;###autoload
(defvar diary-display-hook nil
Richard M. Stallman's avatar
Richard M. Stallman committed
545
  "*List of functions that handle the display of the diary.
Richard M. Stallman's avatar
Richard M. Stallman committed
546
If nil (the default), `simple-diary-display' is used.  Use `ignore' for no
547
diary display.
Richard M. Stallman's avatar
Richard M. Stallman committed
548 549 550 551 552 553

Ordinarily, this just displays the diary buffer (with holidays indicated in
the mode line), if there are any relevant entries.  At the time these
functions are called, the variable `diary-entries-list' is a list, in order
by date, of all relevant diary entries in the form of ((MONTH DAY YEAR)
STRING), where string is the diary entry for the given date.  This can be
554 555
used, for example, a different buffer for display (perhaps combined with
holidays), or produce hard copy output.
Richard M. Stallman's avatar
Richard M. Stallman committed
556 557 558 559 560 561 562 563 564 565

A function `fancy-diary-display' is provided as an alternative
choice for this hook; this function prepares a special noneditable diary
buffer with the relevant diary entries that has neat day-by-day arrangement
with headings.  The fancy diary buffer will show the holidays unless the
variable `holidays-in-diary-buffer' is set to nil.  Ordinarily, the fancy
diary buffer will not show days for which there are no diary entries, even
if that day is a holiday; if you want such days to be shown in the fancy
diary buffer, set the variable `diary-list-include-blanks' to t.")

Jim Blandy's avatar
Jim Blandy committed
566
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
567
(defvar nongregorian-diary-listing-hook nil
568 569 570 571 572
  "*List of functions called for listing diary file and included files.
As the files are processed for diary entries, these functions are used to cull
relevant entries.  You can use either or both of `list-hebrew-diary-entries'
and `list-islamic-diary-entries'.  The documentation for these functions
describes the style of such diary entries.")
Richard M. Stallman's avatar
Richard M. Stallman committed
573

Jim Blandy's avatar
Jim Blandy committed
574
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
575 576 577 578 579
(defvar mark-diary-entries-hook nil
  "*List of functions called after marking diary entries in the calendar.

A function `mark-included-diary-files' is also provided for use as the
mark-diary-entries-hook; it enables you to use shared diary files together
Richard M. Stallman's avatar
Richard M. Stallman committed
580
with your own.  The files included are specified in the diary file by lines
Richard M. Stallman's avatar
Richard M. Stallman committed
581 582 583 584 585 586
of the form
        #include \"filename\"
This is recursive; that is, #include directives in files thus included are
obeyed.  You can change the \"#include\" to some other string by changing the
variable `diary-include-string'.  When you use `mark-included-diary-files' as
part of the mark-diary-entries-hook, you will probably also want to use the
Richard M. Stallman's avatar
Richard M. Stallman committed
587
function `include-other-diary-files' as part of `list-diary-entries-hook'.")
Richard M. Stallman's avatar
Richard M. Stallman committed
588

Jim Blandy's avatar
Jim Blandy committed
589
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
590
(defvar nongregorian-diary-marking-hook nil
591 592 593 594 595
  "*List of functions called for marking diary file and included files.
As the files are processed for diary entries, these functions are used to cull
relevant entries.  You can use either or both of `mark-hebrew-diary-entries'
and `mark-islamic-diary-entries'.  The documentation for these functions
describes the style of such diary entries.")
Richard M. Stallman's avatar
Richard M. Stallman committed
596

Jim Blandy's avatar
Jim Blandy committed
597
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
598
(defvar diary-list-include-blanks nil
599 600 601
  "*If nil, do not include days with no diary entry in the list of diary entries.
Such days will then not be shown in the the fancy diary buffer, even if they
are holidays.")
Richard M. Stallman's avatar
Richard M. Stallman committed
602

Jim Blandy's avatar
Jim Blandy committed
603
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
604
(defvar holidays-in-diary-buffer t
Richard M. Stallman's avatar
Richard M. Stallman committed
605 606
  "*Non-nil means include holidays in the diary display.
The holidays appear in the mode line of the diary buffer, or in the
607
fancy diary buffer next to the date.  This slows down the diary functions
Richard M. Stallman's avatar
Richard M. Stallman committed
608
somewhat; setting it to nil makes the diary display faster.")
Richard M. Stallman's avatar
Richard M. Stallman committed
609

610 611
(defvar calendar-mark-ring nil)

Richard M. Stallman's avatar
Richard M. Stallman committed
612 613
;;;###autoload
(put 'general-holidays 'risky-local-variable t)
Jim Blandy's avatar
Jim Blandy committed
614 615
;;;###autoload
(defvar general-holidays
616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634
  '((holiday-fixed 1 1 "New Year's Day")
    (holiday-float 1 1 3 "Martin Luther King Day")
    (holiday-fixed 2 2 "Ground Hog Day")
    (holiday-fixed 2 14 "Valentine's Day")
    (holiday-float 2 1 3 "President's Day")
    (holiday-fixed 3 17 "St. Patrick's Day")
    (holiday-fixed 4 1 "April Fool's Day")
    (holiday-float 5 0 2 "Mother's Day")
    (holiday-float 5 1 -1 "Memorial Day")
    (holiday-fixed 6 14 "Flag Day")
    (holiday-float 6 0 3 "Father's Day")
    (holiday-fixed 7 4 "Independence Day")
    (holiday-float 9 1 1 "Labor Day")
    (holiday-float 10 1 2 "Columbus Day")
    (holiday-fixed 10 31 "Halloween")
    (holiday-fixed 11 11 "Veteran's Day")
    (holiday-float 11 4 4 "Thanksgiving"))
  "*General holidays.  Default value is for the United States.
See the documentation for `calendar-holidays' for details.")
Richard M. Stallman's avatar
Richard M. Stallman committed
635

Richard M. Stallman's avatar
Richard M. Stallman committed
636 637
;;;###autoload
(put 'local-holidays 'risky-local-variable t)
Jim Blandy's avatar
Jim Blandy committed
638 639 640 641 642
;;;###autoload
(defvar local-holidays nil
  "*Local holidays.
See the documentation for `calendar-holidays' for details.")

Richard M. Stallman's avatar
Richard M. Stallman committed
643 644
;;;###autoload
(put 'other-holidays 'risky-local-variable t)
Jim Blandy's avatar
Jim Blandy committed
645 646 647 648
;;;###autoload
(defvar other-holidays nil
  "*User defined holidays.
See the documentation for `calendar-holidays' for details.")
Richard M. Stallman's avatar
Richard M. Stallman committed
649

Richard M. Stallman's avatar
Richard M. Stallman committed
650 651
;;;###autoload
(put 'hebrew-holidays-1 'risky-local-variable t)
Jim Blandy's avatar
Jim Blandy committed
652
;;;###autoload
653
(defvar hebrew-holidays-1
654
  '((holiday-rosh-hashanah-etc)
Richard M. Stallman's avatar
Richard M. Stallman committed
655
    (if all-hebrew-calendar-holidays
656 657 658 659 660 661 662 663 664 665 666 667
        (holiday-julian
         11
         (let* ((m displayed-month)
                (y displayed-year)
                (year))
           (increment-calendar-month m y -1)
           (let ((year (extract-calendar-year
                        (calendar-julian-from-absolute
                         (calendar-absolute-from-gregorian
                          (list m 1 y))))))
             (if (zerop (% (1+ year) 4))
                 22
668 669
               21))) "\"Tal Umatar\" (evening)"))))

Richard M. Stallman's avatar
Richard M. Stallman committed
670 671
;;;###autoload
(put 'hebrew-holidays-2 'risky-local-variable t)
672 673 674
;;;###autoload
(defvar hebrew-holidays-2
  '((if all-hebrew-calendar-holidays
675 676
        (holiday-hanukkah)
      (holiday-hebrew 9 25 "Hanukkah"))
Richard M. Stallman's avatar
Richard M. Stallman committed
677
    (if all-hebrew-calendar-holidays
678 679 680 681 682 683 684 685 686 687 688
      (holiday-hebrew
       10
       (let ((h-year (extract-calendar-year
                      (calendar-hebrew-from-absolute
                       (calendar-absolute-from-gregorian
                        (list displayed-month 28 displayed-year))))))
         (if (= (% (calendar-absolute-from-hebrew (list 10 10 h-year))
                   7)
                6)
             11 10))
       "Tzom Teveth"))
Richard M. Stallman's avatar
Richard M. Stallman committed
689
    (if all-hebrew-calendar-holidays
690 691
        (holiday-hebrew 11 15 "Tu B'Shevat"))))

Richard M. Stallman's avatar
Richard M. Stallman committed
692 693
;;;###autoload
(put 'hebrew-holidays-3 'risky-local-variable t)
694
;;;###autoload
695
(defvar hebrew-holidays-3
696
  '((if all-hebrew-calendar-holidays
697
        (holiday-hebrew
Richard M. Stallman's avatar
Richard M. Stallman committed
698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722
         11
         (let ((m displayed-month)
               (y displayed-year))
           (increment-calendar-month m y 1)
           (let* ((h-year (extract-calendar-year
                           (calendar-hebrew-from-absolute
                            (calendar-absolute-from-gregorian
                             (list m
                                   (calendar-last-day-of-month m y)
                                   y)))))
                  (s-s
                   (calendar-hebrew-from-absolute
                    (if (=
                         (% (calendar-absolute-from-hebrew
                             (list 7 1 h-year))
                            7)
                         6)
                        (calendar-dayname-on-or-before
                         6 (calendar-absolute-from-hebrew
                            (list 11 17 h-year)))
                      (calendar-dayname-on-or-before
                       6 (calendar-absolute-from-hebrew
                          (list 11 16 h-year))))))
                  (day (extract-calendar-day s-s)))
             day))
723 724
         "Shabbat Shirah"))))

Richard M. Stallman's avatar
Richard M. Stallman committed
725 726
;;;###autoload
(put 'hebrew-holidays-4 'risky-local-variable t)
727 728 729
;;;###autoload
(defvar hebrew-holidays-4
  '((holiday-passover-etc)
Richard M. Stallman's avatar
Richard M. Stallman committed
730 731 732 733 734 735 736 737 738 739
    (if (and all-hebrew-calendar-holidays
             (let* ((m displayed-month)
                    (y displayed-year)
                    (year))
               (increment-calendar-month m y -1)
               (let ((year (extract-calendar-year
                            (calendar-julian-from-absolute
                             (calendar-absolute-from-gregorian
                              (list m 1 y))))))
                 (= 21 (% year 28)))))
740
        (holiday-julian 3 26 "Kiddush HaHamah"))
Richard M. Stallman's avatar
Richard M. Stallman committed
741
    (if all-hebrew-calendar-holidays
742 743
        (holiday-tisha-b-av-etc))))

Richard M. Stallman's avatar
Richard M. Stallman committed
744 745
;;;###autoload
(put 'hebrew-holidays 'risky-local-variable t)
746 747 748
;;;###autoload
(defvar hebrew-holidays (append hebrew-holidays-1 hebrew-holidays-2
				hebrew-holidays-3 hebrew-holidays-4)
Jim Blandy's avatar
Jim Blandy committed
749 750 751
  "*Jewish holidays.
See the documentation for `calendar-holidays' for details.")

Richard M. Stallman's avatar
Richard M. Stallman committed
752 753
;;;###autoload
(put 'christian-holidays 'risky-local-variable t)
Jim Blandy's avatar
Jim Blandy committed
754 755 756
;;;###autoload
(defvar christian-holidays
  '((if all-christian-calendar-holidays
757 758
        (holiday-fixed 1 6 "Epiphany"))
    (holiday-easter-etc)
Jim Blandy's avatar
Jim Blandy committed
759
    (if all-christian-calendar-holidays
760
        (holiday-greek-orthodox-easter))
Jim Blandy's avatar
Jim Blandy committed
761
    (if all-christian-calendar-holidays
762
        (holiday-fixed 8 15 "Assumption"))
Jim Blandy's avatar
Jim Blandy committed
763
    (if all-christian-calendar-holidays
764 765
        (holiday-advent))
    (holiday-fixed 12 25 "Christmas")
Jim Blandy's avatar
Jim Blandy committed
766
    (if all-christian-calendar-holidays
767
        (holiday-julian 12 25 "Eastern Orthodox Christmas")))
Jim Blandy's avatar
Jim Blandy committed
768 769
  "*Christian holidays.
See the documentation for `calendar-holidays' for details.")
Richard M. Stallman's avatar
Richard M. Stallman committed
770

Richard M. Stallman's avatar
Richard M. Stallman committed
771 772
;;;###autoload
(put 'islamic-holidays 'risky-local-variable t)
Jim Blandy's avatar
Jim Blandy committed
773 774
;;;###autoload
(defvar islamic-holidays
775 776 777 778 779 780 781 782 783 784 785
  '((holiday-islamic
     1 1
     (format "Islamic New Year %d"
             (let ((m displayed-month)
                   (y displayed-year))
               (increment-calendar-month m y 1)
               (extract-calendar-year
                (calendar-islamic-from-absolute
                 (calendar-absolute-from-gregorian
                  (list
                   m (calendar-last-day-of-month m y) y)))))))
Richard M. Stallman's avatar
Richard M. Stallman committed
786
    (if all-islamic-calendar-holidays
787
        (holiday-islamic 1 10 "Ashura"))
Richard M. Stallman's avatar
Richard M. Stallman committed
788
    (if all-islamic-calendar-holidays
789
        (holiday-islamic 3 12 "Mulad-al-Nabi"))
Richard M. Stallman's avatar
Richard M. Stallman committed
790
    (if all-islamic-calendar-holidays
791
        (holiday-islamic 7 26 "Shab-e-Mi'raj"))
Richard M. Stallman's avatar
Richard M. Stallman committed
792
    (if all-islamic-calendar-holidays
793 794
        (holiday-islamic 8 15 "Shab-e-Bara't"))
    (holiday-islamic 9 1 "Ramadan Begins")
Richard M. Stallman's avatar
Richard M. Stallman committed
795
    (if all-islamic-calendar-holidays
796
        (holiday-islamic 9 27 "Shab-e Qadr"))
Richard M. Stallman's avatar
Richard M. Stallman committed
797
    (if all-islamic-calendar-holidays
798
        (holiday-islamic 10 1 "Id-al-Fitr"))
Richard M. Stallman's avatar
Richard M. Stallman committed
799
    (if all-islamic-calendar-holidays
800
        (holiday-islamic 12 10 "Id-al-Adha")))
Jim Blandy's avatar
Jim Blandy committed
801 802 803
  "*Islamic holidays.
See the documentation for `calendar-holidays' for details.")

Richard M. Stallman's avatar
Richard M. Stallman committed
804 805
;;;###autoload
(put 'solar-holidays 'risky-local-variable t)
Jim Blandy's avatar
Jim Blandy committed
806 807 808 809
;;;###autoload
(defvar solar-holidays
  '((if (fboundp 'atan)
	(solar-equinoxes-solstices))
810 811 812
    (if (progn
	  (require 'cal-dst)
	  t)
813
      (funcall
814
       'holiday-sexp
815 816 817 818
        calendar-daylight-savings-starts
        '(format "Daylight Savings Time Begins %s"
                  (if (fboundp 'atan)
                      (solar-time-string
819 820
                       (/ calendar-daylight-savings-starts-time (float 60))
                       calendar-standard-time-zone-name)
821 822 823 824 825 826 827
                    ""))))
    (funcall
     'holiday-sexp
     calendar-daylight-savings-ends
     '(format "Daylight Savings Time Ends %s"
              (if (fboundp 'atan)
                  (solar-time-string
828 829
                   (/ calendar-daylight-savings-ends-time (float 60))
                   calendar-daylight-time-zone-name)
830
                ""))))
Jim Blandy's avatar
Jim Blandy committed
831 832 833
  "*Sun-related holidays.
See the documentation for `calendar-holidays' for details.")

Richard M. Stallman's avatar
Richard M. Stallman committed
834 835
;;;###autoload
(put 'calendar-holidays 'risky-local-variable t)
Jim Blandy's avatar
Jim Blandy committed
836
(defvar calendar-holidays
837 838 839
  (append general-holidays local-holidays other-holidays
          christian-holidays hebrew-holidays islamic-holidays
          solar-holidays)
Jim Blandy's avatar
Jim Blandy committed
840 841 842 843 844 845 846 847 848 849
  "*List of notable days for the command M-x holidays.

Additional holidays are easy to add to the list, just put them in the list
`other-holidays' in your .emacs file.  Similarly, by setting any of
`general-holidays', `local-holidays' `christian-holidays', `hebrew-holidays',
`islamic-holidays', or `solar-holidays' to nil in your .emacs file, you can
eliminate unwanted categories of holidays.  The intention is that (in the US)
`local-holidays' be set in site-init.el and `other-holidays' be set by the
user.

850 851 852 853 854 855 856 857 858 859 860 861 862 863 864
Entries on the list are expressions that return (possibly empty) lists of
items of the form ((month day year) string) of a holiday in the in the
three-month period centered around `displayed-month' of `displayed-year'.
Several basic functions are provided for this purpose:

    (holiday-fixed MONTH DAY STRING) is a fixed date on the Gregorian calendar
    (holiday-float MONTH DAYNAME K STRING &optional day) is the Kth DAYNAME in
                               MONTH on the Gregorian calendar (0 for Sunday,
                               etc.); K<0 means count back from the end of the
                               month. An optional parameter DAY means the Kth
                               DAYNAME after/before MONTH DAY.
    (holiday-hebrew MONTH DAY STRING)  a fixed date on the Hebrew calendar
    (holiday-islamic MONTH DAY STRING) a fixed date on the Islamic calendar
    (holiday-julian MONTH DAY STRING)  a fixed date on the Julian calendar
    (holiday-sexp SEXP STRING) SEXP is a Gregorian-date-valued expression
Jim Blandy's avatar
Jim Blandy committed
865 866
                               in the variable `year'; if it evaluates to
                               a visible date, that's the holiday; if it
867 868
                               evaluates to nil, there's no holiday.  STRING
                               is an expression in the variable `date'.
Richard M. Stallman's avatar
Richard M. Stallman committed
869 870 871

For example, to add Bastille Day, celebrated in France on July 14, add

872
     (holiday-fixed 7 14 \"Bastille Day\")
Richard M. Stallman's avatar
Richard M. Stallman committed
873 874 875 876

to the list.  To add Hurricane Supplication Day, celebrated in the Virgin
Islands on the fourth Monday in August, add

877
     (holiday-float 8 1 4 \"Hurricane Supplication Day\")
Richard M. Stallman's avatar
Richard M. Stallman committed
878 879

to the list (the last Monday would be specified with `-1' instead of `4').
Jim Blandy's avatar
Jim Blandy committed
880
To add the last day of Hanukkah to the list, use
Richard M. Stallman's avatar
Richard M. Stallman committed
881

882
     (holiday-hebrew 10 2 \"Last day of Hanukkah\")
Richard M. Stallman's avatar
Richard M. Stallman committed
883 884 885 886

since the Hebrew months are numbered with 1 starting from Nisan, while to
add the Islamic feast celebrating Mohammed's birthday use

887
     (holiday-islamic 3 12 \"Mohammed's Birthday\")
Richard M. Stallman's avatar
Richard M. Stallman committed
888 889 890 891

since the Islamic months are numbered from 1 starting with Muharram.  To
add Thomas Jefferson's birthday, April 2, 1743 (Julian), use

892
     (holiday-julian 4 2 \"Jefferson's Birthday\")
Richard M. Stallman's avatar
Richard M. Stallman committed
893

894 895 896
To include a holiday conditionally, use the sexp form or a conditional.  For
example, to include American presidential elections, which occur on the first
Tuesday after the first Monday in November of years divisible by 4, add
Richard M. Stallman's avatar
Richard M. Stallman committed
897

898 899 900 901 902 903 904
     (holiday-sexp
       (if (zerop (% year 4))
           (calendar-gregorian-from-absolute
             (1+ (calendar-dayname-on-or-before
                   1 (+ 6 (calendar-absolute-from-gregorian
                            (list 11 1 year)))))))
       \"US Presidential Election\")
Jim Blandy's avatar
Jim Blandy committed
905 906 907

or

Richard M. Stallman's avatar
Richard M. Stallman committed
908
     (if (zerop (% displayed-year 4))
909
         (holiday-fixed 11
Richard M. Stallman's avatar
Richard M. Stallman committed
910 911 912 913 914 915 916 917 918 919 920
                (extract-calendar-day
                 (calendar-gregorian-from-absolute
                  (1+ (calendar-dayname-on-or-before
                       1 (+ 6 (calendar-absolute-from-gregorian
                               (list 11 1 displayed-year)))))))
                \"US Presidential Election\"))

to the list.  To include the phases of the moon, add

     (lunar-phases)

921 922 923
to the holiday list, where `lunar-phases' is an Emacs-Lisp function that
you've written to return a (possibly empty) list of the relevant VISIBLE dates
with descriptive strings such as
Richard M. Stallman's avatar
Richard M. Stallman committed
924

925
     (((2 6 1989) \"New Moon\") ((2 12 1989) \"First Quarter Moon\") ... ).")
Richard M. Stallman's avatar
Richard M. Stallman committed
926 927 928 929 930 931 932 933 934 935

(defconst calendar-buffer "*Calendar*"
  "Name of the buffer used for the calendar.")

(defconst holiday-buffer "*Holidays*"
  "Name of the buffer used for the displaying the holidays.")

(defconst fancy-diary-buffer "*Fancy Diary Entries*"
  "Name of the buffer used for the optional fancy display of the diary.")

936 937 938
(defconst lunar-phases-buffer "*Phases of Moon*"
  "Name of the buffer used for the lunar phases.")

Richard M. Stallman's avatar
Richard M. Stallman committed
939
(defmacro increment-calendar-month (mon yr n)
940 941
  "Move the variables MON and YR to the month and year by N months.
Forward if N is positive or backward if N is negative."
Richard M. Stallman's avatar
Richard M. Stallman committed
942 943 944 945 946 947 948 949 950 951 952
  (` (let (( macro-y (+ (* (, yr) 12) (, mon) -1 (, n) )))
       (setq (, mon) (1+ (% macro-y 12) ))
       (setq (, yr) (/ macro-y 12)))))

(defmacro calendar-for-loop (var from init to final do &rest body)
  "Execute a for loop."
  (` (let (( (, var) (1- (, init)) ))
       (while (>= (, final) (setq (, var) (1+ (, var))))
         (,@ body)))))

(defmacro calendar-sum (index initial condition expression)
953
  "For INDEX = INITIAL et seq, as long as CONDITION holds, sum EXPRESSION."
Richard M. Stallman's avatar
Richard M. Stallman committed
954 955 956 957 958 959 960
  (` (let (( (, index) (, initial))
             (sum 0))
       (while (, condition)
         (setq sum (+ sum (, expression) ))
         (setq (, index) (1+ (, index))))
       sum)))

961 962 963
;; The following are in-line for speed; they can be called thousands of times
;; when looking up holidays or processing the diary.  Here, for example, are
;; the numbers of calls to calendar/diary/holiday functions in preparing the
Jim Blandy's avatar
Jim Blandy committed
964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988
;; fancy diary display, for a moderately complex diary file, with functions
;; used instead of macros.  There were a total of 10000 such calls:
;;
;;  1934   extract-calendar-month
;;  1852   extract-calendar-year
;;  1819   extract-calendar-day
;;   845   calendar-leap-year-p
;;   837   calendar-day-number
;;   775   calendar-absolute-from-gregorian
;;   346   calendar-last-day-of-month
;;   286   hebrew-calendar-last-day-of-month
;;   188   hebrew-calendar-leap-year-p
;;   180   hebrew-calendar-elapsed-days
;;   163   hebrew-calendar-last-month-of-year
;;    66   calendar-date-compare
;;    65   hebrew-calendar-days-in-year
;;    60   calendar-absolute-from-julian
;;    50   calendar-absolute-from-hebrew
;;    43   calendar-date-equal
;;    38   calendar-gregorian-from-absolute
;;     .
;;     .
;;     .
;;
;; The use of these seven macros eliminates the overhead of 92% of the function
989
;; calls; it's faster this way.
Jim Blandy's avatar
Jim Blandy committed
990

991
(defsubst extract-calendar-month (date)
Richard M. Stallman's avatar
Richard M. Stallman committed
992
  "Extract the month part of DATE which has the form (month day year)."
993
  (car date))
Richard M. Stallman's avatar
Richard M. Stallman committed
994

995
(defsubst extract-calendar-day (date)
Richard M. Stallman's avatar
Richard M. Stallman committed
996
  "Extract the day part of DATE which has the form (month day year)."
997
  (car (cdr date)))
Richard M. Stallman's avatar
Richard M. Stallman committed
998

999
(defsubst extract-calendar-year (date)
Richard M. Stallman's avatar
Richard M. Stallman committed
1000
  "Extract the year part of DATE which has the form (month day year)."
1001
  (car (cdr (cdr date))))
Richard M. Stallman's avatar
Richard M. Stallman committed
1002

1003
(defsubst calendar-leap-year-p (year)
Jim Blandy's avatar
Jim Blandy committed
1004
  "Returns t if YEAR is a Gregorian leap year."
1005 1006 1007 1008
  (and (zerop (% year 4))
       (or (not (zerop (% year 100)))
           (zerop (% year 400)))))

1009 1010
;; The foregoing is a bit faster, but not as clear as the following:
;;
1011
;;(defsubst calendar-leap-year-p (year)
Jim Blandy's avatar
Jim Blandy committed
1012 1013 1014 1015 1016
;;  "Returns t if YEAR is a Gregorian leap year."
;;  (or
;;    (and (=  (% year   4) 0)
;;         (/= (% year 100) 0))
;;    (= (% year 400) 0)))
Jim Blandy's avatar
Jim Blandy committed
1017

1018
(defsubst calendar-last-day-of-month (month year)
Jim Blandy's avatar
Jim Blandy committed
1019
  "The last day in MONTH during YEAR."
1020 1021 1022 1023 1024 1025 1026 1027
  (if (and (= month 2) (calendar-leap-year-p year))
      29
    (aref [31 28 31 30 31 30 31 31 30 31 30 31] (1- month))))

;; An explanation of the calculation can be found in PascAlgorithms by
;; Edward and Ruth Reingold, Scott-Foresman/Little, Brown, 1988.

(defsubst calendar-day-number (date)
Jim Blandy's avatar
Jim Blandy committed
1028 1029 1030
  "Return the day number within the year of the date DATE.
For example, (calendar-day-number '(1 1 1987)) returns the value 1,
while (calendar-day-number '(12 31 1980)) returns 366."
1031 1032 1033 1034 1035 1036 1037 1038
    (let* ((month (extract-calendar-month date))
           (day (extract-calendar-day date))
           (year (extract-calendar-year date))
         (day-of-year (+ day (* 31 (1- month)))))
      (if (> month 2)
          (progn
            (setq day-of-year (- day-of-year (/ (+ 23 (* 4 month)) 10)))
            (if (calendar-leap-year-p year)
Jim Blandy's avatar
Jim Blandy committed
1039
                (setq day-of-year (1+ day-of-year)))))
1040 1041 1042
      day-of-year))

(defsubst calendar-absolute-from-gregorian (date)
Jim Blandy's avatar
Jim Blandy committed
1043 1044
  "The number of days elapsed between the Gregorian date 12/31/1 BC and DATE.
The Gregorian date Sunday, December 31, 1 BC is imaginary."
1045 1046 1047 1048 1049 1050
  (let ((prior-years (1- (extract-calendar-year date))))
    (+ (calendar-day-number date);; Days this year
       (* 365 prior-years);;        + Days in prior years
       (/ prior-years 4);;          + Julian leap years
       (- (/ prior-years 100));;    - century years
       (/ prior-years 400))));;     + Gregorian leap years
Jim Blandy's avatar
Jim Blandy committed
1051

1052
;;;###autoload
Richard M. Stallman's avatar
Richard M. Stallman committed
1053 1054 1055 1056 1057
(defun calendar (&optional arg)
  "Display a three-month calendar in another window.
The three months appear side by side, with the current month in the middle
surrounded by the previous and next months.  The cursor is put on today's date.

Jim Blandy's avatar
Jim Blandy committed
1058 1059
If called with an optional prefix argument, prompts for month and year.

Richard M. Stallman's avatar
Richard M. Stallman committed
1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085
This function is suitable for execution in a .emacs file; appropriate setting
of the variable `view-diary-entries-initially' will cause the diary entries for
the current date to be displayed in another window.  The value of the variable
`number-of-diary-entries' controls the number of days of diary entries
displayed upon initial display of the calendar.

An optional prefix argument ARG causes the calendar displayed to be ARG
months in the future if ARG is positive or in the past if ARG is negative;
in this case the cursor goes on the first day of the month.

Once in the calendar window, future or past months can be moved into view.
Arbitrary months can be displayed, or the calendar can be scrolled forward
or backward.

The cursor can be moved forward or backward by one day, one week, one month,
or one year.  All of these commands take prefix arguments which, when negative,
cause movement in the opposite direction.  For convenience, the digit keys
and the minus sign are automatically prefixes.  The window is replotted as
necessary to display the desired date.

Diary entries can be marked on the calendar or displayed in another window.

Use M-x describe-mode for details of the key bindings in the calendar window.

The Gregorian calendar is assumed.

Jim Blandy's avatar
Jim Blandy committed
1086 1087 1088 1089
After loading the calendar, the hooks given by the variable
`calendar-load-hook' are run.  This the place to add key bindings to the
calendar-mode-map.

Richard M. Stallman's avatar
Richard M. Stallman committed
1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101
After preparing the calendar window initially, the hooks given by the variable
`initial-calendar-window-hook' are run.

The hooks given by the variable `today-visible-calendar-hook' are run
everytime the calendar window gets scrolled, if the current date is visible
in the window.  If it is not visible, the hooks given by the variable
`today-invisible-calendar-hook' are run.  Thus, for example, setting
`today-visible-calendar-hook' to 'calendar-star-date will cause today's date
to be replaced by asterisks to highlight it whenever it is in the window."
  (interactive "P")
  (set-buffer (get-buffer-create calendar-buffer))
  (calendar-mode)
1102
  (let* ((pop-up-windows t)
Jim Blandy's avatar
Jim Blandy committed
1103
         (split-height-threshold 1000)
1104 1105 1106 1107 1108
         (date (if arg
                   (calendar-read-date t)
                 (calendar-current-date)))
         (month (extract-calendar-month date))
         (year (extract-calendar-year date)))
Richard M. Stallman's avatar
Richard M. Stallman committed
1109
    (pop-to-buffer calendar-buffer)
1110
    (increment-calendar-month month year (- calendar-offset))
Jim Blandy's avatar
Jim Blandy committed
1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121
    (generate-calendar-window month year)
    (if (and view-diary-entries-initially (calendar-date-is-visible-p date))
        (view-diary-entries
         (if (vectorp number-of-diary-entries)
             (aref number-of-diary-entries (calendar-day-of-week date))
           number-of-diary-entries))))
  (let* ((diary-buffer (get-file-buffer diary-file))
         (diary-window (if diary-buffer (get-buffer-window diary-buffer)))
         (split-height-threshold (if diary-window 2 1000)))
    (if view-calendar-holidays-initially
        (list-calendar-holidays)))
Richard M. Stallman's avatar
Richard M. Stallman committed
1122 1123
  (run-hooks 'initial-calendar-window-hook))

1124
(autoload 'view-diary-entries "diary-lib"
Richard M. Stallman's avatar
Richard M. Stallman committed
1125
  "Prepare and display a buffer with diary entries.
Richard M. Stallman's avatar
Richard M. Stallman committed
1126
Searches your diary file for entries that match ARG days starting with
Richard M. Stallman's avatar
Richard M. Stallman committed
1127 1128 1129 1130
the date indicated by the cursor position in the displayed three-month
calendar."
  t)

Jim Blandy's avatar
Jim Blandy committed
1131 1132 1133 1134 1135 1136 1137 1138 1139
(autoload 'calendar-sunrise-sunset "solar"
  "Local time of sunrise and sunset for date under cursor."
  t)

(autoload 'calendar-phases-of-moon "lunar"
  "Create a buffer of the phases of the moon for the current calendar window."
  t)

(autoload 'calendar-print-french-date "cal-french"
1140
  "Show the French Revolutionary calendar equivalent of the date under the cursor."
Jim Blandy's avatar
Jim Blandy committed
1141 1142 1143 1144 1145 1146
  t)

(autoload 'calendar-goto-french-date "cal-french"
 "Move cursor to French Revolutionary date."
  t)

1147 1148 1149 1150 1151 1152 1153 1154
(autoload 'calendar-french-date-string "cal-french"
  "String of French Revolutionary date of Gregorian DATE."
  t)

(autoload 'calendar-mayan-date-string "cal-mayan"
  "String of Mayan date of Gregorian DATE."
  t)

Jim Blandy's avatar
Jim Blandy committed
1155
(autoload 'calendar-print-mayan-date "cal-mayan"
1156
  "Show the Mayan long count, Tzolkin, and Haab equivalents of the date under the cursor."
Jim Blandy's avatar
Jim Blandy committed
1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167