root/trunk/lisp/calendar/calendar.el

Revision 4220, 123.0 kB (checked in by miyoshi, 9 months ago)

Sync up with Emacs22.2.

  • Property svn:eol-style set to LF
Line 
1 ;;; calendar.el --- calendar functions
2
3 ;; Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1997,
4 ;;   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
5
6 ;; Author: Edward M. Reingold <reingold@cs.uiuc.edu>
7 ;; Maintainer: Glenn Morris <rgm@gnu.org>
8 ;; Keywords: calendar
9 ;; Human-Keywords: calendar, Gregorian calendar, diary, holidays
10
11 ;; This file is part of GNU Emacs.
12
13 ;; GNU Emacs is free software; you can redistribute it and/or modify
14 ;; it under the terms of the GNU General Public License as published by
15 ;; the Free Software Foundation; either version 3, or (at your option)
16 ;; any later version.
17
18 ;; GNU Emacs is distributed in the hope that it will be useful,
19 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 ;; GNU General Public License for more details.
22
23 ;; You should have received a copy of the GNU General Public License
24 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
25 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
26 ;; Boston, MA 02110-1301, USA.
27
28 ;;; Commentary:
29
30 ;; This collection of functions implements a calendar window.  It
31 ;; generates a calendar for the current month, together with the
32 ;; previous and coming months, or for any other three-month period.
33 ;; The calendar can be scrolled forward and backward in the window to
34 ;; show months in the past or future; the cursor can move forward and
35 ;; backward by days, weeks, or months, making it possible, for
36 ;; instance, to jump to the date a specified number of days, weeks, or
37 ;; months from the date under the cursor.  The user can display a list
38 ;; of holidays and other notable days for the period shown; the
39 ;; notable days can be marked on the calendar, if desired.  The user
40 ;; can also specify that dates having corresponding diary entries (in
41 ;; a file that the user specifies) be marked; the diary entries for
42 ;; any date can be viewed in a separate window.  The diary and the
43 ;; notable days can be viewed independently of the calendar.  Dates
44 ;; can be translated from the (usual) Gregorian calendar to the day of
45 ;; the year/days remaining in year, to the ISO commercial calendar, to
46 ;; the Julian (old style) calendar, to the Hebrew calendar, to the
47 ;; Islamic calendar, to the Baha'i calendar, to the French
48 ;; Revolutionary calendar, to the Mayan calendar, to the Chinese
49 ;; calendar, to the Coptic calendar, to the Ethiopic calendar, and to
50 ;; the astronomical (Julian) day number.  When floating point is
51 ;; available, times of sunrise/sunset can be displayed, as can the
52 ;; phases of the moon.  Appointment notification for diary entries is
53 ;; available.  Calendar printing via LaTeX is available.
54
55 ;; The following files are part of the calendar/diary code:
56
57 ;;       appt.el                       Appointment notification
58 ;;       cal-china.el                  Chinese calendar
59 ;;       cal-coptic.el                 Coptic/Ethiopic calendars
60 ;;       cal-dst.el                    Daylight saving time rules
61 ;;       cal-hebrew.el                 Hebrew calendar
62 ;;       cal-islam.el                  Islamic calendar
63 ;;       cal-bahai.el                  Baha'i calendar
64 ;;       cal-iso.el                    ISO calendar
65 ;;       cal-julian.el                 Julian/astronomical calendars
66 ;;       cal-mayan.el                  Mayan calendars
67 ;;       cal-menu.el                   Menu support
68 ;;       cal-move.el                   Movement in the calendar
69 ;;       cal-persia.el                 Persian calendar
70 ;;       cal-tex.el                    Calendars in LaTeX
71 ;;       cal-x.el                      X-windows dedicated frame functions
72 ;;       diary-lib.el                  Diary functions
73 ;;       holidays.el                   Holiday functions
74 ;;       lunar.el                      Phases of the moon
75 ;;       solar.el                      Sunrise/sunset, equinoxes/solstices
76
77 ;; Technical details of all the calendrical calculations can be found in
78 ;; ``Calendrical Calculations: The Millennium Edition'' by Edward M. Reingold
79 ;; and Nachum Dershowitz, Cambridge University Press (2001).
80
81 ;; An earlier version of the technical details appeared in
82 ;; ``Calendrical Calculations'' by Nachum Dershowitz and Edward M. Reingold,
83 ;; Software--Practice and Experience, Volume 20, Number 9 (September, 1990),
84 ;; pages 899-928, and in ``Calendrical Calculations, Part II: Three Historical
85 ;; Calendars'' by E. M. Reingold,  N. Dershowitz, and S. M. Clamen,
86 ;; Software--Practice and Experience, Volume 23, Number 4 (April, 1993),
87 ;; pages 383-404.
88
89 ;; Hard copies of these two papers can be obtained by sending email to
90 ;; reingold@cs.uiuc.edu with the SUBJECT "send-paper-cal" (no quotes) and
91 ;; the message BODY containing your mailing address (snail).
92
93 ;;; Code:
94
95 (defvar displayed-month)
96 (defvar displayed-year)
97 (defvar calendar-month-name-array)
98 (defvar calendar-starred-day)
99
100 (defun calendar-version ()
101   (interactive)
102   (message "Version 6, October 12, 1995"))
103
104 (defgroup calendar nil
105   "Calendar and time management support."
106   :group 'applications)
107
108 (defgroup diary nil
109   "Emacs diary."
110   :group 'calendar)
111
112 (defgroup appt nil
113   "Appointment notification."
114   :group 'calendar)
115
116 (defgroup holidays nil
117   "Holidays support in calendar."
118   :group 'calendar
119   :prefix "calendar-"
120   :group 'local)
121
122 (defgroup chinese-calendar nil
123   "Chinese calendar support."
124   :group 'calendar)
125
126 (defgroup calendar-tex nil
127   "Options for printing calendar with LaTeX."
128   :prefix "cal-tex-"
129   :group 'calendar)
130
131 (defgroup calendar-hooks nil
132   "Calendar hooks."
133   :prefix "calendar-"
134   :group 'calendar)
135
136
137 (defconst calendar-buffer "*Calendar*"
138   "Name of the buffer used for the calendar.")
139
140 ;;;###autoload
141 (defcustom calendar-offset 0
142   "The offset of the principal month from the center of the calendar window.
143 0 means the principal month is in the center (default), -1 means on the left,
144 +1 means on the right.  Larger (or smaller) values push the principal month off
145 the screen."
146   :type 'integer
147   :group 'calendar)
148
149 ;;;###autoload
150 (defcustom view-diary-entries-initially nil
151   "Non-nil means display current date's diary entries on entry to calendar.
152 The diary is displayed in another window when the calendar is first displayed,
153 if the current date is visible.  The number of days of diary entries displayed
154 is governed by the variable `number-of-diary-entries'.  This variable can
155 be overridden by the value of `calendar-setup'."
156   :type 'boolean
157   :group 'diary)
158
159 ;;;###autoload
160 (defcustom mark-diary-entries-in-calendar nil
161   "Non-nil means mark dates with diary entries, in the calendar window.
162 The marking symbol is specified by the variable `diary-entry-marker'."
163   :type 'boolean
164   :group 'diary)
165
166 ;;;###autoload
167 (defcustom calendar-remove-frame-by-deleting nil
168   "Determine how the calendar mode removes a frame no longer needed.
169 If nil, make an icon of the frame.  If non-nil, delete the frame."
170   :type 'boolean
171   :group 'view)
172
173 (defvar diary-face 'diary
174   "Face name to use for diary entries.")
175 (defface diary
176   '((((min-colors 88) (class color) (background light))
177      :foreground "red1")
178     (((class color) (background light))
179      :foreground "red")
180     (((min-colors 88) (class color) (background dark))
181      :foreground "yellow1")
182     (((class color) (background dark))
183      :foreground "yellow")
184     (t
185      :weight bold))
186   "Face for highlighting diary entries."
187   :group 'diary)
188 ;; backward-compatibility alias
189 (put 'diary-face 'face-alias 'diary)
190
191 (defface calendar-today
192   '((t (:underline t)))
193   "Face for indicating today's date."
194   :group 'diary)
195 ;; backward-compatibility alias
196 (put 'calendar-today-face 'face-alias 'calendar-today)
197
198 (defface holiday
199   '((((class color) (background light))
200      :background "pink")
201     (((class color) (background dark))
202      :background "chocolate4")
203     (t
204      :inverse-video t))
205   "Face for indicating dates that have holidays."
206   :group 'diary)
207 ;; backward-compatibility alias
208 (put 'holiday-face 'face-alias 'holiday)
209
210 (defcustom diary-entry-marker
211   (if (not (display-color-p))
212       "+"
213     'diary)
214   "How to mark dates that have diary entries.
215 The value can be either a single-character string or a face."
216   :type '(choice string face)
217   :group 'diary)
218
219 (defcustom calendar-today-marker
220   (if (not (display-color-p))
221       "="
222     'calendar-today)
223   "How to mark today's date in the calendar.
224 The value can be either a single-character string or a face.
225 Marking today's date is done only if you set up `today-visible-calendar-hook'
226 to request that."
227   :type '(choice string face)
228   :group 'calendar)
229
230 (defcustom calendar-holiday-marker
231   (if (not (display-color-p))
232       "*"
233     'holiday)
234   "How to mark notable dates in the calendar.
235 The value can be either a single-character string or a face."
236   :type '(choice string face)
237   :group 'calendar)
238
239 ;;;###autoload
240 (defcustom view-calendar-holidays-initially nil
241   "Non-nil means display holidays for current three month period on entry.
242 The holidays are displayed in another window when the calendar is first
243 displayed."
244   :type 'boolean
245   :group 'holidays)
246
247 ;;;###autoload
248 (defcustom mark-holidays-in-calendar nil
249   "Non-nil means mark dates of holidays in the calendar window.
250 The marking symbol is specified by the variable `calendar-holiday-marker'."
251   :type 'boolean
252   :group 'holidays)
253
254 ;;;###autoload
255 (defcustom all-hebrew-calendar-holidays nil
256   "If nil, show only major holidays from the Hebrew calendar.
257 This means only those Jewish holidays that appear on secular calendars.
258
259 If t, show all the holidays that would appear in a complete Hebrew calendar."
260   :type 'boolean
261   :group 'holidays)
262
263 ;;;###autoload
264 (defcustom all-christian-calendar-holidays nil
265   "If nil, show only major holidays from the Christian calendar.
266 This means only those Christian holidays that appear on secular calendars.
267
268 If t, show all the holidays that would appear in a complete Christian
269 calendar."
270   :type 'boolean
271   :group 'holidays)
272
273 ;;;###autoload
274 (defcustom all-islamic-calendar-holidays nil
275   "If nil, show only major holidays from the Islamic calendar.
276 This means only those Islamic holidays that appear on secular calendars.
277
278 If t, show all the holidays that would appear in a complete Islamic
279 calendar."
280   :type 'boolean
281   :group 'holidays)
282
283 (defcustom diary-file-name-prefix-function (function (lambda (str) str))
284   "The function that will take a diary file name and return the desired prefix."
285   :type 'function
286   :group 'diary)
287
288 ;;;###autoload
289 (defcustom all-bahai-calendar-holidays nil
290   "If nil, show only major holidays from the Baha'i calendar.
291 These are the days on which work and school must be suspended.
292
293 If t, show all the holidays that would appear in a complete Baha'i
294 calendar."
295   :type 'boolean
296   :group 'holidays)
297
298 (defcustom calendar-mode-hook nil
299   "Hook run when entering `calendar-mode'."
300   :type 'hook
301   :group 'calendar-hooks)
302
303 ;;;###autoload
304 (defcustom calendar-load-hook nil
305   "List of functions to be called after the calendar is first loaded.
306 This is the place to add key bindings to `calendar-mode-map'."
307   :type 'hook
308   :group 'calendar-hooks)
309
310 ;;;###autoload
311 (defcustom initial-calendar-window-hook nil
312   "List of functions to be called when the calendar window is first opened.
313 The functions invoked are called after the calendar window is opened, but
314 once opened is never called again.  Leaving the calendar with the `q' command
315 and reentering it will cause these functions to be called again."
316   :type 'hook
317   :group 'calendar-hooks)
318
319 ;;;###autoload
320 (defcustom today-visible-calendar-hook nil
321   "List of functions called whenever the current date is visible.
322 This can be used, for example, to replace today's date with asterisks; a
323 function `calendar-star-date' is included for this purpose:
324     (setq today-visible-calendar-hook 'calendar-star-date)
325 It can also be used to mark the current date with `calendar-today-marker';
326 a function is also provided for this:
327     (setq today-visible-calendar-hook 'calendar-mark-today)
328
329 The corresponding variable `today-invisible-calendar-hook' is the list of
330 functions called when the calendar function was called when the current
331 date is not visible in the window.
332
333 Other than the use of the provided functions, the changing of any
334 characters in the calendar buffer by the hooks may cause the failure of the
335 functions that move by days and weeks."
336   :type 'hook
337   :group 'calendar-hooks)
338
339 ;;;###autoload
340 (defcustom today-invisible-calendar-hook nil
341   "List of functions called whenever the current date is not visible.
342
343 The corresponding variable `today-visible-calendar-hook' is the list of
344 functions called when the calendar function was called when the current
345 date is visible in the window.
346
347 Other than the use of the provided functions, the changing of any
348 characters in the calendar buffer by the hooks may cause the failure of the
349 functions that move by days and weeks."
350   :type 'hook
351   :group 'calendar-hooks)
352
353 ;;;###autoload
354 (defcustom calendar-move-hook nil
355   "List of functions called whenever the cursor moves in the calendar.
356
357 For example,
358
359   (add-hook 'calendar-move-hook (lambda () (diary-view-entries 1)))
360
361 redisplays the diary for whatever date the cursor is moved to."
362   :type 'hook
363   :group 'calendar-hooks)
364
365 ;;;###autoload
366 (defcustom diary-file "~/diary"
367   "Name of the file in which one's personal diary of dates is kept.
368
369 The file's entries are lines beginning with any of the forms
370 specified by the variable `american-date-diary-pattern', by default:
371
372             MONTH/DAY
373             MONTH/DAY/YEAR
374             MONTHNAME DAY
375             MONTHNAME DAY, YEAR
376             DAYNAME
377
378 with the remainder of the line being the diary entry string for
379 that date.  MONTH and DAY are one or two digit numbers, YEAR is a
380 number and may be written in full or abbreviated to the final two
381 digits (if `abbreviated-calendar-year' is non-nil).  MONTHNAME
382 and DAYNAME can be spelled in full (as specified by the variables
383 `calendar-month-name-array' and `calendar-day-name-array'),
384 abbreviated (as specified by `calendar-month-abbrev-array' and
385 `calendar-day-abbrev-array') with or without a period,
386 capitalized or not.  Any of DAY, MONTH, or MONTHNAME, YEAR can be
387 `*' which matches any day, month, or year, respectively. If the
388 date does not contain a year, it is generic and applies to any
389 year.  A DAYNAME entry applies to the appropriate day of the week
390 in every week.
391
392 The European style (in which the day precedes the month) can be
393 used instead, if you execute `european-calendar' when in the
394 calendar, or set `european-calendar-style' to t in your .emacs
395 file.  The European forms (see `european-date-diary-pattern') are
396
397             DAY/MONTH
398             DAY/MONTH/YEAR
399             DAY MONTHNAME
400             DAY MONTHNAME YEAR
401             DAYNAME
402
403 To revert to the default American style from the European style, execute
404 `american-calendar' in the calendar.
405
406 A diary entry can be preceded by the character
407 `diary-nonmarking-symbol' (ordinarily `&') to make that entry
408 nonmarking--that is, it will not be marked on dates in the calendar
409 window but will appear in a diary window.
410
411 Multiline diary entries are made by indenting lines after the first with
412 either a TAB or one or more spaces.
413
414 Lines not in one the above formats are ignored.  Here are some sample diary
415 entries (in the default American style):
416
417      12/22/1988 Twentieth wedding anniversary!!
418      &1/1. Happy New Year!
419      10/22 Ruth's birthday.
420      21: Payday
421      Tuesday--weekly meeting with grad students at 10am
422               Supowit, Shen, Bitner, and Kapoor to attend.
423      1/13/89 Friday the thirteenth!!
424      &thu 4pm squash game with Lloyd.
425      mar 16 Dad's birthday
426      April 15, 1989 Income tax due.
427      &* 15 time cards due.
428
429 If the first line of a diary entry consists only of the date or day name with
430 no trailing blanks or punctuation, then that line is not displayed in the
431 diary window; only the continuation lines is shown.  For example, the
432 single diary entry
433
434      02/11/1989
435       Bill Blattner visits Princeton today
436       2pm Cognitive Studies Committee meeting
437       2:30-5:30 Lizzie at Lawrenceville for `Group Initiative'
438       4:00pm Jamie Tappenden
439       7:30pm Dinner at George and Ed's for Alan Ryan
440       7:30-10:00pm dance at Stewart Country Day School
441
442 will appear in the diary window without the date line at the beginning.  This
443 facility allows the diary window to look neater, but can cause confusion if
444 used with more than one day's entries displayed.
445
446 Diary entries can be based on Lisp sexps.  For example, the diary entry
447
448       %%(diary-block 11 1 1990 11 10 1990) Vacation
449
450 causes the diary entry \"Vacation\" to appear from November 1 through
451 November 10, 1990.  Other functions available are `diary-float',
452 `diary-anniversary', `diary-cyclic', `diary-day-of-year',
453 `diary-iso-date', `diary-french-date', `diary-hebrew-date',
454 `diary-islamic-date', `diary-bahai-date', `diary-mayan-date',
455 `diary-chinese-date', `diary-coptic-date', `diary-ethiopic-date',
456 `diary-persian-date', `diary-yahrzeit', `diary-sunrise-sunset',
457 `diary-phases-of-moon', `diary-parasha', `diary-omer',
458 `diary-rosh-hodesh', and `diary-sabbath-candles'.  See the
459 documentation for the function `list-sexp-diary-entries' for more
460 details.
461
462 Diary entries based on the Hebrew, the Islamic and/or the Baha'i
463 calendar are also possible, but because these are somewhat slow, they
464 are ignored unless you set the `nongregorian-diary-listing-hook' and
465 the `nongregorian-diary-marking-hook' appropriately.  See the
466 documentation for these functions for details.
467
468 Diary files can contain directives to include the contents of other files; for
469 details, see the documentation for the variable `list-diary-entries-hook'."
470   :type 'file
471   :group 'diary)
472
473 ;;;###autoload
474 (defcustom diary-nonmarking-symbol "&"
475   "Symbol indicating that a diary entry is not to be marked in the calendar."
476   :type 'string
477   :group 'diary)
478
479 ;;;###autoload
480 (defcustom hebrew-diary-entry-symbol "H"
481   "Symbol indicating a diary entry according to the Hebrew calendar."
482   :type 'string
483   :group 'diary)
484
485 ;;;###autoload
486 (defcustom islamic-diary-entry-symbol "I"
487   "Symbol indicating a diary entry according to the Islamic calendar."
488   :type 'string
489   :group 'diary)
490
491 ;;;###autoload
492 (defcustom bahai-diary-entry-symbol "B"
493   "Symbol indicating a diary entry according to the Baha'i calendar."
494   :type 'string
495   :group 'diary)
496
497 ;;;###autoload
498 (defcustom diary-include-string "#include"
499   "The string indicating inclusion of another file of diary entries.
500 See the documentation for the function `include-other-diary-files'."
501   :type 'string
502   :group 'diary)
503
504 (defcustom diary-glob-file-regexp-prefix "^\\#"
505   "The regular expression that gets pre-pended to each of the attribute-regexp's for file-wide specifiers."
506   :type 'regexp
507   :group 'diary)
508
509 (defcustom diary-face-attrs
510   '((" *\\[foreground:\\([-a-z]+\\)\\]$" 1 :foreground string)
511     (" *\\[background:\\([-a-z]+\\)\\]$" 1 :background string)
512     (" *\\[width:\\([-a-z]+\\)\\]$" 1 :width symbol)
513     (" *\\[height:\\([-0-9a-z]+\\)\\]$" 1 :height int)
514     (" *\\[weight:\\([-a-z]+\\)\\]$" 1 :weight symbol)
515     (" *\\[slant:\\([-a-z]+\\)\\]$" 1 :slant symbol)
516     (" *\\[underline:\\([-a-z]+\\)\\]$" 1 :underline stringtnil)
517     (" *\\[overline:\\([-a-z]+\\)\\]$" 1 :overline stringtnil)
518     (" *\\[strike-through:\\([-a-z]+\\)\\]$" 1 :strike-through stringtnil)
519     (" *\\[inverse-video:\\([-a-z]+\\)\\]$" 1 :inverse-video tnil)
520     (" *\\[face:\\([-0-9a-z]+\\)\\]$" 1 :face string)
521     (" *\\[font:\\([-a-z0-9]+\\)\\]$" 1 :font string)
522     ;; Unsupported.
523 ;;;    (" *\\[box:\\([-a-z]+\\)\\]$" 1 :box)
524 ;;;    (" *\\[stipple:\\([-a-z]+\\)\\]$" 1 :stipple)
525     )
526   "A list of (regexp regnum attr attrtype) lists where the
527 regexp says how to find the tag, the regnum says which
528 parenthetical sub-regexp this regexp looks for, and the attr says
529 which attribute of the face (or that this _is_ a face) is being
530 modified."
531   :type 'sexp
532   :group 'diary)
533
534 (defcustom diary-file-name-prefix nil
535   "If non-nil each diary entry is prefixed with the name of the file where it is defined."
536   :type 'boolean
537   :group 'diary)
538
539 ;;;###autoload
540 (defcustom sexp-diary-entry-symbol "%%"
541   "The string used to indicate a sexp diary entry in `diary-file'.
542 See the documentation for the function `list-sexp-diary-entries'."
543   :type 'string
544   :group 'diary)
545
546 ;;;###autoload
547 (defcustom abbreviated-calendar-year t
548   "Interpret a two-digit year DD in a diary entry as either 19DD or 20DD.
549 For the Gregorian calendar; similarly for the Hebrew, Islamic and
550 Baha'i calendars.  If this variable is nil, years must be written in
551 full."
552   :type 'boolean
553   :group 'diary)
554
555 ;;;###autoload
556 (defcustom european-calendar-style nil
557   "Use the European style of dates in the diary and in any displays.
558 If this variable is t, a date 1/2/1990 would be interpreted as February 1,
559 1990.  The default European date styles (see `european-date-diary-pattern')
560 are
561
562             DAY/MONTH
563             DAY/MONTH/YEAR
564             DAY MONTHNAME
565             DAY MONTHNAME YEAR
566             DAYNAME
567
568 Names can be capitalized or not, written in full (as specified by the
569 variable `calendar-day-name-array'), or abbreviated (as specified by
570 `calendar-day-abbrev-array') with or without a period.
571
572 Setting this variable directly does not take effect (if the
573 calendar package is already loaded).  Rather, use either
574 \\[customize] or the functions `european-calendar' and
575 `american-calendar'."
576   :type 'boolean
577   ;; Without :initialize (require 'calendar) throws an error because
578   ;; american-calendar is undefined at this point.
579   :initialize 'custom-initialize-default
580   :set (lambda (symbol value)
581          (if value
582              (european-calendar)
583            (american-calendar)))
584   :group 'diary)
585
586 ;;;###autoload
587 (defcustom american-date-diary-pattern
588   '((month "/" day "[^/0-9]")
589     (month "/" day "/" year "[^0-9]")
590     (monthname " *" day "[^,0-9]")
591     (monthname " *" day ", *" year "[^0-9]")
592     (dayname "\\W"))
593   "List of pseudo-patterns describing the American patterns of date used.
594 See the documentation of `diary-date-forms' for an explanation."
595   :type '(repeat (choice (cons :tag "Backup"
596                                :value (backup . nil)
597                                (const backup)
598                                (repeat (list :inline t :format "%v"
599                                              (symbol :tag "Keyword")
600                                              (choice symbol regexp))))
601                          (repeat (list :inline t :format "%v"
602                                        (symbol :tag "Keyword")
603                                        (choice symbol regexp)))))
604   :group 'diary)
605
606 ;;;###autoload
607 (defcustom european-date-diary-pattern
608   '((day "/" month "[^/0-9]")
609     (day "/" month "/" year "[^0-9]")
610     (backup day " *" monthname "\\W+\\<\\([^*0-9]\\|\\([0-9]+[:aApP]\\)\\)")
611     (day " *" monthname " *" year "[^0-9]")
612     (dayname "\\W"))
613   "List of pseudo-patterns describing the European patterns of date used.
614 See the documentation of `diary-date-forms' for an explanation."
615   :type '(repeat (choice (cons :tag "Backup"
616                                :value (backup . nil)
617                                (const backup)
618                                (repeat (list :inline t :format "%v"
619                                              (symbol :tag "Keyword")
620                                              (choice symbol regexp))))
621                          (repeat (list :inline t :format "%v"
622                                        (symbol :tag "Keyword")
623                                        (choice symbol regexp)))))
624   :group 'diary)
625
626 (autoload 'diary-font-lock-keywords "diary-lib")
627 (autoload 'diary-live-p "diary-lib")
628 (defvar diary-font-lock-keywords)
629
630 (defcustom diary-date-forms
631   (if european-calendar-style
632       european-date-diary-pattern
633     american-date-diary-pattern)
634   "List of pseudo-patterns describing the forms of date used in the diary.
635 The patterns on the list must be MUTUALLY EXCLUSIVE and should not match
636 any portion of the diary entry itself, just the date component.
637
638 A pseudo-pattern is a list of regular expressions and the keywords `month',
639 `day', `year', `monthname', and `dayname'.  The keyword `monthname' will
640 match the name of the month (see `calendar-month-name-array'), capitalized
641 or not, or its user-specified abbreviation (see `calendar-month-abbrev-array'),
642 followed by a period or not; it will also match `*'.  Similarly, `dayname'
643 will match the name of the day (see `calendar-day-name-array'), capitalized or
644 not, or its user-specified abbreviation (see `calendar-day-abbrev-array'),
645 followed by a period or not.  The keywords `month', `day', and `year' will
646 match those numerical values, preceded by arbitrarily many zeros; they will
647 also match `*'.
648
649 The matching of the diary entries with the date forms is done with the
650 standard syntax table from Fundamental mode, but with the `*' changed so
651 that it is a word constituent.
652
653 If, to be mutually exclusive, a pseudo-pattern must match a portion of the
654 diary entry itself, the first element of the pattern MUST be `backup'.  This
655 directive causes the date recognizer to back up to the beginning of the
656 current word of the diary entry, so in no case can the pattern match more than
657 a portion of the first word of the diary entry."
658   :type '(repeat (choice (cons :tag "Backup"
659                                :value (backup . nil)
660                                (const backup)
661                                (repeat (list :inline t :format "%v"
662                                              (symbol :tag "Keyword")
663                                              (choice symbol regexp))))
664                          (repeat (list :inline t :format "%v"
665                                        (symbol :tag "Keyword")
666                                        (choice symbol regexp)))))
667   :initialize 'custom-initialize-default
668   :set (lambda (symbol value)
669          (unless (equal value (eval symbol))
670            (custom-set-default symbol value)
671            (setq diary-font-lock-keywords (diary-font-lock-keywords))
672            ;; Need to redraw not just to get new font-locking, but also
673            ;; to pick up any newly recognized entries.
674            (and (diary-live-p)
675                 (diary))))
676   :group 'diary)
677
678 ;;;###autoload
679 (defcustom european-calendar-display-form
680   '((if dayname (concat dayname ", ")) day " " monthname " " year)
681   "Pseudo-pattern governing the way a date appears in the European style.
682 See the documentation of `calendar-date-display-form' for an explanation."
683   :type 'sexp
684   :group 'calendar)
685
686 ;;;###autoload
687 (defcustom american-calendar-display-form
688   '((if dayname (concat dayname ", ")) monthname " " day ", " year)
689   "Pseudo-pattern governing the way a date appears in the American style.
690 See the documentation of `calendar-date-display-form' for an explanation."
691   :type 'sexp
692   :group 'calendar)
693
694 (defcustom calendar-date-display-form
695   (if european-calendar-style
696       european-calendar-display-form
697     american-calendar-display-form)
698   "Pseudo-pattern governing the way a date appears.
699
700 Used by the function `calendar-date-string', a pseudo-pattern is a list of
701 expressions that can involve the keywords `month', `day', and `year', all
702 numbers in string form, and `monthname' and `dayname', both alphabetic
703 strings.  For example, the ISO standard would use the pseudo- pattern
704
705        '(year \"-\" month \"-\" day)
706
707 while a typical American form would be
708
709        '(month \"/\" day \"/\" (substring year -2))
710
711 and
712
713        '((format \"%9s, %9s %2s, %4s\" dayname monthname day year))
714
715 would give the usual American style in fixed-length fields.
716
717 See the documentation of the function `calendar-date-string'."
718   :type 'sexp
719   :group 'calendar)
720
721 (defun european-calendar ()
722   "Set the interpretation and display of dates to the European style."
723   (interactive)
724   (setq european-calendar-style t)
725   (setq calendar-date-display-form european-calendar-display-form)
726   (setq diary-date-forms european-date-diary-pattern)
727   (update-calendar-mode-line))
728
729 (defun american-calendar ()
730   "Set the interpretation and display of dates to the American style."
731   (interactive)
732   (setq european-calendar-style nil)
733   (setq calendar-date-display-form american-calendar-display-form)
734   (setq diary-date-forms american-date-diary-pattern)
735   (update-calendar-mode-line))
736
737 ;;;###autoload
738 (defcustom print-diary-entries-hook 'lpr-buffer
739   "List of functions called after a temporary diary buffer is prepared.
740 The buffer shows only the diary entries currently visible in the diary
741 buffer.  The default just does the printing.  Other uses might include, for
742 example, rearranging the lines into order by day and time, saving the buffer
743 instead of deleting it, or changing the function used to do the printing."
744   :type 'hook
745   :group 'diary)
746
747 ;;;###autoload
748 (defcustom list-diary-entries-hook nil
749   "List of functions called after diary file is culled for relevant entries.
750 It is to be used for diary entries that are not found in the diary file.
751
752 A function `include-other-diary-files' is provided for use as the value of
753 this hook.  This function enables you to use shared diary files together
754 with your own.  The files included are specified in the diary file by lines
755 of the form
756
757         #include \"filename\"
758
759 This is recursive; that is, #include directives in files thus included are
760 obeyed.  You can change the \"#include\" to some other string by changing
761 the variable `diary-include-string'.  When you use `include-other-diary-files'
762 as part of the list-diary-entries-hook, you will probably also want to use the
763 function `mark-included-diary-files' as part of `mark-diary-entries-hook'.
764
765 For example, you could use
766
767      (setq list-diary-entries-hook
768        '(include-other-diary-files sort-diary-entries))
769      (setq diary-display-hook 'fancy-diary-display)
770
771 in your `.emacs' file to cause the fancy diary buffer to be displayed with
772 diary entries from various included files, each day's entries sorted into
773 lexicographic order."
774   :type 'hook
775   :options '(include-other-diary-files sort-diary-entries)
776   :group 'diary)
777
778 ;;;###autoload
779 (defcustom diary-hook nil
780   "List of functions called after the display of the diary.
781 Can be used for appointment notification."
782   :type 'hook
783   :group 'diary)
784
785 (autoload 'diary-set-maybe-redraw "diary-lib")
786
787 ;;;###autoload
788 (defcustom diary-display-hook nil
789   "List of functions that handle the display of the diary.
790 If nil (the default), `simple-diary-display' is used.  Use `ignore' for no
791 diary display.
792
793 Ordinarily, this just displays the diary buffer (with holidays indicated in
794 the mode line), if there are any relevant entries.  At the time these
795 functions are called, the variable `diary-entries-list' is a list, in order
796 by date, of all relevant diary entries in the form of ((MONTH DAY YEAR)
797 STRING), where string is the diary entry for the given date.  This can be
798 used, for example, a different buffer for display (perhaps combined with
799 holidays), or produce hard copy output.
800
801 A function `fancy-diary-display' is provided as an alternative
802 choice for this hook; this function prepares a special noneditable diary
803 buffer with the relevant diary entries that has neat day-by-day arrangement
804 with headings.  The fancy diary buffer will show the holidays unless the
805 variable `holidays-in-diary-buffer' is set to nil.  Ordinarily, the fancy
806 diary buffer will not show days for which there are no diary entries, even
807 if that day is a holiday; if you want such days to be shown in the fancy
808 diary buffer, set the variable `diary-list-include-blanks' to t."
809   :type 'hook
810   :options '(fancy-diary-display)
811   :initialize 'custom-initialize-default
812   :set 'diary-set-maybe-redraw
813   :group 'diary)
814
815 ;;;###autoload
816 (defcustom nongregorian-diary-listing-hook nil
817   "List of functions called for listing diary file and included files.
818 As the files are processed for diary entries, these functions are used
819 to cull relevant entries.  You can use either or both of
820 `list-hebrew-diary-entries', `list-islamic-diary-entries' and
821 `list-bahai-diary-entries'.  The documentation for these functions
822 describes the style of such diary ent