[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] scratch/org-contacts-rebased 66e23e6 008/118: org-contacts: added
From: |
Stefan Monnier |
Subject: |
[elpa] scratch/org-contacts-rebased 66e23e6 008/118: org-contacts: added VCard 3.0 exporter and ADDRESS field |
Date: |
Fri, 12 Nov 2021 15:36:54 -0500 (EST) |
branch: scratch/org-contacts-rebased
commit 66e23e6403c8cc07779e6a8760b06ab3336dfc6f
Author: RĂ¼diger Sonderfeld <ruediger@c-plusplus.de>
Commit: Julien Danjou <julien@danjou.info>
org-contacts: added VCard 3.0 exporter and ADDRESS field
Signed-off-by: Julien Danjou <julien@danjou.info>
---
org-contacts.el | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 65 insertions(+)
diff --git a/org-contacts.el b/org-contacts.el
index b32ee86..c07c25e 100644
--- a/org-contacts.el
+++ b/org-contacts.el
@@ -116,6 +116,11 @@ This overrides `org-email-link-description-format' if set."
:group 'org-contacts
:type 'string)
+(defcustom org-contacts-vcard-file "contacts.vcf"
+ "Default file for vcard export."
+ :group 'org-contacts
+ :type 'file)
+
(defvar org-contacts-keymap
(let ((map (make-sparse-keymap)))
(define-key map "M" 'org-contacts-view-send-email)
@@ -529,4 +534,64 @@ If ASK is set, ask for the email address even if there's
only one address."
(add-to-list 'org-property-set-functions-alist
`(,org-contacts-nickname-property .
org-contacts-completing-read-nickname))
+(defun org-contacts-vcard-escape (str)
+ "Escape ; , and \n in STR for use in the VCard format.
+Thanks to http://www.emacswiki.org/cgi-bin/wiki/bbdb-vcard-export.el for the
regexp."
+ (when str
+ (replace-regexp-in-string "\n" "\\\\n" (replace-regexp-in-string
"\\(;\\|,\\|\\\\\\)" "\\\\\\1" str))))
+
+(defun org-contacts-vcard-encode-name (name)
+ "Try to encode NAME as VCard's N property. The N property expects
FamilyName;GivenName;AdditionalNames;Prefix;Postfix.
+Org-contacts does not specify how to encode the name. So we try to do our
best."
+ (concat (replace-regexp-in-string "\\(\\w+\\) \\(.*\\)" "\\2;\\1" name)
";;;"))
+
+(defun org-contacts-vcard-format (contact)
+ "Formats CONTACT in VCard 3.0 format."
+ (let* ((properties (caddr contact))
+ (name (org-contacts-vcard-escape (car contact)))
+ (n (org-contacts-vcard-encode-name name))
+ (email (org-contacts-vcard-escape (cdr (assoc-string
org-contacts-email-property properties))))
+ (bday (org-contacts-vcard-escape (cdr (assoc-string
org-contacts-birthday-property properties))))
+ (addr (cdr (assoc-string org-contacts-address-property properties)))
+ (nick (org-contacts-vcard-escape (cdr (assoc-string
org-contacts-nickname-property properties))))
+
+ (head (format "BEGIN:VCARD\nVERSION:3.0\nN:%s\nFN:%s\n" n name)))
+ (concat head
+ (when email (format "EMAIL:%s\n" email))
+ (when addr
+ (format "ADR:;;%s\n" (replace-regexp-in-string "\\, ?" ";" addr)))
+ (when bday
+ (let ((cal-bday (calendar-gregorian-from-absolute
(org-time-string-to-absolute bday))))
+ (format "BDAY:%04d-%02d-%02d\n"
+ (calendar-extract-year cal-bday)
+ (calendar-extract-month cal-bday)
+ (calendar-extract-day cal-bday))))
+ (when nick (format "NICKNAME:%s\n" nick))
+ "END:VCARD\n\n")))
+
+(defun org-contacts-export-as-vcard (&optional name file to-buffer)
+ "Export all contacts matching NAME as VCard 3.0. It TO-BUFFER is nil, the
content is written to FILE or `org-contacts-vcard-file'. If TO-BUFFER is
non-nil, the buffer is created and the VCard is written into that buffer."
+ (interactive) ; TODO ask for name?
+ (let* ((filename (or file org-contacts-vcard-file))
+ (buffer (if to-buffer
+ (get-buffer-create to-buffer)
+ (find-file-noselect filename))))
+
+ (message "Exporting...")
+
+ (set-buffer buffer)
+ (let ((inhibit-read-only t)) (erase-buffer))
+ (fundamental-mode)
+ (org-install-letbind)
+
+ (when (fboundp 'set-buffer-file-coding-system)
+ (set-buffer-file-coding-system coding-system-for-write))
+
+ (loop for contact in (org-contacts-filter name)
+ do (insert (org-contacts-vcard-format contact)))
+
+ (if to-buffer
+ (current-buffer)
+ (progn (save-buffer) (kill-buffer)))))
+
(provide 'org-contacts)
- [elpa] scratch/org-contacts-rebased b78a119 005/118: Add docstring for `wl-get-from-header-content'., (continued)
- [elpa] scratch/org-contacts-rebased b78a119 005/118: Add docstring for `wl-get-from-header-content'., Stefan Monnier, 2021/11/12
- [elpa] scratch/org-contacts-rebased 4a36f4a 004/118: Merge org-contacts-wl in org-contacts, Stefan Monnier, 2021/11/12
- [elpa] scratch/org-contacts-rebased 4d5b508 007/118: org-contacts: check that completion-at-point-functions is bound, Stefan Monnier, 2021/11/12
- [elpa] scratch/org-contacts-rebased ad99d80 001/118: org-contacts: import, Stefan Monnier, 2021/11/12
- [elpa] scratch/org-contacts-rebased d0caf96 015/118: Replace org-mode-p with usual (eq major-mode 'org-mode) check, Stefan Monnier, 2021/11/12
- [elpa] scratch/org-contacts-rebased 7fcd20b 025/118: contrib/lisp/org-contacts.el: Docstring fixes and small code clean up, Stefan Monnier, 2021/11/12
- [elpa] scratch/org-contacts-rebased dcd313e 021/118: Tags/properties matcher: Fixed issues with todo-only matches, Stefan Monnier, 2021/11/12
- [elpa] scratch/org-contacts-rebased 938ca34 019/118: Add missing word to org-contacts y-or-n-p question, Stefan Monnier, 2021/11/12
- [elpa] scratch/org-contacts-rebased c0f4677 024/118: contrib/lisp/org-contacts.el: Require 'org-agenda., Stefan Monnier, 2021/11/12
- [elpa] scratch/org-contacts-rebased 6b235b4 044/118: contrib/lisp/*el: Fix license information and add "This file is not part...", Stefan Monnier, 2021/11/12
- [elpa] scratch/org-contacts-rebased 66e23e6 008/118: org-contacts: added VCard 3.0 exporter and ADDRESS field,
Stefan Monnier <=
- [elpa] scratch/org-contacts-rebased e585be0 009/118: org-contacts: added org-contacts-show-map (requires google-maps-el), Stefan Monnier, 2021/11/12
- [elpa] scratch/org-contacts-rebased 6c12101 010/118: org-contacts: Use `with-current-buffer' instead of `save-excursion'+`with-current-buffer'., Stefan Monnier, 2021/11/12
- [elpa] scratch/org-contacts-rebased 7cae69f 011/118: org-contacts: Require cl on compilation., Stefan Monnier, 2021/11/12
- [elpa] scratch/org-contacts-rebased ef5cb24 016/118: Copyright year fixes for contrib/., Stefan Monnier, 2021/11/12
- [elpa] scratch/org-contacts-rebased 5f1806a 012/118: org-contacts: fix errors when Gnus or ERC are not loaded, Stefan Monnier, 2021/11/12
- [elpa] scratch/org-contacts-rebased 531d67a 014/118: Fix Emacs 24 compatibility issue with Emacs 24, Stefan Monnier, 2021/11/12
- [elpa] scratch/org-contacts-rebased 2b1a75a 030/118: Improve `completion-at-point' for `org-contacts.el' in mail, Stefan Monnier, 2021/11/12
- [elpa] scratch/org-contacts-rebased 010b2ec 029/118: org-contacts.el (org-contacts-format-name): New function, Stefan Monnier, 2021/11/12
- [elpa] scratch/org-contacts-rebased 8bf8565 027/118: Update copyright years., Stefan Monnier, 2021/11/12
- [elpa] scratch/org-contacts-rebased 72d2caf 022/118: add a missing require for gnus-util, Stefan Monnier, 2021/11/12