Function: icalendar-define-type
icalendar-define-type is a macro defined in icalendar-macs.el.gz.
Signature
(icalendar-define-type SYMBOLIC-NAME PRINT-NAME DOC SPECIFIER MATCHER &key LINK (READER #'identity) (PRINTER #'identity))
Documentation
Define an iCalendar value type named SYMBOLIC-NAME.
PRINT-NAME should be the string used to represent this type in
the value of an icalendar-valuetypeparam property parameter, or
nil if this is not a type that should be specified there. DOC
should be a documentation string for the type. SPECIFIER should
be a type specifier in the sense of cl-deftype. MATCHER should
be an RX definition body (see rx-define; argument lists are not
supported).
Before the type is defined with cl-deftype, a function will be
defined named icalendar-match-PRINT-NAME-value
(or icalendar-match-OTHER-value, if PRINT-NAME is nil, where
OTHER is derived from SYMBOLIC-NAME by removing any prefix
"icalendar-" and suffix "value"). This function takes a
string argument and matches it against MATCHER. This function may
thus occur in SPECIFIER (e.g. in a (satisfies ...) clause).
See the functions icalendar-read-value-node,
icalendar-parse-value-node, and icalendar-print-value-node to
convert values defined with this macro to and from their text
representation in iCalendar format.
The following keyword arguments are accepted:
:reader - a function to read data of this type. It will be passed
a string matching MATCHER and should return an Elisp data structure.
Its name does not need to be quoted. (default: identity)
:printer - a function to convert an Elisp data structure of this
type to a string. Its name does not need to be quoted.
(default: identity)
:link - a string containing a URL for further documentation of this type
Source Code
;; Defined in /usr/src/emacs/lisp/calendar/icalendar-macs.el.gz
;; Define value types:
(cl-defmacro ical:define-type (symbolic-name print-name doc specifier matcher
&key link
(reader #'identity)
(printer #'identity))
"Define an iCalendar value type named SYMBOLIC-NAME.
PRINT-NAME should be the string used to represent this type in
the value of an `icalendar-valuetypeparam' property parameter, or
nil if this is not a type that should be specified there. DOC
should be a documentation string for the type. SPECIFIER should
be a type specifier in the sense of `cl-deftype'. MATCHER should
be an RX definition body (see `rx-define'; argument lists are not
supported).
Before the type is defined with `cl-deftype', a function will be
defined named `icalendar-match-PRINT-NAME-value'
\(or `icalendar-match-OTHER-value', if PRINT-NAME is nil, where
OTHER is derived from SYMBOLIC-NAME by removing any prefix
\"icalendar-\" and suffix \"value\"). This function takes a
string argument and matches it against MATCHER. This function may
thus occur in SPECIFIER (e.g. in a (satisfies ...) clause).
See the functions `icalendar-read-value-node',
`icalendar-parse-value-node', and `icalendar-print-value-node' to
convert values defined with this macro to and from their text
representation in iCalendar format.
The following keyword arguments are accepted:
:reader - a function to read data of this type. It will be passed
a string matching MATCHER and should return an Elisp data structure.
Its name does not need to be quoted. (default: identity)
:printer - a function to convert an Elisp data structure of this
type to a string. Its name does not need to be quoted.
(default: identity)
:link - a string containing a URL for further documentation of this type"
(declare (doc-string 2))
(let* (;; Related functions:
(type-dname (if print-name
(downcase print-name)
(string-trim
(symbol-name symbolic-name)
"icalendar-" "value")))
(matcher-name (intern (concat "icalendar-match-" type-dname "-value")))
;; Documentation:
(header "It names a value type defined by `icalendar-define-type'.")
(matcher-doc (format
"Strings representing values of this type can be matched with
`%s'.\n" matcher-name))
(reader-doc (format "They can be read with `%s'\n" reader))
(printer-doc (format "and printed with `%s'." printer))
(full-doc (concat header "\n\n" doc "\n\n"
matcher-doc reader-doc printer-doc "\n\n"
"A syntax node of this type can be read with
`icalendar-read-value-node' or parsed with `icalendar-parse-value-node',
and printed with `icalendar-print-value-node'.")))
`(progn
;; Type metadata needs to be available at both compile time and
;; run time. In particular, `ical:value-type-symbol-p' needs to
;; work at compile time.
(eval-and-compile
(setplist (quote ,symbolic-name)
(list
'ical:is-type t
'ical:is-value t
'ical:matcher (function ,matcher-name)
'ical:value-rx (quote ,symbolic-name)
'ical:value-reader (function ,reader)
'ical:value-printer (function ,printer)
'ical:type-documentation ,full-doc
'ical:link ,link)))
(rx-define ,symbolic-name
,matcher)
(defun ,matcher-name (s)
,(format "Match string S against rx `%s'." symbolic-name)
(string-match (rx ,symbolic-name) s))
(cl-deftype ,symbolic-name () ,specifier)
;; Store the association between the print name and the type
;; symbol in ical:value-types. The check against print name
;; here allows us to also define value types that aren't
;; "really" types according to the standard, like
;; `ical:geo-coordinates'. Only types that have a
;; print-name can be specified in a VALUE parameter.
(when ,print-name
(push (cons ,print-name (quote ,symbolic-name)) ical:value-types)))))