From 04761429f82bfd2aee63f4978afec3449abaa37d Mon Sep 17 00:00:00 2001 From: Jack Kamm Date: Sat, 1 Apr 2023 16:53:35 -0700 Subject: [PATCH] ox-icalendar: Use consistent CRLF line endings Fixes issue where the ox-icalendar export uses an inconsistent mix of dos and unix style line endings. * lisp/ox-icalendar.el (org-icalendar-fold-string): No longer converts to CRLF, instead delegating that to `org-icalendar--convert-eol'. (org-icalendar--convert-eol): New function to convert EOL to CRLF. It runs early in `org-icalendar-after-save-hook'. * testing/lisp/test-ox-icalendar.el: New file for unit tests of ox-icalendar. Add an initial test for CRLF line endings. See also: https://list.orgmode.org/87o7oetneo.fsf@localhost/T/#m3e3eb80f9fc51ba75854b33ebfe9ecdefa2ded24 https://list.orgmode.org/orgmode/87ilgljv6i.fsf@localhost/ --- etc/ORG-NEWS | 12 +++++++++ lisp/ox-icalendar.el | 14 +++++++--- testing/lisp/test-ox-icalendar.el | 44 +++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 testing/lisp/test-ox-icalendar.el diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index ac233a986..9f7d01707 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -23,6 +23,18 @@ If you still want to use python-mode with ob-python, you might consider [[https://gitlab.com/jackkamm/ob-python-mode-mode][ob-python-mode-mode]], where the code to support python-mode has been ported to. +*** =ox-icalendar.el= line ending fix may affect downstream packages + +iCalendar export now uses dos-style CRLF ("\r\n") line endings +throughout, as required by the iCalendar specification (RFC 5545). +Previously, the export used an inconsistent mix of dos and unix line +endings. + +This might cause errors in external packages that parse output from +ox-icalendar. In particular, older versions of org-caldav may +encounter issues, and users are advised to update to the most recent +version of org-caldav. See [[https://github.com/dengste/org-caldav/commit/618bf4cdc9be140ca1993901d017b7f18297f1b8][this org-caldav commit]] for more information. + ** New and changed options *** New ~org-cite-natbib-export-bibliography~ option defining fallback bibliography style diff --git a/lisp/ox-icalendar.el b/lisp/ox-icalendar.el index 81a77a770..7f675b5d0 100644 --- a/lisp/ox-icalendar.el +++ b/lisp/ox-icalendar.el @@ -540,12 +540,20 @@ (defun org-icalendar-fold-string (s) ;; line, real contents must be split at 74 chars. (while (< (setq chunk-end (+ chunk-start 74)) len) (setq folded-line - (concat folded-line "\r\n " + (concat folded-line "\n " (substring line chunk-start chunk-end)) chunk-start chunk-end)) - (concat folded-line "\r\n " (substring line chunk-start)))))) - (org-split-string s "\n") "\r\n"))) + (concat folded-line "\n " (substring line chunk-start)))))) + (org-split-string s "\n") "\n"))) +(defun org-icalendar--convert-eol (f) + "Convert line endings to CRLF as per RFC 5545." + (with-temp-buffer + (insert-file-contents f) + (let ((coding-system-for-write 'utf-8-dos)) + (write-region nil nil f)))) + +(add-hook 'org-icalendar-after-save-hook #'org-icalendar--convert-eol -90) ;;; Filters diff --git a/testing/lisp/test-ox-icalendar.el b/testing/lisp/test-ox-icalendar.el new file mode 100644 index 000000000..bfc756d51 --- /dev/null +++ b/testing/lisp/test-ox-icalendar.el @@ -0,0 +1,44 @@ +;;; test-ox-icalendar.el --- tests for ox-icalendar.el -*- lexical-binding: t; -*- + +;; Copyright (C) 2023 Jack Kamm + +;; Author: Jack Kamm + +;; This program 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 program 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 program. If not, see . + +;;; Commentary: + +;; Tests checking validity of Org iCalendar export output. + +;;; Code: + +(require 'ox-icalendar) + +(ert-deftest test-ox-icalendar/crlf-endings () + "Test every line of iCalendar export has CRLF ending." + (let ((tmp-ics (org-test-with-temp-text-in-file + "* Test event +:PROPERTIES: +:ID: b17d8f92-1beb-442e-be4d-d2060fa3c7ff +:END: +<2023-03-30 Thu>" + (expand-file-name (org-icalendar-export-to-ics))))) + (unwind-protect + (with-temp-buffer + (insert-file-contents tmp-ics) + (should (eql 1 (coding-system-eol-type last-coding-system-used)))) + (when (file-exists-p tmp-ics) (delete-file tmp-ics))))) + +(provide 'test-ox-icalendar) +;;; test-ox-icalendar.el ends here -- 2.39.2