Here is a completely new and much improved version of bbdb-print.
Please give it a try.
There are now many more options for formatting the printout; the
variable bbdb-print-alist controls them (somewhat in the manner of
default-frame-alist). There are also new options for selecting what
gets printed out (see bbdb-require and the arguments to bbdb-print).
A big thank you goes out to Luigi Semenzato, who designed the TeX
format that bbdb-print is based on. He sent us his 'phoneformat'
program, and helped out with adapting it to work from BBDB databases
rather than text files.
Please let me know what you think! This is the first release of this
code, so I'd expect there to be some problems.
The shar file, which follows my .sig, should unpack to three files:
bbdb-print.el, bbdb-print.tex, and multicol.tex. Put the files in the
appropriate places and you should be ready to go.
Bng
--
Boris Goldowsky The only way you'll end up in a corner
Is by walking in too straight of a li
[EMAIL PROTECTED] --Claudia Schmidt n
57 Glasgow Street, Rochester, NY 14608 e
#!/bin/sh
# This is a shell archive (produced by shar 3.49)
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
#
# made 03/23/1994 22:18 UTC by [EMAIL PROTECTED]
# Source directory /home/diamond/u14/boris/emacs/bbdb-print
#
# existing files will NOT be overwritten unless -c is specified
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 14260 -rw-r--r-- bbdb-print.el
# 5014 -rw-r--r-- bbdb-print.tex
# 7361 -rw-r--r-- multicol.tex
#
# ============= bbdb-print.el ==============
if test -f 'bbdb-print.el' -a X"$1" != X"-c"; then
echo 'x - skipping bbdb-print.el (File already exists)'
else
echo 'x - extracting bbdb-print.el (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'bbdb-print.el' &&
;;; bbdb-print.el -- for printing BBDB databases using TeX.
X
;;; Authors: Boris Goldowsky <[EMAIL PROTECTED]>
;;; Dirk Grunwald <[EMAIL PROTECTED]>
;;; Luigi Semenzato <[EMAIL PROTECTED]>
;;; Copyright (C) 1993 Boris Goldowsky
;;; Version: 3.0; 21Mar94
X
;;; This file is part of the bbdb-print extensions to the Insidious
;;; Big Brother Database, which is for use with GNU Emacs.
;;;
;;; The Insidious Big Brother Database is free software; you can redistribute
;;; it and/or modify it under the terms of the GNU General Public License as
;;; published by the Free Software Foundation; either version 1, or (at your
;;; option) any later version.
;;;
;;; BBDB is distributed in the hope that it will be useful, but WITHOUT ANY
;;; WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
;;; FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
;;; details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Emacs; see the file COPYING. If not, write to
;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
X
;;; Commentary:
;;;
;;; In the *BBDB* buffer, type P to convert the listing to TeX
;;; format. It will prompt you for a filename. Then run TeX on that
;;; file and print it out.
;;;
;;; Bbdb-print understands one new bbdb field: tex-name. If it
;;; exists, this will be used for the printed listing instead of the
;;; name field of that record. This is designed for entering names
;;; with lots of accents that would mess up mailers, or when for any
;;; reason you want the printed version of the name to be different
;;; from the version that appears on outgoing mail and in the *BBDB*
;;; buffer. You may want to add tex-name to bbdb-elided-display so
;;; you only see it in the printout. tex-name is exempted from the
;;; usual special-character quoting done by bbdb-print; it is used
;;; verbatim.
;;;
;;; Not all fields or records need be printed. To not print a certain
;;; field, add it to `bbdb-print-elide' (which see). If after eliding
;;; fields a record contains no interesting information, it will not
;;; be printed at all; the variable `bbdb-print-require' determines
;;; what is meant by "interesting" information. You can also restrict
;;; printing to just the records currently in the *BBDB* buffer by
;;; using *P instead of P.
;;;
;;; There are various options for the way the formatting is done; most
;;; are controlled by the variable bbdb-print-alist. See its
;;; documentation for the allowed options.
X
;;; Installation:
;;;
;;; Put this file somewhere on your load-path. Put bbdb-print.tex and
;;; multicol.tex somewhere on your TEXINPUTS path, or put absolute
;;; pathnames into the variable bbdb-print-format-files (which see). Put
;;; (add-hook 'bbdb-load-hook (function (lambda () (require 'bbdb-print))))
;;; into your .emacs, or autoload it.
;;;
;;; This program was adapted for BBDB by Boris Goldowsky
;;; <[EMAIL PROTECTED]> and Dirk Grunwald
;;; <[EMAIL PROTECTED]> using a TeX format designed by Luigi
;;; Semenzato <[EMAIL PROTECTED]>.
;;; We are also grateful to numerous people on the info-bbdb
;;; mailing list for suggestions and bug reports.
X
;;; Code:
X
(require 'bbdb)
(require 'bbdb-com)
X
(define-key bbdb-mode-map "P" 'bbdb-print)
X
;;; Variables:
X
(defvar bbdb-print-file-name "~/bbdb.tex"
X "*Default file name for printouts of BBDB database.")
X
(defvar bbdb-print-format-files '("bbdb-print" "multicol")
X "*Names of TeX files for formatting BBDB databases.
If these filenames are not absolute, the files must be located
somewhere that TeX will find them.")
X
(defvar bbdb-print-elide '(tex-name aka mail-alias nic nic-updated)
X "*List of fields NOT to print in address list.
See also bbdb-print-require.")
X
(defvar bbdb-print-require '(or address phone)
X "*What fields are required for printing a record.
This is evaluated for each record, and the record will be printed only
if it returns non-nil. The symbols name, company, net, phone,
address, and notes will be set to appropriate values when this is
evaluated; they will be non-nil if the field does not exist or is elided.
X
The value of this variable can be any lisp expression, but typically
it will be used for a boolean combination of the field variables, as
in the following simple examples:
X
X Print only people whose phone numbers are known:
X (setq bbdb-print-require 'phone)
X Print people whose names AND companies are known:
X (setq bbdb-print-require '(and name company))
X Print people whose names, and either addresses OR phone numbers are known:
X (setq bbdb-print-require '(and name (or address phone))).")
X
(defvar bbdb-print-alist '((columns . 3)
X (separator . 2)
X (phone-on-first-line . "^[ \t]*$")
X (ps-fonts . nil)
X (font-size . 6)
X (quad-hsize . "3.15in")
X (quad-vsize . "4.5in"))
X "Formatting options for bbdb-print.
This is an alist of the form ((option1 . value1) (option2 . value2) ...)
The possible options and legal values are:
X - columns: 1, 2, 3, 4 or 'quad (4 little 2-column pages per sheet)
X or 'grid (12 credit-card-sized pages per sheet)
X - separator: 0-7, the style of heading for each letter.
X 0=none, 1=line, 2=boxed letters, 3=large boxed letters, 4=large letters,
X 5=letters with lines, 6=letters with suits, 7=boxed letters with suits.
X - phone-on-first-line: t means to put first phone number on the same
X line with the name, nil means just the name. A string means to
X use the first phone number whose `location' matches that string,
X which should be a valid regular expression.
X - ps-fonts: nonnil means to use them, nil to use standard TeX fonts.
X - font-size: in points, any integer (assuming fonts in that size exist!).
X - quad-hsize, quad-vsize: for the quad format, horizontal and
X vertical size of the little pages. These must be strings which
X are valid TeX dimensions, eg \"10cm\".")
X
(defvar bbdb-print-prolog
X (concat "%%%% ====== Phone/Address list in -*-TeX-*- Format =====\n"
X "%%%% produced by bbdb-print, version 3.0\n\n")
X "*TeX statements to include at the beginning of the bbdb-print file.")
X
(defvar bbdb-print-epilog "\\endaddresses\n\\bye\n"
X "*TeX statements to include at the end of the bbdb-print file.")
X
;;; Functions:
X
(defsubst bbdb-print-if-not-blank (string &rest more)
X "If STRING is not null, then return it concatenated
with rest of arguments. If it is null, then all arguments are
ignored and the null string is returned."
X (if (or (null string) (equal "" string))
X ""
X (apply 'concat string more)))
X
;;;###autoload
(defun bbdb-print (visible-records to-file)
X "Make a TeX file for printing out the bbdb database.\\<bbdb-mode-map>
If \"\\[bbdb-apply-next-command-to-all-records]\\[bbdb-print]\" is \
used instead of simply \"\\[bbdb-print]\", then includes only the
people currently in the *BBDB* buffer. There are various variables
for customizing the content & format of the printout, see the file
bbdb-print.el for more information."
X (interactive (list (bbdb-do-all-records-p)
X (read-file-name "Print To File: " bbdb-print-file-name)))
X (setq bbdb-print-file-name (expand-file-name to-file))
X (let ((current-letter t)
X (records (if (not visible-records)
X (bbdb-records)
X (set-buffer bbdb-buffer-name)
X (mapcar 'car bbdb-records)))
X (psstring (if (cdr (assoc 'bbdb-print-ps-fonts bbdb-print-alist))
X "ps" ""))
X (columns (cdr (assoc 'columns bbdb-print-alist))))
X (find-file bbdb-print-file-name)
X (widen) (erase-buffer)
X (insert bbdb-print-prolog)
X (let ((infiles bbdb-print-format-files))
X (while infiles
X (insert (format "\\input %s\n" (car infiles)))
X (setq infiles (cdr infiles))))
X (insert (format "\n\\set%ssize{%d}\n"
X psstring (cdr (assoc 'font-size bbdb-print-alist)))
X (format "\\setseparator{%d}\n"
X (cdr (assoc 'separator bbdb-print-alist)))
X (cond ((eq 'quad columns)
X (format "\\quadformat{%s}{%s}"
X (cdr (assoc 'quad-hsize bbdb-print-alist))
X (cdr (assoc 'quad-vsize bbdb-print-alist))))
X ((eq 'grid columns) "\\grid")
X ((= 4 columns) "\\fourcol")
X ((= 3 columns) "\\threecol")
X ((= 2 columns) "\\twocol")
X ((= 1 columns) "\\onecol"))
X "\n\n")
X (while records
X (setq current-letter
X (bbdb-print-format-record (car records) current-letter))
X (setq records (cdr records)))
X (insert bbdb-print-epilog)
X (goto-char (point-min))))
X
(defun bbdb-print-format-record (record &optional current-letter brief)
X "Insert the bbdb RECORD in TeX format.
Optional CURRENT-LETTER is the section we're in -- if this is non-nil and
the first letter of the sortkey of the record differs from it, a new section
heading will be output \(an arg of t will always produce a heading).
The new current-letter is the return value of this function.
Someday, optional third arg BRIEF will produce one-line format."
X (bbdb-debug (if (bbdb-record-deleted-p record)
X (error "plus ungood: tex formatting deleted record")))
X
X (let* ((bbdb-elided-display bbdb-print-elide)
X (first-letter
X (substring (concat (bbdb-record-sortkey record) "?") 0 1))
X (name (and (bbdb-field-shown-p 'name)
X (or (bbdb-record-getprop record 'tex-name)
X (bbdb-print-tex-quote
X (bbdb-record-name record)))))
X (company (and (bbdb-field-shown-p 'company)
X (bbdb-record-company record)))
X (net (and (bbdb-field-shown-p 'net)
X (bbdb-record-net record)))
X (phone (and (bbdb-field-shown-p 'phone)
X (bbdb-record-phones record)))
X (address (and (bbdb-field-shown-p 'address)
X (bbdb-record-addresses record)))
X (notes (bbdb-record-raw-notes record))
X (begin (point)))
X
X (if (not (eval bbdb-print-require))
X nil ; lacks required fields
X
X ;; Section header, if neccessary.
X
X (if (and current-letter
X (not (string-equal first-letter current-letter)))
X (insert (format "\\separator{%s}\n\n" (bbdb-print-tex-quote
X (upcase first-letter)))))
X
X (insert "\\beginrecord\n")
X
X ;; if there is no name, use company instead
X (if (and (not name) company)
X (setq name (bbdb-print-tex-quote company)
X company nil))
X
X (let ((pofl (cdr (assoc 'phone-on-first-line bbdb-print-alist)))
X (rightside "")
X p)
X (cond ((null phone))
X ((eq t pofl)
X (setq rightside (bbdb-phone-string (car phone))
X phone (cdr phone)))
X ((stringp pofl)
X (let ((p (bbdb-print-front-if
X (function (lambda (ph)
X (string-match pofl (aref ph 0))))
X phone)))
X (if p
X (setq rightside (bbdb-phone-string (car p))
X phone (cdr p))))))
X (insert (format "\\firstline{%s}{%s}\n"
X name
X (bbdb-print-tex-quote rightside))))
X
X (if company
X (insert (format "\\comp{%s}\n" (bbdb-print-tex-quote company))))
X
X ;; Phone numbers
X
X (while phone
X (let ((place (aref (car phone) 0))
X (number (bbdb-phone-string (car phone))))
X (insert (format "\\phone{%s%s}\n"
X (bbdb-print-tex-quote
X (bbdb-print-if-not-blank place ": "))
X (bbdb-print-tex-quote number)))
X (setq phone (cdr phone))))
X
X ;; Email address -- just list their first address.
X ;; Make all dots legal line-breaks.
X
X (if net
X (let ((net-addr (bbdb-print-tex-quote (car net)))
X (start 0))
X (while (string-match "\\." net-addr start)
X (setq net-addr
X (concat (substring net-addr 0 (match-beginning 0))
X ".\\-"
X (substring net-addr (match-end 0))))
X (setq start (+ 2 (match-end 0))))
X (insert (format "\\email{%s}\n" net-addr))))
X
X ;; Addresses
X
X (while address
X (let ((addr (car address)))
X (insert
X (format
X "\\address{%s}\n"
X (bbdb-print-tex-quote
X (concat
X (bbdb-print-if-not-blank (bbdb-address-street1 addr) "\\\\\n")
X (bbdb-print-if-not-blank (bbdb-address-street2 addr) "\\\\\n")
X (bbdb-print-if-not-blank (bbdb-address-street3 addr) "\\\\\n")
X (bbdb-address-city addr)
X (if (and (not (equal "" (bbdb-address-city addr)))
X (not (equal "" (bbdb-address-state addr))))
X ", ")
X (bbdb-print-if-not-blank (bbdb-address-state addr) " ")
X (bbdb-address-zip-string addr)
X "\\\\")))))
X (setq address (cdr address)))
X
X ;; Notes
X
X (if (stringp notes)
X (setq notes (list (cons 'notes notes))))
X (while notes
X (let ((thisnote (car notes)))
X (if (bbdb-field-shown-p (car thisnote))
X (progn
X (if (eq 'notes (car thisnote))
X (insert (format "\\notes{%s}\n" (bbdb-print-tex-quote
X (cdr thisnote))))
X (insert (format "\\note{%s}{%s}\n"
X (bbdb-print-tex-quote (symbol-name
X (car thisnote)))
X (bbdb-print-tex-quote (cdr thisnote))))))))
X (setq notes (cdr notes)))
X
X ;; Mark end of the record.
X
X (insert "\\endrecord\n\n")
X (setq current-letter first-letter)))
X
X current-letter)
X
(defun bbdb-print-front-if (func list)
X "Move first elt of LIST satisfying FUNC to front.
The car of the returned list is the first element that returned nonnil;
The cdr is the rest of the list.
But if the FUNC returns nil for every elements of the LIST, returns nil."
X (cond ((null list) nil)
X ((funcall func (car list))
X list)
X ((let ((rest (bbdb-print-front-if func (cdr list))))
X (if rest
X (cons (car rest)
X (cons (car list) (cdr rest))))))))
X
(defun bbdb-print-tex-quote (string)
X "Quote any unquoted TeX special characters that appear in STRING.
In other words, # alone will be replaced by \\#, but \\^ will be left for
TeX to process as an accent."
X (if string
X (save-excursion
X (set-buffer (get-buffer-create " bbdb-print-tex-quote"))
X (erase-buffer)
X (insert string)
X (goto-char (point-min))
X (while (not (eobp))
X (cond ((looking-at "[<>=]+")
X (replace-match "$\\&$"))
X ((and (looking-at "[#$%&~_]")
X (not (eq ?\\ (char-after (1- (point))))))
X (insert "\\")
X (forward-char 1))
X ((and (looking-at "[{}]")
X (not (eq ?\\ (char-after (1- (point))))))
X (insert "$\\")
X (forward-char 1)
X (insert "$"))
X (t (forward-char 1))))
X (buffer-string))))
X
(provide 'bbdb-print)
X
;;; bbdb-print ends here.
SHAR_EOF
chmod 0644 bbdb-print.el ||
echo 'restore of bbdb-print.el failed'
Wc_c="`wc -c < 'bbdb-print.el'`"
test 14260 -eq "$Wc_c" ||
echo 'bbdb-print.el: original size 14260, current size' "$Wc_c"
fi
# ============= bbdb-print.tex ==============
if test -f 'bbdb-print.tex' -a X"$1" != X"-c"; then
echo 'x - skipping bbdb-print.tex (File already exists)'
else
echo 'x - extracting bbdb-print.tex (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'bbdb-print.tex' &&
%%% bbdb-print.tex - for formatting address lists.
X
%%% Authors: Luigi Semenzato <[EMAIL PROTECTED]>
%%% Boris Goldowsky <[EMAIL PROTECTED]>
%%% Copyright (C) 1993 Boris Goldowsky
%%% Version: 3.0; 21Mar94
X
%%% For instructions on using this format file with BBDB, see bbdb-print.el
%%% which should have come bundled with this file; or write to
%%% [EMAIL PROTECTED]
X
%%% This file is part of the bbdb-print extensions to the Insidious
%%% Big Brother Database, which is for use with GNU Emacs.
%%%
%%% The Insidious Big Brother Database is free software; you can redistribute
%%% it and/or modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 1, or (at your
%%% option) any later version.
%%%
%%% BBDB is distributed in the hope that it will be useful, but WITHOUT ANY
%%% WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
%%% FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
%%% details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with GNU Emacs; see the file COPYING. If not, write to
%%% the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
X
%%% The address-list file should look something like this:
X
%%% \input file % this format file's filename
%%% \setsize6 % point size of type to use
%%% % or \setpssize6 to use PostScript fonts. (optional)
%%% \setseparator3 % which style of separators, 0-7
%%%
%%% \separator{A} % include a separator here
%%%
%%% \beginrecord
%%% \name{A. Name}
%%% \phone{location: (xxx) xxx-xxxx}
%%% \address{1234 Main Street\\
%%% Anytown, XX 00000\\}
%%% \note{note name}{note text}
%%% \notes{blah blah}
%%% \endrecord
%%%
%%% \endaddresses
%%% \bye
X
\nopagenumbers
\raggedright
\tolerance=10000
\hbadness=10000
\parskip 0pt
\parindent=0pt % was 10pt
X
%%%
%%% Fonts
%%%
X
\def\setsize#1{
X \font\rm=cmr#1
X \font\bf=cmbx#1
X \font\it=\ifnum #1=6 cmti7 \else cmti#1\fi
X \font\bigbf=cmbx10 scaled \magstep3
X \rm
X \baselineskip=#1pt
X \ifnum #1>9 \advance\baselineskip by 1pt \fi
}
X
\def\setpssize#1{
X \font\rm=ptmr at #1pt
X \font\bf=ptmb at #1pt
X \font\it=ptmri at #1pt
X {\dimen0=#1pt\global\font\bigbf=ptmb at 1.8\dimen0}
X \rm
X \baselineskip=#1pt
}
X
%%%
%%% Define separator types
%%%
X
\def\setseparator#1{
X \ifnum #1=1
X \def\separator##1{\hrule\smallskip\mark{##1}}
X \else \ifnum #1=2
X \def\separator##1{\hbox{\vrule\hskip -0.4pt\vbox{\hrule\smallskip
X \centerline{\bf{##1}}\smallskip\hrule}\hskip -0.4pt\vrule
X \mark{##1}}}
X \else \ifnum #1=3
X \def\separator##1{\hbox{\vrule\hskip -0.4pt\vbox{\hrule\smallskip
X \centerline{\bigbf{##1}}\smallskip\hrule}\hskip -0.4pt\vrule}
X \medskip\mark{##1}}
X \else \ifnum #1=4
X \def\separator##1{\smallskip\centerline{\bigbf{##1}}\medskip\mark{##1}}
X \else \ifnum #1=5
X \def\separator##1{\hrule\smallskip
X \centerline{\bigbf{##1}}\smallskip\hrule\medskip\mark{##1}}
X \else \ifnum #1=6
X \def\cute{$\sya\syb\syc\syd$}
X \def\revcute{$\syd\syc\syb\sya$}
X \let\sya=\heartsuit\let\syb=\spadesuit
X \let\syc\diamondsuit\let\syd=\clubsuit
X \def\cycle{\let\tmp=\sya\let\sya=\syb
X \let\syb=\syc\let\syc=\syd\let\syd=\tmp}
X \def\separator##1{\smallskip
X \hbox to \hsize{\hfil\cute\hfil\bigbf{##1}\hfil\revcute\hfil}
X \cycle\medskip\mark{##1}}
X \else \ifnum #1=7
X \def\cute{$\sya\syb\syc\syd$}
X \def\revcute{$\syd\syc\syb\sya$}
X \let\sya=\heartsuit\let\syb=\spadesuit
X \let\syc=\diamondsuit\let\syd=\clubsuit
X \def\cycle{\let\tmp=\sya\let\sya=\syb\let\syb=\syc\let\syc=\syd
X \let\syd=\tmp}
X \def\separator##1{\hbox{\vrule\vbox{\hrule\smallskip
X \hbox to \hsize{\hfil\cute\hfil\bigbf{##1}\hfil\revcute\hfil}
X \smallskip\hrule}\vrule}\medskip\cycle\mark{##1}}
X \else
X \def\separator##1{\mark{##1}}
X \fi\fi\fi\fi\fi\fi\fi
} % end setseparator
X
%%%
%%% Macros for formatting the entries.
%%%
X
\def\\{\par}
X
\def\dots{\leaders\hbox to 0.6em{\hss.\hss}}
X
\def\firstline#1#2{% the name and (maybe) the first phone number.
X \hyphenpenalty=10000\rightskip=0pt plus 1fil
X \noindent{\bf #1}\dotfill\penalty-1\hbox{}\dotfill{#2}\\
}
X
\def\name#1{\firstline{#1}{}} % for backwards compatibility
X
\def\comp#1{#1\\}
X
\def\phone#1{\hfill#1\\}
X
\def\email#1{\smallbreak{\tt#1}\\}
X
\def\address#1{\smallbreak#1\smallbreak}
X
\def\note#1#2{{\smallbreak\leftskip=2em\parindent=-1em
X \noindent\hskip-\leftskip{\it#1: } #2\\ }}
X
\def\notes#1{\smallbreak{\it(#1)}\\ }
X
\def\beginrecord{\bigbreak}
X
\def\endrecord{\bigbreak}
X
\def\endaddresses{
X \bigskip\hrule\smallskip
X \noindent {\bf Printed \today}\vfill\endcol}
X
\def\today{\number\day\space
X \ifcase\month\or Jan\or Feb\or Mar\or Apr \or May\or June\or
X Jul\or Aug\or Sept\or Oct\or Nov\or Dec\fi
X \space\number\year}
X
%%% bbdb-print.tex ends here.
SHAR_EOF
chmod 0644 bbdb-print.tex ||
echo 'restore of bbdb-print.tex failed'
Wc_c="`wc -c < 'bbdb-print.tex'`"
test 5014 -eq "$Wc_c" ||
echo 'bbdb-print.tex: original size 5014, current size' "$Wc_c"
fi
# ============= multicol.tex ==============
if test -f 'multicol.tex' -a X"$1" != X"-c"; then
echo 'x - skipping multicol.tex (File already exists)'
else
echo 'x - extracting multicol.tex (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'multicol.tex' &&
%%% multicol.tex - multiple columns per page, multiple pages per sheet.
X
%%% Authors: Luigi Semenzato <[EMAIL PROTECTED]>
%%% Boris Goldowsky <[EMAIL PROTECTED]>
%%% Copyright (C) 1993 Boris Goldowsky
%%% Version: 3.0; 21Mar94
X
%%% Commentary:
%%%
%%% Put \input multicol.tex
%%% at the beginning of your TeX file.
%%% Then \twocol, \threecol, or \fourcol for multi-column output
%%% or \gridformat (4x3 grid of small credit-card-sized pages)
%%% or \quadformat{xsize}{ysize} for four 2-column pages per sheet.
%%% In any case you will need to put \endcol at the end of the
%%% document, before \bye.
X
%%% This file is part of the bbdb-print extensions to the Insidious
%%% Big Brother Database, which is for use with GNU Emacs.
%%%
%%% The Insidious Big Brother Database is free software; you can redistribute
%%% it and/or modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 1, or (at your
%%% option) any later version.
%%%
%%% BBDB is distributed in the hope that it will be useful, but WITHOUT ANY
%%% WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
%%% FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
%%% details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with GNU Emacs; see the file COPYING. If not, write to
%%% the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
X
X
\newdimen\multicolhsize \multicolhsize=\hsize
\newdimen\columngutter \columngutter=.2in % space between columns
\newdimen\pagegutter \pagegutter=1in % space between minipages
X
\newbox\columnA \newbox\columnB \newbox\columnC
X
\newdimen\FULLHSIZE
\newdimen\FULLVSIZE
\newbox\quadrantbox
\newbox\firstquadrant \newbox\secondquadrant
\newbox\thirdquadrant \newbox\fourthquadrant
\newbox\row \newbox\page
X
\def\columnbox{\leftline{\pagebody}}
X
\def\multicolline{\hbox to \multicolhsize}
X
\newcount\NROW \NROW=3 % for grid format. are these really variables
\newcount\NCOL \NCOL=4 % that can be changed? should they be set
X % from lisp?
\newcount\rowindex \newcount\colindex
X
\def\onecol % for consistency---or maybe one could use it for switching back.
{
X \output={\shipout\vbox{\makeheadline\multicolline{\columnbox}\makefootline}
X \advancepageno \ifnum\outputpenalty>-20000 \else\dosupereject\fi}
X \def\endcol{}
}% end onecol
X
\def\twocol
{
X \advance\hsize by -\columngutter
X \divide\hsize 2
X \let\column=A
X \output={\if A\column
X \global\setbox\columnA=\columnbox \global\let\column=B
X \else
X \shipout\vbox{\makeheadline
X \multicolline{\box\columnA\hfil\columnbox}
X \makefootline}
X \advancepageno \global\let\column=A
X \fi
X \ifnum\outputpenalty>-20000 \else\dosupereject\fi}
X
X \def\endcol
X {
X \vfill\supereject\if A\column \else\null\vfill\eject\fi
X }
X
} % end twocol
X
\def\threecol
{
X \advance\hsize -\columngutter
X \advance\hsize -\columngutter
X \divide\hsize 3
X \let\column=A
X \output={\if A\column
X \global\setbox\columnA=\columnbox \global\let\column=B
X \else \if B\column
X \global\setbox\columnB=\columnbox \global\let\column=C
X \else
X \shipout\vbox{\makeheadline
X \multicolline{\box\columnA\hfil\box\columnB
X \hfil\columnbox}
X \makefootline}
X \advancepageno \global\let\column=A
X \fi\fi
X \ifnum\outputpenalty>-20000 \else\dosupereject\fi}
X
X \def\endcol
X {
X \if A\column
X \null\vfill\eject\null\vfill\eject
X \else\if B\column
X \null\vfill\eject
X \fi\fi
X \vfill\supereject
X }
X
} % end threecol
X
\def\fourcol
{
X \advance\hsize -3\columngutter
X \divide\hsize 4
X \let\column=A
X \output={\if A\column
X \global\setbox\columnA=\columnbox \global\let\column=B
X \else \if B\column
X \global\setbox\columnB=\columnbox \global\let\column=C
X \else \if C\column
X \global\setbox\columnC=\columnbox \global\let\column=D
X \else
X \shipout\vbox
X { \makeheadline
X \multicolline{\box\columnA\hfil\box\columnB\hfil
X \box\columnC\hfil\columnbox}
X \makefootline}
X \advancepageno\global\let\column=A
X \fi\fi\fi
X \ifnum\outputpenalty>-20000 \else\dosupereject\fi
X }
X
X \def\endcol
X {
X \vfill\supereject
X \if A\column \else\null\vfill\eject\fi
X \if B\column \else\null\vfill\eject\fi
X \if C\column \else\null\vfill\eject\fi
X }
X
} % end fourcol
X
\def\quadformat#1#2
{
X \hsize=#1 \advance\hsize by -.15in \divide\hsize 2
X \vsize=#2
X \multicolhsize=#1
X \FULLHSIZE=#1 \multiply\FULLHSIZE 2 \advance\FULLHSIZE by \pagegutter
X \FULLVSIZE=#2 \multiply\FULLVSIZE 2 \advance\FULLVSIZE by \pagegutter
X \let\lr=L
X \let\quadrant=A
X \output={\if L\lr
X \global\setbox\columnA=\columnbox \global\let\lr=R
X \else
X \global\setbox\quadrantbox=\vbox{\multicolline
X {\box\columnA\hfil\columnbox}} \global\let\lr=L
X \quadrantformat
X \fi
X \ifnum\outputpenalty>-20000 \else\dosupereject\fi}
X
X \def\quadrantformat
X {\if A\quadrant
X \global\setbox\firstquadrant=\box\quadrantbox
X \global\let\quadrant=B
X \else \if B\quadrant
X \global\setbox\secondquadrant=\box\quadrantbox
X \global\let\quadrant=C
X \else \if C\quadrant
X \global\setbox\thirdquadrant=\box\quadrantbox
X \global\let\quadrant=D
X \else
X {\shipout
X \vbox to \FULLVSIZE
X {\FULLLINE{\box\firstquadrant\hfil\box\secondquadrant}
X \vfill
X \FULLLINE{\box\thirdquadrant\hfil\box\quadrantbox}}}
X \global\let\quadrant=A
X \advancepageno
X \fi\fi\fi}
X
X \def\FULLLINE{\hbox to \FULLHSIZE}
X
X \def\endcol{\supereject\if R\lr \null\vfill\eject\fi}
} % end of quadformat
X
\def\grid
{
X \def\rowspace{\vbox to 0.2in{}}
X \def\colspace{\hbox to 0.2in{}}
X
X \hsize=1.5in
X \vsize=2.9in
X
X \rowindex=0 \colindex=0
X
X \setbox\row=\null \setbox\page=\null
X
X \output={\global\advance\colindex by 1
X \ifnum\colindex>\NCOL
X \global\colindex=1
X \global\setbox\page=\vbox{\box\page\rowspace\box\row}
X \global\setbox\row=\null
X \global\advance\rowindex by 1
X \ifnum\rowindex=\NROW
X \global\rowindex=1
X \shipout\box\page
X \global\setbox\page=\null
X \advancepageno
X \fi
X \fi
X \global\setbox\row=\hbox{\box\row\colspace\columnbox}}
X
X \def\columnbox{\leftline{\pagebody}}
X
X \def\endcol{\vfill\supereject
X \ifnum\colindex=1\null\vfill\eject\fi}
} % end of grid.
X
%%% multicol.tex ends here.
X
SHAR_EOF
chmod 0644 multicol.tex ||
echo 'restore of multicol.tex failed'
Wc_c="`wc -c < 'multicol.tex'`"
test 7361 -eq "$Wc_c" ||
echo 'multicol.tex: original size 7361, current size' "$Wc_c"
fi
exit 0