aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/calendar/holidays.el255
1 files changed, 112 insertions, 143 deletions
diff --git a/lisp/calendar/holidays.el b/lisp/calendar/holidays.el
index c3986052b49..69ada519931 100644
--- a/lisp/calendar/holidays.el
+++ b/lisp/calendar/holidays.el
@@ -7,6 +7,7 @@
7 7
8;; This file is part of GNU Emacs. 8;; This file is part of GNU Emacs.
9 9
10
10;; GNU Emacs is distributed in the hope that it will be useful, 11;; GNU Emacs is distributed in the hope that it will be useful,
11;; but WITHOUT ANY WARRANTY. No author or distributor 12;; but WITHOUT ANY WARRANTY. No author or distributor
12;; accepts responsibility to anyone for the consequences of using it 13;; accepts responsibility to anyone for the consequences of using it
@@ -49,7 +50,7 @@
49 50
50(require 'calendar) 51(require 'calendar)
51 52
52(autoload 'calendar-holiday-function-solar-equinoxes-solstices "solar" 53(autoload 'solar-equinoxes-solstices "solar"
53 "Date and time of equinoxes and solstices, if visible in the calendar window. 54 "Date and time of equinoxes and solstices, if visible in the calendar window.
54Requires floating point." 55Requires floating point."
55 t) 56 t)
@@ -109,7 +110,7 @@ The holidays are those in the list calendar-holidays."
109 (msg (format "%s: %s" date-string holiday-string))) 110 (msg (format "%s: %s" date-string holiday-string)))
110 (if (not holiday-list) 111 (if (not holiday-list)
111 (message "No holidays known for %s" date-string) 112 (message "No holidays known for %s" date-string)
112 (if (<= (length msg) (screen-width)) 113 (if (<= (length msg) (frame-width))
113 (message msg) 114 (message msg)
114 (set-buffer (get-buffer-create holiday-buffer)) 115 (set-buffer (get-buffer-create holiday-buffer))
115 (setq buffer-read-only nil) 116 (setq buffer-read-only nil)
@@ -172,81 +173,65 @@ holidays are found, nil if not."
172(defun calendar-holiday-list () 173(defun calendar-holiday-list ()
173 "Form the list of holidays that occur on dates in the calendar window. 174 "Form the list of holidays that occur on dates in the calendar window.
174The holidays are those in the list calendar-holidays." 175The holidays are those in the list calendar-holidays."
175 (let ((p (eval calendar-holidays)) 176 (let ((p calendar-holidays)
176 (holiday-list)) 177 (holiday-list))
177 (while p 178 (while p
178 (let* ((function-name 179 (let* ((holidays
179 (intern (format "calendar-holiday-function-%s" (car (car p))))) 180 (if calendar-debug-sexp
180 (holidays 181 (let ((stack-trace-on-error t))
181 (condition-case nil 182 (eval (car p)))
182 (if (cdr (car p));; optional arguments 183 (condition-case nil
183 (funcall function-name (cdr (car p))) 184 (eval (car p))
184 (funcall function-name)) 185 (error (beep)
185 (error 186 (message "Bad holiday list item: %s" (car p))
186 (beep) 187 (sleep-for 2))))))
187 (message "Bad holiday list item: %s" (car p))
188 (sleep-for 2)))))
189 (if holidays 188 (if holidays
190 (setq holiday-list (append holidays holiday-list)))) 189 (setq holiday-list (append holidays holiday-list))))
191 (setq p (cdr p))) 190 (setq p (cdr p)))
192 (setq holiday-list (sort holiday-list 'calendar-date-compare)))) 191 (setq holiday-list (sort holiday-list 'calendar-date-compare))))
193 192
194;; Below are the functions that calculate the dates of holidays; these 193;; Below are the functions that calculate the dates of holidays; these
195;; are called by the funcall in the function calendar-holiday-list. If you 194;; are eval'ed in the function calendar-holiday-list. If you
196;; write other such functions, be sure to imitate the style used below, 195;; write other such functions, be sure to imitate the style used below.
197;; including the evaluation of each element in the list that constitutes 196;; Remember that each function must return a list of items of the form
198;; the argument to the function. If you don't do this evaluation, the 197;; ((month day year) string) of VISIBLE dates in the calendar window.
199;; list calendar-holidays cannot contain expressions (as, for example, in 198
200;; the entry for the Islamic new year.) Also remember that each function 199(defun holiday-fixed (month day string)
201;; must return a list of items of the form ((month day year) string); 200 "Holiday on MONTH, DAY (Gregorian) called STRING.
202;; the date (month day year) should be visible in the calendar window. 201If MONTH, DAY is visible, the value returned is the list (((MONTH DAY year)
203 202STRING)). Returns nil if it is not visible in the current calendar window."
204(defun calendar-holiday-function-fixed (x) 203 (let ((m displayed-month)
205 "Returns the corresponding Gregorian date, if visible in the window, to 204 (y displayed-year))
206(month day) where month is (car X) and day is (car (cdr X)). If it is
207visible, the value returned is the list (((month day year) string)) where
208string is (car (nthcdr 2 X)). Returns nil if it is not visible in the
209current calendar window."
210 (let* ((month (eval (car x)))
211 (day (eval (car (cdr x))))
212 (string (eval (car (nthcdr 2 x))))
213 (m displayed-month)
214 (y displayed-year))
215 (increment-calendar-month m y (- 11 month)) 205 (increment-calendar-month m y (- 11 month))
216 (if (> m 9) 206 (if (> m 9)
217 (list (list (list month day y) string))))) 207 (list (list (list month day y) string)))))
218 208
219(defun calendar-holiday-function-float (x) 209(defun holiday-float (month dayname n string &optional day)
220 "Returns the corresponding Gregorian date, if visible in the window, to the 210 "Holiday on MONTH, DAYNAME (Nth occurrence, Gregorian) called STRING.
221n-th occurrence (negative counts from the end of the month) of dayname in 211If the Nth DAYNAME in MONTH is visible, the value returned is the list
222month where month is (car X), dayname is (car (cdr X)), and n is 212(((MONTH DAY year) STRING)).
223(car (nthcdr 2 X)). If it is visible, the value returned is the list 213
224(((month day year) string)) where string is (car (nthcdr 3 X)). 214If N<0, count backward from the end of MONTH.
215
216An optional parameter DAY means the Nth DAYNAME after/before MONTH DAY.
217
225Returns nil if it is not visible in the current calendar window." 218Returns nil if it is not visible in the current calendar window."
226 (let* ((month (eval (car x))) 219 (let ((m displayed-month)
227 (dayname (eval (car (cdr x)))) 220 (y displayed-year))
228 (n (eval (car (nthcdr 2 x))))
229 (string (eval (car (nthcdr 3 x))))
230 (m displayed-month)
231 (y displayed-year))
232 (increment-calendar-month m y (- 11 month)) 221 (increment-calendar-month m y (- 11 month))
233 (if (> m 9) 222 (if (> m 9)
234 (list (list (calendar-nth-named-day n dayname month y) string))))) 223 (list (list (calendar-nth-named-day n dayname month y day) string)))))
235 224
236(defun calendar-holiday-function-julian (x) 225(defun holiday-julian (month day string)
237 "Returns the corresponding Gregorian date, if visible in the window, to the 226 "Holiday on MONTH, DAY (Julian) called STRING.
238Julian date (month day) where month is (car X) and day is (car (cdr X)). 227If MONTH, DAY (Julian) is visible, the value returned is corresponding
239If it is visible, the value returned is the list (((month day year) string)) 228Gregorian date in the form of the list (((month day year) STRING)). Returns
240where string is (car (nthcdr 2 X)). Returns nil if it is not visible in the 229nil if it is not visible in the current calendar window."
241current calendar window." 230 (let ((m1 displayed-month)
242 (let* ((month (eval (car x))) 231 (y1 displayed-year)
243 (day (eval (car (cdr x)))) 232 (m2 displayed-month)
244 (string (eval (car (nthcdr 2 x)))) 233 (y2 displayed-year)
245 (m1 displayed-month) 234 (year))
246 (y1 displayed-year)
247 (m2 displayed-month)
248 (y2 displayed-year)
249 (year))
250 (increment-calendar-month m1 y1 -1) 235 (increment-calendar-month m1 y1 -1)
251 (increment-calendar-month m2 y2 1) 236 (increment-calendar-month m2 y2 1)
252 (let* ((start-date (calendar-absolute-from-gregorian 237 (let* ((start-date (calendar-absolute-from-gregorian
@@ -264,16 +249,12 @@ current calendar window."
264 (if (calendar-date-is-visible-p date) 249 (if (calendar-date-is-visible-p date)
265 (list (list date string))))))) 250 (list (list date string)))))))
266 251
267(defun calendar-holiday-function-islamic (x) 252(defun holiday-islamic (month day string)
268 "Returns the corresponding Gregorian date, if visible in the window, to the 253 "Holiday on MONTH, DAY (Islamic) called STRING.
269Islamic date (month day) where month is (car X) and day is (car (cdr X)). 254If MONTH, DAY (Islamic) is visible, the value returned is corresponding
270If it is visible, the value returned is the list (((month day year) string)) 255Gregorian date in the form of the list (((month day year) STRING)). Returns
271where string is (car (nthcdr 2 X)). Returns nil if it is not visible in 256nil if it is not visible in the current calendar window."
272the current calendar window." 257 (let* ((islamic-date (calendar-islamic-from-absolute
273 (let* ((month (eval (car x)))
274 (day (eval (car (cdr x))))
275 (string (eval (car (nthcdr 2 x))))
276 (islamic-date (calendar-islamic-from-absolute
277 (calendar-absolute-from-gregorian 258 (calendar-absolute-from-gregorian
278 (list displayed-month 15 displayed-year)))) 259 (list displayed-month 15 displayed-year))))
279 (m (extract-calendar-month islamic-date)) 260 (m (extract-calendar-month islamic-date))
@@ -288,75 +269,64 @@ the current calendar window."
288 (if (calendar-date-is-visible-p date) 269 (if (calendar-date-is-visible-p date)
289 (list (list date string)))))))) 270 (list (list date string))))))))
290 271
291(defun calendar-holiday-function-hebrew (x) 272(defun holiday-hebrew (month day string)
292 "Returns the corresponding Gregorian date, if visible in the window, to the 273 "Holiday on MONTH, DAY (Hebrew) called STRING.
293Hebrew date (month day) where month is (car X) and day is (car (cdr X)). 274If MONTH, DAY (Hebrew) is visible, the value returned is corresponding
294If it is visible, the value returned is the list (((month day year) string)) 275Gregorian date in the form of the list (((month day year) STRING)). Returns
295where string is (car (nthcdr 2 X)). Returns nil if it is not visible in 276nil if it is not visible in the current calendar window."
296the current calendar window." 277 (if (memq displayed-month;; This test is only to speed things up a bit;
297 (let* ((month (eval (car x))) 278 (list ;; it works fine without the test too.
298 (day (eval (car (cdr x)))) 279 (if (< 11 month) (- month 11) (+ month 1))
299 (string (eval (car (nthcdr 2 x))))) 280 (if (< 10 month) (- month 10) (+ month 2))
300 (if (memq displayed-month;; This test is only to speed things up a bit; 281 (if (< 9 month) (- month 9) (+ month 3))
301 (list ;; it works fine without the test too. 282 (if (< 8 month) (- month 8) (+ month 4))
302 (if (< 11 month) (- month 11) (+ month 1)) 283 (if (< 7 month) (- month 7) (+ month 5))))
303 (if (< 10 month) (- month 10) (+ month 2)) 284 (let ((m1 displayed-month)
304 (if (< 9 month) (- month 9) (+ month 3)) 285 (y1 displayed-year)
305 (if (< 8 month) (- month 8) (+ month 4)) 286 (m2 displayed-month)
306 (if (< 7 month) (- month 7) (+ month 5)))) 287 (y2 displayed-year)
307 (let ((m1 displayed-month) 288 (year))
308 (y1 displayed-year) 289 (increment-calendar-month m1 y1 -1)
309 (m2 displayed-month) 290 (increment-calendar-month m2 y2 1)
310 (y2 displayed-year) 291 (let* ((start-date (calendar-absolute-from-gregorian
311 (year)) 292 (list m1 1 y1)))
312 (increment-calendar-month m1 y1 -1) 293 (end-date (calendar-absolute-from-gregorian
313 (increment-calendar-month m2 y2 1) 294 (list m2 (calendar-last-day-of-month m2 y2) y2)))
314 (let* ((start-date (calendar-absolute-from-gregorian 295 (hebrew-start (calendar-hebrew-from-absolute start-date))
315 (list m1 1 y1))) 296 (hebrew-end (calendar-hebrew-from-absolute end-date))
316 (end-date (calendar-absolute-from-gregorian 297 (hebrew-y1 (extract-calendar-year hebrew-start))
317 (list m2 (calendar-last-day-of-month m2 y2) y2))) 298 (hebrew-y2 (extract-calendar-year hebrew-end)))
318 (hebrew-start (calendar-hebrew-from-absolute start-date)) 299 (setq year (if (< 6 month) hebrew-y2 hebrew-y1))
319 (hebrew-end (calendar-hebrew-from-absolute end-date)) 300 (let ((date (calendar-gregorian-from-absolute
320 (hebrew-y1 (extract-calendar-year hebrew-start)) 301 (calendar-absolute-from-hebrew
321 (hebrew-y2 (extract-calendar-year hebrew-end))) 302 (list month day year)))))
322 (setq year (if (< 6 month) hebrew-y2 hebrew-y1)) 303 (if (calendar-date-is-visible-p date)
323 (let ((date (calendar-gregorian-from-absolute 304 (list (list date string))))))))
324 (calendar-absolute-from-hebrew 305
325 (list month day year))))) 306(defun holiday-sexp (sexp string)
326 (if (calendar-date-is-visible-p date)
327 (list (list date string)))))))))
328
329(defun calendar-holiday-function-if (x)
330 "Conditional holiday for dates in the calendar window.
331The boolean condition is (car X). If t, the holiday (car (cdr X)) is
332checked. If nil, the holiday (car (cdr (cdr X))), if there, is checked."
333 (let* ((boolean (eval (car x)))
334 (h (if boolean (car (cdr x)) (car (cdr (cdr x))))))
335 (if h
336 (let* ((function-name
337 (intern (format "calendar-holiday-function-%s" (car h))))
338 (holidays
339 (if (cdr h);; optional arguments
340 (funcall function-name (cdr h))
341 (funcall function-name))))
342 holidays))))
343
344(defun calendar-holiday-function-sexp (x)
345 "Sexp holiday for dates in the calendar window. 307 "Sexp holiday for dates in the calendar window.
346The sexp (in `year') is (car X). If the sexp evals to a date visible in the 308SEXP is an expression in variable `year' evaluates to `date'.
347calendar window, the holiday (car (cdr X)) is on that date. If the sexp evals 309
348to nil, or if the date is not visible, there is no holiday." 310STRING is an expression in `date' that evaluates to the holiday description
311of `date'.
312
313If `date' is visible in the calendar window, the holiday STRING is on that
314date. If date is nil, or if the date is not visible, there is no holiday."
349 (let ((m displayed-month) 315 (let ((m displayed-month)
350 (y displayed-year)) 316 (y displayed-year))
351 (increment-calendar-month m y -1) 317 (increment-calendar-month m y -1)
352 (filter-visible-calendar-holidays 318 (filter-visible-calendar-holidays
353 (append 319 (append
354 (let ((year y)) 320 (let* ((year y)
355 (list (list (eval (car x)) (eval (car (cdr x)))))) 321 (date (eval sexp))
356 (let ((year (1+ y))) 322 (string (if date (eval string))))
357 (list (list (eval (car x)) (eval (car (cdr x)))))))))) 323 (list (list date string)))
358 324 (let* ((year (1+ y))
359(defun calendar-holiday-function-advent () 325 (date (eval sexp))
326 (string (if date (eval string))))
327 (list (list date string)))))))
328
329(defun holiday-advent ()
360 "Date of Advent, if visible in calendar window." 330 "Date of Advent, if visible in calendar window."
361 (let ((year displayed-year) 331 (let ((year displayed-year)
362 (month displayed-month)) 332 (month displayed-month))
@@ -368,7 +338,7 @@ to nil, or if the date is not visible, there is no holiday."
368 (if (calendar-date-is-visible-p advent) 338 (if (calendar-date-is-visible-p advent)
369 (list (list advent "Advent")))))) 339 (list (list advent "Advent"))))))
370 340
371(defun calendar-holiday-function-easter-etc () 341(defun holiday-easter-etc ()
372 "List of dates related to Easter, as visible in calendar window." 342 "List of dates related to Easter, as visible in calendar window."
373 (if (and (> displayed-month 5) (not all-christian-calendar-holidays)) 343 (if (and (> displayed-month 5) (not all-christian-calendar-holidays))
374 nil;; Ash Wednesday, Good Friday, and Easter are not visible. 344 nil;; Ash Wednesday, Good Friday, and Easter are not visible.
@@ -437,9 +407,8 @@ to nil, or if the date is not visible, there is no holiday."
437 output-list))) 407 output-list)))
438 output-list))) 408 output-list)))
439 409
440(defun calendar-holiday-function-greek-orthodox-easter () 410(defun holiday-greek-orthodox-easter ()
441 "Date of Easter according to the rule of the Council of Nicaea, if visible 411 "Date of Easter according to the rule of the Council of Nicaea."
442in the calendar window."
443 (let ((m displayed-month) 412 (let ((m displayed-month)
444 (y displayed-year)) 413 (y displayed-year))
445 (increment-calendar-month m y 1) 414 (increment-calendar-month m y 1)
@@ -461,7 +430,7 @@ in the calendar window."
461 (if (calendar-date-is-visible-p nicaean-easter) 430 (if (calendar-date-is-visible-p nicaean-easter)
462 (list (list nicaean-easter "Pascha (Greek Orthodox Easter)")))))) 431 (list (list nicaean-easter "Pascha (Greek Orthodox Easter)"))))))
463 432
464(defun calendar-holiday-function-rosh-hashanah-etc () 433(defun holiday-rosh-hashanah-etc ()
465 "List of dates related to Rosh Hashanah, as visible in calendar window." 434 "List of dates related to Rosh Hashanah, as visible in calendar window."
466 (if (or (< displayed-month 8) 435 (if (or (< displayed-month 8)
467 (> displayed-month 11)) 436 (> displayed-month 11))
@@ -520,7 +489,7 @@ in the calendar window."
520 output-list))) 489 output-list)))
521 output-list))) 490 output-list)))
522 491
523(defun calendar-holiday-function-hanukkah () 492(defun holiday-hanukkah ()
524 "List of dates related to Hanukkah, as visible in calendar window." 493 "List of dates related to Hanukkah, as visible in calendar window."
525 (if (memq displayed-month;; This test is only to speed things up a bit; 494 (if (memq displayed-month;; This test is only to speed things up a bit;
526 '(10 11 12 1 2));; it works fine without the test too. 495 '(10 11 12 1 2));; it works fine without the test too.
@@ -553,7 +522,7 @@ in the calendar window."
553 (list (calendar-gregorian-from-absolute (+ abs-h 7)) 522 (list (calendar-gregorian-from-absolute (+ abs-h 7))
554 "Hanukkah (eighth day)"))))))) 523 "Hanukkah (eighth day)")))))))
555 524
556(defun calendar-holiday-function-passover-etc () 525(defun holiday-passover-etc ()
557 "List of dates related to Passover, as visible in calendar window." 526 "List of dates related to Passover, as visible in calendar window."
558 (if (< 7 displayed-month) 527 (if (< 7 displayed-month)
559 nil;; None of the dates is visible 528 nil;; None of the dates is visible
@@ -634,7 +603,7 @@ in the calendar window."
634 output-list))) 603 output-list)))
635 output-list))) 604 output-list)))
636 605
637(defun calendar-holiday-function-tisha-b-av-etc () 606(defun holiday-tisha-b-av-etc ()
638 "List of dates around Tisha B'Av, as visible in calendar window." 607 "List of dates around Tisha B'Av, as visible in calendar window."
639 (if (or (< displayed-month 5) 608 (if (or (< displayed-month 5)
640 (> displayed-month 9)) 609 (> displayed-month 9))