[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/ebdb adb60dd 05/13: Refactor formatter classes, add tab
From: |
Eric Abrahamsen |
Subject: |
[elpa] externals/ebdb adb60dd 05/13: Refactor formatter classes, add tabular formatters |
Date: |
Tue, 15 Jan 2019 11:15:51 -0500 (EST) |
branch: externals/ebdb
commit adb60ddd0f4aca355eb88d44dd4dfb7dec8c6d15
Author: Eric Abrahamsen <address@hidden>
Commit: Eric Abrahamsen <address@hidden>
Refactor formatter classes, add tabular formatters
* ebdb-format.el (ebdb-formatter-freeform, ebdb-formatter-constrained,
ebdb-formatter-tabular): New formatter classes separating out
different behavior.
(ebdb-fmt-field-label): Make the record argument optional.
(ebdb-formatter-csv): CSV formatter.
(ebdb-default-csv-formatter): New option.
* ebdb-com.el (ebdb-formatter-ebdb): The EBDB formatter inherits from
ebdb-formatter-freeform.
* ebdb-org.el (ebdb-org-formatter-tabular): Add Org table formatter.
(ebdb-org-default-tabular-formatter): New option.
* ebdb-latex.el (ebdb-latex-formatter-tabular): Latex table formatter.
(ebdb-latex-default-tabular-formatter): New option.
* ebdb-html.el (ebdb-html-formatter-tabular): HTML table formatter.
(ebdb-html-default-formatter-tabular): New option.
---
ebdb-com.el | 5 +-
ebdb-format.el | 200 +++++++++++++++++++++++++++++++++++++++++++++++++--------
ebdb-html.el | 100 +++++++++++++++++++++++++++++
ebdb-latex.el | 84 ++++++++++++++++++++++++
ebdb-org.el | 57 +++++++++++++++-
5 files changed, 416 insertions(+), 30 deletions(-)
diff --git a/ebdb-com.el b/ebdb-com.el
index 5032302..32e5bad 100644
--- a/ebdb-com.el
+++ b/ebdb-com.el
@@ -396,7 +396,7 @@ position-marker mark)."
;;; *EBDB* formatting
-(defclass ebdb-formatter-ebdb (ebdb-formatter)
+(defclass ebdb-formatter-ebdb (ebdb-formatter-freeform)
;; This post-format-function only comes into play when the user
;; chooses the EBDB format in `ebdb-format-to-tmp-buffer'.
((post-format-function
@@ -538,18 +538,21 @@ choice: that formatter should be selected explicitly."
(cl-defmethod ebdb-fmt-field-label :around ((_fmt ebdb-formatter-ebdb)
_field
_style
+ &optional
(_record ebdb-record))
(propertize (cl-call-next-method) 'face 'ebdb-label))
(cl-defmethod ebdb-fmt-field-label ((_fmt ebdb-formatter-ebdb)
(field ebdb-field-phone)
(_style (eql oneline))
+ &optional
(_record ebdb-record))
(format "phone (%s)" (ebdb-field-label field)))
(cl-defmethod ebdb-fmt-field-label ((_fmt ebdb-formatter-ebdb)
(field ebdb-field-address)
(_style (eql oneline))
+ &optional
(_record ebdb-record))
(format "address (%s)" (ebdb-field-label field)))
diff --git a/ebdb-format.el b/ebdb-format.el
index c05551d..4435512 100644
--- a/ebdb-format.el
+++ b/ebdb-format.el
@@ -74,11 +74,18 @@
:initform `,buffer-file-coding-system
:documentation "The coding system for the formatted
file/buffer/stream.")
- ;; The elements of the next two slots, besides field class symbols,
- ;; can also use some shortcut symbols: mail, phone, address, notes,
- ;; tags, role, mail-primary, mail-defunct, mail-not-defunct,
- ;; role-defunct, and role-not-defunct.
- (include
+ (post-format-function
+ :type (or null function)
+ :initarg :post-format-function
+ :initform nil
+ :documentation "A function to be called after formatting is
+ complete. Probably a major mode."))
+ :abstract t
+ :documentation "Abstract base class for EBDB formatters.
+ Subclass this to produce real formatters.")
+
+(defclass ebdb-formatter-freeform (ebdb-formatter)
+ ((include
:type list
:initarg :include
:initform nil
@@ -97,13 +104,6 @@
:documentation "How field instances should be sorted. Field
classes should be listed in their proper sort order. A \"_\"
placeholder indicates where all other fields should go." )
- (header
- :type list
- :initarg :header
- :initform '((ebdb-record-person ebdb-field-role ebdb-field-image)
- (ebdb-record-organization ebdb-field-domain ebdb-field-image))
- :documentation "A list of field classes which will be output
- in the header of the record, grouped by record class type.")
(combine
:type list
:initarg :combine
@@ -119,15 +119,48 @@
generally indicates that most of the field contents will
hidden unless the user takes some action, such as clicking or
hitting <TAB>. (Currently unimplemented.)")
- (post-format-function
- :type (or null function)
- :initarg :post-format-function
+ (header
+ :type list
+ :initarg :header
+ :initform '((ebdb-record-person ebdb-field-role ebdb-field-image)
+ (ebdb-record-organization ebdb-field-domain ebdb-field-image))
+ :documentation "A list of field classes which will be output
+ in the header of the record, grouped by record class type."))
+ :abstract t
+ :documentation "An abstract formatter for formats that can
+ accept variable numbers and types of fields.")
+
+(defclass ebdb-formatter-constrained (ebdb-formatter)
+ ((fields
+ :type list
+ :initarg :fields
:initform nil
- :documentation "A function to be called after formatting is
- complete. Probably a major mode."))
+ :documentation "A list of the record fields to output.
+ Fields will be output in the order listed.")
+ (field-missing
+ :type (or string symbol function)
+ :initarg :field-missing
+ :initform "none"
+ :documentation "How to handle missing fields. Can be a
+ string, which will be inserted in place of the missing field,
+ a symbol, which will be raised as an error symbol, or a
+ function, which will be called with three arguments: the
+ formatter, the record, and the field spec."))
:abstract t
- :documentation "Abstract base class for EBDB formatters.
- Subclass this to produce real formatters.")
+ :documentation "An abstract formatter for formats that require
+ an exact specification of fields.")
+
+(defclass ebdb-formatter-tabular (ebdb-formatter-constrained)
+ ((record-separator
+ :type (or string character)
+ :initarg :record-separator
+ :initform "")
+ (field-separator
+ :type (or string character)
+ :initarg :field-separator
+ :initform ""))
+ :documentation "A formatter for outputting records in tabular
+ format.")
(cl-defmethod ebdb-string ((fmt ebdb-formatter))
(slot-value fmt 'label))
@@ -171,7 +204,7 @@ recursively composing subfields of fields.")
This method only returns the string value of FIELD itself,
possibly with text properties attached.")
-(cl-defgeneric ebdb-fmt-field-label (fmt field-or-class style record)
+(cl-defgeneric ebdb-fmt-field-label (fmt field-or-class style &optional record)
"Format a field label, using formatter FMT.
FIELD-OR-CLASS is a field class or a field instance, and STYLE is
a symbol indicating a style of some sort, such as 'compact or
@@ -188,24 +221,28 @@ a symbol indicating a style of some sort, such as
'compact or
(cl-defmethod ebdb-fmt-field-label ((_fmt ebdb-formatter)
(cls (subclass ebdb-field))
_style
+ &optional
(_record ebdb-record))
(ebdb-field-readable-name cls))
(cl-defmethod ebdb-fmt-field-label ((_fmt ebdb-formatter)
(field ebdb-field)
_style
+ &optional
(_record ebdb-record))
(ebdb-field-readable-name field))
(cl-defmethod ebdb-fmt-field-label ((_fmt ebdb-formatter)
(field ebdb-field-labeled)
_style
+ &optional
(_record ebdb-record))
(ebdb-field-label field))
(cl-defmethod ebdb-fmt-field-label ((_fmt ebdb-formatter)
(field ebdb-field-labeled)
(_style (eql compact))
+ &optional
(_record ebdb-record))
(ebdb-field-readable-name field))
@@ -238,10 +275,11 @@ a symbol indicating a style of some sort, such as
'compact or
`ebdb-string'."
(ebdb-string field))
-(cl-defmethod ebdb-fmt-collect-fields ((fmt ebdb-formatter)
+(cl-defmethod ebdb-fmt-collect-fields ((fmt ebdb-formatter-freeform)
(record ebdb-record)
&optional field-list)
- "Collect all fields of RECORD, and filter according to FMT."
+ "Collect all fields of RECORD, and filter according to FMT.
+Returns RECORD's field as a simple list."
;; Remove the `name' slot entry from the list.
(let ((fields (append
field-list
@@ -262,14 +300,41 @@ a symbol indicating a style of some sort, such as
'compact or
(null (ebdb-foo-in-list-p f exclude))))
fields))))
-(cl-defmethod ebdb-fmt-collect-fields ((fmt ebdb-formatter)
+(cl-defmethod ebdb-fmt-collect-fields ((fmt ebdb-formatter-constrained)
+ (record ebdb-record))
+ "Collect RECORD's fields according to FMT's `fields' slot.
+Return as a vector of field instances, with nil in place of
+missing fields."
+ (let* ((fmt-fields (slot-value fmt 'fields))
+ (missing (slot-value fmt 'field-missing))
+ (fields (make-vector (length fmt-fields) nil)))
+ (dotimes (i (length fields))
+ (aset fields i (or (ebdb-record-field record (nth i fmt-fields))
+ (cons (nth i fmt-fields) missing))))
+ fields))
+
+(cl-defmethod ebdb-fmt-sort-fields ((_fmt ebdb-formatter-constrained)
+ (_record ebdb-record)
+ &optional fields)
+ "Don't sort by default."
+ fields)
+
+(cl-defmethod ebdb-fmt-process-fields ((_fmt ebdb-formatter-constrained)
+ (_record ebdb-record)
+ &optional fields)
+ "Process fields for the \"constrained\" formatter class.
+At present, just makes sure that multiple field instances are
+combined into a single string."
+ fields)
+
+(cl-defmethod ebdb-fmt-collect-fields ((fmt ebdb-formatter-freeform)
(record ebdb-record-organization)
&optional field-list)
(cl-call-next-method
fmt record
(append field-list (gethash (ebdb-record-uuid record) ebdb-org-hashtable))))
-(cl-defmethod ebdb-fmt-sort-fields ((fmt ebdb-formatter)
+(cl-defmethod ebdb-fmt-sort-fields ((fmt ebdb-formatter-freeform)
(_record ebdb-record)
field-list)
"Sort FIELD-LIST using sort order from FMT.
@@ -290,7 +355,7 @@ slot of FMT."
#'< sorted)))
sorted))
-(cl-defmethod ebdb-fmt-process-fields ((fmt ebdb-formatter)
+(cl-defmethod ebdb-fmt-process-fields ((fmt ebdb-formatter-freeform)
(_record ebdb-record)
field-list)
"Process FIELD-LIST for FMT.
@@ -333,8 +398,89 @@ multiple instances in a single alist."
outlist)))
(nreverse outlist))))
-;; No basic implementation of `ebdb-fmt-compose-fields' is given, as
-;; that is entirely formatter-dependent.
+;; Tabular formatting
+
+(cl-defmethod ebdb-fmt-record ((fmt ebdb-formatter-tabular)
+ (rec ebdb-record))
+ (let ((fields (ebdb-fmt-process-fields
+ fmt rec
+ (ebdb-fmt-sort-fields
+ fmt rec
+ (ebdb-fmt-collect-fields
+ fmt rec))))
+ (rec-sep (slot-value fmt 'record-separator)))
+ (concat
+ (ebdb-fmt-compose-fields fmt rec fields)
+ rec-sep)))
+
+(cl-defmethod ebdb-fmt-header ((fmt ebdb-formatter-tabular)
+ _records)
+ (with-slots (fields field-separator record-separator) fmt
+ (concat
+ "Name"
+ field-separator
+ (mapconcat
+ (lambda (f)
+ (cond
+ ((stringp f) f)
+ ((or (class-p f)
+ (eieio-object-p f))
+ (ebdb-fmt-field-label fmt f 'normal))
+ ((symbolp f)
+ (symbol-name f))))
+ fields
+ field-separator))))
+
+(cl-defmethod ebdb-fmt-compose-fields ((fmt ebdb-formatter-tabular)
+ (rec ebdb-record)
+ &optional field-list _depth)
+
+ (with-slots (field-separator) fmt
+ (concat
+ (ebdb-record-name rec)
+ field-separator
+ (mapconcat
+ (lambda (f)
+ (if (object-p f)
+ (ebdb-fmt-field fmt f 'compact rec)
+ ;; See docs of 'field-missing slot of
+ ;; `ebdb-formatter-constrained' for explanation of the
+ ;; following behavior.
+ (pcase f
+ (`(_ . ,(and (pred stringp) str)) str)
+ (`(,spec . ,(and (pred symbolp) sym))
+ (signal sym (list rec spec)))
+ (`(,spec . (and (pred functionp) fun))
+ (funcall fun fmt rec spec)))))
+ field-list
+ field-separator))))
+
+(defclass ebdb-formatter-csv (ebdb-formatter-tabular)
+ ((record-separator :initform "\n")
+ (field-separator :initform ",")
+ (post-format-function :initform #'csv-mode)))
+
+(cl-defmethod ebdb-fmt-field ((fmt ebdb-formatter-csv)
+ (_field ebdb-field)
+ _style
+ (_rec ebdb-record))
+ "Quote field strings containing the separator."
+ (let ((sep (slot-value fmt 'field-separator))
+ (field (cl-call-next-method)))
+ (if (and (stringp sep)
+ (string-match-p sep field))
+ (format "\"%s\"" field)
+ field)))
+
+(cl-defmethod ebdb-fmt-header ((_fmt ebdb-formatter-csv)
+ _records)
+ (concat (cl-call-next-method) "\n"))
+
+(defcustom ebdb-default-csv-formatter
+ (make-instance 'ebdb-formatter-csv :label "csv"
+ :fields '(mail-primary))
+ "Default CSV formatter."
+ :group 'ebdb)
;;; Basic export routines
diff --git a/ebdb-html.el b/ebdb-html.el
new file mode 100644
index 0000000..440b7c2
--- /dev/null
+++ b/ebdb-html.el
@@ -0,0 +1,100 @@
+;;; ebdb-html.el --- EBDB HTML integration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018 Free Software Foundation, Inc.
+
+;; Author: Eric Abrahamsen <address@hidden>
+;; Maintainer: Eric Abrahamsen <address@hidden>
+
+;; 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 3 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, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This file contains code for "doing HTML things" with EBDB records.
+;; Right now that only means formatters for exporting EBDB records as
+;; HTML.
+
+;;; Code:
+
+(require 'ebdb-format)
+
+(defgroup ebdb-html nil
+ "Customization options for EBDB with HTML."
+ :group 'ebdb)
+
+(defclass ebdb-html-formatter (ebdb-formatter)
+ nil
+ :abstract t
+ :documentation "Formatter responsible for HTML-specific field
+ formatting.")
+
+(cl-defmethod ebdb-fmt-field ((_fmt ebdb-html-formatter)
+ (field ebdb-field-mail)
+ _style
+ (_rec ebdb-record))
+ (with-slots (mail aka) field
+ (format "<a href=\"mailto:%s\">%s</a>" mail (or aka mail))))
+
+(defclass ebdb-html-formatter-tabular (ebdb-formatter-tabular
+ ebdb-html-formatter)
+ ;; We put the <tr> elements in manually.
+ ((record-separator :initform "")
+ (field-separator :initform "</td><td>")
+ (post-format-function :initform #'html-mode)))
+
+(defcustom ebdb-html-default-formatter-tabular
+ (make-instance 'ebdb-html-formatter-tabular
+ :label "html table"
+ :fields '(mail-primary))
+ "The default HTML table formatter.")
+
+(cl-defmethod ebdb-fmt-header ((fmt ebdb-html-formatter-tabular)
+ _records)
+ (with-slots (fields) fmt
+ (concat
+ "<table>\n<tr><th>Name</th><th>"
+ (mapconcat
+ (lambda (f)
+ (cond
+ ((stringp f) f)
+ ((or (class-p f)
+ (eieio-object-p f))
+ (ebdb-fmt-field-label fmt f 'normal))
+ ((symbolp f)
+ (symbol-name f))))
+ fields
+ "</th><th>")
+ "</th></tr>\n")))
+
+(cl-defmethod ebdb-fmt-footer ((fmt ebdb-html-formatter-tabular)
+ _records)
+ "\n</table>")
+
+(cl-defmethod ebdb-fmt-record ((_fmt ebdb-html-formatter-tabular)
+ (_rec ebdb-record))
+ "Wrap records in <tr> elements.
+This is done in lieu of a `record-separator' slot, since it's
+around each record, not between records."
+ (concat "<tr>"
+ (cl-call-next-method)
+ "</tr>"))
+
+(cl-defmethod ebdb-fmt-compose-fields :around ((_fmt
ebdb-html-formatter-tabular)
+ (_rec ebdb-record)
+ &optional _field-list _depth)
+ (concat "<td>"
+ (cl-call-next-method)
+ "</td>"))
+
+(provide 'ebdb-html)
+;;; ebdb-html.el ends here
diff --git a/ebdb-latex.el b/ebdb-latex.el
new file mode 100644
index 0000000..e4365ca
--- /dev/null
+++ b/ebdb-latex.el
@@ -0,0 +1,84 @@
+;;; ebdb-latex.el --- LaTex formatting routines for EBDB -*- lexical-binding:
t; -*-
+
+;; Copyright (C) 2018 Free Software Foundation, Inc.
+
+;; Author: Eric Abrahamsen <address@hidden>
+;; Maintainer: Eric Abrahamsen <address@hidden>
+
+;; 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 3 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, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This file contains routines for formatting EBDB records as LaTeX.
+
+;;; Code:
+
+(require 'ebdb-format)
+
+(defgroup ebdb-latex nil
+ "Options for EBDB and LaTeX."
+ :group 'ebdb)
+
+(defclass ebdb-latex-formatter (ebdb-formatter)
+ ((post-format-function :initform #'latex-mode))
+ :abstract t
+ :documentation "")
+
+(cl-defmethod ebdb-fmt-field ((_fmt ebdb-latex-formatter)
+ (field ebdb-field-mail)
+ _style
+ (_rec ebdb-record))
+ (with-slots (mail aka) field
+ (format "\\href{mailto:%s}{%s}" mail (or aka mail))))
+
+(defclass ebdb-latex-formatter-tabular (ebdb-latex-formatter
+ ebdb-formatter-tabular)
+ ((record-separator :initform " \\\\\n")
+ (field-separator :initform " & ")
+ (table-environment :initform "tabular")
+ (table-spec
+ :type (or string null)
+ :initarg :table-spec
+ :initform nil)))
+
+(cl-defmethod ebdb-fmt-field ((_fmt ebdb-latex-formatter-tabular)
+ (_field ebdb-field)
+ _style
+ (_rec ebdb-record))
+ "Escape column separators in field strings."
+ (replace-regexp-in-string "\\([^\\]\\)&" "\\1\\\\&"
+ (cl-call-next-method)))
+
+(cl-defmethod ebdb-fmt-header ((fmt ebdb-latex-formatter-tabular)
+ _recs)
+ (with-slots (table-environment table-spec) fmt
+ (concat (format "\\begin{%s}" table-environment)
+ (when table-spec
+ (format "%s" table-spec))
+ "\n")))
+
+(cl-defmethod ebdb-fmt-footer ((fmt ebdb-latex-formatter-tabular)
+ _recs)
+ (with-slots (table-environment) fmt
+ (format "\\end{%s}" table-environment)))
+
+(defcustom ebdb-latex-default-tabular-formatter
+ (make-instance 'ebdb-latex-formatter-tabular
+ :label "latex table"
+ :fields '(mail-primary))
+ "Default LaTeX tabular formatter."
+ :type 'ebdb-formatter-tabular)
+
+(provide 'ebdb-latex)
+;;; ebdb-latex.el ends here
diff --git a/ebdb-org.el b/ebdb-org.el
index 71ff087..b7c1b65 100644
--- a/ebdb-org.el
+++ b/ebdb-org.el
@@ -53,9 +53,14 @@
;;; Code:
(require 'ebdb-com)
+(require 'ebdb-format)
(require 'org)
(require 'org-agenda)
+(defgroup ebdb-org nil
+ "Custom group for EBDB Org options."
+ :group 'ebdb)
+
(if (fboundp 'org-link-set-parameters)
(org-link-set-parameters "ebdb"
:follow 'ebdb-org-open
@@ -66,8 +71,8 @@
:store 'ebdb-org-store-link
:export 'ebdb-org-export)
(with-no-warnings ;; I know it's obsolete.
- (org-add-link-type "ebdb" #'ebdb-org-open #'ebdb-org-export)
- (add-hook 'org-store-link-functions 'ebdb-org-store-link)))
+ (org-add-link-type "ebdb" #'ebdb-org-open #'ebdb-org-export)
+ (add-hook 'org-store-link-functions 'ebdb-org-store-link)))
;; TODO: Put a custom keymap on the links (or else expand
;; `ebdb-org-open') so that users can choose what to do with the
@@ -155,5 +160,53 @@ To do this automatically for every search, add this
function to
"Use a separate EBDB buffer for Org-related contacts."
(format "*%s-Org*" ebdb-buffer-name))
+;;; Formatters
+
+(defclass ebdb-org-formatter (ebdb-formatter)
+ ((post-format-function :initform #'org-mode))
+ :abstract t
+ :documentation "Formatter responsible for Org-specific field
+ formatting.")
+
+(cl-defmethod ebdb-fmt-field ((fmt ebdb-org-formatter)
+ (field ebdb-field-mail)
+ _style
+ (rec ebdb-record))
+ (concat "mailto:" (cl-call-next-method)))
+
+(defun ebdb-org-table-post-format ()
+ "Align the formatted Org table."
+ (org-mode)
+ (goto-char (point-min))
+ (forward-char)
+ (org-table-align))
+
+(defclass ebdb-org-formatter-tabular (ebdb-formatter-tabular
+ ebdb-org-formatter)
+ ((record-separator :initform "\n")
+ (field-separator :initform " | ")
+ (post-format-function :initform #'ebdb-org-table-post-format)))
+
+(cl-defmethod ebdb-fmt-header :around ((fmt ebdb-org-formatter-tabular)
+ _records)
+ (concat "| "
+ (cl-call-next-method)
+ " |\n"
+ "|---|\n"))
+
+(cl-defmethod ebdb-fmt-compose-fields :around ((_fmt
ebdb-org-formatter-tabular)
+ (_rec ebdb-record)
+ &optional _field-list _depth)
+ (concat "| "
+ (cl-call-next-method)
+ " |"))
+
+(defcustom ebdb-org-default-tabular-formatter
+ (make-instance 'ebdb-org-formatter-tabular
+ :label "org table"
+ :fields '(mail-primary))
+ "Default Org table formatter."
+ :type 'ebdb-formatter-tabular)
+
(provide 'ebdb-org)
;;; ebdb-org.el ends here
- [elpa] externals/ebdb 3cba3d7 01/13: Rejigger insertion of newlines in record formatting, (continued)
- [elpa] externals/ebdb 3cba3d7 01/13: Rejigger insertion of newlines in record formatting, Eric Abrahamsen, 2019/01/15
- [elpa] externals/ebdb f133aef 03/13: Docstring fix for ebdb-mail, Eric Abrahamsen, 2019/01/15
- [elpa] externals/ebdb 5ef1773 04/13: Allow overwriting of previous formatting buffers, Eric Abrahamsen, 2019/01/15
- [elpa] externals/ebdb eec63c8 07/13: Provide basic HTML5 freeform formatter, Eric Abrahamsen, 2019/01/15
- [elpa] externals/ebdb 980927f 02/13: Switch from cond to pcase in ebdb-record-field, Eric Abrahamsen, 2019/01/15
- [elpa] externals/ebdb 6dad4c1 09/13: Allow 'mail-primary as an argument to ebdb-record-field, Eric Abrahamsen, 2019/01/15
- [elpa] externals/ebdb 4625970 11/13: Move map require from ebdb-com.el to ebdb.el, Eric Abrahamsen, 2019/01/15
- [elpa] externals/ebdb 753c049 13/13: Bump to 0.6.3, flush recent changes, Eric Abrahamsen, 2019/01/15
- [elpa] externals/ebdb 65247f6 08/13: Make csv-mode dependency optional, Eric Abrahamsen, 2019/01/15
- [elpa] externals/ebdb cbaa04b 10/13: Fix compose fields for the HTML5 freeform formatter, Eric Abrahamsen, 2019/01/15
- [elpa] externals/ebdb adb60dd 05/13: Refactor formatter classes, add tabular formatters,
Eric Abrahamsen <=
- [elpa] externals/ebdb 7a19553 06/13: Shift base ebdb-fmt-record implementation to ebdb-formatter-freeform, Eric Abrahamsen, 2019/01/15
- [elpa] externals/ebdb 4f4596c 12/13: Re-absorb ebdb-counsel into main package, Eric Abrahamsen, 2019/01/15