[PATCH] More calendar synces with Emacs CVS

Jeff Miller jmiller at cablespeed.com
Fri Oct 20 17:49:04 EDT 2006


 I plan to commit the following in a day or so. 


ChangeLog addition:

2006-10-20  Jeff Miller  <jeff.miller at xemacs.org>

	More Emacs CVS syncs, from the Emacs Changelog:
	
	* calendar/diary-lib.el (diary-bahai-date)
	(list-bahai-diary-entries, mark-bahai-diary-entries)
	(mark-bahai-calendar-date-pattern): Not interactive.
	(add-to-diary-list): New optional arg LITERAL.  Doc fix.
	(diary-entries-list): Change format of 4th element in each entry.
	(diary-list-entries): Use add-to-diary-list.
	(diary-goto-entry): Handle the case where the buffer visiting the
	diary has been killed.
	(fancy-diary-display): Add 'locator to button rather than 'marker.
	Only generate temp-face when there are marks to apply.
	(list-sexp-diary-entries): Pass literal to add-to-diary-list.
	(diary-fancy-date-pattern): New variable.
	(diary-time-regexp): Doc fix.
	(diary-anniversary, diary-time): New faces.
	(fancy-diary-font-lock-keywords): Use diary-fancy-date-pattern and
	diary-time-regexp.  Add font-lock-multiline property where needed.
	Use new faces diary-anniversary and diary-time.
	(diary-fancy-font-lock-fontify-region-function): New function, to
	handle multiline font-lock pattern in fancy diary.
	(fancy-diary-display-mode): Set font-lock-fontify-region-function.
	(diary-font-lock-keywords): Tweak time regexp.  Use new face
	diary-time.

	* calendar/cal-menu.el (calendar-mode-map, calendar-mouse-3-map):
	* calendar/calendar.el (calendar-mode-map):
	* calendar/diary-lib.el (include-other-diary-files,diary-mail-entries):
	* calendar/appt.el (appt-check, appt-make-list): Refer to
	diary-view-entries, diary-list-entries, diary-show-all-entries
	rather than obsolete aliases.

	* calendar/calendar.el (diary-show-all-entries): Do not refer to
	obsolete alias `show-all-diary-entries'.
	(make-diary-entry): Not interactive.
	(cal-tex-cursor-month, cal-tex-cursor-month-landscape)
	(cal-tex-cursor-day, cal-tex-cursor-week, cal-tex-cursor-week2)
	(cal-tex-cursor-week-iso, cal-tex-cursor-week-monday)
	(cal-tex-cursor-filofax-2week, cal-tex-cursor-filofax-week)
	(cal-tex-cursor-year-landscape, cal-tex-cursor-filofax-year)
	(cal-tex-cursor-filofax-daily, cal-tex-cursor-year): Interactive.

	* calendar/calendar.el (calendar-french-date-string)
	(calendar-mayan-date-string, calendar-chinese-date-string)
	(calendar-astro-date-string, calendar-iso-date-string)
	(calendar-islamic-date-string, calendar-bahai-date-string)
	(calendar-hebrew-date-string, calendar-coptic-date-string)
	(calendar-ethiopic-date-string, calendar-persian-date-string):
	These functions are not interactive.

	* calendar/calendar.el (calendar-basic-setup): Set day to 1 in
	prefix arg case, to avoid view-diary-entries-initially error.
	Reported by Stephen Berman <Stephen.Berman at gmx.net>.
	(calendar-date-is-legal-p): Handle dates with no day part.

	* calendar/cal-menu.el (calendar-mode-map): Refer to
	`diary-view-entries' rather than alias `view-diary-entries'.
	* calendar/diary-lib.el (view-other-diary-entries): Ditto.

	* calendar/appt.el (appt-add): Check whether an appointment is
	already present in appt-time-msg-list.  Simplify code.

	* calendar/calendar.el (calendar-holidays): Doc fix.
	* calendar/holidays.el (list-holidays): Doc fix.

	* calendar/calendar.el (calendar-holidays): Doc fix.

	* calendar/appt.el (diary-selective-display): Add defvar.

	* calendar/icalendar.el (icalendar--get-event-property)
	(icalendar--get-event-property-attributes): Fix typos in
	docstrings.

	* calendar/cal-menu.el: Avoid macros from calendar.el so as to break
	the nastiest part of the cyclic dependency.
	(cal-menu-update): Use dotimes and calendar-increment-month.

	* calendar/calendar.el: Remove unnecessary leading stars in docstrings.
	(calendar-week-start-day): Add an :initializer.
	(calendar-mode-map): Use suppress-keymap, and command remapping.
	(describe-calendar-mode): Setup xref-stack info for the back button.
	(calendar-star-date): Insert before delete.
	(calendar-set-mode-line): Add file-modified info if applicable.
	(calendar-increment-month): New function.


	* calendar/diary-lib.el (diary-list-entries): Also hide the
	terminating newline.

	* calendar/diary-lib.el (diary-list-entries, diary-show-all-entries)
	(mark-diary-entries, make-diary-entry): Check default-major-mode rather
	than fundamental-mode to see if the mode was set.

	* calendar/cal-menu.el (date, event): Don't declare as dynamic-var.
	(calendar-mouse-holidays, calendar-mouse-view-diary-entries)
	(calendar-mouse-print-dates): Add optional `event' argument.
	Update interactive-spec.
	(calendar-mouse-cal-tex-menu, cal-tex-mouse-filofax):
	Use `calendar-event-to-date' instead of `event'.

	* calendar/diary-lib.el (diary-list-entries): Prevent infloop when
	diary does not end in a newline.  Do not assume a blank line at
	the start of the diary file.

	* calendar/icalendar.el (icalendar-version): Increase to 0.13.
	Now a string.
	(icalendar-import-format): Handle CLASS, STATUS, URL.
	Rename `subject' to `summary'.
	(icalendar-import-format-summary): Rename from
	`icalendar-import-format-subject'.
	(icalendar-import-format-url, icalendar-import-format-status)
	(icalendar-import-format-class): New variables.
	(icalendar--rris): Take variable argument list.
	(icalendar--datestring-to-isodate): Remove unnecessary
	calendar-style check when converting dates with explicit month names.
	(icalendar-export-region): Change return type of conversion
	subroutines.  Bury current buffer unless error occurred.
	(icalendar--convert-to-ical)
	(icalendar--parse-summary-and-rest): New functions.
	(icalendar--convert-ordinary-to-ical)
	(icalendar--convert-weekly-to-ical)
	(icalendar--convert-yearly-to-ical)
	(icalendar--convert-block-to-ical)
	(icalendar--convert-cyclic-to-ical)
	(icalendar--convert-anniversary-to-ical): Change return type.
	Strip trailing blanks from subject.
	(icalendar--convert-sexp-to-ical): Change return type.
	Strip trailing blanks from subject.  Handle simple sexp
	entries as generated by icalendar.el.
	(icalendar--convert-float-to-ical)
	(icalendar--convert-date-to-ical): Strip trailing blanks from subject.
	(icalendar-import-file): Doc fix.
	(icalendar--format-ical-event): Handle CLASS, STATUS, URL.
	Correct call to icalendar--rris.
	(icalendar--convert-ical-to-diary): Doc fix.  Rename `subject' to
	`summary'.
	(icalendar--add-diary-entry): Rename `subject' to `summary'.

	* calendar/appt.el (appt-check): Use diary-selective-display var.

	* calendar/cal-menu.el (calendar-mouse-view-diary-entries):
	Use the new `list-only' arg to diary-list-entries.

	* calendar/diary-lib.el: Use overlays rather than selective-display.
	(diary-selective-display): New var.
	(diary-header-line-format): Use it.
	(diary-list-entries): Add argument `list-only'.
	Put the buffer in diary-mode.  Don't add \^M at beg and end.
	Replace \^M by invisible overlays.
	(diary-unhide-everything): Replace \^M by invisible overlays.
	(print-diary-entries): Look for overlays rather than \^M.
	Add a space to the temp buffer name.
	(diary-show-all-entries, mark-diary-entries, make-diary-entry):
	Put the buffer in diary-mode.
	(list-sexp-diary-entries): Replace \^M by invisible overlays.
	(diary-anniversary): Make the year arg optional.
	(diary-time-regexp): New const.
	(diary-font-lock-keywords): Use it to accept a few more time formats.

	* calendar/appt.el (appt-time-regexp): New var.
	(appt-add, appt-make-list): Use it.
	(appt-convert-time): Clean up.

	* calendar/timeclock.el (timeclock-ask-for-project):
	Follow convention for reading with the minibuffer.

	* calendar/calendar.el (mark-visible-calendar-date): Save excursion.
	Re-indent within 80 columns.  Use inhibit-read-only.

	* calendar/diary-lib.el (mark-diary-entries): Rearrange to wrap
	with-current-buffer form in save-excursion.
	* calendar/timeclock.el (timeclock-status-string)
	(timeclock-workday-remaining-string, timeclock-workday-elapsed-string)
	(timeclock-when-to-leave-string):
	* calendar/icalendar.el (icalendar--convert-ical-to-diary):
	Fix `message' calls to ensure first arg is a format string.

	* calendar/cal-bahai.el (date, displayed-month, displayed-year)
	(number, original-date):
	* calendar/cal-china.el (date):
	* calendar/cal-coptic.el (date):
	* calendar/cal-french.el (date):
	* calendar/cal-hebrew.el (date, entry, number, original-date):
	* calendar/cal-islam.el (date, number, original-date):
	* calendar/cal-iso.el (date):
	* calendar/cal-julian.el (date):
	* calendar/cal-mayan.el (date):
	* calendar/cal-menu.el (date, event):
	* calendar/cal-persia.el (date):
	* calendar/lunar.el (date):
	* calendar/solar.el (date): Add defvars.

	* calendar/diary-lib.el (diary-modify-entry-list-string-function):
	New hook.
	(add-to-diary-list): Call `diary-modify-entry-list-string-function'

	* calendar/calendar.el (calendar-mode-map): Bind < and > usefully.

	* calendar/calendar.el (calendar-goto-hebrew-date)
	(calendar-goto-coptic-date, calendar-goto-ethiopic-date)
	(calendar-goto-persian-date):
	Delete duplicate duplicate words.

	* calendar/icalendar.el (icalendar--get-unfolded-buffer):

	* calendar/diary-lib.el (diary-header-line-format):
	Change space constants followed by a sexp to "?\s ".

	* calendar/diary-lib.el (diary-button): Remove "-face" suffix from
	face name.
	(diary-button-face): New backward-compatibility alias for renamed face.
	(diary-entry): Use renamed diary-button face.

	* calendar/calendar.el (diary, calendar-today, holiday)
	(mark-visible-calendar-date): Remove "-face" suffix from face names.
	(diary-face, calendar-today-face, holiday-face):
	New backward-compatibility aliases for renamed faces.
	(eval-after-load "facemenu", diary-entry-marker)
	(calendar-today-marker, calendar-holiday-marker, diary-face):
	Use renamed calendar faces.


	* calendar/diary-lib.el (mark-included-diary-files): Only kill
	included diary buffer if it was not already being visited.
	Reported by Stephen Berman <Stephen.Berman at gmx.net>.

	* calendar/icalendar.el (top-level): Do not require appt.

	* calendar/todo-mode.el (todo-mode):
	Use kill-all-local-variables and run-mode-hooks.

	* calendar/cal-menu.el (cal-menu-update): Add separator as a
	string so that tmm doesn't create a completion entry for it.


	Replace `string-to-int' by `string-to-number'.

	* calendar/appt.el (appt-convert-time):
	* calendar/cal-bahai.el (mark-bahai-diary-entries):
	* calendar/cal-hebrew.el (mark-hebrew-diary-entries):
	* calendar/cal-islam.el (mark-islamic-diary-entries):
	* calendar/calendar.el (calendar-cursor-to-date)
	(calendar-star-date):
	* calendar/diary-lib.el (diary-attrtype-convert)
	(mark-diary-entries, diary-entry-time):
	* calendar/solar.el (solar-get-number):

	* calendar/solar.el (solar-data-list): Move definition up.

	* calendar/cal-bahai.el (mark-bahai-diary-entries):

	* calendar/icalendar.el (icalendar-version): Now at 0.12.
	(icalendar-duration-correction): Remove.
	(icalendar--get-event-properties): Split result at commas.
	(icalendar--decode-isoduration): New optional argument
	DURATION-CORRECTION.
	(icalendar--convert-ordinary-to-ical, icalendar--convert-sexp-to-ical)
	(icalendar--convert-yearly-to-ical, icalendar--convert-weekly-to-ical)
	(icalendar--convert-block-to-ical, icalendar--convert-float-to-ical)
	(icalendar--convert-date-to-ical, icalendar--convert-cyclic-to-ical)
	(icalendar--convert-anniversary-to-ical): New functions, extracted
	from icalendar-export-region, with bug fixes.
	(icalendar-export-region): Use the above functions.
	(icalendar-import-buffer): Check before saving diary file.
	(icalendar--convert-recurring-to-diary)
	(icalendar--convert-non-recurring-all-day-to-diary)
	(icalendar--convert-non-recurring-not-all-day-to-diary): New functions,
	extracted from icalendar--convert-ical-to-diary, with bug fixes.
	(icalendar--convert-ical-to-diary): Use the above functions.
	* calendar/calendar.el (diary-face): Add special case for
	displays supporting a high number of colors.

	* calendar/diary-lib.el (add-to-diary-list): MARKER argument made
	optional, to ensure backward compatibility.

	* calendar/timeclock.el (timeclock): Doc fix.

	* calendar/cal-china.el: Update reference to "Calendrical
	Calculations" book; there's a new edition.
	* calendar/cal-coptic.el: Likewise.
	* calendar/cal-french.el: Likewise.
	* calendar/cal-hebrew.el: Likewise.
	* calendar/cal-islam.el: Likewise.
	* calendar/cal-iso.el: Likewise.
	* calendar/cal-julian.el: Likewise.
	* calendar/cal-mayan.el: Likewise.
	* calendar/cal-persia.el: Likewise.
	* calendar/calendar.el: Likewise.
	* calendar/holidays.el: Likewise.
	* calendar/lunar.el: Likewise.
	* calendar/solar.el: Likewise.

	* calendar/calendar.el (calendar-day-abbrev-array): Remove trailing
	white space from doc string.

	* calendar/cal-x.el (calendar-one-frame-setup)
	(calendar-only-one-frame-setup, calendar-two-frame-setup): Use t
	rather than `symbol' for set-window-dedicated-p.

	* calendar/appt.el (appt-buffer-name): Make it a constant.
	(appt-add): Doc fix.

	* calendar/cal-menu.el (top level): Delete local C-down-mouse-3
	binding.  Suggested by Stephan Stahl <stahl at eos.franken.de>.

	* calendar/cal-move.el (calendar-beginning-of-year): Move the
	cursor to Jan 1 when needed.
	(calendar-end-of-year): Fix -/+ typo.
	Reported by Chong Yidong <cyd at stupidchicken.com>.

	* calendar/calendar.el: Replace `legal' with `valid'.

	* calendar/diary-lib.el (mark-diary-entries): Use new optional
	argument REDRAW rather than calendar-redrawing variable.
	* calendar/calendar.el (calendar-redrawing): Delete.
	(redraw-calendar): Do not bind calendar-redrawing.

	* calendar/diary-lib.el (diary-redraw-calendar): Preserve point in
	diary-file buffer.

	* calendar/calendar.el (calendar-redrawing): New internal
	variable.
	(redraw-calendar): Remove bogus save-excursion from previous
	change.  Bind calendar-redrawing to t for mark-diary-entries.
	* calendar/diary-lib.el (mark-diary-entries): No need to redraw
	calendar if that is why we were called.

	* calendar/calendar.el (redraw-calendar): Preserve point.
	Reported by Matt Hodges <MPHodges at member.fsf.org>.
	(calendar-week-start-day): Move after definition of
	redraw-calendar.  Delete buffer test, since redraw-calendar has
	that now.

	* calendar/diary-lib.el (mark-diary-entries): Only call
	redraw-calendar in the first of any recursive calls.
	Reported by Alan Shutko <ats at acm.org>.

	* calendar/icalendar.el (icalendar-version): Increase to 0.11.
	(icalendar-export-file, icalendar-export-region)
	(icalendar-import-file, icalendar-import-buffer): Add autoload cookies.
	(icalendar--convert-ical-to-diary): Fix problem with DURATION.

	* calendar/calendar.el (redraw-calendar): Work from any buffer,
	not just the calendar.

	* calendar/diary-lib.el (mark-diary-entries): Remove any old marks
	first.
	(diary-redraw-calendar): New function.
	(make-diary-entry): Add diary-redraw-calendar to local
	write-contents-functions.  Turn off selective display before
	inserting in diary.

	* calendar/diary-lib.el (diary-remind): Discard any mark portion
	from diary-entry.  Reported by Andrew Kemp <ajwk at pell.uklinux.net>.

	* calendar/calendar.el (calendar-buffer): Move above
	calendar-week-start-day.
	(calendar-week-start-day): Doc fix.  Add :set function.
	(calendar-minimum-window-height): New variable.
	(generate-calendar-window): Only resize window if selected-window
	is displaying the calendar buffer.  Use new variable
	calendar-minimum-window-height.
	(generate-calendar): Reword error message.
	(calendar-mode-map): Bind DEL to scroll-other-window-down.

	* calendar/icalendar.el (icalendar--decode-isodatetime):
	New optional argument DAY-SHIFT.
	(icalendar-export-region): Fix coding-system-for-write.

	(icalendar--convert-ical-to-diary): Shift end-day of all-day
	events by one.

	* calendar/appt.el (appt-time-msg-list): 3rd elt of each
	appointment says it was explicitly made.
	(appt-add): Set the 3rd element.
	(appt-make-list): Preserve explicit appointments.

	* calendar/icalendar.el (icalendar--get-event-property): Doc fix.
	(icalendar--get-event-property-attributes)
	(icalendar--get-event-properties)
	(icalendar--datetime-to-diary-date): New functions.
	(icalendar--split-value): Doc fix.
	(icalendar--datetime-to-noneuropean-date)
	(icalendar--datetime-to-european-date): New optional argument
	SEPARATOR.  Return result as a string instead of a list.
	(icalendar--get-weekday-number): Check if ABBREVWEEKDAY is nil.
	(icalendar--convert-string-for-export): Rename arg S to STRING.
	(icalendar-export-region): Doc fix.  Change name of error buffer.
	Save output buffer.
	(icalendar-import-file): Add blank at end of prompt.
	(icalendar-import-buffer): Doc fix.  Do not switch to error
	buffer.  Indicate status in return value.
	(icalendar--convert-ical-to-diary): Doc fix.  Change name of error
	buffer.  Save output buffer.  Handle exception from recurrence
	rules (EXDATE, EXRULE).  Handle start- and end-date of recurring
	events.  Fix problems with weekly all-day events.

	* calendar/diary-lib.el (mark-diary-entries):
	Set mark-diary-entries-in-calendar only after checking for diary-file.

	* calendar/calendar.el (view-other-diary-entries): Add autoload.
	* calendar/diary-lib.el (view-other-diary-entries):
	Use current-prefix-arg in interactive spec.

	* calendar/holidays.el (holiday-easter-etc): Make arguments
	optional for backwards compatibility.  Doc fix.
	Remove un-necessary local vars mandatory, output-list.
	(holiday-advent): Make arguments optional for backwards
	compatibility.  Doc fix.

	* calendar/diary-lib.el (diary-from-outlook)
	(diary-from-outlook-gnus, diary-from-outlook-rmail): Do not use
	interactive-p; but rather new optional argument NOCONFIRM.

	* calendar/icalendar.el (icalendar-version): Increase to 0.08.
	(icalendar--split-value): Change name of work buffer.
	(icalendar--get-weekday-abbrev): Return nil on error.
	(icalendar--date-to-isodate): New function.
	(icalendar-convert-diary-to-ical)
	(icalendar-extract-ical-from-buffer): Use only two args for
	make-obsolete (XEmacs compatibility).
	(icalendar-export-file, icalendar-import-file): Blank at end of prompt.
	(icalendar-export-region): Doc fix.
	If error, return non-nil and write errors to a buffer.
	Use correct weekday for weekly recurring events.
	Check whether date has been parsed for ordinary events.
	Make weekly events start in the year 2000.
	DTEND is non-inclusive, shift end date by one day if
	necessary (not for entries that have date and time).
	Rename local let variables: oops -> found-error, datestring ->
	startdatestring.

	* calendar/icalendar.el (icalendar--weekday-array): New constant.
	(icalendar-weekdayabbrev-table)
	(icalendar-monthnumber-table): Delete.
	(icalendar--get-month-number): Use calendar-month-name-array.
	(icalendar--get-weekday-number): New function.
	(icalendar--get-weekday-abbrev) Use calendar-day-name-array.
	(icalendar-export-region): Handle multi-line entries.
	(icalendar--convert-ical-to-diary): Use calendar-day-name-array.

	* calendar/icalendar.el: Set coding to utf-8.
	(icalendar-version): Increase to 0.07.
	(icalendar-monthnumber-table): Change March pattern.
	(icalendar-get-all-event-properties)
	(icalendar-set-event-property): Delete.
	(icalendar-all-events): No longer interactive.
	(icalendar-convert-diary-to-ical)
	(icalendar-extract-ical-from-buffer): Make obsolete, and alias to
	their replacements.
	(icalendar-export-file, icalendar-export-region): New functions;
	essentially old `icalendar-convert-diary-to-ical' but appending to
	target rather than overwriting.
	(icalendar-import-file): Append to target file rather than
	overwriting.  Fourth arg deleted.
	(icalendar-import-buffer): New name for old
	`icalendar-extract-ical-from-buffer'.
	(icalendar--convert-string-for-import): New name for
	old `icalendar-convert-for-import'.
	(include-icalendar-files): Delete.
	Prefix for all internal functions changed from `icalendar-'
	to `icalendar--'.

	* calendar/icalendar.el: New file.

	* calendar/calendar.el (calendar-goto-iso-week): Add autoload.
	(calendar-mode-map): Add binding for `calendar-goto-iso-week'.
	* calendar/cal-menu.el (calendar-mode-map): Ditto.

	* calendar/cal-iso.el (calendar-iso-read-args): New function,
	for old interactive spec from calendar-goto-iso-date.
	(calendar-goto-iso-date): Use it.
	(calendar-goto-iso-week): New function.  Suggested by Emilio
	C. Lopes <eclig at gmx.net>.

	* calendar/diary-lib.el (list-diary-entries): Save diary buffer
	from diary display excursion.  Store diary buffer's point for
	`simple-diary-display'.
	(simple-diary-display): Set window point and start when
	displaying buffer, to preserve point.

	* calendar/holidays.el (holiday-advent): Report on a specified day
	offset from advent, not just advent.
	(holiday-easter-etc): Report on one specified day offset from
	easter, not all easter holidays.  Various Easter holidays moved to
	`christian-holidays' variable in calendar.el.
	* calendar/calendar.el (christian-holidays): Adapt for new
	behavior of `holiday-advent' and `holiday-easter-etc' functions.

	* calendar/cal-dst.el (calendar-time-from-absolute): Return a list
	of two integers, instead of a cons.

	* calendar/appt.el (appt-disp-window):
	Use `calendar-set-mode-line' for a centered mode-line.

	* calendar/appt.el (appt-disp-window): Do not split window
	excessively when `split-height-threshold' is low.

	* calendar/cal-bahai.el: New file, which adds support for the
	Baha'i calendar to Emacs.  This calendar is based on a solar year
	of 19 months of 19 days, with 4 intercalary days.  Each year
	begins on March 21, with the calendar starting in 1844.

	* calendar/cal-menu.el, calendar/calendar.el
	* calendar/diary-lib.el, calendar/holidays.el:
	Added support for using cal-bahai.el.

	* calendar/diary-lib.el (diary-outlook-formats): New variable.
	(diary-from-outlook-internal, diary-from-outlook)
	(diary-from-outlook-gnus, diary-from-outlook-rmail):
	New functions to import diary entries from Outlook-format
	appointments in mail messages.

	Use `time-less-p' from calendar/time-date.el instead of defining
	custom versions of it.

	* calendar/timeclock.el (timeclock-time-less-p): Remove.
	(timeclock-generate-report): Use `time-less-p'.

	* calendar/diary-lib.el (diary-mode, fancy-diary-display-mode):
	Derive from fundamental-mode rather than text-mode.

	* calendar/timeclock.el (timeclock-relative)
	(timeclock-get-project-function, timeclock-get-workday-function)
	(timeclock-query-out, timeclock-when-to-leave)
	(timeclock-when-to-leave-string, timeclock-log-data)
	(timeclock-generate-report, timeclock-in): Doc fixes.

	* calendar/appt.el (appt-check): Remove superfluous progn.
	When finished with diary buffer: if it was not being displayed
	before, kill it; otherwise restore its original state.
	Suggested by Matthew Mundell <matt at mundell.ukfsn.org>.

	* calendar/calendar.el (calendar-set-mode-line): Use total
	available mode-line width, rather than frame-width.

	* calendar/diary-lib.el (fancy-diary-display): Set mode-line
	after mode change so effect not lost.

	* calendar/calendar.el (generate-calendar)
	(calendar-read-date): Prevent display of BC calendars once more -
	reverts 2003-10-01 change.
	(generate-calendar-month): Doc fix.

	* calendar/appt.el (appt-display-format): Change default to
	'ignore, for backwards compatibility.
	(appt-display-message): If appt-display-format is 'ignore,
	respect old vars appt-msg-window and appt-visible.
	(appt-activate): Don't depend on return value of cancel-timer.

	* calendar/calendar.el (calendar-holidays): Doc fix.

	* calendar/appt.el (appt-check): Restore usage of
	appt-issue-message deleted in previous change.
	(top-level): Activate package when loaded (needed for backwards
	compatibility).

	* calendar/diary-lib.el (diary-entry-time): Fix typo/bug:
	Remove spurious left square bracket in XX:XXam regexp.

	* calendar/appt.el: Update copyright and commentary.
	(appt-issue-message): Make obsolete.
	(appt-visible, appt-msg-window): Make obsolete, in favor of
	appt-display-format.
	(appt-display-mode-line, appt-display-duration)
	(appt-display-diary, appt-time-msg-list, appt-mode-string)
	(appt-prev-comp-time, appt-display-count, appt-timer)
	(appt-convert-time): Doc change.
	(appt-disp-window-function, appt-delete-window-function):
	Use defcustom rather than defvar.
	(appt-display-format): New variable.
	(appt-display-message): New function with display code from appt-check.
	(appt-check): Add optional FORCE argument.  Doc change.
	Add appt-make-list to diary-hook if displaying diary.
	Remove checking of view-diary-entries-initially.
	Message display section removed to new function appt-display-message.
	(appt-display-window): Doc change.  Remove unused internal var
	this-buffer.  Do not beep, since appt-display-message does that.
	(appt-make-list): Doc change.  Use caar.
	(appt-sort-list): Simplify by using builtin sort function.
	(appt-update-list): New function for updating appts when diary is
	saved.
	(appt-activate): New autoloaded function to toggle package
	functionality.

	* calendar/cal-x.el: (calendar-one-frame-setup)
	(calendar-only-one-frame-setup, calendar-two-frame-setup): Doc change.

	* calendar/calendar.el: Update copyright.
	(view-diary-entries-initially, european-calendar-style): Doc change.
	(calendar-setup): Make defcustom rather than defvar.
	(mark-visible-calendar-date): Initialize temp-face and faceinfo
	in let binding so local to function.

	* calendar/diary-lib.el: Update copyright.
	(diary, diary-entry-time): Doc change.
	(list-diary-entries): Doc change.  Trivial logic change.
	(fancy-diary-display): Restore make-face command mistakenly
	deleted 2003-05-08.
	(show-all-diary-entries): Allow to pop-up frame if needed.

	* calendar/diary-lib.el (diary-entry-time):
	Also accept time in the form XX[.XX][am/pm/AM/PM].
	(fancy-diary-font-lock-keywords): Likewise.
	(diary-font-lock-keywords): Likewise.
	* calendar/appt.el (appt-add): Likewise.
	(appt-make-list): Likewise.
	(appt-convert-time): Likewise.

	* calendar/calendar.el (increment-calendar-month)
	(calendar-leap-year-p, calendar-absolute-from-gregorian)
	(generate-calendar, calendar-read-date, calendar-interval)
	(calendar-day-of-week): Handle years BC.
	(generate-calendar-month, calendar-gregorian-from-absolute): Doc fix.

	* calendar/diary-lib.el (diary-header-line-flag)
	(diary-header-line-format): New variables.
	(list-diary-entries): Use them to set header line in simple diary.

	* calendar/diary-lib.el (simple-diary-display, make-diary-entry):
	Allow the diary to pop up a new frame, if needed.

	* calendar/calendar.el (calendar-make-alist): Correct off-by-one
	keeping December out of the alist.

	* calendar/cal-move.el (calendar-goto-day-of-year): New function.
	* calendar/calendar.el (calendar-mode-map): Bind it to key.
	* calendar/cal-menu.el (calendar-mode-map): Add it to menu.
	(calendar-flatten): New function.
	(calendar-mouse-view-other-diary-entries)
	(calendar-mouse-view-diary-entries): Rewritten to put any holidays
	in the menu title and to show multi-line diary entries correctly
	in the menu.

	* calendar/calendar.el (list-diary-entries-hook)
	(diary-display-hook, nongregorian-diary-listing-hook)
	(mark-diary-entries-hook, nongregorian-diary-marking-hook):
	Add some customize options for these hooks.
	(calendar-abbrev-construct): Don't try to take a substring longer
	than the original string.

	* calendar/calendar.el (diary-file, diary-file-name-prefix)
	(european-calendar-style, diary-date-forms)
	(calendar-day-name-array, calendar-month-name-array): Doc change.
	(generate-calendar-month): Adapt for new behavior of
	`calendar-day-name' function.
	(calendar-abbrev-length, calendar-day-abbrev-array)
	(calendar-month-abbrev-array): New variables.
	(calendar-abbrev-construct): New function.
	(calendar-day-name, calendar-month-name): Use new abbrev arrays,
	rather than fixing abbrevs at some width.  Calling syntax change.
	(calendar-make-alist): Use abbrev arrays.  Calling syntax change.
	(calendar-date-string): Adapt for new behaviors of
	`calendar-day-name' and `calendar-month-name' functions.

	* calendar/diary-lib.el (list-diary-entries): Adapt for new
	behavior of `calendar-day-name' and `calendar-month-name' functions.
	(diary-name-pattern): Use abbrev arrays, rather than fixing
	abbrevs at three chars.  Calling syntax change.
	(mark-diary-entries): Adapt for new behaviors of
	`diary-name-pattern' and `calendar-make-alist' functions.
	(fancy-diary-font-lock-keywords): Adapt for new behavior of
	`diary-name-pattern' function.
	(font-lock-diary-date-forms): Use abbrev arrays, rather than
	fixing abbrevs at three chars.  Calling syntax change.
	(cal-hebrew, cal-islam): Require when compiling.
	(diary-font-lock-keywords): Adapt for new behavior of
	`font-lock-diary-date-forms' function.

	* calendar/cal-hebrew.el: Reposition some code so defined before used.
	(calendar-hebrew-month-name-array-common-year)
	(calendar-hebrew-month-name-array-leap-year): Add doc strings.
	(list-hebrew-diary-entries): Adapt for new behaviors of
	`calendar-day-name' and `add-to-diary-list' functions.
	(mark-hebrew-diary-entries): Adapt for new behaviors of
	`diary-name-pattern' and `calendar-make-alist' functions.

	* calendar/cal-islam.el (calendar-islamic-month-name-array):
	Add doc string.
	(list-islamic-diary-entries): Adapt for new behaviors of
	`calendar-day-name' and `add-to-diary-list' functions.
	(mark-islamic-diary-entries): Adapt for new behaviors of
	`diary-name-pattern' and `calendar-make-alist' functions.

	* calendar/cal-menu.el (cal-menu-update): Adapt for new behavior of
	`calendar-month-name' function.

	* calendar/cal-coptic.el (coptic-name): defvar rather than defconst.

	* calendar/solar.el (solar-seasons-data): Move definition before use.

	* calendar/cal-tex.el (cal-tex-day-name-format): Doc fix.
	(cal-tex-LaTeX-hourbox): Move definition before use.

	* calendar/cal-china.el, cal-hebrew.el, cal-islam.el
	* cal-julian.el, cal-menu.el, cal-move.el, holidays.el
	* lunar.el, solar.el (displayed-month, displayed-year):
	Define for compiler.

	* calendar/timeclock.el (timeclock-relative)
	(timeclock-ask-before-exiting, timeclock-use-display-time):
	Doc changes.
	(timeclock-modeline-display): Give a message if
	`timeclock-use-display-time' is non-nil but `display-time-mode'
	is not active.

	* calendar/timeclock.el (timeclock-use-display-time)
	(timeclock-day-over-hook, timeclock-workday-remaining)
	(timeclock-status-string, timeclock-when-to-leave)
	(timeclock-when-to-leave-string, timeclock-log-data)
	(timeclock-find-discrep, timeclock-day-base)
	(timeclock-generate-report, timeclock-visit-timelog): Doc fix.
	(timeclock-modeline-display): Set the variable
	`timeclock-modeline-display'.
	(timeclock-update-modeline): Doc fix.  Respect value of
	`timeclock-relative'.

	* calendar/diary-lib.el (diary-check-diary-file): New function.
	(diary, view-diary-entries, show-all-diary-entries)
	(mark-diary-entries): Use it.
	(view-other-diary-entries): Doc fix.  Use `prefix-numeric-value'.
	(diary-syntax-table, diary-attrtype-convert, diary-mail-days): Doc fix.
	(diary-modified, d-file): No need to defvar (for compiler).
	(list-diary-entries): No need for `let*' so use `let'.
	(simple-diary-display): Use `diary-file' directly rather than
	inheriting `d-file' from `list-diary-entries' caller.
	(make-fancy-diary-buffer, show-all-diary-entries):
	`mode-line-format' already buffer-local.
	(diary-mail-addr): Set to the empty string (rather than nil) if
	undefined, as per `user-mail-address'.
	(diary-mail-entries): Doc fix.  Error if `diary-mail-address' unset.
	(mark-sexp-diary-entries): Don't regexp-quote sexp-mark twice.
	Remove an un-needed `if'.
	(list-sexp-diary-entries): Remove local vars mark and s-entry, and
	use `let' rather than `let*'.
	(diary-date, insert-monthly-diary-entry)
	(insert-yearly-diary-entry, insert-anniversary-diary-entry)
	(insert-block-diary-entry, insert-cyclic-diary-entry)
	(font-lock-diary-date-forms): No need for `let*' so use `let'.
	(make-diary-entry): Doc fix.  Use `or' rather than `if'.
	(diary-font-lock-keywords): Use `when'.  `cal-islam' is required
	feature, not `cal-islamic'.
	`calendar-islamic-month-name-array-leap-year' does not exist - use
	`calendar-islamic-month-name-array'.

	* calendar/timeclock.el (display-time-hook)
	(timeclock-modeline-display): Define for byte-compiler.
	(timeclock-time-to-date, timeclock-workday-remaining)
	(timeclock-time-to-seconds, timeclock-seconds-to-time):
	Move earlier in the file so defined before used.
	(timeclock-status-string): No need for `let*' so use `let'.
	(timeclock-query-out): Always return a non-nil value.

	* calendar/timeclock.el: Update copyright.
	(timeclock-ask-before-exiting): Put `timeclock-query-out' on
	`kill-emacs-query-functions' rather than `kill-emacs-hook'.
	(timeclock-mode-string): Doc fix.
	(timeclock-modeline-display): Doc fix.  Use `global-mode-string'
	rather than `mode-line-format'.
	(timeclock-query-out): Doc fix.
	(timeclock-update-modeline): No need for `let*', so use `let'.
	Add some help-echo text to `timeclock-mode-string'.
	(timeclock-mode-string): Give it the risky-local-variable
	property, so that help-echo text will display.
	(timeclock-find-discrep): Set `accum' to 0 if
	`timeclock-discrepancy' is nil.

	(diary-mail-entries): There is no fancy-diary-buffer if there are
	no diary entries.  Use call-interactively.

	* calendar/diary-lib.el (diary-pull-attrs): Make `ret-attr',
	`attr' local.
	(list-diary-entries): Make `temp' local.
	(fancy-diary-display): Make `marks', `temp-face', `faceinfo' local.
	(mark-diary-entries): Make `temp' local.
	(mark-sexp-diary-entries): Make `marks' local, remove `temp'.
	(list-sexp-diary-entries): Make `temp' local.
	(add-to-diary-list): Make `prefix' local.

	* calendar/diary-lib.el (fancy-diary-display-mode): Bind "q" to
	`quit-window' in the fancy diary buffer.

	Face markup of calendar and diary displays: Any entry line that
	ends with [foo:value] where foo is a face attribute (except :box
	:stipple) or with [face:blah] tags, will have these values applied
	to the calendar and fancy diary displays. These attributes "stack"
	on calendar displays.  File-wide attributes can be defined as
	follows: the first line matching "^# [tag:value]" defines the
	value for that particular tag.  All of the tags' regexps can be
	customized.

	* calendar/calendar.el (diary-face-attrs): New custom.
	(diary-file-name-prefix-function): New custom.
	(diary-glob-file-regexp-prefix): New custom.
	(diary-file-name-prefix): New custom.
	(generate-calendar-window): Check that font-lock-mode is bound
	before checking value.
	(mark-visible-calendar-date): Add the ability to pass face
	attribute/value pairs in the mark argument.  Handle the mark.

	* calendar/diary-lib.el (diary-attrtype-convert): Convert an
	attribute value string to the desired type.
	(diary-pull-attrs): New function that pulls the attributes off a
	diary entry, merges with file-global attributes, and returns
	the (possibly modified) entry and a list of attribute/values using
	diary-attrtype-convert.
	(list-diary-entries, fancy-diary-display, show-all-diary-entries)
	(mark-diary-entries, mark-sexp-diary-entries)
	(list-sexp-diary-entries): Add handling of file-global attributes;
	add handling of entry attributes using diary-pull-attrs.
	(mark-calendar-days-named, mark-calendar-days-named)
	(mark-calendar-date-pattern, mark-calendar-month)
	(add-to-diary-list): Add optional paramater `color' for passing
	face attribute info through the callchain.  Pass this parameter around.

	* calendar/calendar.el (calendar-only-one-frame-setup): Autoload it.

	* calendar/calendar.el (calendar-day-name): Move defn down.

	* calendar/calendar.el (facemenu-unlisted-faces): Only update
	after facemenu is loaded.
	(calendar-font-lock-keywords): Accept non-ASCII month names.
	Use regexp-opt.

	* calendar/solar.el (solar-atn2): Give correct quadrant for arctan.

	* calendar/diary-lib.el (fancy-diary-font-lock-keywords):
	Grok month numbers, too.

	* calendar/diary-lib.el (list-diary-entries): Pass a marker
	indicating source of entry to add-to-diary-list.
	(list-sexp-diary-entries): Pass a marker indicating source of
	entry to add-to-diary-list.
	(diary-date): Return mark as well as entry.
	(add-to-diary-list): Add new marker argument, appended to
	diary-entries-list.
	(diary-mode, fancy-diary-display-mode): New derived modes, for
	diary file and fancy diary buffer respectively.
	(fancy-diary-font-lock-keywords, diary-font-lock-keywords): New
	variables.
	(font-lock-diary-sexps, font-lock-diary-date-forms): New
	functions, used in diary-font-lock-keywords.
	* calendar/calendar.el (diary-face): New.
	(calendar-mode): Set up font-lock mode, using new variable
	calendar-font-lock-keywords.
	(generate-calendar-window): Fontify if font-lock-mode is on.
	(calendar-font-lock-keywords): New variable.

	* calendar/diary-lib.el 
	(diary-button-face, diary-entry, diary-goto-entry): New, to
	support click to diary file.
	(fancy-diary-display): Buttonize diary entries.  Use new mode
	fancy-diary-display-mode.



calendar source patch:
Diff command:   cvs -q diff -uN
Files affected: todo-mode.el timeclock.el solar.el lunar.el icalendar.el holidays.el diary-lib.el calendar.el cal-xemacs.el cal-x.el cal-tex.el cal-persia.el cal-move.el cal-mayan.el cal-julian.el cal-japanese.el cal-iso.el cal-islam.el cal-hebrew.el cal-french.el cal-dst.el cal-coptic.el cal-compat.el cal-china.el appt.el Makefile

Index: Makefile
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/calendar/Makefile,v
retrieving revision 1.34
diff -u -u -r1.34 Makefile
--- Makefile	2006/08/21 06:06:30	1.34
+++ Makefile	2006/10/20 21:46:43
@@ -31,7 +31,7 @@
 	cal-xemacs.elc calendar.elc diary-lib.elc holidays.elc cal-tex.elc \
 	cal-hebrew.elc cal-islam.elc cal-iso.elc cal-move.elc cal-persia.elc\
 	cal-china.elc cal-coptic.elc cal-julian.elc lunar.elc solar.elc \
-        todo-mode.elc timeclock.elc
+        todo-mode.elc timeclock.elc cal-bahai.elc icalendar.elc cal-compat.elc
 
 ifeq ($(BUILD_WITHOUT_MULE),)
 ELCS += cal-japanese.elc
Index: appt.el
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/calendar/appt.el,v
retrieving revision 1.11
diff -u -u -r1.11 appt.el
--- appt.el	2006/08/04 20:23:50	1.11
+++ appt.el	2006/10/20 21:46:44
@@ -1,12 +1,12 @@
 ;;; appt.el --- appointment notification functions
-;; Keywords: calendar
 
-;; Copyright (C) 1989, 1990, 1994, 1998 Free Software Foundation, Inc.
+;; Copyright (C) 1989, 1990, 1994, 1998, 2001, 2002, 2003, 2004, 2005,
+;;   2006  Free Software Foundation, Inc.
 
 ;; Author: Neil Mager <neilm at juliet.ll.mit.edu>
-;; Maintainer: FSF
+;; Maintainer: Glenn Morris <rgm at gnu.org>
 ;; Keywords: calendar
- 
+
 ;; This file is part of XEmacs.
 
 ;; XEmacs is free software; you can redistribute it and/or modify
@@ -21,145 +21,84 @@
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with XEmacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Synched up with: FSF Emacs 22.1 CVS 2006-09-15
 
 ;;; Commentary:
 
 ;;
 ;; appt.el - visible and/or audible notification of
-;;           appointments from ~/diary file.
+;;           appointments from diary file.
 ;;
 ;;;
-;;; Thanks to  Edward M. Reingold for much help and many suggestions, 
+;;; Thanks to  Edward M. Reingold for much help and many suggestions,
 ;;; And to many others for bug fixes and suggestions.
 ;;;
 ;;;
-;;; This functions in this file will alert the user of a 
-;;; pending appointment based on their diary file.
+;;; This functions in this file will alert the user of a
+;;; pending appointment based on his/her diary file.  This package
+;;; is documented in the Emacs manual.
+;;;
+;;; To activate this package, simply use (appt-activate 1).
+;;; A `diary-file' with appointments of the format described in the
+;;; documentation of the function `appt-check' is required.
+;;; Relevant customizable variables are also listed in the
+;;; documentation of that function.
+;;;
+;;; Today's appointment list is initialized from the diary when this
+;;; package is activated. Additionally, the appointments list is
+;;; recreated automatically at 12:01am for those who do not logout
+;;; every day or are programming late. It is also updated when the
+;;; `diary-file' is saved. Calling `appt-check' with an argument forces
+;;; a re-initialization at any time.
 ;;;
-;;; ******* It is necessary to invoke 'appt-initialize' for this 
-;;; ******* to work properly. 
-;;; 
-;;; A message will be displayed in the mode line of the Emacs buffer 
-;;; and (if you request) the terminal will beep and display a message 
-;;; from the diary in the mini-buffer, or you can choose to 
-;;; have a message displayed in a new buffer.
-;;;
-;;; Variables of note:
-;;;
-;;; appt-issue-message		If this variable is nil, then the code in this
-;;;				file does nothing.
-;;; appt-msg-countdown-list	Specifies how much warning you want before 
-;;;				appointments.
-;;; appt-audible		Whether to beep when it's notification-time.
-;;; appt-display-mode-line	Whether to display a countdown to the next 
-;;;				appointment in the mode-line.
-;;; appt-announce-method	The function used to do the notifications.
-;;;	'appt-window-announce		   do it in a pop-up window.
-;;;     'appt-frame-announce		   do it in a pop-up frame (v19 only)
-;;;	'appt-message-announce		   do it in the echo area.
-;;;	'appt-persistent-message-announce  do it in the echo area, but make the
-;;;				    messages not go away at the next keystroke.
-;;; appt-display-duration	If appt-announce-method is set to the function
-;;;				'appt-window-announce, this specifies how many
-;;;				seconds the pop-up window should stick around.
-;;;
-;;; In order to use this, create a diary file, and add the following to your
-;;; .emacs file:
-;;;
-;;;    (require 'appt)
-;;;    (appt-initialize)
-;;;
-;;; If you wish to see a list of appointments, or a full calendar, when emacs
-;;; starts up, you can add a call to (diary) or (calendar) after this.
-;;;
-;;;  This is an example of what can be in your diary file:
-;;;	 Monday
-;;;	   9:30am Coffee break
-;;;	  12:00pm Lunch
-;;; 
-;;; Based upon the above lines in your .emacs and diary files, 
-;;; the calendar and diary will be displayed when you enter
-;;; Emacs and your appointments list will automatically be created.  
-;;; You will then be reminded at 9:20am about your coffee break 
-;;; and at 11:50am to go to lunch.
-;;;
-;;; In order to interactively add or delete items from today's list, use 
-;;; Meta-x appt-add and Meta-x appt-delete.  (This does not modify your 
-;;; diary file, so these will be forgotten when you exit emacs.)
-;;;
-;;;  Additionally, the appointments list is recreated automatically 
-;;;  at 12:01am for those who do not logout every day or are programming 
-;;;  late.
-;;;
-;;; You can have special appointments which execute arbitrary code rather than
-;;; simply notifying you -- sort of like the unix "cron" facility.  The syntax
-;;; for this is borrowed from the Calendar's special-date format.  If you have
-;;; a diary entry like
-;;;
-;;;  Monday
-;;;    3:00am	%%(save-all-modified-buffers)
-;;;
-;;; then on monday at 3AM, the function `save-all-modified-buffers' will be
-;;; invoked.  (Presumably this function is defined in your .emacs file.)
-;;; There will be no notification that these "special" appointments are being
-;;; triggered, unless the form evaluated produces a notification.
-;;;
-;;; It is necessary for the entire list after the "%%" to be on one line in 
-;;; your .diary file -- there may not be embedded newlines in it.  This is a
-;;; bit of a misfeature.
+;;; In order to add or delete items from today's list, without
+;;; changing the diary file, use `appt-add' and `appt-delete'.
 ;;;
-;;; This also interacts correctly with Benjamin Pierce's reportmail.el package.
-;;;
+
 ;;; Brief internal description - Skip this if you are not interested!
 ;;;
-;;; The function appt-initialize invokes 'diary' to get a list of today's
-;;; appointments, and parses the lines beginning with date descriptions.
-;;; This list is cached away.  'diary' is invoked in such a way so as to
-;;; not pop up a window displaying the diary buffer.
-;;;
-;;; The function appt-check is run from the 'loadst' process (or the 'wakeup'
-;;; process in emacs 18.57 or newer) which is started by invoking display-time.
-;;; It checks this cached list, and announces as appropriate.  At midnight,
-;;; appt-initialize is called again to rebuild this list.
-;;;
-;;; display-time-filter is modified to invoke appt-check.
-;;;
-;;; TO DO:
-;;;
-;;;  o  multiple adjacent appointments are not handled gracefully.  If there 
-;;;     is an appointment at 3:30 and another at 3:35, and you have set things
-;;;     up so that you get a notification twenty minutes before each appt,
-;;;     then a notification should come at 3:10 for the first appt, and at
-;;;     3:15 for the second.  Currently, no notifications are generated for an
-;;;     appointment until all preceding appointments have completely expired.
-;;;
-;;;  o  If there are two appointments at the same time, all but the first are
-;;;     ignored (not announced.)
-;;;
-;;;  o  Appointments which are early enough in the morning that their 
-;;;     announcements should begin before midnight are not announced until
-;;;     midnight.
+;;; The function `appt-make-list' creates the appointments list which
+;;; `appt-check' reads.
 ;;;
-;;;  o  There should be some way to mark certain appointments as "important,"
-;;;     so that you will be harassed about them even after they have expired.
+;;; You can change the way the appointment window is created/deleted by
+;;; setting the variables
+;;;
+;;;	     appt-disp-window-function
+;;; and
+;;; 	     appt-delete-window-function
+;;;
+;;; For instance, these variables could be set to functions that display
+;;; appointments in pop-up frames, which are lowered or iconified after
+;;; `appt-display-interval' minutes.
+;;;
 
 ;;; Code:
 
 ;; Make sure calendar is loaded when we compile this.
 (require 'calendar)
 
-(provide 'appt)
+;; XEmacs - this helps quiet the byte-compiler
+(eval-when-compile
+  (require 'diary-lib))
 
+(defvar diary-selective-display)
+
 ;;;###autoload
 (defcustom appt-issue-message t
   "*Non-nil means check for appointments in the diary buffer.
-To be detected, the diary entry must have the time
-as the first thing on a line."
+To be detected, the diary entry must have the format described in the
+documentation of the function `appt-check'."
   :type 'boolean
   :group 'appt)
 
+;; XEmacs - only use the 2 arg form. 
+(make-obsolete-variable 'appt-issue-message
+                        "use the function `appt-activate', and the \
+variable `appt-display-format' instead.")
+
 ;;;###autoload
 (defcustom appt-message-warning-time 12
   "*Time in minutes before an appointment that the warning begins."
@@ -171,57 +110,78 @@
   "*Non-nil means beep to indicate appointment."
   :type 'boolean
   :group 'appt)
-  
+
 ;;;###autoload
 (defcustom appt-visible t
-  "*Non-nil means display appointment message in echo area."
+  "*Non-nil means display appointment message in echo area.
+This variable is only relevant if `appt-msg-window' is nil."
   :type 'boolean
   :group 'appt)
-  
+
+;; XEmacs - only use the 2 arg form. 
+(make-obsolete-variable 'appt-visible 'appt-display-format)
+
 ;;;###autoload
-(defcustom appt-audible t
-  "*Controls whether appointment announcements should beep.
-Appt uses two sound-types for beeps: `appt' and `appt-final'.
-If this is a number, then that many beeps will occur.
-If this is a cons, the car is how many beeps, and the cdr is the
-  delay between them (a float, fraction of a second to sleep.)
-See also the variable `appt-msg-countdown-list'"
+(defcustom appt-msg-window t
+  "*Non-nil means display appointment message in another window.
+If non-nil, this variable overrides `appt-visible'."
   :type 'boolean
   :group 'appt)
 
+;; XEmacs - only use the 2 arg form. 
+(make-obsolete-variable 'appt-msg-window 'appt-display-format)
+
+
 ;;;###autoload
+;(defcustom appt-audible t
+;  "*Controls whether appointment announcements should beep.
+;Appt uses two sound-types for beeps: `appt' and `appt-final'.
+;If this is a number, then that many beeps will occur.
+;If this is a cons, the car is how many beeps, and the cdr is the
+;  delay between them (a float, fraction of a second to sleep.)
+;See also the variable `appt-msg-countdown-list'"
+;:type 'boolean
+;:group 'appt)
+
+;; TODO - add popup.
+(defcustom appt-display-format 'ignore
+  "How appointment reminders should be displayed.
+The options are:
+   window - use a separate window
+   echo   - use the echo area
+   nil    - no visible reminder.
+See also `appt-audible' and `appt-display-mode-line'.
+
+The default value is 'ignore, which means to fall back on the value
+of the (obsolete) variables `appt-msg-window' and `appt-visible'."
+:type '(choice
+          (const :tag "Separate window" window)
+          (const :tag "Echo-area" echo)
+          (const :tag "No visible display" nil)
+          (const :tag "Backwards compatibility setting - choose another value"
+                 ignore))
+:group 'appt
+:version "22.1")
+
+;;;###autoload
 (defcustom appt-display-mode-line t
-  "*Non-nil means display minutes to appointment and time on the mode line."
+  "*Non-nil means display minutes to appointment and time on the mode line.
+This is in addition to any other display of appointment messages."
   :type 'boolean
   :group 'appt)
 
 ;;;###autoload
-(defcustom appt-msg-window t
-  "*Non-nil means display appointment message in another window."
-:type 'boolean
-:group 'appt)
-
-;;;###autoload
 (defcustom appt-display-duration 10
-  "*The number of seconds an appointment message is displayed."
+  "*The number of seconds an appointment message is displayed.
+Only relevant if reminders are to be displayed in their own window."
   :type 'integer
   :group 'appt)
 
 ;;;###autoload
 (defcustom appt-display-diary t
-  "*Non-nil means to display the next days diary on the screen. 
+  "*Non-nil displays the diary when the appointment list is first initialized.
 This will occur at midnight when the appointment list is updated."
-:type 'boolean
-:group 'appt)
-
-(defcustom appt-announce-method 'appt-window-announce
-  "*The name of the function used to notify the user of an impending 
-appointment.  This is called with two arguments, the number of minutes
-until the appointment, and the appointment description list.
-
-Reasonable values for this variable are 'appt-window-announce,
-'appt-message-announce, or 'appt-persistent-message-announce."
-:type 'function
+:type 'boolean
   :group 'appt)
 
 (defcustom appt-make-list-hook nil
@@ -231,110 +191,130 @@
 :type 'hook
 :group 'appt)
 
-(defvar appt-time-msg-list nil
-  "The list of appointments for today.  
-Use `appt-add' and `appt-delete' to add and delete appointments from list.
-The original list is generated from the today's `diary-entries-list'. 
-The number before each time/message is the time in minutes from midnight.")
 
-(defconst appt-max-time 1439
-  "11:59pm in minutes - number of minutes in a day minus 1.")
-  
-
+
 ;;; Announcement methods
 
-(defun appt-message-announce (min-to-app appt)
-  "Set appt-announce-method to the name of this function to cause appointment
-notifications to be given via messages in the minibuffer."
-  (message (if (eq min-to-app 0) "App't NOW."
-	       (format "App't in %d minute%s -- %s"
-		       min-to-app
-		       (if (eq 1 min-to-app) "" "s")
-		       (car (cdr appt))))))
-
-(defun appt-persistent-message-announce (min-to-app appt)
-  "Set appt-announce-method to the name of this function to cause appointment
-notifications to be given via messages in the minibuffer, but have those 
-messages stay around even if you type something (unlike normal messages)."
-  (let ((str (if (eq min-to-app 0)
-		 (format "App't NOW -- %s" (car (cdr appt)))
-		 (format "App't in %d minute%s -- %s"
-			 min-to-app
-			 (if (eq 1 min-to-app) "" "s")
-			 (car (cdr appt)))))
-	(in-echo-area-already (eq (selected-window) (minibuffer-window))))
-    (if (not in-echo-area-already)
-	;; don't stomp the echo-area-buffer if reading from the minibuffer now.
-	(save-excursion
-	  (save-window-excursion
-	    (select-window (minibuffer-window))
-	    (delete-region (point-min) (point-max))
-	    (insert str))))
-    ;; if we're reading from the echo-area, and all we were going to do is
-    ;; clear the thing, like, don't bother, that's annoying.
-    (if (and in-echo-area-already (string= "" str))
-	nil
-      (message "%s" str))
-    ))
+;(defun appt-message-announce (min-to-app appt)
+;  "Set appt-announce-method to the name of this function to cause appointment
+;notifications to be given via messages in the minibuffer."
+;  (message (if (eq min-to-app 0) "App't NOW."
+;	       (format "App't in %d minute%s -- %s"
+;		       min-to-app
+;		       (if (eq 1 min-to-app) "" "s")
+;		       (car (cdr appt))))))
+
+;(defun appt-persistent-message-announce (min-to-app appt)
+;  "Set appt-announce-method to the name of this function to cause appointment
+;notifications to be given via messages in the minibuffer, but have those 
+;messages stay around even if you type something (unlike normal messages)."
+;  (let ((str (if (eq min-to-app 0)
+;		 (format "App't NOW -- %s" (car (cdr appt)))
+;		 (format "App't in %d minute%s -- %s"
+;			 min-to-app
+;			 (if (eq 1 min-to-app) "" "s")
+;			 (car (cdr appt)))))
+;	(in-echo-area-already (eq (selected-window) (minibuffer-window))))
+;    (if (not in-echo-area-already)
+;	;; don't stomp the echo-area-buffer if reading from the minibuffer now.
+;	(save-excursion
+;	  (save-window-excursion
+;	    (select-window (minibuffer-window))
+;	    (delete-region (point-min) (point-max))
+;	    (insert str))))
+;    ;; if we're reading from the echo-area, and all we were going to do is
+;    ;; clear the thing, like, don't bother, that's annoying.
+;    (if (and in-echo-area-already (string= "" str))
+;	nil
+;      (message "%s" str))
+;    ))
 
 (defcustom appt-display-interval 3
   "*Number of minutes to wait between checking the appointment list."
-:type 'integer
-:group 'appt)
- 
-(defvar appt-buffer-name " *appt-buf*"
+:type 'integer
+:group 'appt)
+
+(defcustom appt-disp-window-function 'appt-disp-window
+  "Function called to display appointment window.
+Only relevant if reminders are being displayed in a window."
+:type '(choice (const appt-disp-window)
+                 function)
+:group 'appt)
+
+(defcustom appt-delete-window-function 'appt-delete-window
+  "Function called to remove appointment window and buffer.
+Only relevant if reminders are being displayed in a window."
+:type '(choice (const appt-delete-window)
+                 function)
+:group 'appt)
+
+
+;;; Internal variables below this point.
+
+(defconst appt-buffer-name " *appt-buf*"
   "Name of the appointments buffer.")
 
-(defun appt-frame-announce (min-to-app appt)
-  "Set appt-announce-method to the name of this function to cause appointment 
-notifications to be given via messages in a pop-up frame."
-  (let ()
-    (save-excursion
-      (set-buffer (get-buffer-create appt-buffer-name))
-      (erase-buffer)
-      ;; set the mode-line of the pop-up window
-      (setq modeline-format 
-	    (concat "-------------------- Appointment "
-		    (if (eq min-to-app 0)
-			"NOW"
-		      (concat "in " (format "%s" min-to-app)
-			      (if (eq min-to-app 1) " minute" " minutes")))
-		    ". ("
-		    (let ((h (string-to-int
-			      (substring (current-time-string) 11 13))))
-		      (concat (if (> h 12) (format "%s" (- h 12))
-				(format "%s" h)) ":"
-			      (substring (current-time-string) 14 16)
-			      (if (< h 12) "am" "pm")))
-		    ") %-"))
-      (insert (car (cdr appt)))
-      (let ((height (max 10 (min 20 (+ 2 (count-lines (point-min)
-						      (point-max)))))))
-        ;; If we already have a frame constructed, use it. If not, or it has
-        ;; been deleted, then make a new one
-	(if (and appt-disp-frame (frame-live-p appt-disp-frame))
-	    (let ((s (selected-frame)))
-	      (select-frame appt-disp-frame)
-	      (make-frame-visible appt-disp-frame)
-	      (set-frame-height appt-disp-frame height)
-	      (sit-for 0)
-	      (select-frame s))
-          (progn
-            (setq appt-disp-frame (make-frame))
-            (set-frame-height appt-disp-frame height)
-            )
-          )
-	;; make the buffer visible in the frame 
-	;; and make the frame visible
-	(let ((pop-up-windows nil))
-	  (pop-to-buffer (get-buffer appt-buffer-name) 
-			 nil 
-			 appt-disp-frame)
-	  (make-frame-visible appt-disp-frame))
-        )
-      )
-    )
-  )
+(defvar appt-time-msg-list nil
+  "The list of appointments for today.
+Use `appt-add' and `appt-delete' to add and delete appointments.
+The original list is generated from today's `diary-entries-list', and
+can be regenerated using the function `appt-check'.
+Each element of the generated list has the form (MINUTES STRING [FLAG]); where
+MINUTES is the time in minutes of the appointment after midnight, and
+STRING is the description of the appointment.
+FLAG, if non-nil, says that the element was made with `appt-add'
+so calling `appt-make-list' again should preserve it.")
+
+;(defun appt-frame-announce (min-to-app appt)
+;  "Set appt-announce-method to the name of this function to cause appointment 
+;notifications to be given via messages in a pop-up frame."
+;  (let ()
+;    (save-excursion
+;      (set-buffer (get-buffer-create appt-buffer-name))
+;      (erase-buffer)
+;      ;; set the mode-line of the pop-up window
+;      (setq modeline-format 
+;	    (concat "-------------------- Appointment "
+;		    (if (eq min-to-app 0)
+;			"NOW"
+;		      (concat "in " (format "%s" min-to-app)
+;			      (if (eq min-to-app 1) " minute" " minutes")))
+;		    ". ("
+;		    (let ((h (string-to-int
+;			      (substring (current-time-string) 11 13))))
+;		      (concat (if (> h 12) (format "%s" (- h 12))
+;				(format "%s" h)) ":"
+;			      (substring (current-time-string) 14 16)
+;			      (if (< h 12) "am" "pm")))
+;		    ") %-"))
+;      (insert (car (cdr appt)))
+;      (let ((height (max 10 (min 20 (+ 2 (count-lines (point-min)
+;						      (point-max)))))))
+;        ;; If we already have a frame constructed, use it. If not, or it has
+;        ;; been deleted, then make a new one
+;	(if (and appt-disp-frame (frame-live-p appt-disp-frame))
+;	    (let ((s (selected-frame)))
+;	      (select-frame appt-disp-frame)
+;	      (make-frame-visible appt-disp-frame)
+;	      (set-frame-height appt-disp-frame height)
+;	      (sit-for 0)
+;	      (select-frame s))
+;          (progn
+;            (setq appt-disp-frame (make-frame))
+;            (set-frame-height appt-disp-frame height)
+;            )
+;          )
+;	;; make the buffer visible in the frame 
+;	;; and make the frame visible
+;	(let ((pop-up-windows nil))
+;	  (pop-to-buffer (get-buffer appt-buffer-name) 
+;			 nil 
+;			 appt-disp-frame)
+;	  (make-frame-visible appt-disp-frame))
+;        )
+;      )
+;    )
+;  )
 (defalias 'appt-screen-announce 'appt-frame-announce)
 
 ;;; To display stuff in the mode line, we use a new variable instead of
@@ -346,29 +326,29 @@
   :type 'string
   :group 'appt)
 
-(defun appt-display-mode-line (min-to-app)
-  "Add an appointment annotation to the mode line."
-  (setq appt-mode-line-string
-	(if (and appt-display-mode-line min-to-app)
-	    (if (eq 0 min-to-app)
-		"App't NOW "
-		(concat "App't in " (format "%s" min-to-app)
-			(if (eq 1 min-to-app) " minute  " " minutes ")))
-	    ""))
-  ;; make sure our variable is visible in global-mode-string.
-  (cond ((not appt-display-mode-line) nil)
-	((null global-mode-string)
-	 (setq global-mode-string (list "" 'appt-mode-line-string)))
-	((stringp global-mode-string)
-	 (setq global-mode-string
-	       (list global-mode-string 'appt-mode-line-string)))
-	((not (memq 'appt-mode-line-string global-mode-string))
-	 (setq global-mode-string
-	       (append global-mode-string (list 'appt-mode-line-string)))))
-  ;; force mode line updates - from time.el
-  (save-excursion (set-buffer (other-buffer)))
-  (set-buffer-modified-p (buffer-modified-p))
-  (sit-for 0))
+;(defun appt-display-mode-line (min-to-app)
+;  "Add an appointment annotation to the mode line."
+;  (setq appt-mode-line-string
+;	(if (and appt-display-mode-line min-to-app)
+;	    (if (eq 0 min-to-app)
+;		"App't NOW "
+;		(concat "App't in " (format "%s" min-to-app)
+;			(if (eq 1 min-to-app) " minute  " " minutes ")))
+;	    ""))
+;  ;; make sure our variable is visible in global-mode-string.
+;  (cond ((not appt-display-mode-line) nil)
+;	((null global-mode-string)
+;	 (setq global-mode-string (list "" 'appt-mode-line-string)))
+;	((stringp global-mode-string)
+;	 (setq global-mode-string
+;	       (list global-mode-string 'appt-mode-line-string)))
+;	((not (memq 'appt-mode-line-string global-mode-string))
+;	 (setq global-mode-string
+;	       (append global-mode-string (list 'appt-mode-line-string)))))
+;  ;; force mode line updates - from time.el
+;  (save-excursion (set-buffer (other-buffer)))
+;  (set-buffer-modified-p (buffer-modified-p))
+;  (sit-for 0))
 
 
 ;;; Internal stuff
@@ -432,104 +412,127 @@
              (sleep-for j)
 	     (setq i (1- i)))))
 	(t (beep))))
-
-(defvar appt-disp-window-function 'appt-disp-window
-  "Function called to display appointment window.")
 
-(defvar appt-delete-window-function 'appt-delete-window
-  "Function called to remove appointment window and buffer.")
+(defconst appt-max-time (1- (* 24 60))
+  "11:59pm in minutes - number of minutes in a day minus 1.")
 
 (defvar appt-mode-string nil
   "String being displayed in the mode line saying you have an appointment.
-The actual string includes the amount of time till the appointment.")
+The actual string includes the amount of time till the appointment.
+Only used if `appt-display-mode-line' is non-nil.")
 
 (defvar appt-prev-comp-time nil
-  "Time of day (mins since midnight) at which we last checked appointments.")
+  "Time of day (mins since midnight) at which we last checked appointments.
+A nil value forces the diary file to be (re-)checked for appointments.")
 
 (defvar appt-now-displayed nil
   "Non-nil when we have started notifying about a appointment that is near.")
+
+(defvar appt-display-count nil
+  "Internal variable used to count number of consecutive reminders.")
+
+(defvar appt-timer nil
+  "Timer used for diary appointment notifications (`appt-check').
+If this is non-nil, appointment checking is active.")
+
+
+;;; Functions.
+
+(defun appt-display-message (string mins)
+  "Display a reminder about an appointment.
+The string STRING describes the appointment, due in integer MINS minutes.
+The format of the visible reminder is controlled by `appt-display-format'.
+The variable `appt-audible' controls the audible reminder."
+  ;; let binding for backwards compatability. Remove when obsolete
+  ;; vars appt-msg-window and appt-visible are dropped.
+  (let ((appt-display-format
+         (if (eq appt-display-format 'ignore)
+             (cond (appt-msg-window 'window)
+                   (appt-visible 'echo))
+           appt-display-format)))
+    (cond ((eq appt-display-format 'window)
+           (funcall appt-disp-window-function
+                    (number-to-string mins)
+                    ;; TODO - use calendar-month-abbrev-array rather
+                    ;; than %b?
+                    (format-time-string "%a %b %e " (current-time))
+                    string)
+           (run-at-time (format "%d sec" appt-display-duration)
+                        nil
+                        appt-delete-window-function))
+          ((eq appt-display-format 'echo)
+           (message "%s" string)))
+    (if appt-audible (beep 1))))
+
+
+(defun appt-check (&optional force)
+  "Check for an appointment and update any reminder display.
+If optional argument FORCE is non-nil, reparse the diary file for
+appointments.  Otherwise the diary file is only parsed once per day,
+and when saved.
+
+Note: the time must be the first thing in the line in the diary
+for a warning to be issued.  The format of the time can be either
+24 hour or am/pm.  For example:
 
-(defvar appt-display-count nil)
- 
-(defun appt-check ()
-  "Check for an appointment and update the mode line and minibuffer if
- desired.
-Note: the time must be the first thing in the line in the diary 
- for a warning to be issued.
-
-The format of the time can be either 24 hour or am/pm.
-Example: 
-  
-               02/23/89
-                 18:00 Dinner
+              02/23/89
+                18:00 Dinner
 
               Thursday
                 11:45am Lunch meeting.
 
 Appointments are checked every `appt-display-interval' minutes.
 The following variables control appointment notification:
- 
-`appt-issue-message'
-       If t, the diary buffer is checked for appointments.
 
-`appt-message-warning-time'
-       Variable used to determine if appointment message
-       should be displayed.
+`appt-display-format'
+        Controls the format in which reminders are displayed.
 
 `appt-audible'
-       Variable used to determine if appointment is audible.
-       Default is t.
+	Variable used to determine if reminder is audible.
+	Default is t.
+
+`appt-message-warning-time'
+	Variable used to determine when appointment message
+	should first be displayed.
 
-`appt-visible'
-       Variable used to determine if appointment message should be
-       displayed in the mini-buffer.  Default is t.
-
-`appt-msg-window'
-       Variable used to determine if appointment message
-       should temporarily appear in another window.  Mutually exclusive
-       to `appt-visible'.
+`appt-display-mode-line'
+        If non-nil, a generic message giving the time remaining
+        is shown in the mode-line when an appointment is due.
+
+`appt-display-interval'
+        Interval in minutes at which to check for pending appointments.
+
+`appt-display-diary'
+        Display the diary buffer when the appointment list is
+        initialized for the first time in a day.
 
+The following variables are only relevant if reminders are being
+displayed in a window:
+
 `appt-display-duration'
-       The number of seconds an appointment message
-       is displayed in another window.
+	The number of seconds an appointment message is displayed.
 
 `appt-disp-window-function'
-       Function called to display appointment window.  You can customize
-       appt.el by setting this variable to a function different from the
-       one provided with this package.
-  
+    	Function called to display appointment window.
+
 `appt-delete-window-function'
-       Function called to remove appointment window and buffer.  You can
-       customize appt.el by setting this variable to a function different
-       from the one provided with this package.
- 
-
- appt-msg-countdown-list	Specifies how much warning you want before 
-				appointments.
- appt-display-mode-line		Whether to display a countdown to the next 
-				appointment in the mode-line.
- appt-announce-method   	The function used to do the notifications.
-				'appt-window-announce to do it in a pop-up
-				window, 'appt-message-announce or 
-				'appt-persistent-message-announce to do it 
-				in the echo-area."
-
-  (let* ((min-to-app -1) 
- 	 (new-time "")
- 	 (prev-appt-mode-string appt-mode-string)
- 	 (prev-appt-display-count (or appt-display-count 0))
-         ;; Non-nil means do a full check for pending appointments
-         ;; and display in whatever ways the user has selected.
-         ;; When no appointment is being displayed,
-         ;; we always do a full check.
-         (full-check
-          (or (not appt-now-displayed)
-              ;; This is true every appt-display-interval minutes.
-              (= 0 (mod prev-appt-display-count appt-display-interval))))
-         ;; Non-nil means only update the interval displayed in the mode line.
-         (mode-line-only
-          (and (not full-check) appt-now-displayed)))
+    	Function called to remove appointment window and buffer."
 
+  (let* ((min-to-app -1)
+	 (prev-appt-mode-string appt-mode-string)
+	 (prev-appt-display-count (or appt-display-count 0))
+	 ;; Non-nil means do a full check for pending appointments
+	 ;; and display in whatever ways the user has selected.
+	 ;; When no appointment is being displayed,
+	 ;; we always do a full check.
+	 (full-check
+	  (or (not appt-now-displayed)
+	      ;; This is true every appt-display-interval minutes.
+	      (zerop (mod prev-appt-display-count appt-display-interval))))
+	 ;; Non-nil means only update the interval displayed in the mode line.
+	 (mode-line-only
+	  (and (not full-check) appt-now-displayed)))
+
     (when (or full-check mode-line-only)
       (save-excursion
 
@@ -541,100 +544,95 @@
 	       (cur-min (nth 1 now))
 	       (cur-comp-time (+ (* cur-hour 60) cur-min)))
 
-	  ;; At the first check in any given day, update our 
+	  ;; At the first check in any given day, update our
 	  ;; appointments to today's list.
-
-          (if (or (null appt-prev-comp-time)
-                  (< cur-comp-time appt-prev-comp-time))
-              (condition-case nil
-                  (progn
-                    (if (and view-diary-entries-initially appt-display-diary)
-                        (diary)
-                      (let ((diary-display-hook 'appt-make-list))
-                        (diary))))
-                (error nil)))
-          (setq appt-prev-comp-time cur-comp-time)
 
-          (setq appt-mode-string nil)
-          (setq appt-display-count nil)
+	  (if (or force                 ; eg initialize, diary save
+                  (null appt-prev-comp-time)             ; first check
+		  (< cur-comp-time appt-prev-comp-time)) ; new day
+	      (condition-case nil
+                  (if appt-display-diary
+                      (let ((diary-hook
+                             (if (assoc 'appt-make-list diary-hook)
+                                 diary-hook
+                               (cons 'appt-make-list diary-hook))))
+                        (diary))
+                    (let* ((diary-display-hook 'appt-make-list)
+                           (d-buff (find-buffer-visiting
+                                    (substitute-in-file-name diary-file)))
+                           (selective
+                            (if d-buff        ; Diary buffer exists.
+                                (with-current-buffer d-buff
+                                  diary-selective-display))))
+                      (diary)
+                      ;; If the diary buffer existed before this command,
+                      ;; restore its display state. Otherwise, kill it.
+                      (if d-buff
+                          ;; Displays the diary buffer.
+                          (or selective (diary-show-all-entries))
+                        (and
+                         (setq d-buff (find-buffer-visiting
+                                       (substitute-in-file-name diary-file)))
+                         (kill-buffer d-buff)))))
+		(error nil)))
+
+	  (setq appt-prev-comp-time cur-comp-time
+                appt-mode-string nil
+                appt-display-count nil)
 
 	  ;; If there are entries in the list, and the
 	  ;; user wants a message issued,
-	  ;; get the first time off of the list 
+	  ;; get the first time off of the list
 	  ;; and calculate the number of minutes until the appointment.
 
 	  (if (and appt-issue-message appt-time-msg-list)
 	      (let ((appt-comp-time (car (car (car appt-time-msg-list)))))
 		(setq min-to-app (- appt-comp-time cur-comp-time))
 
-		(while (and appt-time-msg-list 
+		(while (and appt-time-msg-list
 			    (< appt-comp-time cur-comp-time))
-		  (setq appt-time-msg-list (cdr appt-time-msg-list)) 
+		  (setq appt-time-msg-list (cdr appt-time-msg-list))
 		  (if appt-time-msg-list
-		      (setq appt-comp-time 
+		      (setq appt-comp-time
 			    (car (car (car appt-time-msg-list))))))
-	     
+
 		;; If we have an appointment between midnight and
 		;; 'appt-message-warning-time' minutes after midnight,
 		;; we must begin to issue a message before midnight.
 		;; Midnight is considered 0 minutes and 11:59pm is
 		;; 1439 minutes. Therefore we must recalculate the minutes
-		;; to appointment variable. It is equal to the number of 
-		;; minutes before midnight plus the number of 
+		;; to appointment variable. It is equal to the number of
+		;; minutes before midnight plus the number of
 		;; minutes after midnight our appointment is.
-	     
+
 		(if (and (< appt-comp-time appt-message-warning-time)
 			 (> (+ cur-comp-time appt-message-warning-time)
 			    appt-max-time))
-		    (setq min-to-app (+ (- (1+ appt-max-time) cur-comp-time))
-			  appt-comp-time))
-	     
-		;; issue warning if the appointment time is 
+		    (setq min-to-app (+ (- (1+ appt-max-time) cur-comp-time)
+                                        appt-comp-time)))
+
+		;; issue warning if the appointment time is
 		;; within appt-message-warning time
 
 		(when (and (<= min-to-app appt-message-warning-time)
 			   (>= min-to-app 0))
-		  (setq appt-now-displayed t)
-		  (setq appt-display-count
-			(1+ prev-appt-display-count))
+		  (setq appt-now-displayed t
+                        appt-display-count (1+ prev-appt-display-count))
 		  (unless mode-line-only
-		    (if appt-msg-window
-			(progn
-			  (setq new-time (format-time-string "%a %b %e "
-							     (current-time)))
-			  (funcall
-			   appt-disp-window-function
-			   (number-to-string min-to-app) new-time
-			   (car (cdr (car appt-time-msg-list))))
-		       
-			  (run-at-time
-			   (format "%d sec" appt-display-duration)
-			   nil
-  			   appt-delete-window-function))
-                             ;;; else
-		   
-		      (if appt-visible
-			  (message "%s" 
-				   (car (cdr (car appt-time-msg-list)))))
-		   
-		      (if appt-audible
-			  (beep 1))))
-	       
+                    (appt-display-message (cadr (car appt-time-msg-list))
+                                          min-to-app))
 		  (when appt-display-mode-line
 		    (setq appt-mode-string
-			  (concat  " App't in "
-				   (number-to-string min-to-app)
-				   " min. ")))
-	       
+                          (format " App't in %s min." min-to-app)))
+
 		  ;; When an appointment is reached,
 		  ;; delete it from the list.
 		  ;; Reset the count to 0 in case we display another
 		  ;; appointment on the next cycle.
-		  (if (= min-to-app 0)
-		      (setq appt-time-msg-list 
-			    (cdr appt-time-msg-list)
+		  (if (zerop min-to-app)
+		      (setq appt-time-msg-list (cdr appt-time-msg-list)
 			    appt-display-count nil)))))
-       
+
 	  ;; If we have changed the mode line string,
 	  ;; redisplay all mode lines.
 	  (and appt-display-mode-line
@@ -652,52 +650,51 @@
 ;;notifications to be given via messages in a pop-up window.  The variable
 ;;appt-display-duration controls how long this window should be left up."
 
-(defun  appt-disp-window (min-to-app new-time appt-msg)
-  "Display appointment message APPT-MSG in a separate buffer."
+(defun appt-disp-window (min-to-app new-time appt-msg)
+  "Display appointment message APPT-MSG in a separate buffer.
+The appointment is due in MIN-TO-APP (a string) minutes.
+NEW-TIME is a string giving the date."
   (require 'electric)
-  
+
   ;; Make sure we're not in the minibuffer
   ;; before splitting the window.
-  
+
   (if (equal (selected-window) (minibuffer-window))
-      (if (other-window 1) 
+      (if (other-window 1)
 	  (select-window (other-window 1))
 	(if (display-multi-frame-p)
 	    (select-frame (other-frame 1)))))
-  
-  (let* ((this-buffer (current-buffer))
-	 (this-window (selected-window))
-	 (appt-disp-buf (set-buffer (get-buffer-create appt-buffer-name))))
+
+  (let ((this-window (selected-window))
+        (appt-disp-buf (set-buffer (get-buffer-create appt-buffer-name))))
 
     (if (cdr (assq 'unsplittable (frame-parameters)))
 	;; In an unsplittable frame, use something somewhere else.
 	(display-buffer appt-disp-buf)
-    ;;  (unless (or (special-display-p (buffer-name appt-disp-buf))
-    ;;		  (same-window-p (buffer-name appt-disp-buf)))
+      ;; XEmacs, we don't have either of these functions
+      ;;  (unless (or (special-display-p (buffer-name appt-disp-buf))
+      ;;		  (same-window-p (buffer-name appt-disp-buf)))
 	;; By default, split the bottom window and use the lower part.
 	(appt-select-lowest-window)
-	(split-window)
-    ;;)
-      (pop-to-buffer appt-disp-buf))
-    (setq mode-line-format 
-	  (concat "-------------------- Appointment in "
-		  min-to-app " minutes. " new-time " %-"))
+        (select-window (split-window)))
+      (switch-to-buffer appt-disp-buf)
+      ;;)
+    (calendar-set-mode-line
+     (format " Appointment in %s minutes. %s " min-to-app new-time))
     (erase-buffer)
     (insert appt-msg)
     (shrink-window-if-larger-than-buffer (get-buffer-window appt-disp-buf t))
     (set-buffer-modified-p nil)
     (raise-frame (selected-frame))
-    (select-window this-window)
-    (if appt-audible
-	(beep 1))))
-  
+    (select-window this-window)))
+
 (defun appt-delete-window ()
   "Function called to undisplay appointment messages.
 Usually just deletes the appointment buffer."
   (let ((window (get-buffer-window appt-buffer-name t)))
     (and window
-        (or (eq window (frame-root-window (window-frame window)))
-            (delete-window window))))
+	 (or (eq window (frame-root-window (window-frame window)))
+	     (delete-window window))))
   (kill-buffer appt-buffer-name)
   (if appt-audible
       (beep 1)))
@@ -705,44 +702,45 @@
 (defun appt-select-lowest-window ()
 "Select the lowest window on the frame."
   (let ((lowest-window (selected-window))
+        ;; XEmacs change, we don't have window-edges
        (bottom-edge (nth 3 (window-pixel-edges))))
     (walk-windows (lambda (w)
-                   (let ((next-bottom-edge (nth 3 (window-pixel-edges w))))
-                     (when (< bottom-edge next-bottom-edge)
-                       (setq bottom-edge next-bottom-edge
-                             lowest-window w)))))
+		    (let ((next-bottom-edge (nth 3 (window-pixel-edges w))))
+		      (when (< bottom-edge next-bottom-edge)
+			(setq bottom-edge next-bottom-edge
+			      lowest-window w)))))
     (select-window lowest-window)))
 
+(defconst appt-time-regexp
+  "[0-9]?[0-9]\\(h\\([0-9][0-9]\\)?\\|[:.][0-9][0-9]\\)\\(am\\|pm\\)?")
+
 ;;;###autoload
 (defun appt-add (new-appt-time new-appt-msg)
-  "Add an appointment for the day at NEW-APPT-TIME and issue message NEW-APPT-MSG.
+  "Add an appointment for today at NEW-APPT-TIME with message NEW-APPT-MSG.
 The time should be in either 24 hour format or am/pm format."
- 
   (interactive "sTime (hh:mm[am/pm]): \nsMessage: ")
-  (if (string-match "[0-9]?[0-9]:[0-9][0-9]\\(am\\|pm\\)?" new-appt-time)
-      nil
+  (unless (string-match appt-time-regexp new-appt-time)
     (error "Unacceptable time-string"))
-  
-  (let* ((appt-time-string (concat new-appt-time " " new-appt-msg))
-         (appt-time (list (appt-convert-time new-appt-time)))
-         (time-msg (cons appt-time (list appt-time-string))))
-    (setq appt-time-msg-list (nconc appt-time-msg-list (list time-msg)))
-    (setq appt-time-msg-list (appt-sort-list appt-time-msg-list)))) 
+  (let ((time-msg (list (list (appt-convert-time new-appt-time))
+                        (concat new-appt-time " " new-appt-msg) t)))
+    (unless (member time-msg appt-time-msg-list)
+      (setq appt-time-msg-list
+            (appt-sort-list (nconc appt-time-msg-list (list time-msg)))))))
 
 ;;;###autoload
 (defun appt-delete ()
   "Delete an appointment from the list of appointments."
   (interactive)
-  (let* ((tmp-msg-list appt-time-msg-list))
+  (let ((tmp-msg-list appt-time-msg-list))
     (while tmp-msg-list
       (let* ((element (car tmp-msg-list))
-             (prompt-string (concat "Delete " 
+             (prompt-string (concat "Delete "
 				    ;; We want to quote any doublequotes
 				    ;; in the string, as well as put
 				    ;; doublequotes around it.
                                     (prin1-to-string
 				     (substring-no-properties
-				      (car (cdr element)) 0)) 				    
+				      (car (cdr element)) 0))
                                     " from list? "))
              (test-input (y-or-n-p prompt-string)))
         (setq tmp-msg-list (cdr tmp-msg-list))
@@ -751,217 +749,203 @@
     (appt-check)
     (message "")))
 
-
+
 (eval-when-compile (defvar number)
-                  (defvar original-date)
-                  (defvar diary-entries-list))
+		   (defvar original-date)
+		   (defvar diary-entries-list))
 ;;;###autoload
 (defun appt-make-list ()
-  "Create the appointments list from todays diary buffer.
+  "Update the appointments list from today's diary buffer.
 The time must be at the beginning of a line for it to be
-put in the appointments list.
-  02/23/89
-    12:00pm lunch
-   Wednesday
-     10:00am group meeting
-We assume that the variables DATE and NUMBER
-hold the arguments that `list-diary-entries' received.
-They specify the range of dates that the diary is being processed for."
-
-  ;; We have something to do if the range of dates that the diary is
-  ;; considering includes the current date.
-  (if (and (not (calendar-date-compare
-		 (list (calendar-current-date))
-		 (list original-date)))
-	   (calendar-date-compare
-	    (list (calendar-current-date))
-            (list (calendar-gregorian-from-absolute
-		   (+ (calendar-absolute-from-gregorian original-date)
-		      number)))))
-      (save-excursion
-	;; Clear the appointments list, then fill it in from the diary.
-	(setq appt-time-msg-list nil)
-	(if diary-entries-list
-
-	    ;; Cycle through the entry-list (diary-entries-list)
-	    ;; looking for entries beginning with a time. If 
-	    ;; the entry begins with a time, add it to the
-	    ;; appt-time-msg-list. Then sort the list.
-
-	    (let ((entry-list diary-entries-list)
-		  (new-time-string ""))
-	      ;; Skip diary entries for dates before today.
-	      (while (and entry-list
-			  (calendar-date-compare
-			   (car entry-list) (list (calendar-current-date))))
-		(setq entry-list (cdr entry-list)))
-	      ;; Parse the entries for today.
-	      (while (and entry-list 
-			  (calendar-date-equal 
-			   (calendar-current-date) (car (car entry-list))))
-               (let ((time-string (cadr (car entry-list))))
-		  (while (string-match
-                         "\\([0-9]?[0-9]:[0-9][0-9]\\(am\\|pm\\)?\\).*"
-			  time-string)
-                  (let* ((beg (match-beginning 0))
-                         ;; Get just the time for this appointment.
-                         (only-time (match-string 1 time-string))
-                         ;; Find the end of this appointment
-                         ;; (the start of the next).
-                         (end (string-match
-                               "^[ \t]*[0-9]?[0-9]:[0-9][0-9]\\(am\\|pm\\)?"
-                               time-string
-                               (match-end 0)))
-                         ;; Get the whole string for this appointment.
-                         (appt-time-string
-                          (substring time-string beg (if end (1- end)))))
-
-                    ;; Add this appointment to appt-time-msg-list.
-                    (let* ((appt-time (list (appt-convert-time only-time)))
-                           (time-msg (list appt-time appt-time-string)))
-                      (setq appt-time-msg-list
-                            (nconc appt-time-msg-list (list time-msg))))
-
-                     ;; Discard this appointment from the string.
-                     (setq time-string
-                           (if end (substring time-string end) "")))))
-                (setq entry-list (cdr entry-list)))))
-	(run-hooks 'appt-make-list-hook)
-        (setq appt-time-msg-list (appt-sort-list appt-time-msg-list))
-	;; Get the current time and convert it to minutes
-	;; from midnight. ie. 12:01am = 1, midnight = 0,
- 	;; so that the elements in the list
-	;; that are earlier than the present time can
-	;; be removed.
-	(let* ((now (decode-time))
-	       (cur-hour (nth 2 now))
-	       (cur-min (nth 1 now))
-	       (cur-comp-time (+ (* cur-hour 60) cur-min))
-	       (appt-comp-time (car (car (car appt-time-msg-list)))))
+put in the appointments list (see examples in documentation of
+the function `appt-check').  We assume that the variables DATE and
+NUMBER hold the arguments that `diary-list-entries' received.
+They specify the range of dates that the diary is being processed for.
+
+Any appointments made with `appt-add' are not affected by this
+function.
+
+For backwards compatibility, this function activates the
+appointment package (if it is not already active)."
+  ;; See comments above appt-activate defun.
+  (if (not appt-timer)
+      (appt-activate 1)
+    ;; We have something to do if the range of dates that the diary is
+    ;; considering includes the current date.
+    (if (and (not (calendar-date-compare
+                   (list (calendar-current-date))
+                   (list original-date)))
+             (calendar-date-compare
+              (list (calendar-current-date))
+              (list (calendar-gregorian-from-absolute
+                     (+ (calendar-absolute-from-gregorian original-date)
+                        number)))))
+        (save-excursion
+          ;; Clear the appointments list, then fill it in from the diary.
+          (dolist (elt appt-time-msg-list)
+            ;; Delete any entries that were not made with appt-add.
+            (unless (nth 2 elt)
+              (setq appt-time-msg-list
+                    (delq elt appt-time-msg-list))))
+          (if diary-entries-list
+
+              ;; Cycle through the entry-list (diary-entries-list)
+              ;; looking for entries beginning with a time. If
+              ;; the entry begins with a time, add it to the
+              ;; appt-time-msg-list. Then sort the list.
+
+              (let ((entry-list diary-entries-list)
+                    (new-time-string ""))
+                ;; Skip diary entries for dates before today.
+                (while (and entry-list
+                            (calendar-date-compare
+                             (car entry-list) (list (calendar-current-date))))
+                  (setq entry-list (cdr entry-list)))
+                ;; Parse the entries for today.
+                (while (and entry-list
+                            (calendar-date-equal
+                             (calendar-current-date) (car (car entry-list))))
+                  (let ((time-string (cadr (car entry-list))))
+                    (while (string-match appt-time-regexp time-string)
+                      (let* ((beg (match-beginning 0))
+                             ;; Get just the time for this appointment.
+                             (only-time (match-string 0 time-string))
+                             ;; Find the end of this appointment
+                             ;; (the start of the next).
+                             (end (string-match
+                                   (concat "\n[ \t]*" appt-time-regexp)
+                                   time-string
+                                   (match-end 0)))
+                             ;; Get the whole string for this appointment.
+                             (appt-time-string
+                              (substring time-string beg (if end (1- end)))))
+
+                        ;; Add this appointment to appt-time-msg-list.
+                        (let* ((appt-time (list (appt-convert-time only-time)))
+                               (time-msg (list appt-time appt-time-string)))
+                          (setq appt-time-msg-list
+                                (nconc appt-time-msg-list (list time-msg))))
+
+                        ;; Discard this appointment from the string.
+                        (setq time-string
+                              (if end (substring time-string end) "")))))
+                  (setq entry-list (cdr entry-list)))))
+          ;; XEmacs change
+          (run-hooks 'appt-make-list-hook)
+          (setq appt-time-msg-list (appt-sort-list appt-time-msg-list))
+
+          ;; Get the current time and convert it to minutes
+          ;; from midnight. ie. 12:01am = 1, midnight = 0,
+          ;; so that the elements in the list
+          ;; that are earlier than the present time can
+          ;; be removed.
+
+          (let* ((now (decode-time))
+                 (cur-hour (nth 2 now))
+                 (cur-min (nth 1 now))
+                 (cur-comp-time (+ (* cur-hour 60) cur-min))
+                 (appt-comp-time (car (caar appt-time-msg-list))))
+
+            (while (and appt-time-msg-list (< appt-comp-time cur-comp-time))
+              (setq appt-time-msg-list (cdr appt-time-msg-list))
+              (if appt-time-msg-list
+                  (setq appt-comp-time (car (caar appt-time-msg-list))))))))))
 
-	  (while (and appt-time-msg-list (< appt-comp-time cur-comp-time))
-	    (setq appt-time-msg-list (cdr appt-time-msg-list)) 
-	    (if appt-time-msg-list
-		(setq appt-comp-time (car (car (car appt-time-msg-list))))))))))
-  
 
 (defun appt-sort-list (appt-list)
-  "Simple sort to put the appointments list APPT-LIST in order.
-Scan the list for the smallest element left in the list.
-Append the smallest element left into the new list, and remove
-it from the original list."
-  (let ((order-list nil))
-    (while appt-list
-      (let* ((element (car appt-list))
-             (element-time (car (car element)))
-             (tmp-list (cdr appt-list)))
-        (while tmp-list
-          (if (< element-time (car (car (car tmp-list))))
-              nil
-            (setq element (car tmp-list))
-            (setq element-time (car (car element))))
-          (setq tmp-list (cdr tmp-list)))
-        (setq order-list (nconc order-list (list element)))
-        (setq appt-list (delq element appt-list))))
-    order-list))
+  "Sort an appointment list, putting earlier items at the front.
+APPT-LIST is a list of the same format as `appt-time-msg-list'."
+(sort appt-list (lambda (e1 e2) (< (caar e1) (caar e2)))))
 
 
 (defun appt-convert-time (time2conv)
-  "Convert hour:min[am/pm] format to minutes from midnight."
+  "Convert hour:min[am/pm] format to minutes from midnight.
+A period (.) can be used instead of a colon (:) to separate the
+hour and minute parts."
+  ;; Formats that should be accepted:
+  ;;   10:00 10.00 10h00 10h 10am 10:00am 10.00am
+  (let ((min (if (string-match "[h:.]\\([0-9][0-9]\\)" time2conv)
+                 (string-to-number (match-string 1 time2conv))
+               0))
+        (hr (if (string-match "[0-9]*[0-9]" time2conv)
+                (string-to-number (match-string 0 time2conv))
+              0)))
 
-  (let ((conv-time 0)
-        (hr 0)
-        (min 0))
-
-    (string-match ":\\([0-9][0-9]\\)" time2conv)
-    (setq min (string-to-int 
-               (match-string 1 time2conv)))
-  
-    (string-match "[0-9]?[0-9]:" time2conv)
-    (setq hr (string-to-int 
-              (match-string 0 time2conv)))
-  
     ;; convert the time appointment time into 24 hour time
-  
     (cond ((and (string-match "pm" time2conv) (< hr 12))
 	   (setq hr (+ 12 hr)))
 	  ((and (string-match "am" time2conv) (= hr 12))
            (setq hr 0)))
-  
-    ;; convert the actual time
-    ;; into minutes for comparison
-    ;; against the actual time.
-  
-    (setq conv-time (+ (* hr 60) min))
-    conv-time))
-
 
+    ;; convert the actual time into minutes.
+    (+ (* hr 60) min)))
 
-(defvar display-time-hook-installed nil)
-
-(defun install-display-time-hook ()
- (unless display-time-hook-installed	; only do this stuff once!
-   (unless (boundp 'display-time-hook)	; Need to wrapper it.
-     (defvar display-time-hook nil
-       "*List of functions to be called when the time is updated on the mode line.")
-     (let ((old-fn (if (or (featurep 'reportmail)
-			   ;; old reportmail without a provide statement
-			   (and (fboundp 'display-time-filter-18-55)
-				(fboundp 'display-time-filter-18-57)))
-		       (if (and (featurep 'itimer)  ; XEmacs reportmail.el
-				(fboundp 'display-time-timer-function))
-			   'display-time-timer-function
-			 ;; older reportmail, or no timer.el.
-			 (if (string-match "18\\.5[0-5]" (emacs-version))
-			     'display-time-filter-18-55
-			   'display-time-filter-18-57))
-		     ;; othewise, time.el
-		     (if (and (featurep 'itimer)
-			      (fboundp 'display-time-function)) ; XEmacs
-			 'display-time-function
-		       'display-time-filter))))
-    ;; we're about to redefine it...
-       (fset 'old-display-time-filter (symbol-function old-fn))
-       (fset old-fn
-	     (lambda (&rest args)  ;; ...here's the revised definition
-	       "Revised version of the original function: this version calls a hook."
-	       (apply 'old-display-time-filter args)
-	       (run-hooks 'display-time-hook)))))
-   (setq display-time-hook-installed t)
-   (if (fboundp 'add-hook)
-       (add-hook 'display-time-hook 'appt-check)
-     (setq display-time-hook (cons appt-check display-time-hook)))
-   ))
 
+(defun appt-update-list ()
+  "If the current buffer is visiting the diary, update appointments.
+This function is intended for use with `write-file-functions'."
+  (and (string-equal buffer-file-name (expand-file-name diary-file))
+       appt-timer
+       (let ((appt-display-diary nil))
+         (appt-check t)))
+  nil)
+
+
+;; In Emacs-21.3, the manual documented the following procedure to
+;; activate this package:
+;;     (display-time)
+;;     (add-hook 'diary-hook 'appt-make-list)
+;;     (diary 0)
+;; The display-time call was not necessary, AFAICS.
+;; What was really needed was to add the hook and load this file.
+;; Calling (diary 0) once the hook had been added was in some sense a
+;; roundabout way of loading this file. This file used to have code at
+;; the top-level that set up the appt-timer and global-mode-string.
+;; One way to maintain backwards compatibility would be to call
+;; (appt-activate 1) at top-level. However, this goes against the
+;; convention that just loading an Emacs package should not activate
+;; it. Instead, we make appt-make-list activate the package (after a
+;; suggestion from rms). This means that one has to call diary in
+;; order to get it to work, but that is in line with the old (weird,
+;; IMO) documented behavior for activating the package.
+;; Actually, since (diary 0) does not run diary-hook, I don't think
+;; the documented behavior in Emacs-21.3 would ever have worked.
+;; Oh well, at least with the changes to appt-make-list it will now
+;; work as well as it ever did.
+;; The new method is just to use (appt-activate 1).
+;; -- gmorris
+
+;;;###autoload
+(defun appt-activate (&optional arg)
+"Toggle checking of appointments.
+With optional numeric argument ARG, turn appointment checking on if
+ARG is positive, otherwise off."
+  (interactive "P")
+  (let ((appt-active appt-timer))
+    (setq appt-active (if arg (> (prefix-numeric-value arg) 0)
+                        (not appt-active)))
+    ;; XEmacs - we use write-file-hooks
+    (remove-hook 'write-file-hooks 'appt-update-list)
+    (or global-mode-string (setq global-mode-string '("")))
+    (delq 'appt-mode-string global-mode-string)
+    (when appt-timer
+      ;; XEmacs - really uses itimer
+      (appt-cancel-timer appt-timer)
+      (setq appt-timer nil))
+    (when appt-active
+      ;; XEmacs - we use write-file-hooks
+      (add-hook 'write-file-hooks 'appt-update-list)
+      (setq appt-timer (run-at-time t 60 'appt-check)
+            global-mode-string
+            (append global-mode-string '(appt-mode-string)))
+      (appt-check t))))
+
+;; This is needed for backwards compatibility. Feh.
+;; Not for XEmacs, we don't activate appt when the package is loaded.
+;;(appt-activate 1)
 
-(defvar appt-timer nil
-  "Timer used for diary appointment notifications (`appt-check').")
-
-(defun appt-initialize ()
-  "Read your `diary-file' and remember today's appointments.  Call this from 
- your .emacs file, or any time you want your .diary file re-read (this happens 
- automatically at midnight to notice the next day's appointments).
- 
- The time must be at the beginning of a line for it to be put in the 
- appointments list.
-               02/23/89
-                  12:00pm    lunch
-                Wednesday
-                  10:00am    group meeting"
-
-  (unless appt-timer
-    (setq appt-timer (run-at-time t 60 'appt-check)))
-  
-  (or global-mode-string (setq global-mode-string '("")))
-  (or (memq 'appt-mode-string global-mode-string)
-      (setq global-mode-string
-	    (append global-mode-string '(appt-mode-string))))
-
-  (let ((n (length (appt-diary-entries))))
-    (cond ((= n 0) (message "no appointments today."))
-	  ((= n 1) (message "1 appointment today."))
-	  (t (message "%d appointments today." n))))
-  )
+(defalias 'appt-initialize 'appt-activate)
+(provide 'appt)
 
+;; arch-tag: bf5791c4-8921-499e-a26f-772b1788d347
 ;;; appt.el ends here
-
Index: cal-china.el
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/calendar/cal-china.el,v
retrieving revision 1.4
diff -u -u -r1.4 cal-china.el
--- cal-china.el	2006/07/31 02:15:22	1.4
+++ cal-china.el	2006/10/20 21:46:44
@@ -1,8 +1,10 @@
 ;;; cal-china.el --- calendar functions for the Chinese calendar
 
-;; Copyright (C) 1995,1997 Free Software Foundation, Inc.
+;; Copyright (C) 1995, 1997, 2001, 2002, 2003, 2004, 2005, 2006
+;;   Free Software Foundation, Inc.
 
 ;; Author: Edward M. Reingold <reingold at cs.uiuc.edu>
+;; Maintainer: Glenn Morris <rgm at gnu.org>
 ;; Keywords: calendar
 ;; Human-Keywords: Chinese calendar, calendar, holidays, diary
 
@@ -20,10 +22,10 @@
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with XEmacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
 
-;;; Synched up with: FSF 21.4
+;;; Synched up with: FSF Emacs 22.1 CVS 2006-09-15
 
 ;;; Commentary:
 
@@ -40,8 +42,8 @@
 ;; The date of Chinese New Year is correct from 1644-2051.
 
 ;; Technical details of all the calendrical calculations can be found in
-;; ``Calendrical Calculations'' by Nachum Dershowitz and Edward M. Reingold,
-;; Cambridge University Press (1997).
+;; ``Calendrical Calculations: The Millennium Edition'' by Edward M. Reingold
+;; and Nachum Dershowitz, Cambridge University Press (2001).
 
 ;; Comments, corrections, and improvements should be sent to
 ;;  Edward M. Reingold               Department of Computer Science
@@ -51,6 +53,10 @@
 
 ;;; Code:
 
+(defvar date)
+(defvar displayed-month)
+(defvar displayed-year)
+
 (require 'lunar)
 
 (defvar chinese-calendar-celestial-stem
@@ -59,7 +65,7 @@
 (defvar chinese-calendar-terrestrial-branch
   ["Zi" "Chou" "Yin" "Mao" "Chen" "Si" "Wu" "Wei" "Shen" "You" "Xu" "Hai"])
 
-(defcustom chinese-calendar-time-zone 
+(defcustom chinese-calendar-time-zone
   '(if (< year 1928)
        (+ 465 (/ 40.0 60.0))
      480)
@@ -500,4 +506,5 @@
 
 (provide 'cal-china)
 
+;;; arch-tag: 7e5b7e0d-676c-47e3-8696-93e7ea0ab644
 ;;; cal-china.el ends here
Index: cal-compat.el
===================================================================
RCS file: cal-compat.el
diff -N cal-compat.el
--- /dev/null	Fri Oct 20 23:46:17 2006
+++ cal-compat.el	Fri Oct 20 23:46:44 2006
@@ -0,0 +1,241 @@
+;;; cal-compat.el --- calendar compatibility functions
+
+;; Author: Jeff Miller <jmiller at xemacs.org>
+
+;; This file is part of XEmacs.
+
+;; XEmacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; XEmacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with XEmacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Synched up with: Not in FSF
+
+;;; Commentary:
+
+;; Provide functional equivalents to code present only in Emacs or
+;; currently only found in XEmacs betas.
+
+;; XEmacs change
+(if (featurep 'xemacs)
+    (defalias 'appt-cancel-timer 'delete-itimer)
+  (defalias 'appt-cancel-timer 'cancel-timer))
+
+;; XEmacs change
+;;;###autoload
+(eval-and-compile
+  (unless (fboundp 'line-beginning-position)
+    (defalias 'line-beginning-position 'point-at-bol))
+  (unless (fboundp 'line-end-position)
+    (defalias 'line-end-position 'point-at-eol)))
+
+;; XEmacs change, mimic button.el from Emacs 22
+;;;###autoload
+(defun make-button (beg end &rest properties)
+  "Make a button from BEG to END in the current buffer.
+The remaining arguments form a sequence of PROPERTY VALUE pairs,
+
+This function is included with calendar for compatability with Emacs."
+  (let ((extent  (make-extent beg end))
+        (map (make-sparse-keymap)))
+
+    (define-key map [button2] 'diary-goto-entry)
+    ;;    (define-key map [return] 'diary-goto-entry)
+    (set-extent-keymap extent map)
+
+    (set-extent-mouse-face extent 'highlight)
+    (set-extent-property extent 'button extent)
+    (set-extent-face extent 'diary-button)
+    ;; set the properties from the calling function
+    (set-extent-properties extent  properties )
+
+    extent ))
+
+;; XEmacs change, mimic button.el from Emacs 22
+;;;###autoload
+(defun insert-button (label &rest properties)
+  "Insert a button with the label LABEL.
+The remaining arguments form a sequence of PROPERTY VALUE pairs.
+
+This function is included with calendar for compatability with Emacs."
+  (apply #'make-button (prog1 (point) (insert label))
+         (point)
+         properties))
+
+;; XEmacs change, this shows up in XEmacs 21.5
+;;;###autoload
+(unless (fboundp 'match-string-no-properties)
+  (defun match-string-no-properties (num &optional string)
+    "Return string of text matched by last search, without text properties.
+NUM specifies which parenthesized expression in the last regexp.
+ Value is nil if NUMth pair didn't match, or there were less than NUM pairs.
+Zero means the entire text matched by the whole regexp or whole string.
+STRING should be given if the last search was by `string-match' on STRING."
+    (if (match-beginning num)
+        (if string
+            (let ((result
+                   (substring string (match-beginning num) (match-end num))))
+              (set-text-properties 0 (length result) nil result)
+              result)
+          (buffer-substring-no-properties (match-beginning num)
+                                          (match-end num))))))
+
+;; XEmacs change, this shows up in XEmacs 21.5
+;;;###autoload
+(unless (fboundp 'add-to-invisibility-spec)
+  (defun add-to-invisibility-spec (arg)
+    "Add elements to `buffer-invisibility-spec'.
+See documentation for `buffer-invisibility-spec' for the kind of elements
+that can be added."
+    (if (eq buffer-invisibility-spec t)
+        (setq buffer-invisibility-spec (list t)))
+    (setq buffer-invisibility-spec
+          (cons arg buffer-invisibility-spec))))
+
+;;;###autoload
+(if (fboundp 'assoc-string)
+    (defalias 'cal-assoc-string 'assoc-string)
+  (defun cal-assoc-string (key list case-fold)
+    (if case-fold
+        (assoc-ignore-case key list)
+      (assoc key list)))  
+  )
+
+;; XEmacs change
+;; not available until 21.5
+  ;;;###autoload
+(unless (fboundp 'display-multi-frame-p)
+  (defun display-multi-frame-p ()
+    (not (null (memq (device-type) '(x mswindows gtk))))
+    ))
+
+;; XEmacs change
+;; not available until 21.5
+;;;###autoload
+(unless (fboundp 'display-color-p)
+  (defun display-color-p ()
+    (eq  'color (device-class))
+    ))
+
+;; XEmacs change
+;; only available in MULE
+(unless (featurep 'mule)
+  (setq enable-multibyte-characters nil))
+
+; propertize appeared in XEmacs subr.el r21-5-7: 1.26
+;;;###autoload
+(unless (fboundp 'propertize)
+  ;; `propertize' is a builtin in GNU Emacs 21.
+  (defun propertize (string &rest properties)
+    "Return a copy of STRING with text properties added.
+First argument is the string to copy.
+Remaining arguments form a sequence of PROPERTY VALUE pairs for text
+properties to add to the result."
+    (let ((str (copy-sequence string)))
+      (add-text-properties 0 (length str)
+                           properties
+                           str)
+      str))
+  )
+
+;; XEmacs change
+;; fit-window-to-buffer is only available in Emacs.
+;; shamelessly taken from ibuffer
+;;;###autoload
+(unless (fboundp 'fit-window-to-buffer)
+  (defun cal-fit-window-to-buffer (&optional owin)
+    "Make window the right size to display its contents exactly."
+    (interactive)
+    (if owin
+	(delete-other-windows))
+    (when (> (length (window-list nil 'nomini)) 1)
+      (let* ((window (selected-window))
+	     (buf (window-buffer window))
+	     (height (window-displayed-height (selected-window)))
+	     (new-height (with-current-buffer buf
+			   (count-lines (point-min) (point-max))))
+	     (diff (- new-height height)))
+	(unless (zerop diff)
+	  (enlarge-window diff))
+	(let ((end (with-current-buffer buf (point-max))))
+	  (while (and (> (length (window-list nil 'nomini)) 1)
+		      (not (pos-visible-in-window-p end)))
+	    (enlarge-window 1)))))))
+
+;; XEmacs change. Mimic remove-overlays from Emacs, but for extents
+;;;###autoload
+(defun cal-remove-extents (&optional beg end name val)   
+  "Clear BEG and END of overlays whose property NAME has value VAL.
+Extents might be moved and or split. "
+  (interactive)
+  ;; Stolen from planner as planner-remove-overlays
+  (if (< end beg)
+      (setq beg (prog1 end (setq end beg))))
+  (save-excursion
+      (dolist (e (extent-list nil  beg end))
+        (when (eq (extent-property e name) val)
+          ;; Either push this overlay outside beg...end
+          ;; or split it to exclude beg...end
+          ;; or delete it entirely (if it is contained in beg...end).
+          (if (< (extent-start-position e) beg)
+              (if (> (extent-end-position e) end)
+                  (progn
+                    (let ((e1  (copy-extent e))
+                          (props (extent-properties e)))
+                      (set-extent-endpoints e1
+                                            (extent-start-position e) beg)
+                      (set-extent-endpoints e end (extent-end-position e))
+                      (while props
+                        (set-extent-property e1 (pop props) (pop props)))))
+                (set-extent-endpoints e (extent-start-position e) beg))
+          (if (> (extent-end-position e) end)
+              (set-extent-endpoints e end (extent-end-position e))
+            (delete-extent e)))))))
+
+;;;###autoload
+(defun cal-tp-ml-conv (string)
+"Used to convert a propertized calendar modeline string to the XEmacs modeline format. 
+If there are any text properties present in the string, it will be split on the text-property 
+boundaries and extents added to the substrings with text properties."
+  (let* ((start 0)
+         (end (length string))
+         (next)
+         (s)
+         (e)
+         (plist)
+         (ml))
+    (while (/= start end)
+      (setq next (next-property-change start string end))
+      (setq s (substring string start next))
+      (setq plist (text-properties-at start string))
+      (if plist (progn
+                  (setq e  (make-extent nil nil))
+                  (set-extent-properties e plist)
+                  (setq ml (append ml (list (cons e s )))))
+        (setq  ml (append ml (list s))))
+      
+      (setq start next))
+    ml))
+
+;; Available in Emacs 22 
+;;;###autoload
+(defun make-mode-line-mouse-map (mouse function) "\
+Return a keymap with single entry for mouse key MOUSE on the mode line.
+MOUSE is defined to run function FUNCTION with no args in the buffer
+corresponding to the mode line clicked."
+  (let ((map (make-sparse-keymap)))
+    (define-key map (vector  mouse) function)
+    map))
+
+
+(provide 'cal-compat)
Index: cal-coptic.el
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/calendar/cal-coptic.el,v
retrieving revision 1.4
diff -u -u -r1.4 cal-coptic.el
--- cal-coptic.el	2006/07/31 02:15:22	1.4
+++ cal-coptic.el	2006/10/20 21:46:44
@@ -1,8 +1,10 @@
 ;;; cal-coptic.el --- calendar functions for the Coptic/Ethiopic calendars
 
-;; Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+;; Copyright (C) 1995, 1997, 2001, 2002, 2003, 2004, 2005, 2006
+;;   Free Software Foundation, Inc.
 
 ;; Author: Edward M. Reingold <reingold at cs.uiuc.edu>
+;; Maintainer: Glenn Morris <rgm at gnu.org>
 ;; Keywords: calendar
 ;; Human-Keywords: Coptic calendar, Ethiopic calendar, calendar, diary
 
@@ -20,10 +22,10 @@
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with XEmacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
 
-;;; Synched up with: FSF 21.4
+;;; Synched up with: FSF Emacs 22.1 CVS 2006-09-15
 
 ;;; Commentary:
 
@@ -31,8 +33,8 @@
 ;; diary.el that deal with the Coptic and Ethiopic calendars.
 
 ;; Technical details of all the calendrical calculations can be found in
-;; ``Calendrical Calculations'' by Nachum Dershowitz and Edward M. Reingold,
-;; Cambridge University Press (1997).
+;; ``Calendrical Calculations: The Millennium Edition'' by Edward M. Reingold
+;; and Nachum Dershowitz, Cambridge University Press (2001).
 
 ;; Comments, corrections, and improvements should be sent to
 ;;  Edward M. Reingold               Department of Computer Science
@@ -42,6 +44,8 @@
 
 ;;; Code:
 
+(defvar date)
+
 (require 'cal-julian)
 
 (defvar coptic-calendar-month-name-array
@@ -51,7 +55,7 @@
 (defvar coptic-calendar-epoch (calendar-absolute-from-julian '(8 29 284))
   "Absolute date of start of Coptic calendar = August 29, 284 A.D. (Julian).")
 
-(defconst coptic-name "Coptic")
+(defvar coptic-name "Coptic")
 
 (defun coptic-calendar-leap-year-p (year)
   "True if YEAR is a leap year on the Coptic calendar."
@@ -79,7 +83,7 @@
        (/ year 4)                ;; Leap days in prior years
        (* 30 (1- month))         ;; Days in prior months this year
        day)))                    ;; Days so far this month
-       
+
 
 (defun calendar-coptic-from-absolute (date)
   "Compute the Coptic equivalent for absolute date DATE.
@@ -153,14 +157,15 @@
                   (calendar-coptic-from-absolute
                    (calendar-absolute-from-gregorian today))))))
          (completion-ignore-case t)
-         (month (cdr (assoc-ignore-case
-                       (completing-read
-                        (format "%s calendar month name: " coptic-name)
-                        (mapcar 'list
-                                (append coptic-calendar-month-name-array nil))
-                        nil t)
+         ;; XEmacs change, we don't have assoc-string
+         (month (cdr (cal-assoc-ignore
+                      (completing-read
+                       (format "%s calendar month name: " coptic-name)
+                       (mapcar 'list
+                               (append coptic-calendar-month-name-array nil))
+                       nil t)
                       (calendar-make-alist coptic-calendar-month-name-array
-                                           1))))
+                                           1) t)))
          (last (coptic-calendar-last-day-of-month month year))
          (day (calendar-read
                (format "%s calendar day (1-%d): " coptic-name last)
@@ -236,4 +241,5 @@
 
 (provide 'cal-coptic)
 
+;;; arch-tag: 72d49161-25df-4072-9312-b182cdca7627
 ;;; cal-coptic.el ends here
Index: cal-dst.el
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/calendar/cal-dst.el,v
retrieving revision 1.5
diff -u -u -r1.5 cal-dst.el
--- cal-dst.el	2006/07/31 02:15:22	1.5
+++ cal-dst.el	2006/10/20 21:46:44
@@ -1,9 +1,11 @@
 ;;; cal-dst.el --- calendar functions for daylight savings rules
 
-;; Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+;; Copyright (C) 1993, 1994, 1995, 1996, 2001, 2002, 2003, 2004, 2005,
+;;   2006  Free Software Foundation, Inc.
 
 ;; Author: Paul Eggert <eggert at twinsun.com>
 ;;	Edward M. Reingold <reingold at cs.uiuc.edu>
+;; Maintainer: Glenn Morris <rgm at gnu.org>
 ;; Keywords: calendar
 ;; Human-Keywords: daylight savings time, calendar, diary, holidays
 
@@ -21,10 +23,10 @@
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with XEmacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
 
-;;; Synched up with: FSF 21.4
+;;; Synched up with: FSF Emacs 22.1 CVS 2006-09-15
 
 ;;; Commentary:
 
@@ -72,14 +74,14 @@
 (defun calendar-time-from-absolute (abs-date s)
   "Time of absolute date ABS-DATE, S seconds after midnight.
 
-Returns the pair (HIGH . LOW) where HIGH and LOW are the high and low
+Returns the list (HIGH LOW) where HIGH and LOW are the high and low
 16 bits, respectively, of the number of seconds 1970-01-01 00:00:00 UTC,
 ignoring leap seconds, that is the equivalent moment to S seconds after
 midnight UTC on absolute date ABS-DATE."
   (let* ((a (- abs-date calendar-system-time-basis))
          (u (+ (* 163 (mod a 512)) (floor s 128))))
     ;; Overflow is a terrible thing!
-    (cons
+    (list
      ;; floor((60*60*24*a + s) / 2^16)
      (+ a (* 163 (floor a 512)) (floor u 512))
      ;; (60*60*24*a + s) mod 2^16
@@ -156,16 +158,16 @@
 		      (cons
 		       (list 'calendar-nth-named-day 1 weekday m 'year j)
 		       l)))
-            l)
-          ;; 01-01 and 07-01 for this year's Persian calendar.
-          (if (and (= m 3) (<= 20 d) (<= d 21))
-              '((calendar-gregorian-from-absolute
-                 (calendar-absolute-from-persian
-                  (list 1 1 (- year 621))))))
-          (if (and (= m 9) (<= 22 d) (<= d 23))
-              '((calendar-gregorian-from-absolute
-                 (calendar-absolute-from-persian
-                  (list 7 1 (- year 621))))))))
+	     l)
+	   ;; 01-01 and 07-01 for this year's Persian calendar.
+	   (if (and (= m 3) (<= 20 d) (<= d 21))
+	       '((calendar-gregorian-from-absolute
+		  (calendar-absolute-from-persian
+		   (list 1 1 (- year 621))))))
+	   (if (and (= m 9) (<= 22 d) (<= d 23))
+	       '((calendar-gregorian-from-absolute
+		  (calendar-absolute-from-persian
+		   (list 7 1 (- year 621))))))))
 	 (prevday-sec (- -1 utc-diff)) ;; last sec of previous local day
 	 (year (1+ y)))
     ;; Scan through the next few years until only one rule remains.
@@ -280,7 +282,7 @@
 (defvar calendar-daylight-time-offset
   (or (car (cdr calendar-current-time-zone-cache)) 60)
   "*Number of minutes difference between daylight savings and standard time.
-  
+
 If the locale never uses daylight savings time, set this to 0.")
 
 (defvar calendar-standard-time-zone-name
@@ -292,7 +294,7 @@
   (or (car (nthcdr 3 calendar-current-time-zone-cache)) "EDT")
   "*Abbreviated name of daylight-savings time zone at `calendar-location-name'.
 For example, \"EDT\" in New York City, \"PDT\" for Los Angeles.")
-  
+
 ;;;###autoload
 (put 'calendar-daylight-savings-starts 'risky-local-variable t)
 (defvar calendar-daylight-savings-starts
@@ -333,11 +335,11 @@
       '(calendar-nth-named-day -1 0 10 year)
 
 If the locale never uses daylight savings time, set this to nil.")
-  
+
 (defvar calendar-daylight-savings-starts-time
   (or (car (nthcdr 6 calendar-current-time-zone-cache)) 120)
   "*Number of minutes after midnight that daylight savings time starts.")
-  
+
 (defvar calendar-daylight-savings-ends-time
   (or (car (nthcdr 7 calendar-current-time-zone-cache))
       calendar-daylight-savings-starts-time)
@@ -383,17 +385,18 @@
 `calendar-daylight-savings-offset'."
 
   (let* ((rounded-abs-date (+ (calendar-absolute-from-gregorian date)
-                             (/ (round (* 60 time)) 60.0 24.0)))
+			      (/ (round (* 60 time)) 60.0 24.0)))
          (dst (dst-in-effect rounded-abs-date))
-        (time-zone (if dst
-                       calendar-daylight-time-zone-name
-                       calendar-standard-time-zone-name))
-        (time (+ rounded-abs-date
+	 (time-zone (if dst
+			calendar-daylight-time-zone-name
+			calendar-standard-time-zone-name))
+	 (time (+ rounded-abs-date
                   (if dst (/ calendar-daylight-time-offset 24.0 60.0) 0))))
     (list (calendar-gregorian-from-absolute (truncate time))
           (* 24.0 (- time (truncate time)))
           time-zone)))
- 
+
 (provide 'cal-dst)
 
+;;; arch-tag: a141d204-213c-4ca5-bdc6-f9df3aa92aad
 ;;; cal-dst.el ends here
Index: cal-french.el
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/calendar/cal-french.el,v
retrieving revision 1.4
diff -u -u -r1.4 cal-french.el
--- cal-french.el	2006/07/31 02:15:22	1.4
+++ cal-french.el	2006/10/20 21:46:44
@@ -1,8 +1,10 @@
 ;;; cal-french.el --- calendar functions for the French Revolutionary calendar
 
-;; Copyright (C) 1988, 89, 92, 94, 95, 1997 Free Software Foundation, Inc.
+;; Copyright (C) 1988, 1989, 1992, 1994, 1995, 1997, 2001, 2002, 2003,
+;;   2004, 2005, 2006  Free Software Foundation, Inc.
 
 ;; Author: Edward M. Reingold <reingold at cs.uiuc.edu>
+;; Maintainer: Glenn Morris <rgm at gnu.org>
 ;; Keywords: calendar
 ;; Human-Keywords: French Revolutionary calendar, calendar, diary
 
@@ -20,18 +22,18 @@
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with XEmacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
 
-;;; Synched up with: FSF 21.4
+;;; Synched up with: FSF Emacs 22.1 CVS 2006-09-15
 ;;; Commentary:
 
 ;; This collection of functions implements the features of calendar.el and
 ;; diary.el that deal with the French Revolutionary calendar.
 
 ;; Technical details of the French Revolutionary calendar can be found in
-;; ``Calendrical Calculations'' by Nachum Dershowitz and Edward M. Reingold,
-;; Cambridge University Press (1997), and in
+;; ``Calendrical Calculations: The Millennium Edition'' by Edward M. Reingold
+;; and Nachum Dershowitz, Cambridge University Press (2001), and in
 ;; ``Calendrical Calculations, Part II: Three Historical Calendars'' by
 ;; E. M. Reingold, N. Dershowitz, and S. M. Clamen, Software--Practice and
 ;; Experience, Volume 23, Number 4 (April, 1993), pages 383-404.
@@ -44,6 +46,8 @@
 
 ;;; Code:
 
+(defvar date)
+
 (require 'calendar)
 
 (defun french-calendar-accents ()
@@ -177,17 +181,17 @@
     (cond
      ((< y 1) "")
      ((= m 13) (format (if (french-calendar-accents)
-			   "Jour %s de l'Année %d de la Révolution"
-			 "Jour %s de l'Anne'e %d de la Re'volution")
-		       (aref (french-calendar-special-days-array) (1- d))
-			     y))
-     (t (format 
-	 (if (french-calendar-accents)
+                           "Jour %s de l'Année %d de la Révolution"
+                         "Jour %s de l'Anne'e %d de la Re'volution")
+                       (aref (french-calendar-special-days-array) (1- d))
+                       y))
+     (t (format
+         (if (french-calendar-accents)
              "%d %s an %d de la Révolution"
            "%d %s an %d de la Re'volution")
          d
          (aref (french-calendar-month-name-array) (1- m))
-	 y)))))
+         y)))))
 
 (defun calendar-print-french-date ()
   "Show the French Revolutionary calendar equivalent of the selected date."
@@ -202,48 +206,49 @@
 Echo French Revolutionary date unless NOECHO is t."
   (interactive
    (let ((accents (french-calendar-accents))
-        (months (french-calendar-month-name-array))
-        (special-days (french-calendar-special-days-array)))
+	 (months (french-calendar-month-name-array))
+	 (special-days (french-calendar-special-days-array)))
      (let* ((year
 	     (progn
 	       (calendar-read
 		(if accents
-		    "Année de la Révolution (>0): "
-                  "Anne'e de la Re'volution (>0): ")
+	            "Année de la Révolution (>0): "
+		   "Anne'e de la Re'volution (>0): ")
 		'(lambda (x) (> x 0))
 		(int-to-string
 		 (extract-calendar-year
 		  (calendar-french-from-absolute
 		   (calendar-absolute-from-gregorian
 		    (calendar-current-date))))))))
-	     (month-list
-	      (mapcar 'list
-		      (append months
-                           (if (french-calendar-leap-year-p year)
-                               (mapcar
-                                '(lambda (x) (concat "Jour " x))
-                                french-calendar-special-days-array)
-                             (reverse
-                              (cdr;; we don't want rev. day in a non-leap yr.
-                               (reverse
-                                (mapcar
-                                 '(lambda (x) 
-				    (concat "Jour " x))
-                                 special-days))))))))
-          (completion-ignore-case t)
-          (month (cdr (assoc-ignore-case
-                        (completing-read
-                         "Mois ou Sansculottide: "
-                         month-list
-                         nil t)
-			(calendar-make-alist month-list 1 'car))))
-          (day (if (> month 12)
-                   (- month 12)
-                 (calendar-read
-                  "Jour (1-30): "
-                   '(lambda (x) (and (<= 1 x) (<= x 30))))))
-           (month (if (> month 12) 13 month)))
-      (list (list month day year)))))
+	    (month-list
+	     (mapcar 'list
+		     (append months
+			     (if (french-calendar-leap-year-p year)
+				 (mapcar
+				  '(lambda (x) (concat "Jour " x))
+				  french-calendar-special-days-array)
+			       (reverse
+				(cdr;; we don't want rev. day in a non-leap yr.
+				 (reverse
+				  (mapcar
+				   '(lambda (x)
+				      (concat "Jour " x))
+				   special-days))))))))
+	    (completion-ignore-case t)
+            ;; XEmacs change, we don't have assoc-string
+	    (month (cdr (cal-assoc-string
+                         (completing-read
+                          "Mois ou Sansculottide: "
+                          month-list
+                          nil t)
+			 (calendar-make-alist month-list 1 'car) t)))
+	    (day (if (> month 12)
+		     (- month 12)
+		   (calendar-read
+		    "Jour (1-30): "
+		    '(lambda (x) (and (<= 1 x) (<= x 30))))))
+	    (month (if (> month 12) 13 month)))
+       (list (list month day year)))))
   (calendar-goto-date (calendar-gregorian-from-absolute
                        (calendar-absolute-from-french date)))
   (or noecho (calendar-print-french-date)))
@@ -257,4 +262,5 @@
 
 (provide '