[cl-typesetting-devel] paragraph macro
Marc Battyani
marc.battyani at fractalconcept.com
Sat May 5 21:24:41 UTC 2007
"Cyrus Harmon" <ch-lisp at bobobeach.com> wrote:
> First of all, thanks for cl-typesetting and cl-pdf. After spending the
> last year or so wrangling my smarkup package into generating suitable
> latex for thinks like the UC thesis package and beamer, I've decided to
> bite the bullet and try to add a cl-typesetting backend to smarkup,
> noticing, of course, that Francois-Rene Rideau has done something similar
> for exscribe.
Great. The more user friendly syntaxes the better!
> What strikes me from playing with cl-typesetting is that the interface,
> or at least the parts of it I'm looking at, look more like a DSL than a
> library. What I mean by this that the macros for things like paragraph
> allow for the following:
>
> (paragraph (:h-align :center :font "Helvetica" :font-size 16 :color '(0.0
> 0 0.6))
> "Table of content")
>
> Which is, of course, nice shorthand and saves the user from typing:
>
> (paragraph '(:h-align :center :font "Helvetica" :font-size 16 :color
> '(0.0 0 0.6))
> "Table of content")
Looks like some sarcasm here... :)
> which would allow (but certainly other reasons might prevent this from
> being the case) for paragraph to be a function instead of a macro.
There are 2 different issues here: Why is it a macro and why style is not
evaluated at run-time.
The reason why it's a macro is to be able to put arbitrary lisp code in the
paragraph generation to write stuff like that:
(paragraph ... (loop for ...) ... (if ...)) you can't do that with a
function.
Why style is used at compile time is to be able to make optimizations at
compile time. (more on that at the end)
> But the problem comes in when I try to do something like:
>
> (defparameter *default-paragraph-font*
> '(:font "Times-Roman" :font-size 12))
>
> (defmethod %render-elt ((tag (eql :p)) contents)
> (tt::paragraph *default-paragraph-font*
> (tt:put-string (collect-elements contents))))
>
> Now perhaps I'm just showing my lack of mad macro-skillz. I suppose I
> could rewrite my code as macros that generate the appropriate forms but
> then I start to get lost in nested backquotes. It would seem easier to
> have something like this:
>
> (defmacro paragraph2 (style &body body)
> (with-gensyms (top-margin bottom-margin first-line-indent
> new-style restore-style first-indent)
> `(let* ((,top-margin (getf ,style :top-margin 0))
> (,bottom-margin (getf ,style :bottom-margin 0))
> (,first-line-indent (getf ,style :first-line-indent 0))
> (,new-style (apply #'make-instance 'text-style ,style))
> (,restore-style (make-restore-style ,new-style))
> (,first-indent ,first-line-indent))
> (add-box ,new-style)
> (use-style ,new-style)
> (add-box (make-instance 'v-spacing :dy ,top-margin))
> (unless (zerop ,first-indent)
> (add-box (make-instance 'h-spacing :dx ,first-indent)))
> ,@(mapcar 'insert-stuff body)
> (unless (eq (first (boxes-tail *content*)) :eol)
> (add-box :eol))
> (add-box (make-instance 'v-spacing :dy ,bottom-margin))
> (add-box ,restore-style)
> (use-style ,restore-style))))
If you want to do something like that, you should at least evaluate style
only once in case it's not just a constant plist.
> but then perhaps I'm missing the point of why style is not evaluated in
> the paragraph macro.
>
> Anyway, I see the argument for the shorthand syntax, but it would be nice
> if there were an equivalent form that evaluated its arguments so that one
> can build functions that call the typesetting functionality.
>
> It's quite possible that I'm 1) completely missing the point here or that
> there are some simple macro tricks that render this point moot, but if so
> the point or the tricks are not obvious to me.
OK here is some information on why it is like that.
When I started cl-typesetting I wanted to generate reports and documents in
web applications. I tried to use TeX but it's almost impossible to do simple
things like nested tables with TeX. Even with the help of a TeX guru! So I
decided to make one that could be embedded into Lisp so that I would have
the access to the full power of Common Lisp rather than some lame weird
macro language. But then there are 2 possible uses of cl-typesetting. The
first one which, for now is its primary use is to generate automated
documents and reports in applications. For this you want to be able to
compile a maximum of things at compile time so that the doc generation is
fast. Hence the heavy use of macros, the use of style at compile time, etc.
The second use which is probably what you want to do is to process a
document description in some kind of markup language at run time and
generally one time only. For this you should use the functional API. i.e.
the functions that are called by the paragraph macro for instance (add-box,
put-string, use-type, etc.). As I don't use cl-typesetting in that mode,
there is probably the need for more high level functions.
Of course, as life is too short to write documentation, all this is probably
not obvious ;-)
Also I didn't find the time to continue the compilation optimization so for
instance constant strings should be converted to boxes at compile time
instead of runtime like it is now.
> Thanks again for cl-typesetting and cl-pdf.
Thanks :)
User friendly text markups are welcome!
BTW there a lot of things I wanted to put in cl-typesetting but never found
the time to do like named styles, finish the math mode (with a TeX
compatible syntax), optimize the compilation, improve the typesetting
engine, etc. So even if I'm not working on it at that moment, that does not
mean it's finished ;-)
(Right now, I'm still working more than 100% of my time on my FPGA based
supercomputer project.)
Marc
More information about the cl-typesetting-devel
mailing list