aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Morris2008-04-01 02:47:40 +0000
committerGlenn Morris2008-04-01 02:47:40 +0000
commitd600b86560dcd44fb6708fd0f5350d65a364fcb0 (patch)
tree8f968f3b60afd64f8213c07e35fecb37222ac9c2
parentbf276a50b36e858057a72633f194b0024d3f186b (diff)
downloademacs-d600b86560dcd44fb6708fd0f5350d65a364fcb0.tar.gz
emacs-d600b86560dcd44fb6708fd0f5350d65a364fcb0.zip
(Commentary): Point to calendar.el.
(calendar-holiday-list, holiday-easter-etc): Simplify by using mapcar. (calendar-list-holidays): Return holiday-list. (list-holidays): Use let rather than let*. Remove un-needed locals `d', `never'. (calendar-check-holidays): Return result from dolist. (holiday-float): Use a single let*. Simplify if-and to and. (holiday-sexp, holiday-advent, holiday-greek-orthodox-easter): Use a single let*.
-rw-r--r--lisp/calendar/holidays.el294
1 files changed, 134 insertions, 160 deletions
diff --git a/lisp/calendar/holidays.el b/lisp/calendar/holidays.el
index 7c50af09f0e..8404f604abc 100644
--- a/lisp/calendar/holidays.el
+++ b/lisp/calendar/holidays.el
@@ -26,24 +26,7 @@
26 26
27;;; Commentary: 27;;; Commentary:
28 28
29;; This collection of functions implements the holiday features as described 29;; See calendar.el.
30;; in calendar.el.
31
32;; Technical details of all the calendrical calculations can be found in
33;; ``Calendrical Calculations: The Millennium Edition'' by Edward M. Reingold
34;; and Nachum Dershowitz, Cambridge University Press (2001).
35
36;; An earlier version of the technical details appeared in
37;; ``Calendrical Calculations'' by Nachum Dershowitz and Edward M. Reingold,
38;; Software--Practice and Experience, Volume 20, Number 9 (September, 1990),
39;; pages 899-928. ``Calendrical Calculations, Part II: Three Historical
40;; Calendars'' by E. M. Reingold, N. Dershowitz, and S. M. Clamen,
41;; Software--Practice and Experience, Volume 23, Number 4 (April, 1993),
42;; pages 383-404.
43
44;; Hard copies of these two papers can be obtained by sending email to
45;; reingold@cs.uiuc.edu with the SUBJECT "send-paper-cal" (no quotes) and
46;; the message BODY containing your mailing address (snail).
47 30
48;;; Code: 31;;; Code:
49 32
@@ -56,20 +39,19 @@
56(defun calendar-holiday-list () 39(defun calendar-holiday-list ()
57 "Form the list of holidays that occur on dates in the calendar window. 40 "Form the list of holidays that occur on dates in the calendar window.
58The holidays are those in the list `calendar-holidays'." 41The holidays are those in the list `calendar-holidays'."
59 (let (holiday-list) 42 (sort (delq nil
60 (dolist (p calendar-holidays) 43 (mapcar (lambda (p)
61 (let* ((holidays 44 (car
62 (if calendar-debug-sexp 45 (if calendar-debug-sexp
63 (let ((stack-trace-on-error t)) 46 (let ((stack-trace-on-error t))
64 (eval p)) 47 (eval p))
65 (condition-case nil 48 (condition-case nil
66 (eval p) 49 (eval p)
67 (error (beep) 50 (error (beep)
68 (message "Bad holiday list item: %s" p) 51 (message "Bad holiday list item: %s" p)
69 (sleep-for 2)))))) 52 (sleep-for 2))))))
70 (if holidays 53 calendar-holidays))
71 (setq holiday-list (append holidays holiday-list))))) 54 'calendar-date-compare))
72 (setq holiday-list (sort holiday-list 'calendar-date-compare))))
73 55
74(defvar displayed-month) ; from generate-calendar 56(defvar displayed-month) ; from generate-calendar
75(defvar displayed-year) 57(defvar displayed-year)
@@ -77,8 +59,8 @@ The holidays are those in the list `calendar-holidays'."
77;;;###cal-autoload 59;;;###cal-autoload
78(defun calendar-list-holidays () 60(defun calendar-list-holidays ()
79 "Create a buffer containing the holidays for the current calendar window. 61 "Create a buffer containing the holidays for the current calendar window.
80The holidays are those in the list `calendar-notable-days'. Returns t if any 62The holidays are those in the list `calendar-notable-days'.
81holidays are found, otherwise nil." 63Returns non-nil if any holidays are found."
82 (interactive) 64 (interactive)
83 (message "Looking up holidays...") 65 (message "Looking up holidays...")
84 (let ((holiday-list (calendar-holiday-list)) 66 (let ((holiday-list (calendar-holiday-list))
@@ -87,9 +69,7 @@ holidays are found, otherwise nil."
87 (m2 displayed-month) 69 (m2 displayed-month)
88 (y2 displayed-year)) 70 (y2 displayed-year))
89 (if (not holiday-list) 71 (if (not holiday-list)
90 (progn 72 (message "Looking up holidays...none found")
91 (message "Looking up holidays...none found")
92 nil)
93 (calendar-in-read-only-buffer holiday-buffer 73 (calendar-in-read-only-buffer holiday-buffer
94 (increment-calendar-month m1 y1 -1) 74 (increment-calendar-month m1 y1 -1)
95 (increment-calendar-month m2 y2 1) 75 (increment-calendar-month m2 y2 1)
@@ -104,8 +84,8 @@ holidays are found, otherwise nil."
104 (lambda (x) (concat (calendar-date-string (car x)) 84 (lambda (x) (concat (calendar-date-string (car x))
105 ": " (cadr x))) 85 ": " (cadr x)))
106 holiday-list "\n"))) 86 holiday-list "\n")))
107 (message "Looking up holidays...done") 87 (message "Looking up holidays...done"))
108 t))) 88 holiday-list))
109 89
110(define-obsolete-function-alias 90(define-obsolete-function-alias
111 'list-calendar-holidays 'calendar-list-holidays "23.1") 91 'list-calendar-holidays 'calendar-list-holidays "23.1")
@@ -186,20 +166,17 @@ The optional LABEL is used to label the buffer created."
186 (list start-year end-year which name))) 166 (list start-year end-year which name)))
187 (unless y2 (setq y2 y1)) 167 (unless y2 (setq y2 y1))
188 (message "Computing holidays...") 168 (message "Computing holidays...")
189 (let* ((calendar-holidays (or l calendar-holidays)) 169 (let ((calendar-holidays (or l calendar-holidays))
190 (title (or label "Holidays")) 170 (title (or label "Holidays"))
191 (holiday-list nil) 171 (s (calendar-absolute-from-gregorian (list 2 1 y1)))
192 (s (calendar-absolute-from-gregorian (list 2 1 y1))) 172 (e (calendar-absolute-from-gregorian (list 11 1 y2)))
193 (e (calendar-absolute-from-gregorian (list 11 1 y2))) 173 (displayed-month 2)
194 (d s) 174 (displayed-year y1)
195 (never t) 175 holiday-list)
196 (displayed-month 2) 176 (while (<= s e)
197 (displayed-year y1)) 177 (setq holiday-list (append holiday-list (calendar-holiday-list)))
198 (while (or never (<= d e))
199 (setq holiday-list (append holiday-list (calendar-holiday-list))
200 never nil)
201 (increment-calendar-month displayed-month displayed-year 3) 178 (increment-calendar-month displayed-month displayed-year 3)
202 (setq d (calendar-absolute-from-gregorian 179 (setq s (calendar-absolute-from-gregorian
203 (list displayed-month 1 displayed-year)))) 180 (list displayed-month 1 displayed-year))))
204 (save-excursion 181 (save-excursion
205 (calendar-in-read-only-buffer holiday-buffer 182 (calendar-in-read-only-buffer holiday-buffer
@@ -224,11 +201,10 @@ The value returned is a list of strings of relevant holiday descriptions.
224The holidays are those in the list `calendar-holidays'." 201The holidays are those in the list `calendar-holidays'."
225 (let ((displayed-month (extract-calendar-month date)) 202 (let ((displayed-month (extract-calendar-month date))
226 (displayed-year (extract-calendar-year date)) 203 (displayed-year (extract-calendar-year date))
227 (holiday-list)) 204 holiday-list)
228 (dolist (h (calendar-holiday-list)) 205 (dolist (h (calendar-holiday-list) holiday-list)
229 (if (calendar-date-equal date (car h)) 206 (if (calendar-date-equal date (car h))
230 (setq holiday-list (append holiday-list (cdr h))))) 207 (setq holiday-list (append holiday-list (cdr h)))))))
231 holiday-list))
232 208
233(define-obsolete-function-alias 209(define-obsolete-function-alias
234 'check-calendar-holidays 'calendar-check-holidays "23.1") 210 'check-calendar-holidays 'calendar-check-holidays "23.1")
@@ -304,48 +280,47 @@ If N<0, count backward from the end of MONTH.
304An optional parameter DAY means the Nth DAYNAME on or after/before MONTH DAY. 280An optional parameter DAY means the Nth DAYNAME on or after/before MONTH DAY.
305 281
306Returns nil if it is not visible in the current calendar window." 282Returns nil if it is not visible in the current calendar window."
307 ;; This is messy because the holiday may be visible, while the date on which 283 ;; This is messy because the holiday may be visible, while the date
308 ;; it is based is not. For example, the first Monday after December 30 may be 284 ;; on which it is based is not. For example, the first Monday after
309 ;; visible when January is not. For large values of |n| the problem is more 285 ;; December 30 may be visible when January is not. For large values
310 ;; grotesque. If we didn't have to worry about such cases, we could just use 286 ;; of |n| the problem is more grotesque. If we didn't have to worry
311 287 ;; about such cases, we could just use the original version of this
288 ;; function:
312 ;; (let ((m displayed-month) 289 ;; (let ((m displayed-month)
313 ;; (y displayed-year)) 290 ;; (y displayed-year))
314 ;; (increment-calendar-month m y (- 11 month)) 291 ;; (increment-calendar-month m y (- 11 month))
315 ;; (if (> m 9); month in year y is visible 292 ;; (if (> m 9); month in year y is visible
316 ;; (list (list (calendar-nth-named-day n dayname month y day) string))))) 293 ;; (list (list (calendar-nth-named-day n dayname month y day) string)))))
317
318 ;; which is the way the function was originally written.
319
320 (let* ((m1 displayed-month) 294 (let* ((m1 displayed-month)
321 (y1 displayed-year) 295 (y1 displayed-year)
322 (m2 m1) 296 (m2 displayed-month)
323 (y2 y1)) 297 (y2 displayed-year)
324 (increment-calendar-month m1 y1 -1) 298 (d1 (progn ; first possible base date for holiday
325 (increment-calendar-month m2 y2 1) 299 (increment-calendar-month m1 y1 -1)
326 (let* ((d1 ; first possible base date for holiday 300 (+ (calendar-nth-named-absday 1 dayname m1 y1)
327 (+ (calendar-nth-named-absday 1 dayname m1 y1) 301 (* -7 n)
328 (* -7 n) 302 (if (> n 0) 1 -7))))
329 (if (> n 0) 1 -7))) 303 (d2 ; last possible base date for holiday
330 (d2 ; last possible base date for holiday 304 (progn
305 (increment-calendar-month m2 y2 1)
331 (+ (calendar-nth-named-absday -1 dayname m2 y2) 306 (+ (calendar-nth-named-absday -1 dayname m2 y2)
332 (* -7 n) 307 (* -7 n)
333 (if (> n 0) 7 -1))) 308 (if (> n 0) 7 -1))))
334 (y1 (extract-calendar-year (calendar-gregorian-from-absolute d1))) 309 (y1 (extract-calendar-year (calendar-gregorian-from-absolute d1)))
335 (y2 (extract-calendar-year (calendar-gregorian-from-absolute d2))) 310 (y2 (extract-calendar-year (calendar-gregorian-from-absolute d2)))
336 (y ; year of base date 311 (y ; year of base date
337 (if (or (= y1 y2) (> month 9)) 312 (if (or (= y1 y2) (> month 9))
338 y1 313 y1
339 y2)) 314 y2))
340 (d ; day of base date 315 (d ; day of base date
341 (or day (if (> n 0) 316 (or day (if (> n 0)
342 1 317 1
343 (calendar-last-day-of-month month y)))) 318 (calendar-last-day-of-month month y))))
344 (date ; base date for holiday 319 (date ; base date for holiday
345 (calendar-absolute-from-gregorian (list month d y)))) 320 (calendar-absolute-from-gregorian (list month d y))))
346 (if (and (<= d1 date) (<= date d2)) 321 (and (<= d1 date) (<= date d2)
347 (list (list (calendar-nth-named-day n dayname month y d) 322 (list (list (calendar-nth-named-day n dayname month y d)
348 string)))))) 323 string)))))
349 324
350(defun holiday-filter-visible-calendar (l) 325(defun holiday-filter-visible-calendar (l)
351 "Return a list of all visible holidays of those on L." 326 "Return a list of all visible holidays of those on L."
@@ -360,26 +335,26 @@ Returns nil if it is not visible in the current calendar window."
360 335
361(defun holiday-sexp (sexp string) 336(defun holiday-sexp (sexp string)
362 "Sexp holiday for dates in the calendar window. 337 "Sexp holiday for dates in the calendar window.
363SEXP is an expression in variable `year' evaluates to `date'. 338SEXP is an expression in variable `year' that is evaluated to
364 339give `date'. STRING is an expression in `date' that evaluates to
365STRING is an expression in `date' that evaluates to the holiday description 340the holiday description of `date'. If `date' is visible in the
366of `date'. 341calendar window, the holiday STRING is on that date. If date is
367 342nil, or if the date is not visible, there is no holiday."
368If `date' is visible in the calendar window, the holiday STRING is on that
369date. If date is nil, or if the date is not visible, there is no holiday."
370 (let ((m displayed-month) 343 (let ((m displayed-month)
371 (y displayed-year)) 344 (y displayed-year)
345 year date)
372 (increment-calendar-month m y -1) 346 (increment-calendar-month m y -1)
373 (holiday-filter-visible-calendar 347 (holiday-filter-visible-calendar
374 (list 348 (list
375 (let* ((year y) 349 (progn
376 (date (eval sexp)) 350 (setq year y
377 (string (if date (eval string)))) 351 date (eval sexp))
378 (list date string)) 352 (list date (if date (eval string))))
379 (let* ((year (1+ y)) 353 (progn
380 (date (eval sexp)) 354 (setq year (1+ y)
381 (string (if date (eval string)))) 355 date (eval sexp))
382 (list date string)))))) 356 (list date (if date (eval string))))))))
357
383 358
384(defun holiday-advent (&optional n string) 359(defun holiday-advent (&optional n string)
385 "Date of Nth day after advent (named STRING), if visible in calendar window. 360 "Date of Nth day after advent (named STRING), if visible in calendar window.
@@ -393,17 +368,18 @@ arguments, then it returns the value appropriate for advent itself."
393 ;; Backwards compatibility layer. 368 ;; Backwards compatibility layer.
394 (if (not n) 369 (if (not n)
395 (holiday-advent 0 "Advent") 370 (holiday-advent 0 "Advent")
396 (let ((year displayed-year) 371 (let* ((year displayed-year)
397 (month displayed-month)) 372 (month displayed-month)
398 (increment-calendar-month month year -1) 373 (advent (progn
399 (let ((advent (calendar-gregorian-from-absolute 374 (increment-calendar-month month year -1)
400 (+ n 375 (calendar-gregorian-from-absolute
401 (calendar-dayname-on-or-before 376 (+ n
402 0 377 (calendar-dayname-on-or-before
403 (calendar-absolute-from-gregorian 378 0
404 (list 12 3 year))))))) 379 (calendar-absolute-from-gregorian
405 (if (calendar-date-is-visible-p advent) 380 (list 12 3 year))))))))
406 (list (list advent string))))))) 381 (if (calendar-date-is-visible-p advent)
382 (list (list advent string))))))
407 383
408(defun holiday-easter-etc (&optional n string) 384(defun holiday-easter-etc (&optional n string)
409 "Date of Nth day after Easter (named STRING), if visible in calendar window. 385 "Date of Nth day after Easter (named STRING), if visible in calendar window.
@@ -418,30 +394,28 @@ holidays (with more entries if `all-christian-calendar-holidays'
418is non-nil)." 394is non-nil)."
419 ;; Backwards compatibility layer. 395 ;; Backwards compatibility layer.
420 (if (not n) 396 (if (not n)
421 (let (res-list res) 397 (delq nil ; filter out nil (not visible) dates
422 (dolist (elem (append 398 (mapcar (lambda (e)
423 (if all-christian-calendar-holidays 399 (apply 'holiday-easter-etc e))
424 '((-63 . "Septuagesima Sunday") 400 (append
425 (-56 . "Sexagesima Sunday") 401 (if all-christian-calendar-holidays
426 (-49 . "Shrove Sunday") 402 '((-63 "Septuagesima Sunday")
427 (-48 . "Shrove Monday") 403 (-56 "Sexagesima Sunday")
428 (-47 . "Shrove Tuesday") 404 (-49 "Shrove Sunday")
429 (-14 . "Passion Sunday") 405 (-48 "Shrove Monday")
430 (-7 . "Palm Sunday") 406 (-47 "Shrove Tuesday")
431 (-3 . "Maundy Thursday") 407 (-14 "Passion Sunday")
432 (35 . "Rogation Sunday") 408 (-7 "Palm Sunday")
433 (39 . "Ascension Day") 409 (-3 "Maundy Thursday")
434 (49 . "Pentecost (Whitsunday)") 410 (35 "Rogation Sunday")
435 (50 . "Whitmonday") 411 (39 "Ascension Day")
436 (56 . "Trinity Sunday") 412 (49 "Pentecost (Whitsunday)")
437 (60 . "Corpus Christi"))) 413 (50 "Whitmonday")
438 '((0 . "Easter Sunday") 414 (56 "Trinity Sunday")
439 (-2 . "Good Friday") 415 (60 "Corpus Christi")))
440 (-46 . "Ash Wednesday"))) 416 '((0 "Easter Sunday")
441 res-list) 417 (-2 "Good Friday")
442 ;; Filter out nil (not visible) values. 418 (-46 "Ash Wednesday")))))
443 (if (setq res (holiday-easter-etc (car elem) (cdr elem)))
444 (setq res-list (append res res-list)))))
445 (let* ((century (1+ (/ displayed-year 100))) 419 (let* ((century (1+ (/ displayed-year 100)))
446 (shifted-epact ; age of moon for April 5... 420 (shifted-epact ; age of moon for April 5...
447 (% (+ 14 (* 11 (% displayed-year 19)) ; ...by Nicaean rule 421 (% (+ 14 (* 11 (% displayed-year 19)) ; ...by Nicaean rule
@@ -469,26 +443,26 @@ is non-nil)."
469 443
470(defun holiday-greek-orthodox-easter () 444(defun holiday-greek-orthodox-easter ()
471 "Date of Easter according to the rule of the Council of Nicaea." 445 "Date of Easter according to the rule of the Council of Nicaea."
472 (let ((m displayed-month) 446 (let* ((m displayed-month)
473 (y displayed-year)) 447 (y displayed-year)
474 (increment-calendar-month m y 1) 448 (julian-year (progn
475 (let* ((julian-year 449 (increment-calendar-month m y 1)
476 (extract-calendar-year 450 (extract-calendar-year
477 (calendar-julian-from-absolute 451 (calendar-julian-from-absolute
478 (calendar-absolute-from-gregorian 452 (calendar-absolute-from-gregorian
479 (list m (calendar-last-day-of-month m y) y))))) 453 (list m (calendar-last-day-of-month m y) y))))))
480 (shifted-epact ; age of moon for April 5 454 (shifted-epact ; age of moon for April 5
481 (% (+ 14 455 (% (+ 14
482 (* 11 (% julian-year 19))) 456 (* 11 (% julian-year 19)))
483 30)) 457 30))
484 (paschal-moon ; day after full moon on or after March 21 458 (paschal-moon ; day after full moon on or after March 21
485 (- (calendar-absolute-from-julian (list 4 19 julian-year)) 459 (- (calendar-absolute-from-julian (list 4 19 julian-year))
486 shifted-epact)) 460 shifted-epact))
487 (nicaean-easter ; Sunday following the Paschal moon 461 (nicaean-easter ; Sunday following the Paschal moon
488 (calendar-gregorian-from-absolute 462 (calendar-gregorian-from-absolute
489 (calendar-dayname-on-or-before 0 (+ paschal-moon 7))))) 463 (calendar-dayname-on-or-before 0 (+ paschal-moon 7)))))
490 (if (calendar-date-is-visible-p nicaean-easter) 464 (if (calendar-date-is-visible-p nicaean-easter)
491 (list (list nicaean-easter "Pascha (Greek Orthodox Easter)")))))) 465 (list (list nicaean-easter "Pascha (Greek Orthodox Easter)")))))
492 466
493(provide 'holidays) 467(provide 'holidays)
494 468