33.10.7.1 Importing iCalendar data as Diary Entries

iCalendar is an Internet standard format for exchanging calendar data. Many calendar applications can export and import data in iCalendar format. iCalendar data is also often sent as email attachments. iCalendar data usually uses the .ics file extension, and is sent with the ‘text/calendar’ MIME type in email. (See Mail Miscellany, for more information on MIME and email attachments.)

The diary-icalendar package allows you to make use of iCalendar data with the Emacs diary. You can import and export data between iCalendar format and your Emacs diary file, and also display iCalendar data directly in the diary.

The following commands will import iCalendar data to your diary file:

diary-icalendar-import-file

Imports an iCalendar file to an Emacs diary file.

diary-icalendar-import-buffer

Imports iCalendar data from the current buffer to an Emacs diary file.

diary-icalendar-import-buffer is also suitable for importing iCalendar data from email attachments. For example, with the Rmail mail client, you could use:

(add-hook 'rmail-show-message-hook #'diary-icalendar-import-buffer)

Diary import depends on a number of user-customizable variables, which are in the diary-icalendar-import customization group. You can review and customize these variables with M-x customize-group. See Customization Groups.

iCalendar data is grouped into components which represent calendar events (the VEVENT component), tasks (VTODO), and other text data (VJOURNAL). Because these components contain different types of data, they are imported by different functions, determined by the following variables:

diary-icalendar-vevent-format-function

Function to format VEVENT components for the diary.

diary-icalendar-vjournal-format-function

Function to format VJOURNAL components for the diary.

diary-icalendar-vtodo-format-function

Function to format VTODO components for the diary.

You can customize the format of the imported diary entries by writing your own formatting functions. It is convenient (but not required) to express such functions as templates called skeletons.

For example, suppose you only want to import the date, time, summary, and location of each calendar event, and to write them on a single line like:

2025/11/11 Summary @ Some Location

Then you could write the import formatting function as a skeleton and set it to the value of diary-icalendar-vevent-format-function as follows:

(require 'skeleton)

(defun simple-vevent (_)
  "Format a VEVENT summary and location on a single line"
  (skeleton-insert
    '(nil
      ical-start-to-end & " " & ical-summary & " "
      (when ical-location "@ ") & ical-location "\n")))

(setopt diary-icalendar-vevent-format-function #'simple-vevent)

The variables ical-start-to-end, ical-summary and ical-location in this example are dynamically bound to appropriate values when the skeleton is called. See the docstring of diary-icalendar-vevent-format-function for more information.

Any errors encountered during import will be reported in a buffer named *icalendar-errors*. You can review these errors with the next-error command. See Compilation Mode. If you regularly need to import malformed iCalendar data, there are several hooks available for this purpose; see the icalendar-parser customization group.