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)))))