debian/0000775000000000000000000000000012323027441007166 5ustar debian/README.Debian0000664000000000000000000000651512056121451011235 0ustar To enable bbdb support add a call to bbdb-initialize in your .emacs: bbdb-initialize is a compiled Lisp function in `bbdb'. (bbdb-initialize &rest TO-INSINUATE) *Initialize the BBDB. One or more of the following symbols can be passed as arguments to initiate the appropriate insinuations. Initialization of mail/news readers: Gnus Initialize BBDB support for the Gnus version 3.14 or older. gnus Initialize BBDB support for the Gnus mail/news reader version 3.15 or newer. If you pass the `gnus' symbol, you should probably also pass the `message' symbol. mh-e Initialize BBDB support for the MH-E mail reader. rmail Initialize BBDB support for the RMAIL mail reader. sendmail Initialize BBDB support for sendmail (M-x mail). vm Initialize BBDB support for the VM mail reader. NOTE: For the VM insinuation to work properly, you must either call `bbdb-initialize' with the `vm' symbol from within your VM initialization file ("~/.vm") or you must call `bbdb-insinuate-vm' manually from within your VM initialization file. Initialization of miscellaneous package: message Initialize BBDB support for Message mode. reportmail Initialize BBDB support for the Reportmail mail notification package. sc Initialize BBDB support for the Supercite message citation package. w3 Initialize BBDB support for Web browsers. ---+++--- In bits.tar.gz is the bits/ Subdir of the bbdb-Source packaged. The README there states this: This is the collection of bits and pieces located on the net or mailed to me by various folk that may or may not wind up in BBDB proper. They shouldn't be considered part of the bbdb as-is, nor should you complain to me about their failure to work. Look at it if you find something useful. If there is enough demand for some of the files i can install them with bbdb. Just ask me. :) ---------------------------------------------------------------- Trying to bring up-to-date, and make compatible with Emacs23 RMAIL. Imported via: git cvsimport -v -C bbdb -s -k -u -a bbdb -d :pserver:anonymous@bbdb.cvs.sourceforge.net:/cvsroot/bbdb on 17-Nov-2009 (the -s -k was a bug, as it substitutes "-k" for "/" in tags, oops, thus disabling the -k, double oops.) Manually merged Debian patches and tagged Debian releases. Note that the upstream CVS repo did not contain the ./configure file, while the upstream .orig tarballs do. I have left these out. To do an incremental update with upstream changes: cd src/git/bbdb git cvsimport -v -i -r origin -k -u -a -d :pserver:anonymous@bbdb.cvs.sourceforge.net:/cvsroot/bbdb bbdb gitk --all; git merge origin/origin The default upstream build process compiles the .el files, and therefore needs a working emacs. The debian packaging process leaves this to install time, so at build time we do not actually need an emacs. But the configure script looks for one anyway, in order to produce a proper lisp/Makefile, whose execution is however deferred until installation time. Tweaking things to cause configuration to not bail when no emacs is present is more trouble than just requiring one at build time. So that's what we do. -- Barak A. Pearlmutter , Tue, 9 Mar 2010 16:04:29 +0000 debian/source/0000775000000000000000000000000012056121452010466 5ustar debian/source/format0000664000000000000000000000001412056121452011674 0ustar 3.0 (quilt) debian/copyright0000664000000000000000000000426112056121450011122 0ustar This package was debianized by Frederic Lepied on Mon, 17 Oct 1997 23:09:25 +0200. Actual Maintainer: Joerg Jaspert It was downloaded from http://bbdb.sourceforge.net/ Authors: Jamie Zawinski, Ronan Waide (Waider), Todd Kaufmann, Boris Goldowsky, Christopher Kline, John Heidemann, Roland McGrath Current Upstream: Ronan Waide Copyright: Copyright subsets of 1991-2001, subsets of Jamie Zawinski, Ronan Waide (Waider), Todd Kaufmann, Boris Goldowsky, Christopher Kline, John Heidemann, Roland McGrath lisp/* texinfo/* tex/* utils/* Copyright (c) 1997-1999 Matt Simmons texinfo/bbdb.texinfo Copyright (c) 2000 Alex Schroeder misc/bbdb-unmigrate-stuff.el Copyright 1995 Neda Communications, Inc. bits/bbdb-filters/doc/main.texinfo bits/bbdb-filters/bbdb-filters-0.2.sh Copyright (C) 1998 Ivar Rummelhoff bits/bbdb-anniv.el Copyright (C) 1999, 2000, 2001 Shenghuo ZHU bits/bbdb-edit.el Copyright (C) 1998,2000 by Niels Elgaard Larsen bits/bbdb-ldif.el Copyright (C) 2001 Colin Rafferty bits/bbdb-obsolete.el Copyright (C) 1997,1999 Kevin Davidson bits/bbdb-pgp.el bits/bbdb-signature.el Copyright (C) 1997 Kevin Davidson Copyright (C) 1985, 1986, 1992 Free Software Foundation, Inc bits/bbdb-signature.el ;;; The Insidious Big Brother Database is free software; you can redistribute ;;; it and/or modify it under the terms of the GNU General Public License as ;;; published by the Free Software Foundation; either version 2, or (at your ;;; option) any later version. ;;; ;;; BBDB is distributed in the hope that it will be useful, but WITHOUT ANY ;;; WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS ;;; FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ;;; details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with GNU Emacs; see the file COPYING. If not, write to ;;; the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ;;; MA 02110-1301, USA. On Debian systems, the complete text of the GNU General Public License version 2 can be found in /usr/share/common-licenses/GPL-2 file. debian/bbdb.info0000664000000000000000000000002212056121450010724 0ustar texinfo/bbdb.info debian/bbdb.doc-base0000664000000000000000000000076312056121450011462 0ustar Document: bbdb Title: Insidious Big Brother Database User Manual Author: Jamie Zawinski, Matt Simmons and the BBDB Development Team Abstract: BBDB is a rolodex-like database program for GNU Emacs and XEmacs. BBDB stands for Insidious Big Brother Database, and is not, repeat, not an obscure reference to the Buck Rogers TV series. Section: Editors Format: HTML Index: /usr/share/doc/bbdb/html/bbdb.html Files: /usr/share/doc/bbdb/html/*.html Format: PDF Files: /usr/share/doc/bbdb/bbdb.pdf.gz debian/bbdb.install0000664000000000000000000000055412056121450011451 0ustar Makefile usr/share/emacs/site-lisp/bbdb lisp/*.el usr/share/emacs/site-lisp/bbdb/lisp lisp/Makefile usr/share/emacs/site-lisp/bbdb/lisp utils/*.el usr/share/emacs/site-lisp/bbdb/utils debian/bbdb-pilot-jwz.el usr/share/emacs/site-lisp/bbdb tex/*.tex usr/share/texmf/tex/bbdb texinfo/bbdb/*.html usr/share/doc/bbdb/html utils/*.pl usr/bin debian/bbdb-unlazy-lock.10000664000000000000000000000275612056121450012417 0ustar .\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH BBDB-UNLAZY-LOCK.PL 1 "March 31, 2002" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: .\" .nh disable hyphenation .\" .hy enable hyphenation .\" .ad l left justify .\" .ad b justify to both left and right margins .\" .nf disable filling .\" .fi enable filling .\" .br insert line break .\" .sp insert n+1 empty lines .\" for manpage-specific macros, see man(7) .SH NAME bbdb--unlazy-lock \- Removes crap from lazy-lock from your .bbdb .SH SYNOPSIS .B bbdb-unlazy-lock .SH DESCRIPTION Lazy-lock-mode has (had) a nasty habit of munging .bbdb files if you visited them with it on. This script removes the lazy-lock mung This manual page was written for the Debian distribution because the original program does not have a manual page. Instead, it has documentation in the GNU Info format; see below. .SH SEE ALSO .BR bbdb-areacode-split (1), .BR bbdb-unlazy-lock (1). .BR bbdb-srv (1). .br The bbdb is fully documented by .IR "The insidious Big Brother Database for mail and news" , available via the Infonode .BR bbdb . .SH AUTHOR This manual page was written by Joerg Jaspert (JJ) , for the Debian GNU/Linux system (but may be used by others). debian/changelog0000664000000000000000000004335412323027435011054 0ustar bbdb (2.36-3ubuntu1) trusty; urgency=medium * Use emacs24 by default to remove emacs23 from main. -- Dimitri John Ledkov Mon, 14 Apr 2014 19:55:25 +0100 bbdb (2.36-3) unstable; urgency=low [ Sébastien Villemot ] * debian/bbdb.emacsen-install: no longer create /root/.gnupg during installation of the package. This is achieved by binding GNUPGHOME to a temporary directory during bytecode compilation (Closes: #694417) -- Barak A. Pearlmutter Fri, 30 Nov 2012 11:52:46 +0000 bbdb (2.36-2) unstable; urgency=low * Update to bbdb-vcard 0.3, which better parses birthdays * bump standards version (debian/changelog) * bump to dh 8, dh --parallel, dh --with autotools_dev (debian/compat, debian/control, debian/rules) * rephrase for grammar and Moore's Law (debian/bbdb.emacsen-install) (closes: #440192, #540539) -- Barak A. Pearlmutter Sun, 12 Dec 2010 14:57:47 +0000 bbdb (2.36-1) unstable; urgency=low * New "upstream" release. * Look for upstream in github repo (debian/watch) -- Barak A. Pearlmutter Tue, 20 Apr 2010 20:18:13 +0100 bbdb (2.35.cvs20080316-7) unstable; urgency=low * Update to bbdb-vcard 0.2, which no longer uses convcard * Switch to dpkg-source 3.0 (quilt) format * Build dependency on texlive-latex-base (closes: #577860) -- Barak A. Pearlmutter Mon, 19 Apr 2010 09:59:29 +0100 bbdb (2.35.cvs20080316-6) unstable; urgency=low * Update bbdb-vcard * Suggest multisync-tools for convcard used (default) by bbdb-vcard * Use dpkg-source 1.0 format, as 3.0 (git) cannot handle submodules -- Barak A. Pearlmutter Sat, 27 Mar 2010 10:31:32 +0000 bbdb (2.35.cvs20080316-5) unstable; urgency=low * fiddle with info stuff for robustness * require emacs at build, avoiding extras install problem (closes: #571686) * include bbdb-vcard in bits tarball -- Barak A. Pearlmutter Tue, 09 Mar 2010 16:20:16 +0000 bbdb (2.35.cvs20080316-4) unstable; urgency=low * prevent debian build-time error when emacs not installed (closes: #571434) * rev deb std -- Barak A. Pearlmutter Fri, 26 Feb 2010 09:04:09 +0000 bbdb (2.35.cvs20080316-3) unstable; urgency=low * chmod +x configure patch, thanks to Kumar Appaiah (closes: #567197) -- Barak A. Pearlmutter Wed, 03 Feb 2010 13:43:30 +0000 bbdb (2.35.cvs20080316-2) unstable; urgency=low * Misc additional files in bits/ * Minor packaging tweaks * Build dependency for /usr/bin/tex (closes: #560582) -- Barak A. Pearlmutter Sun, 27 Dec 2009 20:26:22 -0500 bbdb (2.35.cvs20080316-1) unstable; urgency=low * Merge ongoing changes from upstream. (Closes: #440191) - Includes menu commands (Closes: #96300) - Fixes lisp/Makefile.in target extras mixing .el .elc (Closes: #366059) * Bring into GIT. * Regenerate debian/Makepatch to accommodate upstream changes. * Fix RMAIL insinuation in Emacs 23. (Closes: #556993) * Apply bbdb startup patch from Peter S Galbraith. (Closes: #353937) * Correct typo. (Closes: #488729) * Update backquote style in file lisp/bbdb-com.el. (Closes: #475600) * Update Debian packaging. - Avoiding double-installing bbdb-pilot-jwz.el file. (Closes: #557356) - Avoiding double-installing .tex files. - dh 7. - rev deb std. - debian/copyright updates: FSF address, common license location, expand. - Misc housekeeping and tracking policy. - Give debian patch files consistent names and locations. * Switch scripts from /usr/bin/bbdb-FOO.pl to /usr/bin/bbdb-FOO. * Merge Ununtu patch that symlinks some .el files at emacsen-install time. * Include PDF documentation. * Add Barak A. Pearlmutter as co-maintainer. -- Barak A. Pearlmutter Tue, 01 Dec 2009 22:10:39 -0500 bbdb (2.35.cvs20060204-1.2) unstable; urgency=low * NMU with the permission of the maintainer to adjust the dependencies to accommodate the removal of emacs21. Change the emacs21 dependency to emacs23 and the emacs21 build dependency to emacs22 or emacs23. Thanks to Sven Joachim . (Closes: #478799) -- Rob Browning Sat, 01 Aug 2009 12:16:02 -0700 bbdb (2.35.cvs20060204-1.1) unstable; urgency=low * NMU with the permission of the maintainer. * Set coding system when writing .bbdb file to prevent data corruption. (Closes: #351778) -- Hubert Chan Thu, 13 Apr 2006 15:42:40 +0200 bbdb (2.35.cvs20060204-1) unstable; urgency=low * New CVS co - Bug fix: "bbdb-news-auto-create-p with 'prompt doesn't work" (Closes: #296577). * Bug fix: "bbdb: File error: "Cannot open load file", 'bbdb-autoloads'" (Closes: #344032, #345186, #345297, #350449, #308336, #279920). * Bug fix: "bbdb does not work with gnus-5.10", (works for me [TM]) (Closes: #192904). -- Joerg Jaspert Sat, 4 Feb 2006 16:32:31 +0100 bbdb (2.35.cvs20040528-1) unstable; urgency=low * CVS co - last changes there are from 28.05.2004 * Bug fix: "fails to load : missing bbdb-vm.el". (Closes: #179821, #180024, #210248, #233904). * Removed | emacs20 from Depends. (Closes: #232731) * Removed old w3-el-e{20|19} Suggests. * Bug fix: "bbdb: Include /usr/share/emacs/site-lisp/bbdb/tex/", thanks to Mario Lang (Closes: #243211). -- Joerg Jaspert Wed, 11 Aug 2004 23:12:05 +0200 bbdb (2.35.cvs20030801-1) unstable; urgency=low * CVS from 01 August 2003. -- Joerg Jaspert Sun, 24 Aug 2003 14:51:51 +0200 bbdb (2.34.cvs20030503-1) unstable; urgency=low * CVS from 03 Mai 2003. * Removed a suggestion about charsets in .bbdb. It should work without that (closes: #177625) -- Joerg Jaspert Sat, 3 May 2003 20:16:15 +0200 bbdb (2.34.cvs20030102-1) unstable; urgency=low * CVS checkout from 02 Januar 2003. * A note in README.Debian about charsets and .bbdb. (closes: #174006,173817) * This patch for encoding issues is included upstream (closes: #159339) * Standards 3.5.8 -- Joerg Jaspert Sun, 5 Jan 2003 15:38:42 +0100 bbdb (2.34.cvs20021102-1) unstable; urgency=low * Newest CVS Checkout. Well, new.... -- Joerg Jaspert Wed, 13 Nov 2002 21:02:25 +0100 bbdb (2.34.cvs20021027-1) unstable; urgency=low * Newest CVS checkout. This is really 2.35 :) * Standards-Version: 3.5.7 * Removed mk-binary from debian/ dir, it is not used. -- Joerg Jaspert Sun, 27 Oct 2002 16:09:56 +0100 bbdb (2.34.cvs20020819-1) unstable; urgency=low * Newest CVS checkout. -- Joerg Jaspert Tue, 20 Aug 2002 22:20:26 +0200 bbdb (2.34.cvs20020703-1) unstable; urgency=low * Newest cvs checkout. * (require 'bbdb-autloads) in startup file (closes: #152435) -- Joerg Jaspert Wed, 10 Jul 2002 12:03:34 +0200 bbdb (2.34.cvs20020418-3) unstable; urgency=low * Added bbdb-pilot-jwz.el as suggested in (closes: #144465) I dont have a handheld, so i cant test it. (Hint :) ) -- Joerg Jaspert Fri, 26 Apr 2002 00:13:03 +0200 bbdb (2.34.cvs20020418-2) unstable; urgency=high * Urgency=high because the Bugfix for #143463 should really go into woody. I have not made any other changes in the emacsen-install files, and there are no Bug Reports since my last Upload, so i think this is OK. * I now generate some html Pages from the texinfo Source and install the doc-base things. So you can read the bbdb documentation from your Webbrowser if you want that. -- Joerg Jaspert Sun, 21 Apr 2002 20:02:31 +0200 bbdb (2.34.cvs20020418-1) unstable; urgency=low * New Upstream release. This fixes bbdb-gui which (closes: #143463) * Changed my Email Address. -- Joerg Jaspert Thu, 18 Apr 2002 20:53:56 +0200 bbdb (2.34.cvs20020404-2) unstable; urgency=low * Changed emacsen-install: Hide make autoloads output for the user and redirect it to the Compile-Log Tell the User that the Byte-Compile of bbdb could be a long-running process. -- Joerg Jaspert (JJ) Mon, 8 Apr 2002 15:42:46 +0200 bbdb (2.34.cvs20020404-1) unstable; urgency=low * If a Variable in Makefile changes between two releases it is very helpful to change it in the calling installscript too. Thx to James LewisMoss for this. This (closes: #141207) * New CVS checkout. bbdb-merge.el changed. * I now package the bits/ subdir with bbdb. It is *not* official part of bbdb. So i only make a .tar.gz of it and place it into /usr/share/doc/bbdb. Have a look at it and see if you find some things useful. If there is enough demand for one thing i can install it with bbdb (if License is clear). -- Joerg Jaspert (JJ) Thu, 4 Apr 2002 23:48:32 +0200 bbdb (2.34.cvs20020330-4) unstable; urgency=low * Im so stupid blind. bbdb needs bbdb-autoloads.el. I must generate it before i compile the package at install-time. If not we have a not existing bbdb-autoloads.el so bbdb cant load anything and crashes. Argh, i hate me. I shold read INSTALL full. Next time... I now generate bbdb-autoloads.el and bbdb works again. Sorry for this stupidity. It (closes: #140968) -- Joerg Jaspert (JJ) Wed, 3 Apr 2002 19:45:36 +0200 bbdb (2.34.cvs20020330-3) unstable; urgency=low * Hmm, i should look if I really remove all installed files between my tests. I left some crap and all worked fine. So i cant see that Makefile.in is neccessary. Added it again. * Apply a patch to the Makefile in /usr/share/emacs/site-lisp which really should remove checking for configure.ac. This two should (closes: #140868) -- Joerg Jaspert (JJ) Tue, 2 Apr 2002 12:38:53 +0200 bbdb (2.34.cvs20020330-2) unstable; urgency=low * It now works to look at the bbdb info files with emacs, so this should (closes: #111769) * It should also (closes: #139287) * Argh. If i want to install the info files without dh_installinfo i have to copy them to the Packagedir. * Suggest tetex-base. * Install the .tex files for bbdb-print in /usr/share/texmf/tex/bbdb so one can use bbdb-print without any extra work required. This two changes are for this: (closes: #101282) * -1 was not uploaded. So i just close the bug here again. New Maintainer. (closes: #140041) * gzip -9 for Readme.Debain * Remove unneccessary Makefile.in from bbdb/lisp dir. -- Joerg Jaspert (JJ) Mon, 1 Apr 2002 13:44:19 +0200 bbdb (2.34.cvs20020330-1) unstable; urgency=low * New Maintainer. (closes: #140041) * My first Emacs-addon Package. Hope it works. * New Version. Used CVS from 30 March 2002 * Added w3-el-e21 to Suggests. * Changed URL in debian/copyright to point to right Site. * Changed Path for License to /usr/share/common-license * Disabled dh_installinfo in debian/rules. We do it manually so we dont need to double it. * Dont install Upstream README. Its just four words: Read the INSTALL file. We dont need this for a Debian Package. :) * Remove Files generated by configure or build-process which are not removed by Upstream Makefiles clean target. * Changed Depends to emacs21 | emacsen to make Lintian happy. * Wrote manpages for the 4 Perlskripts. Better than a link to dh_undocumented. * Use sed to change the Target all in the Makefiles so emacs-install could work. We dont want to check for configure there so we dont check for it. :) -- Joerg Jaspert (JJ) Sun, 31 Mar 2002 20:15:42 +0200 bbdb (2.32-2) unstable; urgency=low * don't install FLAVOR/etc/bbdb (closes: #123612) tex be isntalled into document directory utils/*.el be installed into site-lisp/bbdb with byte-compile utils/*.pl be installed into /usr/bin/ * install /etc/emacs/site-start.d/50bbdb.el as conffile * Build-Depends: debhelper (>> 3.0.0) * Standards-Version: 3.5.2 * DH_COMPAT=3 -- Takuo KITAME Thu, 13 Dec 2001 00:45:23 +0900 bbdb (2.32-1) unstable; urgency=low * New upstream release * fixed bashizm of emacsen-install (closes: Bug#98574) * remove (require 'message) from init.el (closes: Bug#109062) -- Takuo KITAME Sat, 25 Aug 2001 11:23:09 +0900 bbdb (2.3-2) unstable; urgency=low * debian/emacsen-install: insert (provide 'bbdb-autoloads) if not xemacs20 or xemacs21. (closes: Bug#88471) -- Takuo KITAME Mon, 5 Mar 2001 00:24:20 +0900 bbdb (2.3-1) unstable; urgency=low * New upstream release * some upstream bug ware fixed (closes: Bug#86816,Bug#83920,Bug#83601) * fix #85283: bbdb doesn't load bbdb-autoload (closes: Bug#85283) * fix #82338: bbdb: upgrade leaves files behind (closes: Bug#82338) * fix #85019: bbdb complains about nonexistent directory (closes: Bug#85019) * fix #78721: calls switch-to-buffer(-1) on exit, xemacs doesn't like this (closes: Bug#78721) -- Takuo KITAME Sun, 4 Mar 2001 02:51:34 +0900 bbdb (2.2-1) unstable; urgency=low * New upstream release * cloese: #82338: bbdb: upgrade leaves files behind * closes: #81653: bbdb-complete-name fails, * closes: #78564: bbdb breaks gnus * closes: #80838: bbdb: perl scripts broken -- Takuo KITAME Fri, 26 Jan 2001 11:57:09 +0900 bbdb (2.00.06.20001116cvs-1) unstable; urgency=low * New upstream release -- Takuo KITAME Wed, 29 Nov 2000 08:22:33 +0900 bbdb (2.00.06.20001015cvs-3) unstable; urgency=low * Support xemacs21 (clsoes: Bug#76254) -- Takuo KITAME Mon, 13 Nov 2000 10:21:54 +0900 bbdb (2.00.06.20001015cvs-2) unstable; urgency=low * install info * debian/bbdb-init.el: (require 'bbdb) (bbdb-initialize) * lisp/bbdb.el: at defun bbdb-insinuate-message, (if (not (boundp 'message-mode-map)) (require 'message)) (closes: Bug#74998) -- Takuo KITAME Wed, 18 Oct 2000 11:04:30 +0900 bbdb (2.00.06.20001015cvs-1) unstable; urgency=low * New upstream release (CVS snapshot) * closes: Bug#72315 bbdb 2.00 is known not to work with Emacs 20. * debian/control: Suggests: w3-el-e20|w3-el-e19 instead of w3-el. (closes: Bug#74194) * put perl script. (closes: Bug#72481) * from lisp/bbdb-hooks.el, ;; Revision 1.58 2000/04/05 17:09:06 bbdb-writer ;; * Autoload cookie for bbdb-header-start It seems Bug#69182 was fixed. (closes: Bug#69182) * (setq bbdb-electric-p t) is worked. I think it was fixed by Upstream. (closes: Bug#52453) * applied view-mode -1 patch. (closes: Bug#48805) -- Takuo KITAME Tue, 17 Oct 2000 16:06:12 +0900 bbdb (2.00.06-1) unstable; urgency=low * New upstream release (closes: Bug#48316, Bug#19262) * Work well on XEmacs (closes: Bug#12086) * removing usr/share/xemacs20/etc/bbdb when package remove. It was fixed in previous release. (closes: Bug#52527) * install.log will be created as mode 644. (closes: Bug#55433) -- Takuo KITAME Wed, 29 Mar 2000 03:09:33 +0900 bbdb (2.00-6) frozen unstable; urgency=high * Maintainer was changed. * Fixed install script for bbdb-gnus.el (closes: Bug#59177) -- Takuo KITAME Tue, 28 Mar 2000 13:30:34 +0900 bbdb (2.00-5) unstable frozen; urgency=high * ignore xemacs21 in the install stage. Closes: Bug#55432. -- Frederic Lepied Thu, 24 Feb 2000 09:36:47 +0100 bbdb (2.00-4) unstable; urgency=low * applied documentation fixes from . Closes: Bug#36225. * (bbdb-print.el): corrected invalid condition-case. Closes: Bug#36846, Bug#44355, Bug#44364. * removed itimer Suggests:. * really install README.debian. Closes: Bug#26687. * (bbdb-print.el): hard code the location of TeX files. CLoses: Bug#36844. * (bbdb-print.tex): applied patch from Mattia Monga to correct the size of tt fonts. Closes: Bug#41268. * avoid aborting the install when a file failed to compile. Closes: Bug#37373, Bug#40379. -- Frederic Lepied Tue, 14 Sep 1999 21:57:24 +0200 bbdb (2.00-3) frozen unstable; urgency=low * (install): added vm target for xemacs19 and xemacs20. Fixes Bug#21940. * (install): corrected echo placement. Fixes Bug#21496. * (install): suppressed duplicate. Fixes Bug#21497. * (README.debian): new file to explain how to initialize bbdb. Fixes Bug#21497. -- Frederic Lepied Mon, 4 May 1998 05:56:21 +0200 bbdb (2.00-2) frozen unstable; urgency=low * (control): added a dependency on make. * (control): priority optional. * (control): suggests vm, w3-el, gnuserv and itimer. * (install): byte compile with -no-site-file. -- Frederic Lepied Sun, 19 Apr 1998 08:11:15 +0200 bbdb (2.00-1) unstable; urgency=low * new upstream version. -- Frederic Lepied Wed, 18 Mar 1998 21:45:28 +0100 bbdb (1.55unoff-1.1) unstable; urgency=low * Non-maintainer release. * Updated for new emacsen requirements. * Removed empty README.Debian file. * Removed debmake dependencies--made it easier to fix everything else. * Updated to standards 2.4.0.0. -- Ben Pfaff Thu, 5 Mar 1998 11:48:24 -0500 bbdb (1.55unoff-1) unstable; urgency=low * upstream release. * removed gnus-bbdb.el for lack of copyright and integration into upstream bbdb-gnus. -- Frederic Lepied Sun, 26 Oct 1997 11:34:06 +0100 bbdb (1.54unoff-1) unstable; urgency=low * new maintainer. * new upstream release. * Added the missing P binding for bbdb-print in bbdb.el. * Added gnus-bbdb.el to work with newer version of gnus. -- Frederic Lepied Fri, 17 Oct 1997 22:54:11 +0200 debian/bbdb.emacsen-startup0000664000000000000000000000160112056121450013110 0ustar ;; bbdb startup file for Debian. ;; Modified by Peter S Galbraith to skip loading when ;; bbdb is not fully installed, as this file still exists when the ;; package is removed but not purged. (cond ((not (file-exists-p "/usr/share/emacs/site-lisp/bbdb")) (message "Package bbdb removed but not purged. Skipping setup.")) ((not (file-exists-p (concat "/usr/share/" (symbol-name debian-emacs-flavor) "/site-lisp/bbdb/bbdb-autoloads.elc"))) (message "Package bbdb not fully installed. Skipping setup.")) (t (debian-pkg-add-load-path-item (concat "/usr/share/" (symbol-name debian-emacs-flavor) "/site-lisp/bbdb")) ;; (require 'message) ;; http://bugs.debian.org/85019 (setq bbdb-sound-files nil) (setq bbdb-sound-player nil) (setq bbdb-sounds-directory nil) ;; (require 'bbdb) ;; (bbdb-initialize) (require 'bbdb-autoloads))) debian/bbdb.manpages0000664000000000000000000000013312056121450011567 0ustar debian/bbdb-areacode-split.1 debian/bbdb-cid.1 debian/bbdb-srv.1 debian/bbdb-unlazy-lock.1 debian/control0000664000000000000000000000171412323027436010600 0ustar Source: bbdb Section: mail Priority: optional Maintainer: Ubuntu Developers XSBC-Original-Maintainer: Joerg Jaspert Uploaders: Barak A. Pearlmutter Build-Depends: debhelper (>= 8), autotools-dev (>= 20100122.1~) Build-Depends-Indep: texinfo, texi2html, ghostscript, texlive-base, texlive-latex-base, emacs24-nox | emacs24 | emacs Standards-Version: 3.9.1 Vcs-Git: git://github.com/barak/BBDB.git Vcs-Browser: http://github.com/barak/BBDB Homepage: http://bbdb.sourceforge.net/ Package: bbdb Architecture: all Depends: make, emacs24 | emacsen, ${misc:Depends}, ${perl:Depends} Suggests: vm, w3m-el, gnuserv, gnus|t-gnus, perl Description: The Insidious Big Brother Database (email rolodex) for Emacs BBDB is a rolodex-like database program for GNU Emacs. BBDB stands for Insidious Big Brother Database, and is not, repeat, *not* an obscure reference to the Buck Rogers TV series. debian/bbdb.emacsen-remove0000775000000000000000000000135012056121452012711 0ustar #!/bin/sh # /usr/lib/emacsen-common/packages/remove/bbdb # I don't think that remove scripts should have -e set, because # that makes the package unremovable if the script fails. # set -e FLAVOR=$1 PACKAGE="bbdb" if [ "X${FLAVOR}" = "X" ]; then echo Need argument to determine FLAVOR of emacs; exit 1 fi if [ "X${PACKAGE}" = "X" ]; then echo Internal error: need package name; exit 1; fi ELDIR=/usr/share/emacs/site-lisp/${PACKAGE} ELCDIR=/usr/share/${FLAVOR}/site-lisp/${PACKAGE} case "${FLAVOR}" in emacs) echo "remove/${PACKAGE}: Ignoring Flavor ${FLAVOR} ..." ;; *) echo -n "remove/${PACKAGE}: Handling removal of emacsen flavor ${FLAVOR} ..." rm -rf ${ELCDIR} echo " done." ;; esac exit 0; debian/bbdb-srv.10000664000000000000000000000420512056121450010750 0ustar .\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH BBDB-SRV.PL 1 "March 31, 2002" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: .\" .nh disable hyphenation .\" .hy enable hyphenation .\" .ad l left justify .\" .ad b justify to both left and right margins .\" .nf disable filling .\" .fi enable filling .\" .br insert line break .\" .sp insert n+1 empty lines .\" for manpage-specific macros, see man(7) .SH NAME bbdb-srv \- Converts Mail-Headers to an Emacs-Lisp String. .SH SYNOPSIS .B echo "Some Headers" | bbdb-srv .SH DESCRIPTION This script reads a block of message headers on stdin, and converts them to an emacs-lisp string (quoting all dangerous characters) and then uses the `gnudoit' program to cause a running Emacs process to invoke the `bbdb-srv' function with that string. This has the effect of causing the running Emacs to display the BBDB record corresponding to these headers. See the Emacs side of things in bbdb-srv.el for more info. A trivial application of this is the shell command: echo 'From: Jamie Zawinski ' | bbdb-srv.perl which will cause the corresponding record to be displayed. A more interesting application of this is: setenv NS_MSG_DISPLAY_HOOK bbdb-srv.perl which will hook BBDB up to Mozilla (Unix Netscape Mail and Netscape News versions 3.0b2 and later only.) This manual page was written for the Debian distribution because the original program does not have a manual page. Instead, it has documentation in the GNU Info format; see below. .SH SEE ALSO .BR bbdb-areacode-split (1), .BR bbdb-unlazy-lock (1). .BR bbdb-srv (1). .br The bbdb is fully documented by .IR "The insidious Big Brother Database for mail and news" , available via the Infonode .BR bbdb . .SH AUTHOR This manual page was written by Joerg Jaspert (JJ) , for the Debian GNU/Linux system (but may be used by others). debian/rules0000775000000000000000000000171612056121453010254 0ustar #!/usr/bin/make -f build clean install binary-arch binary-indep binary: dh $@ --with autotools_dev --parallel .PHONY: build clean install binary-arch binary-indep binary override_dh_auto_configure: if [ ! -x configure ]; then chmod +x configure; fi # debian.diff fails to +x dh_auto_configure override_dh_auto_build: bits.tar.gz $(MAKE) -C texinfo bbdb.info bbdb.pdf texi2html --split=chapter --output=texinfo/bbdb texinfo/bbdb.texinfo override_dh_install: dh_install @echo Give perl executables to implementation-agnostic filenames cd debian/bbdb/usr/bin && \ for f in *.pl; do \ mv $$f $$(basename $$f .pl); \ done @echo Apply Debian patches for f in $$(find debian/patches -name '*.patch'); do \ echo applying patch: $$f ; \ d=debian/bbdb/usr/share/emacs/site-lisp/bbdb ; \ patch $$d/$$(echo $$f | sed 's|^debian/patches/\(.*\)[.]patch$$|\1|') $$f; \ done bits.tar.gz: tar -cf - extern/*/* | tar -C bits -xvf - tar -czf bits.tar.gz bits/ debian/bbdb-areacode-split.10000664000000000000000000000335312056121450013035 0ustar .\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH BBDB-AREACODE-SPLIT.PL 1 "March 31, 2002" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: .\" .nh disable hyphenation .\" .hy enable hyphenation .\" .ad l left justify .\" .ad b justify to both left and right margins .\" .nf disable filling .\" .fi enable filling .\" .br insert line break .\" .sp insert n+1 empty lines .\" for manpage-specific macros, see man(7) .SH NAME bbdb-areacode-split \- Looks for phone numbers in your .bbdb .SH SYNOPSIS .B bbdb-areacode-split [bbdb] .SH DESCRIPTION Looks for phone numbers in your .bbdb with a particular area code and one of a set of exchanges and changes the area code. The old and new area codes are specified on the command line, as is the location of a file that contains the exchanges that are being changed. (The format of that file is very loose. Every three digit sequence will be used.) This manual page was written for the Debian distribution because the original program does not have a manual page. Instead, it has documentation in the GNU Info format; see below. .SH SEE ALSO .BR bbdb-cid (1), .BR bbdb-unlazy-lock (1). .BR bbdb-srv (1). .br The bbdb is fully documented by .IR "The insidious Big Brother Database for mail and news" , available via the Infonode .BR bbdb . .SH AUTHOR This manual page was written by Joerg Jaspert (JJ) , for the Debian GNU/Linux system (but may be used by others). debian/watch0000664000000000000000000000030212056121452010212 0ustar version=3 http://githubredir.debian.net/github/barak/BBDB \ /github/barak/BBDB/BBDB\.([0-9].*).tar.gz http://githubredir.debian.net/github/barak/BBDB \ /github/barak/BBDB/upstream/(.*).tar.gz debian/patches/0000775000000000000000000000000012056121453010616 5ustar debian/patches/Makefile.patch0000664000000000000000000000107012056121450013347 0ustar --- Makefile.orig 2009-11-17 16:13:19.000000000 -0500 +++ Makefile 2009-11-17 16:16:25.000000000 -0500 @@ -16,18 +16,7 @@ aclocal.m4 configure configure.ac install-sh Makefile.in \ bits lisp misc tex texinfo utils -all: Makefile bbdb info gnus - -Makefile:: Makefile.in - ./config.status - -Makefile:: configure - @echo "Configure has changed, you may need to rerun configure!" - exit 1 - -configure: configure.ac - @echo "configure.ac has changed. Please rerun autoconf!" - exit 1 +all: bbdb info gnus bbdb: cd lisp; $(MAKE) bbdb debian/patches/lisp/0000775000000000000000000000000012056121450011562 5ustar debian/patches/lisp/Makefile.patch0000664000000000000000000000072412056121450014323 0ustar *** lisp/Makefile 2009-11-21 19:43:53.000000000 -0500 --- debian/bbdb/usr/share/emacs/site-lisp/bbdb/lisp/Makefile 2009-11-21 20:27:35.000000000 -0500 *************** *** 56,64 **** all: Makefile gnus bbdb autoloadsc - Makefile: Makefile.in - cd ..; ./config.status - install-pkg: uninstall-pkg bbdb autoloadsc @if test "x$(SYMLINKS)" = "xno" ; then \ mkdir -p -m 0755 $(PACKAGEDIR)/lisp/bbdb; \ --- 56,61 ---- debian/patches/series0000664000000000000000000000002612056121453012031 0ustar debian-changes-2.36-2 debian/patches/debian-changes-2.36-20000664000000000000000000047261212056121453014132 0ustar Description: Upstream changes introduced in version 2.36-2 This patch has been created by dpkg-source during the package build. Here's the last changelog entry, hopefully it gives details on why those changes were made: . bbdb (2.36-2) unstable; urgency=low . * Update to bbdb-vcard 0.3, which better parses birthdays * bump standards version (debian/changelog) * bump to dh 8, dh --parallel, dh --with autotools_dev (debian/compat, debian/control, debian/rules) * rephrase for grammar and Moore's Law (debian/bbdb.emacsen-install) (closes: #440192, #540539) . The person named in the Author field signed this changelog entry. Author: Barak A. Pearlmutter Bug-Debian: http://bugs.debian.org/440192 Bug-Debian: http://bugs.debian.org/540539 --- The information above should follow the Patch Tagging Guidelines, please checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here are templates for supplementary fields that you might want to add: Origin: , Bug: Bug-Debian: http://bugs.debian.org/ Bug-Ubuntu: https://launchpad.net/bugs/ Forwarded: Reviewed-By: Last-Update: --- bbdb-2.36.orig/ChangeLog +++ bbdb-2.36/ChangeLog @@ -1,3 +1,12 @@ +2010-06-03 Barak A. Pearlmutter + + * texinfo/bbdb.texinfo: include pointers to github repo. + +2010-09-29 Julien Danjou + + * lisp/bbdb-gnus.el (bbdb/gnus-split-myaddr-regexp): Remove usage + of deprecated gnus-local-domain. + 2010-04-20 Barak A. Pearlmutter * README: Emacs, meaning both GNU Emacs and XEmacs. --- bbdb-2.36.orig/configure.ac +++ bbdb-2.36/configure.ac @@ -23,7 +23,7 @@ dnl Inc., 675 Mass Ave, Cambridge, MA 02 dnl Process this file with autoconf to produce a new configure script -AC_PREREQ(2.65) +AC_PREREQ([2.67]) BBDB_PRE_INIT AC_INIT([BBDB],[BBDB_VERSION],[bbdb-info@lists.sourceforge.net]) --- bbdb-2.36.orig/configure +++ bbdb-2.36/configure @@ -1,13 +1,13 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.65 for BBDB 2.36. +# Generated by GNU Autoconf 2.67 for BBDB 2.36. # # Report bugs to . # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. # # # This configure script is free software; the Free Software Foundation @@ -320,7 +320,7 @@ $as_echo X"$as_dir" | test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p @@ -360,19 +360,19 @@ else fi # as_fn_arith -# as_fn_error ERROR [LINENO LOG_FD] -# --------------------------------- +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with status $?, using 1 if that was 0. +# script with STATUS, using 1 if that was 0. as_fn_error () { - as_status=$?; test $as_status -eq 0 && as_status=1 - if test "$3"; then - as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi - $as_echo "$as_me: error: $1" >&2 + $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error @@ -534,7 +534,7 @@ test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. -# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` @@ -713,8 +713,9 @@ do fi case $ac_option in - *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *) ac_optarg=yes ;; + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. @@ -759,7 +760,7 @@ do ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error "invalid feature name: $ac_useropt" + as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -785,7 +786,7 @@ do ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error "invalid feature name: $ac_useropt" + as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -989,7 +990,7 @@ do ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error "invalid package name: $ac_useropt" + as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1005,7 +1006,7 @@ do ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error "invalid package name: $ac_useropt" + as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1035,8 +1036,8 @@ do | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; - -*) as_fn_error "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information." + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" ;; *=*) @@ -1044,7 +1045,7 @@ Try \`$0 --help' for more information." # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error "invalid variable name: \`$ac_envvar'" ;; + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; @@ -1062,13 +1063,13 @@ done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error "missing argument to $ac_option" + as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; - fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi @@ -1091,7 +1092,7 @@ do [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac - as_fn_error "expected an absolute directory name for --$ac_var: $ac_val" + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' @@ -1105,8 +1106,8 @@ target=$target_alias if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe - $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used." >&2 + $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi @@ -1121,9 +1122,9 @@ test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error "working directory cannot be determined" + as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error "pwd does not report name of working directory" + as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. @@ -1162,11 +1163,11 @@ else fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error "cannot find sources ($ac_unique_file) in $srcdir" + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg" + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then @@ -1206,7 +1207,7 @@ Configuration: --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking...' messages + -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files @@ -1346,9 +1347,9 @@ test -n "$ac_init_help" && exit $ac_stat if $ac_init_version; then cat <<\_ACEOF BBDB configure 2.36 -generated by GNU Autoconf 2.65 +generated by GNU Autoconf 2.67 -Copyright (C) 2009 Free Software Foundation, Inc. +Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. @@ -1365,7 +1366,7 @@ This file contains any messages produced running configure, to aid debugging if configure makes a mistake. It was created by BBDB $as_me 2.36, which was -generated by GNU Autoconf 2.65. Invocation command line was +generated by GNU Autoconf 2.67. Invocation command line was $ $0 $@ @@ -1475,11 +1476,9 @@ trap 'exit_status=$? { echo - cat <<\_ASBOX -## ---------------- ## + $as_echo "## ---------------- ## ## Cache variables. ## -## ---------------- ## -_ASBOX +## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( @@ -1513,11 +1512,9 @@ $as_echo "$as_me: WARNING: cache variabl ) echo - cat <<\_ASBOX -## ----------------- ## + $as_echo "## ----------------- ## ## Output variables. ## -## ----------------- ## -_ASBOX +## ----------------- ##" echo for ac_var in $ac_subst_vars do @@ -1530,11 +1527,9 @@ _ASBOX echo if test -n "$ac_subst_files"; then - cat <<\_ASBOX -## ------------------- ## + $as_echo "## ------------------- ## ## File substitutions. ## -## ------------------- ## -_ASBOX +## ------------------- ##" echo for ac_var in $ac_subst_files do @@ -1548,11 +1543,9 @@ _ASBOX fi if test -s confdefs.h; then - cat <<\_ASBOX -## ----------- ## + $as_echo "## ----------- ## ## confdefs.h. ## -## ----------- ## -_ASBOX +## ----------- ##" echo cat confdefs.h echo @@ -1607,7 +1600,12 @@ _ACEOF ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then - ac_site_file1=$CONFIG_SITE + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site @@ -1622,7 +1620,11 @@ do { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5 ; } fi done @@ -1698,7 +1700,7 @@ if $ac_cache_corrupted; then $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## @@ -1728,7 +1730,7 @@ fi $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF @@ -1736,7 +1738,7 @@ SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF -# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; @@ -1757,16 +1759,22 @@ fi ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do - for ac_t in install-sh install.sh shtool; do - if test -f "$ac_dir/$ac_t"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/$ac_t -c" - break 2 - fi - done + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi done if test -z "$ac_aux_dir"; then - as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, @@ -2268,12 +2276,12 @@ done fi if test "x${EMACS_PROG}" = "x" ; then - as_fn_error "*** No Emacs program found." "$LINENO" 5 + as_fn_error $? "*** No Emacs program found." "$LINENO" 5 fi if test -x "${EMACS_PROG}"; then echo "yay" > /dev/null # because I don't know if 'if !' is portable else - as_fn_error "*** ${EMACS_PROG} isn't executable." "$LINENO" 5 + as_fn_error $? "*** ${EMACS_PROG} isn't executable." "$LINENO" 5 fi if test "x`echo $EMACS_PROG | grep \" \"`" != "x"; then EMACS_PROG=\"$EMACS_PROG\" @@ -2390,7 +2398,7 @@ BBDB_LOADPATH="${ac_confdir}/loadpath.el if test "x$enable_vm" != "x"; then BBDB_VM=`${EMACS_PROG} --no-site-file --no-init-file -batch -q -l ${BBDB_LOADPATH} -eval "(if (locate-library \"vm-autoload\") (message \"vm\"))" 2>&1` if test "x$BBDB_VM" = "x"; then - as_fn_error "*** Cannot build VM support without VM's source." "$LINENO" 5 + as_fn_error $? "*** Cannot build VM support without VM's source." "$LINENO" 5 fi fi @@ -2595,6 +2603,7 @@ DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= +U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' @@ -2756,19 +2765,19 @@ export LANGUAGE (unset CDPATH) >/dev/null 2>&1 && unset CDPATH -# as_fn_error ERROR [LINENO LOG_FD] -# --------------------------------- +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with status $?, using 1 if that was 0. +# script with STATUS, using 1 if that was 0. as_fn_error () { - as_status=$?; test $as_status -eq 0 && as_status=1 - if test "$3"; then - as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi - $as_echo "$as_me: error: $1" >&2 + $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error @@ -2964,7 +2973,7 @@ $as_echo X"$as_dir" | test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p @@ -3018,7 +3027,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_wri # values after options handling. ac_log=" This file was extended by BBDB $as_me 2.36, which was -generated by GNU Autoconf 2.65. Invocation command line was +generated by GNU Autoconf 2.67. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -3071,10 +3080,10 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_writ ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ BBDB config.status 2.36 -configured by $0, generated by GNU Autoconf 2.65, +configured by $0, generated by GNU Autoconf 2.67, with options \\"\$ac_cs_config\\" -Copyright (C) 2009 Free Software Foundation, Inc. +Copyright (C) 2010 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -3090,11 +3099,16 @@ ac_need_defaults=: while test $# != 0 do case $1 in - --*=*) + --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; *) ac_option=$1 ac_optarg=$2 @@ -3116,6 +3130,7 @@ do $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; @@ -3126,7 +3141,7 @@ do ac_cs_silent=: ;; # This is an error. - -*) as_fn_error "unrecognized option: \`$1' + -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" @@ -3182,7 +3197,7 @@ do "utils/Makefile") CONFIG_FILES="$CONFIG_FILES utils/Makefile" ;; "testing/Makefile") CONFIG_FILES="$CONFIG_FILES testing/Makefile" ;; - *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;; esac done @@ -3218,7 +3233,7 @@ $debug || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") -} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5 +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. @@ -3235,7 +3250,7 @@ if test "x$ac_cr" = x; then fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\r' + ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi @@ -3249,18 +3264,18 @@ _ACEOF echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || - as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || - as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then - as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi @@ -3349,20 +3364,28 @@ if sed "s/$ac_cr//" < /dev/null > /dev/n else cat fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ - || as_fn_error "could not setup config files machinery" "$LINENO" 5 + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF -# VPATH may cause trouble with some makes, so we remove $(srcdir), -# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=/{ -s/:*\$(srcdir):*/:/ -s/:*\${srcdir}:*/:/ -s/:*@srcdir@:*/:/ -s/^\([^=]*=[ ]*\):*/\1/ + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// s/^[^=]*=[ ]*$// }' fi @@ -3380,7 +3403,7 @@ do esac case $ac_mode$ac_tag in :[FHL]*:*);; - :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac @@ -3408,7 +3431,7 @@ do [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || - as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;; + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" @@ -3435,7 +3458,7 @@ $as_echo "$as_me: creating $ac_file" >&6 case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin" \ - || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac @@ -3566,22 +3589,22 @@ s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ - || as_fn_error "could not create $ac_file" "$LINENO" 5 + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined." >&5 +which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined." >&2;} +which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out" && rm -f "$tmp/out";; *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; esac \ - || as_fn_error "could not create $ac_file" "$LINENO" 5 + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; @@ -3596,7 +3619,7 @@ _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || - as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5 + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. @@ -3617,7 +3640,7 @@ if test "$no_create" != yes; then exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit $? + $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 --- /dev/null +++ bbdb-2.36/extern/bbdb-vcard/bbdb-vcard.el @@ -0,0 +1,1136 @@ +;;; bbdb-vcard.el --- vCard import/export for BBDB + +;; Copyright (c) 2010 Bert Burgemeister + +;; Author: Bert Burgemeister +;; Keywords: data calendar mail news +;; URL: http://github.com/trebb/bbdb-vcard +;; Version: 0.3 + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;; The exporter functionality is based on code from +;; bbdb-vcard-export.el by Jim Hourihan and Alex Schroeder. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;; Commentary: +;; +;; Purpose +;; ======= +;; +;; Import and export of vCards as defined in RFC 2425 and RFC 2426 +;; to/from The Insidious Big Brother Database (BBDB). +;; +;; +;; Usage +;; ===== +;; +;; vCard Import +;; ------------ +;; +;; On a file, a buffer or a region containing one or more vCards, use +;; `bbdb-vcard-import-file', `bbdb-vcard-import-buffer', or +;; `bbdb-vcard-import-region' respectively to import them into BBDB. +;; +;; Preferred input format is vCard version 3.0. Version 2.1 vCards +;; are converted to version 3.0 on import. +;; +;; +;; vCard Export +;; ------------ +;; +;; In buffer *BBDB*, press v to export the record under point. Press +;; * v to export all records in buffer into one vCard file. Press * +;; C-u v to export them into one file each. +;; +;; To put one or all vCard(s) into the kill ring, press V or * V +;; respectively. +;; +;; Exported vCards are always version 3.0. They can be re-imported +;; without data loss with one exception: North American phone numbers +;; lose their structure and are stored as flat strings. +;; +;; +;; There are a few customization variables grouped under `bbdb-vcard'. +;; +;; +;; Installation +;; ============ +;; +;; Put this file and file vcard.el into your `load-path' and add the +;; following line to your Emacs initialization file: +;; +;; (require 'bbdb-vcard) +;; +;; +;; Implementation +;; ============== +;; +;; vCard Import +;; ------------ +;; +;; For conversion of v2.1 vCards into v3.0 on import, Noah Friedman's +;; vcard.el is needed. +;; +;; An existing BBDB record is extended by new information from a vCard +;; +;; (a) if name and company and an email address match +;; (b) or if name and company match +;; (c) or if name and an email address match +;; (d) or if name and birthday match +;; (e) or if name and a phone number match. +;; +;; Otherwise, a fresh BBDB record is created. +;; +;; When `bbdb-vcard-try-merge' is set to nil, there is always a fresh +;; record created. +;; +;; In cases (c), (d), and (e), if the vCard has ORG defined, this ORG +;; would overwrite an existing Company in BBDB. +;; +;; Phone numbers are always imported as strings. +;; +;; For vCard types that have more or less direct counterparts in BBDB, +;; labels and parameters are translated and structured values +;; (lastname; firstname; additional names; prefixes etc.) are +;; converted appropriately with the risk of some (hopefully +;; unessential) information loss. For labels of the vCard types ADR +;; and TEL, parameter translation is defined in +;; `bbdb-vcard-import-translation-table'. +;; +;; If there is a REV element, it is stored in BBDB's creation-date in +;; newly created BBDB records, or discarded for existing ones. Time +;; and time zone information from REV are stored there as well if +;; there are any, but are ignored by BBDB (v2.36). +;; +;; VCard type prefixes (A.ADR:..., B.ADR:... etc.) are stripped off +;; and discarded from the following types: N, FN, NICKNAME, ORG (first +;; occurrence), ADR, TEL, EMAIL, URL, BDAY (first occurrence), NOTE. +;; +;; VCard types that are prefixed `X-BBDB-' are stored in BBDB without +;; the prefix. +;; +;; VCard type X-BBDB-ANNIVERSARY may contain (previously exported) +;; newline-separated non-birthday anniversaries that are meant to be +;; read by org-mode. +;; +;; All remaining vCard types that don't match the regexp in +;; `bbdb-vcard-skip-on-import' and that have a non-empty value are +;; stored unaltered in the BBDB Notes alist where, for instance, +;; `TZ;VALUE=text:-05:00' is stored as `(tz\;value=text . "-05:00")'. +;; From the BBDB data fields AKA, Phones, Addresses, Net Addresses, +;; and Notes, duplicates are removed, respectively. +;; +;; VCards found inside other vCards (as values of type AGENT) are +;; imported as well. +;; +;; +;; Handling of the individual types defined in RFC2426 during import +;; (assuming default label translation and no vCard type exclusion): +;; " +;; |----------------------+----------------------------------------| +;; | VCARD TYPE; | STORAGE IN BBDB | +;; | PARAMETERS | | +;; |----------------------+----------------------------------------| +;; | VERSION | - | +;; |----------------------+----------------------------------------| +;; | N | First occurrence: | +;; | | Firstname | +;; | | Lastname | +;; | | | +;; | | Rest: | +;; | | AKAs (append) | +;; |----------------------+----------------------------------------| +;; | FN | AKAs (append) | +;; | NICKNAME | AKAs (append) | +;; |----------------------+----------------------------------------| +;; | ORG | First occurrence: | +;; | | Company | +;; | | | +;; | | Rest: | +;; | | Notes\ +If \"\\[bbdb-apply-next-command-to-all-records]\\[bbdb-vcard-export]\"\ +is used instead of simply \"\\[bbdb-vcard-export]\", then export all \ +records currently +in the *BBDB* buffer. If used with prefix argument, store records +in individual files." + (interactive + (let ((default-filename ; argument filename-or-directory + (bbdb-vcard-make-file-name (bbdb-current-record nil))) + (all-records-p (bbdb-do-all-records-p))) + (list + (if all-records-p + (if current-prefix-arg + (read-directory-name "Write vCard files to directory: " + bbdb-vcard-default-dir nil 42) + (read-file-name + "Write vCards to file: " + bbdb-vcard-default-dir + nil nil + (format-time-string "%Y-%m-%dT%H:%M.vcf" (current-time)))) + (read-file-name "Write current record to vCard file: " + bbdb-vcard-default-dir nil nil default-filename)) + all-records-p ; argument all-records-p + current-prefix-arg))) ; argument one-file-per-record-p + (if all-records-p + (let ((records (progn (set-buffer bbdb-buffer-name) + (mapcar 'car bbdb-records))) + used-up-basenames) ; keep them unique + (if one-file-per-record-p + (progn + (dolist (record records) + (with-temp-buffer + (let ((basename + (bbdb-vcard-make-file-name record + used-up-basenames))) + (insert (bbdb-vcard-from record)) + (bbdb-vcard-write-buffer + (concat filename-or-directory basename)) + (push basename used-up-basenames)))) + (message "Wrote %d vCards to %s" + (length used-up-basenames) filename-or-directory)) + (with-temp-buffer ; all visible BBDB records in one file + (dolist (record records) + (insert (bbdb-vcard-from record))) + (bbdb-vcard-write-buffer filename-or-directory)))) + (let ((vcard (bbdb-vcard-from (bbdb-current-record nil)))) ; current record + (with-temp-buffer + (insert vcard) + (bbdb-vcard-write-buffer filename-or-directory))))) + +;;;###autoload +(defun bbdb-vcard-export-to-kill-ring (all-records-p) + "From Buffer *BBDB*, copy one or more record(s) as vCard(s) to the kill ring. +\\\ +If \"\\[bbdb-apply-next-command-to-all-records]\ +\\[bbdb-vcard-export-to-kill-ring]\"\ +is used instead of simply \"\\[bbdb-vcard-export-to-kill-ring]\", \ +then export all records currently in +the *BBDB* buffer." + (interactive (let ((all-records-p (bbdb-do-all-records-p))) + (list all-records-p))) + (if all-records-p + (let ((records (progn (set-buffer bbdb-buffer-name) + (mapcar 'car bbdb-records)))) + (kill-new "") + (dolist (record records) + (kill-append (bbdb-vcard-from record) nil)) + (message "Saved %d records as vCards" (length records))) + (kill-new (bbdb-vcard-from (bbdb-current-record nil))) + (message "Saved record as vCard"))) + +;;;###autoload (define-key bbdb-mode-map [(v)] 'bbdb-vcard-export) +(define-key bbdb-mode-map [(v)] 'bbdb-vcard-export) +;;;###autoload (define-key bbdb-mode-map [(V)] 'bbdb-vcard-export-to-kill-ring) +(define-key bbdb-mode-map [(V)] 'bbdb-vcard-export-to-kill-ring) + + + +(defun bbdb-vcard-iterate-vcards (vcard-processor vcards) + "Apply VCARD-PROCESSOR successively to each vCard in string VCARDS. +When VCARDS is nil, return nil. Otherwise, return t." + (with-temp-buffer + (insert vcards) + (goto-char (point-min)) + ;; Change CRLF into CR if necessary, dealing with inconsistent line + ;; endings. + (while (re-search-forward "\r\n" nil t) + (replace-match "\n" nil nil nil 1)) + (setf (buffer-string) (bbdb-vcard-unfold-lines (buffer-string))) + (goto-char (point-min)) + (while (re-search-forward + "^\\([[:alnum:]-]*\\.\\)?*BEGIN:VCARD[\n[:print:][:cntrl:]]*?\\(^\\([[:alnum:]-]*\\.\\)?END:VCARD\\)" + nil t) + (let ((vcard (match-string 0))) + (if (string= "3.0" (bbdb-vcard-version-of vcard)) + (funcall vcard-processor vcard) + (funcall vcard-processor ; probably a v2.1 vCard + (bbdb-vcard-unfold-lines + (bbdb-vcard-convert-to-3.0 vcard)))))))) + +(defun bbdb-vcard-version-of (vcard) + "Return version number string of VCARD." + (with-temp-buffer + (insert vcard) + (car (bbdb-vcard-values-of-type "version" "value")))) + +(defun bbdb-vcard-import-vcard (vcard) + "Store VCARD (version 3.0) in BBDB. +Extend existing BBDB records where possible." + (with-temp-buffer + (insert vcard) + (let* ((raw-name (car (bbdb-vcard-values-of-type "N" "value" t t))) + ;; Name suitable for storing in BBDB: + (name (bbdb-vcard-unescape-strings + (bbdb-vcard-unvcardize-name raw-name))) + ;; Name to search for in BBDB now: + (name-to-search-for + (when raw-name (if (stringp raw-name) + raw-name + (concat (nth 1 raw-name) ;given name + " .*" + (nth 0 raw-name))))) ; family name + ;; Additional names from prefixed types like A.N, B.N, etc.: + (other-names + (mapcar + (lambda (n) + (bbdb-join (bbdb-vcard-unvcardize-name (cdr (assoc "value" n))) + " ")) + (bbdb-vcard-elements-of-type "N" nil t))) + (vcard-formatted-names (bbdb-vcard-unescape-strings + (bbdb-vcard-values-of-type "FN" "value"))) + (vcard-nicknames + (bbdb-vcard-unescape-strings + (bbdb-vcard-split-structured-text + (car (bbdb-vcard-values-of-type "NICKNAME" "value")) + "," t))) + ;; Company suitable for storing in BBDB: + (vcard-org + (bbdb-vcard-unescape-strings + (bbdb-vcard-unvcardize-org + (car (bbdb-vcard-values-of-type "ORG" "value" t t))))) + ;; Company to search for in BBDB now: + (org-to-search-for vcard-org) ; sorry + ;; Email suitable for storing in BBDB: + (vcard-email (bbdb-vcard-values-of-type "EMAIL" "value")) + ;; Email to search for in BBDB now: + (email-to-search-for + (when vcard-email + (concat "\\(" (bbdb-join vcard-email "\\)\\|\\(") "\\)"))) + ;; Phone numbers suitable for storing in BBDB: + (vcard-tels + (mapcar (lambda (tel) + (vector (bbdb-vcard-translate + (or (cdr (assoc "type" tel)) "")) + (cdr (assoc "value" tel)))) + (bbdb-vcard-elements-of-type "TEL"))) + ;; Phone numbers to search for in BBDB now: + (tel-to-search-for + (when vcard-tels + (concat "\\(" + (mapconcat (lambda (x) (elt x 1)) + vcard-tels "\\)\\|\\(") + "\\)"))) + ;; Addresses + (vcard-adrs + (mapcar 'bbdb-vcard-unvcardize-adr + (bbdb-vcard-elements-of-type "ADR" nil t))) + (vcard-url (car (bbdb-vcard-values-of-type "URL" "value" t))) + (vcard-notes (bbdb-vcard-values-of-type "NOTE" "value")) + (raw-bday (bbdb-vcard-unvcardize-date-time + (car (bbdb-vcard-values-of-type "BDAY" "value" t)))) + ;; Birthday suitable for storing in BBDB (usable by org-mode): + (vcard-bday (when raw-bday (concat raw-bday " birthday"))) + ;; Birthday to search for in BBDB now: + (bday-to-search-for vcard-bday) + ;; Non-birthday anniversaries, probably exported by ourselves: + (vcard-x-bbdb-anniversaries + (bbdb-vcard-split-structured-text + (car (bbdb-vcard-values-of-type "X-BBDB-ANNIVERSARY" "value")) + "\\\\n" t)) + (vcard-rev (bbdb-vcard-unvcardize-date-time + (car (bbdb-vcard-values-of-type "REV" "value")))) + (vcard-categories (bbdb-vcard-values-of-type "CATEGORIES" "value")) + ;; The BBDB record to change: + (record-freshness-info "BBDB record changed:") ; default user info + (bbdb-record + (or + ;; Try to find an existing one ... + ;; (a) try company and net and name: + (car (and bbdb-vcard-try-merge + (bbdb-vcard-search-intersection + (bbdb-records) + name-to-search-for + org-to-search-for email-to-search-for))) + ;; (b) try company and name: + (car (and bbdb-vcard-try-merge + (bbdb-vcard-search-intersection + (bbdb-records) name-to-search-for org-to-search-for))) + ;; (c) try net and name; we may change company here: + (car (and bbdb-vcard-try-merge + (bbdb-vcard-search-intersection + (bbdb-records) + name-to-search-for nil email-to-search-for))) + ;; (d) try birthday and name; we may change company here: + (car (and bbdb-vcard-try-merge + (bbdb-vcard-search-intersection + (bbdb-records) + name-to-search-for nil nil bday-to-search-for))) + ;; (e) try phone and name; we may change company here: + (car (and bbdb-vcard-try-merge + (bbdb-vcard-search-intersection + (bbdb-records) + name-to-search-for nil nil nil tel-to-search-for))) + ;; No existing record found; make a fresh one: + (let ((fresh-record (make-vector bbdb-record-length nil))) + (bbdb-record-set-cache fresh-record + (make-vector bbdb-cache-length nil)) + (if vcard-rev ; For fresh records, + (bbdb-record-putprop ; set creation-date from vcard-rev + fresh-record 'creation-date vcard-rev) + (bbdb-invoke-hook 'bbdb-create-hook fresh-record)) + (setq record-freshness-info "BBDB record added:") ; user info + fresh-record))) + (bbdb-akas (bbdb-record-aka bbdb-record)) + (bbdb-addresses (bbdb-record-addresses bbdb-record)) + (bbdb-phones (bbdb-record-phones bbdb-record)) + (bbdb-nets (bbdb-record-net bbdb-record)) + (bbdb-raw-notes (bbdb-record-raw-notes bbdb-record)) + notes + other-vcard-type) + (bbdb-vcard-elements-of-type "BEGIN") ; get rid of delimiter + (bbdb-vcard-elements-of-type "END") ; get rid of delimiter + (bbdb-vcard-elements-of-type "VERSION") ; get rid of this too + (when name ; which should be the case as N is mandatory in vCard + (bbdb-record-set-firstname bbdb-record (car name)) + (bbdb-record-set-lastname bbdb-record (cadr name))) + (bbdb-record-set-aka + bbdb-record + (remove (concat (bbdb-record-firstname bbdb-record) + " " (bbdb-record-lastname bbdb-record)) + (reduce (lambda (x y) (union x y :test 'string=)) + (list vcard-nicknames + other-names + vcard-formatted-names + bbdb-akas)))) + (when vcard-org (bbdb-record-set-company bbdb-record vcard-org)) + (bbdb-record-set-net + bbdb-record (union vcard-email bbdb-nets :test 'string=)) + (bbdb-record-set-addresses + bbdb-record (union vcard-adrs bbdb-addresses :test 'equal)) + (bbdb-record-set-phones bbdb-record + (union vcard-tels bbdb-phones :test 'equal)) + ;; prepare bbdb's notes: + (when vcard-url (push (cons 'www vcard-url) bbdb-raw-notes)) + (when vcard-notes + ;; Put vCard NOTEs under key 'notes (append if necessary). + (unless (assq 'notes bbdb-raw-notes) + (push (cons 'notes "") bbdb-raw-notes)) + (setf (cdr (assq 'notes bbdb-raw-notes)) + (bbdb-vcard-merge-strings + (cdr (assq 'notes bbdb-raw-notes)) + (bbdb-vcard-unescape-strings vcard-notes) + ";\n"))) + (when (or vcard-bday vcard-x-bbdb-anniversaries) + ;; Put vCard BDAY and vCard X-BBDB-ANNIVERSARY's under key + ;; 'anniversary (append if necessary) where org-mode can find + ;; it. Org-mode doesn't currently (v6.35) bother with time + ;; and time zone, though. + (when vcard-bday (push vcard-bday vcard-x-bbdb-anniversaries)) + (unless (assq 'anniversary bbdb-raw-notes) + (push (cons 'anniversary "") bbdb-raw-notes)) + (setf (cdr (assq 'anniversary bbdb-raw-notes)) + (bbdb-vcard-merge-strings + (cdr (assq 'anniversary bbdb-raw-notes)) + (bbdb-vcard-unescape-strings vcard-x-bbdb-anniversaries) + "\n"))) + (when vcard-categories + ;; Put vCard CATEGORIES under key 'mail-alias (append if necessary). + (unless (assq 'mail-alias bbdb-raw-notes) + (push (cons 'mail-alias "") bbdb-raw-notes)) + (setf (cdr (assq 'mail-alias bbdb-raw-notes)) + (bbdb-vcard-merge-strings + (cdr (assq 'mail-alias bbdb-raw-notes)) + vcard-categories + ","))) + (while (setq other-vcard-type (bbdb-vcard-other-element)) + (when (string-match "^\\([[:alnum:]-]*\\.\\)?AGENT" + (symbol-name (car other-vcard-type))) + ;; Notice other vCards inside the current one. + (bbdb-vcard-iterate-vcards + 'bbdb-vcard-import-vcard ; needed for inner v2.1 vCards: + (replace-regexp-in-string "\\\\" "" (cdr other-vcard-type)))) + (unless (or (and bbdb-vcard-skip-on-import + (string-match bbdb-vcard-skip-on-import + (symbol-name (car other-vcard-type)))) + (and bbdb-vcard-skip-valueless + (zerop (length (cdr other-vcard-type))))) + (push (bbdb-vcard-remove-x-bbdb other-vcard-type) bbdb-raw-notes))) + (bbdb-record-set-raw-notes + bbdb-record + (remove-duplicates bbdb-raw-notes :test 'equal :from-end t)) + (bbdb-change-record bbdb-record t) + ;; Tell the user what we've done. + (message "%s %s %s -- %s" + record-freshness-info + (bbdb-record-firstname bbdb-record) + (bbdb-record-lastname bbdb-record) + (replace-regexp-in-string + "\n" "; " (or (bbdb-record-company bbdb-record) "-")))))) + +(defun bbdb-vcard-from (record) + "Return BBDB RECORD as a vCard." + (with-temp-buffer + (let* ((name (bbdb-record-name record)) + (first-name (bbdb-record-firstname record)) + (last-name (bbdb-record-lastname record)) + (aka (bbdb-record-aka record)) + (company (bbdb-record-company record)) + (net (bbdb-record-net record)) + (phones (bbdb-record-phones record)) + (addresses (bbdb-record-addresses record)) + (www (bbdb-get-field record 'www)) + (notes + (bbdb-vcard-split-structured-text (bbdb-record-notes record) + ";\n" t)) + (raw-anniversaries (bbdb-vcard-split-structured-text + (bbdb-get-field record 'anniversary) "\n" t)) + (birthday-regexp + "\\([0-9]\\{4\\}-[01][0-9]-[0-3][0-9][t:0-9]*[-+z:0-9]*\\)\\([[:blank:]]+birthday\\)?\\'") + (birthday + (car (bbdb-vcard-split-structured-text + (find-if (lambda (x) (string-match birthday-regexp x)) + raw-anniversaries) + " " t))) + (other-anniversaries + (remove-if (lambda (x) (string-match birthday-regexp x)) + raw-anniversaries :count 1)) + (creation-date (bbdb-get-field record 'creation-date)) + (mail-aliases (bbdb-record-getprop record + bbdb-define-all-aliases-field)) + (raw-notes (copy-alist (bbdb-record-raw-notes record)))) + (bbdb-vcard-insert-vcard-element "BEGIN" "VCARD") + (bbdb-vcard-insert-vcard-element "VERSION" "3.0") + (bbdb-vcard-insert-vcard-element "FN" (bbdb-vcard-escape-strings name)) + (bbdb-vcard-insert-vcard-element + "N" (bbdb-vcard-escape-strings last-name) + ";" (bbdb-vcard-escape-strings first-name) + ";;;") ; Additional Names, Honorific Prefixes, Honorific Suffixes + (bbdb-vcard-insert-vcard-element + "NICKNAME" (bbdb-join (bbdb-vcard-escape-strings aka) ",")) + (bbdb-vcard-insert-vcard-element + "ORG" (bbdb-vcard-escape-strings company)) + (dolist (mail net) + (bbdb-vcard-insert-vcard-element + "EMAIL;TYPE=INTERNET" (bbdb-vcard-escape-strings mail))) + (dolist (phone phones) + (bbdb-vcard-insert-vcard-element + (concat + "TEL;TYPE=" + (bbdb-vcard-escape-strings + (bbdb-vcard-translate (bbdb-phone-location phone) t))) + (bbdb-vcard-escape-strings (bbdb-phone-string phone)))) + (dolist (address addresses) + (bbdb-vcard-insert-vcard-element + (concat + "ADR;TYPE=" + (bbdb-vcard-escape-strings + (bbdb-vcard-translate (bbdb-address-location address) t))) + ";;" ; no Postbox, no Extended + (bbdb-join (bbdb-vcard-escape-strings (bbdb-address-streets address)) + ",") + ";" (bbdb-vcard-vcardize-address-element + (bbdb-vcard-escape-strings (bbdb-address-city address))) + ";" (bbdb-vcard-vcardize-address-element + (bbdb-vcard-escape-strings (bbdb-address-state address))) + ";" (bbdb-vcard-vcardize-address-element + (bbdb-vcard-escape-strings (bbdb-address-zip address))) + ";" (bbdb-vcard-vcardize-address-element + (bbdb-vcard-escape-strings (bbdb-address-country address))))) + (bbdb-vcard-insert-vcard-element "URL" www) + (dolist (note notes) + (bbdb-vcard-insert-vcard-element + "NOTE" (bbdb-vcard-escape-strings note))) + (bbdb-vcard-insert-vcard-element "BDAY" birthday) + (bbdb-vcard-insert-vcard-element ; non-birthday anniversaries + "X-BBDB-ANNIVERSARY" (bbdb-join other-anniversaries "\\n")) + (bbdb-vcard-insert-vcard-element "REV" creation-date) + (bbdb-vcard-insert-vcard-element + "CATEGORIES" + (bbdb-join (bbdb-vcard-escape-strings + (bbdb-vcard-split-structured-text mail-aliases "," t)) ",")) + ;; prune raw-notes... + (dolist (key '(www notes anniversary mail-alias creation-date timestamp)) + (setq raw-notes (assq-delete-all key raw-notes))) + ;; ... and output what's left + (dolist (raw-note raw-notes) + (bbdb-vcard-insert-vcard-element + (symbol-name (bbdb-vcard-prepend-x-bbdb-maybe (car raw-note))) + (bbdb-vcard-escape-strings (cdr raw-note)))) + (bbdb-vcard-insert-vcard-element "END" "VCARD") + (bbdb-vcard-insert-vcard-element nil)) ; newline + (buffer-string))) + + + +(defun bbdb-vcard-convert-to-3.0 (vcard) + "Convert VCARD from v2.1 to v3.0. +Return a version 3.0 vCard as a string. Don't bother about the vCard +v3.0 mandatory elements N and FN." + ;; Prevent customization of vcard.el's from being changed behind our back: + (let ((vcard-standard-filters '(vcard-filter-html))) + (with-temp-buffer + (bbdb-vcard-insert-vcard-element "BEGIN" "VCARD") + (bbdb-vcard-insert-vcard-element "VERSION" "3.0") + (dolist (element (remove* + "VERSION" (vcard-parse-string vcard) + :key (lambda (x) (upcase (caar x))) :test 'string=)) + (bbdb-vcard-insert-vcard-element + (concat (caar element) + (mapconcat 'bbdb-vcard-parameter-pair (cdar element) "")) + (bbdb-join (bbdb-vcard-escape-strings (cdr element)) ";"))) + (bbdb-vcard-insert-vcard-element "END" "VCARD") + (bbdb-vcard-insert-vcard-element nil) + (buffer-string)))) + +(defun bbdb-vcard-parameter-pair (input) + "Return \"parameter=value\" made from INPUT. +INPUT is its representation in vcard.el. Return empty string if INPUT +is nil." + (cond ((consp input) (concat ";" (car input) "=" (cdr input))) + ((stringp input) (concat ";TYPE=" input)) + ((null input) ""))) + + + +(defun bbdb-vcard-values-of-type + (type parameter &optional one-is-enough-p split-value-at-semi-colon-p) + "Return in a list the values of PARAMETER of vCard element of TYPE. +The VCard element is read and deleted from current buffer which is +supposed to contain a single vCard. If ONE-IS-ENOUGH-P is non-nil, +read and delete only the first element of TYPE. If PARAMETER is +\"value\" and SPLIT-VALUE-AT-SEMI-COLON-P is non-nil, split the value +at semi-colons into a list." + (mapcar (lambda (x) (cdr (assoc parameter x))) + (bbdb-vcard-elements-of-type + type one-is-enough-p split-value-at-semi-colon-p))) + +(defun bbdb-vcard-elements-of-type + (type &optional one-is-enough-p split-value-at-semi-colon-p) + "From current buffer read and delete the vCard elements of TYPE. +The current buffer is supposed to contain a single vCard. If +ONE-IS-ENOUGH-P is non-nil, read and delete only the first element of +TYPE. Return a list of alists, one per element. Each alist has a +cell with key \"value\" containing the element's value, and may have +other elements of the form \(parameter-name . parameter-value). If +SPLIT-VALUE-AT-SEMI-COLON-P is non-nil, split the value at key +\"value\" at semi-colons into a list." + (goto-char (point-min)) + (let (values parameters read-enough) + (while + (and + (not read-enough) + (re-search-forward + (concat + "^\\([[:alnum:]-]*\\.\\)?\\(" type "\\)\\(;.*\\)?:\\(.*\\)$") + nil t)) + (goto-char (match-end 2)) + (setq parameters nil) + (push (cons "value" (if split-value-at-semi-colon-p + (bbdb-vcard-split-structured-text + (match-string 4) ";") + (match-string 4))) + parameters) + (while (re-search-forward "\\([^;:=]+\\)=\\([^;:]+\\)" + (line-end-position) t) + (let* ((parameter-key (downcase (match-string 1))) + (parameter-value (downcase (match-string 2))) + (parameter-sibling (assoc parameter-key parameters))) + (if parameter-sibling ; i.e., pair with equal key + ;; collect vCard parameter list `;a=x;a=y;a=z' + ;; into vCard value list `;a=x,y,z'; becoming ("a" . "x,y,z") + (setf (cdr parameter-sibling) + (concat (cdr parameter-sibling) "," parameter-value)) + ;; vCard parameter pair `;key=value;' with new key + (push (cons parameter-key parameter-value) parameters)))) + (push parameters values) + (delete-region (line-end-position 0) (line-end-position)) + (when one-is-enough-p (setq read-enough t))) + (nreverse values))) + +(defun bbdb-vcard-other-element () + "From current buffer read and delete the topmost vCard element. +Buffer is supposed to contain a single vCard. Return (TYPE . VALUE)." + (goto-char (point-min)) + (when (re-search-forward "^\\([[:graph:]]*?\\):\\(.*\\)$" nil t) + (let ((type (match-string 1)) + (value (match-string 2))) + (delete-region (match-beginning 0) (match-end 0)) + (cons (intern (downcase type)) (bbdb-vcard-unescape-strings value))))) + +(defun bbdb-vcard-insert-vcard-element (type &rest values) + "Insert a vCard element comprising TYPE, `:', VALUES into current buffer. +Take care of TYPE canonicalization, line folding, and closing newline. +Do nothing if TYPE is non-nil and VALUES are empty. Insert just a +newline if TYPE is nil." + (if type + (let ((value (bbdb-join values ""))) + (unless (zerop (length value)) + (insert (bbdb-vcard-fold-line + (concat (bbdb-vcard-canonicalize-vcard-type type) + ":" value))))) + (insert (bbdb-vcard-fold-line "")))) + + + +(defun bbdb-vcard-unfold-lines (vcards) + "Return folded vCard lines from VCARDS unfolded." + (replace-regexp-in-string "\n\\( \\|\t\\)" "" vcards)) + +(defun bbdb-vcard-fold-line (long-line) + "Insert after every 75th position in LONG-LINE a newline and a space." + (with-temp-buffer (insert long-line) + (goto-char (point-min)) + (while (< (goto-char (+ (point) 75)) + (point-max)) + (insert "\n ")) + (insert "\n") + (buffer-string))) + +(defun bbdb-vcard-unescape-strings (escaped-strings) + "Unescape escaped `;', `,', `\\', and newlines in ESCAPED-STRINGS. +ESCAPED-STRINGS may be a string or a sequence of strings." + (flet ((unescape (x) (replace-regexp-in-string + "\\([\\\\]\\)\\([,;\\]\\)" "" + (replace-regexp-in-string "\\\\n" "\n" x) + nil nil 1))) + (bbdb-vcard-process-strings 'unescape escaped-strings))) + +(defun bbdb-vcard-escape-strings (unescaped-strings ) + "Escape `;', `,', `\\', and newlines in UNESCAPED-STRINGS. +UNESCAPED-STRINGS may be a string or a sequence of strings." + (flet ((escape (x) (replace-regexp-in-string ; from 2.1 conversion: + "\r" "" (replace-regexp-in-string + "\n" "\\\\n" (replace-regexp-in-string + "\\(\\)[,;\\]" "\\\\" (or x "") + nil nil 1))))) + (bbdb-vcard-process-strings 'escape unescaped-strings))) + +(defun bbdb-vcard-process-strings (string-processor strings) + "Apply STRING-PROCESSOR to STRINGS. +STRINGS may be a string or a sequence of strings." + (if (stringp strings) + (funcall string-processor strings) + (mapcar string-processor strings))) + + + +(defun bbdb-vcard-remove-x-bbdb (vcard-element) + "Remove the `X-BBDB-' prefix from the type part of VCARD-ELEMENT if any." + (cons (intern (replace-regexp-in-string + "^X-BBDB-" "" (symbol-name (car vcard-element)))) + (cdr vcard-element))) + +(defun bbdb-vcard-prepend-x-bbdb-maybe (bbdb-fieldname) + "If BBDB-FIELDNAME is in `bbdb-vcard-x-bbdb-candidates', prepend `X-BBDB'." + (if (member bbdb-fieldname bbdb-vcard-x-bbdb-candidates) + (intern (concat "x-bbdb-" (symbol-name bbdb-fieldname))) + bbdb-fieldname)) ; lowercase more consistent here + +(defun bbdb-vcard-unvcardize-name (vcard-name) + "Convert VCARD-NAME (type N) into (FIRSTNAME LASTNAME)." + (if (stringp vcard-name) ; unstructured N + (bbdb-divide-name vcard-name) + (let ((vcard-name + (mapcar (lambda (x) + (bbdb-join (bbdb-vcard-split-structured-text x "," t) + " ")) + vcard-name))) ; flatten comma-separated substructure + (list (concat (nth 3 vcard-name) ; honorific prefixes + (unless (zerop (length (nth 3 vcard-name))) " ") + (nth 1 vcard-name) ; given name + (unless (zerop (length (nth 2 vcard-name))) " ") + (nth 2 vcard-name)) ; additional names + (concat (nth 0 vcard-name) ; family name + (unless (zerop (length (nth 4 vcard-name))) " ") + (nth 4 vcard-name)))))) ; honorific suffixes + +(defun bbdb-vcard-unvcardize-org (vcard-org) + "Convert VCARD-ORG (type ORG), which may be a list, into a string." + (if (or (null vcard-org) + (stringp vcard-org)) ; unstructured, probably non-standard ORG + vcard-org ; Company, unit 1, unit 2... + (bbdb-join vcard-org "\n"))) + +(defun bbdb-vcard-unvcardize-adr (vcard-adr) + "Convert VCARD-ADR into BBDB format. +Turn a vCard element of type ADR into (TYPE STREETS CITY STATE ZIP +COUNTRY)." + (let ((adr-type (or (cdr (assoc "type" vcard-adr)) "")) + (streets ; all comma-separated sub-elements of + (remove ; Postbox, Extended, Streets go into one list + "" (reduce 'append + (mapcar (lambda (x) + (bbdb-vcard-split-structured-text x "," t)) + (subseq (cdr (assoc "value" vcard-adr)) + 0 3))))) + (non-streets ; turn comma-separated substructure into + (mapcar ; newline-separated text + (lambda (x) (bbdb-join + (bbdb-vcard-split-structured-text x "," t) + "\n")) + (subseq (cdr (assoc "value" vcard-adr)) + 3 nil)))) + (vector (bbdb-vcard-translate adr-type) + streets + (or (elt non-streets 0) "") ; City + (or (elt non-streets 1) "") ; State + (or (elt non-streets 2) "") ; Zip + (or (elt non-streets 3) "")))) ; Country + +(defun bbdb-vcard-unvcardize-date-time (date-time) + "If necessary, make DATE-TIME usable for storage in BBDB. +Convert yyyymmdd, yyyymmddThhmmss, or yyymmddThhmmssZhhmm into +yyyy-mm-dd, yyyy-mm-ddThh:mm:ss, or yyy-mm-ddThh:mm:ssZhh:mm +respectively. Discard fractions of a second. Return anything else +unchanged." + (if (and (stringp date-time) + (string-match + "\\([0-9]\\{4\\}\\)-?\\([0-2][0-9]\\)-?\\([0-3][0-9]\\)\\(?:t\\([0-5][0-9]\\):?\\([0-5][0-9]\\):?\\([0-5][0-9]\\)\\(?:[,.0-9]*\\(\\([+-][0-5][0-9]\\):?\\([0-5][0-9]\\)?\\|z\\)\\)?\\)?" + date-time)) + (concat + (match-string 1 date-time) "-" + (match-string 2 date-time) "-" (match-string 3 date-time) + (when (match-string 6 date-time) ; seconds part of time + (concat + "T" (match-string 4 date-time) ":" + (match-string 5 date-time) ":" (match-string 6 date-time) + (when (match-string 7 date-time) ; time zone + (if (match-string 9 date-time) ; time zone minute + (concat (match-string 8 date-time) ; time zone hour + ":" (match-string 9 date-time)) ; time zone minute + "Z"))))) + date-time)) + +(defun bbdb-vcard-vcardize-address-element (address-element) + "Replace escaped newlines in ADDRESS-ELEMENT by commas." + (replace-regexp-in-string "\\\\n" "," address-element)) + +(defun bbdb-vcard-translate (label &optional exportp) + "Translate LABEL from vCard to BBDB or, if EXPORTP is non-nil, vice versa. +Translations are defined in `bbdb-vcard-import-translation-table' and +`bbdb-vcard-export-translation-table' respectively." + (when label + (capitalize + (or (assoc-default label + (if exportp + bbdb-vcard-export-translation-table + bbdb-vcard-import-translation-table) 'string-match) + label)))) + +(defun bbdb-vcard-merge-strings (old-string new-strings separator) + "Merge strings successively from list NEW-STRINGS into OLD-STRING. +If an element of NEW-STRINGS is already in OLD-STRING, leave +OLD-STRING unchanged. Otherwise append SEPARATOR and NEW-STRING." + (with-temp-buffer + (insert old-string) + (dolist (new-string new-strings) + (unless (prog1 (search-backward new-string nil t) + (goto-char (point-max))) + (unless (zerop (buffer-size)) (insert separator)) + (insert new-string))) + (buffer-string))) + +(defun bbdb-vcard-split-structured-text + (text separator &optional return-always-list-p) + "Split TEXT at unescaped occurrences of SEPARATOR; return parts in a list. +Return text unchanged if there aren't any separators and RETURN-ALWAYS-LIST-P +is nil." + (when (stringp text) + (let ((string-elements + (split-string + (replace-regexp-in-string + (concat "\\\\\r" separator) (concat "\\\\" separator) + (replace-regexp-in-string separator (concat "\r" separator) text)) + (concat "\r" separator)))) + (if (and (null return-always-list-p) + (= 1 (length string-elements))) + (car string-elements) + string-elements)))) + +(defun bbdb-vcard-canonicalize-vcard-type (&rest strings) + "Concatenate STRINGS and apply `bbdb-vcard-type-canonicalizer' to them." + (funcall bbdb-vcard-type-canonicalizer (bbdb-join strings ""))) + +(defun bbdb-vcard-write-buffer (vcard-file-name) + "Write current buffer to VCARD-FILE-NAME. +Create directories where necessary." + (make-directory (file-name-directory vcard-file-name) t) + (let ((buffer-file-coding-system bbdb-vcard-export-coding-system)) + (write-region nil nil vcard-file-name nil nil nil t))) + +(defun bbdb-vcard-make-file-name (bbdb-record &optional used-up-basenames) + "Come up with a vCard filename given a BBDB-RECORD. +Make it unique against the list USED-UP-BASENAMES." + (let ((name (bbdb-record-name bbdb-record)) + (aka (car (bbdb-record-aka bbdb-record))) + (unique-number 0) + filename) + (while (member + (setq filename + (concat + (replace-regexp-in-string + "[[:blank:]]+" "_" + (or (unless (zerop (length name)) name) + (unless (zerop (length aka)) aka) + "bbdb-record")) + (unless (zerop unique-number) + (concat "-" (number-to-string unique-number))) + ".vcf")) + used-up-basenames) + (incf unique-number)) + filename)) + +(defmacro bbdb-vcard-search-intersection + (records &optional name company net notes phone) + "Search RECORDS for records that match each non-nil argument." + (let* + ((phone-search + (if phone `(when ,phone (bbdb-search ,records nil nil nil nil ,phone)) + records)) + (notes-search + (if notes `(when ,notes (bbdb-search ,phone-search nil nil nil ,notes)) + phone-search)) + (net-search + (if net `(when ,net (bbdb-search ,notes-search nil nil ,net)) + notes-search)) + (company-search + (if company `(when ,company (bbdb-search ,net-search nil ,company)) + net-search)) + (name-search + (if name `(when ,name (bbdb-search ,company-search ,name)) + company-search))) + name-search)) + + + +(provide 'bbdb-vcard) + +;;; bbdb-vcard.el ends here + +; LocalWords: vcard firstname --- /dev/null +++ bbdb-2.36/extern/bbdb-vcard/vcard.el @@ -0,0 +1,704 @@ +;;; vcard.el --- vcard parsing and display routines + +;; Copyright (C) 1997, 1999, 2000 Noah S. Friedman + +;; Author: Noah Friedman +;; Maintainer: friedman@splode.com +;; Keywords: vcard, mail, news +;; Created: 1997-09-27 + +;; $Id: vcard.el,v 1.11 2000/06/29 17:07:55 friedman Exp $ + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, you can either send email to this +;; program's maintainer or write to: The Free Software Foundation, +;; Inc.; 59 Temple Place, Suite 330; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; Unformatted vcards are just plain ugly. But if you live in the MIME +;; world, they are a better way of exchanging contact information than +;; freeform signatures since the former can be automatically parsed and +;; stored in a searchable index. +;; +;; This library of routines provides the back end necessary for parsing +;; vcards so that they can eventually go into an address book like BBDB +;; (although this library does not implement that itself). Also included +;; is a sample pretty-printer which MUAs can use which do not provide their +;; own vcard formatters. + +;; This library does not interface directly with any mail user agents. For +;; an example of bindings for the VM MUA, see vm-vcard.el available from +;; +;; http://www.splode.com/~friedman/software/emacs-lisp/index.html#mail +;; +;; Updates to vcard.el should be available there too. + +;; The main entry point to this package is `vcard-pretty-print' although +;; any documented variable or function is considered part of the API for +;; operating on vcard data. + +;; The vcard 2.1 format is defined by the versit consortium. +;; See http://www.imc.org/pdi/vcard-21.ps +;; +;; RFC 2426 defines the vcard 3.0 format. +;; See ftp://ftp.rfc-editor.org/in-notes/rfc2426.txt + +;; A parsed vcard is a list of attributes of the form +;; +;; (proplist value1 value2 ...) +;; +;; Where proplist is a list of property names and parameters, e.g. +;; +;; (property1 (property2 . parameter2) ...) +;; +;; Each property has an associated implicit or explicit parameter value +;; (not to be confused with attribute values; in general this API uses +;; `parameter' to refer to property values and `value' to refer to attribute +;; values to avoid confusion). If a property has no explicit parameter value, +;; the parameter value is considered to be `t'. Any property which does not +;; exist for an attribute is considered to have a nil parameter. + +;; TODO: +;; * Finish supporting the 3.0 extensions. +;; Currently, only the 2.1 standard is supported. +;; * Handle nested vcards and grouped attributes? +;; (I've never actually seen one of these in use.) +;; * Handle multibyte charsets. +;; * Inverse of vcard-parse-string: write .VCF files from alist +;; * Implement a vcard address book? Or is using BBDB preferable? +;; * Improve the sample formatter. + +;;; Code: + +(defgroup vcard nil + "Support for the vCard electronic business card format." + :group 'vcard + :group 'mail + :group 'news) + +;;;###autoload +(defcustom vcard-pretty-print-function 'vcard-format-sample-box + "*Formatting function used by `vcard-pretty-print'." + :type 'function + :group 'vcard) + +;;;###autoload +(defcustom vcard-standard-filters + '(vcard-filter-html + vcard-filter-adr-newlines + vcard-filter-tel-normalize + vcard-filter-textprop-cr) + "*Standard list of filters to apply to parsed vcard data. +These filters are applied sequentially to vcard attributes when +the function `vcard-standard-filter' is supplied as the second argument to +`vcard-parse'." + :type 'hook + :group 'vcard) + + +;;; No user-settable options below. + +;; XEmacs 21 ints and chars are disjoint types. +;; For all else, treat them as the same. +(defalias 'vcard-char-to-int + (if (fboundp 'char-to-int) 'char-to-int 'identity)) + +;; This is just the version number for this package; it does not refer to +;; the vcard format specification. Currently, this package does not yet +;; support the full vcard 3.0 specification. +;; +;; Whenever any part of the API defined in this package change in a way +;; that is not backward-compatible, the major version number here should be +;; incremented. Backward-compatible additions to the API should be +;; indicated by increasing the minor version number. +(defconst vcard-api-version "2.0") + +;; The vcard standards allow specifying the encoding for an attribute using +;; these values as immediate property names, rather than parameters of the +;; `encoding' property. If these are encountered while parsing, associate +;; them as parameters of the `encoding' property in the returned structure. +(defvar vcard-encoding-tags + '("quoted-printable" "base64" "8bit" "7bit")) + +;; The vcard parser will auto-decode these encodings when they are +;; encountered. These methods are invoked via vcard-parse-region-value. +(defvar vcard-region-decoder-methods + '(("quoted-printable" . vcard-region-decode-quoted-printable) + ("base64" . vcard-region-decode-base64))) + +;; This is used by vcard-region-decode-base64 +(defvar vcard-region-decode-base64-table + (let* ((a "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/") + (len (length a)) + (tbl (make-vector 123 nil)) + (i 0)) + (while (< i len) + (aset tbl (vcard-char-to-int (aref a i)) i) + (setq i (1+ i))) + tbl)) + + +;;; This function can be used generically by applications to obtain +;;; a printable representation of a vcard. + +;;;###autoload +(defun vcard-pretty-print (vcard) + "Format VCARD into a string suitable for display to user. +VCARD can be an unparsed string containing raw VCF vcard data +or a parsed vcard alist as returned by `vcard-parse-string'. + +The result is a string with formatted vcard information suitable for +insertion into a mime presentation buffer. + +The function specified by the variable `vcard-pretty-print-function' +actually performs the formatting. That function will always receive a +parsed vcard alist." + (and (stringp vcard) + (setq vcard (vcard-parse-string vcard))) + (funcall vcard-pretty-print-function vcard)) + + +;;; Parsing routines + +;;;###autoload +(defun vcard-parse-string (raw &optional filter) + "Parse RAW vcard data as a string, and return an alist representing data. + +If the optional function FILTER is specified, apply that filter to each +attribute. If no filter is specified, `vcard-standard-filter' is used. + +Filters should accept two arguments: the property list and the value list. +Modifying in place the property or value list will affect the resulting +attribute in the vcard alist. + +Vcard data is normally in the form + + begin: vcard + prop1a: value1a + prop2a;prop2b;prop2c=param2c: value2a + prop3a;prop3b: value3a;value3b;value3c + end: vcard + +\(Whitespace around the `:' separating properties and values is optional.\) +If supplied to this function an alist of the form + + \(\(\(\"prop1a\"\) \"value1a\"\) + \(\(\"prop2a\" \"prop2b\" \(\"prop2c\" . \"param2c\"\)\) \"value2a\"\) + \(\(\"prop3a\" \"prop3b\"\) \"value3a\" \"value3b\" \"value3c\"\)\) + +would be returned." + (let ((vcard nil) + (buf (generate-new-buffer " *vcard parser work*"))) + (unwind-protect + (save-excursion + (set-buffer buf) + ;; Make sure last line is newline-terminated. + ;; An extra trailing newline is harmless. + (insert raw "\n") + (setq vcard (vcard-parse-region (point-min) (point-max) filter))) + (kill-buffer buf)) + vcard)) + +;;;###autoload +(defun vcard-parse-region (beg end &optional filter) + "Parse the raw vcard data in region, and return an alist representing data. +This function is just like `vcard-parse-string' except that it operates on +a region of the current buffer rather than taking a string as an argument. + +Note: this function modifies the buffer!" + (or filter + (setq filter 'vcard-standard-filter)) + (let ((case-fold-search t) + (vcard-data nil) + (pos (make-marker)) + (newpos (make-marker)) + properties value) + (save-restriction + (narrow-to-region beg end) + (save-match-data + ;; Unfold folded lines and delete naked carriage returns + (goto-char (point-min)) + (while (re-search-forward "\r$\\|\n[ \t]" nil t) + (goto-char (match-beginning 0)) + (delete-char 1)) + + (goto-char (point-min)) + (re-search-forward "^begin:[ \t]*vcard[ \t]*\n") + (set-marker pos (point)) + (while (and (not (looking-at "^end[ \t]*:[ \t]*vcard[ \t]*$")) + (re-search-forward ":[ \t]*" nil t)) + (set-marker newpos (match-end 0)) + (setq properties + (vcard-parse-region-properties pos (match-beginning 0))) + (set-marker pos (marker-position newpos)) + (re-search-forward "[ \t]*\n") + (set-marker newpos (match-end 0)) + (setq value + (vcard-parse-region-value properties pos (match-beginning 0))) + (set-marker pos (marker-position newpos)) + (goto-char pos) + (funcall filter properties value) + (setq vcard-data (cons (cons properties value) vcard-data))))) + (nreverse vcard-data))) + +(defun vcard-parse-region-properties (beg end) + (downcase-region beg end) + (let* ((proplist (vcard-split-string (buffer-substring beg end) ";")) + (props proplist) + split) + (save-match-data + (while props + (cond ((string-match "=" (car props)) + (setq split (vcard-split-string (car props) "=" 2)) + (setcar props (cons (car split) (car (cdr split))))) + ((member (car props) vcard-encoding-tags) + (setcar props (cons "encoding" (car props))))) + (setq props (cdr props)))) + proplist)) + +(defun vcard-parse-region-value (proplist beg end) + (let* ((encoding (vcard-get-property proplist "encoding")) + (decoder (cdr (assoc encoding vcard-region-decoder-methods))) + result pos match-beg match-end) + (save-restriction + (narrow-to-region beg end) + (cond (decoder + ;; Each `;'-separated field needs to be decoded and saved + ;; separately; if the entire region were decoded at once, we + ;; would not be able to distinguish between the original `;' + ;; chars and those which were encoded in order to quote them + ;; against being treated as field separators. + (goto-char beg) + (setq pos (set-marker (make-marker) (point))) + (setq match-beg (make-marker)) + (setq match-end (make-marker)) + (save-match-data + (while (< pos (point-max)) + (cond ((search-forward ";" nil t) + (set-marker match-beg (match-beginning 0)) + (set-marker match-end (match-end 0))) + (t + (set-marker match-beg (point-max)) + (set-marker match-end (point-max)))) + (funcall decoder pos match-beg) + (setq result (cons (buffer-substring pos match-beg) result)) + (set-marker pos (marker-position match-end)))) + (setq result (nreverse result)) + (vcard-set-property proplist "encoding" nil)) + (t + (setq result (vcard-split-string (buffer-string) ";"))))) + (goto-char (point-max)) + result)) + + +;;; Functions for retrieving property or value information from parsed +;;; vcard attributes. + +(defun vcard-values (vcard have-props &optional non-props limit) + "Return the values in VCARD. +This function is like `vcard-ref' and takes the same arguments, but return +only the values, not the associated property lists." + (mapcar 'cdr (vcard-ref vcard have-props non-props limit))) + +(defun vcard-ref (vcard have-props &optional non-props limit) + "Return the attributes in VCARD with HAVE-PROPS properties. +Optional arg NON-PROPS is a list of properties which candidate attributes +must not have. +Optional arg LIMIT means return no more than that many attributes. + +The attributes in VCARD which have all properties specified by HAVE-PROPS +but not having any specified by NON-PROPS are returned. The first element +of each attribute is the actual property list; the remaining elements are +the values. + +If a specific property has an associated parameter \(e.g. an encoding\), +use the syntax \(\"property\" . \"parameter\"\) to specify it. If property +parameter is not important or it has no specific parameter, just specify +the property name as a string." + (let ((attrs vcard) + (result nil) + (count 0)) + (while (and attrs (or (null limit) (< count limit))) + (and (vcard-proplist-all-properties (car (car attrs)) have-props) + (not (vcard-proplist-any-properties (car (car attrs)) non-props)) + (setq result (cons (car attrs) result) + count (1+ count))) + (setq attrs (cdr attrs))) + (nreverse result))) + +(defun vcard-proplist-all-properties (proplist props) + "Returns nil unless PROPLIST contains all properties specified in PROPS." + (let ((result t)) + (while (and result props) + (or (vcard-get-property proplist (car props)) + (setq result nil)) + (setq props (cdr props))) + result)) + +(defun vcard-proplist-any-properties (proplist props) + "Returns `t' if PROPLIST contains any of the properties specified in PROPS." + (let ((result nil)) + (while (and (not result) props) + (and (vcard-get-property proplist (car props)) + (setq result t)) + (setq props (cdr props))) + result)) + +(defun vcard-get-property (proplist property) + "Return the value from PROPLIST of PROPERTY. +PROPLIST is a vcard attribute property list, which is normally the first +element of each attribute entry in a vcard." + (or (and (member property proplist) t) + (cdr (assoc property proplist)))) + +(defun vcard-set-property (proplist property value) + "In PROPLIST, set PROPERTY to VALUE. +PROPLIST is a vcard attribute property list. +If VALUE is nil, PROPERTY is deleted." + (let (elt) + (cond ((null value) + (vcard-delete-property proplist property)) + ((setq elt (member property proplist)) + (and value (not (eq value t)) + (setcar elt (cons property value)))) + ((setq elt (assoc property proplist)) + (cond ((eq value t) + (setq elt (memq elt proplist)) + (setcar elt property)) + (t + (setcdr elt value)))) + ((eq value t) + (nconc proplist (cons property nil))) + (t + (nconc proplist (cons (cons property value) nil)))))) + +(defun vcard-delete-property (proplist property) + "Delete from PROPLIST the specified property PROPERTY. +This will not succeed in deleting the first member of the proplist, but +that element should never be deleted since it is the primary key." + (let (elt) + (cond ((setq elt (member property proplist)) + (delq (car elt) proplist)) + ((setq elt (assoc property proplist)) + (delq (car (memq elt proplist)) proplist))))) + + +;;; Vcard data filters. +;;; +;;; Filters receive both the property list and value list and may modify +;;; either in-place. The return value from the filters are ignored. +;;; +;;; These filters can be used for purposes such as removing HTML tags or +;;; normalizing phone numbers into a standard form. + +(defun vcard-standard-filter (proplist values) + "Apply filters in `vcard-standard-filters' to attributes." + (vcard-filter-apply-filter-list vcard-standard-filters proplist values)) + +;; This function could be used to dispatch other filter lists. +(defun vcard-filter-apply-filter-list (filter-list proplist values) + (while filter-list + (funcall (car filter-list) proplist values) + (setq filter-list (cdr filter-list)))) + +;; Some lusers put HTML (or even javascript!) in their vcards under the +;; misguided notion that it's a standard feature of vcards just because +;; Netscape supports this feature. That is wrong; the vcard specification +;; does not define any html content semantics and most MUAs cannot do +;; anything with html text except display them unparsed, which is ugly. +;; +;; Thank Netscape for abusing the standard and damned near rendering it +;; useless for interoperability between MUAs. +;; +;; This filter does a very rudimentary job. +(defun vcard-filter-html (proplist values) + "Remove HTML tags from attribute values." + (save-match-data + (while values + (while (string-match "<[^<>\n]+>" (car values)) + (setcar values (replace-match "" t t (car values)))) + (setq values (cdr values))))) + +(defun vcard-filter-adr-newlines (proplist values) + "Replace newlines with \"; \" in `adr' values." + (and (vcard-get-property proplist "adr") + (save-match-data + (while values + (while (string-match "[\r\n]+" (car values)) + (setcar values (replace-match "; " t t (car values)))) + (setq values (cdr values)))))) + +(defun vcard-filter-tel-normalize (proplist values) + "Normalize telephone numbers in `tel' values. +Spaces and hyphens are replaced with `.'. +US domestic telephone numbers are replaced with international format." + (and (vcard-get-property proplist "tel") + (save-match-data + (while values + (while (string-match "[\t._-]+" (car values)) + (setcar values (replace-match " " t t (car values)))) + (and (string-match "^(?\\(\\S-\\S-\\S-\\))? ?\ +\\(\\S-\\S-\\S- \\S-\\S-\\S-\\S-\\)" + (car values)) + (setcar values + (replace-match "+1 \\1 \\2" t nil (car values)))) + (setq values (cdr values)))))) + +(defun vcard-filter-textprop-cr (proplist values) + "Strip carriage returns from text values." + (and (vcard-proplist-any-properties + proplist '("adr" "email" "fn" "label" "n" "org" "tel" "title" "url")) + (save-match-data + (while values + (while (string-match "\r+" (car values)) + (setcar values (replace-match "" t t (car values)))) + (setq values (cdr values)))))) + + +;;; Decoding methods. + +(defmacro vcard-hexstring-to-ascii (s) + (if (string-lessp emacs-version "20") + `(format "%c" (car (read-from-string (format "?\\x%s" ,s)))) + `(format "%c" (string-to-number ,s 16)))) + +(defun vcard-region-decode-quoted-printable (&optional beg end) + (save-excursion + (save-restriction + (save-match-data + (narrow-to-region (or beg (point-min)) (or end (point-max))) + (goto-char (point-min)) + (while (re-search-forward "=\n" nil t) + (delete-region (match-beginning 0) (match-end 0))) + (goto-char (point-min)) + (while (re-search-forward "=[0-9A-Za-z][0-9A-Za-z]" nil t) + (let ((s (buffer-substring (1+ (match-beginning 0)) (match-end 0)))) + (replace-match (vcard-hexstring-to-ascii s) t t))))))) + +(defun vcard-region-decode-base64 (&optional beg end) + (save-restriction + (narrow-to-region (or beg (point-min)) (or end (point-max))) + (save-match-data + (goto-char (point-min)) + (while (re-search-forward "[ \t\r\n]+" nil t) + (delete-region (match-beginning 0) (match-end 0)))) + (goto-char (point-min)) + (let ((count 0) + (n 0) + (c nil)) + (while (not (eobp)) + (setq c (char-after (point))) + (delete-char 1) + (cond ((char-equal c ?=) + (if (= count 2) + (insert (lsh n -10)) + ;; count must be 3 + (insert (lsh n -16) (logand 255 (lsh n -8)))) + (delete-region (point) (point-max))) + (t + (setq n (+ n (aref vcard-region-decode-base64-table + (vcard-char-to-int c)))) + (setq count (1+ count)) + (cond ((= count 4) + (insert (logand 255 (lsh n -16)) + (logand 255 (lsh n -8)) + (logand 255 n)) + (setq n 0 count 0)) + (t + (setq n (lsh n 6)))))))))) + + +(defun vcard-split-string (string &optional separator limit) + "Split STRING at occurences of SEPARATOR. Return a list of substrings. +Optional argument SEPARATOR can be any regexp, but anything matching the + separator will never appear in any of the returned substrings. + If not specified, SEPARATOR defaults to \"[ \\f\\t\\n\\r\\v]+\". +If optional arg LIMIT is specified, split into no more than that many + fields \(though it may split into fewer\)." + (or separator (setq separator "[ \f\t\n\r\v]+")) + (let ((string-list nil) + (len (length string)) + (pos 0) + (splits 0) + str) + (save-match-data + (while (<= pos len) + (setq splits (1+ splits)) + (cond ((and limit + (>= splits limit)) + (setq str (substring string pos)) + (setq pos (1+ len))) + ((string-match separator string pos) + (setq str (substring string pos (match-beginning 0))) + (setq pos (match-end 0))) + (t + (setq str (substring string pos)) + (setq pos (1+ len)))) + (setq string-list (cons str string-list)))) + (nreverse string-list))) + +(defun vcard-copy-tree (tree) + "Make a deep copy of nested conses." + (cond + ((consp tree) + (cons (vcard-copy-tree (car tree)) + (vcard-copy-tree (cdr tree)))) + (t tree))) + +(defun vcard-flatten (l) + (if (consp l) + (apply 'nconc (mapcar 'vcard-flatten l)) + (list l))) + + +;;; Sample formatting routines. + +(defun vcard-format-sample-box (vcard) + "Like `vcard-format-sample-string', but put an ascii box around text." + (let* ((lines (vcard-format-sample-lines vcard)) + (len (vcard-format-sample-max-length lines)) + (edge (concat "\n+" (make-string (+ len 2) ?-) "+\n")) + (line-fmt (format "| %%-%ds |" len)) + (formatted-lines + (mapconcat (function (lambda (s) (format line-fmt s))) lines "\n"))) + (if (string= formatted-lines "") + formatted-lines + (concat edge formatted-lines edge)))) + +(defun vcard-format-sample-string (vcard) + "Format VCARD into a string suitable for display to user. +VCARD should be a parsed vcard alist. The result is a string +with formatted vcard information which can be inserted into a mime +presentation buffer." + (mapconcat 'identity (vcard-format-sample-lines vcard) "\n")) + +(defun vcard-format-sample-lines (vcard) + (let* ((name (vcard-format-sample-get-name vcard)) + (title (vcard-format-sample-values-concat vcard '("title") 1 "; ")) + (org (vcard-format-sample-values-concat vcard '("org") 1 "; ")) + (addr (vcard-format-sample-get-address vcard)) + (tel (vcard-format-sample-get-telephone vcard)) + (lines (delete nil (vcard-flatten (list name title org addr)))) + (col-template (format "%%-%ds%%s" + (vcard-format-sample-offset lines tel))) + (l lines)) + (while tel + (setcar l (format col-template (car l) (car tel))) + ;; If we stripped away too many nil slots from l, add empty strings + ;; back in so setcar above will work on next iteration. + (and (cdr tel) + (null (cdr l)) + (setcdr l (cons "" nil))) + (setq l (cdr l)) + (setq tel (cdr tel))) + lines)) + +(defun vcard-format-sample-get-name (vcard) + (let ((name (car (car (vcard-values vcard '("fn") nil 1)))) + (email (car (vcard-format-sample-values + vcard '((("email" "pref")) + (("email" "internet")) + (("email"))) 1)))) + (cond ((and name email) + (format "%s <%s>" name email)) + (email) + (name) + ("")))) + +(defun vcard-format-sample-get-telephone (vcard) + (let ((fields '(("Work: " + (("tel" "work" "pref") . ("fax" "pager" "cell")) + (("tel" "work" "voice") . ("fax" "pager" "cell")) + (("tel" "work") . ("fax" "pager" "cell"))) + ("Home: " + (("tel" "home" "pref") . ("fax" "pager" "cell")) + (("tel" "home" "voice") . ("fax" "pager" "cell")) + (("tel" "home") . ("fax" "pager" "cell")) + (("tel") . ("fax" "pager" "cell" "work"))) + ("Cell: " + (("tel" "cell" "pref")) + (("tel" "cell"))) + ("Fax: " + (("tel" "pref" "fax")) + (("tel" "work" "fax")) + (("tel" "home" "fax")) + (("tel" "fax"))))) + (phones nil) + result) + (while fields + (setq result (vcard-format-sample-values vcard (cdr (car fields)))) + (while result + (setq phones + (cons (concat (car (car fields)) (car (car result))) phones)) + (setq result (cdr result))) + (setq fields (cdr fields))) + (nreverse phones))) + +(defun vcard-format-sample-get-address (vcard) + (let* ((addr (vcard-format-sample-values vcard '((("adr" "pref" "work")) + (("adr" "pref")) + (("adr" "work")) + (("adr"))) 1)) + (street (delete "" (list (nth 0 addr) (nth 1 addr) (nth 2 addr)))) + (city-list (delete "" (nthcdr 3 addr))) + (city (cond ((null (car city-list)) nil) + ((cdr city-list) + (format "%s, %s" + (car city-list) + (mapconcat 'identity (cdr city-list) " "))) + (t (car city-list))))) + (delete nil (if city + (append street (list city)) + street)))) + +(defun vcard-format-sample-values-concat (vcard have-props limit sep) + (let ((l (car (vcard-values vcard have-props nil limit)))) + (and l (mapconcat 'identity (delete "" (vcard-copy-tree l)) sep)))) + +(defun vcard-format-sample-values (vcard proplists &optional limit) + (let ((result (vcard-format-sample-ref vcard proplists limit))) + (if (equal limit 1) + (cdr result) + (mapcar 'cdr result)))) + +(defun vcard-format-sample-ref (vcard proplists &optional limit) + (let ((result nil)) + (while (and (null result) proplists) + (setq result (vcard-ref vcard + (car (car proplists)) + (cdr (car proplists)) + limit)) + (setq proplists (cdr proplists))) + (if (equal limit 1) + (vcard-copy-tree (car result)) + (vcard-copy-tree result)))) + +(defun vcard-format-sample-offset (row1 row2 &optional maxwidth) + (or maxwidth (setq maxwidth (frame-width))) + (let ((max1 (vcard-format-sample-max-length row1)) + (max2 (vcard-format-sample-max-length row2))) + (if (zerop max1) + 0 + (+ max1 (min 5 (max 1 (- maxwidth (+ max1 max2)))))))) + +(defun vcard-format-sample-max-length (strings) + (let ((maxlen 0)) + (while strings + (setq maxlen (max maxlen (length (car strings)))) + (setq strings (cdr strings))) + maxlen)) + +(provide 'vcard) + +;;; vcard.el ends here. --- /dev/null +++ bbdb-2.36/extern/bbdb-vcard/test-bbdb-vcard.el @@ -0,0 +1,1749 @@ +;;; Tests for bbdb-vcard.el +;; +;; Before proceeding, you should probably save your production bbdb file. +;; +;; To run the tests, eval this file. +;; In case of failure, find test results in buffer `bbdb-vcard-test-result'. +;; +;; For the sake of minimality, not all test cases are rfc compliant. + + +(require 'bbdb-vcard) + +(defun bbdb-vcard-import-test + (vcard bbdb-entry search-name + &optional search-company search-net check-creation-date-p) + "Import VCARD and search for it in bbdb by SEARCH-NAME, +SEARCH-COMPANY, (perhaps later) SEARCH-NET. If search result +disagrees with BBDB-ENTRY, talk about it in buffer +bbdb-vcard-test-result. timestamp and, if CHECK-CREATION-DATE-P is +nil, creation-date are not taken into account." + (bbdb-vcard-iterate-vcards 'bbdb-vcard-import-vcard vcard) + (let* ((search-company (or search-company "")) + (bbdb-search-result + (car (bbdb-search (bbdb-search (bbdb-records) search-name) + nil search-company)))) + (setf (cdr (assoc 'timestamp (elt bbdb-search-result 7))) "2010-03-04" + (cdr (assoc 'timestamp (elt bbdb-entry 7))) "2010-03-04") + (unless check-creation-date-p + (setf (cdr (assoc 'creation-date (elt bbdb-search-result 7))) "2010-03-04" + (cdr (assoc 'creation-date (elt bbdb-entry 7))) "2010-03-04")) + (unless (equal (subseq bbdb-search-result 0 8) + (subseq bbdb-entry 0 8)) + (princ "\nTest failed:\n" (get-buffer-create "bbdb-vcard-test-result")) + (prin1 vcard (get-buffer-create "bbdb-vcard-test-result")) + (princ "\nwas stored as\n" (get-buffer-create "bbdb-vcard-test-result")) + (prin1 (subseq bbdb-search-result 0 8) + (get-buffer-create "bbdb-vcard-test-result")) + (princ "\nbut was expected as\n" (get-buffer-create "bbdb-vcard-test-result")) + (prin1 bbdb-entry (get-buffer-create "bbdb-vcard-test-result"))))) + +(defun bbdb-vcard-normalize-notes (notes) + "Sort a BBDB NOTES field and delete the timestamps in order to make them +comparable after re-import." + (let ((notes (remove-alist 'notes 'timestamp))) + (setq notes (remove-alist 'notes 'creation-date)) + (sort + notes + '(lambda (x y) (if (string= (symbol-name (car x)) (symbol-name (car y))) + (string< (cdr x) (cdr y)) + (string< (symbol-name (car x)) (symbol-name (car y)))))))) + +(defun bbdb-vcard-normalize-record (record) + "Make BBDB RECORD comparable by deleting certain things and sorting others." + (setf (elt record 6) (bbdb-vcard-normalize-notes (elt record 7))) + (subseq record 0 7)) + +(defun bbdb-vcard-compare-bbdbs (first-bbdb second-bbdb) + "Compare two BBDB record lists. Tell about mismatches in buffer +`bbdb-vcard-test-result'." + (let ((i 0) + first-record second-record) + (while (or (nth i first-bbdb) (nth i second-bbdb)) + (unless (equal (bbdb-vcard-normalize-record (nth i first-bbdb)) + (bbdb-vcard-normalize-record (nth i second-bbdb))) + (princ "\nRe-import: comparison of these records failed:" + (get-buffer-create "bbdb-vcard-test-result")) + (print (bbdb-vcard-normalize-record (nth i first-bbdb)) + (get-buffer-create "bbdb-vcard-test-result")) + (prin1 (bbdb-vcard-normalize-record (nth i second-bbdb)) + (get-buffer-create "bbdb-vcard-test-result"))) + (incf i)))) + + +;;; Try not to mess up our real BBDB: +(when bbdb-buffer + (save-buffer bbdb-buffer) + (kill-buffer bbdb-buffer)) +(when (get-buffer "test-bbdb") (kill-buffer "test-bbdb")) +(setq bbdb-file "/tmp/test-bbdb") +(when (file-exists-p bbdb-file) (delete-file bbdb-file)) +(when (get-buffer "bbdb-vcard-test-result") (kill-buffer "bbdb-vcard-test-result")) + + +;;;; The Import Tests +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(bbdb-vcard-import-test + " +** A vcard without any type parameters. +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +FN:First1 Last1 +N:Last1;First1 +NICKNAME:Firsty1 +PHOTO:The Alphabet: + abcdefghijklmnop + qrstuvwsyz +BDAY:1999-12-05 +ADR:Box111;Room 111;First Street,First Corner;Cityone;First State;11111;Country +LABEL:Label 1 +TEL:+11111111 +EMAIL:first1@provider1 +MAILER:Wanderlust1 +TZ:+01:00 +GEO:37.386013;-122.082932 +TITLE:Director\\, Research and Development +ROLE:Programmer +LOGO:encoded logo #1 +AGENT:CID:JQPUBLIC.part3.960129T083020.xyzMail@host3.com +ORG:Company1;Unit1;Subunit1 +CATEGORIES:category1 +NOTE:This vcard uses every type defined in rfc2426. +PRODID:-//ONLINE DIRECTORY//NONSGML Version 1//EN +REV:1995-10-31T22:27:10Z +SORT-STRING:aaa000 +SOUND:Audible1 +UID:111-111-111-111 +URL:http://first1.host1.org +CLASS:CONFIDENTIAL +KEY:The Key No 1 +X-foo:extended type 1 +END:VCARD +" + ["First1" "Last1" + ("Firsty1") + "Company1 +Unit1 +Subunit1" + (["Office" "+11111111"]) + (["Office" + ("Box111" "Room 111" "First Street" "First Corner") + "Cityone" + "First State" + "11111" + "Country"]) + ("first1@provider1") + ((x-foo . "extended type 1") + (key . "The Key No 1") + (class . "CONFIDENTIAL") + (uid . "111-111-111-111") + (sound . "Audible1") + (sort-string . "aaa000") + (prodid . "-//ONLINE DIRECTORY//NONSGML Version 1//EN") + (agent . "CID:JQPUBLIC.part3.960129T083020.xyzMail@host3.com") + (logo . "encoded logo #1") + (role . "Programmer") + (title . "Director, Research and Development") + (geo . "37.386013;-122.082932") + (tz . "+01:00") + (mailer . "Wanderlust1") + (label . "Label 1") + (photo . "The Alphabet:abcdefghijklmnopqrstuvwsyz") + (mail-alias . "category1") + (anniversary . "1999-12-05 birthday") + (notes . "This vcard uses every type defined in rfc2426.") + (www . "http://first1.host1.org") + (creation-date . "1995-10-31T22:27:10Z") (timestamp . "2010-03-04"))] + "First1 Last1" + nil nil t) + + +(bbdb-vcard-import-test + " +** Bad vCard: semi-colons where they don't belong +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +FN:First2; Last2 +N:Last2;First2 +NICKNAME:Firsty2,or; something +PHOTO:The Alphabet: + abcdefghij;klmnop + qrstuvwsyz +BDAY:1999-12-05 +ADR:Box111;Room 111;First Street,First Corner;Cityone;First State;11111;Country +LABEL:Label 1;Label 2 +TEL:+11111111;+222222 +EMAIL:first1@provider1 +MAILER:Wanderlust1;Wanderlust2 +TZ:+01:00;Here +GEO:37.386013;-122.082932 +TITLE:Director\\, Research; and Development +ROLE:Programmer +LOGO:encoded logo #1 +AGENT:CID:JQPUBLIC.part3.960129T083020.xyzMail@host3.com +ORG:Company1;Unit1;Subunit1 +CATEGORIES:category1 +NOTE:This isn't a decent vCard. It shouldn't render our bbdb unusable. We don't expect it to re-import unchanged, though. +REV:1995-10-31T22:27:10Z +SORT-STRING:aaa000 +SOUND:Audible1 +UID:111-111-111-111 +URL:http://first1.host1.org; My home +CLASS:CONFIDENTIAL +KEY:The Key No 1 +X-foo:extended type 1 +END:VCARD +" + ["First2" "Last2" + ("First2; Last2" "Firsty2" "or; something") + "Company1 +Unit1 +Subunit1" + (["Office" "+11111111;+222222"]) + (["Office" ("Box111" "Room 111" "First Street" "First Corner") "Cityone" "First State" "11111" "Country"]) + ("first1@provider1") + ((x-foo . "extended type 1") + (key . "The Key No 1") + (class . "CONFIDENTIAL") + (uid . "111-111-111-111") + (sound . "Audible1") + (sort-string . "aaa000") + (agent . "CID:JQPUBLIC.part3.960129T083020.xyzMail@host3.com") + (logo . "encoded logo #1") + (role . "Programmer") + (title . "Director, Research; and Development") + (geo . "37.386013;-122.082932") + (tz . "+01:00;Here") + (mailer . "Wanderlust1;Wanderlust2") + (label . "Label 1;Label 2") + (photo . "The Alphabet:abcdefghij;klmnopqrstuvwsyz") + (mail-alias . "category1") + (anniversary . "1999-12-05 birthday") + (notes . "This isn't a decent vCard. It shouldn't render our bbdb unusable. We don't expect it to re-import unchanged, though.") + (www . "http://first1.host1.org; My home") + (creation-date . "1995-10-31T22:27:10Z") (timestamp . "2010-03-04"))] + "First2 Last2" + nil nil t) + + +(bbdb-vcard-import-test + " +** The following is made of examples from rfc2426. +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +FN:Mr. John Q. Public\\, Esq. +N:Stevenson;John;Philip,Paul;Dr.;Jr.,M.D.,A.C.P. +NICKNAME:Robbie +PHOTO;VALUE=uri:http://www.abc.com/pub/photos + /jqpublic.gif +BDAY:1996-04-15 +ADR;TYPE=dom,home,postal,parcel:;;123 Main + Street;Any Town;CA;91921-1234 +LABEL;TYPE=dom,home,postal,parcel:Mr.John Q. Public\\, Esq.\\n + Mail Drop: TNE QB\\n123 Main Street\\nAny Town\\, CA 91921-1234 + \\nU.S.A. +TEL;TYPE=work,voice,pref,msg:+1-213-555-1234 +EMAIL;TYPE=internet:jqpublic@xyz.dom1.com +EMAIL;TYPE=internet:jdoe@isp.net +MAILER:PigeonMail 2.1 +TZ:-05:00 +GEO:37.386013;-122.082932 +TITLE:Director\\, Research and Development +ROLE:Programmer +LOGO;ENCODING=b;TYPE=JPEG:MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhvcN + AQEEBQAwdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENvbW11bm + ljYXRpb25zIENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZvcm1hdGlvbiBTeXN0 +AGENT;VALUE=uri: + CID:JQPUBLIC.part3.960129T083020.xyzMail@host3.com +ORG:ABC\\, Inc.;North American Division;Marketing +CATEGORIES:TRAVEL AGENT +NOTE:This fax number is operational 0800 to 1715 + EST\\, Mon-Fri. +PRODID:-//ONLINE DIRECTORY//NONSGML Version 1//EN +REV:1995-10-31T22:27:10Z +SOUND;TYPE=BASIC;ENCODING=b:MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhvcN + AQEEBQAwdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENvbW11bm + ljYXRpb25zIENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZvcm1hdGlvbiBTeXN0 +UID:19950401-080045-40000F192713-0052 +URL:http://www.swbyps.restaurant.french/~chezchic.html +CLASS:PUBLIC +KEY;ENCODING=b:MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhvcNAQEEBQA + wdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENbW11bmljYX + Rpb25zIENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZvcm1hdGlvbiBTeXN0 + ZW1zMRwwGgYDVQQDExNyb290Y2EubmV0c2NhcGUuY29tMB4XDTk3MDYwNj + E5NDc1OVoXDTk3MTIwMzE5NDc1OVowgYkxCzAJBgNVBAYTAlVTMSYwJAYD + VQQKEx1OZXRzY2FwZSBDb21tdW5pY2F0aW9ucyBDb3JwLjEYMBYGA1UEAx + MPVGltb3RoeSBBIEhvd2VzMSEwHwYJKoZIhvcNAQkBFhJob3dlc0BuZXRz + Y2FwZS5jb20xFTATBgoJkiaJk/IsZAEBEwVob3dlczBcMA0GCSqGSIb3DQ + EBAQUAA0sAMEgCQQC0JZf6wkg8pLMXHHCUvMfL5H6zjSk4vTTXZpYyrdN2 + dXcoX49LKiOmgeJSzoiFKHtLOIboyludF90CgqcxtwKnAgMBAAGjNjA0MB + EGCWCGSAGG+EIBAQQEAwIAoDAfBgNVHSMEGDAWgBT84FToB/GV3jr3mcau + +hUMbsQukjANBgkqhkiG9w0BAQQFAAOBgQBexv7o7mi3PLXadkmNP9LcIP + mx93HGp0Kgyx1jIVMyNgsemeAwBM+MSlhMfcpbTrONwNjZYW8vJDSoi//y + rZlVt9bJbs7MNYZVsyF1unsqaln4/vy6Uawfg8VUMk1U7jt8LYpo4YULU7 + UZHPYVUaSgVttImOHZIKi4hlPXBOhcUQ== +END:VCARD +" + ["Dr. John Philip Paul" "Stevenson Jr. M.D. A.C.P." + ("Mr. John Q. Public, Esq." "Robbie") + "ABC, Inc. +North American Division +Marketing" + (["Office" "+1-213-555-1234"]) + (["Home" + ("123 Main Street") + "Any Town" + "CA" + "91921-1234" + ""]) + ("jqpublic@xyz.dom1.com" "jdoe@isp.net") + ((key\;encoding=b . "MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhvcNAQEEBQAwdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENbW11bmljYXRpb25zIENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZvcm1hdGlvbiBTeXN0ZW1zMRwwGgYDVQQDExNyb290Y2EubmV0c2NhcGUuY29tMB4XDTk3MDYwNjE5NDc1OVoXDTk3MTIwMzE5NDc1OVowgYkxCzAJBgNVBAYTAlVTMSYwJAYDVQQKEx1OZXRzY2FwZSBDb21tdW5pY2F0aW9ucyBDb3JwLjEYMBYGA1UEAxMPVGltb3RoeSBBIEhvd2VzMSEwHwYJKoZIhvcNAQkBFhJob3dlc0BuZXRzY2FwZS5jb20xFTATBgoJkiaJk/IsZAEBEwVob3dlczBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC0JZf6wkg8pLMXHHCUvMfL5H6zjSk4vTTXZpYyrdN2dXcoX49LKiOmgeJSzoiFKHtLOIboyludF90CgqcxtwKnAgMBAAGjNjA0MBEGCWCGSAGG+EIBAQQEAwIAoDAfBgNVHSMEGDAWgBT84FToB/GV3jr3mcau+hUMbsQukjANBgkqhkiG9w0BAQQFAAOBgQBexv7o7mi3PLXadkmNP9LcIPmx93HGp0Kgyx1jIVMyNgsemeAwBM+MSlhMfcpbTrONwNjZYW8vJDSoi//yrZlVt9bJbs7MNYZVsyF1unsqaln4/vy6Uawfg8VUMk1U7jt8LYpo4YULU7UZHPYVUaSgVttImOHZIKi4hlPXBOhcUQ==") + (class . "PUBLIC") + (uid . "19950401-080045-40000F192713-0052") + (sound\;type=basic\;encoding=b . "MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhvcNAQEEBQAwdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENvbW11bmljYXRpb25zIENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZvcm1hdGlvbiBTeXN0") + (prodid . "-//ONLINE DIRECTORY//NONSGML Version 1//EN") + (agent\;value=uri . "CID:JQPUBLIC.part3.960129T083020.xyzMail@host3.com") + (logo\;encoding=b\;type=jpeg . "MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhvcNAQEEBQAwdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENvbW11bmljYXRpb25zIENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZvcm1hdGlvbiBTeXN0") + (role . "Programmer") + (title . "Director, Research and Development") + (geo . "37.386013;-122.082932") + (tz . "-05:00") + (mailer . "PigeonMail 2.1") + (label\;type=dom\,home\,postal\,parcel . "Mr.John Q. Public, Esq. +Mail Drop: TNE QB +123 Main Street +Any Town, CA 91921-1234 +U.S.A.") + (photo\;value=uri . "http://www.abc.com/pub/photos/jqpublic.gif") + (mail-alias . "TRAVEL AGENT") + (anniversary . "1996-04-15 birthday") + (notes . "This fax number is operational 0800 to 1715 EST, Mon-Fri.") + (www . "http://www.swbyps.restaurant.french/~chezchic.html") + (creation-date . "1995-10-31T22:27:10Z") (timestamp . "2010-03-04"))] + "John" + nil nil t) + + +(bbdb-vcard-import-test + " +** Exactly the same as before. + Re-reading it shouldn't duplicate anything. +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +FN:Mr. John Q. Public\\, Esq. +N:Stevenson;John;Philip,Paul;Dr.;Jr.,M.D.,A.C.P. +NICKNAME:Robbie +PHOTO;VALUE=uri:http://www.abc.com/pub/photos + /jqpublic.gif +BDAY:1996-04-15 +ADR;TYPE=dom,home,postal,parcel:;;123 Main + Street;Any Town;CA;91921-1234 +LABEL;TYPE=dom,home,postal,parcel:Mr.John Q. Public\\, Esq.\\n + Mail Drop: TNE QB\\n123 Main Street\\nAny Town\\, CA 91921-1234 + \\nU.S.A. +TEL;TYPE=work,voice,pref,msg:+1-213-555-1234 +EMAIL;TYPE=internet:jqpublic@xyz.dom1.com +EMAIL;TYPE=internet:jdoe@isp.net +MAILER:PigeonMail 2.1 +TZ:-05:00 +GEO:37.386013;-122.082932 +TITLE:Director\\, Research and Development +ROLE:Programmer +LOGO;ENCODING=b;TYPE=JPEG:MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhvcN + AQEEBQAwdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENvbW11bm + ljYXRpb25zIENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZvcm1hdGlvbiBTeXN0 +AGENT;VALUE=uri: + CID:JQPUBLIC.part3.960129T083020.xyzMail@host3.com +ORG:ABC\\, Inc.;North American Division;Marketing +CATEGORIES:TRAVEL AGENT +NOTE:This fax number is operational 0800 to 1715 + EST\\, Mon-Fri. +PRODID:-//ONLINE DIRECTORY//NONSGML Version 1//EN +REV:1995-10-31T22:27:10Z +SOUND;TYPE=BASIC;ENCODING=b:MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhvcN + AQEEBQAwdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENvbW11bm + ljYXRpb25zIENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZvcm1hdGlvbiBTeXN0 +UID:19950401-080045-40000F192713-0052 +URL:http://www.swbyps.restaurant.french/~chezchic.html +CLASS:PUBLIC +KEY;ENCODING=b:MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhvcNAQEEBQA + wdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENbW11bmljYX + Rpb25zIENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZvcm1hdGlvbiBTeXN0 + ZW1zMRwwGgYDVQQDExNyb290Y2EubmV0c2NhcGUuY29tMB4XDTk3MDYwNj + E5NDc1OVoXDTk3MTIwMzE5NDc1OVowgYkxCzAJBgNVBAYTAlVTMSYwJAYD + VQQKEx1OZXRzY2FwZSBDb21tdW5pY2F0aW9ucyBDb3JwLjEYMBYGA1UEAx + MPVGltb3RoeSBBIEhvd2VzMSEwHwYJKoZIhvcNAQkBFhJob3dlc0BuZXRz + Y2FwZS5jb20xFTATBgoJkiaJk/IsZAEBEwVob3dlczBcMA0GCSqGSIb3DQ + EBAQUAA0sAMEgCQQC0JZf6wkg8pLMXHHCUvMfL5H6zjSk4vTTXZpYyrdN2 + dXcoX49LKiOmgeJSzoiFKHtLOIboyludF90CgqcxtwKnAgMBAAGjNjA0MB + EGCWCGSAGG+EIBAQQEAwIAoDAfBgNVHSMEGDAWgBT84FToB/GV3jr3mcau + +hUMbsQukjANBgkqhkiG9w0BAQQFAAOBgQBexv7o7mi3PLXadkmNP9LcIP + mx93HGp0Kgyx1jIVMyNgsemeAwBM+MSlhMfcpbTrONwNjZYW8vJDSoi//y + rZlVt9bJbs7MNYZVsyF1unsqaln4/vy6Uawfg8VUMk1U7jt8LYpo4YULU7 + UZHPYVUaSgVttImOHZIKi4hlPXBOhcUQ== +END:VCARD +" +["Dr. John Philip Paul" "Stevenson Jr. M.D. A.C.P." + ("Mr. John Q. Public, Esq." "Robbie") + "ABC, Inc. +North American Division +Marketing" + (["Office" "+1-213-555-1234"]) + (["Home" + ("123 Main Street") + "Any Town" + "CA" + "91921-1234" + ""]) + ("jqpublic@xyz.dom1.com" "jdoe@isp.net") + ((key\;encoding=b . "MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhvcNAQEEBQAwdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENbW11bmljYXRpb25zIENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZvcm1hdGlvbiBTeXN0ZW1zMRwwGgYDVQQDExNyb290Y2EubmV0c2NhcGUuY29tMB4XDTk3MDYwNjE5NDc1OVoXDTk3MTIwMzE5NDc1OVowgYkxCzAJBgNVBAYTAlVTMSYwJAYDVQQKEx1OZXRzY2FwZSBDb21tdW5pY2F0aW9ucyBDb3JwLjEYMBYGA1UEAxMPVGltb3RoeSBBIEhvd2VzMSEwHwYJKoZIhvcNAQkBFhJob3dlc0BuZXRzY2FwZS5jb20xFTATBgoJkiaJk/IsZAEBEwVob3dlczBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC0JZf6wkg8pLMXHHCUvMfL5H6zjSk4vTTXZpYyrdN2dXcoX49LKiOmgeJSzoiFKHtLOIboyludF90CgqcxtwKnAgMBAAGjNjA0MBEGCWCGSAGG+EIBAQQEAwIAoDAfBgNVHSMEGDAWgBT84FToB/GV3jr3mcau+hUMbsQukjANBgkqhkiG9w0BAQQFAAOBgQBexv7o7mi3PLXadkmNP9LcIPmx93HGp0Kgyx1jIVMyNgsemeAwBM+MSlhMfcpbTrONwNjZYW8vJDSoi//yrZlVt9bJbs7MNYZVsyF1unsqaln4/vy6Uawfg8VUMk1U7jt8LYpo4YULU7UZHPYVUaSgVttImOHZIKi4hlPXBOhcUQ==") + (class . "PUBLIC") + (uid . "19950401-080045-40000F192713-0052") + (sound\;type=basic\;encoding=b . "MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhvcNAQEEBQAwdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENvbW11bmljYXRpb25zIENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZvcm1hdGlvbiBTeXN0") + (prodid . "-//ONLINE DIRECTORY//NONSGML Version 1//EN") + (agent\;value=uri . "CID:JQPUBLIC.part3.960129T083020.xyzMail@host3.com") + (logo\;encoding=b\;type=jpeg . "MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhvcNAQEEBQAwdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENvbW11bmljYXRpb25zIENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZvcm1hdGlvbiBTeXN0") + (role . "Programmer") + (title . "Director, Research and Development") + (geo . "37.386013;-122.082932") + (tz . "-05:00") + (mailer . "PigeonMail 2.1") + (label\;type=dom\,home\,postal\,parcel . "Mr.John Q. Public, Esq. +Mail Drop: TNE QB +123 Main Street +Any Town, CA 91921-1234 +U.S.A.") + (photo\;value=uri . "http://www.abc.com/pub/photos/jqpublic.gif") + (www . "http://www.swbyps.restaurant.french/~chezchic.html") + (mail-alias . "TRAVEL AGENT") + (anniversary . "1996-04-15 birthday") + (notes . "This fax number is operational 0800 to 1715 EST, Mon-Fri.") + (creation-date . "1995-10-31T22:27:10Z") (timestamp . "2010-03-04"))] + "John" + nil nil t) + + +(bbdb-vcard-import-test + " +** Re-use of existing BBDB entries. +*** N, ORG, EMAIL +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyA;FirstA +ORG:OrgA;UnitA +EMAIL:userA@hostA.example.com +END:vcard +" + ["FirstA" "FamilyA" + nil + "OrgA +UnitA" + nil + nil + ("userA@hostA.example.com") + ((creation-date . "2010-03-04") (timestamp . "2010-03-04")) ] + "FirstA FamilyA") + + +(bbdb-vcard-import-test + " +*** The same again; shouldn't change the previous one. +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyA;FirstA +ORG:OrgA;UnitA +EMAIL:userA@hostA.example.com +END:VCARD +" + ["FirstA" "FamilyA" + nil + "OrgA +UnitA" + nil + nil + ("userA@hostA.example.com") + ((creation-date . "2010-03-04") (timestamp . "2010-03-04")) ] + "FirstA FamilyA") + + +(bbdb-vcard-import-test + " +*** Same N, same ORG, different EMAIL, which should be added to the previous + one. +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyA;FirstA +ORG:OrgA;UnitA +EMAIL:personA@example.com +END:VCARD +" + ["FirstA" "FamilyA" + nil + "OrgA +UnitA" + nil + nil + ("userA@hostA.example.com" "personA@example.com") + ((creation-date . "2010-03-04") (timestamp . "2010-03-04")) ] + "FirstA FamilyA") + + +(bbdb-vcard-import-test + " +*** Same N, same ORG, no EMAIL; shouldn't change anything. +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyA;FirstA +ORG:OrgA;UnitA +END:VCARD +" + ["FirstA" "FamilyA" + nil + "OrgA +UnitA" + nil + nil + ("userA@hostA.example.com" "personA@example.com") + ((creation-date . "2010-03-04") (timestamp . "2010-03-04")) ] + "FirstA FamilyA") + + +(bbdb-vcard-import-test + " +*** Same N, same EMAIL, no ORG; shouldn't change anything. +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyA;FirstA +EMAIL:userA@hostA.example.com +END:VCARD +" + ["FirstA" "FamilyA" + nil + "OrgA +UnitA" + nil + nil + ("userA@hostA.example.com" "personA@example.com") + ((creation-date . "2010-03-04") (timestamp . "2010-03-04")) ] + "FirstA FamilyA") + + +(bbdb-vcard-import-test + " +*** Same N, same EMAIL, different ORG by which Company of the previous one + should be replaced. +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyA;FirstA +ORG:OrgA;UnitB +EMAIL:userA@hostA.example.com +END:VCARD +" + ["FirstA" "FamilyA" + nil + "OrgA +UnitB" + nil + nil + ("userA@hostA.example.com" "personA@example.com") + ((creation-date . "2010-03-04") (timestamp . "2010-03-04")) ] + "FirstA FamilyA") + + +(bbdb-vcard-import-test + " +*** Different N, same EMAIL, same ORG; should go into a fresh entry. +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyA1;FirstA1 +ORG:OrgA;UnitB +EMAIL:userA@hostA.example.com +END:VCARD +" + ["FirstA1" "FamilyA1" + nil + "OrgA +UnitB" + nil + nil + ("userA@hostA.example.com") + ((creation-date . "2010-03-04") (timestamp . "2010-03-04")) ] + "FirstA1 FamilyA1") + + + +(bbdb-vcard-import-test + " +** AKA has various sources; duplicates are being discarded. +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyB;FirstB +A.N:PseudonymB;FirstB +FN:The FirstB of FamilyB +A.FN:FirstB1 FamilyB1 +B.FN:FirstB2 FamilyB2 +C.FN:FirstB FamilyB +NICKNAME:Bee,Effy Bee,FirstB FamilyB +END:VCARD +" + ["FirstB" "FamilyB" + ("FirstB2 FamilyB2" + "FirstB1 FamilyB1" + "The FirstB of FamilyB" + "FirstB PseudonymB" + "Bee" + "Effy Bee") + nil + nil + nil + nil + ((creation-date . "2010-03-04") (timestamp . "2010-03-04"))] + "FirstB FamilyB") + + +(bbdb-vcard-import-test + " +** Additional ORGs go to Notes, org. +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyC;FirstC +ORG:OrgC1 +ORG:OrgC2 +END:vcard +" + ["FirstC" "FamilyC" + nil + "OrgC1" + nil + nil + nil + ((org . "OrgC2") + (creation-date . "2010-03-04") (timestamp . "2010-03-04")) ] + "FirstC FamilyC") + + +(bbdb-vcard-import-test + " +*** ... but only if they are unique +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyC;FirstC +ORG:OrgC1 +ORG:OrgC2 +ORG:OrgC3 +ORG:OrgC3 +ORG:OrgC4 +END:VCARD +" + ["FirstC" "FamilyC" + nil + "OrgC1" + nil + nil + nil + ((org . "OrgC4") + (org . "OrgC3") + (org . "OrgC2") + (creation-date . "2010-03-04") (timestamp . "2010-03-04")) ] + "FirstC FamilyC") + + +(bbdb-vcard-import-test + " +** Prefixes are discarded. +------------------------------------------------------------ +X.BEGIN:VCARD +X.VERSION:3.0 +X.N:FamilyD;FirstD +X.ORG:OrgD;UnitD +X.EMAIL:userD@hostD.example.com +X.END:VCARD +" + ["FirstD" "FamilyD" + nil + "OrgD +UnitD" + nil + nil + ("userD@hostD.example.com") + ((creation-date . "2010-03-04") (timestamp . "2010-03-04")) ] + "FirstD FamilyD") + + +(bbdb-vcard-import-test + " +*** Same as before, don't change anything. +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyD;FirstD +ORG:OrgD;UnitD +EMAIL:userD@hostD.example.com +END:VCARD +" + ["FirstD" "FamilyD" + nil + "OrgD +UnitD" + nil + nil + ("userD@hostD.example.com") + ((creation-date . "2010-03-04") (timestamp . "2010-03-04")) ] + "FirstD FamilyD") + + +(bbdb-vcard-import-test + " +*** Same as before, don't change anything. +------------------------------------------------------------ +Y.BEGIN:VCARD +Y.VERSION:3.0 +Y.N:FamilyD;FirstD +Y.ORG:OrgD;UnitD +Y.EMAIL:userD@hostD.example.com +Y.END:VCARD +" + ["FirstD" "FamilyD" + nil + "OrgD +UnitD" + nil + nil + ("userD@hostD.example.com") + ((creation-date . "2010-03-04") (timestamp . "2010-03-04")) ] + "FirstD FamilyD") + + +(bbdb-vcard-import-test + " +** Case Insensitivity +------------------------------------------------------------ +BEGIN:Vcard +Version:3.0 +n:FamilyE;FirstE +Org:OrgE;UnitE +email:userE@hostE.example.com +end:vcard +" + ["FirstE" "FamilyE" + nil + "OrgE +UnitE" + nil + nil + ("userE@hostE.example.com") + ((creation-date . "2010-03-04") (timestamp . "2010-03-04")) ] + "FirstE FamilyE") + + +(bbdb-vcard-import-test + " +** Non-ASCII Content +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +FN:Franz Rübezahl +N:Rübezahl;Franz +NICKNAME:Fränzchen,Rübe +ADR:Postschließfach 17;Zimmer Zwölf;Einbahnstraße;Ödstadt;;75480; +ORG:Rübe AG +END:VCARD +" + ["Franz" "Rübezahl" + ("Fränzchen" "Rübe") + "Rübe AG" + nil + (["Office" + ("Postschließfach 17" "Zimmer Zwölf" "Einbahnstraße") + "Ödstadt" + "" + "75480" + ""]) + nil + ((creation-date . "2010-03-06") (timestamp . "2010-03-06")) ] + "Rübe") + + +(bbdb-vcard-import-test + " +*** Multiple, structured ADR +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyF;FirstF +ORG:OrgF;UnitF +ADR;TYPE=dom,home,postal,parcel:Box111,LHS;Room 111,or not;First Street,First Corner;Cityone;First State;11111,22222;Country +ADR;TYPE=intl,work,postal,parcel:Box222,RHS;Room 22,or something;Second Street,First Corner;Citytwo;Second State;222,33333;Country +ADR;TYPE=dom,work,postal,parcel:;;Second Street,First Corner;Citytwo;;222,33333; +ADR;TYPE=intl;TYPE=home;TYPE=parcel:;;Third Street,First Corner;Citythree;;222,33333; +END:VCARD +" + ["FirstF" "FamilyF" + nil + "OrgF +UnitF" + nil + (["Home" + ("Box111" "LHS" "Room 111" "or not" "First Street" "First Corner") + "Cityone" + "First State" + "11111\n22222" + "Country"] + ["Office" + ("Box222" "RHS" "Room 22" "or something" "Second Street" "First Corner") + "Citytwo" + "Second State" + "222\n33333" + "Country"] + ["Office" + ("Second Street" "First Corner") + "Citytwo" + "" + "222\n33333" + ""] + ["Home" + ("Third Street" "First Corner") + "Citythree" + "" + "222\n33333" + ""]) + nil + ((creation-date . "2010-03-04") (timestamp . "2010-03-04"))] + "FirstF FamilyF") + + +(bbdb-vcard-import-test + " +*** Skip types from bbdb-vcard-skip-on-import +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyH;FirstH +ORG:OrgH;UnitH +EMAIL:userH@hostH.example.com +X-GSM-FOO:Blah +X-GSM-BAR:Blahblah +END:VCARD +" + ["FirstH" "FamilyH" + nil + "OrgH +UnitH" + nil + nil + ("userH@hostH.example.com") + ((creation-date . "2010-03-04") (timestamp . "2010-03-04")) ] + "FirstH FamilyH") + + +(bbdb-vcard-import-test + " +*** Skip empty types. +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyG;FirstG +ORG:OrgG;UnitG +EMAIL:userG@hostG.example.com +ROLE: +TITLE: +GEO: +END:VCARD +" + ["FirstG" "FamilyG" + nil + "OrgG +UnitG" + nil + nil + ("userG@hostG.example.com") + ((creation-date . "2010-03-04") (timestamp . "2010-03-04")) ] + "FirstG FamilyG") + + +(bbdb-vcard-import-test + " +*** Remove X-BBDB- prefixes +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyN;FirstN +ORG:OrgN;UnitN +EMAIL:userN@hostN.example.com +X-BBDB-MARK-CHAR:b +X-BBDB-TEX-NAME:{\\\\em FirstM FamilyM} +END:VCARD +" + ["FirstN" "FamilyN" + nil + "OrgN +UnitN" + nil + nil + ("userN@hostN.example.com") + ((tex-name . "{\\em FirstM FamilyM}") + (mark-char . "b") + (creation-date . "2010-03-04") (timestamp . "2010-03-04"))] + "FirstN FamilyN") + + +(bbdb-vcard-import-test + " +** Merging of vcard NOTEs +*** A vcard with two NOTEs. +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyI;FirstI +ORG:OrgI +NOTE:Note No. 1a +NOTE:Note No. 1b +END:VCARD +" + ["FirstI" "FamilyI" + nil + "OrgI" + nil + nil + nil + ((notes . "Note No. 1a;\nNote No. 1b") + (creation-date . "2010-03-04") (timestamp . "2010-03-04")) ] + "FirstI FamilyI") + + +(bbdb-vcard-import-test + " +*** Same as before, but a different NOTE. +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyI;FirstI +ORG:OrgI +NOTE:Note No. 2 +END:VCARD +" + ["FirstI" "FamilyI" + nil + "OrgI" + nil + nil + nil + ((notes . "Note No. 1a;\nNote No. 1b;\nNote No. 2") + (creation-date . "2010-03-04") (timestamp . "2010-03-04")) ] + "FirstI FamilyI") + + +(bbdb-vcard-import-test + " +*** Same as before, but a NOTE we've seen already +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyI;FirstI +ORG:OrgI +NOTE:Note No. 1b +END:VCARD +" + ["FirstI" "FamilyI" + nil + "OrgI" + nil + nil + nil + ((notes . "Note No. 1a;\nNote No. 1b;\nNote No. 2") + (creation-date . "2010-03-04") (timestamp . "2010-03-04")) ] + "FirstI FamilyI") + + + +(bbdb-vcard-import-test + " +** Merging of vcard CATEGORIES +*** A vcard with two CATEGORIES. +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyM;FirstM +ORG:OrgI +CATEGORIES:Category 1a,Category 1b +CATEGORIES:Category 2a,Category 2b +END:VCARD +" + ["FirstM" "FamilyM" + nil + "OrgI" + nil + nil + nil + ((mail-alias . "Category 1a,Category 1b,Category 2a,Category 2b") + (creation-date . "2010-03-04") (timestamp . "2010-03-04"))] + "FirstM FamilyM") + + +(bbdb-vcard-import-test + " +*** Same as before, but a different CATEGORIES. +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyM;FirstM +ORG:OrgI +CATEGORIES:Category 3 +END:VCARD +" + ["FirstM" "FamilyM" + nil + "OrgI" + nil + nil + nil + ((mail-alias . "Category 1a,Category 1b,Category 2a,Category 2b,Category 3") + (creation-date . "2010-03-04") (timestamp . "2010-03-04"))] + "FirstM FamilyM") + + +(bbdb-vcard-import-test + " +*** Same as before, but a CATEGORIES we've seen already +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyM;FirstM +ORG:OrgI +CATEGORIES:Category 2b +END:VCARD +" + ["FirstM" "FamilyM" + nil + "OrgI" + nil + nil + nil + ((mail-alias . "Category 1a,Category 1b,Category 2a,Category 2b,Category 3") + (creation-date . "2010-03-04") (timestamp . "2010-03-04"))] + "FirstM FamilyM") + + +(bbdb-vcard-import-test + " +** A vcard with two other vcards inside; we check the outer one +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +FN:OuterfirstA OuterlastA +N:OuterlastA OuterfirstA +AGENT:BEGIN:VCARD\\nVERSION:3.0\\nN:InnerlastA\\;InnerfirstA\\nFN:InnerfirstA InnerlastA\\nTEL:+1-919-555- + 1234\\nEMAIL\\;TYPE=INTERNET:InnerA@hostA.com\\nEND:VCARD\\n +B.AGENT:BEGIN:VCARD\\nVERSION:3.0\\nN:InnerlastB\\;InnerfirstB\\nFN:InnerfirstB InnerlastB\\nTEL:+1-919-555- + 1234\\nEMAIL\\;TYPE=INTERNET:InnerB@hostB.com\\nEND:VCARD\\n +NOTE:A note +END:VCARD +" + ["OuterlastA" "OuterfirstA" + ("OuterfirstA OuterlastA") + nil + nil + nil + nil + ((b\.agent . "BEGIN:VCARD +VERSION:3.0 +N:InnerlastB;InnerfirstB +FN:InnerfirstB InnerlastB +TEL:+1-919-555-1234 +EMAIL;TYPE=INTERNET:InnerB@hostB.com +END:VCARD +") + (agent . "BEGIN:VCARD +VERSION:3.0 +N:InnerlastA;InnerfirstA +FN:InnerfirstA InnerlastA +TEL:+1-919-555-1234 +EMAIL;TYPE=INTERNET:InnerA@hostA.com +END:VCARD +") + (notes . "A note") + (creation-date . "2010-03-04") (timestamp . "2010-03-04")) ] + "OuterfirstA OuterlastA") + + +(bbdb-vcard-import-test + " +** A vcard with two other vcards inside; we check the first inner one +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +FN:OuterfirstA OuterlastA +N:OuterlastA OuterfirstA +AGENT:BEGIN:VCARD\\nVERSION:3.0\\nN:InnerlastA\\;InnerfirstA\\nFN:InnerfirstA InnerlastA\\nTEL:+1-919-555- + 1234\\nEMAIL\\;TYPE=INTERNET:InnerA@hostA.com\\nEND:VCARD\\n +B.AGENT:BEGIN:VCARD\\nVERSION:3.0\\nN:InnerlastB\\;InnerfirstB\\nFN:InnerfirstB InnerlastB\\nTEL:+1-919-555- + 1234\\nEMAIL\\;TYPE=INTERNET:InnerB@hostB.com\\nEND:VCARD\\n +NOTE:A note +END:VCARD +" + ["InnerfirstA" "InnerlastA" + nil + nil + (["Office" "+1-919-555-1234"]) + nil + ("InnerA@hostA.com") + ((creation-date . "2010-03-04") (timestamp . "2010-03-04"))] + "InnerfirstA InnerlastA") + + +(bbdb-vcard-import-test + " +** A vcard with two other vcards inside; we check the second inner one +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +FN:OuterfirstA OuterlastA +N:OuterlastA OuterfirstA +AGENT:BEGIN:VCARD\\nVERSION:3.0\\nN:InnerlastA\\;InnerfirstA\\nFN:InnerfirstA InnerlastA\\nTEL:+1-919-555- + 1234\\nEMAIL\\;TYPE=INTERNET:InnerA@hostA.com\\nEND:VCARD\\n +B.AGENT:BEGIN:VCARD\\nVERSION:3.0\\nN:InnerlastB\\;InnerfirstB\\nFN:InnerfirstB InnerlastB\\nTEL:+1-919-555- + 1234\\nEMAIL\\;TYPE=INTERNET:InnerB@hostB.com\\nEND:VCARD\\n +NOTE:A note +END:VCARD +" + ["InnerfirstB" "InnerlastB" + nil + nil + (["Office" "+1-919-555-1234"]) + nil + ("InnerB@hostB.com") + ((creation-date . "2010-03-04") (timestamp . "2010-03-04"))] + "InnerfirstB InnerlastB") + + +(bbdb-vcard-import-test + " +** Treatment of REV +*** Store REV as creation-date in new records... +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyJ;FirstJ +ORG:OrgJ +REV:1997-03-27T22:27:10Z +END:VCARD +" + ["FirstJ" "FamilyJ" + nil + "OrgJ" + nil + nil + nil + ((creation-date . "1997-03-27T22:27:10Z") (timestamp . "2010-03-04")) ] + "FirstJ FamilyJ" + nil nil t) + + +(bbdb-vcard-import-test + " +*** ...but not in existing records +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyJ;FirstJ +ORG:OrgJ +REV:1977-12-03T22:27:10Z +END:VCARD +" + ["FirstJ" "FamilyJ" + nil + "OrgJ" + nil + nil + nil + ((creation-date . "1997-03-27T22:27:10Z") (timestamp . "2010-03-04")) ] + "FirstJ FamilyJ" + nil nil t) + + +(bbdb-vcard-import-test + " +*** The same, but dashless REV +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyR;FirstR +ORG:OrgR +REV:19771203T222710Z +END:VCARD +" + ["FirstR" "FamilyR" + nil + "OrgR" + nil + nil + nil + ((creation-date . "1977-12-03T22:27:10Z") (timestamp . "2010-03-04")) ] + "FirstR FamilyR" + nil nil t) + + + +(bbdb-vcard-import-test + " +** Matching BDAY and N induce merge +*** Storing a new person +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyK;FirstK +ORG:CompanyK +BDAY:1927-03-27 +END:VCARD +" + ["FirstK" "FamilyK" + nil + "CompanyK" + nil + nil + nil + ((anniversary . "1927-03-27 birthday") + (creation-date . "2010-03-04") (timestamp . "2010-03-04")) ] + "FirstK FamilyK") + + +(bbdb-vcard-import-test + " +*** Not quite the same person: BDAY differs. +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyK;FirstK +ORG:CompanyK2 +BDAY:1937-04-28 +END:VCARD +" + ["FirstK" "FamilyK" + nil + "CompanyK2" + nil + nil + nil + ((anniversary . "1937-04-28 birthday") + (creation-date . "2010-03-04") (timestamp . "2010-03-04")) ] + "FirstK FamilyK" + "CompanyK2") + + +(bbdb-vcard-import-test + " +*** Known person due to matching BDAY. Different ORG, though. +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyK;FirstK +ORG:CompanyK1 +BDAY:1927-03-27 +END:VCARD +" + ["FirstK" "FamilyK" + nil + "CompanyK1" + nil + nil + nil + ((anniversary . "1927-03-27 birthday") + (creation-date . "2010-03-04") (timestamp . "2010-03-04")) ] + "FirstK FamilyK" + "CompanyK1") + + +(bbdb-vcard-import-test + " +*** Known person due to matching BDAY (albeit in another date format). Different ORG, again. +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyK;FirstK +ORG:CompanyK3 +BDAY:19270327 +END:VCARD +" + ["FirstK" "FamilyK" + nil + "CompanyK3" + nil + nil + nil + ((anniversary . "1927-03-27 birthday") + (creation-date . "2010-03-04") (timestamp . "2010-03-04")) ] + "FirstK FamilyK" + "CompanyK3") + + + +(bbdb-vcard-import-test + " +*** Anniversaries +** Birthdays include time. +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyP;FirstP +BDAY:1927-03-27T23:44:54Z +END:VCARD +" + ["FirstP" "FamilyP" + nil + nil + nil + nil + nil + ((anniversary . "1927-03-27T23:44:54Z birthday") + (creation-date . "2010-03-04") (timestamp . "2010-03-04"))] + "FirstP FamilyP") + + +(bbdb-vcard-import-test + " +** Birthdays include time (half-obsolete format). +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyQ;FirstQ +BDAY:19580327T234454 +END:VCARD +" + ["FirstQ" "FamilyQ" + nil + nil + nil + nil + nil + ((anniversary . "1958-03-27T23:44:54 birthday") + (creation-date . "2010-03-04") (timestamp . "2010-03-04"))] + "FirstQ FamilyQ") + + +(bbdb-vcard-import-test + " +** Non-birthday anniversaries +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyM;FirstM +BDAY:1927-03-27 +X-BBDB-ANNIVERSARY:1960-12-12 wedding\\n1970-11-11 blah\\n1998-03-12 %s created bbdb-anniv.el %d years ago +END:VCARD +" + ["FirstM" "FamilyM" + nil + nil + nil + nil + nil + ((anniversary . "1927-03-27 birthday\n1960-12-12 wedding\n1970-11-11 blah\n1998-03-12 %s created bbdb-anniv.el %d years ago") + (creation-date . "2010-03-04") (timestamp . "2010-03-04"))] + "FirstM FamilyM") + + +(bbdb-vcard-import-test + " +** Non-birthday anniversaries, no BDAY +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyN;FirstN +X-BBDB-ANNIVERSARY:1960-12-12 wedding\\n1970-11-11 blah +END:VCARD +" + ["FirstN" "FamilyN" + nil + nil + nil + nil + nil + ((anniversary . "1960-12-12 wedding\n1970-11-11 blah") + (creation-date . "2010-03-04") (timestamp . "2010-03-04"))] + "FirstN FamilyN") + + + +(bbdb-vcard-import-test + " +** No BDAY, but unlabelled birthday in anniversary +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyO;FirstO +X-BBDB-ANNIVERSARY:1960-12-12\\n1970-11-11 blah +NOTE:On re-import, birthday gets labelled. + Therefore, re-import test of this one should fail. +END:VCARD +" + ["FirstO" "FamilyO" + nil + nil + nil + nil + nil + ((anniversary . "1960-12-12\n1970-11-11 blah") + (notes . "On re-import, birthday gets labelled. Therefore, re-import test of this one should fail.") + (creation-date . "2010-03-04") (timestamp . "2010-03-04"))] + "FirstO FamilyO") + + + +(bbdb-vcard-import-test + " +** Matching TEL and N induce merge +*** Storing a new person +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyL;FirstL +TEL;TYPE=work:111100001 +TEL;TYPE=home:111100002 +TEL:111100003 +ORG:CompanyL +END:VCARD +" + ["FirstL" "FamilyL" + nil + "CompanyL" + (["Office" "111100001"] + ["Home" "111100002"] + ["Office" "111100003"] +) + nil + nil + ((creation-date . "2010-03-04") (timestamp . "2010-03-04"))] + "FirstL FamilyL") + + +(bbdb-vcard-import-test + " +*** Not quite the same person: no matching TEL. +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyL;FirstL +TEL;TYPE=work:222200001 +TEL;TYPE=home:222200002 +TEL:222200003 +ORG:CompanyL2 +END:VCARD +" + ["FirstL" "FamilyL" + nil + "CompanyL2" + (["Office" "222200001"] + ["Home" "222200002"] + ["Office" "222200003"]) + nil + nil + ((creation-date . "2010-03-04") (timestamp . "2010-03-04"))] + "FirstL FamilyL" + "CompanyL2") + + +(bbdb-vcard-import-test + " +*** Known person: matching TEL (but different ORG). +------------------------------------------------------------ +BEGIN:VCARD +VERSION:3.0 +N:FamilyL;FirstL +TEL;TYPE=work:333300001 +TEL;TYPE=work:111100002 +TEL:333300003 +ORG:CompanyL3 +END:VCARD +" + ["FirstL" "FamilyL" + nil + "CompanyL3" + (["Office" "111100003"] + ["Home" "111100002"] + ["Office" "111100001"] + ["Office" "333300001"] + ["Office" "111100002"] + ["Office" "333300003"]) + nil + nil + ((creation-date . "2010-03-04") (timestamp . "2010-03-04"))] + "FirstL FamilyL" + "CompanyL3") + + + +(bbdb-vcard-import-test + " +** From RFC 2426: author's address. Note the omission or type N + which is declared mandatory by this very RFC. +------------------------------------------------------------ +BEGIN:vCard +VERSION:3.0 +FN:Frank Dawson +ORG:Lotus Development Corporation +ADR;TYPE=WORK,POSTAL,PARCEL:;;6544 Battleford Drive + ;Raleigh;NC;27613-3502;U.S.A. +TEL;TYPE=VOICE,MSG,WORK:+1-919-676-9515 +TEL;TYPE=FAX,WORK:+1-919-676-9564 +EMAIL;TYPE=INTERNET,PREF:Frank_Dawson@Lotus.com +EMAIL;TYPE=INTERNET:fdawson@earthlink.net +URL:http://home.earthlink.net/~fdawson +END:vCard +" + ["" "" + ("Frank Dawson") + "Lotus Development Corporation" + (["Office" "+1-919-676-9515"] ["Office" "+1-919-676-9564"]) + (["Office" + ("6544 Battleford Drive") + "Raleigh" + "NC" + "27613-3502" + "U.S.A."]) + ("Frank_Dawson@Lotus.com" "fdawson@earthlink.net") + ((www . "http://home.earthlink.net/~fdawson") + (creation-date . "2010-03-04") (timestamp . "2010-03-04"))] + "Frank Dawson") + +(bbdb-vcard-import-test + " +** The other author of RFC 2426 +------------------------------------------------------------ +BEGIN:vCard +VERSION:3.0 +FN:Tim Howes +ORG:Netscape Communications Corp. +ADR;TYPE=WORK:;;501 E. Middlefield Rd.;Mountain View; + CA; 94043;U.S.A. +TEL;TYPE=VOICE,MSG,WORK:+1-415-937-3419 +TEL;TYPE=FAX,WORK:+1-415-528-4164 +EMAIL;TYPE=INTERNET:howes@netscape.com +END:vCard +" + ["" "" + ("Tim Howes") + "Netscape Communications Corp." + (["Office" "+1-415-937-3419"] + ["Office" "+1-415-528-4164"]) + (["Office" + ("501 E. Middlefield Rd.") + "Mountain View" + "CA" + " 94043" + "U.S.A."]) + ("howes@netscape.com") + ((creation-date . "2010-03-04") (timestamp . "2010-03-04"))] + "Tim Howes") + + + +(bbdb-vcard-import-test + " +** vCard version 2.1 +------------------------------------------------------------ +BEGIN:VCARD +VERSION:2.1 +N:Friday;Fred +TEL;WORK;VOICE:+1-213-555-1234 +TEL;WORK;FAX:+1-213-555-5678 +BDAY:19661221t173745 +END:VCARD +" + ["Fred" "Friday" + nil + nil + (["Office" "+1-213-555-1234"] + ["Office" "+1-213-555-5678"]) + nil + nil + ((anniversary . "1966-12-21T17:37:45 birthday") (creation-date . "2010-03-04") (timestamp . "2010-03-04"))] + "Fred Friday") + + +(bbdb-vcard-import-test + " +** vCard version 2.1 +*** Case insensitivity +------------------------------------------------------------ +begin:VCARD +version:2.1 +n:Thursday;Tom +tel;WORK;VOICE:+1-213-555-1234 +tel;WORK;FAX:+1-213-555-5678 +end:VCARD +" + ["Tom" "Thursday" + nil + nil + (["Office" "+1-213-555-1234"] + ["Office" "+1-213-555-5678"]) + nil + nil + ((creation-date . "2010-03-04") (timestamp . "2010-03-04"))] + "Tom Thursday") + + +(bbdb-vcard-import-test + " +** vCard version 2.1 +------------------------------------------------------------ +BEGIN:VCARD +VERSION:2.1 +N:Smith;John;M.;Mr.;Esq. +TEL;WORK;VOICE;MSG:+1 (919) 555-1234 +TEL;CELL:+1 (919) 554-6758 +TEL;WORK;FAX:+1 (919) 555-9876 +ADR;WORK;PARCEL;POSTAL;DOM:Suite 101;1 Central St.;AnyTown;NC;27654 +END:VCARD +" + ["Mr. John M." "Smith Esq." + nil + nil + (["Office" "+1 (919) 555-1234"] + ["Mobile" "+1 (919) 554-6758"] + ["Office" "+1 (919) 555-9876"]) + (["Office" ("Suite 101" "1 Central St." "AnyTown") "NC" "27654" "" ""]) + nil + ((creation-date . "2010-03-04") (timestamp . "2010-03-04"))] + "Smith") + + +(bbdb-vcard-import-test + " +** vCard version 2.1 +*** Quoted-printable +------------------------------------------------------------ +BEGIN:VCARD +VERSION:2.1 +N:Doe;John;;; +FN:John Doe +ORG:Doe Company, The; +TITLE: President +NOTE;ENCODING=QUOTED-PRINTABLE: This is a note associated + with this contact=0D=0A +TEL;WORK;VOICE:(987) 123-4567 +TEL;HOME;VOICE:(987) 765-4321 +TEL;CELL;VOICE:(987) 135-8642 +TEL;WORK;FAX:(987) 246-1357 +ADR;WORK:;;1234 North Street;Anytown;TX 751234;;United States + of America +LABEL;WORK;ENCODING=QUOTED-PRINTABLE:1234 North Street=0D=0AAnytown, + TX 751234 =0D=0AUnited States of America +URL: +URL:http://www.doeweb.com +EMAIL;PREF;INTERNET:jdoe@nowhere.com +REV:19980114T170559Z +END:VCARD +" + ["John" "Doe" + nil + "Doe Company, The +" + (["Office" "(987) 123-4567"] + ["Home" "(987) 765-4321"] + ["Mobile" "(987) 135-8642"] + ["Office" "(987) 246-1357"]) + (["Office" ("1234 North Street") "Anytown" "TX 751234" "" "United States of America"]) + ("jdoe@nowhere.com") + ((label\;type=work . "1234 North Street +Anytown, TX 751234 +United States of America") + (title . "President") + (notes . "This is a note associated with this contact +") + (www . "http://www.doeweb.com") + (creation-date . "1998-01-14T17:05:59Z") (timestamp . "2010-03-04"))] + "John Doe" + nil nil t) + + + +(bbdb-vcard-import-test + " +** A v2.1 vcard with another vcard inside; we check the outer one +------------------------------------------------------------ +BEGIN:VCARD +VERSION:2.1 +N:Outerlast2A; Outerfirst2A +FN:Outerfirst2A Outerlast2A +AGENT:BEGIN:VCARD\\nVERSION:2.1\\nN:Innerlast2A\\;Innerfirst2A\\nFN:Innerfirst2A Innerlast2A\\nTEL:+1-919-555- + 1234\\nEMAIL\\;TYPE=INTERNET:InnerA@hostA.com\\nEND:VCARD\\n +NOTE:A note +END:VCARD +" + [" Outerfirst2A" "Outerlast2A" + ("Outerfirst2A Outerlast2A") + nil + nil + nil + nil + ((agent . "BEGIN:VCARD\\ +VERSION:2.1\\ +N:Innerlast2A\\;Innerfirst2A\\ +FN:Innerfirst2A Innerlast2A\\ +TEL:+1-919-555-1234\\ +EMAIL\\;TYPE=INTERNET:InnerA@hostA.com\\ +END:VCARD\\ +") + (notes . "A note") + (creation-date . "2010-03-04") (timestamp . "2010-03-04"))] + "Outerfirst2A Outerlast2A") + + +(bbdb-vcard-import-test + " +** A v2.1 vcard with another vcard inside; we check the inner one +------------------------------------------------------------ +BEGIN:VCARD +VERSION:2.1 +N:Outerlast2A Outerfirst2A +AGENT:BEGIN:VCARD\\nVERSION:2.1\\nN:Innerlast2A\\;Innerfirst2A\\nFN:Innerfirst2A Innerlast2A\\nTEL:+1-919-555- + 1234\\nEMAIL\\;TYPE=INTERNET:InnerA@hostA.com\\nEND:VCARD\\n +NOTE:A note +END:VCARD +" + ["Innerfirst2A" "Innerlast2A" + nil + nil + (["Office" "+1-919-555-1234"]) + nil + ("InnerA@hostA.com") + ((creation-date . "2010-03-04") (timestamp . "2010-03-04"))] + "Innerfirst2A Innerlast2A") + + + +;;;; The Export/Re-Import Tests +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(bbdb "" nil) +(with-current-buffer "*BBDB*" + (bbdb-vcard-export "/tmp/test-bbdb-0.vcf" t nil)) + +(let ((first-bbdb (bbdb-search (bbdb-records) "")) + second-bbdb) + (bbdb-save-db) + (save-buffer bbdb-buffer) + (kill-buffer bbdb-buffer) + (kill-buffer "*BBDB*") + (delete-file "/tmp/test-bbdb") + (bbdb-vcard-import-file "/tmp/test-bbdb-0.vcf") + (setq second-bbdb (bbdb-search (bbdb-records) "")) + (bbdb-vcard-compare-bbdbs first-bbdb second-bbdb)) +;; FIXME: previous line messes bbdb up. --- /dev/null +++ bbdb-2.36/extern/bbdb-vcard/README @@ -0,0 +1,19 @@ +bbdb-vcard.el +============= + +bbdb-vcard.el imports and exports vCards (version 3.0) as defined in +RFC 2425 and RFC 2426 to/from The Insidious Big Brother Database +(BBDB). Version 2.1 vCards are converted into version 3.0 on import. + +On a file, a buffer or a region containing one or more vCards, use +`bbdb-vcard-import-file', `bbdb-vcard-import-buffer', or +`bbdb-vcard-import-region' respectively to import them into BBDB. + +In buffer *BBDB*, press v to export the record under point. Press * v +to export all records in buffer into one vCard file. Press * C-u v to +export them into one file each. + +To put one or all vCard(s) into the kill ring, press V or * V +respectively. + +Refer to the Commentary in file bbdb-vcard.el for further information. --- bbdb-2.36.orig/texinfo/bbdb.texinfo +++ bbdb-2.36/texinfo/bbdb.texinfo @@ -3543,6 +3543,9 @@ intended for developers to follow the ch development version. Developers of the @b{BBDB} should consider to subscribe to this list. +There is also an issue tracker associated with the @b{BBDB} +repository at @code{http://github.com/barak/BBDB}. + @node Changes, The Latest Version, Mailing Lists, Top @section Changes in this Version @@ -3601,6 +3604,8 @@ following site: WWW: @code{http://bbdb.sourceforge.net} @item FTP: @code{ftp://ftp.sourceforge.net/pub/bbdb} +@item +Git Fork: @code{http://github.com/barak/BBDB} @end itemize @noindent @@ -3612,6 +3617,8 @@ following ways: WWW: @code{http://bbdb.sourceforge.net} @item Anonymous CVS: See @code{http://bbdb.sourceforge.net} for instructions. +@item +Git Fork: @code{http://github.com/barak/BBDB} @end itemize Users of development versions of the @b{BBDB} should subscribe to the --- bbdb-2.36.orig/lisp/bbdb-gnus.el +++ bbdb-2.36/lisp/bbdb-gnus.el @@ -580,13 +580,11 @@ excellent choice." (defcustom bbdb/gnus-split-myaddr-regexp (concat "^" (user-login-name) "$\\|^" (user-login-name) "@\\([-a-z0-9]+\\.\\)*" - (or gnus-local-domain (message-make-domain) + (or (message-make-domain) (system-name) "") "$") - "*This regular expression should match your address as found in the -From header of your mail. You should make sure gnus-local-domain or -gnus-use-generic-from are set before loading this module, if they differ -from (system-name). If you send mail/news from multiple addresses, then -you'll likely have to set this yourself anyways." + "This regular expression should match your address as found in +the From header of your mail. If you send mail/news from multiple +addresses, then you'll likely have to set this yourself anyway." :group 'bbdb-mua-specific-gnus-splitting :type 'string) --- /dev/null +++ bbdb-2.36/bits/bbdb-adapt-ispell.el @@ -0,0 +1,125 @@ +;;; bbdbadapt-ispell.el --- Use the BBDB to insert a gcc field + +;; Copyright (C) 2009 Uwe Brauer + +;; Author: Uwe Brauer oub@mat.ucm.es +;; Maintainer: Uwe Brauer oub@mat.ucm.es +;; Created: 17 Mar 2009 +;; Version: 1.0 +;; Keywords: + + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 1, or (at your option) +;; any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; A copy of the GNU General Public License can be obtained from this +;; program's author (send electronic mail to oub@mat.ucm.es) or from +;; the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA +;; 02139, USA. + +;; LCD Archive Entry: +;; bbdbadpt-gcc|Uwe Brauer|oub@mat.ucm.es +;; |Use the BBDB to insert a gcc field +;; |$Date: 2009/03/17 17:27:31 $|$Revision: 1.1 $|~/packages/bbdbadpt-gcc.el + +;;; Commentary: +;; I wanted to have the ispell dict selected +;; based on a relevant bbdb entry which I call ispell-dict. +;; This is what the code does. + +;; The starting point was some code provided to me by Robert +;; Fenk. However the problem with that code was that it took the gcc +;; field from some entry of the BBDB buffer and if there was more than +;; on entry often the wrong string was inserted. So I had to use code +;; which extracted the correct BBDB entry from the TO field . I +;; succeeded by using to a large extend code from sigadapt.el written +;; by by C.Queinnec (University of Paris 6 & INRIA) +;; + +;;; Change log: +;; $Log: bbdbadapt-ispell.el,v $ +;; Revision 1.1 2009/03/17 17:27:31 oub +;; Initial revision +;; +;; Revision 1.2 2009/03/17 16:50:20 oub +;; modify the central function +;; +;; Revision 1.1 2009/03/17 16:32:26 oub +;; Initial revision +;; + +;;; Code: + +(defconst bbdbadpt-ispell-version (concat "0." (substring "$Revision: 1.1 $" 13 14)) + "$Id: bbdbadapt-ispell.el,v 1.1 2009/03/17 17:27:31 oub Exp oub $ +Report bugs to: Uwe Brauer oub@mat.ucm.es") + + + + +(defun bbdbispelladpt-search-record (to) + "Search a BBDB record associated to TO or return NIL." + (let* ((data (mail-extract-address-components to)) + (name (car data)) + (net (car (cdr data)))) + (if (equal name net) (setq name nil)) + (if (and net bbdb-canonicalize-net-hook) + (setq net (bbdb-canonicalize-address net))) + (bbdb-search-simple name net))) + +(defun bbdbispelladpt-try-bbdbispell-new () + "Try to adapt non-interactively the current bbdbispell. +This function looks silently in the current message to find how to +choose the bbdbispell. It does nothinng if not enough information is +present. This function is useful in a hook." + (save-excursion + (condition-case nil + (progn + (goto-char (point-min)) + (let ((record (bbdbispelladpt-search-record + (bbdb-extract-field-value "To")))) + (if record + (let ((signame (bbdbispelladpt-retrieve-bbdbispell record))) + (when (and (stringp signame) (string= signame "castellano8")) + (ispell-change-dictionary "castellano8" nil)) + (when (and (stringp signame) (string= signame "english")) + (ispell-change-dictionary "american" nil )) + (when (and (stringp signame) (string= signame "deutsch")) + (ispell-change-dictionary "deutsch8" nil)) + (when (and (stringp signame) (string= signame "french")) + (ispell-change-dictionary "francais" nil))))))))) + + + + +(defun bbdbispelladpt-retrieve-bbdbispell (&optional record) + "Retrieve the bbdbispell (a symbol) associated to a mailee. +The search is done through a BBDB record. " + (if (not record) + (save-excursion + (goto-char (point-min)) + (let* ((to (bbdb-extract-field-value "To")) + (rec (bbdbispelladpt-search-record to)) ) + (if rec (bbdbispelladpt-do-retrieve-bbdbispell rec) + (progn (message "No bound record") + nil)))) + (bbdbispelladpt-do-retrieve-bbdbispell record) ) ) + +(defun bbdbispelladpt-do-retrieve-bbdbispell (record) + (let ((signame + (bbdb-record-getprop record 'ispell-dict))) + (if (stringp signame) + (setq signame signame)) + signame)) + + +(provide 'bbdbadapt-ispell) + +;;; BBDBADPT-ISPELL.EL ends here debian/compat0000664000000000000000000000000212056121453010365 0ustar 8 debian/bbdb-cid.10000664000000000000000000000316012056121450010674 0ustar .\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH BBDB-CID.PL 1 "March 31, 2002" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: .\" .nh disable hyphenation .\" .hy enable hyphenation .\" .ad l left justify .\" .ad b justify to both left and right margins .\" .nf disable filling .\" .fi enable filling .\" .br insert line break .\" .sp insert n+1 empty lines .\" for manpage-specific macros, see man(7) .SH NAME bbdb-cid \- Caller-ID-logger .SH SYNOPSIS .B bbdb-cid .SH DESCRIPTION Opens the modem and waits for it to print caller-ID data. When it does, it logs it to a file, parses it, and pops up a window using "xmessage". If the number is present in your .bbdb file, it shows the name (or company) associated with it. .IR "You have to edit the Skript and change it to fit into your System!" This manual page was written for the Debian distribution because the original program does not have a manual page. Instead, it has documentation in the GNU Info format; see below. .SH SEE ALSO .BR bbdb-areacode-split (1), .BR bbdb-unlazy-lock (1). .BR bbdb-srv (1). .br The bbdb is fully documented by .IR "The insidious Big Brother Database for mail and news" , available via the Infonode .BR bbdb . .SH AUTHOR This manual page was written by Joerg Jaspert (JJ) , for the Debian GNU/Linux system (but may be used by others). debian/bbdb.emacsen-install0000775000000000000000000000732612056122014013066 0ustar #!/bin/sh # /usr/lib/emacsen-common/packages/install/bbdb FLAVOR=$1 PACKAGE="bbdb" if [ "X${FLAVOR}" = "X" ]; then echo Need argument to determine FLAVOR of emacs; exit 1 fi if [ "X${PACKAGE}" = "X" ]; then echo Internal error: need package name; exit 1; fi ELDIR=/usr/share/emacs/site-lisp/${PACKAGE} ELCDIR=/usr/share/${FLAVOR}/site-lisp/${PACKAGE} COMPILE="-q -batch -f batch-byte-compile" case "${FLAVOR}" in emacs) echo "install/${PACKAGE}: Ignoring Flavor ${FLAVOR} ..." ;; *) echo "install/${PACKAGE}: Byte-compiling for ${FLAVOR} ..." rm -rf ${ELCDIR} cd ${ELDIR} TARGETS="rmail mhe gnus bbdb" if [ -d /usr/share/${FLAVOR}/site-lisp/vm ]; then TARGETS="$TARGETS vm" elif [ ${FLAVOR} = xemacs20 -o ${FLAVOR} = xemacs21 ]; then TARGETS="$TARGETS vm" fi if [ ${FLAVOR} = emacs19 -o ${FLAVOR} = mule2 ]; then MHEDIR=/usr/share/${FLAVOR}/site-lisp/../lisp elif [ ${FLAVOR} = xemacs20 -o ${FLAVOR} = xemacs21 ]; then MHEDIR=/usr/share/${FLAVOR}/site-lisp/../lisp/mh-e else # emacs20 MHEDIR=/usr/share/${FLAVOR}/site-lisp/../lisp/mail fi ## for Gnus if [ -d /usr/share/${FLAVOR}/site-lisp/gnus ]; then GNUSDIR=/usr/share/${FLAVOR}/site-lisp/gnus elif [ -d /usr/share/${FLAVOR}/site-lisp/semi-gnus ]; then GNUSDIR=/usr/share/${FLAVOR}/site-lisp/semi-gnus elif [ -d /usr/share/${FLAVOR}/site-lisp/t-gnus ]; then GNUSDIR=/usr/share/${FLAVOR}/site-lisp/t-gnus elif [ -d /usr/share/${FLAVOR}/site-lisp/chaos ]; then GNUSDIR=/usr/share/${FLAVOR}/site-lisp/chaos fi if [ -z ${GNUSDIR} ]; then if [ ${FLAVOR} = emacs19 -o ${FLAVOR} = mule2 ]; then GNUSDIR=/usr/share/emacs/19.34/lisp elif [ ${FLAVOR} = xemacs20 ]; then GNUSDIR=/usr/lib/xemacs-20.4/lisp/gnus elif [ ${FLAVOR} = xemacs21 ]; then GNUSDIR=/usr/share/xemacs21/packages/lisp/gnus else GNUSDIR=/usr/share/${FLAVOR}/site-lisp/../lisp/gnus fi fi LOG=`tempfile` rm -rf ${ELCDIR} && cp -a ${ELDIR} ${ELCDIR} # at ELCDIR ( cd ${ELCDIR} # Prevent epg from manipulating /root/.gnupg (#694417) TMPGNUPGHOME=`mktemp -d --tmpdir gnupg.XXXXXXXXXX` export GNUPGHOME=${TMPGNUPGHOME} echo "Generating bbdb-autoloads..." echo "Generating bbdb-autoloads" >> $LOG make autoloads >> $LOG 2>&1 if [ $FLAVOR != xemacs20 -a $FLAVOR != xemacs21 ]; then echo "(provide 'bbdb-autoloads)" >> lisp/bbdb-autoloads.el fi echo "Byte-compiling bbdb..." make $TARGETS EMACS_PROG=${FLAVOR} \ VMDIR=/usr/share/${FLAVOR}/site-lisp/vm \ GNUSDIR=${GNUSDIR} \ MHEDIR=${MHEDIR} >> $LOG 2>&1 mv lisp/*.elc utils/*.el . rm -rf tex utils lisp Makefile ${TMPGNUPGHOME} ${FLAVOR} ${COMPILE} *.el >> $LOG 2>&1 ) cat > ${ELCDIR}/load-path.el <> $LOG echo "install -m 644 ${ELDIR}/lisp/bbdb-gnus.el ${ELCDIR}/" >> $LOG install -m 644 ${ELDIR}/lisp/bbdb-gnus.el ${ELCDIR}/ fi # a hack to fix #179821, #210248, #233904 # If bbdb is installed before vm, then bbdb does not have bbdb-vm compiled.... install -m 644 ${ELDIR}/lisp/bbdb-vm.el ${ELCDIR}/ # make -k clean >> $LOG mv $LOG ${ELCDIR}/CompilationLog gzip -9 ${ELCDIR}/CompilationLog chmod 644 ${ELCDIR}/CompilationLog.gz # make symlinks for source files that were not copied over to ELCDIR # this makes find-function and find-library work properly cd ${ELDIR}/lisp for f in *.el; do if [ -e ${ELCDIR}/${f}c ] && [ ! -e ${ELCDIR}/${f} ]; then ln -sf ${ELDIR}/lisp/${f} ${ELCDIR}/${f} fi done echo " done." ;; esac debian/bbdb.docs0000664000000000000000000000003512056121450010725 0ustar bits.tar.gz texinfo/bbdb.pdf debian/bbdb-pilot-jwz.el0000664000000000000000000005276012056121446012353 0ustar ;;; bbdb-pilot-jwz.el --- bbdb to palmos address book conduit ;; Copyright (C) 1999 Jamie Zawinski , all rights reserved. ;; Maintainer: Noah Friedman ;; Created: 2000-01-21 ;; $Id: bbdb-pilot-jwz.el,v 1.8 2001/06/19 03:45:37 friedman Exp $ ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with this program; if not, you can either send email to this ;; program's maintainer or write to: The Free Software Foundation, ;; Inc.; 59 Temple Place, Suite 330; Boston, MA 02111-1307, USA. ;;; Commentary: ;; pilot-addresses expects a file with the following 19 fields: ;; ;; Last Name ;; First Name ;; Title ;; Company ;; Named Field 1 (default: Work) ;; Named Field 2 (default: Home) ;; Named Field 3 (default: Fax) ;; Named Field 4 (default: Other) ;; Named Field 5 (default: E-mail) ;; Address ;; City ;; State ;; Zip ;; Country ;; Custom 1 ;; Custom 2 ;; Custom 3 ;; Custom 4 ;; Note ;; ;; The "named fields" are the ones that have a field title that can be set ;; with a popup menu. The available titles are: ;; ;; Work ;; Home ;; Fax ;; Other ;; E-mail ;; Main ;; Pager ;; Mobile ;; ;; A record in the file consists of 19 fields followed by a newline. ;; Field values are enclosed in double-quotes and are separated by commas. ;; The "named" fields may also be preceeded by the field name and a ;; semicolon, e.g.: ;; "Home";"(415) 555-1212", ;; ;; Strings may contain newlines, and are read with backslash-decoding ;; (for \n, \t and so on.) ;; ;; Embedded quotes are double-quoted in csv output, e.g. " -> "" ;;; Code: (require 'bbdb) (require 'cl) (defconst bbdb-pilot-field-names '["Work" "Home" "Fax" "Other" "E-mail" "Main" "Pager" "Mobile"]) ;; `title' is in this list since, if present, it is handled specially and ;; we do not want to duplicate it in the notes section of each entry. ;; But it's still a user-defined "notes" field as far as bbdb is concerned. (defconst bbdb-pilot-ignored-notes '(mail-name mail-alias face mark-char title creation-date timestamp)) (bbdb-defstruct bbdb-pilot- lastname ; 1 firstname ; 2 title ; 3 company ; 4 name-1 value-1 ; 5 name-2 value-2 ; 6 name-3 value-3 ; 7 name-4 value-4 ; 8 name-5 value-5 ; 9 address ; 10 city ; 11 state ; 12 zip ; 13 country ; 14 custom-1 ; 15 custom-2 ; 16 custom-3 ; 17 custom-4 ; 18 note ; 19 ) (defun bbdb-pilot-format (pilot) "Inserts a `pilot-addresses'-compatible description of the `pilot' struct into the current buffer." (let ((print-escape-newlines nil) (print-escape-nonascii nil) (standard-output (current-buffer))) (save-restriction (narrow-to-region (point) (point)) (prin1 (or (bbdb-pilot-lastname pilot) "")) (insert ",") (prin1 (or (bbdb-pilot-firstname pilot) "")) (insert ",") (prin1 (or (bbdb-pilot-title pilot) "")) (insert ",") (prin1 (or (bbdb-pilot-company pilot) "")) (insert ",") (prin1 (or (bbdb-pilot-name-1 pilot) "Other")) (insert ";") (prin1 (or (bbdb-pilot-value-1 pilot) "")) (insert ",") (prin1 (or (bbdb-pilot-name-2 pilot) "Other")) (insert ";") (prin1 (or (bbdb-pilot-value-2 pilot) "")) (insert ",") (prin1 (or (bbdb-pilot-name-3 pilot) "Other")) (insert ";") (prin1 (or (bbdb-pilot-value-3 pilot) "")) (insert ",") (prin1 (or (bbdb-pilot-name-4 pilot) "Other")) (insert ";") (prin1 (or (bbdb-pilot-value-4 pilot) "")) (insert ",") (prin1 (or (bbdb-pilot-name-5 pilot) "Other")) (insert ";") (prin1 (or (bbdb-pilot-value-5 pilot) "")) (insert ",") (prin1 (or (bbdb-pilot-address pilot) "")) (insert ",") (prin1 (or (bbdb-pilot-city pilot) "")) (insert ",") (prin1 (or (bbdb-pilot-state pilot) "")) (insert ",") (prin1 (or (bbdb-pilot-zip pilot) "")) (insert ",") (prin1 (or (bbdb-pilot-country pilot) "")) (insert ",") (prin1 (or (bbdb-pilot-custom-1 pilot) "")) (insert ",") (prin1 (or (bbdb-pilot-custom-2 pilot) "")) (insert ",") (prin1 (or (bbdb-pilot-custom-3 pilot) "")) (insert ",") (prin1 (or (bbdb-pilot-custom-4 pilot) "")) (insert ",") (prin1 (or (bbdb-pilot-note pilot) "")) (insert "\n") ;; Replace escaped double quotes (\") with "". (goto-char (point-min)) (while (re-search-forward "\\\\\"" nil t) (replace-match "\"\"" nil t)) (goto-char (point-max)))) nil) (defun bbdb-pilot-pretty-print (pilot) ;; for debugging (let ((i 0) (names '["lastname" "firstname" "title" "company" "name-1" "value-1" "name-2" "value-2" "name-3" "value-3" "name-4" "value-4" "name-5" "value-5" "address" "city" "state" "zip" "country" "custom-1" "custom-2" "custom-3" "custom-4" "note"])) (while (< i bbdb-pilot-length) (insert (format "%12s: " (aref names i))) (let ((s (aref pilot i)) (print-escape-newlines t)) (if (null s) (setq s "")) (insert (format "%S\n" s))) (setq i (1+ i)))) nil) (defun bbdb-record-to-pilot-record (record) "Converts a BBDB record to a Pilot record." (let ((pilot (make-vector bbdb-pilot-length nil)) (phones (bbdb-record-phones record)) (notes (bbdb-record-raw-notes record))) (if (stringp notes) (setq notes (list (cons 'notes notes))) ;; may be destructively modified later (setq notes (copy-alist notes))) (if (bbdb-record-aka record) (setq notes (append notes (list (cons 'AKA (mapconcat 'identity (bbdb-record-aka record) ",\n")))))) ;; These fields are easy... ;; (bbdb-pilot-set-lastname pilot (bbdb-record-lastname record)) (bbdb-pilot-set-firstname pilot (bbdb-record-firstname record)) (bbdb-pilot-set-title pilot (bbdb-record-getprop record 'title)) (bbdb-pilot-set-company pilot (bbdb-record-company record)) ;; Now do the phone numbers... ;; (let ((pilot-phones '())) (while phones (let ((loc (bbdb-phone-location (car phones))) (num (bbdb-phone-string (car phones))) field) (cond ((string-match "\\b\\(work\\|office\\)" loc) (setq field "Work")) ((string-match "\\b\\(home\\)" loc) (setq field "Home")) ((string-match "\\b\\(fax\\|facs?imile\\)" loc) (setq field "Fax")) ((string-match "\\b\\(pager?\\|beeper\\)" loc) (setq field "Pager")) ((string-match "\\b\\(cell\\|mobile\\)" loc) (setq field "Mobile")) ((string-match "\\b\\(voice\\|main\\|phone\\)\\b" loc) (setq field "Main")) (t ;; If we don't recognise the phone label, then call it ;; "Other" but preserve the original label in the field ;; itself. (setq field "Other" num (concat loc ": " num)))) ;; If this phone number is the same type as one previously seen ;; (e.g. there are two pager numbers), append with a newline to ;; the existing entry. This makes it possible to group multiple ;; numbers in the same pilot field and make room for more numbers ;; of different loc types. (let ((seen (assoc field pilot-phones))) (if seen (setcdr seen (concat (cdr seen) "\n" num)) (setq pilot-phones (cons (cons field num) pilot-phones)))) (setq phones (cdr phones)))) (setq pilot-phones (nreverse pilot-phones)) ;; The email field goes last in the list of phone fields (if (bbdb-record-net record) (let ((c (cons "E-mail" (car (bbdb-record-net record))))) (setq pilot-phones (nconc pilot-phones (list c))))) (if (cdr (bbdb-record-net record)) (setq notes (cons (cons 'other-email (mapconcat 'identity (cdr (bbdb-record-net record)) ",\n")) notes))) (let (pp) (setq pp (pop pilot-phones)) (bbdb-pilot-set-name-1 pilot (car pp)) (bbdb-pilot-set-value-1 pilot (cdr pp)) (setq pp (pop pilot-phones)) (bbdb-pilot-set-name-2 pilot (car pp)) (bbdb-pilot-set-value-2 pilot (cdr pp)) (setq pp (pop pilot-phones)) (bbdb-pilot-set-name-3 pilot (car pp)) (bbdb-pilot-set-value-3 pilot (cdr pp)) ;; We've filled in three phone-number fields. ;; If there are more than 2 phone numbers left (not counting the ;; email field), put remaining numbers in 4th field (with their ;; headings) and put the email address in the 5th field. (cond ((< (length pilot-phones) 3) (setq pp (pop pilot-phones)) (bbdb-pilot-set-name-4 pilot (car pp)) (bbdb-pilot-set-value-4 pilot (cdr pp)) (setq pp (pop pilot-phones)) (bbdb-pilot-set-name-5 pilot (car pp)) (bbdb-pilot-set-value-5 pilot (cdr pp))) (t (let* ((email (assoc "E-mail" pilot-phones)) (val (mapconcat #'(lambda (pp) (let ((p 0) s) ;; If there are newlines in the data, make sure ;; each new line begins with the field name ;; since this record is heterogenous. (while (string-match "\n" (cdr pp) p) (setq s (concat "\n" (car pp) ": ")) (setq p (+ (match-end 0) (length s))) (setcdr pp (replace-match s t t (cdr pp))))) (concat (car pp) ": " (cdr pp))) (delq email pilot-phones) "\n"))) (bbdb-pilot-set-name-4 pilot "Other") (bbdb-pilot-set-value-4 pilot val) (bbdb-pilot-set-name-5 pilot (car email)) (bbdb-pilot-set-value-5 pilot (cdr email))))))) ;; Now do the addresses... ;; Put the first address in the address field, and the others ;; in the "custom" fields. ;; (let* ((addrs (bbdb-record-addresses record)) (addr1 (pop addrs))) (cond (addr1 (let (st) (cond ((>= bbdb-file-format 6) (setq st (bbdb-join (bbdb-address-streets addr1) "\n"))) (t (setq st (bbdb-address-street1 addr1)) (if (> (length (bbdb-address-street2 addr1)) 0) (setq st (concat st "\n" (bbdb-address-street2 addr1)))) (if (> (length (bbdb-address-street3 addr1)) 0) (setq st (concat st "\n" (bbdb-address-street3 addr1)))))) (setq st (concat (bbdb-address-location addr1) ":\n" st)) (bbdb-pilot-set-address pilot st) (bbdb-pilot-set-city pilot (bbdb-address-city addr1)) (bbdb-pilot-set-state pilot (bbdb-address-state addr1)) (bbdb-pilot-set-zip pilot (bbdb-address-zip-string addr1)) (bbdb-pilot-set-country pilot nil)))) (cond (addrs (let ((indent-tabs-mode nil) (formatted '()) addr c s) (while addrs (setq addr (car addrs)) (save-excursion (set-buffer (get-buffer-create "*bbdb-tmp*")) (erase-buffer) (insert (bbdb-address-location addr) ":\n") (cond ((>= bbdb-file-format 6) (let ((sts (bbdb-address-streets addr))) (while sts (indent-to 8) (insert (car sts) "\n") (setq sts (cdr sts))))) (t (if (= 0 (length (setq s (bbdb-address-street1 addr)))) nil (indent-to 8) (insert s "\n")) (if (= 0 (length (setq s (bbdb-address-street2 addr)))) nil (indent-to 8) (insert s "\n")) (if (= 0 (length (setq s (bbdb-address-street3 addr)))) nil (indent-to 8) (insert s "\n")))) (indent-to 8) (insert (setq c (bbdb-address-city addr))) (setq s (bbdb-address-state addr)) (if (and (> (length c) 0) (> (length s) 0)) (insert ", ")) (insert s " ") (insert (bbdb-address-zip-string addr)) (setq formatted (cons (buffer-string) formatted)) (setq addrs (cdr addrs)))) (setq formatted (nreverse formatted)) (bbdb-pilot-set-custom-1 pilot (pop formatted)) (bbdb-pilot-set-custom-2 pilot (pop formatted)) (bbdb-pilot-set-custom-3 pilot (pop formatted)) (if (null (cdr formatted)) (bbdb-pilot-set-custom-4 pilot (pop formatted)) (bbdb-pilot-set-custom-4 pilot (mapconcat 'identity formatted "\n")))))) ) ;; Now handle the notes... ;; (let ((losers bbdb-pilot-ignored-notes)) (while losers (let ((c (assq (car losers) notes))) (if c (setq notes (delete c notes)))) (setq losers (cdr losers)))) (bbdb-pilot-set-note pilot (mapconcat #'(lambda (cons) (save-excursion (set-buffer (get-buffer-create "*bbdb-tmp*")) (erase-buffer) (insert (format "%s:\n%s" (car cons) (cdr cons))) (goto-char (point-min)) (while (search-forward "\n" nil t) (replace-match "\n " t t)) (goto-char (point-max)) (skip-chars-backward "\n\t ") (buffer-substring (point-min) (point)))) notes "\n\n")) pilot)) (defun bbdb-pilot-make-phone (location phone-string) (let* ((num (make-vector (if bbdb-north-american-phone-numbers-p bbdb-phone-length 2) nil)) (p (bbdb-parse-phone-number phone-string))) (bbdb-phone-set-location num location) (bbdb-phone-set-area num (nth 0 p)) ; euronumbers too. (if (= (length num) 2) nil (bbdb-phone-set-exchange num (nth 1 p)) (bbdb-phone-set-suffix num (nth 2 p)) (bbdb-phone-set-extension num (or (nth 3 p) 0))) num)) (defun pilot-record-to-bbdb-record (pilot) "Converts a Pilot record to a BBDB record." (let ((firstname (bbdb-pilot-firstname pilot)) (lastname (bbdb-pilot-lastname pilot)) (company (bbdb-pilot-company pilot)) (title (bbdb-pilot-title pilot)) ; #### ;; #### AKA (net nil) (addrs '()) (phones '()) (pphones '()) (notes '()) ) (if (equal company "") (setq company nil)) (if (equal title "") (setq title nil)) (if (equal notes "") (setq notes nil)) ;; Process the phone numbers and primary net address... ;; (setq pphones (list (cons (bbdb-pilot-name-1 pilot) (bbdb-pilot-value-1 pilot)) (cons (bbdb-pilot-name-2 pilot) (bbdb-pilot-value-2 pilot)) (cons (bbdb-pilot-name-3 pilot) (bbdb-pilot-value-3 pilot)) (cons (bbdb-pilot-name-4 pilot) (bbdb-pilot-value-4 pilot)) (cons (bbdb-pilot-name-5 pilot) (bbdb-pilot-value-5 pilot)))) (while pphones (cond ((equal (car (car pphones)) "E-mail") (setq net (list (cdr (car pphones))))) ((and (equal (car (car pphones)) "Other") (string-match "^\\([^ \t\n:]+\\):[ \t]*" (cdr (car pphones)))) (let ((a (substring (cdr (car pphones)) (match-beginning 1) (match-end 1))) (b (substring (cdr (car pphones)) (match-end 0)))) (setq phones (cons (bbdb-pilot-make-phone a b) phones)))) ((> (length (cdr (car pphones))) 0) (setq phones (cons (bbdb-pilot-make-phone (car (car pphones)) (cdr (car pphones))) phones)))) (setq pphones (cdr pphones))) (setq phones (nreverse phones)) ;; Now parse the primary address... ;; (cond ((> (length (bbdb-pilot-address pilot)) 0) (let ((addr (make-vector bbdb-address-length nil)) loc sts st1 st2 st3 (street (bbdb-pilot-address pilot)) (cty (bbdb-pilot-city pilot)) (ste (bbdb-pilot-state pilot)) (zip (bbdb-pilot-zip pilot)) ) (if (equal cty "") (setq cty nil)) (if (equal ste "") (setq ste nil)) (if (equal zip "") (setq zip nil)) (if zip (setq zip (bbdb-parse-zip-string zip))) (if (string-match "^\\([^ \t\n:]+\\):[ \t\n]*" street) (setq loc (substring street 0 (match-end 1)) street (substring street (match-end 0)))) (bbdb-address-set-location addr loc) (cond ((>= bbdb-file-format 6) (while (string-match "^\\([^\n]+\\)\\(\n\\|$\\)" street) (setq sts (append sts (list (substring street 0 (match-end 1)))) street (substring street (match-end 0)))) (bbdb-address-set-streets addr sts)) (t (if (string-match "^\\([^\n]+\\)\\(\n\\|$\\)" street) (setq st1 (substring street 0 (match-end 1)) street (substring street (match-end 0)))) (if (string-match "^\\([^\n]+\\)\\(\n\\|$\\)" street) (setq st2 (substring street 0 (match-end 1)) street (substring street (match-end 0)))) (if (string-match "^\\([^\n]+\\)\\(\n\\|$\\)" street) (setq st3 (substring street 0 (match-end 1)) street (substring street (match-end 0)))) (bbdb-address-set-street1 addr (or st1 "")) (bbdb-address-set-street2 addr (or st2 "")) (bbdb-address-set-street3 addr (or st3 "")))) (bbdb-address-set-city addr (or cty "")) (bbdb-address-set-state addr (or ste "")) (bbdb-address-set-zip addr zip) (setq addrs (list addr)) ))) ;; Now parse the secondary addresses... ;; (let ((paddrs (list (bbdb-pilot-custom-1 pilot) (bbdb-pilot-custom-2 pilot) (bbdb-pilot-custom-3 pilot) (bbdb-pilot-custom-4 pilot)))) (while paddrs (cond ((car paddrs) ;; #### parse text to address. fmh. )) (setq paddrs (cdr paddrs)))) ;; Now parse the notes field. ;; ;; #### (let ((record (vector firstname lastname nil company phones addrs net notes (make-vector bbdb-cache-length nil)))) record))) ;;;###autoload (defun bbdb-to-pilot-file (filename &optional records) (interactive "FWrite pilot-addresses file: ") (or records (setq records (bbdb-records))) (save-excursion (set-buffer (find-file-noselect filename)) (erase-buffer) (let ((len (length records)) (i 0)) (while records (message "%d%%..." (/ (* 100 i) len)) (bbdb-pilot-format (bbdb-record-to-pilot-record (car records))) (setq records (cdr records) i (1+ i)))) (save-buffer) (kill-buffer (current-buffer))) filename) (defun bbdb-to-pilot () "Push the current contents of BBDB out to the Pilot." ; (interactive) (bbdb-records) ; load bbdb (message "Selecting records...") (let ((records (remove-if-not #'(lambda (record) (and (or (bbdb-record-name record) (bbdb-record-company record)) (let ((phones-p nil) (phones (bbdb-record-phones record))) (while phones (let ((loc (bbdb-phone-location (car phones)))) (if (and (not (string-match "cid" loc)) (not (string-match "[?]" loc))) (setq phones-p t))) (setq phones (cdr phones))) phones-p))) (bbdb-records))) (file (format "/tmp/pilot-bbdb-%s-%d-%s" (user-login-name) (emacs-pid) (float-time)))) (bbdb-to-pilot-file file records) (shell-command (concat "pilot-addresses -p /dev/pilot " "-d BBDB -c BBDB -r " file ;;"; rm " file " &")) )) (provide 'bbdb-pilot-jwz) ;;; bbdb-pilot-jwz.el ends here