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))))))