Add short documentation group for iCalendar lib

Define a short documentation group and document the major functions:

* lisp/calendar/icalendar-shortdoc.el: New file.
* lisp/calendar/diary-icalendar.el:
* lisp/calendar/icalendar-ast.el:
* lisp/calendar/icalendar-parser.el:
* lisp/calendar/icalendar-recur.el:
* lisp/calendar/icalendar-utils.el: Refer to icalendar-shortdoc.el in
file commentary.
* lisp/calendar/icalendar-macs.el: Ditto, and also mention the macros
for binding values.
* lisp/calendar/icalendar.el: Ditto, and also remove some obsolete
commentary.

Also make some improvements to documentation strings that the above
changes revealed would be helpful:

* lisp/calendar/icalendar-recur.el
(icalendar-recur-recurrences-in-window-w/end-times): Fix broken ref.
(icalendar-recur-current-tz-to-vtimezone): Clarify docstring.
* lisp/calendar/icalendar-parser.el (icalendar-parse): Clarify
docstring.

(Bug#80727)
This commit is contained in:
Richard Lawrence
2026-03-31 18:35:19 +02:00
committed by Eli Zaretskii
parent 6eea015337
commit 0326130e1b
8 changed files with 308 additions and 22 deletions

View File

@@ -24,8 +24,12 @@
;;; Commentary:
;; This file is a replacement for icalendar.el that uses a new parser
;; and offers more features.
;; For an overview of the iCalendar library, see icalendar-shortdoc.el.
;; This file is a replacement for the diary import/export features
;; previously provided by icalendar.el. It uses a new parser and offers
;; more flexibility and features than the old implementation. It is
;; documented in the Emacs manual.
;;; Code:

View File

@@ -24,6 +24,8 @@
;;; Commentary:
;; For an overview of the iCalendar library, see icalendar-shortdoc.el.
;; This file defines the abstract syntax tree representation for
;; iCalendar data. The AST is based on `org-element-ast' (which see;
;; that feature will eventually be renamed and moved out of the Org tree

View File

@@ -24,10 +24,19 @@
;;; Commentary:
;; This file defines the macros `ical:define-type', `ical:define-param',
;; `ical:define-property' and `ical:define-component', used in
;; icalendar-parser.el to define the particular value types, parameters,
;; properties and components in the standard as type symbols.
;; For an overview of the iCalendar library, see icalendar-shortdoc.el.
;; This file defines the macros `icalendar-define-type',
;; `icalendar-define-param', `icalendar-define-property' and
;; `icalendar-define-component', used in icalendar-parser.el to define
;; the particular value types, parameters, properties and components in
;; the standard as type symbols. It also defines the following macros
;; for binding values in iCalendar syntax nodes:
;; `icalendar-with-component'
;; `icalendar-with-property'
;; `icalendar-with-property-of'
;; `icalendar-with-param'
;; `icalendar-with-param-of'
;; TODOs:
;; - in the define* macros, :default needs rethinking.

View File

@@ -24,6 +24,8 @@
;;; Commentary:
;; For an overview of the iCalendar library, see icalendar-shortdoc.el.
;; This file defines regular expressions, constants and functions that
;; implement the iCalendar grammar according to RFC5545.
;;
@@ -4350,7 +4352,7 @@ during printing will be logged in the buffer returned by
;;; High-level parsing and printing functions.
(defun ical:parse (&optional buffer)
"Parse an `icalendar-vcalendar' object in BUFFER (default: current buffer).
"Parse an iCalendar VCALENDAR object in BUFFER (default: current buffer).
An unfolded copy of BUFFER (see `icalendar-unfolded-buffer-from-buffer')
will first be obtained if necessary. Parsing will begin at the first
@@ -4359,9 +4361,9 @@ occurrence of \"BEGIN:VCALENDAR\" in the unfolded buffer.
The buffer may be tidied up by user functions before parsing begins; see
`icalendar-pre-unfolding-hook' and `icalendar-pre-parsing-hook'.
If parsing is successful, the VCALENDAR object is returned. Otherwise,
nil is returned, a warning is issued, and errors are logged in the
buffer returned by `icalendar-error-buffer'."
If parsing is successful, an `icalendar-vcalendar' object is returned.
Otherwise, nil is returned, a warning is issued, and errors are logged
in the buffer returned by `icalendar-error-buffer'."
(let* ((buf (or buffer (current-buffer)))
(unfolded (cond ((ical:unfolded-p buf) buf)
((buffer-file-name buf)

View File

@@ -23,6 +23,8 @@
;;; Commentary:
;; For an overview of the iCalendar library, see icalendar-shortdoc.el.
;; This is a sub-library for working with recurrence rules and time
;; zones, as defined by RFC5545 (see especially Secs. 3.3.10 and
;; 3.8.5.3, which are required reading before you make any changes to
@@ -1387,7 +1389,7 @@ UTC offsets local to that time zone."
(defun icr:recurrences-in-window-w/end-times
(lower upper component &optional vtimezone)
"Like `icalendar-recurrences-in-window', but returns end times.
"Like `icalendar-recur-recurrences-in-window', but returns end times.
The return value is a list of (START END) pairs representing the start
and end time of each recurrence of COMPONENT in the window defined by
@@ -2111,7 +2113,7 @@ observance."
(null dst-ends-time))))))
(defun icr:current-tz-to-vtimezone (&optional tz tzid start-year)
"Convert TZ to an `icalendar-vtimezone'.
"Convert TZ (default: current time zone) to an `icalendar-vtimezone'.
TZ defaults to the output of `calendar-current-time-zone'; if specified,
it should be a list of the same form as that function returns.

View File

@@ -0,0 +1,273 @@
;;; icalendar-shortdoc.el --- Short documentation for iCalendar -*- lexical-binding: t; -*-
;; Copyright (C) 2026 Free Software Foundation, Inc.
;; Author: Richard Lawrence <rwl@recursewithless.net>
;; Created: April 2026
;; Keywords: calendar, help
;; Human-Keywords: calendar, iCalendar
;; This file is part of GNU Emacs.
;; This file is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this file. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;; This file defines a short documentation group for the main functions
;; of the iCalendar API. It does not aim to cover every function in the
;; library; it is a guide to the high-level functions for Lisp
;; programmers who want to interpret or produce iCalendar data.
;; To read this documentation, do:
;; M-x load-libraray RET icalendar-shortdoc RET
;; M-x shortdoc RET icalendar RET
;;; Code:
(require 'shortdoc)
(require 'icalendar-macs)
(require 'icalendar-parser)
(require 'icalendar-utils)
(require 'icalendar-ast)
(require 'icalendar-recur)
(define-short-documentation-group icalendar
"Parsing and printing VCALENDAR objects"
(icalendar-parse
:no-manual t
:no-eval* (icalendar-parse)
:result-string "(icalendar-vcalendar ...)")
(icalendar-parse-and-index
:no-manual t
:no-eval* (icalendar-parse-and-index)
:result (vcalendar index))
(icalendar-index-get
:args (index &rest kwargs)
:no-manual t
:no-eval (icalendar-index-get index :uid "some-event-UID")
:eg-result-string "(icalendar-vevent ...)"
:no-eval (icalendar-index-get index :date '(5 28 2026))
:eg-result-string "((icalendar-vevent ...) ...)"
:no-eval (icalendar-index-get index :tzid "Europe/Vienna")
:eg-result-string "(icalendar-vtimezone ...)")
(icalendar-parse-from-string
:no-eval
(icalendar-parse-from-string 'icalendar-rrule "RRULE:FREQ=WEEKLY\n")
:result-string "(icalendar-rrule ...)")
(icalendar-print-calendar-node
:no-manual t
:no-eval (icalendar-print-calendar-node vcalendar)
:result "BEGIN:VCALENDAR...")
"Constructing syntax nodes"
(icalendar-make-vcalendar
:no-manual t
:no-eval
"(icalendar-make-vcalendar
some-vtimezone
(@ list-of-vevents)
...)"
:result-string "(icalendar-vcalendar ...)")
(icalendar-make-vevent
:no-manual t
:no-eval
"(icalendar-make-vevent
(icalendar-summary \"Party\")
(icalendar-location \"Robot House\")
(icalendar-organizer \"mailto:bender@mars.edu\"
(icalendar-cnparam \"Bender B. Rodriguez\"))
(icalendar-attendee \"mailto:philip.j.fry@mars.edu\"
(icalendar-partstatparam \"ACCEPTED\"))
(icalendar-dtstart '(3 13 3003))
(icalendar-rrule '((FREQ MONTHLY))))"
:result-string "(icalendar-vevent ...)")
(icalendar-make-vtodo
:no-manual t
:no-eval
"(icalendar-make-vtodo
(icalendar-summary \"Sell another doomsday device\")
(icalendar-description \"Need funds for electronium hat experiment.\")
(icalendar-due '(6 6 3002)))"
:result-string "(icalendar-vtodo ...)")
(icalendar-make-vjournal
:no-manual t
:no-eval
"(icalendar-make-vjournal
(icalendar-summary \"Results: Electronium Hat Experiment\")
(icalendar-description \"How do you like them bananas?\")
(icalendar-dtstart '(8 6 3002)))"
:result-string "(icalendar-vjournal ...)")
"Binding values in syntax nodes"
(icalendar-with-component
:args (node bindings &rest body)
:no-manual t
:no-eval
"(icalendar-with-component vevent
((icalendar-summary :value summary)
(icalendar-location :value location))
(format \"%s @ %s\" summary location))"
:eg-result "Party @ Robot House")
(icalendar-with-property
:args (node bindings &rest body)
:no-manual t
:no-eval "(icalendar-with-property location-node nil
(downcase value))"
:eg-result "robot house")
(icalendar-with-property-of
:args (component property-type bindings &rest body)
:no-manual t
:no-eval
"(icalendar-with-property-of vevent 'icalendar-location nil
(downcase value))"
:eg-result "robot house")
(icalendar-with-param
:args (parameter &rest body)
:no-manual t
:no-eval "(icalendar-with-param cnparam-node
(upcase value))"
:eg-result "BENDER B. RODRIGUEZ")
(icalendar-with-param-of
:args (property param-type &rest body)
:no-manual t
:no-eval "(icalendar-with-param-of organizer-node 'icalendar-cnparam
(upcase value))"
:eg-result "BENDER B. RODRIGUEZ")
"Time zones"
(icalendar-recur-current-tz-to-vtimezone
:no-manual t
:no-eval (icalendar-recur-current-tz-to-vtimezone)
:result-string "(icalendar-vtimezone ...)")
(icalendar-recur-tz-decode-time
:no-manual t
:no-eval (icalendar-recur-tz-decode-time timestamp vtimezone)
:eg-result (0 0 11 11 11 2024 1 nil 3600))
(icalendar-recur-tz-set-zone
:no-eval (icalendar-recur-tz-set-zone '(0 0 11 11 11 2024 1 -1 nil) vtimezone)
:eg-result (0 0 11 11 11 2024 1 nil 3600))
"Dates and date-times"
(icalendar-make-date-time
:no-manual t
:args (&rest kwargs)
:no-eval
"(icalendar-make-date-time :year 2024 :month 12 :day 11
:hour 10 :minute 0 :second 0
:tz vtimezone)"
:eg-result (0 0 10 11 12 2024 3 -1 3600))
(icalendar-date/time<=
:eval (icalendar-date/time<= '(12 15 2024) '(12 11 2024))
:eval "(icalendar-date/time<= '(0 0 8 11 11 2024 1 nil 3600)
'(0 0 10 11 11 2024 3 nil 3600))"
:no-manual t)
(icalendar-date/time<
:no-manual t
:eval (icalendar-date/time< '(12 15 2024) '(12 15 2024)))
(icalendar-date/time-min
:no-manual t
:eval (icalendar-date/time-min '(12 15 2024) '(11 15 2024) '(12 1 2024))
:eval
"(icalendar-date/time-min '(0 0 8 11 12 2024 3 nil 3600)
'(0 0 9 11 12 2024 3 nil 3600)
'(0 0 10 11 12 2024 3 nil 3600))")
(icalendar-date/time-max
:no-manual t
:eval (icalendar-date/time-max '(12 15 2024) '(11 15 2024) '(12 1 2024))
:eval
"(icalendar-date/time-max '(0 0 8 11 12 2024 3 nil 3600)
'(0 0 9 11 12 2024 3 nil 3600)
'(0 0 10 11 12 2024 3 nil 3600))")
(icalendar-date/time-add
:no-manual t
:eval (icalendar-date/time-add '(11 11 2024) :month 2)
:eval (icalendar-date/time-add '(0 0 10 11 11 2024 1 -1 nil) :hour -3))
(icalendar-date/time-add-duration
:no-manual t
:eval "(icalendar-date/time-add-duration '(12 11 2024)
(make-decoded-time :day 4))"
:eval "(icalendar-date/time-add-duration '(0 0 10 11 12 2024 3 -1 nil)
(make-decoded-time :hour 2 :minute 30))")
(icalendar-date/time-year
:no-manual t
:eval (icalendar-date/time-year '(12 11 2024))
:eval (icalendar-date/time-year '(0 0 10 11 12 2024 3 nil 3600)))
(icalendar-date/time-month
:no-manual t
:eval (icalendar-date/time-month '(12 11 2024))
:eval (icalendar-date/time-month '(0 0 10 11 12 2024 3 nil 3600)))
(icalendar-date/time-monthday
:no-manual t
:eval (icalendar-date/time-monthday '(12 11 2024))
:eval (icalendar-date/time-monthday '(0 0 10 11 12 2024 3 nil 3600)))
(icalendar-date/time-weekday
:no-manual t
:eval (icalendar-date/time-weekday '(12 11 2024))
:eval (icalendar-date/time-weekday '(0 0 10 11 12 2024 3 nil 3600)))
(icalendar-date/time-weekno
:no-manual t
:eval (icalendar-date/time-weekno '(12 11 2024))
:eval (icalendar-date/time-weekno '(0 0 10 11 12 2024 3 nil 3600)))
(icalendar-date/time-hour
:no-manual t
:eval (icalendar-date/time-hour '(12 11 2024))
:eval (icalendar-date/time-hour '(0 0 10 11 12 2024 3 nil 3600)))
(icalendar-date/time-minute
:no-manual t
:eval (icalendar-date/time-minute '(12 11 2024))
:eval (icalendar-date/time-minute '(0 0 10 11 12 2024 3 nil 3600)))
(icalendar-date/time-second
:no-manual t
:eval (icalendar-date/time-second '(12 11 2024))
:eval (icalendar-date/time-second '(0 0 10 11 12 2024 3 nil 3600)))
(icalendar-date/time-zone
:no-manual t
:eval (icalendar-date/time-zone '(12 11 2024))
:eval (icalendar-date/time-zone '(0 0 10 11 12 2024 3 nil 3600)))
"Recurrence rules and recurrences"
(icalendar-recur-recurrences-in-window
:no-manual t
:no-eval
"(icalendar-recur-recurrences-in-window '(1 1 2026) '(12 31 2026)
vevent)"
:eg-result-string "((1 10 2026) (2 10 2026) ...)")
(icalendar-recur-recurrences-in-window-w/end-times
:no-manual t
:no-eval
"(icalendar-recur-recurrences-in-window-w/end-times
'(0 0 0 1 1 2026 4 -1 nil) '(0 0 0 1 2 2026 1 -1 nil)
vevent)"
:eg-result-string
"(((0 0 10 10 1 2026 4 -1 nil) (0 0 11 10 1 2026 4 -1 nil)) ...)")
(icalendar-recur-recurrences-to-count
:no-manual t
:no-eval
"(icalendar-recur-recurrences-to-count '(1 1 2026) '(12 31 2026)
vevent)"
:eg-result-string "((1 10 2026) (2 10 2026) (3 10 2026))")
(icalendar-recur-freq
:eval
(icalendar-recur-freq '((FREQ MONTHLY) (INTERVAL 3) (BYDAY ((5 . -1))))))
(icalendar-recur-interval-size
:eval (icalendar-recur-interval-size '((FREQ MONTHLY) (BYDAY ((5 . -1)))))
:eval (icalendar-recur-interval-size '((FREQ MONTHLY) (INTERVAL 3))))
(icalendar-recur-count
:eval (icalendar-recur-count '((FREQ MONTHLY) (INTERVAL 2) (COUNT 6))))
(icalendar-recur-until
:eval (icalendar-recur-until '((FREQ WEEKLY) (UNTIL (12 31 2026)))))
(icalendar-recur-by*
:eval (icalendar-recur-by* 'BYDAY '((FREQ MONTHLY) (BYDAY ((5 . -1))))))
(icalendar-recur-weekstart
:eval
(icalendar-recur-weekstart '((FREQ WEEKLY) (UNTIL (12 31 2026)) (WKST 0)))
:eval
(icalendar-recur-weekstart '((FREQ WEEKLY) (UNTIL (12 31 2026))))))
(provide 'icalendar-shortdoc)

View File

@@ -23,6 +23,8 @@
;;; Commentary:
;; For an overview of the iCalendar library, see icalendar-shortdoc.el.
;; This file contains a variety of utility functions to work with
;; iCalendar data which are used throughout the rest of the iCalendar
;; library. Most of the functions here deal with calendar and clock

View File

@@ -27,21 +27,13 @@
;;; Commentary:
;; Most of the code in this file is now obsolete and has been marked as such.
;; For an overview of the new iCalendar library, see icalendar-shortdoc.el.
;; For the new implementation of diary import/export, see diary-icalendar.el.
;; Error handling code, global variables, and user options relevant for the
;; entire iCalendar library remain in this file.
;; This package is documented in the Emacs Manual.
;; The diary-icalendar feature is documented in the Emacs Manual.
;; Please note:
;; - Diary entries which have a start time but no end time are assumed to
;; last for one hour when they are exported.
;; - Weekly diary entries are assumed to occur the first time in the first
;; week of the year 2000 when they are exported.
;; - Yearly diary entries are assumed to occur the first time in the year
;; 1900 when they are exported.
;; - Float diary entries are assumed to occur the first time on the
;; day when they are exported.
;;; History: