Remove junk from end of file.
[gnus] / contrib / vcard.el
1 ;;; vcard.el --- vcard parsing and display routines
2
3 ;; Copyright (C) 1997, 1999, 2000 Noah S. Friedman
4
5 ;; Author: Noah Friedman <friedman@splode.com>
6 ;; Maintainer: friedman@splode.com
7 ;; Keywords: vcard, mail, news
8 ;; Created: 1997-09-27
9
10 ;; <http://www.splode.com/users/friedman/software/emacs-lisp/>
11 ;; Id: vcard.el,v 1.11 2000/06/29 17:07:55 friedman Exp
12
13 ;; This program is free software; you can redistribute it and/or modify
14 ;; it under the terms of the GNU General Public License as published by
15 ;; the Free Software Foundation; either version 3, or (at your option)
16 ;; any later version.
17 ;;
18 ;; This program is distributed in the hope that it will be useful,
19 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 ;; GNU General Public License for more details.
22 ;;
23 ;; You should have received a copy of the GNU General Public License
24 ;; along with this program; if not, you can either send email to this
25 ;; program's maintainer or write to: The Free Software Foundation,
26 ;; Inc.; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27
28 ;;; Commentary:
29
30 ;; Unformatted vcards are just plain ugly.  But if you live in the MIME
31 ;; world, they are a better way of exchanging contact information than
32 ;; freeform signatures since the former can be automatically parsed and
33 ;; stored in a searchable index.
34 ;;
35 ;; This library of routines provides the back end necessary for parsing
36 ;; vcards so that they can eventually go into an address book like BBDB
37 ;; (although this library does not implement that itself).  Also included
38 ;; is a sample pretty-printer which MUAs can use which do not provide their
39 ;; own vcard formatters.
40
41 ;; This library does not interface directly with any mail user agents.  For
42 ;; an example of bindings for the VM MUA, see vm-vcard.el available from
43 ;;
44 ;;    http://www.splode.com/~friedman/software/emacs-lisp/index.html#mail
45 ;;
46 ;; Updates to vcard.el should be available there too.
47
48 ;; The main entry point to this package is `vcard-pretty-print' although
49 ;; any documented variable or function is considered part of the API for
50 ;; operating on vcard data.
51
52 ;; The vcard 2.1 format is defined by the versit consortium.
53 ;; See http://www.imc.org/pdi/vcard-21.ps
54 ;;
55 ;; RFC 2426 defines the vcard 3.0 format.
56 ;; See ftp://ftp.rfc-editor.org/in-notes/rfc2426.txt
57
58 ;; A parsed vcard is a list of attributes of the form
59 ;;
60 ;;     (proplist value1 value2 ...)
61 ;;
62 ;; Where proplist is a list of property names and parameters, e.g.
63 ;;
64 ;;     (property1 (property2 . parameter2) ...)
65 ;;
66 ;; Each property has an associated implicit or explicit parameter value
67 ;; (not to be confused with attribute values; in general this API uses
68 ;; `parameter' to refer to property values and `value' to refer to attribute
69 ;; values to avoid confusion).  If a property has no explicit parameter value,
70 ;; the parameter value is considered to be `t'.  Any property which does not
71 ;; exist for an attribute is considered to have a nil parameter.
72
73 ;; TODO:
74 ;;   * Finish supporting the 3.0 extensions.
75 ;;     Currently, only the 2.1 standard is supported.
76 ;;   * Handle nested vcards and grouped attributes?
77 ;;     (I've never actually seen one of these in use.)
78 ;;   * Handle multibyte charsets.
79 ;;   * Inverse of vcard-parse-string: write .VCF files from alist
80 ;;   * Implement a vcard address book?  Or is using BBDB preferable?
81 ;;   * Improve the sample formatter.
82
83 ;;; Code:
84
85 (defgroup vcard nil
86   "Support for the vCard electronic business card format."
87   :group 'vcard
88   :group 'mail
89   :group 'news)
90
91 ;;;###autoload
92 (defcustom vcard-pretty-print-function 'vcard-format-sample-box
93   "*Formatting function used by `vcard-pretty-print'."
94   :type 'function
95   :group 'vcard)
96
97 ;;;###autoload
98 (defcustom vcard-standard-filters
99   '(vcard-filter-html
100     vcard-filter-adr-newlines
101     vcard-filter-tel-normalize
102     vcard-filter-textprop-cr)
103   "*Standard list of filters to apply to parsed vcard data.
104 These filters are applied sequentially to vcard attributes when
105 the function `vcard-standard-filter' is supplied as the second argument to
106 `vcard-parse'."
107   :type 'hook
108   :group 'vcard)
109
110 \f
111 ;;; No user-settable options below.
112
113 ;; XEmacs 21 ints and chars are disjoint types.
114 ;; For all else, treat them as the same.
115 (defalias 'vcard-char-to-int
116   (if (fboundp 'char-to-int) 'char-to-int 'identity))
117
118 ;; This is just the version number for this package; it does not refer to
119 ;; the vcard format specification.  Currently, this package does not yet
120 ;; support the full vcard 3.0 specification.
121 ;;
122 ;; Whenever any part of the API defined in this package change in a way
123 ;; that is not backward-compatible, the major version number here should be
124 ;; incremented.  Backward-compatible additions to the API should be
125 ;; indicated by increasing the minor version number.
126 (defconst vcard-api-version "2.0")
127
128 ;; The vcard standards allow specifying the encoding for an attribute using
129 ;; these values as immediate property names, rather than parameters of the
130 ;; `encoding' property.  If these are encountered while parsing, associate
131 ;; them as parameters of the `encoding' property in the returned structure.
132 (defvar vcard-encoding-tags
133   '("quoted-printable" "base64" "8bit" "7bit"))
134
135 ;; The vcard parser will auto-decode these encodings when they are
136 ;; encountered.  These methods are invoked via vcard-parse-region-value.
137 (defvar vcard-region-decoder-methods
138   '(("quoted-printable" . vcard-region-decode-quoted-printable)
139     ("base64"           . vcard-region-decode-base64)))
140
141 ;; This is used by vcard-region-decode-base64
142 (defvar vcard-region-decode-base64-table
143   (let* ((a "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
144          (len (length a))
145          (tbl (make-vector 123 nil))
146          (i 0))
147     (while (< i len)
148       (aset tbl (vcard-char-to-int (aref a i)) i)
149       (setq i (1+ i)))
150     tbl))
151
152 \f
153 ;;; This function can be used generically by applications to obtain
154 ;;; a printable representation of a vcard.
155
156 ;;;###autoload
157 (defun vcard-pretty-print (vcard)
158   "Format VCARD into a string suitable for display to user.
159 VCARD can be an unparsed string containing raw VCF vcard data
160 or a parsed vcard alist as returned by `vcard-parse-string'.
161
162 The result is a string with formatted vcard information suitable for
163 insertion into a mime presentation buffer.
164
165 The function specified by the variable `vcard-pretty-print-function'
166 actually performs the formatting.  That function will always receive a
167 parsed vcard alist."
168   (and (stringp vcard)
169        (setq vcard (vcard-parse-string vcard)))
170   (funcall vcard-pretty-print-function vcard))
171
172 \f
173 ;;; Parsing routines
174
175 ;;;###autoload
176 (defun vcard-parse-string (raw &optional filter)
177   "Parse RAW vcard data as a string, and return an alist representing data.
178
179 If the optional function FILTER is specified, apply that filter to each
180 attribute.  If no filter is specified, `vcard-standard-filter' is used.
181
182 Filters should accept two arguments: the property list and the value list.
183 Modifying in&n