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

3
;; Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1997,
Miles Bader's avatar
Miles Bader committed
4
;;   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Glenn Morris's avatar
Glenn Morris committed
5
;;   Free Software Foundation, Inc.
Eric S. Raymond's avatar
Eric S. Raymond committed
6

Eric S. Raymond's avatar
Eric S. Raymond committed
7
;; Author: Edward M. Reingold <reingold@cs.uiuc.edu>
8
;; Maintainer: Glenn Morris <rgm@gnu.org>
Eric S. Raymond's avatar
Eric S. Raymond committed
9
;; Keywords: calendar
10
;; Human-Keywords: calendar, Gregorian calendar, 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
;; 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
16
;; the Free Software Foundation; either version 3, or (at your option)
Richard M. Stallman's avatar
Richard M. Stallman committed
17 18
;; 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
;; 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
Erik Naggum's avatar
Erik Naggum committed
25
;; along with GNU Emacs; see the file COPYING.  If not, write to the
Lute Kamstra's avatar
Lute Kamstra committed
26 27
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.
Richard M. Stallman's avatar
Richard M. Stallman committed
28

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

31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
;; 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 Baha'i calendar, to the French
;; Revolutionary calendar, to the Mayan calendar, to the Chinese
;; calendar, to the Coptic calendar, to the Ethiopic calendar, and to
51 52 53 54
;; the astronomical (Julian) day number.  Times of sunrise/sunset can
;; be displayed, as can the phases of the moon.  Appointment
;; notification for diary entries is available.  Calendar printing via
;; LaTeX is available.
Jim Blandy's avatar
Jim Blandy committed
55 56 57

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

58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
;;    appt.el                    Appointment notification
;;    cal-bahai.el               Baha'i calendar
;;    cal-china.el               Chinese calendar
;;    cal-coptic.el              Coptic/Ethiopic calendars
;;    cal-dst.el                 Daylight saving time rules
;;    cal-french.el              French revolutionary calendar
;;    cal-hebrew.el              Hebrew calendar
;;    cal-html.el                Calendars in HTML
;;    cal-islam.el               Islamic calendar
;;    cal-iso.el                 ISO calendar
;;    cal-julian.el              Julian/astronomical calendars
;;    cal-mayan.el               Mayan calendars
;;    cal-menu.el                Menu support
;;    cal-move.el                Movement in the calendar
;;    cal-persia.el              Persian calendar
;;    cal-tex.el                 Calendars in LaTeX
;;    cal-x.el                   Dedicated frame functions
;;    calendar.el                This file
;;    diary-lib.el               Diary functions
;;    holidays.el                Holiday functions
;;    lunar.el                   Phases of the moon
;;    solar.el                   Sunrise/sunset, equinoxes/solstices
Richard M. Stallman's avatar
Richard M. Stallman committed
80 81

;; Technical details of all the calendrical calculations can be found in
82 83
;; ``Calendrical Calculations: The Millennium Edition'' by Edward M. Reingold
;; and Nachum Dershowitz, Cambridge University Press (2001).
Jim Blandy's avatar
Jim Blandy committed
84

85
;; An earlier version of the technical details appeared in
Richard M. Stallman's avatar
Richard M. Stallman committed
86 87
;; ``Calendrical Calculations'' by Nachum Dershowitz and Edward M. Reingold,
;; Software--Practice and Experience, Volume 20, Number 9 (September, 1990),
88
;; pages 899-928, and in ``Calendrical Calculations, Part II: Three Historical
Jim Blandy's avatar
Jim Blandy committed
89
;; Calendars'' by E. M. Reingold,  N. Dershowitz, and S. M. Clamen,
90 91
;; Software--Practice and Experience, Volume 23, Number 4 (April, 1993),
;; pages 383-404.
Jim Blandy's avatar
Jim Blandy committed
92 93 94 95

;; 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
96

97 98 99 100 101 102 103 104 105 106 107

;; A note on free variables:

;; The calendar passes around a few dynamically bound variables, which
;; unfortunately have rather common names.  They are meant to be
;; available for external functions, so the names can't be changed.

;; displayed-month, displayed-year: bound in generate-calendar, the
;;   central month of the 3 month calendar window
;; original-date, number: bound in diary-list-entries, the arguments
;;   with which that function was called.
108
;; date, entry: bound in diary-list-sexp-entries (qv)
109 110

;; Bound in diary-list-entries:
111
;; diary-entries-list: use in d-l, appt.el, and by diary-add-to-list
112
;; diary-saved-point: only used in diary-lib.el, passed to the display func
Glenn Morris's avatar
Glenn Morris committed
113 114 115
;; date-string: only used in diary-lib.el
;; list-only: don't modify the diary-buffer, just return a list of entries
;; file-glob-attrs: yuck
116

Eric S. Raymond's avatar
Eric S. Raymond committed
117
;;; Code:
Richard M. Stallman's avatar
Richard M. Stallman committed
118

119
(require 'cal-loaddefs)
120

121
;; Avoid recursive load of calendar when loading cal-menu.  Yuck.
122
(provide 'calendar)
123 124
(require 'cal-menu)

125

126 127 128 129
(defgroup calendar nil
  "Calendar and time management support."
  :group 'applications)

130 131 132
(defgroup calendar-hooks nil
  "Calendar hooks."
  :prefix "calendar-"
133 134
  :group 'calendar)

135 136
(defgroup diary nil
  "Emacs diary."
137 138 139 140 141 142 143 144 145
  :group 'calendar)

(defgroup holidays nil
  "Holidays support in calendar."
  :group 'calendar
  :prefix "calendar-"
  :group 'local)


146 147 148 149 150 151
(defcustom 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."
  :type 'integer
152 153
  :group 'calendar)

154 155 156 157 158 159 160 161 162 163 164 165
(defcustom calendar-setup nil
  "The frame setup of the calendar.
The choices are: `one-frame' (calendar and diary together in one separate,
dedicated frame); `two-frames' (calendar and diary in separate, dedicated
frames); `calendar-only' (calendar in a separate, dedicated frame); with
any other value the current frame is used.  Using any of the first
three options overrides the value of `view-diary-entries-initially'."
  :type '(choice
          (const :tag "calendar and diary in separate frame" one-frame)
          (const :tag "calendar and diary each in own frame" two-frames)
          (const :tag "calendar in separate frame" calendar-only)
          (const :tag "use current frame" nil))
166 167
  :group 'calendar)

168 169 170 171 172
(defcustom calendar-minimum-window-height 8
  "Minimum height `generate-calendar-window' should use for calendar window."
  :type 'integer
  :version "22.1"
  :group 'calendar)
173

174 175 176
(defcustom 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.
177

178 179 180 181
If you change this variable directly (without using customize)
after starting `calendar', you should call `redraw-calendar' to
update the calendar display to reflect the change, otherwise
movement commands will not work correctly."
182
  :type 'integer
183 184 185 186 187 188 189
  ;; Change the initialize so that if you reload calendar.el, it will not
  ;; cause a redraw (which may fail, e.g. with "invalid byte-code in
  ;; calendar.elc" because of the "byte-compile-dynamic").
  :initialize 'custom-initialize-default
  :set (lambda (sym val)
         (set sym val)
         (redraw-calendar))
190
  :group 'calendar)
191

192
(defcustom view-diary-entries-initially nil
193
  "Non-nil means display current date's diary entries on entry to calendar.
Richard M. Stallman's avatar
Richard M. Stallman committed
194 195
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
196
is governed by the variable `diary-number-of-entries'.  This variable can
Glenn Morris's avatar
Glenn Morris committed
197
be overridden by the value of `calendar-setup'."
198 199
  :type 'boolean
  :group 'diary)
Richard M. Stallman's avatar
Richard M. Stallman committed
200

201
(defcustom mark-diary-entries-in-calendar nil
202
  "Non-nil means mark dates with diary entries, in the calendar window.
203 204 205
The marking symbol is specified by the variable `diary-entry-marker'."
  :type 'boolean
  :group 'diary)
Richard M. Stallman's avatar
Richard M. Stallman committed
206

207
(defcustom calendar-remove-frame-by-deleting t
208
  "Determine how the calendar mode removes a frame no longer needed.
209 210
If nil, make an icon of the frame.  If non-nil, delete the frame."
  :type 'boolean
211 212 213
  :version "23.1"                       ; changed from nil to t
  :group 'view
  :group 'calendar)
214

215 216 217 218 219 220 221
(defface calendar-today
  '((t (:underline t)))
  "Face for indicating today's date."
  :group 'diary)
;; Backward-compatibility alias.  FIXME make obsolete.
(put 'calendar-today-face 'face-alias 'calendar-today)

222
(defface diary
223 224 225
  '((((min-colors 88) (class color) (background light))
     :foreground "red1")
    (((class color) (background light))
ShengHuo ZHU's avatar
ShengHuo ZHU committed
226
     :foreground "red")
227 228
    (((min-colors 88) (class color) (background dark))
     :foreground "yellow1")
229
    (((class color) (background dark))
ShengHuo ZHU's avatar
ShengHuo ZHU committed
230
     :foreground "yellow")
231
    (t
232
     :weight bold))
233 234
  "Face for highlighting diary entries."
  :group 'diary)
Glenn Morris's avatar
Glenn Morris committed
235
;; Backward-compatibility alias.  FIXME make obsolete.
236
(put 'diary-face 'face-alias 'diary)
237

238
(defface holiday
239
  '((((class color) (background light))
ShengHuo ZHU's avatar
ShengHuo ZHU committed
240
     :background "pink")
241
    (((class color) (background dark))
ShengHuo ZHU's avatar
ShengHuo ZHU committed
242
     :background "chocolate4")
243
    (t
ShengHuo ZHU's avatar
ShengHuo ZHU committed
244
     :inverse-video t))
245 246
  "Face for indicating dates that have holidays."
  :group 'diary)
247
;; Backward-compatibility alias.  FIXME make obsolete.
248
(put 'holiday-face 'face-alias 'holiday)
249

250 251 252 253
;; These don't respect changes in font-lock-mode after loading.
(defcustom diary-entry-marker (if (and font-lock-mode (display-color-p))
                                  'diary
                                "+")
254
  "How to mark dates that have diary entries.
255
The value can be either a single-character string or a face."
256 257
  :type '(choice string face)
  :group 'diary)
258

259 260 261
(defcustom calendar-today-marker (if (and font-lock-mode (display-color-p))
                                     'calendar-today
                                   "=")
262
  "How to mark today's date in the calendar.
263
The value can be either a single-character string or a face.
264
Used by `calendar-mark-today'."
265 266
  :type '(choice string face)
  :group 'calendar)
267

268 269 270
(defcustom calendar-holiday-marker (if (and font-lock-mode (display-color-p))
                                       'holiday
                                     "*")
271
  "How to mark notable dates in the calendar.
272
The value can be either a single-character string or a face."
273 274
  :type '(choice string face)
  :group 'calendar)
Richard M. Stallman's avatar
Richard M. Stallman committed
275

276
(defcustom view-calendar-holidays-initially nil
277
  "Non-nil means display holidays for current three month period on entry.
278
The holidays are displayed in another window when the calendar is first
279 280 281
displayed."
  :type 'boolean
  :group 'holidays)
Richard M. Stallman's avatar
Richard M. Stallman committed
282

283
(defcustom mark-holidays-in-calendar nil
284
  "Non-nil means mark dates of holidays in the calendar window.
285 286 287
The marking symbol is specified by the variable `calendar-holiday-marker'."
  :type 'boolean
  :group 'holidays)
Richard M. Stallman's avatar
Richard M. Stallman committed
288

289 290 291 292 293
(defcustom calendar-mode-hook nil
  "Hook run when entering `calendar-mode'."
  :type 'hook
  :group 'calendar-hooks)

294
(defcustom calendar-load-hook nil
295
  "List of functions to be called after the calendar is first loaded.
296 297 298
This is the place to add key bindings to `calendar-mode-map'."
  :type 'hook
  :group 'calendar-hooks)
Jim Blandy's avatar
Jim Blandy committed
299

300
(defcustom initial-calendar-window-hook nil
301
  "List of functions to be called when the calendar window is created.
302
Quitting the calendar and re-entering it will cause these functions
303
to be called again."
304 305
  :type 'hook
  :group 'calendar-hooks)
Richard M. Stallman's avatar
Richard M. Stallman committed
306

307
(defcustom today-visible-calendar-hook nil
308
  "List of functions called whenever the current date is visible.
309 310 311 312
To mark today's date, add the function `calendar-mark-today'.
To replace the date with asterisks, add the function `calendar-star-date'.
See also `today-invisible-calendar-hook'.

313 314
In general, be careful about changing characters in the calendar buffer,
since it may cause the movement commands to fail."
315
  :type 'hook
316
  :options '(calendar-mark-today calendar-star-date)
317
  :group 'calendar-hooks)
Richard M. Stallman's avatar
Richard M. Stallman committed
318

319
(defcustom today-invisible-calendar-hook nil
320
  "List of functions called whenever the current date is not visible.
321
See also `today-visible-calendar-hook'."
322 323
  :type 'hook
  :group 'calendar-hooks)
Richard M. Stallman's avatar
Richard M. Stallman committed
324

325
(defcustom calendar-move-hook nil
326
  "List of functions called whenever the cursor moves in the calendar.
327
For example,
328

329
  (add-hook 'calendar-move-hook (lambda () (diary-view-entries 1)))
330 331 332 333 334

redisplays the diary for whatever date the cursor is moved to."
  :type 'hook
  :group 'calendar-hooks)

Jim Blandy's avatar
Jim Blandy committed
335
;;;###autoload
336
(defcustom diary-file "~/diary"
337
  "Name of the file in which one's personal diary of dates is kept.
Richard M. Stallman's avatar
Richard M. Stallman committed
338

339
The file's entries are lines beginning with any of the forms
Glenn Morris's avatar
Glenn Morris committed
340 341
specified by the variable `diary-date-forms', which by default
uses the forms of `american-date-diary-pattern':
Richard M. Stallman's avatar
Richard M. Stallman committed
342 343 344 345 346 347 348

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

349 350 351
with the remainder of the line being 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
352
digits (if `diary-abbreviated-year-flag' is non-nil).  MONTHNAME
Glenn Morris's avatar
Glenn Morris committed
353
and DAYNAME can be spelled in full (as specified by the variables
Glenn Morris's avatar
Glenn Morris committed
354
`calendar-month-name-array' and `calendar-day-name-array'), or
355
abbreviated (as specified by `calendar-month-abbrev-array' and
Glenn Morris's avatar
Glenn Morris committed
356 357 358 359 360
`calendar-day-abbrev-array') with or without a period.  Case is
ignored.  Any of DAY, MONTH, or MONTHNAME, YEAR can be `*' which
matches any day, month, or year, respectively.  If the date does
not contain a year, it is generic and applies to any year.  A
DAYNAME entry applies to the appropriate day of the week in every week.
361

362 363 364 365 366
You can customize `diary-date-forms' to your preferred format.
Three default styles are provided: `american-date-diary-pattern',
`european-date-diary-pattern', and `iso-date-diary-pattern'.
You can choose between these by setting `calendar-date-style' in your
.emacs file, or by using `calendar-set-date-style' when in the calendar.
Richard M. Stallman's avatar
Richard M. Stallman committed
367

Glenn Morris's avatar
Glenn Morris committed
368 369 370
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
371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390

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
391 392
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
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410
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

411
causes the diary entry \"Vacation\" to appear from November 1 through
Glenn Morris's avatar
Glenn Morris committed
412
November 10, 1990.  See the documentation for the function
413
`diary-list-sexp-entries' for more details.
Richard M. Stallman's avatar
Richard M. Stallman committed
414

415 416
Diary entries based on the Hebrew, the Islamic and/or the Baha'i
calendar are also possible, but because these are somewhat slow, they
417 418
are ignored unless you set the `diary-nongregorian-listing-hook' and
the `diary-nongregorian-marking-hook' appropriately.  See the
419
documentation of these hooks for details.
Richard M. Stallman's avatar
Richard M. Stallman committed
420 421

Diary files can contain directives to include the contents of other files; for
422
details, see the documentation for the variable `diary-list-entries-hook'."
423 424
  :type 'file
  :group 'diary)
Richard M. Stallman's avatar
Richard M. Stallman committed
425

426
;; FIXME do these have to be single characters?
427
(defcustom diary-nonmarking-symbol "&"
428
  "Symbol indicating that a diary entry is not to be marked in the calendar."
429 430
  :type 'string
  :group 'diary)
Richard M. Stallman's avatar
Richard M. Stallman committed
431

432
(defcustom diary-hebrew-entry-symbol "H"
433
  "Symbol indicating a diary entry according to the Hebrew calendar."
434 435
  :type 'string
  :group 'diary)
Richard M. Stallman's avatar
Richard M. Stallman committed
436

437 438 439 440
(define-obsolete-variable-alias 'hebrew-diary-entry-symbol
  'diary-hebrew-entry-symbol "23.1")

(defcustom diary-islamic-entry-symbol "I"
441
  "Symbol indicating a diary entry according to the Islamic calendar."
442 443
  :type 'string
  :group 'diary)
Richard M. Stallman's avatar
Richard M. Stallman committed
444

445 446 447 448
(define-obsolete-variable-alias 'islamic-diary-entry-symbol
  'diary-islamic-entry-symbol "23.1")

(defcustom diary-bahai-entry-symbol "B"
449
  "Symbol indicating a diary entry according to the Baha'i calendar."
450 451 452
  :type 'string
  :group 'diary)

453 454 455
(define-obsolete-variable-alias 'bahai-diary-entry-symbol
  'diary-bahai-entry-symbol "23.1")

Jim Blandy's avatar
Jim Blandy committed
456
;;;###autoload
457
(defcustom european-calendar-style nil
458 459 460 461
  "Non-nil means use the European style of dates in the diary and display.
In this case, a date like 1/2/1990 would be interpreted as
February 1, 1990.  See `european-date-diary-pattern' for the
default European diary date styles.
462 463 464

Setting this variable directly does not take effect (if the
calendar package is already loaded).  Rather, use either
465
\\[customize] or the function `calendar-set-date-style'."
466
  :type 'boolean
467
  ;; Without :initialize (require 'calendar) throws an error because
468
  ;; calendar-set-date-style is undefined at this point.
469
  :initialize 'custom-initialize-default
470 471
  :set (lambda (symbol value)
         (if value
472 473
             (calendar-set-date-style 'european)
           (calendar-set-date-style 'american)))
474
  :group 'diary)
Richard M. Stallman's avatar
Richard M. Stallman committed
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 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527
;;;###autoload
(make-obsolete-variable 'european-calendar-style 'calendar-date-style "23.1")

;; Used by various other packages.
;;;###autoload
(defcustom calendar-date-style (if european-calendar-style 'european
                                 'american)
  "Your preferred style for writing dates.
The options are:
`american' - month/day/year
`european' - day/month/year
`iso'      - year/month/day
This affects how dates written in your diary are interpreted.
It also affects date display, as well as those calendar and diary
functions that take a date as an argument, e.g. `diary-date', by
changing the order in which the arguments are interpreted.

Setting this variable directly does not take effect (if the
calendar package is already loaded).  Rather, use either
\\[customize] or the function `calendar-set-date-style'."
  :version "23.1"
  :type '(choice (const american :tag "Month/Day/Year")
                 (const european :tag "Day/Month/Year")
                 (const iso      :tag "Year/Month/Day"))
  :initialize 'custom-initialize-default
  :set (lambda (symbol value)
         (calendar-set-date-style value))
  :group 'calendar)

;; Next three are provided to aid in setting diary-date-forms.
(defcustom iso-date-diary-pattern
  '((month "[-/]" day "[^-/0-9]")
    (year "[-/]" month "[-/]" day "[^0-9]")
    (monthname "-" day "[^-0-9]")
    (year "-" monthname "-" day "[^0-9]")
    (dayname "\\W"))
    "List of pseudo-patterns describing the ISO style of dates.
The defaults are: MONTH[-/]DAY; YEAR[-/]MONTH[-/]DAY; MONTHNAME-DAY;
YEAR-MONTHNAME-DAY; DAYNAME.  Normally you should not customize this,
but `diary-date-forms' (which see)."
    :version "23.1"
    :type '(repeat (choice (cons :tag "Backup"
                               :value (backup . nil)
                               (const backup)
                               (repeat (list :inline t :format "%v"
                                             (symbol :tag "Keyword")
                                             (choice symbol regexp))))
                         (repeat (list :inline t :format "%v"
                                       (symbol :tag "Keyword")
                                       (choice symbol regexp)))))
    :group 'diary)

528
(defcustom american-date-diary-pattern
Richard M. Stallman's avatar
Richard M. Stallman committed
529 530 531 532 533
  '((month "/" day "[^/0-9]")
    (month "/" day "/" year "[^0-9]")
    (monthname " *" day "[^,0-9]")
    (monthname " *" day ", *" year "[^0-9]")
    (dayname "\\W"))
534 535 536 537
  "List of pseudo-patterns describing the American style of dates.
The defaults are: MONTH/DAY; MONTH/DAY/YEAR; MONTHNAME DAY;
MONTHNAME DAY, YEAR; DAYNAME.  Normally you should not customize this,
but `diary-date-forms' (which see)."
538
  :type '(repeat (choice (cons :tag "Backup"
Glenn Morris's avatar
Glenn Morris committed
539 540 541 542 543 544 545 546
                               :value (backup . nil)
                               (const backup)
                               (repeat (list :inline t :format "%v"
                                             (symbol :tag "Keyword")
                                             (choice symbol regexp))))
                         (repeat (list :inline t :format "%v"
                                       (symbol :tag "Keyword")
                                       (choice symbol regexp)))))
547
  :group 'diary)
Richard M. Stallman's avatar
Richard M. Stallman committed
548

549
(defcustom european-date-diary-pattern
Richard M. Stallman's avatar
Richard M. Stallman committed
550 551
  '((day "/" month "[^/0-9]")
    (day "/" month "/" year "[^0-9]")
552
    (backup day " *" monthname "\\W+\\<\\([^*0-9]\\|\\([0-9]+[:aApP]\\)\\)")
Richard M. Stallman's avatar
Richard M. Stallman committed
553 554
    (day " *" monthname " *" year "[^0-9]")
    (dayname "\\W"))
555 556 557 558
  "List of pseudo-patterns describing the European style of dates.
The defaults are: DAY/MONTH; DAY/MONTH/YEAR; DAY MONTHNAME;
DAY MONTHNAME YEAR; DAYNAME.  Normally you should not customize this, but
`diary-date-forms' (which see)."
559
  :type '(repeat (choice (cons :tag "Backup"
Glenn Morris's avatar
Glenn Morris committed
560 561 562 563 564 565 566 567
                               :value (backup . nil)
                               (const backup)
                               (repeat (list :inline t :format "%v"
                                             (symbol :tag "Keyword")
                                             (choice symbol regexp))))
                         (repeat (list :inline t :format "%v"
                                       (symbol :tag "Keyword")
                                       (choice symbol regexp)))))
568 569
  :group 'diary)

570 571
(defvar diary-font-lock-keywords)

572 573 574 575 576
(defcustom diary-date-forms (cond ((eq calendar-date-style 'iso)
                                   iso-date-diary-pattern)
                                  ((eq calendar-date-style 'european)
                                   european-date-diary-pattern)
                                  (t american-date-diary-pattern))
577
  "List of pseudo-patterns describing the forms of date used in the diary.
Juanma Barranquero's avatar
Juanma Barranquero committed
578
The patterns on the list must be MUTUALLY EXCLUSIVE and should not match
Richard M. Stallman's avatar
Richard M. Stallman committed
579 580 581 582
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
583 584 585 586 587 588 589 590
match the name of the month (see `calendar-month-name-array'), capitalized
or not, or its user-specified abbreviation (see `calendar-month-abbrev-array'),
followed by a period or not; it will also match `*'.  Similarly, `dayname'
will match the name of the day (see `calendar-day-name-array'), capitalized or
not, or its user-specified abbreviation (see `calendar-day-abbrev-array'),
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 `*'.
Richard M. Stallman's avatar
Richard M. Stallman committed
591 592 593 594 595 596 597

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
598 599
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
600 601 602 603
a portion of the first word of the diary entry.

For examples of three common styles, see `american-date-diary-pattern',
`european-date-diary-pattern', and `iso-date-diary-pattern'."
604
  :type '(repeat (choice (cons :tag "Backup"
Glenn Morris's avatar
Glenn Morris committed
605 606 607 608 609 610 611 612
                               :value (backup . nil)
                               (const backup)
                               (repeat (list :inline t :format "%v"
                                             (symbol :tag "Keyword")
                                             (choice symbol regexp))))
                         (repeat (list :inline t :format "%v"
                                       (symbol :tag "Keyword")
                                       (choice symbol regexp)))))
613 614 615 616 617 618 619 620 621
  :initialize 'custom-initialize-default
  :set (lambda (symbol value)
         (unless (equal value (eval symbol))
           (custom-set-default symbol value)
           (setq diary-font-lock-keywords (diary-font-lock-keywords))
           ;; Need to redraw not just to get new font-locking, but also
           ;; to pick up any newly recognized entries.
           (and (diary-live-p)
                (diary))))
622
  :group 'diary)
Richard M. Stallman's avatar
Richard M. Stallman committed
623

624 625 626 627 628 629 630 631 632 633 634
;; Next three are provided to aid in setting calendar-date-display-form.
(defcustom iso-calendar-display-form '((format "%s-%.2d-%.2d" year
                                               (string-to-number month)
                                               (string-to-number day)))
  "Pseudo-pattern governing the way a date appears in the ISO style.
Normally you should not customize this, but `calendar-date-display-form'
\(which see)."
  :type 'sexp
  :version "23.1"
  :group 'calendar)

635
(defcustom european-calendar-display-form
Jim Blandy's avatar
Jim Blandy committed
636
  '((if dayname (concat dayname ", ")) day " " monthname " " year)
637
  "Pseudo-pattern governing the way a date appears in the European style.
638 639
Normally you should not customize this, but `calendar-date-display-form'
\(which see)."
640 641
  :type 'sexp
  :group 'calendar)
Richard M. Stallman's avatar
Richard M. Stallman committed
642

643
(defcustom american-calendar-display-form
Jim Blandy's avatar
Jim Blandy committed
644
  '((if dayname (concat dayname ", ")) monthname " " day ", " year)
645
  "Pseudo-pattern governing the way a date appears in the American style.
646 647
Normally you should not customize this, but `calendar-date-display-form'
\(which see)."
648 649
  :type 'sexp
  :group 'calendar)
Richard M. Stallman's avatar
Richard M. Stallman committed
650

651 652 653 654 655 656 657 658 659 660
(defcustom calendar-date-display-form (cond ((eq calendar-date-style 'iso)
                                             iso-calendar-display-form)
                                            ((eq calendar-date-style 'european)
                                             european-calendar-display-form)
                                            (t american-calendar-display-form))
  "Pseudo-pattern governing the way a calendar date appears.
Used by the function `calendar-date-string' (which see), 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, a typical American form would be
Richard M. Stallman's avatar
Richard M. Stallman committed
661 662 663

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

664
whereas
Richard M. Stallman's avatar
Richard M. Stallman committed
665 666 667

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

668 669 670 671
would give the usual American style in fixed-length fields.  The variables
`iso-calendar-display-form', `european-calendar-display-form', and
`american-calendar-display-form' provide some defaults for three common
styles."
672 673
  :type 'sexp
  :group 'calendar)
Richard M. Stallman's avatar
Richard M. Stallman committed
674

675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690
(defun calendar-set-date-style (style)
  "Set the style of calendar and diary dates to STYLE (a symbol).
The valid styles are described in the documentation of `calendar-date-style'."
  (interactive (list (intern
                      (completing-read "Date style: "
                                       '("american" "european" "iso") nil t
                                       nil nil "american"))))
  (or (memq style '(american european iso))
      (setq style 'american))
  (setq calendar-date-style style
        calendar-date-display-form
        (symbol-value (intern-soft (format "%s-calendar-display-form" style)))
        diary-date-forms
        (symbol-value (intern-soft (format "%s-date-diary-pattern" style))))
  (update-calendar-mode-line))

Richard M. Stallman's avatar
Richard M. Stallman committed
691 692 693
(defun european-calendar ()
  "Set the interpretation and display of dates to the European style."
  (interactive)
694 695 696
  (calendar-set-date-style 'european))

(make-obsolete 'european-calendar 'calendar-set-date-style "23.1")
Richard M. Stallman's avatar
Richard M. Stallman committed
697 698 699 700

(defun american-calendar ()
  "Set the interpretation and display of dates to the American style."
  (interactive)
701 702 703
  (calendar-set-date-style 'american))

(make-obsolete 'american-calendar 'calendar-set-date-style "23.1")
Richard M. Stallman's avatar
Richard M. Stallman committed
704

705
;; FIXME move to diary-lib and adjust appt.
706
;; Add appt-make-list as an option?
707
(defcustom diary-hook nil
708
  "List of functions called after the display of the diary.
709 710 711
Can be used for appointment notification."
  :type 'hook
  :group 'diary)
712

713
(defcustom diary-display-hook nil
714
  "List of functions that handle the display of the diary.
715
If nil (the default), `diary-simple-display' is used.  Use
716 717 718 719 720 721 722 723 724 725 726
`ignore' for no diary display.

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 used,
for example, a different buffer for display (perhaps combined
with holidays), or produce hard copy output.

727
A function `diary-fancy-display' is provided for use with this
728 729 730 731 732 733 734 735
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' non-nil."
736
  :type 'hook
737
  :options '(diary-fancy-display)
738 739
  :initialize 'custom-initialize-default
  :set 'diary-set-maybe-redraw
740
  :group 'diary)
Richard M. Stallman's avatar
Richard M. Stallman committed
741

742
(defcustom holidays-in-diary-buffer t
743
  "Non-nil means include holidays in the diary display.
Richard M. Stallman's avatar
Richard M. Stallman committed
744
The holidays appear in the mode line of the diary buffer, or in the
745
fancy diary buffer next to the date.  This slows down the diary functions
746 747 748
somewhat; setting it to nil makes the diary display faster."
  :type 'boolean
  :group 'holidays)
Richard M. Stallman's avatar
Richard M. Stallman committed
749

750 751 752 753
(defcustom calendar-debug-sexp nil
  "Turn debugging on when evaluating a sexp in the diary or holiday list."
  :type 'boolean
  :group 'calendar)
754

755 756 757 758
;; The various holiday variables are autoloaded because people
;; are used to using them to set calendar-holidays without having to
;; explicitly load this file.

759
;;;###autoload
760
(defcustom general-holidays
761 762
  '((holiday-fixed 1 1 "New Year's Day")
    (holiday-float 1 1 3 "Martin Luther King Day")
Edward M. Reingold's avatar
Edward M. Reingold committed
763
    (holiday-fixed 2 2 "Groundhog Day")
764 765 766
    (holiday-fixed 2 14 "Valentine's Day")
    (holiday-float 2 1 3 "President's Day")
    (holiday-fixed 3 17 "St. Patrick's Day")
Edward M. Reingold's avatar
Edward M. Reingold committed
767
    (holiday-fixed 4 1 "April Fools' Day")
768 769 770 771 772 773 774 775 776 777
    (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"))
778
  "General holidays.  Default value is for the United States.
779 780 781
See the documentation for `calendar-holidays' for details."
  :type 'sexp
  :group 'holidays)
782
;;;###autoload
783 784
(put 'general-holidays 'risky-local-variable t)

785
;;;###autoload
786
(defcustom oriental-holidays
787
  '((holiday-chinese-new-year))
788
  "Oriental holidays.
789 790 791
See the documentation for `calendar-holidays' for details."
  :type 'sexp
  :group 'holidays)
Richard M. Stallman's avatar
Richard M. Stallman committed
792
;;;###autoload
793 794
(put 'oriental-holidays 'risky-local-variable t)

795
;;;###autoload
796
(defcustom local-holidays nil
797
  "Local holidays.
798 799 800
See the documentation for `calendar-holidays' for details."
  :type 'sexp
  :group 'holidays)
Richard M. Stallman's avatar
Richard M. Stallman committed
801
;;;###autoload
802 803
(put 'local-holidays 'risky-local-variable t)

804
;;;###autoload
805
(defcustom other-holidays nil
806
  "User defined holidays.
807 808 809
See the documentation for `calendar-holidays' for details."
  :type 'sexp
  :group 'holidays)
Richard M. Stallman's avatar
Richard M. Stallman committed
810
;;;###autoload
811 812
(put 'other-holidays 'risky-local-variable t)

813
(defcustom calendar-hebrew-all-holidays-flag nil
814 815 816 817 818 819 820
  "If nil, show only major holidays from the Hebrew calendar.
This means only those Jewish holidays that appear on secular calendars.
Otherwise, show all the holidays that would appear in a complete Hebrew
calendar."
  :type 'boolean
  :group 'holidays)

821 822 823
(define-obsolete-variable-alias 'all-hebrew-calendar-holidays
  'calendar-hebrew-all-holidays-flag "23.1")

824
;;;###autoload
825
(defvar hebrew-holidays-1
826
  '((holiday-hebrew-rosh-hashanah)
827
    (if calendar-hebrew-all-holidays-flag
828 829
        (holiday-julian
         11
830 831 832
         (let ((m displayed-month)
               (y displayed-year)
               year)
833
           (increment-calendar-month m y -1)
834 835 836 837 838 839
           (setq year (extract-calendar-year
                       (calendar-julian-from-absolute
                        (calendar-absolute-from-gregorian (list m 1 y)))))
           (if (zerop (% (1+ year) 4))
               22
             21)) "\"Tal Umatar\" (evening)")))
Glenn Morris's avatar
Glenn Morris committed
840
  "Component of the default value of `hebrew-holidays'.")
Richard M. Stallman's avatar
Richard M. Stallman committed
841
;;;###autoload
842
(put 'hebrew-holidays-1 'risky-local-variable t)
843
(make-obsolete-variable 'hebrew-holidays-1 'hebrew-holidays "23.1")
844

845
;;;###autoload
846
(defvar hebrew-holidays-2
847
  '((holiday-hebrew-hanukkah) ; respects calendar-hebrew-all-holidays-flag
848
    (if calendar-hebrew-all-holidays-flag
849 850 851 852 853 854
      (holiday-hebrew
       10
       (let ((h-year (extract-calendar-year
                      (calendar-hebrew-from-absolute
                       (calendar-absolute-from-gregorian
                        (list displayed-month 28 displayed-year))))))
855
         (if (= 6 (% (calendar-hebrew-to-absolute (list 10 10 h-year))
856
                     7))
857 858
             11 10))
       "Tzom Teveth"))
859
    (if calendar-hebrew-all-holidays-flag
Glenn Morris's avatar
Glenn Morris committed
860 861
        (holiday-hebrew 11 15 "Tu B'Shevat")))
  "Component of the default value of `hebrew-holidays'.")
Richard M. Stallman's avatar
Richard M. Stallman committed
862
;;;###autoload
863
(put 'hebrew-holidays-2 'risky-local-variable t)
864
(make-obsolete-variable 'hebrew-holidays-2 'hebrew-holidays "23.1")
865

866
;;;###autoload
867
(defvar hebrew-holidays-3
868
  '((if calendar-hebrew-all-holidays-flag
869
        (holiday-hebrew
Richard M. Stallman's avatar
Richard M. Stallman committed
870
         11
871 872 873 874 875
         (let* ((m displayed-month)
                (y displayed-year)
                (h-year (progn
                          (increment-calendar-month m y 1)
                          (extract-calendar-year
Richard M. Stallman's avatar
Richard M. Stallman committed
876 877
                           (calendar-hebrew-from-absolute
                            (calendar-absolute-from-gregorian
878 879 880 881
                             (list m (calendar-last-day-of-month m y) y))))))
                (s-s
                 (calendar-hebrew-from-absolute
                  (if (= 6
882
                         (% (calendar-hebrew-to-absolute
883 884
                             (list 7 1 h-year))
                            7))
Richard M. Stallman's avatar
Richard M. Stallman committed
885
                      (calendar-dayname-on-or-before
886
                       6 (calendar-hebrew-to-absolute
887 888
                          (list 11 17 h-year)))
                    (calendar-dayname-on-or-before
889
                     6 (calendar-hebrew-to-absolute
890 891 892
                        (list 11 16 h-year))))))
                (day (extract-calendar-day s-s)))
           day)
Glenn Morris's avatar
Glenn Morris committed
893 894
         "Shabbat Shirah")))
  "Component of the default value of `hebrew-holidays'.")
Richard M. Stallman's avatar
Richard M. Stallman committed
895
;;;###autoload
896
(put 'hebrew-holidays-3 'risky-local-variable t)
897
(make-obsolete-variable 'hebrew-holidays-3 'hebrew-holidays "23.1")
898

899
;;;###autoload
900
(defvar hebrew-holidays-4
901
  '((holiday-hebrew-passover)
902
    (and calendar-hebrew-all-holidays-flag
903 904 905 906 907 908 909 910 911
         (let* ((m displayed-month)
                (y displayed-year)
                (year (progn
                        (increment-calendar-month m y -1)
                        (extract-calendar-year
                         (calendar-julian-from-absolute
                          (calendar-absolute-from-gregorian (list m 1 y)))))))
           (= 21 (% year 28)))
         (holiday-julian 3 26 "Kiddush HaHamah"))
912
    (if calendar-hebrew-all-holidays-flag
913
        (holiday-hebrew-tisha-b-av)))
Glenn Morris's avatar
Glenn Morris committed
914
    "Component of the default value of `hebrew-holidays'.")
Richard M. Stallman's avatar
Richard M. Stallman committed
915