Function: diary-icalendar-format-entry
diary-icalendar-format-entry is a byte-compiled function defined in
diary-icalendar.el.gz.
Signature
(diary-icalendar-format-entry COMPONENT INDEX &optional NONMARKING)
Documentation
Format an iCalendar component for the diary.
COMPONENT should be an icalendar-vevent, icalendar-vtodo, or
icalendar-vjournal. INDEX should be an index into the calendar where
COMPONENT occurs, as returned by icalendar-parse-and-index.
Depending on the type of COMPONENT, the body will be formatted by one of:
diary-icalendar-vevent-format-function
diary-icalendar-vtodo-format-function
diary-icalendar-vjournal-format-function
which see.
The variable ical-nonmarking will be bound to the value of NONMARKING in
the relevant skeleton command. If it is non-nil, the user requested the
entry to be nonmarking.
Returns a string containing the diary entry.
Source Code
;; Defined in /usr/src/emacs/lisp/calendar/diary-icalendar.el.gz
;; This function puts all of the above together to format individual
;; iCalendar components as diary entries. The final formatting is done
;; by the appropriate skeleton command for the component, or by
;; `di:-format-vevent-legacy' if the legacy format string variables from
;; icalendar.el are set.
(defun di:format-entry (component index &optional nonmarking)
"Format an iCalendar component for the diary.
COMPONENT should be an `icalendar-vevent', `icalendar-vtodo', or
`icalendar-vjournal'. INDEX should be an index into the calendar where
COMPONENT occurs, as returned by `icalendar-parse-and-index'.
Depending on the type of COMPONENT, the body will be formatted by one of:
`diary-icalendar-vevent-format-function'
`diary-icalendar-vtodo-format-function'
`diary-icalendar-vjournal-format-function'
which see.
The variable `ical-nonmarking' will be bound to the value of NONMARKING in
the relevant skeleton command. If it is non-nil, the user requested the
entry to be nonmarking.
Returns a string containing the diary entry."
(ical:with-component component
((ical:attach :all attach-nodes)
(ical:attendee :all attendee-nodes)
(ical:categories :all categories-nodes)
(ical:class :value access)
(ical:comment :all comment-nodes)
(ical:completed :value completed-dt)
(ical:contact :all contact-nodes)
(ical:description :value description)
;; in `icalendar-vjournal', multiple `icalendar-description'
;; nodes are allowed:
(ical:description :all description-nodes)
(ical:dtend :first dtend-node :value dtend)
(ical:dtstart :first dtstart-node :value dtstart)
(ical:duration :value duration)
(ical:due :first due-node :value due-dt)
(ical:geo :value geo)
(ical:location :value location)
(ical:organizer :first organizer-node ; for skeleton formatting
:value organizer-addr) ; for legacy formatting
(ical:percent-complete :value percent-complete)
(ical:priority :value priority)
(ical:rrule :value rrule)
(ical:rdate :all rdate-nodes)
(ical:status :value status)
(ical:summary :value summary)
(ical:transp :value transp)
(ical:uid :value uid)
(ical:url :value url))
(let* ((is-recurring (or rdate-nodes rrule))
(start-tz (when dtstart-node
(ical:with-property dtstart-node
((ical:tzidparam :value tzid))
(when tzid (ical:index-get index :tzid tzid)))))
(start-tzname (when start-tz (icr:tzname-on dtstart start-tz)))
(dtstart-local (ical:date/time-to-local dtstart))
(due-tz (when due-node
(ical:with-property due-node
((ical:tzidparam :value tzid))
(when tzid (ical:index-get index :tzid tzid)))))
(due-tzname (when due-tz (icr:tzname-on due-dt due-tz)))
(dtend
(cond (dtend dtend)
;; DTEND and DUE never occur in the same component,
;; so we alias dtend to due:
(due-dt due-dt)
(duration
(ical:date/time-add-duration dtstart duration start-tz))))
(dtend-local (ical:date/time-to-local dtend))
(end-tz
(cond (dtend-node
(ical:with-property dtend-node
((ical:tzidparam :value tzid))
(when tzid (ical:index-get index :tzid tzid))))
(due-node due-tz)
(duration start-tz)))
(end-tzname (when end-tz (icr:tzname-on dtend end-tz)))
(component-type (ical:ast-node-type component)))
(dlet
;; We use "ical-" rather than "icalendar-" as prefix for these
;; vars because (a) it's shorter and (b) to avoid shadowing
;; any library symbols:
((ical-attachments
(when attach-nodes
(di:save-attachments-from attach-nodes uid)))
(ical-attendees (mapcar #'di:format-attendee attendee-nodes))
(ical-categories
(mapcan
(lambda (node)
(mapcar #'ical:text-to-string (ical:ast-node-value node)))
categories-nodes))
(ical-access (when access (downcase access)))
(ical-comments
(mapcar
(lambda (node) (ical:text-to-string (ical:ast-node-value node)))
comment-nodes))
(ical-contacts
(mapcar
(lambda (node) (ical:text-to-string (ical:ast-node-value node)))
contact-nodes))
(ical-completed
(when completed-dt (di:format-date/time-as-local completed-dt)))
(ical-description
(if (eq 'icalendar-vjournal component-type)
(mapconcat
(lambda (node)
(ical:trimp (ical:text-to-string (ical:ast-node-value node))))
description-nodes
"\n\n")
(ical:trimp description)))
(ical-start
(when dtstart
(if (bound-and-true-p ical-importing)
(di:format-date/time-as-local dtstart start-tzname)
(di:format-time-as-local dtstart start-tzname))))
(ical-end
(when dtend
(if (bound-and-true-p ical-importing)
(di:format-date/time-as-local dtend end-tzname)
(di:format-time-as-local dtend end-tzname))))
(ical-start-to-end
(with-suppressed-warnings ((lexical date) (free-vars date))
(cond
((not dtstart) nil)
((or (not dtend) (equal dtstart dtend))
;; without a distinct DTEND/DUE, same as start:
(if (bound-and-true-p ical-importing)
(di:format-date/time-as-local dtstart start-tzname)
(di:format-time-as-local dtstart start-tzname)))
((and (bound-and-true-p ical-importing)
(cl-typep dtstart 'ical:date)
(cl-typep dtend 'ical:date))
;; Importing two dates:
;; %%(diary-block ...)
(di:format-block-sexp
dtstart
;; DTEND is an exclusive bound, while
;; diary-block needs an inclusive bound, so
;; subtract a day:
(ical:date-add dtend :day -1)))
((and (bound-and-true-p ical-importing)
(equal (ical:date/time-to-date dtstart-local)
(ical:date/time-to-date dtend-local)))
;; Importing, start and end times on same day:
;; DATE HH:MM-HH:MM
(di:format-time-range dtstart-local dtend-local))
((bound-and-true-p ical-importing)
;; Importing at least one date-time, on different days:
;; %%(diary-time-block :start ... :end ...)
(di:format-time-block-sexp dtstart-local dtend-local))
((and (boundp 'date) ; bound when displaying diary
(cl-typep dtstart-local 'ical:date-time)
(cl-typep dtend-local 'ical:date-time)
(equal date (ical:date-time-to-date dtstart-local))
(equal date (ical:date-time-to-date dtend-local)))
;; Displaying, start and end times on the day displayed:
;; HH:MM-HH:MM
(di:format-time-range dtstart-local dtend-local t))
((and (boundp 'date) ; bound when displaying diary
(cl-typep dtstart-local 'ical:date-time)
(cl-typep dtend-local 'ical:date-time))
;; Displaying, start and/or end time on other days:
;; HH:MM-HH:MM for just the times on `date'
(di:format-time-range
(ical:date/time-max dtstart-local
(ical:make-date-time
:year (calendar-extract-year date)
:month (calendar-extract-month date)
:day (calendar-extract-day date)
:hour 0 :minute 0 :second 0
:zone
(decoded-time-zone dtstart-local)))
(ical:date/time-min dtend-local
(ical:make-date-time
:year (calendar-extract-year date)
:month (calendar-extract-month date)
:day (calendar-extract-day date)
:hour 23 :minute 59 :second 59
:zone
(decoded-time-zone dtend-local)))))
(t
;; That's all the cases we care about here.
nil))))
(ical-due
(when (eq component-type 'ical:vtodo)
(if due-node
(di:format-date/time-as-local due-dt due-tzname)
;; here we use start-tzname because due/dtend is calculated from
;; dtstart, not its own node with a tzid:
(di:format-date/time-as-local dtend start-tzname))))
(ical-work-time-sexp
(when (and dtstart due-dt (bound-and-true-p ical-importing))
(di:format-time-block-sexp dtstart-local due-dt)))
(ical-importing (bound-and-true-p ical-importing))
(ical-location (or (ical:trimp location)
(when geo (di:format-geo-coordinates geo))))
(ical-nonmarking nonmarking)
(ical-organizer (di:format-attendee organizer-node))
(ical-percent-complete percent-complete)
(ical-priority priority)
(ical-rrule-sexp
(when (and is-recurring (bound-and-true-p ical-importing))
(di:format-rrule-sexp component)))
(ical-status (when status (ical:trimp (downcase status))))
(ical-summary (ical:trimp summary))
(ical-transparency transp)
(ical-uid (ical:trimp uid))
(ical-url (ical:trimp url)))
(with-temp-buffer
(cl-case (ical:ast-node-type component)
(ical:vevent
(with-suppressed-warnings
((obsolete ical:import-format
di:-use-legacy-vars-p
di:-vevent-to-legacy-alist
di:-format-vevent-legacy))
;; N.B. icalendar.el *only* imported VEVENT components
(if (di:-use-legacy-vars-p)
(if (functionp ical:import-format)
(insert (funcall ical:import-format
(di:-vevent-to-legacy-alist component)))
(di:-format-vevent-legacy (or ical-rrule-sexp
ical-start-to-end
ical-start)
ical-access ical-description
ical-location organizer-addr
ical-summary ical-status
ical-url ical-uid))
(funcall di:vevent-format-function component))))
(ical:vtodo (funcall di:vtodo-format-function component))
(ical:vjournal (funcall di:vjournal-format-function component)))
(buffer-string))))))