branch: externals/ebdb commit 5d9c9b0b0201648d76791e8efa1b3e6e7cda2b00 Author: Eric Abrahamsen <e...@ericabrahamsen.net> Commit: Eric Abrahamsen <e...@ericabrahamsen.net>
Add a method for parsing US phone numbers, fix phone parsing Fixes #81 * ebdb-i18n-basic.el (ebdb-parse-i18n): New method for pasing US phone numbers. * ebdb.el (ebdb-parse): Turn any object creation error into an ebdb-unparseable error. (ebdb-parse): Base method for phones should do nothing if the slots are completely filled out, same as other parsing methods. --- ebdb-i18n-basic.el | 25 +++++++++++++++++++++++++ ebdb.el | 28 ++++++++++++++++------------ 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/ebdb-i18n-basic.el b/ebdb-i18n-basic.el index 351d11b..24a3856 100644 --- a/ebdb-i18n-basic.el +++ b/ebdb-i18n-basic.el @@ -89,6 +89,31 @@ ("Wyoming" . "WY")) "All the states in the US, for use with completion.") +(cl-defmethod ebdb-parse-i18n ((_class (subclass ebdb-field-phone)) + (str string) + (_cc (eql 1)) + &optional slots) + "Parse a US phone number. +Uses first three digits as the area code, next seven as the +number, and any remaining as an extension." + (let ((numstr (replace-regexp-in-string "[^[:digit:]]+" "" str)) + ext) + (setq slots + (plist-put + (plist-put + slots :area-code + (string-to-number (substring numstr 0 3))) + :number (substring numstr 3 10))) + (condition-case nil + (setq slots (plist-put + slots + :extension + (when (and (setq ext (substring numstr 10)) + (null (string-empty-p ext))) + (string-to-number ext)))) + (args-out-of-range nil)) + slots)) + (cl-defmethod ebdb-string-i18n ((phone ebdb-field-phone) (_cc (eql 1))) (with-slots (area-code number extension) phone diff --git a/ebdb.el b/ebdb.el index ac63a12..f7d03e7 100644 --- a/ebdb.el +++ b/ebdb.el @@ -870,9 +870,11 @@ Then call `cl-call-next-method' with the new values.") (save-match-data (cl-call-next-method))) -(cl-defmethod ebdb-parse ((field-class (subclass ebdb-field)) _str &optional slots) +(cl-defmethod ebdb-parse ((field-class (subclass ebdb-field)) str &optional slots) "Create the actual field instance." - (apply 'make-instance field-class slots)) + (condition-case nil + (apply 'make-instance field-class slots) + (error (signal 'ebdb-unparseable (list str))))) (cl-defmethod ebdb-parse :before ((_field-class (subclass ebdb-field)) str &optional _slots) (when (string-empty-p str) @@ -1828,17 +1830,19 @@ The result looks like this: ;; "number" is saved as a string, partially for ease in ;; formatting, partially because if it's too long Emacs turns it ;; into a float, which is a pain in the ass. - (while (and (< (point) (point-max)) - (null (looking-at-p ext-regexp)) - (looking-at "[ \t]?\\([0-9]+\\)[- .]?")) - (setq acc (concat acc (match-string-no-properties 1))) - (goto-char (match-end 0))) - (when (looking-at ext-regexp) + (unless (plist-member slots :number) + (while (and (< (point) (point-max)) + (null (looking-at-p ext-regexp)) + (looking-at "[ \t]?\\([0-9]+\\)[- .]?")) + (setq acc (concat acc (match-string-no-properties 1))) + (goto-char (match-end 0))) (setq slots - (plist-put slots :extension (string-to-number - (match-string 1)))))) - (setq slots - (plist-put slots :number acc)) + (plist-put slots :number acc))) + (unless (plist-member slots :number) + (when (looking-at ext-regexp) + (setq slots + (plist-put slots :extension (string-to-number + (match-string 1))))))) (cl-call-next-method class string slots))) (cl-defmethod cl-print-object ((phone ebdb-field-phone) stream)