From: David J Cooper Jr
Subject: Lisp front-end for generating LaTeX
Date: 
Message-ID: <364651D5.4822C266@genworks.com>
Fellow Lispers:

  I had some marketing letters to prepare, and wasn't real
happy with the lack of openness of the Windows and PC-based
mail merge facilities (plus the fact that I only have a 
Solaris box and a Linux box!). I pretty much want to keep 
my contacts in a simple SQL database or flat files, and
I want the highest degree of flexibility for creating form
letters and so forth out of them.

  I also have other varied needs to generate finely controlled printed
outputs.

  HTML is great for web publishing and web applications, but 
it is still not really to the point of supporting finely
controlled printed output (and maybe never will be, since 
that was never its original intent).

  So, I decided to go ahead and develop a set of Lisp macros 
and functions for generating LaTeX output, in the spirit of 
the nice CL-HTTP macros for HTML output.

 To make things additionally comfortable for myself, I also
decided to go ahead and develop a macro for declarative specification of
CLOS objects and methods, which looks 
very similar to the Defpart macro I am used to using in 
ICAD. I want my office-automation tools to work in both
an ICAD and non-ICAD Lisp, so I put together a very small
subset of a defpart-compatible macro, since I am so used
to working in that declarative mode.

  Attached is an example of a standard-form-letter
``defpart'' for your preliminary perusal.

  The complete source for the LaTeX synthesis (beginning
with just a very small set limited to the ``letter''
documentclass), and other supporting utilities will soon 
be GPL'ed and available via anonymous ftp from www.genworks.org, if any
interest manifests itself.

  (It's not there now, and documenting and packaging will 
probably not happen until after the Lisp conference next week, unless I
get some specific requests for it sooner 
than that).
 
  I just wanted to ask this group a few questions:

  1) Has something like this already been done? Am I wasting 
     my time?

  2) Would anyone be so kind as to look through the code I         have
so far and comment on it? Does it look like the
     beginnings of anything remotely useful?

  4) Any other specific or general comments welcome.


  Thanks!

  -djc

============================================

(in-package :drl-user)

(defpart standard-form-letter 
    (base-web-inspectable-object)

  :optional-inputs
  (
   :body-filename 
   "~/office/marketing/autofact-body-1.txt"
   
   :data-filename 
   "~/office/marketing/autofact-leads.lisp"
   
   :name "David J. Cooper Jr."
   
   :signature 
   '("David J. Cooper Jr." 
     "President, Genworks International")
   
   :address '("Genworks International"
	      "5777 West Maple, Suite 130"
	      "West Bloomfield, MI 48125")
   
   :point-size 11
   
   :paper-size :usletter
   
   :make-labels? t)

  
  :attributes
  (
   :recipient-data 
   (with-open-file (instream (the :data-filename))
     (read instream))
   
   :body-string 
   (with-open-file (instream (the :body-filename))
     (read-multi-line-string-from-stream instream)))
  
  :parts
  ((:letters :type 'standard-letter
	     :quantify (:series 
			(length 
			 (rest (the :recipient-data))))

	     :data (rest (the :recipient-data))

	     :body-string (the :body-string)))
  
  :methods
  ((:print-to-stream 
    (&key (stream t))
    (latex2e:document-class 
     :letter
     :point-size (the :point-size)
     :paper-size (the :paper-size)
     :name (the :name)
     :address (the :address)
     :signature (the :signature)
     :make-labels? (the :make-labels?)
     :stream stream)
    (latex2e:with-document (:stream stream)
      (dotimes (n (array-dimension (the :letters) 0))
	(the (:letters n) 
	  (:print-to-stream :stream stream)))))))


(defpart standard-letter (base-web-inspectable-object)

  :inputs
  (:data
   :body-string)
  
  :attributes
  (:my-data 
   (nth (the :index) (the :data)))
  
  :uncached-attributes
  (
   :last-name    
   (first   (the :my-data))
   :first-name   (second  (the :my-data))
   :title        (third   (the :my-data))
   :company-name (fourth  (the :my-data))
   :address      (fifth   (the :my-data))
   :city         (sixth   (the :my-data))
   :state        (seventh (the :my-data))
   :zip          (eighth  (the :my-data))
   :phone        (ninth   (the :my-data))
   :fax          (tenth   (the :my-data))
   :salutation   (nth 11  (the :my-data))
   
   :opening (format nil "Dear ~a ~a:" 
		    (the :salutation)
		    (the :last-name))
   
   :recipient-field (list (concatenate 'string 
			    (the :first-name) 
			    " " 
			    (the :last-name))
			  (the :title)
			  (the :company-name)
			  (the :address)
			  (concatenate 'string
			    (the :city)  ", "
			    (the :state) " "
			    (the :zip))))
  
  :methods
  ((:print-to-stream
    (&key (stream t))
    (latex2e:print-letter :recipient (the :recipient-field) 
			  :opening (the :opening)
			  :closing "Yours Truly,"
			  :body (the :body-string)
			  :stream stream))))

===================================================

Sample of Generated LaTeX:
==============================

\documentclass[letterpaper,10pt]{letter}
\name{David J. Cooper Jr.}
\address{Genworks International\\
         5777 West Maple, Suite 130\\
         West Bloomfield, MI 48125}
\signature{David J. Cooper Jr.\\
           President, Genworks International}
\makelabels
\begin{document}
\begin{letter}{Jane Doe\\
               Big Shot\\
               Acme Industries, Inc.\\
               P.O. Box 55555\\
               Springfield, PA 55555-5555}
\opening{Dear Ms. Doe:}


Recently, you visited our booth at Autofact in Detroit,
or otherwise expressed an interest about a generic
manufacturing process planning system we have developed
using the ICAD System and Common Lisp. 

We at Genworks continue to increase our commitment to
Dynamic Objects and Common Lisp, and remain convinced
that this concentrated vision will allow us to accelerate
the technology gap between the more ``mundane'' approaches
and our own.

Hopefully you have had a chance to review our white paper,
``Understanding Multi-state Generative Process Planning.''

Also, we have recently installed a new web server, powered
by the Common Lisp Hypermedia Server, at
\emph{http://www.genworks.com/}, which will soon be 
host to live running examples of process planning and
related systems.

Please feel free to contact us to arrange for further correspondence and
perhaps an on-site visit, to discuss 
any further questions you may have or your specific 
potential needs for such a system.

Thank you.
\closing{Yours Truly,}

\end{letter}

\begin{letter}

...

...

...


-- 
-----
   "Microsoft is not the answer. Microsoft is a question,
    and the answer is `No.'"