summaryrefslogtreecommitdiffstats
path: root/lisp/bbdb/bbdb-tex.el
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lisp/bbdb/bbdb-tex.el557
1 files changed, 0 insertions, 557 deletions
diff --git a/lisp/bbdb/bbdb-tex.el b/lisp/bbdb/bbdb-tex.el
deleted file mode 100644
index 38654e3..0000000
--- a/lisp/bbdb/bbdb-tex.el
+++ /dev/null
@@ -1,557 +0,0 @@
-;;; bbdb-tex.el --- feed BBDB into LaTeX -*- lexical-binding: t -*-
-
-;; Copyright (C) 2010-2017 Free Software Foundation, Inc.
-
-;; Authors: Boris Goldowsky <boris@cs.rochester.edu>
-;; Dirk Grunwald <grunwald@cs.colorado.edu>
-;; Luigi Semenzato <luigi@paris.cs.berkeley.edu>
-
-;; This file is part of the Insidious Big Brother Database (aka BBDB),
-
-;; BBDB 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.
-
-;; BBDB is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with BBDB. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file lets you feed BBDB into LaTeX.
-;; See the BBDB info manual for documentation.
-;;
-;; In the *BBDB* buffer, type M-x `bbdb-tex' to convert the listing
-;; to LaTeX format.
-;;
-;; TeX macros appearing in the output:
-;; \name{first}{last}
-;; \organization{foo bar}
-;; \affix{foo bar}
-;; \aka{foo bar}
-;; \phone{key}{123 456 7890}
-;; \address{key}{foo bar}
-;; \mail{foo@bar.com}{Smith <foo@bar.com>}
-;; \xfield{key}{value}
-;; Each macro may appear multiple times.
-;;
-;; The detailed grammar of the output is defined in `bbdb-tex-alist'.
-;; The output starts with a prolog where you can specify LaTeX packages
-;; and other customizations in the usual way. The above macros should get
-;; defined, too. By default, this happens in the style file bbdb.sty that
-;; is shipped with BBDB.
-;;
-;; The body of the output contains the BBDB records. Usually, the records
-;; are placed inside some "bbdb" environment. You can customize which fields
-;; of each record should appear in the listing and in which order.
-;; Also, you can put separators between individual fields. A separator macro
-;; can also separate records when the first character of the last name differs
-;; from the first character of the last name of the previous record.
-;; The listing ends with an epilog.
-
-;; A few notes on "advanced usage" of `bbdb-tex':
-;;
-;; It should be possible to use `bbdb-tex' with all the bells and whistles
-;; of LaTeX by loading the appropriate LaTeX style files and packages or
-;; embedding the output of `bbdb-tex' into more complex LaTeX documents.
-;; For this you can customize the rules in `bbdb-tex-alist' and use
-;; customized style files for interpreting the TeX macros used by `bbdb-tex'.
-;;
-;; Generally, lisp customizations for `bbdb-tex' are intended to provide control
-;; of *what* appears in the TeX listing. But there are no lisp customization
-;; options to control the actual layout that should be handled by LaTeX.
-;; BBDB is shipped with one basic LaTeX style file bbdb.sty to handle
-;; the TeX macros listed above. You should customize this LaTeX style file
-;; to match your taste and / or your needs. Note also that `bbdb-tex-alist'
-;; allows you to specify an arbitrary number of rules that may use different
-;; style files for the above TeX macros.
-
-;; Generally, it will be advantageous to make all relevant style files
-;; and packages known to LaTeX by putting them in the appropriate directories
-;; of your TeX installation. Likely, the user variable `bbdb-tex-path'
-;; should not be used in such advanced cases. The main purpose of the
-;; inlining mechanism provided via `bbdb-tex-path' is that we can ship
-;; and install BBDB without worrying about the tricky question where to
-;; (auto-) install the basic style file bbdb.sty shipped with BBDB so that
-;; TeX finds it. Most often, it will be best to manually install even bbdb.sty
-;; in a directory where TeX finds it and bind `bbdb-tex-path' to t to fully
-;; suppress the inlining.
-;;
-;; Before generating the TeX output, the field values of a record are massaged
-;; by `bbdb-tex-field' that passes these values by default to `bbdb-tex-replace',
-;; see also `bbdb-tex-replace-list'. Instead the user may also define functions
-;; `bbdb-tex-output-...' that take precedence, see `bbdb-tex-field'.
-;;
-;; `bbdb-tex' understands one new BBDB xfield: tex-name, see also
-;; `bbdb-tex-name'. If this xfield is defined for a record,
-;; this will be used for the TeXed listing instead of the name field
-;; of that record. The value of the xfield tex-name is used verbatim,
-;; it does not see `bbdb-tex-field' and `bbdb-tex-replace-list'.
-;;
-;;
-;; This program was adapted for BBDB by Boris Goldowsky
-;; <boris@cs.rochester.edu> and Dirk Grunwald
-;; <grunwald@cs.colorado.edu> using a TeX format designed by Luigi
-;; Semenzato <luigi@paris.cs.berkeley.edu>.
-;; We are also grateful to numerous people on the bbdb-info
-;; mailing list for suggestions and bug reports.
-
-;;; Code:
-
-(require 'bbdb)
-(require 'bbdb-com)
-
-;;; Variables:
-
-(defcustom bbdb-tex-name 'tex-name
- "Xfield holding the name in TeX format.
-The string in this field gets split into first and last name
-using `bbdb-separator-alist'. The separator defaults to \"#\"."
- :group 'bbdb-utilities-tex
- :type '(symbol :tag "Xfield"))
-
-(defcustom bbdb-tex-alist
- `((multi-line
- (demand (or address phone))
- (prolog ,(concat "\\documentclass{article}\n\\usepackage{bbdb}\n"
- "\\usepackage{multicol}\n"
- "\\begin{document}\n\\begin{multicols}{2}"))
- (record "\\begin{bbdbrecord}" name organization ; affix aka
- (address t) (phone t) (mail t)
- (xfields t nil
- (omit ,bbdb-tex-name mail-alias creation-date timestamp))
- "\\end{bbdbrecord}\n")
- (separator "\\bbdbseparator{%s}\n")
- (epilog ,(concat "\\noindent\\hrulefill\\\\\nPrinted \\today\n"
- "\\end{multicols}\n\\end{document}"))
- (options (bbdb-tex-linebreak "\\\\\\\\\n")
- (bbdb-tex-address-layout 2)))
-
- (one-line
- (demand phone)
- (prolog ,(concat "\\documentclass{article}\n\\usepackage{bbdb}\n"
- "\\begin{document}\n\\begin{bbdb}{llllll}"))
- (record name "&" (organization 1) "&" (phone 2 "&") "&" (mail 1)
- "&" (address 1) "\\\\")
- (separator "\\bbdbseparator{%s}")
- (epilog "\\end{bbdb}\n\\end{document}")
- (options (bbdb-tex-linebreak ", ")
- (bbdb-tex-address-layout 3)))
-
- (phone
- (demand phone)
- (prolog ,(concat "\\documentclass{article}\n\\usepackage{bbdb}\n"
- "\\begin{document}\n\\begin{bbdb}{ll}"))
- (record name "&" (phone 2 "&") "\\\\")
- (separator "\\bbdbseparator{%s}")
- (epilog "\\end{bbdb}\n\\end{document}")
- (options (bbdb-tex-linebreak ", ")
- (bbdb-tex-address-layout 3)))
-
- (example ; another rule with more examples
- (demand (or address phone))
- (prolog ,(concat "\\documentclass{article}\n\\usepackage{bbdb}\n"
- "\\usepackage{multicol}\n"
- "\\begin{document}\n\\begin{multicols}{2}"))
- (record "\\begin{bbdbrecord}" name organization
- (address 1 nil (omit "work"))
- (phone 2 nil (admit "home" "cell"))
- (mail t)
- (birthday t)
- (xfields t nil
- (omit ,bbdb-tex-name mail-alias creation-date timestamp))
- "\\end{bbdbrecord}\n")
- (separator "\\bbdbseparator{%s}\n")
- (epilog ,(concat "\\noindent\\hrulefill\\\\\nPrinted \\today\n"
- "\\end{multicols}\n\\end{document}"))
- (options (bbdb-tex-linebreak "\\\\\\\\\n")
- (bbdb-tex-address-layout 2))))
-
- "Alist of rules for passing BBDB to LaTeX.
-Each rule has the form (RULE LIST1 LIST2 ...).
-The symbol RULE identifies the rule.
-The remainder are lists LIST that should have one of these forms:
-
- (demand FORM)
-
- Here FORM is a lisp expression. A record will be TeXed only
- if evaluating FORM yields a non-nil value for this record.
- When FORM is evaluated, the symbols name, affix, organization, mail,
- phone, address, and xfields are set to the corresponding values
- of this record; these symbols are nil if the respective field
- does not exist for this record.
-
- (prolog STRING)
-
- The string STRING is inserted at the beginning of the buffer.
- If STRING contains the substring \"\\usepackage{foo}\" and
- a file \"foo.sty\" exists within `bbdb-tex-path', replace
- \"\\usepackage{foo}\" with the content of the file \"foo.sty\",
- surrounded by \"\\makeatletter\" and \"\\makeatother\".
- Note: This fails with more sophisticated LaTeX style files
- using, e.g., optional arguments for the \"\\usepackage\" macro.
-
- (record ELT1 ELT2 ...)
-
- Here ELT may be one of the following:
-
- IF ELT is name, this expands to \"\\name{first}{last}\"
-
- If ELT is affix, organization, or aka, ELT expands to \"\\ELT{value}\".
- Here the elements of ELT are concatenated to get one value.
-
- If ELT is the key of an xfield, ELT expands to \"\\xfield{ELT}{value}\".
-
- If ELT is a string, this is inserted \"as is\" in the TeX buffer.
-
- ELT may also be a loop (FLD COUNT [SEPARATOR] [OPT...])
- looping over the values of FLD.
-
- If FLD is mail, this expands to \"\\mail{short}{long}\",
- such as \"\\mail{foo@bar.com}{Smith <foo@bar.com>}\",
- If FLD is phone, this expands to \"\\phone{key}{number}\"
- If FLD is address, this expands to \"\\address{key}{value}\".
- If FLD is xfields, this expands to \"\\xfield{key}{value}\".
- If FLD is the key of an xfield, split the value of FLD
- using `bbdb-separator-alist' to generate a list of values,
- which then expand to \"\\xfield{FLD}{value}\".
-
- If COUNT is a number, process at most COUNT values of FLD.
- IF COUNT is t, process all values of FLD.
-
- If SEPARATOR is non-nil, it is a string that is inserted between
- the values of FLD. Insert COUNT - 1 instances of SEPARATOR,
- even if there are fewer values of FLD.
-
- If FLD is mail, phone, address, or xfields,
- OPT may be a list (admit KEY ...) or (omit KEY ...).
- Then a value is admitted or omitted if its key KEY is listed here.
-
- (separator STRING)
-
- When the first letter of the records' sortkey increases compared with
- the previous record in the TeX listing, the new letter is formatted
- using the format string STRING to generate a separator macro.
-
- (epilog STRING)
-
- The string STRING is inserted at the end of the buffer."
- :group 'bbdb-utilities-tex)
-
-(defcustom bbdb-tex-rule-default 'multi-line
- "Default rule for BBDB tex.
-This symbol should be a key in `bbdb-tex-alist'."
- :group 'bbdb-utilities-tex
- :type '(symbol :tag "rule"))
-
-;; FIXME
-;; (defcustom bbdb-tex-empty-fields nil
-;; "If non-nil generate TeX output even for empty fields."
-;; :group 'bbdb-utilities-tex)
-
-(defcustom bbdb-tex-replace-list
- '(("[#$%&_]" . "\\\\\\&")
- ("<" . "\\\\textless ")
- (">" . "\\\\textgreater ")
- ("~" . "\\\\textasciitilde ")
- ("{" . "\\\\textbraceleft ")
- ("}" . "\\\\textbraceright "))
- "Replacement list for TeX's special characters.
-Each element is of the form (REGEXP . REPLACE)."
- :group 'bbdb-utilities-tex
- :type '(repeat (cons regexp string)))
-
-(defcustom bbdb-tex-linebreak "\\\\\\\\\n"
- "Replacement for linebreaks."
- :group 'bbdb-utilities-tex
- :type 'string)
-
-(defcustom bbdb-tex-address-format-list bbdb-address-format-list
- "List of address formatting rules for `bbdb-tex'.
-Each element may take the same values as in `bbdb-address-format-list'.
-The elements EDIT of `bbdb-address-format-list' are ignored."
- :group 'bbdb-utilities-tex
- :type '(repeat (list (choice (const :tag "Default" t)
- (function :tag "Function")
- (repeat (string)))
- (choice (string)
- (function :tag "Function"))
- (choice (string)
- (function :tag "Function"))
- (choice (string)
- (function :tag "Function")))))
-
-(defcustom bbdb-tex-address-layout 2
- "Address layout according to `bbdb-tex-address-format-list'.
-2 is multi-line layout, 3 is one-line layout."
- :group 'bbdb-utilities-tex)
-
-(defcustom bbdb-tex-file "~/bbdb.tex"
- "Default file name for TeXing BBDB."
- :group 'bbdb-utilities-tex
- :type 'file)
-
-;;; Internal variables
-
-(defvar bbdb-tex-rule-last bbdb-tex-rule-default
- "Last rule used for TeXing BBDB.")
-
-(defvar bbdb-tex-file-last bbdb-tex-file
- "Last used TeX file")
-
-;;; Functions:
-
-;; While we use `bbdb-tex-replace' only once in `bbdb-tex-field',
-;; we keep it as a separate function so that it can also be used
-;; inside user-defined functions `bbdb-tex-output-...'.
-(defun bbdb-tex-replace (string)
- "Apply replacement rules `bbdb-tex-replace-list' to STRING.
-Also, replace linebreaks by `bbdb-tex-linebreak'."
- (if (not string)
- ""
- (dolist (elt bbdb-tex-replace-list)
- (setq string (replace-regexp-in-string (car elt) (cdr elt) string)))
- (replace-regexp-in-string "\n" bbdb-tex-linebreak string)))
-
-(defun bbdb-tex-field (field str)
- "Massage string STR for LaTeX.
-By default, STR is passed to `bbdb-tex-replace'.
-The user may also define a function `bbdb-tex-output-FIELD'
-that takes precedence."
- (let ((fun (intern-soft (format "bbdb-tex-output-%s" field))))
- (if fun
- (funcall fun str)
- (bbdb-tex-replace str))))
-
-(defun bbdb-tex-list (list rule fun)
- "Use function FUN to generate output for LIST according to RULE.
-LIST is a list of field values such as a list of addresses.
-RULE is an element of a record list as in `bbdb-tex-alist'
-used to select the elements of LIST that get processed by calling FUN."
- (let ((admit (cdr (assq 'admit rule)))
- (omit (cdr (assq 'omit rule)))
- (num (if (numberp (nth 1 rule)) (nth 1 rule)))
- (sep (if (nth 2 rule) (concat (nth 2 rule) "\n")))
- (i -1)
- new-list elt)
-
- ;; Select the relevant elements of LIST.
- (cond (admit
- (dolist (l list)
- (if (member (elt l 0) admit)
- (push l new-list)))
- (setq new-list (nreverse new-list)))
-
- (omit
- (dolist (l list)
- (unless (member (elt l 0) omit)
- (push l new-list)))
- (setq new-list (nreverse new-list)))
-
- (t
- (setq new-list list)))
-
- (cond ((not num)
- (insert (mapconcat fun new-list (or sep ""))))
- ((not sep)
- (while (and (< (setq i (1+ i)) num)
- (setq elt (pop new-list)))
- (insert (funcall fun elt))))
- (t
- (while (< (setq i (1+ i)) num)
- (if (setq elt (pop new-list))
- (insert (funcall fun elt)))
- (if (< (1+ i) num)
- (insert sep)))))))
-
-;;;###autoload
-(defun bbdb-tex (records file rule)
- "Generate FILE for TeXing RECORDS.
-Interactively, use BBDB prefix \
-\\<bbdb-mode-map>\\[bbdb-do-all-records], see `bbdb-do-all-records'.
-RULE should be an element of `bbdb-tex-alist'."
- (interactive
- (list (bbdb-do-records)
- (read-file-name
- (format "TeX file: (default %s) "
- (abbreviate-file-name bbdb-tex-file-last))
- (file-name-directory bbdb-tex-file-last)
- bbdb-tex-file-last)
- (intern (completing-read (format "Rule: (default %s) "
- bbdb-tex-rule-last)
- bbdb-tex-alist nil t
- nil nil (symbol-name bbdb-tex-rule-last)))))
- ;; Remember our choice for `bbdb-tex-file-last'.
- (setq bbdb-tex-file-last (expand-file-name file))
-
- (find-file bbdb-tex-file-last)
- (let* ((buffer-undo-list t)
- (rule (assq rule bbdb-tex-alist))
- (demand (nth 1 (assq 'demand rule)))
- (separator (nth 1 (assq 'separator rule)))
- current-letter p-symbols p-values)
- (erase-buffer)
-
- ;; Options
- (dolist (option (cdr (assq 'options rule)))
- (push (car option) p-symbols)
- (push (cadr option) p-values))
- (cl-progv p-symbols p-values
-
- ;; Prolog
- (let ((prolog (nth 1 (assq 'prolog rule))))
- (when prolog
- (insert prolog)
- (when (consp bbdb-tex-path)
- (goto-char (point-min))
- (while (re-search-forward "\\\\usepackage[ \t\n]*{\\([^}]+\\)}" nil t)
- (let ((sty (locate-file (match-string 1) bbdb-tex-path '(".sty"))))
- (when sty
- (replace-match (format "\n\\\\makeatletter\n%% begin %s\n%% end %s\n\\\\makeatother\n" sty sty))
- (save-excursion
- (forward-line -2)
- (insert-file-contents sty))))))
- (goto-char (point-max))
- (unless (bolp) (insert "\n"))
- (insert "% end BBDB prolog\n")))
-
- ;; Process Records
- (dolist (record (bbdb-record-list records))
- (let* ((first-letter
- (substring (bbdb-record-sortkey record) 0 1))
- (firstname (bbdb-record-firstname record))
- (lastname (bbdb-record-lastname record))
- (name (bbdb-record-name record))
- (name-lf (bbdb-record-name-lf record))
- (organization (bbdb-record-organization record))
- (affix (bbdb-record-affix record))
- (aka (bbdb-record-aka record))
- (mail (bbdb-record-mail record))
- (phone (bbdb-record-phone record))
- (address (bbdb-record-address record))
- (xfields (bbdb-record-xfields record))
- (lex-env `((firstname . ,firstname) (lastname . ,lastname)
- (name . ,name) (name-lf . ,name-lf) (aka . ,aka)
- (organization . ,organization) (affix . ,affix)
- (mail . ,mail) (phone . ,phone)
- (address . ,address) (xfields . ,xfields)))
- (bbdb-address-format-list bbdb-tex-address-format-list))
-
- ;; A record is processed only if the form DEMAND
- ;; evaluates to a non-nil value.
- (when (or (not demand)
- (eval demand lex-env))
-
- ;; Separator
- (if (and separator
- (not (and current-letter
- (equal first-letter current-letter))))
- (insert (format separator (upcase first-letter)) "\n"))
- (setq current-letter first-letter)
-
- (dolist (elt (cdr (assq 'record rule)))
- (cond ((stringp elt)
- (insert elt "\n"))
-
- ((eq elt 'name) ; name of record
- (let ((tex-name (and bbdb-tex-name
- (bbdb-record-field record bbdb-tex-name)))
- (fmt "\\name{%s}{%s}\n"))
- (if tex-name
- (let ((first-last (bbdb-split bbdb-tex-name tex-name)))
- (cond ((eq 2 (length first-last))
- (insert (format fmt (car first-last) (cadr first-last))))
- ((eq 1 (length first-last))
- (insert (format fmt "" (car first-last))))
- (t (error "TeX name %s cannot be split" tex-name))))
- (insert (format fmt
- (bbdb-tex-field 'firstname firstname)
- (bbdb-tex-field 'lastname lastname))))))
-
- ;; organization, affix or aka as single string
- ((memq elt '(organization affix aka))
- (let ((val (bbdb-record-field record elt)))
- (if val
- (insert (format "\\%s{%s}\n" elt
- (bbdb-tex-field elt (bbdb-concat elt val)))))))
-
- ;; organization, affix or aka as list of strings
- ((memq (car elt) '(organization affix aka))
- (bbdb-tex-list
- (bbdb-record-field record (car elt))
- elt
- `(lambda (o)
- (format "\\%s{%s}\n" ',(car elt)
- (bbdb-tex-field ',(car elt) o)))))
-
- ((eq (car elt) 'mail) ; mail
- (bbdb-tex-list
- mail elt
- (lambda (m)
- (format "\\mail{%s}{%s}\n"
- ;; No processing of plain mail address
- (nth 1 (bbdb-decompose-bbdb-address m))
- (bbdb-tex-field 'mail m)))))
-
- ((eq (car elt) 'address) ; address
- (bbdb-tex-list
- address elt
- (lambda (a)
- (format "\\address{%s}{%s}\n"
- (bbdb-tex-field 'address-label (bbdb-address-label a))
- (bbdb-tex-field 'address (bbdb-format-address
- a bbdb-tex-address-layout))))))
-
- ((eq (car elt) 'phone) ; phone
- (bbdb-tex-list
- phone elt
- (lambda (p)
- (format "\\phone{%s}{%s}\n"
- (bbdb-tex-field 'phone-label (bbdb-phone-label p))
- (bbdb-tex-field 'phone (bbdb-phone-string p))))))
-
- ((eq (car elt) 'xfields) ; list of xfields
- (bbdb-tex-list
- (bbdb-record-field record 'xfields)
- elt
- (lambda (x)
- (format "\\xfield{%s}{%s}\n"
- (bbdb-tex-field 'xfield-label (symbol-name (car x)))
- (bbdb-tex-field 'xfield (cdr x))))))
-
- ((symbolp elt) ; xfield as single string
- ;; The value of an xfield may be a sexp instead of a string.
- ;; Ideally, a sexp should be formatted by `pp-to-string',
- ;; then printed verbatim.
- (let ((val (format "%s" (bbdb-record-field record elt))))
- (if val
- (insert (format "\\xfield{%s}{%s}\n" elt
- (bbdb-tex-field elt (bbdb-concat elt val)))))))
-
- ((consp elt) ; xfield as list of strings
- (bbdb-tex-list
- (bbdb-split (car elt)
- (format "%s" (bbdb-record-field record (car elt))))
- elt
- `(lambda (x)
- (format "\\xfield{%s}{%s}\n" ',(car elt)
- (bbdb-tex-field ',(car elt) x)))))
-
- (t (error "Rule `%s' undefined" elt)))))))
-
- ;; Epilog
- (let ((epilog (nth 1 (assq 'epilog rule))))
- (when epilog
- (insert "% begin BBDB epilog\n" epilog)
- (unless (bolp) (insert "\n"))))))
- (setq buffer-undo-list nil)
- (save-buffer))
-
-(provide 'bbdb-tex)
-
-;;; bbdb-tex.el ends here