[cl-typesetting-devel] paragraph macro

Cyrus Harmon ch-lisp at bobobeach.com
Mon May 7 02:11:22 UTC 2007


On May 5, 2007, at 2:24 PM, Marc Battyani wrote:

> "Cyrus Harmon" <ch-lisp at bobobeach.com> wrote:
>> 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... :)

Yeah, I wasn't sure why we weren't evaluating this.

>> 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.

Ah yes, this is one of the reasons lisp is so great. Sometimes it  
takes a while for me to wrap my head around things like this.


> Why style is used at compile time is to be able to make  
> optimizations at compile time. (more on that at the end)
>
>> 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.

Good point.

> 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.

Yes, but as you point it, it's nice to be able to wrap those calls in  
a macro to do nice initialization/cleanup stuff.

> Of course, as life is too short to write documentation, all this is  
> probably not obvious ;-)

Or to read it sometimes :)

> 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.

Ah yes, I'm a bit confused why sometimes I can use a naked string and  
other times it seems I need a put-string. I guess insert-stuff is  
handling it sometimes.

>> Thanks again for cl-typesetting and cl-pdf.
>
> Thanks :)
> User friendly text markups are welcome!

Working on it :)

> 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.)

Ok, so I'm working on my with-paragraph macro that evaluates the  
style argument, but I don't understand why we (use-style ,restore- 
style) when ,restore-style is (make-restore-style ,new-style). I  
guess a defgeneric and some docstrings for make-restore-style might  
clue me in.

Thanks again,

Cyrus




More information about the cl-typesetting-devel mailing list