[cl-typesetting-devel] Page n of m?

Peter Seibel peter at javamonkey.com
Thu Sep 30 20:14:39 UTC 2004


"Marc Battyani" <marc.battyani at fractalconcept.com> writes:

> Peter Seibel wrote:
>
>
>> I haven't really spent much time on this, mostly because I somehow
>> picked up the impression that it'd would be a pain. But maybe I'm
>> wrong. Is there an easy way to typeset a document and generate
>> something like a header with "Page n of m" in it where n is the
>> current page number and m is the total number of pages. I've got "Page
>> n" already but I have no idea to get the whole number of pages in
>> advance.
>>
>> -Peter
>>
>> P.S. A more complex version of this is something like cross-references
>> where I want to insert some text along the lines of (see page X) where
>> X is determined at typesetting time based on where some anchor ended
>> up getting placed. And of course there's the wrinkle that depending on
>> the value of X, inserting the text might change the way the pages
>> break. But maybe someone has solved this problem and I just missed it.
>
> Hum, you should follow more closely the evolution of cl-typesetting
> ;-) What you want is called references and it's in references.lisp.

Great! Next you're going to tell me you've already got a mechanism for
doing footnotes.

Hmmmm. Not quite. I did what you said but it thinks my document is 999
pages long. Here's the main bit of my code. Maybe I've just made some
dumb mistake that you can point out:

  (defun sexp->pdf (paragraphs &optional (file #P"/tmp/hello.pdf"))
    (let ((*note-counter* 0)
          (*notes* nil))
      (typeset:with-document ()
        (let ((content
               (typeset::compile-text ()
                 (let ((*my-leading-ratio* 2.0))
                   (dolist (p paragraphs) (emit-pdf p)))
                 (typeset::vspace 24)
                 (typeset::hrule :dy .1)
                 (typeset::vspace 6)
                 (let ((*default-font-size* 10))
                   (loop for n in (nreverse *notes*)
                         for counter from 1
                         do (emit-note counter n)))
                 (typeset:mark-ref-point :the-end))))
          (loop for page-number from 1
                for header = (typeset::compile-text ()
                               (typeset::paragraph
                                (:h-align :right :font "Times-Italic" :font-size 10)
                                (typeset::put-string
                                  (format nil "~a~c~d of ~d"
                                         (second (first paragraphs))
                                         +mdash+
                                         pdf:*page-number*
                                         (typeset:find-ref-point-page-number :the-end))) :eol
                                (typeset::put-string
                                  (format nil "Copyright ~c 2003-2004, Peter Seibel." +copyright+)) :eol
                                (typeset::put-string (date-string)) :eol))
                while (typeset::boxes content)
                do (draw-page content header :width 612 :height 792 :margins '(72 36 72 72) :header-height (- 108 36))))
        (pdf:write-document file)))
    (truename file))


  (defun draw-page (content header &key width height margins (header-height 12))
    (destructuring-bind (left &optional (top left) (right left) (bottom top)) margins
      (let ((x left)
            (y (- height top))
            (dx (- width left right))
            (dy (- height top bottom)))
        (pdf:with-page (:bounds (vector 0 0 width height))
          (pdf:with-saved-state
            (when header (typeset::stroke (typeset::make-filled-vbox header dx header-height :top) x y))
            (typeset::stroke (typeset::make-filled-vbox content  dx (- dy header-height) :top) x (- y header-height)))))))


-Peter

-- 
Peter Seibel                                      peter at javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp




More information about the cl-typesetting-devel mailing list