[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/bbdb ee316b4e6a 1/4: Improve snarfing vCards.
From: |
Roland Winkler |
Subject: |
[elpa] externals/bbdb ee316b4e6a 1/4: Improve snarfing vCards. |
Date: |
Mon, 23 Oct 2023 01:59:38 -0400 (EDT) |
branch: externals/bbdb
commit ee316b4e6a33c83555a6d4181a05c0442861fcac
Author: Roland Winkler <winkler@gnu.org>
Commit: Roland Winkler <winkler@gnu.org>
Improve snarfing vCards.
---
lisp/bbdb-snarf.el | 72 ++++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 59 insertions(+), 13 deletions(-)
diff --git a/lisp/bbdb-snarf.el b/lisp/bbdb-snarf.el
index f67cd31483..83d2317dff 100644
--- a/lisp/bbdb-snarf.el
+++ b/lisp/bbdb-snarf.el
@@ -47,6 +47,7 @@
;;; Code:
(require 'bbdb-com)
+(require 'qp)
(defcustom bbdb-snarf-rule-alist
'((us bbdb-snarf-surrounding-space
@@ -199,6 +200,20 @@ The first subexpression becomes the URL."
:group 'bbdb-utilities-vcard
:type 'symbol)
+(defcustom bbdb-snarf-vcard-adr-type-re
+ (concat "\\`" (regexp-opt '("work" "home")) "\\'")
+ "Regexp matching the default types for vCard property ADR."
+ :group 'bbdb-utilities-vcard
+ :type 'regexp)
+
+(defcustom bbdb-snarf-vcard-tel-type-re
+ (concat "\\`" (regexp-opt '("work" "home" "text" "voice"
+ "fax" "cell" "video" "pager" "textphone"))
+ "\\'")
+ "Regexp matching the default types for vCard property TEL."
+ :group 'bbdb-utilities-vcard
+ :type 'regexp)
+
(defcustom bbdb-snarf-ignore-mail-re
(regexp-opt '("noreply" "no-reply" "donotreply" "do-not-reply" "notify"))
"`bbdb-snarf-sanity-check' ignores mail addresses matching this regexp."
@@ -442,7 +457,9 @@ The return value is a list with elements (VALUE (PAR . VAL)
(PAR . VAL) ...)
for each instance of PROPERTY in the vCard. String VALUE is the value
of the instance of PROPERTY. With separator SEP non-nil, VALUE is a list
of split values of the instance of PROPERTY. PAR is a parameter of the
-instance of PROPERTY with value VAL. If PROPERTY is not found return nil.
+instance of PROPERTY with value VAL. PAR may be nil if VAL is a parameter
+value that has no parameter key associated with it.
+If PROPERTY is not found return nil.
Delete all instances of PROPERTY from the snarfing buffer."
;; Possible extensions of this code that are not yet implemented:
;; - Property value escaping (RFC 6350, Sec. 3.4)
@@ -475,16 +492,27 @@ Delete all instances of PROPERTY from the snarfing
buffer."
(goto-char (match-end 0))
(let ((par (match-string 1)))
;; We try to split the property parameters into pairs PAR=VAL.
- ;; If this fails, we include the dangling VAL with PAR being nil.
+ ;; If this fails, we include the dangling VAL with PAR being nil,
+ ;; e.g., "work" instead of "TYPE=work".
;; Certain parameter values may be comma-separated lists.
;; Fixme: Use custom var `bbdb-vcard-parameter-sep-alist'
;; with elements (PAR . SEP).
- (if (string-match "\\`\\([^=]+\\)=\\([^=]+\\)\\'" par)
- (push (cons (match-string 1 par) (match-string 2 par))
- par-list)
- (push (cons nil par) par-list))))
+ (push (if (string-match "\\`\\([^=]+\\)=\\([^=]+\\)\\'" par)
+ (cons (match-string 1 par) (match-string 2 par))
+ (cons nil par))
+ par-list)))
(let ((value (buffer-substring-no-properties
- (1+ (point)) (point-max))))
+ (1+ (point)) (point-max)))
+ (encoding (cdr (bbdb-snarf-assoc
+ "encoding" "\\`quoted-printable\\'"
+ par-list))))
+ (when encoding
+ (if (bbdb-string= encoding "quoted-printable")
+ ;; RFC6350 requires utf-8.
+ (setq value (decode-coding-string
+ (quoted-printable-decode-string value)
+ 'utf-8))
+ (user-error "Vcard encoding %s undefined" encoding)))
;; Again, this ignores the possiblity that `;' and `:'
;; may appear in property values inside quoted strings.
(push (cons (if sep (split-string value sep) value)
@@ -502,6 +530,20 @@ Delete all instances of PROPERTY from the snarfing buffer."
(if (zerop n) 100 n))))
(< (num p1) (num p2)))))))
+(defun bbdb-snarf-assoc (key regexp alist)
+ "Return the first association in ALIST with key KEY or value matching REGEXP.
+In the latter case, the key of the association must be nil. Case is ignored."
+ (let ((case-fold-search t)
+ done)
+ (while alist
+ (if (or (bbdb-string= key (caar alist))
+ (and (not (caar alist))
+ (string-match regexp (cdar alist))))
+ (setq done (car alist)
+ alist nil)
+ (setq alist (cdr alist))))
+ done))
+
(defun bbdb-snarf-vcard-name (record)
"Snarf vCard properties N and/or FN => BBDB name and aka."
;; We give the structured N property precedence over the unstructured
@@ -580,8 +622,9 @@ Delete all instances of PROPERTY from the snarfing buffer."
(progn (message "Unstructured vCard address: not implemented")
(sit-for 1))
(setf (bbdb-address-label address)
- (or (cdr (assoc-string "TYPE" (cdr adr) t))
- (cdr (assq 'address bbdb-snarf-default-label-alist))))
+ (cdr (or (bbdb-snarf-assoc "TYPE" bbdb-snarf-vcard-adr-type-re
+ (cdr adr))
+ (assq 'address bbdb-snarf-default-label-alist))))
;; (0) PO box (1) extended address (2) street (3) city
;; (4) region (5) postal code (6) country
(cl-flet ((str (n) (let ((elt (nth n adr-list)))
@@ -633,8 +676,9 @@ Delete all instances of PROPERTY from the snarfing buffer."
(let ((phones (nreverse (bbdb-record-phone record))))
(mapc (lambda (phone)
(bbdb-pushnew
- (vconcat (list (or (cdr (assoc-string "TYPE" (cdr phone) t))
- (cdr (assq 'phone
bbdb-snarf-default-label-alist))))
+ (vconcat (list (cdr (or (bbdb-snarf-assoc
+ "TYPE" bbdb-snarf-vcard-tel-type-re (cdr
phone))
+ (assq 'phone
bbdb-snarf-default-label-alist))))
(bbdb-parse-phone (car phone)))
phones))
(bbdb-snarf-vcard-property "TEL"))
@@ -648,7 +692,7 @@ Delete all instances of PROPERTY from the snarfing buffer."
(mapc (lambda (org) ; list of values
(mapc (lambda (o) (bbdb-pushnew o orgs))
(car org)))
- (bbdb-snarf-vcard-property "ORG" ","))
+ (bbdb-snarf-vcard-property "ORG" ";"))
(setf (bbdb-record-organization record) (nreverse orgs))))
(defun bbdb-snarf-vcard-uid (record)
@@ -695,6 +739,7 @@ Return record. Also, display the record unless NO-DISPLAY
is non-nil."
(beg-re "^BEGIN:VCARD$")
(limit-re "^\\(BEGIN\\|END\\):VCARD$")
(end-re "^END:VCARD$")
+ (case-fold-search t)
beg end)
(save-excursion
(goto-char pos)
@@ -714,7 +759,8 @@ RULE defaults to `bbdb-snarf-vcard'. See
`bbdb-snarf-rule-alist' for details.
Return the records. Also, display the records unless NO-DISPLAY is non-nil."
(interactive (list bbdb-snarf-vcard))
(save-excursion
- (let (records)
+ (let ((case-fold-search t)
+ records)
(goto-char (point-min))
(while (re-search-forward "^BEGIN:VCARD$" nil t)
(let ((record (bbdb-snarf-vcard (match-beginning 0) rule t)))