Function: icalendar-parse-component

icalendar-parse-component is a byte-compiled function defined in icalendar-parser.el.gz.

Signature

(icalendar-parse-component LIMIT)

Documentation

Parse an iCalendar component from point up to LIMIT.

Point should be at the start of the component, i.e., at the start of a line that looks like "BEGIN:[COMPONENT-NAME]". After parsing, point is at the beginning of the next line following the component
(or end of the buffer). Returns a syntax node representing the component.

Source Code

;; Defined in /usr/src/emacs/lisp/calendar/icalendar-parser.el.gz
(defun ical:parse-component (limit)
  "Parse an iCalendar component from point up to LIMIT.
Point should be at the start of the component, i.e., at the start
of a line that looks like \"BEGIN:[COMPONENT-NAME]\".  After parsing,
point is at the beginning of the next line following the component
\(or end of the buffer).  Returns a syntax node representing the component."
  (let ((begin-pos nil)
        (body-begin-pos nil)
        (end-pos nil)
        (body-end-pos nil)
        (begin-regex (rx line-start "BEGIN:" (group-n 2 ical:name) line-end)))

    (unless (re-search-forward begin-regex limit t)
      (ical:signal-parse-error "Not at start of a component"))

    (setq begin-pos (match-beginning 0)
          body-begin-pos (1+ (match-end 0))) ; start of next line

    (let* ((component-name (match-string 2))
           (known-type (alist-get (upcase component-name)
                                  ical:component-types
                                  nil nil #'equal))
           (component-type (or known-type 'ical:other-component))
           child children)

      ;; Find end of component:
      (save-excursion
        (if (re-search-forward (concat "^END:" component-name "$") limit t)
            (setq end-pos (match-end 0)
                  body-end-pos (1- (match-beginning 0))) ; end of prev. line
          (ical:signal-parse-error
           (format  "Matching 'END:%s' not found between %d and %d"
                    component-name begin-pos limit)
           :restart-at (1+ limit))))

      (while (not (bolp))
        (forward-char))

      ;; Parse the properties and subcomponents of this component:
      (while (<= (point) body-end-pos)
        (condition-case err
            (setq child (ical:parse-property-or-component end-pos))
          (ical:parse-error
           (ical:handle-parse-error err)
           (setq child nil)))
        (when child (push child children)))

      ;; Set point up for the next parser:
      (goto-char end-pos)
      (while (and (< (point) (point-max)) (not (bolp)))
        (forward-char))

      ;; Return the syntax node for the component:
      (when children
        (ical:make-ast-node component-type
                            (list
                             :original-name
                             (when (eq component-type 'ical:other-component)
                               component-name)
                             :buffer (current-buffer)
                             :begin begin-pos
                             :end end-pos
                             :value-begin body-begin-pos
                             :value-end body-end-pos)
                            (nreverse children))))))