Function: icalendar-index-insert
icalendar-index-insert is a byte-compiled function defined in
icalendar-parser.el.gz.
Signature
(icalendar-index-insert INDEX COMPONENT)
Documentation
Insert COMPONENT into INDEX.
Source Code
;; Defined in /usr/src/emacs/lisp/calendar/icalendar-parser.el.gz
(defun ical:index-insert (index component)
"Insert COMPONENT into INDEX."
(require 'icalendar-recur) ; avoid circular imports
(require 'icalendar-utils) ;
(declare-function icr:recurrences-to-count "icalendar-recur")
(declare-function ical:date/time-to-local "icalendar-utils")
(declare-function ical:date/time-to-date "icalendar-utils")
(declare-function ical:dates-until "icalendar-utils")
(ical:with-component component
((ical:dtstart :first dtstart-node :value dtstart)
(ical:dtend :first dtend-node :value dtend)
(ical:due :value due)
(ical:duration :value duration)
(ical:rrule :value rrule)
(ical:rdate :all rdate-nodes)
(ical:exdate :all exdate-nodes)
(ical:uid :value uid))
(let ((date-index (plist-get index :bydate))
(uid-index (plist-get index :byuid))
(tzid-index (plist-get index :bytzid))
(recurring (plist-get index :recurring))
(rdates
(mapcar #'ical:ast-node-value
(apply #'append (mapcar #'ical:ast-node-value rdate-nodes))))
(exdates
(mapcar #'ical:ast-node-value
(apply #'append (mapcar #'ical:ast-node-value exdate-nodes))))
dates)
;; Everything with a UID goes into the uid-index:
(when uid
(puthash uid component uid-index))
;; For all top-level components, we gather a list of dates on which
;; they recur for date-index, or put them in the recurring list:
(when dtstart
(cond
;; If the component has an RRULE that specifies a fixed number
;; of recurrences, compute them now and index them for each date
;; in each recurrence:
((and rrule (ical:rrule-count rrule))
(let* ((tz (gethash (ical:with-param-of dtstart-node 'ical:tzidparam)
tzid-index))
(recs (cons dtstart (icr:recurrences-to-count component tz))))
(dolist (rec recs)
(let ((end-time
(when duration (ical:date/time-add-duration rec duration))))
(setq dates
(append dates
(if end-time (ical:dates-until rec end-time t)
(list (ical:date/time-to-date
(ical:date/time-to-local rec))))))))))
;; Same with RDATEs when there's no RRULE:
((and rdates (not rrule))
(dolist (rec (cons dtstart rdates))
(unless (or (cl-typep rec 'ical:period) (member rec exdates))
(let ((end-time
(when duration
(ical:date/time-add-duration rec duration))))
(setq dates
(append dates
(if end-time (ical:dates-until rec end-time t)
(list (ical:date/time-to-date
(ical:date/time-to-local rec))))))))
(when (cl-typep rec 'ical:period)
(let* ((start (ical:period-start rec))
(end (or (ical:period-end rec)
(ical:date/time-add-duration
start (ical:period-dur-value rec)))))
(setq dates (append dates (ical:dates-until start end t)))))))
;; A non-recurring event also gets an index entry for each date
;; until its end time:
((not rrule)
(let ((end-time
(or dtend due
(when duration
(ical:date/time-add-duration dtstart duration)))))
(setq dates (if end-time (ical:dates-until dtstart end-time t)
(list
(ical:date/time-to-date
(ical:date/time-to-local dtstart)))))))
;; Otherwise, we put off the computation of recurrences until queried:
(t (push component recurring)))
(dolist (date (seq-uniq dates))
(let ((others (gethash date date-index)))
;; TODO: wonder if we should normalize, and instead store UIDs
;; in the date index, then look them up by UID when queried.
(puthash date (cons component others) date-index))))
;; Return the updated index:
(setq index (plist-put index :byuid uid-index))
(setq index (plist-put index :bytzid tzid-index))
(setq index (plist-put index :bydate date-index))
(setq index (plist-put index :recurring recurring))
index)))