Function: icalendar-make-node-from-templates

icalendar-make-node-from-templates is a macro defined in icalendar-ast.el.gz.

Signature

(icalendar-make-node-from-templates TYPE &rest TEMPLATES)

Documentation

Construct an iCalendar syntax node of TYPE from TEMPLATES.

TYPE should be an iCalendar type symbol; it should not be quoted. This macro (and the derived macros icalendar-make-vcalendar, icalendar-make-vevent, icalendar-make-vtodo, icalendar-make-vjournal, icalendar-make-vfreebusy, icalendar-make-valarm, icalendar-make-vtimezone, icalendar-make-standard, and icalendar-make-daylight) makes it easy to write iCalendar syntax nodes of TYPE as Lisp code.

Each expression in TEMPLATES represents a child node of the constructed node. It must either evaluate to such a node, or it must have one of the following forms:

(VALUE-TYPE VALUE) - constructs a node of VALUE-TYPE containing the
  value VALUE.

(PARAM-TYPE VALUE) - constructs a parameter node of PARAM-TYPE
  containing the VALUE.

(PROPERTY-TYPE VALUE [PARAM ...]) - constructs a property node of
  PROPERTY-TYPE containing the value VALUE and PARAMs as child
  nodes. Each PARAM should be a template (PARAM-TYPE VALUE), as above,
  or any other expression that evaluates to a parameter node.

(COMPONENT-TYPE CHILD [CHILD ...]) - constructs a component node of
  COMPONENT-TYPE with given child nodes. Each CHILD should either be
  a template for a property (as above), a template for a
  sub-component (of the same form), or any other expression that
  evaluates to an iCalendar syntax node.

If TYPE is an iCalendar component or property type, a TEMPLATE can also have the form (@ L), where L evaluates to a list of child nodes to be added to the component or property node.

For example, an iCalendar VEVENT could be written like this:

  (icalendar-make-node-from-templates icalendar-vevent
    (icalendar-uid "some-unique-id")
    (icalendar-summary "Party")
    (icalendar-location "Robot House")
    (icalendar-organizer "mailto:bender@mars.edu")
    (icalendar-attendee "mailto:philip.j.fry@mars.edu"
      (icalendar-partstatparam "ACCEPTED"))
    (icalendar-attendee "mailto:gunther@mars.edu"
      (icalendar-partstatparam "DECLINED"))
    (icalendar-categories (list "MISCHIEF" "DOUBLE SECRET PROBATION"))
    (icalendar-dtstart (icalendar-make-date-time :year 3003 :month 3 :day 13
                                                 :hour 22 :minute 0 :second 0)
       (icalendar-tzidparam "Mars/University_Time")))

Before the constructed node is returned, it is validated by icalendar-ast-node-valid-p.

Source Code

;; Defined in /usr/src/emacs/lisp/calendar/icalendar-ast.el.gz
;; TODO: allow disabling the validity check??
(defmacro ical:make-node-from-templates (type &rest templates)
  "Construct an iCalendar syntax node of TYPE from TEMPLATES.

TYPE should be an iCalendar type symbol; it should not be quoted.  This
macro (and the derived macros `icalendar-make-vcalendar',
`icalendar-make-vevent', `icalendar-make-vtodo',
`icalendar-make-vjournal', `icalendar-make-vfreebusy',
`icalendar-make-valarm', `icalendar-make-vtimezone',
`icalendar-make-standard', and `icalendar-make-daylight') makes it easy
to write iCalendar syntax nodes of TYPE as Lisp code.

Each expression in TEMPLATES represents a child node of the constructed
node.  It must either evaluate to such a node, or it must have one of
the following forms:

\(VALUE-TYPE VALUE) - constructs a node of VALUE-TYPE containing the
  value VALUE.

\(PARAM-TYPE VALUE) - constructs a parameter node of PARAM-TYPE
  containing the VALUE.

\(PROPERTY-TYPE VALUE [PARAM ...]) - constructs a property node of
  PROPERTY-TYPE containing the value VALUE and PARAMs as child
  nodes.  Each PARAM should be a template (PARAM-TYPE VALUE), as above,
  or any other expression that evaluates to a parameter node.

\(COMPONENT-TYPE CHILD [CHILD ...]) - constructs a component node of
  COMPONENT-TYPE with given child nodes.  Each CHILD should either be
  a template for a property (as above), a template for a
  sub-component (of the same form), or any other expression that
  evaluates to an iCalendar syntax node.

If TYPE is an iCalendar component or property type, a TEMPLATE can also
have the form (@ L), where L evaluates to a list of child nodes to be
added to the component or property node.

For example, an iCalendar VEVENT could be written like this:

  (icalendar-make-node-from-templates icalendar-vevent
    (icalendar-uid \"some-unique-id\")
    (icalendar-summary \"Party\")
    (icalendar-location \"Robot House\")
    (icalendar-organizer \"mailto:bender@mars.edu\")
    (icalendar-attendee  \"mailto:philip.j.fry@mars.edu\"
      (icalendar-partstatparam \"ACCEPTED\"))
    (icalendar-attendee  \"mailto:gunther@mars.edu\"
      (icalendar-partstatparam \"DECLINED\"))
    (icalendar-categories (list \"MISCHIEF\" \"DOUBLE SECRET PROBATION\"))
    (icalendar-dtstart (icalendar-make-date-time :year 3003 :month 3 :day 13
                                                 :hour 22 :minute 0 :second 0)
       (icalendar-tzidparam \"Mars/University_Time\")))

Before the constructed node is returned, it is validated by
`icalendar-ast-node-valid-p'."
  (declare (debug (symbolp &rest form))
           (indent 1))
  (cond
   ((not (ical:type-symbol-p type))
    (error "Not an iCalendar type symbol: %s" type))
   ((ical:value-type-symbol-p type)
    `(ical:ast-node-valid-p
      (ical:make-value-node-of (quote ,type) ,(car templates))))
   ((ical:param-type-symbol-p type)
    `(ical:make-param ,type ,(car templates)))
   ((ical:property-type-symbol-p type)
    `(ical:make-property ,type ,(car templates) ,@(cdr templates)))
   ((ical:component-type-symbol-p type)
    `(ical:make-component ,type ,@templates))))