[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[commit-womb] addressbook COPYING ChangeLog Makefile README a...
From: |
Jose E. Marchesi |
Subject: |
[commit-womb] addressbook COPYING ChangeLog Makefile README a... |
Date: |
Thu, 23 Aug 2007 20:20:54 +0000 |
CVSROOT: /cvsroot/womb
Module name: addressbook
Changes by: Jose E. Marchesi <jemarch> 07/08/23 20:20:54
Removed files:
. : COPYING ChangeLog Makefile README
addressbook.el addressbook.texi uuid.el
vcard.el
Log message:
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/addressbook/COPYING?cvsroot=womb&r1=1.1&r2=0
http://cvs.savannah.gnu.org/viewcvs/addressbook/ChangeLog?cvsroot=womb&r1=1.29&r2=0
http://cvs.savannah.gnu.org/viewcvs/addressbook/Makefile?cvsroot=womb&r1=1.3&r2=0
http://cvs.savannah.gnu.org/viewcvs/addressbook/README?cvsroot=womb&r1=1.2&r2=0
http://cvs.savannah.gnu.org/viewcvs/addressbook/addressbook.el?cvsroot=womb&r1=1.31&r2=0
http://cvs.savannah.gnu.org/viewcvs/addressbook/addressbook.texi?cvsroot=womb&r1=1.1.1.1&r2=0
http://cvs.savannah.gnu.org/viewcvs/addressbook/uuid.el?cvsroot=womb&r1=1.1&r2=0
http://cvs.savannah.gnu.org/viewcvs/addressbook/vcard.el?cvsroot=womb&r1=1.3&r2=0
Patches:
Index: COPYING
===================================================================
RCS file: COPYING
diff -N COPYING
--- COPYING 31 May 2007 14:07:36 -0000 1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- 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 of the License, 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, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
Index: ChangeLog
===================================================================
RCS file: ChangeLog
diff -N ChangeLog
--- ChangeLog 31 May 2007 14:06:50 -0000 1.29
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,186 +0,0 @@
-2007-05-31 Jose E. Marchesi <address@hidden>
-
- * vcard.el: FSF address updated in copyright notice.
-
- * COPYING: New file.
-
-2007-05-30 Jose E. Marchesi <address@hidden>
-
- * uuid.el: New file.
- (uuid): New group.
- (uuid-ifconfig-program): New custom.
- (uuid-hexoctect-regexp): New variable.
- (uuid-time-low-regexp): New variable.
- (uuid-time-mid-regexp): New variable.
- (uuid-version-and-time-high-regexp): New variable.
- (uuid-variant-and-clock-seqhigh-regexp): New variable.
- (uuid-clock-seq-low-regexp): New variable.
- (uuid-node-regexp): New variable.
- (uuid-regexp): New variable.
- (uuid-time-based-version-hex): New variable.
- (uuid-dce-security-version-hex): New variable.
- (uuid-name-based-md5-version-hex): New variable.
- (uuid-name-based-sha1-version-hex): New variable.
- (uuid-random-number-based-version-hex): New variable.
- (uuid-namespace-dns): New variable.
- (uuid-namespace-url): New variable.
- (uuid-namespace-oid): New variable.
- (uuid-namespace-x500): New variable.
- (uuid-generate): New function.
- (uuid-generate-name-based): New function.
- (uuid-generate-random-based): New function.
- (uuid-generate-time-based): New function.
- (uuid-generate-time): New function.
- (uuid-generate-clock-sequence): New function.
- (uuid-format-mac-address): New function.
- (uuid-get-mac-address): New function.
- (uuid-namespace-to-string): New function.
- (uuidp): New function.
- (uuid-lessp): New function.
- (uuid-equal): New function.
-
-2007-05-27 Xavier Maillard <address@hidden>
-
- * addressbook.el (addrbook-summary-mode): Bind <up> and <down> to
- respectively previous and next contact. Bind 'a' to contact creation.
-
-2007-05-15 Jose E. Marchesi <address@hidden>
-
- * addressbook.el (addrbook-backend): New customize.
- (addrbook-directory): New customize.
- (addrbook-be-read-cards): New function.
- (addrbook-be-write-card): New function.
- (addrbook-be-delete-card): New function.
-
-2007-05-10 Xavier Maillard <address@hidden>
-
- * addressbook.el (addrbook-contact-display-attribute-photo-logo):
- Introduce url package again so that we can fetch local or remote
- image. Only require url when we are sure we need it and use
- string-as-unibyte to get data.
- (addrbook): Added :link property
-
-2007-05-09 Jose E. Marchesi <address@hidden>
-
- * addressbook.el: outline-mode like headlines
-
-2007-05-08 Xavier Maillard <address@hidden>
-
- * vcard.el (vcard-parse-file): New helper function used in
addrbook-import-vcard.
-
- * addressbook.el (addrbook-bury): New function.
- (addrbook-summary-mode, addrbook-contact-mode): Bind b key to
- addrbook-bury.
- (addrbook-write-data-1): New function. Take one VCARD and write
- its data in a FILE.
- (addrbook-import-vcard, addrbook-export-vcard): New functions. Use
- it. Import and Export VCARDs from addrbook-summary buffer.
- (addrbook-summary-mode): Bind i and x to import/export.
- (addrbook-contact-display-attribute-photo-logo): Dropped misuse of
- the url package and replace it with simpler functions. No longer
- require url package.
-
- * Makefile: Completely rewritten to follow standards. Added
- several new target to build and to install the manual.
- Added license header and CVS tag.
-
-2007-05-08 Jose E. Marchesi <address@hidden>
-
- * addressbook.el (addrbook-summary-display): expand line to
- frame-width. Do not fill with blanks. Append a extra newline to
- the buffer in order to let the line highlight overlay trick to
- work in the last entry.
- (addrbook-summary-goto-contact): Make the contact buffer writable
- before card displaying. Trick to expand the overlay to the entire
- line without filling with blanks.
- (addrbook-summary): Remove call to `addrbook-open'.
- (addrbook-summary-show-contact): Make the contact buffer read only.
- (addrbook-contact-delete-attribute): renamed from
- `addrbook-contact-delete-attribute-type'
- (addrbook-contact-mode): Use `addrbook-contact-delete-attribute'.
- (addressbook): Show summary when the buffer exists.
- (addrbook-multiple-frames-p): New custom variable.
- (addrbook-show-contact): Take care about `addrbook-multiple-frames-p'.
- (addrbook-show-summary): idem.
- (addrbook-ask-for-search): Changed default to nil.
-
-2007-05-07 Xavier Maillard <address@hidden>
-
- * Makefile: New file.
-
-2007-05-07 Jose E. Marchesi <address@hidden>
-
- * addressbook.el (addrbook-summary-mode): Added mailer function to
- the summary.
- Sources reestructured.
- (addrbook-summary-display): renamed from `addrbook-summary-redisplay'
- (addrbook-quit): Fixed.
- (addrbook-get-prop-index): New function.
-
-2007-05-06 Jose E. Marchesi <address@hidden>
-
- * addressbook.el: `addrbook-custom-properties' removed.
- (addrbook-build-custom-property-group): New function.
- (addrbook-set-custom-properties): New function.
- (addrbook-set-custom-properties): Added doc string.
- (addrbook-ask-for-search): New customizable variable.
- (addrbook-attr-matches-p): New function.
- (addrbook-search-cards): New function.
- (addressbook-summary): Made non-interactive.
- (addrbook-summary-get-current-card): New function.
- (addrbook-summary-next-card): New function.
- (addrbook-summary-previous-card): New function.
- (addrbook-contact): New function.
-
-2007-05-05 Xavier Maillard <address@hidden>
-
- * addressbook.el: Do not require 'cl at run-time.
- (addrbook-mode-line-string, addrbook-summary-mode-line-string):
- New variables. Use them in *-set-mode-line (still needs attention).
- (addressbook-summary): Fixed autoload cookie.
-
-2007-05-05 Jose E. Marchesi <address@hidden>
-
- * addressbook.el (addrbook-open): New function.
- (addressbook): Use `addrbook-open'.
-
- * README: Added urls to web resources
-
- * addressbook.el (addrbook-get-prop-fields): use
- `addrbook-get-prop-fields'
- (addrbook-get-prop-parameters): simplified
- (addrbook-property-in-group-p): simplified
- (addrbook-get-prop-default-type): simplified
- (addrbook-value-empty-p): simplified
- (addrbook-number-of-values): simplified
- (addrbook-get-card-fn): simplified
- (addrbook-attribute-nodisplay): simplified
- (addrbook-display-attribute-photo-logo): simplified
- (addrbook-display-attribute-type): simplified
- (addrbook-group-hidden-p): simplified
- (addrbook-hide-show-group): simplified
- (addrbook-get-current-group): simplified
- (addrbook-get-text-property-line): simplified
- (addrbook-redisplay-group): simplified
- (addrbook-group-in-display-p): simplified
- (addrbook-read-cards): simplified
- (addrbook-add-attribute-type): simplified
- (addrbook-remove-attribute-type): simplified
- (addrbook-delete-card): simplified
- (addrbook-add-attribute): simplified
- (addrbook-next-card): simplified
- (addrbook-previous-card): simplified
- (addrbook-quit): simplified
- (addrbook-goto-next-group): simplified
- (addrbook-toggle-hide-show-group): simplified
- (addrbook-hide-all-groups): simplified
- (addrbook-show-all-groups): simplified
- (addrbook-cycle-groups): simplified
- (addrbook-fast-selection): simplified
- (addrbook-select-group): simplified
- (addrbook-select-property): simplified
- (addrbook-select-field): simplified
- (addressbook): simplified
-
- * New ChangeLog
-
Index: Makefile
===================================================================
RCS file: Makefile
diff -N Makefile
--- Makefile 8 May 2007 10:05:09 -0000 1.3
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,74 +0,0 @@
-# Copyright (C) 2007 Xavier Maillard <address@hidden>
-# Jose E. Marchesi <address@hidden>
-
-# This file is NOT part of GNU Emacs.
-
-# GNU Emacs 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.
-
-# GNU Emacs 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 Street, Fifth Floor,
-# Boston, MA 02110-1301, USA.
-
-# $Id: Makefile,v 1.3 2007/05/08 10:05:09 zeDek Exp $
-
-# make install
-# make all
-# make clean
-
-EMACS = emacs
-SITEFLAG=--no-site-file
-GZIP=gzip
-
-SOURCE=$(wildcard *.el)
-TARGET=$(patsubst %.el,%.elc,$(SOURCE))
-COMPILED=$(wildcard *.elc)
-
-DESTDIR=
-PREFIX=$(DESTDIR)/usr/local
-INFODIR=$(PREFIX)/info
-MAN1DIR=$(PREFIX)/share/man/man1
-SITELISP=$(PREFIX)/share/emacs/site-lisp/addressbook
-
-INFODIR=$(PREFIX)/info
-
-INSTALLINFO = /usr/sbin/install-info --info-dir=$(INFODIR)
-
-.PHONY: all install clean
-.PRECIOUS: %.elc %.info %.html
-
-all: $(TARGET) addressbook.info
-
-install:
- test -d $(SITELISP) || mkdir -p $(SITELISP)
- [ -d $(INFODIR) ] || install -d $(INFODIR)
- install -m 644 $(SOURCE) $(SITELISP)
- install -m 644 $(COMPILED) $(SITELISP)
- install -m 0644 addressbook.info $(INFODIR)/addressbook
- $(INSTALLINFO) addressbook.info
-
-%.elc: %.el
- @echo "Byte compiling the source file "$<
- @$(EMACS) -batch -q \
- --eval '(setq load-path (cons "." load-path))' \
- -f batch-byte-compile $<
-
-%.info: %.texi
- makeinfo --no-split $<
-
-%.html: %.texi
- makeinfo --html --no-split $<
-
-remove-info:
- $(INSTALLINFO) --remove addressbook.info
-
-clean:
- -rm -f *~ $(COMPILED) addressbook.info addressbook.html
Index: README
===================================================================
RCS file: README
diff -N README
--- README 5 May 2007 02:39:54 -0000 1.2
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,19 +0,0 @@
--*- mode:text -*- Time-stamp: "07/05/05 04:32:44 jemarch"
-
-README for AddressBook
-======================
-
-AddresBook is a implementation of an addressbook for Emacs that makes
-use of the vCard standard to store contact information.
-
-The homepage of the addressbook is hosted in the Emacs Wiki:
-
- http://www.emacswiki.org/cgi-bin/wiki/AddressBook
-
-Development resources are currently hosted in the GNU Womb:
-
- http://savannah.gnu.org/projects/womb
-
-
-Send bug reports and suggestions to address@hidden
-
Index: addressbook.el
===================================================================
RCS file: addressbook.el
diff -N addressbook.el
--- addressbook.el 29 May 2007 23:11:41 -0000 1.31
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,2278 +0,0 @@
-;;;; addressbook.el --- A simple addressbook
-
-;; Copyright (C) 2007 Jose E. Marchesi
-
-;; Maintainer: Jose E. Marchesi
-;; Keywords: contacts, applications
-
-;; $Id: addressbook.el,v 1.31 2007/05/29 23:11:41 jemarch Exp $
-
-;; This file is NOT part of GNU Emacs.
-
-;; 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; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
-
-;;;; Commentary:
-
-;; A simple vCard based addressbook for Emacs
-;;
-;; File Contents
-;; =============
-;;
-;; * Constants
-;; * Customization
-;; * Variables
-;;
-;; * Properties management functions
-;;
-;; ** Groups
-;; ** Properties
-;; ** Cards
-;; ** Attributes
-;;
-;; * Addressbook contact editor
-;;
-;; ** Constants
-;; ** Variables
-;; ** Contact buffer management
-;; ** Display functions
-;; ** Modeline management
-;; ** Commands
-;; ** Major mode
-;;
-;; * Addressbook summary
-;;
-;; ** Constants
-;; ** Variables
-;; ** Summary buffer management
-;; ** Display functions
-;; ** Commands
-;; ** Modeline management
-;; ** Major mode
-;;
-;; * General commands (usable from all addressbook modes)
-;; * Backend management
-;;
-;; ** Customization and Variables
-;; ** Utility functions
-;; ** API
-;; ** Simple backend
-;; ** Multiple backend
-;;
-;; * Utility functions
-;;
-;; ** Fast selection
-;; ** Search functions
-;;
-;; * Entry points to the addressbook
-
-;;; Code:
-
-(eval-when-compile (require 'cl))
-(require 'vcard)
-(require 'mm-decode)
-
-;;;; * Constants
-
-(defconst addrbook-version "0.1"
- "Version of the addressbook")
-
-;;;; * Customization
-
-(defgroup addrbook nil
- "Addressbook subsytem"
- :group 'applications
- :link '(url-link "http://www.emacswiki.org/cgi-bin/wiki/AddressBook"))
-
-(defgroup addrbook-hooks nil
- "Addressbook hooks"
- :group 'addrbook)
-
-(defcustom addrbook-directory "~/.contacts"
- "Directory with stored vCards"
- :type 'directory
- :group 'addrbook)
-
-(defcustom addrbook-display-images t
- "Display images in the addressbook"
- :type 'boolean
- :group 'addrbook)
-
-(defcustom addrbook-display-groups
- '(identification-properties)
- "Groups to expand by default"
- :type 'sexp
- :group 'addrbook)
-
-(defcustom addrbook-force-addressbook-creation
- t
- "Force the creation of the addressbook file if it doesnt exist upon startup"
- :type 'boolean
- :group 'addrbook)
-
-(defcustom addrbook-attribute-indentation
- 1
- "Indentation deep for attribute titles"
- :type 'integer
- :group 'addrbook)
-
-(defcustom addrbook-field-indentation
- 2
- "Indentation deep for attribute fields"
- :type 'integer
- :group 'addrbook)
-
-(defcustom addrbook-ask-for-search
- nil
- "Whether the addressbook should ask for a search upon `addressbook'
invocation"
- :type 'boolean
- :group 'addrbook)
-
-(defcustom addrbook-field-for-sort
- "First name"
- "Field to use when sorting contacts.
-
-It may be \"Surname\", \"First Name\", \"AKA\", \"Name prefix\" or \"Name
suffix\"."
- :type 'string
- :group 'addrbook)
-
-(defcustom addrbook-use-multiple-frames
- nil
- "If t, open new frames when switching summary<->contact"
- :type 'boolean
- :group 'addrbook)
-
-(defface addrbook-summary-card-number
- '((((min-colors 88) (class color) (background light))
- :foreground "red1")
- (((class color) (background light))
- :foreground "red")
- (((min-colors 88) (class color) (background dark))
- :foreground "blue")
- (((class color) (background dark))
- :foreground "blue")
- (t
- :weight bold))
- "Face for summary card numbers"
- :group 'addrbook)
-
-(defface addrbook-summary-modified-flag
- '((((min-colors 88) (class color) (background light))
- :foreground "red1")
- (((class color) (background light))
- :foreground "red")
- (((min-colors 88) (class color) (background dark))
- :foreground "red")
- (((class color) (background dark))
- :foreground "red")
- (t
- :weight bold))
- "Face for summary modified flag"
- :group 'addrbook)
-
-(defface addrbook-summary-match-flag
- '((((min-colors 88) (class color) (background light))
- :foreground "brown")
- (((class color) (background light))
- :foreground "brown")
- (((min-colors 88) (class color) (background dark))
- :foreground "brown")
- (((class color) (background dark))
- :foreground "brown")
- (t
- :weight bold))
- "Face for summary match flag"
- :group 'addrbook)
-
-(defface addrbook-properties-group-name
- '((((min-colors 88) (class color) (background light))
- :foreground "red1")
- (((class color) (background light))
- :foreground "red")
- (((min-colors 88) (class color) (background dark))
- :foreground "yellow1")
- (((class color) (background dark))
- :foreground "yellow")
- (t
- :weight bold))
- "Face for properties group titles"
- :group 'addrbook)
-
-(defface addrbook-attribute-title-name
- '((((min-colors 88) (class color) (background light))
- )
- (((class color) (background light))
- )
- (((min-colors 88) (class color) (background dark))
- )
- (((class color) (background dark))
- )
- (t
- ))
- "Face for attribute titles"
- :group 'addrbook)
-
-(defface addrbook-contact-title
- '((((min-colors 88) (class color) (background light))
- :underline t
- )
- (((class color) (background light))
- :underline t
- )
- (((min-colors 88) (class color) (background dark))
- :underline t
- )
- (((class color) (background dark))
- :underline t
- )
- (t
- ))
- "Face for contact titles"
- :group 'addrbook)
-
-(defface addrbook-attribute-type
- '((((min-colors 88) (class color) (background light))
- :foreground "blue")
- (((class color) (background light))
- :foreground "blue")
- (((min-colors 88) (class color) (background dark))
- :foreground "blue")
- (((class color) (background dark))
- )
- (t
- ))
- "Face for attribute types"
- :group 'addrbook)
-
-(defface addrbook-attribute-value
- '((((min-colors 88) (class color) (background light))
- :foreground "grey")
- (((class color) (background light))
- :foreground "grey")
- (((min-colors 88) (class color) (background dark))
- :foreground "grey")
- (((class color) (background dark))
- :weight bold)
- (t
- :weight bold))
- "Face for attribute values"
- :group 'addrbook)
-
-(defface addrbook-summary-selected-card
- '((((min-colors 88) (class color) (background light))
- :background "grey"
- :foreground "black")
- (((class color) (background light))
- :background "grey"
- :foreground "black")
- (((min-colors 88) (class color) (background dark))
- :background "grey"
- :foreground "black"
- :weight bold)
- (((class color) (background dark))
- :weight bold)
- (t
- :weight bold))
- "Face for selected summary contact line"
- :group 'addrbook)
-
-;;;; * Variables
-
-(defvar addrbook-image-types
- '(("gif" nil)
- ("cgm" nil)
- ("wmf" nil)
- ("bmp" nil)
- ("met" nil)
- ("pbm" pbm)
- ("dib" nil)
- ("pict" nil)
- ("tiff" nil)
- ("pdf" nil)
- ("ps" postscript)
- ("jpeg" jpeg)
- ("mpeg" nil)
- ("mpeg2" nil)
- ("avi" nil)
- ("qtime" nil))
- "Association between vCard image types and emacs image types")
-
-(defvar addrbook-cards nil
- "Cards of the current addressbook")
-
-(defvar addrbook-modified-cards nil
- "Indexes of modified cards in addrbook-cards")
-
-(defvar addrbook-current-card nil
- "Number of current card")
-
-(defvar addrbook-properties
- '((identification-properties
- "Identification"
- (("fn" "Formatted Name" nil)
- ("n" "Name" ?n
- (("Surname" ?s)
- ("First name" ?f)
- ("AKA" ?a)
- ("Name prefix" ?p)
- ("Name suffix" ?x)))
- ("photo" "Photograph" ?p nil
- ("type" (("jpeg" "jpeg" ?j)
- ("gif" "gif" ?g)
- ("cgm" "cgm" ?c)
- ("wmf" "wmf" ?w)
- ("bmp" "bmp" ?b)
- ("met" "met" ?m)
- ("pbm" "pbm" ?p)
- ("dib" "dib" ?d)
- ("pict" "pict" ?i)
- ("tiff" "tiff" ?t)
- ("ps" "ps" ?s)
- ("pdf" "pdf" ?f)
- ("mpeg" "mpeg" ?e)
- ("mpeg2" "mpeg2" ?2)
- ("avi" "avi" ?v)
- ("qtime" "qtime" ?q))
- nil t))
- ("bday" "Birthdate" ?b nil))
- ?i)
- (delivering-addressing-properties
- "Delivering Addressing"
- (("adr" "Delivery Address" ?a
- (("Post office address" ?p)
- ("Extended address" ?e)
- ("Street" ?s)
- ("Locality" ?l)
- ("Region" ?r)
- ("Postal code" ?o)
- ("Country" ?c))
- ("type" (("home" "home" ?h)
- ("dom" "domestic" ?d)
- ("intl" "international" ?i)
- ("postal" "postal" ?p)
- ("parcel" "parcel" ?a)
- ("work" "work" ?w))
- t nil))
- ("label" "Delivery Label" ?l nil
- ("type" (("home" "home" ?h)
- ("dom" "domestic" ?d)
- ("intl" "international" ?i)
- ("postal" "postal" ?p)
- ("parcel" "parcel" ?a)
- ("work" "work" ?w))
- t nil)))
- ?d)
- (telecommunications-addressing-properties
- "Telecommunications Addressing"
- (("tel" "Telephone Number" ?t nil
- ("type" (("cell" "cellular" ?c)
- ("home" "home" ?h)
- ("pref" "preferred" ?p)
- ("work" "work" ?w)
- ("voice" "voice" ?v)
- ("fax" "facsimile" ?f)
- ("msg" "messaging service" ?m)
- ("pager" "pager" ?g)
- ("bbs" "bbs" ?b)
- ("modem" "modem" ?o)
- ("car" "car-phone" ?r)
- ("isdn" "isdn" ?i)
- ("video" "video-phone" ?d))
- t nil))
- ("email" "Electronic Mail" ?e nil
- ("type" (("internet" "smtp" ?s)
- ("aol" "America On-Line" ?l)
- ("applelink" "AppleLink" ?a)
- ("attmail" "AT&T" ?t)
- ("cis" "cis" ?c)
- ("cworld" "CWorld" ?w)
- ("ibmmail" "IBM mail" ?b)
- ("mcimail" "MCI mail" ?m)
- ("powershare" "powershare" ?p)
- ("prodigy" "prodigy" ?r)
- ("tlx" "telex" ?e)
- ("x400" "X.400" ?x))
- nil t))
- ("mailer" "Mailer" nil nil))
- ?t)
- (geographical-properties
- "Geographical"
- (("tz" "Time Zone" ?z nil)
- ("geo" "Geographic Position" ?g nil))
- ?g)
- (organizational-properties
- "Organizational"
- (("title" "Title" ?i nil)
- ("role" "Business Category" ?r nil)
- ("logo" "Business Logotype" ?w nil
- ("type" (("jpeg" "jpeg" ?j)
- ("gif" "gif" ?g)
- ("cgm" "cgm" ?c)
- ("wmf" "wmf" ?w)
- ("bmp" "bmp" ?b)
- ("met" "met" ?m)
- ("pbm" "pbm" ?p)
- ("dib" "dib" ?d)
- ("pict" "pict" ?i)
- ("tiff" "tiff" ?t)
- ("ps" "ps" ?s)
- ("pdf" "pdf" ?f)
- ("mpeg" "mpeg" ?e)
- ("mpeg2" "mpeg2" ?2)
- ("avi" "avi" ?v)
- ("qtime" "qtime" ?q))
- nil t))
- ("agent" "Agent" nil nil)
- ("org" "Organization" ?o
- (("Name" ?n)
- ("Unit" ?u)
- ("Additional units" ?a))))
- ?o)
- (explanatory-properties
- "Explanatory"
- (("note" "Comment" ?m nil)
- ("rev" "Last Revision" nil nil)
- ("sound" "Sound" ?d nil
- ("type" (("wave" "wave" ?w)
- ("pcm" "pcm" ?p)
- ("aiff" "aiff" ?a))
- nil t))
- ("url" "URL" ?u nil)
- ("uid" "Unique Identifier" nil nil)
- ("version" "Version of vCard" nil nil))
- ?e)
- (security-properties
- "Security"
- (("key" "Public Key" ?k nil
- ("type" (("pgp" "pgp" ?g)
- ("x509" "x509" ?x))
- nil t)))
- ?s))
- "vCard specification standard properties")
-
-(defvar addrbook-required-attrs '("n")
- "List of required attributes")
-
-(defvar addrbook-general-params
- '(("url" "value") ("content-id" "value"))
- "General vCard parameters")
-
-;;;; * Properties management functions
-
-;;;; ** Groups
-(defun addrbook-get-group (group-symbol)
- "Return the sexp containing information for GROUP"
- (assoc group-symbol addrbook-properties))
-
-(defun addrbook-get-group-symbol (group)
- (nth 0 group))
-
-(defun addrbook-get-group-name (group)
- (nth 1 group))
-
-(defun addrbook-get-group-props (group)
- (nth 2 group))
-
-(defun addrbook-get-group-letter (group)
- (nth 3 group))
-
-(defun addrbook-group-has-properties-p (group)
- (let ((group-attrs (addrbook-get-group-props group))
- (result nil))
- (dolist (attr (addrbook-get-card addrbook-current-card))
- (if (and (addrbook-property-in-group-p attr group-attrs)
- (not (member (vcard-attr-get-name attr)
addrbook-contact-properties-nodisplay)))
- (setq result t)))
- result))
-
-;;;; ** Properties
-
-(defun addrbook-get-group-prop (props prop-name)
- (assoc prop-name props))
-
-(defun addrbook-get-prop-name (property)
- (nth 0 property))
-
-(defun addrbook-get-prop-title (property)
- (nth 1 property))
-
-(defun addrbook-get-prop-letter (property)
- (nth 2 property))
-
-(defun addrbook-get-prop-fields-list (property)
- (nth 3 property))
-
-(defun addrbook-get-prop-fields (property)
- (let ((fields (addrbook-get-prop-fields-list property))
- (result nil) field)
- (dolist (field fields)
- (setq result (cons (car field) result)))
- (reverse result)))
-
-(defun addrbook-get-prop-field-name (field)
- (nth 0 field))
-
-(defun addrbook-get-prop-field-letter (field)
- (nth 1 field))
-
-(defun addrbook-get-prop-index (prop-fields field-name)
- (let ((index 0) result)
- (dotimes (index (length prop-fields) result)
- (if (equal (nth index prop-fields) field-name)
- (setq result index)))))
-
-(defun addrbook-get-prop-field-description (fields field-name)
- (cadr (assoc field-name fields)))
-
-(defun addrbook-get-prop-parameters (prop)
- (nthcdr 4 prop))
-
-(defun addrbook-get-prop-parameter (prop param-name)
- (let ((prop-parameters (addrbook-get-prop-parameters prop)))
- (cadr (assoc param-name prop-parameters))))
-
-(defun addrbook-prop-parameter-allow-duplicates (prop param-name)
- (let ((prop-parameters (addrbook-get-prop-parameters prop)))
- (nth 2 (assoc param-name prop-parameters))))
-
-(defun addrbook-prop-parameter-is-mandatory (prop param-name)
- (let ((prop-parameters (addrbook-get-prop-parameters prop)))
- (nth 3 (assoc param-name prop-parameters))))
-
-(defun addrbook-property-in-group-p (attr group-props)
- (let ((attr-name (vcard-attr-get-name attr)))
- (when (assoc attr-name group-props)
- t)))
-
-(defun addrbook-get-property (attr-name)
- (let (group result)
- (dolist (group addrbook-properties)
- (let* ((group-props (addrbook-get-group-props group))
- (group-prop (addrbook-get-group-prop group-props attr-name)))
- (if group-prop
- (setq result group-prop))))
- result))
-
-(defun addrbook-get-prop-default-type (prop-name)
- (let* ((property (addrbook-get-property prop-name))
- (prop-type (addrbook-get-prop-parameter property "type")))
- (when prop-type
- (car (car prop-type)))))
-
-;;;; ** Cards
-
-(defun addrbook-get-card (numcard)
- (nth numcard addrbook-cards))
-
-(defun addrbook-set-card (numcard card)
- (if addrbook-cards
- (cond
- ((and (>= numcard 0) (< numcard (length addrbook-cards)))
- (setcar (nthcdr numcard addrbook-cards) card))
- ((>= numcard (length addrbook-cards))
- (setq addrbook-cards (append addrbook-cards (list card)))))
- (setq addrbook-cards (list card))))
-
-(defun addrbook-remove-card (numcard)
- (setq addrbook-cards (delete (addrbook-get-card numcard)
- addrbook-cards)))
-
-(defun addrbook-value-empty-p (values)
- "Return t if VALUES is empty"
- (when (listp values)
- (if (cdr values)
- (when (equal (car values) "")
- (addrbook-value-empty-p (cdr values)))
- (equal (car values) ""))))
-
-(defun addrbook-number-of-values (values)
- (if (listp values)
- (let (value
- (nov 0))
- (dolist (value values nov)
- (if (not (equal value ""))
- (setq nov (+ nov 1)))))
- 1))
-
-(defun addrbook-get-card-fn (&optional with-aka card-number)
- (let* ((card (addrbook-get-card (if card-number
- card-number
- addrbook-current-card)))
- (name-attr (vcard-get-named-attribute card "n"))
- (name-attr-values (vcard-attr-get-values name-attr))
- (name-surname (nth 0 name-attr-values))
- (name-surname-p (and name-surname
- (not (equal name-surname ""))))
- (name-first-name (nth 1 name-attr-values))
- (name-first-name-p (and name-first-name
- (not (equal name-first-name ""))))
- (name-aka (nth 2 name-attr-values))
- (name-aka-p (and name-aka
- (not (equal name-aka ""))))
- (name-prefix (nth 3 name-attr-values))
- (name-prefix-p (and name-prefix
- (not (equal name-prefix ""))))
- (name-suffix (nth 4 name-attr-values))
- (name-suffix-p (and name-suffix
- (not (equal name-suffix ""))))
- (result ""))
- (when name-prefix-p
- (setq result (concat result name-prefix)))
- (when name-first-name-p
- (setq result (concat result
- (when name-prefix-p " ")
- name-first-name)))
- (when name-surname-p
- (setq result (concat result
- (when (or name-prefix-p
- name-first-name-p) " ")
- name-surname)))
- (when name-suffix-p
- (setq result (concat result
- (when (or name-prefix-p
- name-first-name-p
- name-surname-p) " ")
- name-suffix)))
- (when (and with-aka name-aka-p)
- (setq result (concat result
- (when (or name-prefix-p
- name-first-name-p
- name-surname-p
- name-suffix-p) " ")
- "(" name-aka ")")))
- result))
-
-;;;; ** Attributes
-
-(defun addrbook-delete-attr (attr-index attr-subindex)
- (let* ((card (addrbook-get-card addrbook-current-card))
- (attr (vcard-get-attribute card attr-index))
- (attr-value (vcard-attr-get-values attr)))
- (if attr-subindex
- (progn
- ;; Delete the field from the values
- (setcar (nthcdr attr-subindex attr-value) "")
- (vcard-attr-set-values attr attr-value)
- (if (addrbook-value-empty-p attr-value)
- (addrbook-set-card addrbook-current-card
(vcard-delete-indexed-attribute card attr-index))))
- ;; Delete the attribute
- (addrbook-set-card addrbook-current-card (vcard-delete-indexed-attribute
card attr-index)))))
-
-(defun addrbook-build-custom-property-group ()
- "Return an empty custom property group"
- (list 'custom-properties
- "Custom Properties"
- nil
- ?c))
-
-(defun addrbook-set-custom-properties (props-data)
-"This function accepts a list of the form:
-
- (PROP1 PROP2 ... PROPN)
-
-where each property PROP is defined with the following structure:
-
- (\"property-name\" \"Property displayed name\"
- ?character-identifying-the-group-for-fast-selection
- (FIELD1 FIELD2 ... FIELDN)
- (\"type\"
- ((\"type1\" \"type1 displayed name\" ?fast-selection-char1)
- (\"type2\" \"type 2 displayed name\" ?fast-selection-char2)
- ...)
- allow-several-types-p at-least-one-type-mandatory-p))
-
-where each field FIELD is defined with the following structure:
-
- (\"Field name\" ?character-identifying-the-field-for-fast-selection)"
- (let (custom-group
- prop)
- (dolist (prop props-data)
- (setcar prop (concat "x-emacs-" (car prop))))
- (when (not (addrbook-get-group 'custom-properties))
- (setq addrbook-properties
- (append addrbook-properties (list
(addrbook-build-custom-property-group)))))
- (setq custom-group (addrbook-get-group 'custom-properties))
- (setcar (nthcdr 2 custom-group) props-data)))
-
-
-;;;; * Addressbook contact editor
-
-;;;; ** Constants
-
-(defconst addrbook-contact-buffer-name "*AddressBook Contact*"
- "Name of the buffer for the addressbook contact editor")
-
-;;;; ** Variables
-
-(defvar addrbook-contact-properties-nodisplay
- '("sound" "agent" "version" "uid" "label" "mailer" "uid"))
-
-(defvar addrbook-contact-mode-map nil
- "Keymap for addrbook-contact-mode")
-
-(defvar addrbook-contact-displayed-groups nil
- "List of displayed property groups")
-
-(defvar addrbook-contact-mode-line-string " ABook Contact"
- "String to display on the mode line when in the addressbook mode.
-If `nil', do not show anything.")
-
-;;;; ** Contact buffer management
-
-(defun addrbook-create-contact-buffer ()
- "Create a new addressbook buffer to show contact information"
- (setq buffer (get-buffer-create addrbook-contact-buffer-name))
- (set-buffer buffer)
- (addrbook-contact-mode))
-
-(defun addrbook-show-contact ()
- (let ((buffer (get-buffer addrbook-contact-buffer-name)))
- (if addrbook-use-multiple-frames
- (switch-to-buffer-other-window buffer)
- (switch-to-buffer buffer))))
-
-;;;; ** Display functions
-
-(defun addrbook-contact-display-card (numcard)
- "Display the NUMCARD card into the addressbook buffer"
- (save-excursion
- (let ((card (addrbook-get-card numcard)))
- (if card
- (progn
- (erase-buffer)
- (setq addrbook-current-card numcard)
- (insert "\n\n")
- ;; Reset displayed groups list
- (setq addrbook-contact-displayed-groups nil)
- ;; Display groups
- (mapcar #'addrbook-contact-display-group addrbook-properties)
- ;; Hide all groups not present in addrbook-display-groups
- (dolist (group addrbook-contact-displayed-groups nil)
- (if (not (member group addrbook-display-groups))
- (addrbook-contact-hide-show-group group nil)))
- ;; Set mode line contents
- (addrbook-contact-set-mode-line (+ addrbook-current-card 1)
- (length addrbook-cards)))))))
-
-(defun addrbook-contact-display-group (group)
- (if (addrbook-group-has-properties-p group)
- (let ((group-region-begin (make-marker))
- (group-region-end nil))
- (set-marker group-region-begin (point))
- (addrbook-contact-display-properties group)
- (insert "\n")
- (setq group-region-end (point))
- (put-text-property (marker-position group-region-begin)
- group-region-end
- 'group-region (car group)))))
-
-(defun addrbook-contact-display-properties (group)
- "Display the GROUP properties from the current card"
- (let* ((card (addrbook-get-card addrbook-current-card))
- (group-name (addrbook-get-group-name group))
- (group-props (addrbook-get-group-props group))
- (num-attributes (vcard-get-num-attributes card))
- (i 0))
- ;; Mark this group as displayed
- (add-to-list 'addrbook-contact-displayed-groups (addrbook-get-group-symbol
group))
- (insert (propertize group-name 'face 'addrbook-properties-group-name
- 'group (addrbook-get-group-symbol group)))
- (insert "\n\n")
- (dolist (property group-props)
- (dotimes (i num-attributes)
- (let ((attr (vcard-get-attribute card i)))
- (if (and (equal (vcard-attr-get-name attr) (addrbook-get-prop-name
property))
- (not (addrbook-contact-attribute-nodisplay attr
addrbook-contact-properties-nodisplay))
- (addrbook-property-in-group-p attr group-props))
- (addrbook-contact-display-attribute i)))))))
-
-(defun addrbook-contact-attribute-nodisplay (attr nodisplay-attrs)
- (let ((attr-name (vcard-attr-get-name attr)))
- (if nodisplay-attrs
- (or (equal (car nodisplay-attrs) attr-name)
- (addrbook-contact-attribute-nodisplay attr (cdr nodisplay-attrs))))))
-
-(defun addrbook-contact-display-attribute (attr-index)
- "Display the ATTR-INDEXth attribute"
- (let* ((card (addrbook-get-card addrbook-current-card))
- (attr (vcard-get-attribute card attr-index))
- (attr-name (vcard-attr-get-name attr)))
- (cond
- ((equal attr-name "fn")
- t)
- ((equal attr-name "n")
- (addrbook-contact-display-attribute-n attr-index))
- ((or (equal attr-name "photo")
- (equal attr-name "logo"))
- (addrbook-contact-display-attribute-photo-logo attr-index))
- (t
- (addrbook-contact-display-attribute-regular attr-index)))))
-
-(defun addrbook-contact-display-attribute-n (attr-index)
- (let* ((card (addrbook-get-card addrbook-current-card))
- (attr (vcard-get-attribute card attr-index))
- (attr-value (vcard-attr-get-values attr))
- (surname (nth 0 attr-value))
- (name (nth 1 attr-value))
- (additional-names (nth 2 attr-value))
- (name-prefix (nth 3 attr-value))
- (name-suffix (nth 4 attr-value)))
- (addrbook-contact-display-attribute-regular attr-index)
- ;; Insert name on the first line
- (save-excursion
- (goto-char (point-min))
- (if (get-text-property (point) 'title)
- (addrbook-erase-tagged-region 'title))
- (insert (propertize
- (addrbook-get-card-fn t)
- 'face 'addrbook-contact-title
- 'title t)))))
-
-(defun addrbook-contact-display-attribute-photo-logo (attr-index)
- "Display photo from ATTR-INDEX.
-Only display it if not already displayed and/or image type is
-supported and if `display-images-p' is non nil.
-
-ATTR-INDEX can represent eith an inlined data or an offline url.
-When ressource is of type URL, we use url package to get the image data."
- (let* ((card (addrbook-get-card addrbook-current-card))
- (attr (vcard-get-attribute card attr-index))
- (attr-value (car (vcard-attr-get-values attr)))
- (photo-type (car (vcard-attr-get-parameter attr "type")))
- (photo-value (car (vcard-attr-get-parameter attr "value")))
- (image-type nil)
- (image-data nil))
- (addrbook-contact-display-attribute-regular attr-index)
- ;; Insert photo in buffer
- ;; Determine emacs image type
- (setq image-type
- (cadr (assoc photo-type addrbook-image-types)))
-
- ;; Display the image or a link
- (when (and addrbook-display-images
- (display-images-p)
- image-type
- (image-type-available-p image-type)
- (not (addrbook-contact-photo-displayed-p)))
-
- ;; Get image data
- (let ((image-data
- (if (equal photo-value "url")
- (save-excursion
- (require 'url)
-
- (let ((image-buffer (url-retrieve-synchronously attr-value)))
- (if image-buffer
- (unwind-protect
- (with-current-buffer image-buffer
- ;; FIXME: could be more robust
- (goto-char (point-min))
- (re-search-forward "^\r?$" nil 1)
- (forward-line)
- (delete-region (point-min) (point))
-
- (setq image-data (string-as-unibyte
(buffer-string))))
- (kill-buffer image-buffer)))))
- attr-value)))
-
- ;; Display the image
- (save-excursion
- (goto-char (point-min))
- (goto-char (line-end-position))
- (insert "\n\n")
- (insert-image (create-image image-data image-type t)
- (propertize "[photo]"
- 'identification-photo t
- 'attr-index attr-index
- 'attr-subindex nil)))))))
-
-(defun addrbook-contact-display-attribute-regular (attr-index)
- (let* ((card (addrbook-get-card addrbook-current-card))
- (attr (vcard-get-attribute card attr-index))
- (attr-name (vcard-attr-get-name attr))
- (attr-value (vcard-attr-get-values attr))
- (property (addrbook-get-property attr-name))
- (prop-title (addrbook-get-prop-title property))
- (prop-fields (addrbook-get-prop-fields property))
- (attr-type (car (vcard-attr-get-parameter attr "type")))
- (attr-region-begin nil)
- (attr-region-end nil))
- (setq attr-region-begin (point))
- (if prop-fields
- (progn
- ;; Insert attribute fields instead of name
- (insert (make-string addrbook-attribute-indentation ?\ ))
- (insert (propertize prop-title
- 'face 'addrbook-attribute-title-name
- 'attr-compound-title t
- 'attr-index attr-index))
- (addrbook-contact-display-attribute-type attr-index)
- (insert ":")
- (insert "\n")
- (dotimes (i (length prop-fields))
- (let ((value (nth i attr-value)))
- (if (and value
- (not (equal value "")))
- (progn
- (insert (make-string
- (+ addrbook-field-indentation
- addrbook-attribute-indentation)
- ?\ ))
- (insert (propertize (nth i prop-fields)
- 'face 'addrbook-attribute-title-name
- 'attr-index attr-index
- 'attr-subindex i))
- (insert ":")
- (insert " ")
- (insert (propertize (nth i attr-value)
- 'face 'addrbook-attribute-value
- 'attr-index attr-index
- 'attr-subindex i))
- (insert "\n"))))))
- ;; Insert attribute title
- (insert " ")
- (insert (propertize prop-title
- 'face 'addrbook-attribute-title-name
- 'attr-index attr-index
- 'attr-subindex nil))
- (addrbook-contact-display-attribute-type attr-index)
- (insert ":")
- (insert " ")
- ;; Insert attribute value
- (insert (propertize (car attr-value)
- 'face 'addrbook-attribute-value
- 'attr-index attr-index
- 'attr-subindex nil))
- (insert "\n"))
-
- (setq attr-region-end (point))
- (put-text-property attr-region-begin attr-region-end
- 'attr-region attr-index)))
-
-(defun addrbook-contact-display-attribute-type (attr-index)
- (let* ((card (addrbook-get-card addrbook-current-card))
- (attr (vcard-get-attribute card attr-index))
- (attr-name (vcard-attr-get-name attr))
- (property (addrbook-get-property attr-name))
- (type-param (addrbook-get-prop-parameter property "type"))
- (attr-type-params (vcard-attr-get-parameter attr "type"))
- attr-type
- prop-type-param
- printable-type-list)
- (dolist (attr-type attr-type-params)
- (setq printable-type-list
- (cons (nth 1 (assoc attr-type type-param)) printable-type-list)))
- (setq printable-type-list (reverse printable-type-list))
- (when attr-type-params
- (insert " ")
- (insert "(")
- (insert (propertize
- (addrbook-list-to-csv printable-type-list)
- 'face 'addrbook-attribute-type))
- (insert ")"))))
-
-(defun addrbook-contact-group-hidden-p (group)
- (save-excursion
- (let ((group-exist (addrbook-contact-goto-group group)))
- (and group-exist
- (get-text-property group-exist 'invisible)))))
-
-(defun addrbook-contact-hide-show-group (group show-p)
- "Hide GROUP attributes from the screen"
- (save-excursion
- (let ((group-exist (addrbook-contact-goto-group group))
- (group-real-begin-pos nil)
- (group-end-pos nil)
- (group-begin-pos nil))
- (when group-exist
- (setq group-real-begin-pos (next-single-property-change (point)
'group))
- (goto-char group-real-begin-pos)
- (setq group-end-pos (next-single-property-change (point) 'group))
- (if (not group-end-pos)
- (setq group-end-pos (point-max)))
- (if show-p
- (progn
- (remove-text-properties group-real-begin-pos
- (- group-end-pos 1)
- '(invisible nil)))
- (put-text-property group-real-begin-pos
- (- group-end-pos 1)
- 'invisible t))))))
-
-(defun addrbook-contact-get-current-group ()
- "Return the group affecting current buffer point, or nil"
- (let ((prop-change-pos (previous-single-property-change
- (point) 'group)))
- (when prop-change-pos
- (save-excursion
- (goto-char (- prop-change-pos 1))
- (get-text-property (point) 'group)))))
-
-(defun addrbook-contact-get-current-attr-index ()
- "Return the attribute index of the attribute displayed in the current line"
- (addrbook-get-text-property-line 'attr-index))
-
-(defun addrbook-contact-get-current-attr-subindex ()
- "Return the attribute subindex of the attribute displayed in the current
line"
- (addrbook-get-text-property-line 'attr-subindex))
-
-(defun addrbook-contact-get-current-attr-compound-title ()
- (addrbook-get-text-property-line 'attr-compound-title))
-
-(defun addrbook-contact-goto-group (group)
- "Leave the point at the beginning of GROUP"
- (let ((group-begin-pos nil)
- (found nil)
- (group-exist t))
- ;; Search for the first non-nil 'group
- ;; property change with 'group == GROUP
- (goto-char (point-min))
- (while (not found)
- (setq group-begin-pos (next-single-property-change (point) 'group))
- (if group-begin-pos
- (progn
- (goto-char group-begin-pos)
- (if (eq (get-text-property (point) 'group) group)
- (setq found t)))
- (setq found t)
- (setq group-exist nil)))
- group-exist))
-
-(defun addrbook-contact-redisplay-card ()
- "Redisplay current card"
- (erase-buffer)
- (addrbook-contact-display-card addrbook-current-card))
-
-(defun addrbook-contact-redisplay-group (group)
- "Redisplay GROUP in the screen"
- (save-excursion
- (let ((group-exist (addrbook-contact-goto-group group)))
- (when group-exist
- ;; Remove old group contents
- (addrbook-contact-erase-group-region)
- ;; Display the group
- (addrbook-contact-display-group (addrbook-get-group group))))))
-
-(defun addrbook-contact-erase-group-region ()
- "Erase the region used by the group in point"
- (addrbook-erase-tagged-region 'group-region))
-
-(defun addrbook-contact-erase-attr-region ()
- "Erase the region used by the attribute in point"
- (addrbook-erase-tagged-region 'attr-region))
-
-(defun addrbook-contact-redisplay-attr-at-point ()
- "Redisplay the attribute at point"
- (let* ((column-backup (current-column))
- (line-backup (line-number-at-pos (point)))
- (group-symbol (addrbook-contact-get-current-group))
- (attr-index (addrbook-contact-get-current-attr-index)))
- (if (and group-symbol attr-index)
- (let* ((card (addrbook-get-card addrbook-current-card))
- (group (addrbook-get-group group-symbol))
- (group-attrs (addrbook-get-group-props group))
- group-aregion-begin group-region-end)
- (addrbook-contact-erase-attr-region)
- (setq group-region-begin (point))
- (addrbook-contact-display-attribute attr-index)
- (setq group-region-end (point))
- (put-text-property group-region-begin
- group-region-end
- 'group-region group-symbol)
- (goto-line line-backup)
- (goto-char (+ (line-beginning-position) column-backup))))))
-
-(defun addrbook-contact-in-display-p (group-symbol)
- (addrbook-contact-goto-group group-symbol))
-
-(defun addrbook-contact-photo-displayed-p ()
- (next-single-property-change (point-min) 'identification-photo))
-
-;;;; ** Commands
-
-(defun addrbook-contact-add-attribute-type ()
- "Add a new type to the attribute under point"
- (interactive)
- (let ((buffer-read-only nil)
- (point-backup (point))
- (group-symbol (addrbook-contact-get-current-group))
- (attr-index (addrbook-contact-get-current-attr-index))
- (attr-subindex (addrbook-contact-get-current-attr-subindex)))
- (if (and attr-index
- (not attr-subindex))
- (let* ((card (addrbook-get-card addrbook-current-card))
- (attr (vcard-get-attribute card attr-index))
- (attr-name (vcard-attr-get-name attr))
- (property (addrbook-get-property attr-name))
- (prop-types (addrbook-get-prop-parameter property "type")))
- (if prop-types
- (let ((new-type (addrbook-select-non-existing-type attr))
- type result)
- (dolist (type prop-types)
- (if (equal (cadr type)
- new-type)
- (setq result (car type))))
- (when result
- (if (addrbook-prop-parameter-allow-duplicates property
"type")
- ;; Add the new type
- (vcard-attr-add-property attr "type" result)
- ;; Replace current type
- (vcard-attr-set-property attr "type" result))
- ;; Redisplay attribute
- (addrbook-contact-redisplay-attr-at-point)
- ;; Addressbook modified
- (add-to-list 'addrbook-modified-cards
addrbook-current-card))))))
- (goto-char point-backup)))
-
-(defun addrbook-contact-remove-attribute-type ()
- "Remove a type from the attribute under point"
- (interactive)
- (let ((buffer-read-only nil)
- (point-backup (point))
- (group-symbol (addrbook-contact-get-current-group))
- (attr-index (addrbook-contact-get-current-attr-index))
- (attr-subindex (addrbook-contact-get-current-attr-subindex)))
- (if (and attr-index
- (not attr-subindex))
- (let* ((card (addrbook-get-card addrbook-current-card))
- (attr (vcard-get-attribute card attr-index))
- (attr-name (vcard-attr-get-name attr))
- (property (addrbook-get-property attr-name))
- (prop-types (addrbook-get-prop-parameter property "type")))
- (if prop-types
- (if (and (equal (length (vcard-attr-get-parameter attr "type"))
1)
- (addrbook-prop-parameter-is-mandatory property "type"))
- (message "This attribute should have a type")
- (let ((new-type (addrbook-select-existing-type attr))
- type result)
- (dolist (type prop-types)
- (if (equal (cadr type)
- new-type)
- (setq result (car type))))
- (when result
- ;; Add the new type
- (vcard-attr-remove-property attr "type" result)
- ;; Redisplay attribute
- (addrbook-contact-redisplay-attr-at-point)
- ;; Addressbook modified
- (add-to-list 'addrbook-modified-cards
addrbook-current-card)))))))
- (goto-char point-backup)))
-
-(defun addrbook-contact-delete-attribute ()
- "Delete the attribute under point"
- (interactive)
- (let ((buffer-read-only nil)
- (point-backup (point))
- (group-symbol (addrbook-contact-get-current-group))
- (attr-index (addrbook-contact-get-current-attr-index))
- (attr-subindex (addrbook-contact-get-current-attr-subindex)))
- (if (and group-symbol attr-index)
- (let* ((group (addrbook-get-group group-symbol))
- (group-attrs (addrbook-get-group-props group))
- (card (addrbook-get-card addrbook-current-card))
- (attr (vcard-get-attribute card attr-index))
- (attr-name (vcard-attr-get-name attr))
- (attr-value (vcard-attr-get-values attr))
- (group-attr (addrbook-get-group-prop group-attrs attr-name))
- (attr-title (addrbook-get-prop-title group-attr))
- (attr-fields (addrbook-get-prop-fields-list group-attr))
- (attr-field (when attr-subindex (nth attr-subindex attr-fields)))
- (attr-field-name (when attr-field (addrbook-get-prop-field-name
attr-field)))
- (prompt (concat "Are you sure you want to delete "
- (if attr-subindex
- (concat "field " attr-field-name)
- (concat "attribute " attr-title))
- "? "))
- elt)
- (if (yes-or-no-p prompt)
- (if (and (member attr-name addrbook-required-attrs)
- (or (addrbook-contact-get-current-attr-compound-title)
- (equal (addrbook-number-of-values attr-value) 1)))
- (error "Trying to delete a required attribute")
- (addrbook-delete-attr attr-index attr-subindex)
- (if (not (equal attr-name "photo"))
- (addrbook-contact-redisplay-group group-symbol)
- (addrbook-contact-redisplay-card))))))
- (goto-char point-backup)
- (add-to-list 'addrbook-modified-cards addrbook-current-card)))
-
-(defun addrbook-contact-add-attribute ()
- "Add a new attribute to the current card"
- (interactive)
- (let* (buffer-read-only
- (backup-point (point))
- group-symbol
- group group-attrs
- (i 0)
- (current-card (addrbook-get-card addrbook-current-card)))
- ;; Get group
- (setq group-symbol (or (addrbook-contact-get-current-group)
- (addrbook-select-group)))
- (setq group (addrbook-get-group group-symbol))
- (setq group-attrs (addrbook-get-group-props group))
- (if group-symbol
- (let (attr-index attr-subindex property-index)
- ;; Get property
- (setq attr-index (addrbook-contact-get-current-attr-index))
- (setq attr-subindex (addrbook-contact-get-current-attr-subindex))
- (if (and attr-index attr-subindex)
- (let ((attr (vcard-get-attribute current-card attr-index)))
- (setq property-name (vcard-attr-get-name attr)))
- (setq property-name (addrbook-select-property group-symbol)))
- (if property-name
- (let* ((property (addrbook-get-group-prop group-attrs
property-name))
- (property-title (addrbook-get-prop-title property))
- (property-fields (addrbook-get-prop-fields property))
- field-index (property-value "") prompt
- (continue t))
- ;; Get field
- (when property-fields
- (setq field-index (addrbook-select-field group-symbol
property-name))
- (setq continue field-index))
- (when continue
- ;; Ask for a new value for the property or field
- (setq prompt (concat
- property-title
- (if field-index
- (concat " ("
- (nth field-index property-fields)
- ")"))
- ": "))
- ;; Read value from minibuffer
- (while (equal property-value "")
- (setq property-value
- (read-from-minibuffer prompt)))
- (if (and attr-index property-fields)
- (let* ((attr (vcard-get-attribute current-card
attr-index))
- (attr-values (vcard-attr-get-values attr))
- (attr-value (nthcdr field-index attr-values)))
- ;; Add a field to a specific attribute
- (if attr-value
- (setcar attr-value property-value)
- (setq attr-values (reverse attr-values))
- ;; Add enough empty values and then the new value
- (dotimes (i (- field-index (length attr-values)))
- (setq attr-values (cons "" attr-values)))
- (setq attr-values (cons property-value attr-values))
- (setq attr-values (reverse attr-values))
- (vcard-attr-set-values attr attr-values)))
- ;; Create a new attribute
- (let* ((new-attr-type (addrbook-get-prop-default-type
property-name))
- (new-attr-name property-name)
- (new-attr-values property-value)
- new-attr)
- (setq new-attr (list (list new-attr-name)
- new-attr-values))
- (vcard-attr-set-property new-attr "type" new-attr-type)
- (if (equal new-attr-name "photo")
- (vcard-attr-set-property new-attr "value" "url"))
- (setq current-card (vcard-add-attribute current-card
new-attr))))
- (addrbook-set-card addrbook-current-card current-card)
- (if (addrbook-contact-in-display-p group-symbol)
- (progn
- ;; Redisplay the group with new contents
- (addrbook-contact-redisplay-group group-symbol)
- ;; Hide the group if it was hidden
- (if (addrbook-contact-group-hidden-p group)
- (addrbook-contact-hide-show-group group nil)))
- ;; Redisplay the entire card
- (addrbook-contact-redisplay-card))
- ;; This card has been modified
- (add-to-list 'addrbook-modified-cards
addrbook-current-card))))))
- (goto-char backup-point)))
-
-(defun addrbook-contact-edit-attribute ()
- (interactive)
- "Edit the value of the attribute located in the current line"
- (let ((buffer-read-only nil)
- (group-symbol (addrbook-contact-get-current-group))
- (attr-index (addrbook-contact-get-current-attr-index))
- (attr-subindex (addrbook-contact-get-current-attr-subindex))
- (attr-compound-title-p
(addrbook-contact-get-current-attr-compound-title)))
- (if (and group-symbol attr-index (not attr-compound-title-p))
- (let* ((group (addrbook-get-group group-symbol))
- (group-attrs (addrbook-get-group-props group))
- (card (addrbook-get-card addrbook-current-card))
- (attr (vcard-get-attribute card attr-index))
- (attr-name (vcard-attr-get-name attr))
- (attr-value (vcard-attr-get-values attr))
- (group-attr (addrbook-get-group-prop group-attrs attr-name))
- (attr-fields (addrbook-get-prop-fields group-attr))
- (attr-real-value (if attr-subindex
- (nth attr-subindex attr-value)
- (car attr-value)))
- (attr-real-name (if attr-subindex
- (nth attr-subindex attr-fields)
- (addrbook-get-prop-title group-attr)))
- (new-value nil))
- ;; Ask for a new value for the attribute
- (setq new-value
- (read-from-minibuffer (concat attr-real-name ": ")
- attr-real-value))
- ;; Set the new value into the cards list
- ;; attr-fields[attr-subindex], attr-value, attr
- (let ((new-values nil))
- (if attr-subindex
- (setcar (nthcdr attr-subindex attr-value) new-value)
- (setq new-values (list new-value))
- (vcard-attr-set-values attr new-values)))
- ;; FIXME: update Last Revision field
- ;; Mark the current card as modified
- (add-to-list 'addrbook-modified-cards addrbook-current-card)
- ;; Redisplay attribute
- ;; FIXME: use addrbook-contact-redisplay-attr-at-point
- (let ((column-backup (current-column))
- (line-backup (line-number-at-pos (point))))
- (addrbook-contact-erase-attr-region)
- (addrbook-contact-display-attribute attr-index)
- (goto-line line-backup)
- (goto-char (+ (line-beginning-position) column-backup)))))))
-
-(defun addrbook-contact-goto-next-group ()
- "Leave the point at the beginning of the next group"
- (let ((next-point))
- (setq next-point (next-single-property-change (point) 'group))
- (when next-point
- (if (get-text-property next-point 'group)
- (goto-char next-point)
- (goto-char next-point)
- (setq next-point (next-single-property-change (point) 'group))
- (when next-point
- (goto-char next-point))))))
-
-(defun addrbook-contact-toggle-hide-show-group ()
- "When staying on a parameters group title, toggle visibility of the group"
- (interactive)
- (let ((buffer-read-only nil)
- (group (get-text-property (point) 'group))
- (group-content-pos nil))
- (when group
- ;; Search for visibility properties in group contents
- (setq group-content-pos (next-single-property-change (point) 'group))
- (if (get-text-property group-content-pos 'invisible)
- (addrbook-contact-hide-show-group group t)
- (addrbook-contact-hide-show-group group nil)))))
-
-(defun addrbook-contact-hide-all-groups ()
- "Hide all displayed groups"
- (interactive)
- (let (buffer-read-only)
- (dolist (group addrbook-contact-displayed-groups nil)
- (addrbook-contact-hide-show-group group nil))))
-
-(defun addrbook-contact-show-all-groups ()
- "Show all displayed groups"
- (interactive)
- (let (buffer-read-only)
- (dolist (group addrbook-contact-displayed-groups nil)
- (addrbook-contact-hide-show-group group t))))
-
-(defun addrbook-contact-cycle-groups ()
- "Cycle to next group"
- (interactive)
- (let ((next-group-pos (addrbook-contact-goto-next-group)))
- (when (not next-group-pos)
- (goto-char (point-min))
- (addrbook-contact-goto-next-group))))
-
-;;;; ** Modeline management
-
-(defun addrbook-contact-set-mode-line (card-number total-cards)
- "Update the modeline of the current buffer"
- ;; FIXME: this is ugly
- (when addrbook-contact-mode-line-string
- (setq mode-line-buffer-identification
- (list 24
- addrbook-contact-mode-line-string
- ": "
- (list 10
- (format "%d/%d" card-number total-cards))))))
-
-;;;; ** Major mode
-(defun addrbook-contact-mode ()
- "A major mode for contact editing
-
-Commands:
-\\{addrbook-contact-mode-map}"
- (interactive)
- (kill-all-local-variables)
- (setq addrbook-contact-mode-map (make-keymap))
- (define-key addrbook-contact-mode-map "c" 'addrbook-create-card)
- (define-key addrbook-contact-mode-map "D" 'addrbook-delete-card)
- (define-key addrbook-contact-mode-map "n" 'addrbook-next-contact)
- (define-key addrbook-contact-mode-map "p" 'addrbook-previous-contact)
- (define-key addrbook-contact-mode-map "s" 'addrbook-save-cards)
- (define-key addrbook-contact-mode-map "x" 'addrbook-export-card)
- (define-key addrbook-contact-mode-map "b" 'addrbook-bury)
- (define-key addrbook-contact-mode-map "q" 'addrbook-quit)
- (define-key addrbook-contact-mode-map "e"
'addrbook-contact-edit-attribute)
- (define-key addrbook-contact-mode-map (kbd "SPC")
'addrbook-contact-toggle-hide-show-group)
- (define-key addrbook-contact-mode-map (kbd "TAB")
'addrbook-contact-cycle-groups)
- (define-key addrbook-contact-mode-map "d"
'addrbook-contact-delete-attribute)
- (define-key addrbook-contact-mode-map "a"
'addrbook-contact-add-attribute)
- (define-key addrbook-contact-mode-map "t"
'addrbook-contact-add-attribute-type)
- (define-key addrbook-contact-mode-map "r"
'addrbook-contact-remove-attribute-type)
- (define-key addrbook-contact-mode-map "m" 'addrbook-send-email)
- (define-key addrbook-contact-mode-map "H"
'addrbook-contact-hide-all-groups)
- (define-key addrbook-contact-mode-map "S"
'addrbook-contact-show-all-groups)
- (define-key addrbook-contact-mode-map "h" 'addrbook-summarize)
- (use-local-map addrbook-contact-mode-map)
- (setq mode-name "ABook Contact")
- (setq major-mode 'addrbook-contact-mode))
-
-;;;; * Addressbook Summary
-
-;;;; ** Constants
-
-(defconst addrbook-summary-buffer-name "*AddressBook Summary*"
- "Name of the buffer for the addressbook summary")
-
-;;;; ** Variables
-
-(defvar addrbook-summary-mode-map nil
- "Keymap for addrbook-summary-mode")
-
-(defvar addrbook-summary-mode-line-string " ABook Summary"
- "String to display on the mode line when in the addressbook summary mode.
-If `nil', do not show anything.")
-
-;;;; ** Summary buffer management
-
-(defun addrbook-make-summary-buffer ()
- (save-excursion
- (let ((buffer (get-buffer-create addrbook-summary-buffer-name)))
- (set-buffer buffer)
- (addrbook-summary-mode)
- (addrbook-summary-display)
- (setq buffer-read-only t)
- (setq addrbook-summary-buffer buffer)
- buffer)))
-
-(defun addrbook-summary ()
- "Open the addressbook and show the summary window"
- (let ((buffer (get-buffer addrbook-summary-buffer-name)))
- (when (not buffer)
- (setq buffer (addrbook-make-summary-buffer)))
- (switch-to-buffer-other-window addrbook-summary-buffer)
- (addrbook-summary-goto-contact 0 t)))
-
-(defun addrbook-summarize ()
- "Summarize the contents of the addressbook in a summary buffer.
-
-The format is as described in the variable `addrbook-summary-format'"
- (interactive)
- (if (not (get-buffer addrbook-summary-buffer-name))
- (save-excursion
- (addrbook-get-create-summary-buffer)
- (set-buffer (get-buffer addrbook-summary-buffer-name))
- (addrbook-summary-goto-contact addrbook-current-card nil)))
- (addrbook-show-summary))
-
-(defun addrbook-show-summary ()
- (let ((buffer (get-buffer addrbook-summary-buffer-name)))
- (if addrbook-use-multiple-frames
- (switch-to-buffer-other-window buffer)
- (switch-to-buffer buffer))
- (addrbook-summary-goto-contact addrbook-current-card nil)))
-
-(defun addrbook-get-create-summary-buffer ()
- (if (not addrbook-summary-buffer)
- (save-excursion
- (setq addrbook-summary-buffer (get-buffer-create
addrbook-summary-buffer-name))
- (set-buffer addrbook-summary-buffer)
- (addrbook-summary-mode)
- (addrbook-summary-display)))
- addrbook-summary-buffer)
-
-;;;; ** Display functions
-
-(defun addrbook-summary-display ()
- (erase-buffer)
- (let (card-index card name)
- (dotimes (card-index (length addrbook-cards))
- (insert " ")
- (insert " ")
- (insert (propertize (number-to-string (+ card-index 1))
- 'face 'addrbook-summary-card-number)
- " ")
- (insert (make-string (- 4 (length (number-to-string card-index))) ?\ ))
- (setq card (addrbook-get-card card-index))
- (setq name (vcard-get-named-attribute card "n"))
- (insert (propertize (addrbook-get-card-fn t card-index)
- 'face 'addrbook-attribute-value))
- (add-text-properties (line-beginning-position)
- (line-end-position)
- (list 'card-index card-index))
- (insert (propertize "\n"
- 'card-index card-index)))))
-
-(defun addrbook-summary-goto-contact (numcard update-contact-buffer)
- (let (new-pos temp-new-pos found)
- (remove-overlays (point-min) (point-max))
- (if (equal (get-text-property (point-min) 'card-index) numcard)
- (setq new-pos (point-min))
- (setq temp-new-pos (point-min))
- (while (and (not found)
- (setq temp-new-pos (next-single-property-change temp-new-pos
'card-index)))
- (when (equal (get-text-property temp-new-pos 'card-index) numcard)
- (setq new-pos temp-new-pos)
- (setq found t))))
- (when new-pos
- (goto-char new-pos)
- (beginning-of-line)
- (let ((highlight-overlay (make-overlay (line-beginning-position)
- (line-beginning-position 2))))
- (overlay-put highlight-overlay 'face 'addrbook-summary-selected-card))
- (addrbook-summary-set-mode-line (+ numcard 1) (length addrbook-cards))
- (when (and update-contact-buffer
- (get-buffer addrbook-contact-buffer-name))
- (save-excursion
- (set-buffer (get-buffer addrbook-contact-buffer-name))
- (let (buffer-read-only)
- (addrbook-contact-display-card numcard)))))))
-
-(defun addrbook-summary-get-current-card ()
- (get-text-property (point) 'card-index))
-
-;;;; ** Commands
-
-(defun addrbook-summary-next-contact ()
- "Select the next card in the summary buffer"
- (interactive)
- (let ((card-index (addrbook-summary-get-current-card)))
- (cond
- ((equal card-index (- (length addrbook-cards) 1))
- (addrbook-summary-goto-contact 0 t))
- (t
- (addrbook-summary-goto-contact (+ card-index 1) t)))))
-
-(defun addrbook-summary-previous-contact ()
- "Select the previous card in the summary buffer"
- (interactive)
- (let ((card-index (addrbook-summary-get-current-card)))
- (cond
- ((equal card-index 0)
- (addrbook-summary-goto-contact (- (length addrbook-cards) 1) t))
- (t
- (addrbook-summary-goto-contact (- card-index 1) t)))))
-
-(defun addrbook-summary-show-contact ()
- "Open an addressbook buffer to show the current selected card"
- (interactive)
- (let ((card-index (addrbook-summary-get-current-card)))
- (when (not (get-buffer addrbook-contact-buffer-name))
- (save-excursion
- (addrbook-create-contact-buffer)
- (addrbook-contact-display-card card-index)
- (setq buffer-read-only t)))
- (addrbook-show-contact)))
-
-;; Modeline management
-
-(defun addrbook-summary-set-mode-line (card-number total-cards)
- "Update the mdoeline of the current summary buffer"
- ;; FIXME: this is ugly
- (when addrbook-summary-mode-line-string
- (setq mode-line-buffer-identification
- (list 24
- addrbook-summary-mode-line-string
- ": "
- (list 10
- (format "%d/%d" card-number total-cards))))))
-
-;;;; ** Major mode
-
-(defun addrbook-summary-mode ()
- "A major mode for the addressbook summary window
-
-Commands:
-\\{addrbook-summary-mode-map}"
- (interactive)
- (kill-all-local-variables)
- (setq addrbook-summary-mode-map (make-keymap))
- (define-key addrbook-summary-mode-map "n" 'addrbook-summary-next-contact)
- (define-key addrbook-summary-mode-map "p" 'addrbook-summary-previous-contact)
- (define-key addrbook-summary-mode-map (kbd "<down>")
'addrbook-summary-next-contact)
- (define-key addrbook-summary-mode-map (kbd "<up>")
'addrbook-summary-previous-contact)
- (define-key addrbook-summary-mode-map (kbd "RET")
'addrbook-summary-show-contact)
- (define-key addrbook-summary-mode-map "b" 'addrbook-bury)
- (define-key addrbook-summary-mode-map "q" 'addrbook-quit)
- (define-key addrbook-summary-mode-map "a" 'addrbook-create-card)
- (define-key addrbook-summary-mode-map "i" 'addrbook-import-vcard)
- (define-key addrbook-summary-mode-map "x" 'addrbook-export-vcard)
- (define-key addrbook-summary-mode-map "m" 'addrbook-send-email)
- (use-local-map addrbook-summary-mode-map)
- (setq mode-name "AddressBook Summary")
- (setq major-mode 'addrbook-summary-mode))
-
-;;;; * General commands (usable from all addressbook modes)
-
-(defun addrbook-send-email ()
- "Send an email to current contact"
- (interactive)
- (let* ((card (addrbook-get-card addrbook-current-card))
- (mail-addresses (vcard-ref card (list "email")))
- mail-names name i attr sendto-address letter)
- (dotimes (i (length mail-addresses))
- (let* ((attr (nth i mail-addresses))
- (attr-type (car (vcard-attr-get-parameter attr "type"))))
- (if (equal attr-type "internet")
- (setq mail-names (cons (list (car (vcard-attr-get-values attr))
- (+ ?a i))
- mail-names)))))
- (setq mail-names (reverse mail-names))
- (if (not mail-names)
- (message "Contact doesnt have a suitable smtp address")
- (if (equal (length mail-names) 1)
- (setq sendto-address (car (car mail-names)))
- (setq letter (addrbook-fast-selection mail-names "Select email address
to send mail to"))
- (dolist (name mail-names)
- (if (equal letter
- (cadr name))
- (setq sendto-address (car name)))))
- ;; Send the email
- (if sendto-address
- (compose-mail-other-frame (concat
- "\"" (addrbook-get-card-fn) "\""
- " <" sendto-address ">"))))))
-
-(defun addrbook-delete-card ()
- "Delete the current card"
- (interactive)
- (let ((buffer-read-only nil)
- (current-card addrbook-current-card)
- (prompt "Are you sure you want to delete current contact? "))
- (when (yes-or-no-p prompt)
- (if (equal current-card (- (length addrbook-cards) 1))
- (setq current-card (- (length addrbook-cards) 2)))
- (addrbook-remove-card addrbook-current-card)
- (add-to-list 'addrbook-modified-cards current-card)
- (if (equal (length addrbook-cards) 0)
- (addrbook-quit)
- (addrbook-contact-display-card current-card)))))
-
-(defun addrbook-create-card ()
- "Create a new card"
- (interactive)
- (let ((buffer-read-only nil)
- (new-card-index (addrbook-create-card-2)))
- (if new-card-index
- (addrbook-contact-display-card new-card-index))))
-
-(defun addrbook-create-card-2 ()
- "Create a new card with minimum identification properties and insert it
-into `addrbook-cards'.
-
-Return the index position of the new card"
- (let* (new-card
- (n-surname (read-from-minibuffer "Surname: "))
- (n-first-name (read-from-minibuffer "First name: "))
- (n-aka (read-from-minibuffer "AKA: "))
- (n-name-prefix (read-from-minibuffer "Name prefix: "))
- (n-name-suffix (read-from-minibuffer "Name suffix: "))
- (no-values (and (equal n-surname "")
- (equal n-first-name "")
- (equal n-aka "")
- (equal n-name-prefix "")
- (equal n-name-suffix "")))
- (new-card-index (length addrbook-cards)))
- (if no-values
- (progn
- (message "Contact not created")
- nil)
- ;; Create a new card
- (setq new-card (vcard-add-attribute new-card
- (cons (list "n")
- (list n-surname
- n-first-name
- n-aka
- n-name-prefix
- n-name-suffix))))
- (addrbook-set-card new-card-index new-card)
- (add-to-list 'addrbook-modified-cards new-card-index)
- new-card-index)))
-
-(defun addrbook-import-vcard (filename)
- "Import vCard from FILENAME and add it into our contact database and return
index card number."
- (interactive
- (list
- (expand-file-name
- (read-file-name "vCard file to import: "))))
-
- (let ((index nil)
- vcard)
- (addrbook-be-read-cards)
- (save-excursion
- (unwind-protect
- (if (and (setq index (length addrbook-cards))
- (setq vcard (vcard-parse-file filename)))
- (progn
- (addrbook-set-card index (car vcard))
- (add-to-list 'addrbook-modified-cards index))
- (error "Vcard import failed!"))
- ;; Just to be sure, call save-cards
- (addrbook-save-cards nil)))
- index))
-
-;; FIXME: does not work in contact mode
-(defun addrbook-export-vcard ()
- "Export current card data to a file."
- (interactive)
- (let* ((index (addrbook-summary-get-current-card))
- (fullname (addrbook-get-card-fn nil index ))
- (filename (read-file-name "Export vCard to file: " nil nil
- nil (concat fullname ".vcf"))))
- (addrbook-write-data-1 filename (addrbook-get-card index))
- (message "vCard exported")))
-
-(defun addrbook-write-data-1 (filename &optional vcard)
- "Save raw vCard formatted data into FILENAME.
-If optional VCARD parameter is not set, use `addrbook-current-card'."
- (let ((vcard (or vcard (addrbook-get-card addrbook-current-card))))
- (with-temp-file filename
- (vcard-insert vcard))))
-
-(defun addrbook-send-email ()
- "Send an email to current contact"
- (interactive)
- (let* ((card (addrbook-get-card addrbook-current-card))
- (mail-addresses (vcard-ref card (list "email")))
- mail-names name i attr sendto-address letter)
- (dotimes (i (length mail-addresses))
- (let* ((attr (nth i mail-addresses))
- (attr-type (car (vcard-attr-get-parameter attr "type"))))
- (if (equal attr-type "internet")
- (setq mail-names (cons (list (car (vcard-attr-get-values attr))
- (+ ?a i))
- mail-names)))))
- (setq mail-names (reverse mail-names))
- (if (not mail-names)
- (message "Contact doesnt have a suitable smtp address")
- (if (equal (length mail-names) 1)
- (setq sendto-address (car (car mail-names)))
- (setq letter (addrbook-fast-selection mail-names "Select email address
to send mail to"))
- (dolist (name mail-names)
- (if (equal letter
- (cadr name))
- (setq sendto-address (car name)))))
- ;; Send the email
- (if sendto-address
- (compose-mail-other-frame (concat
- "\"" (addrbook-get-card-fn) "\""
- " <" sendto-address ">"))))))
-
-(defun addrbook-save-cards (prefix)
- "Save cards into addrbook-file"
- (interactive "P")
- (if prefix
- (addrbook-export-card)
- ;; Save modified cards into addressbook-file
- (if (equal (length addrbook-modified-cards) 0)
- (message "addressbook not saved")
- (let ((i 0))
- (dotimes (i (length addrbook-cards))
- (when (member i addrbook-modified-cards)
- (addrbook-be-write-card i))))
- (setq addrbook-modified-cards nil)
- (set-buffer-modified-p nil)
- (message "addressbook saved"))))
-
-(defun addrbook-next-contact ()
- "Display the next card"
- (interactive)
- (let (buffer-read-only window-list win)
- (if (equal addrbook-current-card (- (length addrbook-cards) 1))
- (message "No more cards")
- (addrbook-contact-display-card (+ addrbook-current-card 1))
- (let ((summary-buffer (get-buffer addrbook-summary-buffer)))
- (when summary-buffer
- (setq window-list (get-buffer-window-list summary-buffer nil t))
- (dolist (win window-list)
- (with-selected-window (get-buffer-window summary-buffer t)
- (addrbook-summary-goto-contact addrbook-current-card nil))))))))
-
-(defun addrbook-previous-contact ()
- "Display the previous card"
- (interactive)
- (let (buffer-read-only)
- (if (equal addrbook-current-card 0)
- (message "First card")
- (addrbook-contact-display-card (- addrbook-current-card 1))
- (let ((summary-buffer (get-buffer addrbook-summary-buffer)))
- (when summary-buffer
- (setq window-list (get-buffer-window-list summary-buffer nil t))
- (dolist (win window-list)
- (with-selected-window (get-buffer-window summary-buffer t)
- (addrbook-summary-goto-contact addrbook-current-card nil))))))))
-
-(defun addrbook-quit ()
- "Exit the addressbook."
- (interactive)
- (if (and (not (equal (length addrbook-modified-cards) 0))
- (yes-or-no-p "Save addressbook? "))
- (addrbook-save-cards nil))
- (let ((contact-buffer (get-buffer addrbook-contact-buffer-name))
- (summary-buffer (get-buffer addrbook-summary-buffer-name))
- win window-list)
- (when summary-buffer
- ;; Delete windows (and possibly frames)
- (delete-windows-on summary-buffer)
- (kill-buffer summary-buffer))
- (when contact-buffer
- ;; Delete windows (and possibly frames)
- (delete-windows-on contact-buffer)
- (kill-buffer contact-buffer))))
-
-(defun addrbook-bury ()
- "Bury the addressbook buffer(s)."
- (interactive)
- (when (or (eq major-mode 'addrbook-summary-mode)
- (eq major-mode 'addrbook-contact-mode ))
- (bury-buffer)))
-
-(defun addrbook-export-card ()
- "Export current card data to a file"
- (interactive)
- (let ((filename (read-file-name "Export vCard to file: "))
- (card (addrbook-get-card addrbook-current-card)))
- (with-temp-file filename
- (vcard-insert card))
- (message "vCard exported")))
-
-;;;; * Backend management
-
-;;;; ** Customization and Variables
-
-(defcustom addrbook-backend
- 'addrbook-backend-simple
- "Backend to use for the addressbook.
-
-Currently there are two backends available: `addrbook-backend-simple' (simple
backend
-to store all contacts in one file) and `addrbook-backend-multiple' (that
stores one contact per file in
-a given directory"
- :type 'symbol)
-
-;;;; ** Utility functions
-
-(defun addrbook-make-params-explicit ()
- "Make unambiguous anonymous params explicit.
-
-It uses `addrbook-general-params' and the type parameter for each property
-defined in `addrbook-properties'"
- (let ((i 0))
- (dolist (card addrbook-cards)
- (dotimes (i (vcard-get-num-attributes card))
- (let* ((attr (vcard-get-attribute card i))
- (attr-name (vcard-attr-get-name attr))
- (attr-props (cdr (vcard-attr-get-proplist attr)))
- (property (addrbook-get-property attr-name))
- param
- (j 0))
- (dotimes (j (length attr-props))
- (let* ((param (nth j attr-props))
- (param-name (if (and param
- (listp param))
- (car param)
- nil))
- (param-value (if (and param
- (listp param))
- (cdr param)
- param)))
- ;; Search the param name in general-value
- (if (not param-name)
- (let* ((general-param (assoc param-value
addrbook-general-params))
- (general-param-name (if general-param (cadr
general-param)))
- (prop-types (addrbook-get-prop-parameter property
"type")))
- (if general-param-name
- (setq param-name general-param-name)
- (if (and prop-types
- (assoc param-value prop-types))
- (setq param-name "type")))
- (if param-name
- (setcar (nthcdr j attr-props) (cons param-name
param-value))))))))))))
-
-;;;; ** API
-
-(defun addrbook-be-read-cards ()
- "Read cards from an addressbook backend.
-
-This function stores the retrieved vCard information in
-`addrbook-cards'."
- (cond
- ((equal addrbook-backend 'addrbook-backend-simple)
- (addrbook-be-simple-read-cards))
- ((equal addrbook-backend 'addrbook-backend-multiple)
- (addrbook-be-multiple-read-cards))
- (t
- (error "No valid addressbook backend selected.")))
- (when addrbook-cards
- (addrbook-make-params-explicit)
- t))
-
-(defun addrbook-be-write-card (card-id)
- "Write the CARD-ID card to the appropiate backend."
- (cond
- ((equal addrbook-backend 'addrbook-backend-simple)
- (addrbook-be-simple-write-card card-id))
- ((equal addrbook-backend 'addrbook-backend-multiple)
- (addrbook-be-multiple-write-card card-id))
- (t
- (error "No valid addressbook backend selected."))))
-
-(defun addrbook-be-delete-card (card-id)
- "Delete the CARD-ID card from the appropiate backend."
- (cond
- ((equal addrbook-backend 'addrbook-backend-simple)
- (addrbook-be-simple-delete-card card-id))
- ((equal addrbook-backend 'addrbook-backend-multiple)
- (addrbook-be-multiple-delete-card card-id))
- (t
- (error "No valid addressbook backend selected."))))
-
-;;;; ** Simple backend
-
-(defcustom addrbook-file "~/.addressbook"
- "File with stored addresses"
- :type 'file
- :group 'addrbook)
-
-(defun addrbook-be-simple-read-cards ()
- "Read cards from addressbook file"
- (with-temp-buffer
- (insert-file-contents addrbook-file)
- (setq addrbook-cards (vcard-parse-region (point-min)
- (point-max)))))
-
-(defun addrbook-be-simple-write-card (card-id)
- "Write cards information to `addrbook-file', discarding any
-previous content."
- (with-temp-file addrbook-file
- (dotimes (i (length addrbook-cards))
- (let ((card (addrbook-get-card i)))
- (vcard-insert card)
- (if (not (equal i (- (length addrbook-cards) 1)))
- (insert "\n\n"))))))
-
-;;;; * Utility functions
-
-(defun addrbook-list-to-csv (list)
- (let ((result "")
- i)
- (dotimes (i (length list))
- (setq result (concat result (nth i list)))
- (if (not (equal i (- (length list) 1)))
- (setq result (concat result ","))))
- result))
-
-(defun addrbook-open ()
- "Open the addressbook"
- (or (addrbook-be-read-cards)
- (addrbook-create-card-2)))
-
-(defun addrbook-get-text-property-line (prop)
- "Return the value of text property PROP in the nearest position on current
line
-that has PROP defined as a text property"
- (let ((current-point (get-text-property (point) prop))
- (next-point-with-prop (next-single-property-change
- (point) prop nil (line-end-position)))
- (previous-point-with-prop (previous-single-property-change
- (point) prop nil
(line-beginning-position))))
- (or current-point
- (if next-point-with-prop
- (get-text-property next-point-with-prop prop)
- (get-text-property previous-point-with-prop prop)))))
-
-(defun addrbook-erase-tagged-region (tag)
- "Erase the region tagged with the same TAG value"
- (let ((begin-pos (previous-single-property-change (point) tag))
- (end-pos (next-single-property-change (point) tag)))
- (if (equal (point) (point-min))
- (setq begin-pos (point-min))
- (if (not (equal (get-text-property (point) tag)
- (get-text-property (- (point) 1) tag)))
- (setq begin-pos (point))))
- (if (equal (point) (point-max))
- (setq end-pos (point-max))
- (if (not (equal (get-text-property (point) tag)
- (get-text-property (+ (point) 1) tag)))
- (setq end-pos (+ point 1))))
- (cond ((and begin-pos end-pos)
- (delete-region begin-pos end-pos))
- ((and begin-pos (not end-pos))
- (delete-region begin-pos (point-max)))
- ((and (not begin-pos) end-pos)
- (delete-region (point-min) end-pos)))))
-
-(defun addrbook-sort-cards ()
- "Sort `addrbook-cards' using the `addrbook-field-for-sort' field"
- (setq addrbook-cards
- (sort addrbook-cards
- (lambda (card1 card2)
- (let* ((card1-n (vcard-get-named-attribute card1 "n"))
- (card2-n (vcard-get-named-attribute card2 "n"))
- (n-prop (addrbook-get-property "n"))
- (n-fields (addrbook-get-prop-fields n-prop))
- (field-index (addrbook-get-prop-index n-fields
addrbook-field-for-sort))
- (card1-n-field (nth field-index (vcard-attr-get-values
card1-n)))
- (card2-n-field (nth field-index (vcard-attr-get-values
card2-n))))
- (cond
- ((and (null card1-n-field) (not (null card2-n-field)))
- t)
- ((and (not (null card1-n-field)) (null card2-n-field))
- nil)
- ((and (null card1-n-field) (null card2-n-field))
- t)
- (t
- (string-lessp card1-n-field card2-n-field))))))))
-
-;;;; * Fast selection
-
-(defun addrbook-fast-selection (names prompt)
- "Fast group tag selection with single keys.
-
-NAMES is an association list of the form:
-
- ((\"NAME1\" char1) ...)
-
-Each character should identify only one name."
- ;; Adapted from `org-fast-tag-selection' in org.el by Carsten Dominic
- ;; Thanks Carsten! ;P
- (let* ((maxlen (apply 'max (mapcar (lambda (name)
- (string-width (car name))) names)))
- (buf (current-buffer))
- (fwidth (+ maxlen 3 1 3))
- (ncol (/ (- (window-width) 4) fwidth))
- name count result char i key-list)
- (save-window-excursion
- (set-buffer (get-buffer-create " *AddrBook Groups*"))
- (delete-other-windows)
- (split-window-vertically)
- (switch-to-buffer-other-window (get-buffer-create " *AddrBook Groups*"))
- (erase-buffer)
- (insert prompt ":")
- (insert "\n\n")
- (setq count 0)
- (while (setq name (pop names))
- (setq key-list (cons (cadr name) key-list))
- (insert "[" (cadr name) "] "
- (car name)
- (make-string (- fwidth 4 (length (car name))) ?\ ))
- (when (= (setq count (+ count 1)) ncol)
- (insert "\n")
- (setq count 0)))
- (goto-char (point-min))
- (if (fboundp 'fit-window-to-buffer)
- (fit-window-to-buffer))
- (catch 'exit
- (while t
- (message "[a-z0-9...]: Select entry [RET]: Exit")
- (setq char (let ((inhibit-quit t)) (read-char-exclusive)))
- (cond
- ((= char ?\r)
- (setq result nil)
- (throw 'exit t))
- ((member char key-list)
- (setq result char)
- (throw 'exit t)))))
- result)))
-
-(defun addrbook-select-type (attr-name)
- (let* ((property (addrbook-get-property attr-name))
- (prop-types (addrbook-get-prop-parameter property "type")))
- (let (type-names type letter result)
- (dolist (type prop-types)
- (setq type-names
- (cons (cdr type) type-names)))
- (setq type-names (reverse type-names))
- (setq letter (addrbook-fast-selection type-names "Select attribute
type"))
- (if letter
- (dolist (type type-names)
- (if (equal letter
- (cadr type))
- (setq result (car type)))))
- result)))
-
-(defun addrbook-select-non-existing-type (attr)
- (let* ((attr-name (vcard-attr-get-name attr))
- (property (addrbook-get-property attr-name))
- (prop-types (addrbook-get-prop-parameter property "type"))
- (attr-types (vcard-attr-get-parameter attr "type")))
- (let (type-names type letter result)
- (dolist (type prop-types)
- (if (not (member (car type) attr-types))
- (setq type-names
- (cons (cdr type) type-names))))
- (setq type-names (reverse type-names))
- (setq letter (addrbook-fast-selection type-names "Select attribute
type"))
- (if letter
- (dolist (type type-names)
- (if (equal letter
- (cadr type))
- (setq result (car type)))))
- result)))
-
-(defun addrbook-select-existing-type (attr)
- (let* ((attr-name (vcard-attr-get-name attr))
- (property (addrbook-get-property attr-name))
- (prop-types (addrbook-get-prop-parameter property "type"))
- (attr-types (vcard-attr-get-parameter attr "type")))
- (let (type-names type letter result)
- (dolist (type prop-types)
- (if (member (car type) attr-types)
- (setq type-names
- (cons (cdr type) type-names))))
- (setq type-names (reverse type-names))
- (setq letter (addrbook-fast-selection type-names "Select attribute
type"))
- (if letter
- (dolist (type type-names)
- (if (equal letter
- (cadr type))
- (setq result (car type)))))
- result)))
-
-(defun addrbook-select-group ()
- "Select a group interactively and return its symbol"
- (let (names group group-elt letter result)
- ;; Build the names list
- (dolist (group-elt addrbook-properties)
- (setq names
- (cons (list (addrbook-get-group-name group-elt)
- (addrbook-get-group-letter group-elt))
- names)))
- (setq names (reverse names))
- ;; Call the fast menu function to get the desired group
- (setq letter (addrbook-fast-selection names "Select group"))
- (dolist (group-elt addrbook-properties)
- (if (and (addrbook-get-group-letter group-elt)
- (equal letter (addrbook-get-group-letter group-elt)))
- (setq result (addrbook-get-group-symbol group-elt))))
- result))
-
-(defun addrbook-select-property (group-symbol)
- "Select a property interactively from GROUP and return its name"
- (let* ((group (addrbook-get-group group-symbol))
- (group-props (addrbook-get-group-props group))
- names attr attr-elt letter result)
- ;; Build the names list
- (dolist (prop group-props)
- (if (and (not (member (addrbook-get-prop-name prop)
addrbook-required-attrs))
- (addrbook-get-prop-letter prop))
- (setq names
- (cons (list (addrbook-get-prop-title prop)
- (addrbook-get-prop-letter prop))
- names))))
- (setq names (reverse names))
- ;; Call the fast menu function to get the desired group
- (setq letter (addrbook-fast-selection names "Select property"))
- (dolist (prop group-props)
- (if (and (addrbook-get-prop-letter prop)
- (equal letter (addrbook-get-prop-letter prop)))
- (setq result (addrbook-get-prop-name prop))))
- result))
-
-(defun addrbook-select-field (group-symbol prop-name)
- "Select a field interactively from PROP-NAME"
- (let* ((group (addrbook-get-group group-symbol))
- (group-props (addrbook-get-group-props group))
- (property (assoc prop-name group-props))
- (prop-fields (addrbook-get-prop-fields-list property))
- letter field result i)
- (setq letter (addrbook-fast-selection prop-fields "Select property field"))
- (dotimes (i (length prop-fields))
- (setq field (nth i prop-fields))
- (if (equal letter (addrbook-get-prop-field-letter field))
- (setq result i)))
- result))
-
-;;;; ** Search functions
-
-(defun addrbook-attr-matches-p (attr regexp)
- (let (result value
- (attr-values (vcard-attr-get-values attr)))
- (if (listp attr-values)
- (dolist (value attr-values)
- (if (string-match regexp value)
- (setq result t)))
- (setq result (string-match regexp attr-values)))
- result))
-
-(defun addrbook-search-cards (regexp &optional properties)
- "Search for REGEXP in card data and return a list with the indexes
-of matching cards.
-
-PROPERTIES is a list of property names.
-If PROPERTIES is specified and non-nil, the search is performed only in those
-attributes."
- (let (card prop attr card-index attr-index result)
- (dotimes (card-index (length addrbook-cards))
- (setq card (addrbook-get-card card-index))
- (dotimes (attr-index (vcard-get-num-attributes card))
- (setq attr (vcard-get-attribute card attr-index))
- (if (and (or (not properties)
- (member (vcard-attr-get-name attr) properties))
- (addrbook-attr-matches-p attr regexp))
- (add-to-list 'result card-index))))
- (reverse result)))
-
-;;;; * Entry points to the addressbook
-
-;;;###autoload
-(defun addressbook ()
- "Open the addressbook"
- (interactive)
- (if (and addrbook-force-addressbook-creation
- (not (file-exists-p addrbook-file)))
- (with-temp-file addrbook-file))
- (catch 'exit
- (let ((buffer (get-buffer addrbook-contact-buffer-name)))
- (if (not buffer)
- (let ((show-card-index 0)
- (user-input (if addrbook-ask-for-search
- (read-from-minibuffer "Search for contact [RET
goes to the summary]: ")
- "")))
- (unless (addrbook-open)
- (throw 'exit t))
- (addrbook-sort-cards)
- (if (not (equal user-input ""))
- (let ((found-cards (addrbook-search-cards user-input)))
- (if found-cards
- (setq show-card-index (car found-cards))
- (message "No contacts found")
- (throw 'exit t))
- ;; Goto the first card with matched data
- (addrbook-create-contact-buffer)
- (addrbook-contact-display-card show-card-index)
- (setq addrbook-modified-cards nil)
- (switch-to-buffer-other-window (get-buffer
addrbook-contact-buffer-name))
- (setq buffer-read-only t)
- (setq addrbook-buffer buffer))
- ;; Goto the summary
- (addrbook-summary))))
- (addrbook-show-summary))))
-
-
-;;;###autoload
-(defun addressbook-create ()
- "Create a new contact into the addressbook and save it"
- (interactive)
- (addrbook-be-read-cards)
- (let ((new-card-index (addrbook-create-card-2)))
- (if new-card-index
- (addrbook-save-cards nil))))
-
-
-(provide 'addressbook)
-
-;;; addrbook.el ends here
Index: addressbook.texi
===================================================================
RCS file: addressbook.texi
diff -N addressbook.texi
--- addressbook.texi 4 May 2007 22:20:03 -0000 1.1.1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,140 +0,0 @@
-\input texinfo
address@hidden %**start of header
address@hidden addressbook.info
address@hidden Addressbook Manual
-
address@hidden VERSION 0.1
address@hidden DATE May 2007
-
address@hidden Emacs
address@hidden
-* Addressbook: (addressbook). Simple addressbook for Emacs
address@hidden direntry
-
address@hidden Version and Contact Info
address@hidden MAINTAINERSITE
@uref{http://www.emacswiki.org/cgi-bin/wiki/AddressBook}
address@hidden AUTHOR Jose E. Marchesi
address@hidden MAINTAINER Jose E. Marchesi
address@hidden MAINTAINEREMAIL @email{jemarch at gnu dot org}
address@hidden MAINTAINERCONTACT @uref{mailto:jemarch at gnu dot org, contact
the maintainer}
address@hidden %**end of header
address@hidden
-
address@hidden
-This manual is for Addressbook (version @value{VERSION}).
-
-Copyright @copyright{} 2007 Jose E. Marchesi
-
address@hidden
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.1 or
-any later version published by the Free Software Foundation; with no
-Invariant Sections.
address@hidden quotation
address@hidden copying
-
address@hidden
address@hidden Addressbook Manual
-
address@hidden Release @value{VERSION}
address@hidden by Jose E. Marchesi
-
address@hidden
address@hidden 0pt plus 1filll
address@hidden
address@hidden titlepage
-
address@hidden
-
address@hidden
-
address@hidden Top, Summary, (dir), (dir)
address@hidden Addressbook Manual
-
address@hidden
address@hidden ifnottex
-
address@hidden
-* Summary:: Brief summary of the
addressbook
-* Getting the program:: Downloading the addressbook
-* Installation:: How to install the adressbook
-* Configuration::
-* Contacts:: The addressbook stores data
about contacts
-* Accessing the addressbook::
-* Importing and exporting contact data::
address@hidden menu
-
address@hidden Summary, Getting the program, Top, Top
address@hidden Summary
-
-AddressBook is a simple vCard based addressbook for Emacs.
-
-It is similar to the insidious big brother database, but instead of
-using a custom format for data storage, it uses the standard vCard
-format to maintain contacts data.
-
address@hidden Getting the program, Installation, Summary, Top
address@hidden Getting the program
-
-You need the following files in order to run the addressbook:
-
address@hidden @bullet
address@hidden
-addressbook.el
address@hidden://es.gnu.org/~jemarch/downloads/addrbook/addressbook.el}
address@hidden
-A modified version of Noah Friedman's vcard.el
address@hidden://es.gnu.org/~jemarch/downloads/addrbook/vcard.el}
address@hidden itemize
-
-Note that since the addressbook is under heavy development and it has
-not released yet, those files may change (even several times in a
-day). You can use the CVS Id tag to determine if you are downloading a
-new version.
-
-
address@hidden Installation, Configuration, Getting the program, Top
address@hidden Installation
-
-Make @file{addrbook.el} and @file{vcard.el} loadable to your emacs (put the
-files in a directory contained in your @code{load-path}).
-
-You can customize the addressbook using the customize interface. If
-you dont like to use customize, take a look into the sources for
-interesting variables.
-
-The most important variable to set is @code{addrbook-file}, that contain
-the file where you store your contacts (a collection of vCards). It
-defaults to @file{~/.addressbook}.
-
address@hidden Configuration, Contacts, Installation, Top
address@hidden Configuration
-
address@hidden Contacts, Accessing the addressbook, Configuration, Top
address@hidden Contacts
-
-The addressbook manages a collection of contact data.
-
address@hidden Accessing the addressbook, Importing and exporting contact data,
Contacts, Top
address@hidden Accessing the addressbook
-
-There are several ways to access the addressbook:
-
address@hidden @bullet
address@hidden
-Opening the interactive interface calling the interactive function
@code{addressbook}
address@hidden
-Inserting a new contact without open the interactive interface calling
-the interactive function @code{addressbook-create}
address@hidden
-Using the addressbook API (see FIXME:)
address@hidden
-From any other application that uses the addressbook API (such as a MUA).
address@hidden itemize
-
-Next sections of this manual discuss the interactive interface.
-
address@hidden Importing and exporting contact data, , Accessing the
addressbook, Top
address@hidden Importing and exporting contact data
-
address@hidden
Index: uuid.el
===================================================================
RCS file: uuid.el
diff -N uuid.el
--- uuid.el 29 May 2007 23:11:41 -0000 1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,484 +0,0 @@
-;;;; uuid.el --- Universal Unique Identifiers
-
-;; Copyright (C) 2007 Jose E. Marchesi
-
-;; Maintainer: Jose E. Marchesi
-;; Keywords: standards
-
-;; $Id: uuid.el,v 1.1 2007/05/29 23:11:41 jemarch Exp $
-
-;; This file is NOT part of GNU Emacs.
-
-;; 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; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
-
-;;;; Commentary
-
-;; This file contain an implementation of the ITU X.667 Recommendation
-;; for the generation of Universal Unique Identifiers (also known as
-;; Globally Unique Identifiers or GUIDs).
-;;
-;; Each UUID is a hexadecimal-coded ascii sequence composed by the
-;; following fields (separated by the ascii hypen-minus, 45 character,
-;; except between the VariantAndClockSeqHigh and ClockSeqLow):
-;;
-;; - TimeLow (4 octects => 8 hexadecimal digits)
-;; - TimeMid (2 octects => 4 hexadecimal digits)
-;; - VersionAndTimeHigh (2 octects => 4 hexadecimal digits)
-;; - VariantAndClockSeqHigh (1 octect => 2 hexadecimal digits)
-;; - ClockSeqLow (1 octect => 2 hexadecimal digits)
-;; - Node (6 octects => 12 hexadecimal digits)
-;;
-;; For example:
-;;
-;; 00000000-0000-0000-0000-000000000000
-;;
-;; There are three standarized ways to generate the values of those
-;; fields:
-;;
-;; - time-based
-;; - random-based
-;; - name-based
-;;
-;; You can specify the generation semantics to use via the optional
-;; `uuid-type' parameter to `uuid-generate'. The default method is the
-;; time-based one.
-;;
-;; Note that, according to the ITU recommendation, uuid generators
-;; should generate lower-case letters in hexadecimal encoding. On the
-;; other hand, it is recommended for uuid consumers to be
-;; case-insensitive regarding alphabetic characters in hex
-;; strings. This implementation follows both recommendations.
-
-;;;; Code:
-
-(require 'calc)
-
-(defgroup uuid nil
- "Universal Unique Identifiers"
- :group 'development
- :link '(url-link
"http://www.emacswiki.org/cgi-bin/wiki/UniversalUniqueIdentifiers"))
-
-(defcustom uuid-ifconfig-program
- "/sbin/ifconfig"
- "Location of the `ifconfig' program to determine the MAC
-address to use in the time-based method. If it is set to nil,
-then a standarized alternative random method is used."
- :group 'uuid)
-
-(defvar uuid-hexoctect-regexp
- "[0-9a-fA-F][0-9a-fA-F]"
- "Regexp that matches the hexadecimal representation of an octect using
lower-case letters")
-
-(defvar uuid-time-low-regexp
- (concat uuid-hexoctect-regexp
- uuid-hexoctect-regexp
- uuid-hexoctect-regexp
- uuid-hexoctect-regexp)
- "Regexp that matches the TimeLow field of a uuid")
-
-(defvar uuid-time-mid-regexp
- (concat uuid-hexoctect-regexp
- uuid-hexoctect-regexp)
- "Regexp that matches the TimeMid field of a uuid")
-
-(defvar uuid-version-and-time-high-regexp
- (concat uuid-hexoctect-regexp
- uuid-hexoctect-regexp)
- "Regexp that matches the VersionAndTimeHigh field of a uuid")
-
-(defvar uuid-variant-and-clock-seqhigh-regexp
- uuid-hexoctect-regexp
- "Regexp that matches the VariantAndClockSeqHigh field of a uuid")
-
-(defvar uuid-clock-seq-low-regexp
- uuid-hexoctect-regexp
- "Regexp that matches the ClockSeqLow field of a uuid")
-
-(defvar uuid-node-regexp
- (concat uuid-hexoctect-regexp
- uuid-hexoctect-regexp
- uuid-hexoctect-regexp
- uuid-hexoctect-regexp
- uuid-hexoctect-regexp
- uuid-hexoctect-regexp)
- "Regexp that matches the Node field of a uuid")
-
-(defvar uuid-regexp
- (concat "^"
- uuid-time-low-regexp
- "-"
- uuid-time-mid-regexp
- "-"
- uuid-version-and-time-high-regexp
- "-"
- uuid-variant-and-clock-seqhigh-regexp
- uuid-clock-seq-low-regexp
- "-"
- uuid-node-regexp
- "$")
- "Regexp that matches a uuid hexadecimal-coded value")
-
-(defvar uuid-time-based-version-hex
- "1"
- "Hexadecimal string encoding the time-based version of a uuid")
-
-(defvar uuid-dce-security-version-hex
- "2"
- "Hexadecimal string encoding the reserved DCE security version of a uuid")
-
-(defvar uuid-name-based-md5-version-hex
- "3"
- "Hexadecimal string encoding the name-based version with MD5 hash of a uuid")
-
-(defvar uuid-name-based-sha1-version-hex
- "4"
- "Hexadecimal string encoding the name-based version with SHA-1 hash of a
uuid")
-
-(defvar uuid-random-number-based-version-hex
- "5"
- "Hexadecimal string encoding the random-number-based version of a uuid")
-
-(defvar uuid-namespace-dns
- ;; 6BA7B810
- (list #x6BA7 #xB810
- #x9DAD
- #x11D1
- #x80B4 #x00C0 #x4FD4 #x30C8)
- "ITU X.667 recommended namespace for DNS names")
-
-(defvar uuid-namespace-url
- (list #x6BA7 #xB811
- #x9DAD
- #x11D1
- #x80B4 #x00C0 #x4FD4 #x30C8)
- "ITU X.667 recommended namespace for URL names")
-
-(defvar uuid-namespace-oid
- (list #x6BA7 #xB812
- #x9DAD
- #x11D1
- #x80B4 #x00C0 #x4FD4 #x30C8)
- "ITU X.667 recommended namespace for OID names")
-
-(defvar uuid-namespace-x500
- (list #x6BA7 #xB814
- #x9DAD
- #x11D1
- #x80B4 #x00C0 #x4FD4 #x30C8)
- "ITU X.667 recommended namespace for directory names")
-
-;;;###autoload
-(defun uuid-generate (&optional uuid-type namespace name)
- "Generate and return a new universal unique identifier according
-with the ITU X.667 Recommendation for the generation of Universal Unique
-Identifiers.
-
-If specified, UUID-TYPE identifies the desired uuid type: `time',
-`name-md5', `name-sha1' or `random'. It defaults to `time'.
-
-If specified and `name-md5' or `name-sha1' is used, NAMESPACE is
-the namespace to use (see `uuid-namespace-XXX' variables).
-
-If specified, NAME is the name for the `name-md5' or `name-sha1'
-method."
- (if (not uuid-type)
- (setq uuid-type 'time))
- (cond
- ((equal uuid-type 'time)
- (uuid-generate-time-based))
- ((or (equal uuid-type 'name-md5)
- (equal uuid-type 'name-sha1))
- (when (not (and namespace name))
- (error "You must specify values for both NAMESPACE and NAME"))
- (uuid-generate-name-based uuid-type namespace name))
- ((equal uuid-type 'random)
- (uuid-generate-random-based))
- (t
- (error "Wrong generation algorithm.\
- Valid ones are 'time 'name-md5 'name-sha1 or 'random"))))
-
-(defun uuid-generate-name-based (type namespace name)
- "Generate and return a name-based uuid."
- (let (time-low
- time-mid
- version-and-time-high
- clock-seq-low
- variant-and-clock-seq-high
- node
- hash
- (name-sequence "")
- i)
- ;; Convert the name to a canonical sequence of octets (as defined by the
standards or conventions of its
- ;; name space).
- (dotimes (i (length name))
- (setq name-sequence
- (concat name-sequence (format "%.2x" (aref name i)))))
- ;; Compute the 16-octet hash value of the name space identifier
- ;; concatenated with the name, using the hash function specified
- ;; in 14.2 or 14.3. The numbering of the octets in the hash value
- ;; is from 0 to 15, as specified in IETF RFC 1321 (for MD5) and as
- ;; specified in FIPS PUB 180-2 for SHA-1.
- (cond
- ((equal type 'name-sha1)
- (error "Name-based type method sha1 not implemented"))
- ((equal type 'name-md5)
- (setq hash (md5 (concat (uuid-namespace-to-string namespace)
- name-sequence))))
- (t
- (error "Wrong name-based type")))
-
- ;; Set octets 3 through 0 of the "TimeLow" field to octets 3
- ;; through 0 of the hash value.
- (setq time-low
- (concat (format "%.2x" 0)
- (substring hash 26)))
- ;; Set octets 1 and 0 of the "TimeMid" field to octets 5 and 4 of
- ;; the hash value.
- (setq time-mid
- (substring hash 22 25))
- ;; Set octets 1 and 0 of the "VersionAndTimeHigh" field to octets
- ;; 7 and 6 of the hash value.
-
- ;; Overwrite the four most significant bits (bits 15 through 12)
- ;; of the "VersionAndTimeHigh" field with the four-bit version
- ;; number from Table 3 of 12.2 for the hash function that was
- ;; used.
-
- ;; Set the "VariantAndClockSeqHigh" field to octet 8 of the hash
- ;; value.
-
- ;; Overwrite the two most significant bits (bits 7 and 6) of the
- ;; "VariantAndClockSeqHigh" field with 1 and 0, respectively.
-
- ;; Set the "ClockSeqLow" field to octet 9 of the hash value.
-
- ;; Set octets 5 through 0 of the "Node" field to octets 15 through
- ;; 10 of the hash value.
- (concat time-low "-"
- time-mid "-"
- version-and-time-high "-"
- variant-and-clock-seq-high
- clock-seq-low "-"
- node)))
-
-(defun uuid-generate-random-based ()
- "Generate and return a random-based uuid"
- (let (time-low
- time-mid
- version-and-time-high
- clock-seq-low
- variant-and-clock-seq-high
- node)
- ;; Set the two most significant bits (bits 7 and 6) of the
- ;; "VariantAndClockSeqHigh" field to 1 and 0, respectively.
- (setq variant-and-clock-seq-high
- (format "%.2x" (logior #x80 (logand #xBF (random (expt 2 8))))))
- ;; Set the four most significant bits (bits 15 through 12) of the
- ;; "VersionAndTimeHigh" field to the four-bit version number
- ;; specified in 12.2.
- (setq version-and-time-high
- (concat uuid-random-number-based-version-hex
- (format "%.3x" (random (expt 2 12)))))
- ;; Set all the other bits of the UUID to randomly (or
- ;; pseudo-randomly) generated values.
- (setq time-low
- (concat (format "%.4x" (random (expt 2 16)))
- (format "%.4x" (random (expt 2 16)))))
- (setq time-mid
- (format "%.4x" (random (expt 2 16))))
- (setq clock-seq-low
- (format "%.2x" (random (expt 2 8))))
- (setq node
- (concat
- (format "%.4x" (random (expt 2 16)))
- (format "%.4x" (random (expt 2 16)))
- (format "%.4x" (random (expt 2 16)))))
- (concat time-low "-"
- time-mid "-"
- version-and-time-high "-"
- variant-and-clock-seq-high
- clock-seq-low "-"
- node)))
-
-(defun uuid-generate-time-based ()
- "Generate and return a time-based uuid"
- ;; Determine the values for the UTC-based Time and the Clock
- ;; Sequence to be used in the UUID, as specified in 12.3 and 12.4.
- (let (time
- clock-sequence
- time-low time-mid version-and-time-high clock-seq-low
- variant-and-clock-seq-high
- node)
- ;; For the purposes of this algorithm, consider Time to be a
- ;; 60-bit unsigned integer and the Clock Sequence to be a 14-bit
- ;; unsigned integer.
- (setq time (uuid-generate-time))
- (setq clock-sequence (uuid-generate-clock-sequence))
- ;; Set the "TimeLow" field equal to the least significant 32 bits
- ;; (bits 31 through 0) of Time in the same order of significance.
- (setq time-low
- (concat
- (format "%.3x" (logand #x000FF (nth 1 time)))
- (format "%.5x" (nth 2 time))))
- ;; Set the "TimeMid" field equal to bits 47 through 32 from the
- ;; Time in the same order of significance.
- (setq time-mid
- (concat
- (format "%.2x" (logand #x0007F (nth 0 time)))
- (format "%.2x" (ash (nth 1 time) -12))))
-
- ;; Set the 12 least significant bits (bits 11 through 0) of the
- ;; "VersionAndTimeHigh" field equal to bits 59 through 48 from
- ;; Time in the same order of significance.
- ;; Set the four most significant bits (bits 15 through 12) of the
- ;; "VersionAndTimeHigh" field to the four-bit version number
- ;; specified in 12.2.
- (setq version-and-time-high
- (concat uuid-time-based-version-hex
- (format "%.3x" (ash (nth 0 time) -7))))
- ;; Set the "ClockSeqLow" field to the eight least significant bits
- ;; (bits 7 through 0) of the Clock Sequence in the same order of
- ;; significance.
- (setq clock-seq-low
- (format "%.2x" (logand #x000F clock-sequence)))
- ;; Set the six least significant bits (bits 5 through 0) of the
- ;; "VariantAndClockSeqHigh" field to the six most significant bits
- ;; (bits 13 through 8) of the Clock Sequence in the same order of
- ;; significance.
- ;; Set the two most significant bits (bits 7 and 6) of the
- ;; "VariantAndClockSeqHigh" clock to one and zero, respectively.
- (setq variant-and-clock-seq-high
- (format "%.2x" (logand #x00BF (ash clock-sequence -9))))
- ;; Set the node field to the 48-bit MAC address in the same order
- ;; of significance as the address.
- (let ((mac-address (uuid-get-mac-address)))
- (if mac-address
- (setq node (uuid-format-mac-address mac-address))
- ;; Use a random number
- (setq node
- (concat
- (format "%.4x" (random (expt 2 16)))
- (format "%.4x" (random (expt 2 16)))
- (format "%.4x" (random (expt 2 16)))))))
- (concat time-low "-"
- time-mid "-"
- version-and-time-high "-"
- variant-and-clock-seq-high
- clock-seq-low "-"
- node)))
-
-(defun uuid-generate-time ()
- "Return the number of 100 nanosecond intervals of UTC since the beginning
-of the Gregorian calendar (00:00:00, 15 October 1582).
-
-The returned value is a list:
-
- (TIME-HIGH TIME-MID TIME-LOW)
-
-with three 20-bits unsigned integers that conform a 60-bit
-unsigned integer.
-
-NOTE: we use a resolution of seconds in this code."
- ;; 100 ns intervals offset between Gregorian beginning (00:00:00, 15
- ;; October 1582) and the epoch (00:00:00, 1 January 1970):
- ;; 0x1B21DD213814000
-
- ;; Operate with 20-bit numbers (GNU Emacs assures integers are
- ;; at least 29 bits wide and 20/4 = 5)
- (let ((greg-epoch-offset-high #x1B21D)
- (greg-epoch-offset-mid #xD2138)
- (greg-epoch-offset-low #x14000)
- since-epoch-high since-epoch-mid since-epoch-low
- (current-time (current-time)))
- ;; Calculate time since the epoch in seconds
- (setq since-epoch-time-low (+ (nth 1 current-time)
- (logand #xF (nth 0 current-time))))
- (setq since-epoch-time-mid (ash (nth 0 current-time) -4))
- (setq since-epoch-time-high (ash (nth 2 current-time) -9))
- ;; TODO: since-epoch-time * 10.000.000
- ;; TODO: Finishme
- (list since-epoch-time-high
- since-epoch-time-mid
- since-epoch-time-low)))
-
-(defun uuid-generate-clock-sequence ()
- "Return a clock sequence number that should be interpreted
-as a 14-bit unsigned integer.
-
-NOTE: Since this implementation does not store any state, we
-follow the ITU recommendation in using a pseudo-random number
-that is _not_ derivated from the Node."
- (random (expt 2 14)))
-
-(defun uuid-format-mac-address (mac-addr)
- "Format MAC-ADDR (a valid MAC address) to a raw hex format"
- (downcase (replace-regexp-in-string ":" "" mac-addr)))
-
-(defun uuid-get-mac-address ()
- "Return a suitable MAC address from a network card in the host computer.
-If no MAC address is found, then return nil."
- (when (file-executable-p uuid-ifconfig-program)
- (save-excursion
- (with-temp-buffer
- (call-process uuid-ifconfig-program nil t nil "-a")
- (goto-char (point-min))
- (when (re-search-forward "HWaddr " nil t)
- (re-search-forward (concat uuid-hexoctect-regexp
- ":"
- uuid-hexoctect-regexp
- ":"
- uuid-hexoctect-regexp
- ":"
- uuid-hexoctect-regexp
- ":"
- uuid-hexoctect-regexp
- ":"
- uuid-hexoctect-regexp) nil t)
- (buffer-substring (match-beginning 0)
- (match-end 0)))))))
-
-(defun uuid-namespace-to-string (namespace)
- "Return the hex string representation of NAMESPACE"
- (concat
- (format "%.4x" (nth 0 namespace))
- (format "%.4x" (nth 1 namespace))
- (format "%.4x" (nth 2 namespace))
- (format "%.4x" (nth 3 namespace))
- (format "%.4x" (nth 4 namespace))
- (format "%.4x" (nth 5 namespace))
- (format "%.4x" (nth 6 namespace))
- (format "%.4x" (nth 7 namespace))))
-
-;;;###autoload
-(defun uuidp (uuid)
- "Return t if UUID is a valid uuid"
- (save-match-data
- (when (string-match uuid-regexp uuid)
- t)))
-
-;;;###autoload
-(defun uuid-lessp (uuid1 uuid2)
- "Return t if UUID1 is lesser than UUID2."
- (string-lessp uuid1 uuid2))
-
-;;;###autoload
-(defun uuid-equal (uuid1 uuid2)
- "Return t if UUID1 and UUID2 are the same uuid."
- (string-equal uuid1 uuid2))
-
-(provide 'uuid)
-
-;;; uuid.el ends here
Index: vcard.el
===================================================================
RCS file: vcard.el
diff -N vcard.el
--- vcard.el 31 May 2007 14:06:59 -0000 1.3
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,727 +0,0 @@
-;;; vcard.el --- vcard parsing routines
-
-;; Copyright (C) 1997, 1999, 2000 Noah S. Friedman
-;; Copyright (C) 2007 Jose E. Marchesi
-
-;; Author: Noah Friedman <address@hidden>
-;; Maintainer: address@hidden
-;; Keywords: vcard, mail, news
-;; Created: 1997-09-27
-
-;; $Id: vcard.el,v 1.3 2007/05/31 14:06:59 jemarch 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; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, 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).
-
-;; 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 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.
-
-;;; Code:
-
-(defgroup vcard nil
- "Support for the vCard electronic business card format."
- :group 'vcard
- :group 'mail
- :group 'news)
-
-;;;###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 "3.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))
-
-(defvar vcard-regexp-begin-vcard "^begin:[ \t]*vcard[ \t]*\n"
- "Regexp to match the begin of a vcard")
-(defvar vcard-regexp-end-vcard "^end[ \t]*:[ \t]*vcard[ \t]*$"
- "Regexp to match the end of a 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-list-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))
- (while (re-search-forward vcard-regexp-begin-vcard nil t)
- (let ((vcard-data nil))
- (set-marker pos (point))
- (while (and (not (looking-at vcard-regexp-end-vcard))
- (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)))
- (setq vcard-list-data (cons (nreverse vcard-data)
vcard-list-data))))))
- (nreverse vcard-list-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))
-
-(defun vcard-parse-file (filename)
- "Parse FILENAME as a vCard object and return it.
-Parsing occurs with `vcard-parse-region'."
- (let ((result nil))
- (with-temp-buffer
- (insert-file filename)
- (setq result (vcard-parse-region (point-min) (point-max))))
- (if result
- result
- (error "FILENAME parsing error !"))))
-
-
-;;; 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)))))
-
-(defun vcard-get-attribute (vcard index)
- "Return the INDEXth attribute from VCARD.
-Return nil if INDEX is out of bounds"
- (cond ((or (< index 0) (>= index (length vcard)))
- nil)
- (t
- (nth index vcard))))
-
-(defun vcard-get-named-attribute (vcard attr-name)
- (let (attr result)
- (dolist (attr vcard)
- (if (equal attr-name (vcard-attr-get-name attr))
- (setq result attr)))
- result))
-
-(defun vcard-set-attribute (vcard index attribute)
- "Set ATTRIBUTE as the new INDEXth attribute in VCARD in a destructive way.
-Do nothing if INDEX is out of bounds."
- (cond ((or (< index 0) (>= index (length vcard)))
- nil)
- (t
- (setcar (nthcdr index vcard) attribute))))
-
-
-(defun vcard-get-indexed-property (proplist index)
- "Return the INDEXth property from PROPLIST.
-Return nil if INDEX if out of bounds."
- (cond ((or (< index 0) (>= index (length proplist)))
- nil)
- (t
- (nth index proplist))))
-
-(defun vcard-set-indexed-property (proplist index value)
- "Set VALUE as the new INDEXth parameter value in VCARD in a destructive way.
-Do nothing if INDEX is out of bounds."
- (cond ((or (< index 0) (>= index (length proplist)))
- nil)
- (t
- (let ((prop (nth index proplist)))
- (if (listp prop)
- (setcar (nthcdr index proplist) (cons (car prop) value))
- (setcar (nthcdr index proplist) value))))))
-
-(defun vcard-delete-indexed-property (proplist index)
- "Return a list with the INDEXth property from PROPLIST deleted.
-Do nothing if INDEX is out of bounds."
- (cond ((or (< index 0) (>= index (length proplist)))
- nil)
- (t
- (let ((prop (nth index proplist)))
- (setq proplist (delq prop proplist))))))
-
-(defun vcard-attr-get-values (attr)
- "Return a list with the values of ATTR"
- (cdr attr))
-
-(defun vcard-attr-set-values (attr values)
- "Set VALUES (a list of values) as the ATTR's values, in a destructive way."
- (setcdr attr values))
-
-(defun vcard-attr-get-proplist (attr)
- "Return the properties list of ATTR"
- (car attr))
-
-(defun vcard-attr-set-proplist (attr proplist)
- "Set ATTR's property list to PROPLIST in a destructive way"
- (setcar attr proplist))
-
-(defun vcard-delete-attribute (vcard proplist)
- "Return a VCARD with a properties list equal to PROPLIST deleted
-in a destructive way."
- (let ((elt (assoc proplist vcard)))
- (if elt
- (delq elt vcard))))
-
-(defun vcard-delete-indexed-attribute (vcard index)
- "Return a VCARD with the INDEXth attribute deleted"
- (delete-if (lambda (elt) t)
- vcard
- :start index
- :end (+ index 1)))
-
-(defun vcard-add-attribute (vcard attr)
- "Return a vcard composed of attributes of VCARD plus ATTR"
- (if (not (member attr vcard))
- (setq vcard (reverse (cons attr vcard)))
- vcard))
-
-(defun vcard-get-num-attributes (vcard)
- "Return the number of attributes contained in VCARD"
- (length vcard))
-
-(defun vcard-attr-get-name (attr)
- "Return the first property of ATTR"
- (car (vcard-attr-get-proplist attr)))
-
-(defun vcard-attr-get-parameter (attr property)
- "Return the parameter value associated with PROPERTY in ATTR.
-Return nil if PROPERTY is not a property of ATTR."
- (let* ((proplist (vcard-attr-get-proplist attr))
- (result nil))
- (dolist (prop proplist nil)
- (if (listp prop)
- (if (equal property (car prop))
- (setq result (cons (cdr prop) result)))
- (if (equal property prop)
- (setq result (cons t result)))))
- result))
-
-(defun vcard-attr-set-property (attr property value)
- (let ((proplist (vcard-attr-get-proplist attr)))
- (vcard-set-property proplist property value)))
-
-(defun vcard-attr-add-property (attr property value)
- "Add a new property to ATTR with PROPERTY and VALUE"
- (let ((proplist (vcard-attr-get-proplist attr)))
- (setcdr proplist (cons (cons property value) (cdr proplist)))
- (vcard-attr-set-proplist attr proplist)))
-
-(defun vcard-attr-remove-property (attr property value)
- "Remove the PROPERTY-VALUE in ATTR"
- (let ((proplist (vcard-attr-get-proplist attr))
- prop i prop-index-to-delete)
- (dotimes (i (length proplist))
- (setq prop (nth i proplist))
- (if (or (and (listp prop)
- (equal (car prop) property)
- (equal (cdr prop) value))
- (and (not (listp prop))
- (equal value t)
- (equal prop property)))
- (setq prop-index-to-delete i)))
- (if prop-index-to-delete
- (setq proplist (vcard-delete-indexed-property proplist
- prop-index-to-delete)))
- (vcard-attr-set-proplist attr proplist)))
-
-
-;;; Vcard writing routines
-
-(defun vcard-insert (vcard)
- "Insert the textual representation of VCARD in the current buffer.
-Leave the point after the last inserted character.
-VCARD is a parsed vCard."
- (insert "begin: vcard")
- (insert "\n")
- (dolist (attr vcard)
- (let ((proplist (vcard-attr-get-proplist attr))
- (values (vcard-attr-get-values attr)))
- (dotimes (i (length proplist))
- (let ((prop (nth i proplist)))
- (if (listp prop)
- (insert (concat (car prop)
- "="
- (cdr prop)))
- (insert prop)))
- (if (not (equal i (- (length proplist) 1)))
- (insert ";")))
- (insert ":")
- (insert " ")
- (dotimes (i (length values))
- (let ((value (nth i values)))
- (insert value)
- (if (not (equal i (- (length values) 1)))
- (insert ";"))))
- (insert "\n")))
- (insert "end: vcard"))
-
-(defun vcard-to-string (vcard)
- "Return a string with VCARD's textual representation"
- (save-excursion
- (with-temp-buffer
- (vcard-insert vcard)
- (buffer-substring (point-min) (point-max)))))
-
-
-
-
-;;; 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)))
-
-(provide 'vcard)
-
-;;; vcard.el ends here.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [commit-womb] addressbook COPYING ChangeLog Makefile README a...,
Jose E. Marchesi <=