Function: icalendar-fix-ms-tzids

icalendar-fix-ms-tzids is a byte-compiled function defined in icalendar-parser.el.gz.

Signature

(icalendar-fix-ms-tzids)

Documentation

Replace certain non-standard TZIDs with acceptable values.

Some implementations (particularly on Microsoft platforms) are known to produce TZID strings which are not compliant with RFC5545, like:

  TZID:Amsterdam, Belgrade, Berlin
  ...;TZID="Amsterdam, Belgrade, Berlin"...

This function replaces such TZIDs with an RFC-compliant version like:

  TZID:AmsterdamEtc
  ...;TZID=AmsterdamEtc...

This does not affect the interpretation of the time data, and allows the TZIDs to be parsed correctly. This function is intended to be used from icalendar-pre-parsing-hook, which see.

Source Code

;; Defined in /usr/src/emacs/lisp/calendar/icalendar-parser.el.gz
(defun ical:fix-ms-tzids ()
  "Replace certain non-standard TZIDs with acceptable values.

Some implementations (particularly on Microsoft platforms) are known to
produce TZID strings which are not compliant with RFC5545, like:

  TZID:Amsterdam, Belgrade, Berlin
  ...;TZID=\"Amsterdam, Belgrade, Berlin\"...

This function replaces such TZIDs with an RFC-compliant version like:

  TZID:AmsterdamEtc
  ...;TZID=AmsterdamEtc...

This does not affect the interpretation of the time data, and allows the
TZIDs to be parsed correctly.  This function is intended to be used from
`icalendar-pre-parsing-hook', which see."
  (goto-char (point-min))
  (let (tzids)
    ;; Collect and replace MS-style TZID property values:
    (while (re-search-forward
            (rx line-start "TZID"
                (zero-or-more ical:other-param-safe) ":"
                (group-n 1 ; everything until EOL, including unescaped commas
                  (group-n 2 (one-or-more ical:safe-char)) ; for new TZID
                  (zero-or-more (not "\n"))))
            nil t)
      (let ((old (match-string 1))
            (new (concat (match-string 2) "Etc")))
        (while (rassoc new tzids)
          (setq new (symbol-name (gensym new))))
        (when (string-match-p (rx (not ical:safe-char)) old)
          (replace-match new nil nil nil 1)
          (push (cons old new)
                tzids))))

    (goto-char (point-min))
    ;; Replace TZID param values:
    ;; In all the examples I've seen, when these TZIDs appear in param
    ;; values, they're surrounded by double quotes, which are invalid.
    ;; Remove them if present.
    (while (re-search-forward (rx ";TZID="
                                  (group-n 1
                                    (? ?\")
                                    (group-n 2
                                      (one-or-more (not (any ?\" ?\; ?\: "\n"))))
                                    (? ?\")))
                              nil t)
      (when-let* ((pair (assoc (match-string 2) tzids))
                  (new (cdr pair)))
        (replace-match new nil nil nil 1)))))