Add initial version of ics2org function

Function parses an ICS file and returns formatted as an Org event,
currently just prints to standard out, but will modify to insert to
current buffer / buffer of choosing

Move a couple of extra functions into lib directory with ics2org, to
be a bit more organised
This commit is contained in:
Evie Litherland-Smith 2024-06-24 11:25:41 +01:00
parent b7a86988ad
commit 2f0ebbf9b4
5 changed files with 72 additions and 3 deletions

View file

@ -7,7 +7,7 @@
(setopt warning-minimum-level :error)
;; Configure packages archives with priority
(load-file (locate-user-emacs-file "package-config.el"))
(load-file (locate-user-emacs-file "lib/package-config.el"))
(setq custom-file (locate-user-emacs-file "custom.el"))
(when (and custom-file
@ -1115,7 +1115,7 @@ Calls `project-remember-projects-under' for ~/Projects/"
:custom
(bbdb-file (locate-user-emacs-file "bbdb.gpg")))
(load-file (locate-user-emacs-file "mu4e-custom.el"))
(load-file (locate-user-emacs-file "lib/mu4e-custom.el"))
(use-package erc
:commands erc-compute-nick

View file

@ -2,7 +2,7 @@
;;; Commentary:
;;; Code:
;; Configure packages archives with priority
(load-file "package-config.el")
(load-file "lib/package-config.el")
(package-refresh-contents)
(setopt package-selected-packages
'(

69
lib/ics2org.el Normal file
View file

@ -0,0 +1,69 @@
;;; ics2org.el -- ics2org -*- lexical-binding: t -*-
;;; Commentary:
;;; Inspired by / adapted from `fosdem-ics-to-org-list', from
;;; https://geeksocket.in/posts/elisp-ics-org-mode-list/
;;; Original Code:
;;; (defun fosdem-ics-to-org-list ()
;;; "Iterate over the VEVENT entries and create an Org list"
;;; (interactive)
;;; (let (talks-list)
;;; (setq talks-list
;;; (concat
;;; "* FOSDEM talks [/]\n"
;;; (cl-loop while (re-search-forward "BEGIN:VEVENT" nil t) concat
;;; (let (start-time end-time summary url duration duration-minutes)
;;; (re-search-forward "DTSTART:\\(.*\\)")
;;; (setq start-time (match-string 1))
;;; (re-search-forward "DTEND:\\(.*\\)")
;;; (setq end-time (match-string 1))
;;; (re-search-forward "SUMMARY:\\(.*\\)")
;;; (setq summary (match-string 1))
;;; (re-search-forward "URL:\\(.*\\)")
;;; (setq url (match-string 1))
;;; (setq duration (time-subtract
;;; (parse-iso8601-time-string end-time)
;;; (parse-iso8601-time-string start-time)))
;;; (setq duration-minutes (/ duration 60))
;;; (format "- [ ] [[%s][%s]] (%sm)\n" url summary duration-minutes)))))
;;; (with-current-buffer (generate-new-buffer "FOSDEM")
;;; (insert talks-list)
;;; (org-mode)
;;; (org-update-statistics-cookies (point)))))
;;; Code:
(defun ics2org (filename)
"Convert ICS file `FILENAME' to Org event format and insert at point."
(interactive)
(let (output-format
event-start
event-end
event-summary)
(if (not (file-exists-p filename))
(error "File %s not found" filename))
(progn
(find-file filename)
;; Find start time
(goto-char (point-min))
(re-search-forward "DTSTART:\\(.*\\)")
(setq event-start (date-to-time (match-string 1)))
;; Find end time
(goto-char (point-min))
(re-search-forward "DTEND:\\(.*\\)")
(setq event-end (date-to-time (match-string 1)))
;; Get event summary / title
(goto-char (point-min))
(re-search-forward "SUMMARY:\\(.*\\)")
(setq event-summary (match-string 1))
(previous-buffer))
;; Set a default `output-format', but replace with
;; `org-time-stamp-format' if available
(setq output-format "<%Y-%m-%d %a %H:%M>")
(if (fboundp 'org-time-stamp-format)
(setq output-format (org-time-stamp-format t nil)))
;; Return a formatted `org-mode' entry using parsed data
(format "* %s\n%s--%s\n"
event-summary
(format-time-string output-format event-start)
(format-time-string output-format event-end))))
(provide 'ics2org)
;;; ics2org.el ends here