BBDB tags

| emacs, organizer, productivity

Right, that tags thing looks like a good idea. It should be easy to
hack into BBDB. I’ll need to actually tag people, and then write an
Emacs Lisp script that scans through all of the records, gathers them
into categories, and then creates the list.

HEY. This might actually work. Here’s a quick test of tags:

ateneo Charles Yeung,Sean Uy,Ryan Kristoffer Tan,Stephanie Sy,Bit Santos,Jerome Punzalan
pisay Jerome Punzalan,clair ching,mario carreon
linux Eric Pareja,Jared Odulio,Chris G. Haravata,levi guerrero,Zak B. Elep,clair ching,Dean Michael Berris,Jan Alonzo
blog Charles Yeung,Sean Uy,Ryan Kristoffer Tan,Stephanie Sy,Aaditya Sood,Bit Santos,Raven,Jerome Punzalan,Richard Plana,Phillip Pearson,Eric Pareja,Jared Odulio,Celsus Kintanar,Jan Michael Ibanez,Mark A. Hershberger,Chris G. Haravata,levi guerrero,Cha Gascon,Sim Gamboa, III,Marcelle Fabie,Zak B. Elep,David Edmondson,edelgado,Dominique Cimafranca,clair ching,Sean Champ,Dean Michael Berris,Jason Banico,John S. J. Anderson,Jan Alonzo
debian Federico Sevilla III,Paul Lussier,Angus Lees,Frederik Fouvry,Zak B. Elep,Joe Corneli,clair ching,Sean Champ,Miles Bader,Jan Alonzo,Jesse Alama
emacs Manoj Srivastava,Paul Lussier,Lukhas,Angus Lees,Mario Lang,Jan Michael Ibanez,Mark A. Hershberger,Frederik Fouvry,clair ching,Miles Bader,Ethan Aubin,John S. J. Anderson,Jesse Alama
planner Paul Lussier,Mark A. Hershberger,Frederik Fouvry,Zak B. Elep,Joe Corneli,clair ching,Ethan Aubin,John S. J. Anderson,Jesse Alama

Use C-o to add a “tags” field to your BBDB records. This should be a space-delimited list of tags (case-sensitive for now).
Call M-x sacha/planner-bbdb-insert-tags-alist to produce a list like the one above.

(defun sacha/bbdb-get-tags (record)
  "Return the tags for RECORD as a list."
  (let ((tags (bbdb-record-getprop record 'tags)))
    (when tags (split-string tags))))

(defun sacha/bbdb-test-tags (query tags)
  "Return non-nil if QUERY is a subset of TAGS."
  (let ((result t))
    (while (and result query)
      (unless (member (car query) tags)
        (setq result nil))
      (setq query (cdr query)))
    result))

(defun sacha/bbdb-search-tags-internal (records tags)
  "Return a list of RECORDS matching TAGS."
  (when (stringp tags) (setq tags (split-string tags)))
  (let (result)
    (while records
      (when (sacha/bbdb-test-tags tags
                                  (sacha/bbdb-get-tags (car records)))
        (setq result (cons (car records) result)))
      (setq records (cdr records)))
    result))

(defun sacha/bbdb-search-tags (tags)
  "Display all the records that match TAGS."
  (interactive "MTags: ")
  (bbdb-display-records (sacha/bbdb-search-tags-internal (bbdb-records) tags)))

(defun sacha/planner-bbdb-link (record)
  "Return a link to RECORD."
  (or (bbdb-record-getprop record 'plan)
      ;; From a BBDB entry with a plan page; use that. Yay!
      (concat "[[bbdb://"
              (emacs-wiki-replace-regexp-in-string
               " " "."
               (bbdb-record-name record))
              "][" (bbdb-record-name record)
              "]]")))

(defun sacha/bbdb-get-tags-index ()
  "Return a list of tags and records."
  (let ((tags-alist '())
        (records (bbdb-records))
        tags
        entry
        list
        link)
    (while records
      (setq tags (sacha/bbdb-get-tags (car records)))
      (while tags
        (setq entry (assoc (car tags) tags-alist))
        (setq list (cdr entry))
        (add-to-list 'list (car records))
        (if entry
            (setcdr entry list)
          (add-to-list 'tags-alist (cons (car tags) list)))
        (setq tags (cdr tags)))
      (setq records (cdr records)))
    tags-alist))

(defun sacha/planner-bbdb-insert-tags-alist (&optional tag-alist)
  "Insert TAG-ALIST into the current buffer."
  (interactive)
  (unless tag-alist (setq tag-alist (sacha/bbdb-get-tags-index)))
  (insert (mapconcat
           (lambda (item)
             (concat (car item) " | "
                     (mapconcat
                      'sacha/planner-bbdb-link
                      (cdr item)
                      ",")))
           tag-alist
           "\n")))

To think that only took me an hour of leisurely coding (including tagging my contact information)…

You can comment with Disqus or you can e-mail me at sacha@sachachua.com.