From marc.battyani at fractalconcept.com Fri Oct 1 08:31:39 2004 From: marc.battyani at fractalconcept.com (Marc Battyani) Date: Fri, 1 Oct 2004 10:31:39 +0200 Subject: [cl-typesetting-devel] Page n of m? References: <142101c4a727$b0585a80$0a02a8c0@marcxp><149101c4a72d$99ef24d0$0a02a8c0@marcxp><70EB07C2-1323-11D9-985D-000A95728F12@recursive.ca><14da01c4a733$5cb987d0$0a02a8c0@marcxp><156c01c4a73a$ca59a1b0$0a02a8c0@marcxp> <15bc01c4a73d$bb9d2c20$0a02a8c0@marcxp> Message-ID: <169d01c4a791$13068f30$0a02a8c0@marcxp> Marc Battyani wrote: > Peter Seibel writes: > > > > Okay, that makes sense. So is my workaround the Right Way or a nasty > > kludge? > > You really want to know ? ;-) > > I will have a deeper look at all this tomorow. I've looked at it. the reason why it worked well for me and not for you was because I used the reference in the text while you were using it only in the footer. It turn out that the footer can be called in a rather out of order way relative to the normal flow of the text (at stroking time). So the right way is to add a located-p to the ref class as a ref can be defined but not yet located when it is seen from a footer. I hope I'm clear enough. Anyway now Bob' example works. The new version is on the repositories.(get cl-pdf also) Please tell me if this works in your case now. Another nice stuff related to references is the contextual variables. Have you looked at it ? Marc From hutch at recursive.ca Fri Oct 1 12:52:19 2004 From: hutch at recursive.ca (Bob Hutchison) Date: Fri, 1 Oct 2004 08:52:19 -0400 Subject: [cl-typesetting-devel] Page n of m? In-Reply-To: <169d01c4a791$13068f30$0a02a8c0@marcxp> References: <142101c4a727$b0585a80$0a02a8c0@marcxp><149101c4a72d$99ef24d0$0a02a8c0@marcxp><70EB07C2-1323-11D9-985D-000A95728F12@recursive.ca><14da01c4a733$5cb987d0$0a02a8c0@marcxp><156c01c4a73a$ca59a1b0$0a02a8c0@marcxp> <15bc01c4a73d$bb9d2c20$0a02a8c0@marcxp> <169d01c4a791$13068f30$0a02a8c0@marcxp> Message-ID: On Oct 1, 2004, at 4:31 AM, Marc Battyani wrote: > Marc Battyani wrote: >> Peter Seibel writes: >>> >>> Okay, that makes sense. So is my workaround the Right Way or a nasty >>> kludge? >> >> You really want to know ? ;-) >> >> I will have a deeper look at all this tomorow. > > I've looked at it. the reason why it worked well for me and not for > you was > because I used the reference in the text while you were using it only > in the > footer. It turn out that the footer can be called in a rather out of > order > way relative to the normal flow of the text (at stroking time). So the > right > way is to add a located-p to the ref class as a ref can be defined but > not > yet located when it is seen from a footer. > I hope I'm clear enough. Anyway now Bob' example works. > > The new version is on the repositories.(get cl-pdf also) > Please tell me if this works in your case now. I've checked this out, and it works for all of my other examples as well. Thanks. > > Another nice stuff related to references is the contextual variables. > Have > you looked at it ? I just had a look. I added a contextual variable to keep track of the paragraph count and I can show it in the header (yes, I know it isn't a great example). Interesting effect going on, not sure why either, but it seems that the paragraph count is not updated until after the whole paragraph is completed (i.e. the counter will contain the number of the last completed paragraph on the page). Actually, when I think about it... when is the header 'computed' for the page? How is this working at all? I've added the modified example at the end of this post. It looks as though we can have a stack of values with contextual variables, so I guess this means that I could keep track of the current section title, pushing and popping as the sections nest. What did you have in mind for these? I also see that there are contextual actions. What did you have in mind for these? What kind of thing can you do here? When are these called? They are triggered by the stroke method, so these are executed at drawing time? Cheers, Bob (defun page-n-of-m (&optional (file #P"/tmp/page-n-of-m.pdf") &aux (content nil) (margins '(72 72 72 50))) (with-document () (let* ((print-stamp (multiple-value-bind (second minute hour date month year) (get-decoded-time) (declare (ignore second)) (format nil "Printed on ~4D-~2,'0D-~2,'0D ~2,'0D:~2,'0D" year month date hour minute))) (sentence1 "The quick brown fox jumps over the lazy dog. ") (sentence2 " associate associates declination obligatory philanthropic.") (header (lambda (pdf:*page*) (compile-text () (hbox (:align :center :adjustable-p t) :hfill (verbatim (format nil "Multi-page example document (paragraph ~A)" (tt::get-contextual-variable :current-paragraph-number -1)))) (hrule :dy 1/2)))) (footer (lambda (pdf:*page*) (compile-text (:font "Helvetica" :font-size 10) (hrule :dy 1/2) (hbox (:align :center :adjustable-p t) (verbatim print-stamp) :hfill (verbatim (format nil "Page ~d of ~d" pdf:*page-number* (tt::find-ref-point-page-number :end-of-doc)))))))) (format t "about to compile...~%") (setq content (compile-text () (paragraph (:font "Times-Bold" :font-size 16 :top-margin 20) "2. Second paragraph group" (hrule :dy 2)) (dotimes (i 400) (tt::set-contextual-variable :current-paragraph-number i) (paragraph (:font "Times-Roman" :font-size (+ 6 (random 10)) :h-align :justified) (verbatim (format nil "2.~d. " (1+ i))) (dotimes (j (1+ (random 5))) (put-string sentence2)))) (unless (typeset::find-ref-point :end-of-doc) (tt::mark-ref-point :end-of-doc)))) (format t "about to draw...~%") (draw-pages content :margins margins :header header :footer footer)) (when pdf:*page* (finalize-page pdf:*page*)) (format t "current pass: ~A ~A, undefined references: ~A, changed-references: ~A~%" tt::*current-pass* (if (tt::final-pass-p) "FINAL" "") tt::*undefined-references* tt::*changed-references*) (when (tt::final-pass-p) (format t "WRITE THE DOCUMENT NOW~%") (pdf:write-document file)))) From hutch at recursive.ca Fri Oct 1 13:26:10 2004 From: hutch at recursive.ca (Bob Hutchison) Date: Fri, 1 Oct 2004 09:26:10 -0400 Subject: [cl-typesetting-devel] Page n of m? In-Reply-To: References: <142101c4a727$b0585a80$0a02a8c0@marcxp><149101c4a72d$99ef24d0$0a02a8c0@marcxp><70EB07C2-1323-11D9-985D-000A95728F12@recursive.ca><14da01c4a733$5cb987d0$0a02a8c0@marcxp><156c01c4a73a$ca59a1b0$0a02a8c0@marcxp> <15bc01c4a73d$bb9d2c20$0a02a8c0@marcxp> <169d01c4a791$13068f30$0a02a8c0@marcxp> Message-ID: <75645A8C-13AD-11D9-B817-000A95728F12@recursive.ca> On Oct 1, 2004, at 8:52 AM, Bob Hutchison wrote: >> >> Another nice stuff related to references is the contextual variables. >> Have >> you looked at it ? > > I just had a look. I added a contextual variable to keep track of the > paragraph count and I can show it in the header (yes, I know it isn't > a great example). Interesting effect going on, not sure why either, > but it seems that the paragraph count is not updated until after the > whole paragraph is completed (i.e. the counter will contain the number > of the last completed paragraph on the page). Actually, when I think > about it... when is the header 'computed' for the page? How is this > working at all? I've added the modified example at the end of this > post. Sorry, my mistake. There are a bunch of errors in the code I used that wound up with that phenomenon. The contextual variables appear to work exactly as one would expect. Cheers, Bob From marc.battyani at fractalconcept.com Fri Oct 1 13:44:31 2004 From: marc.battyani at fractalconcept.com (Marc Battyani) Date: Fri, 1 Oct 2004 15:44:31 +0200 Subject: [cl-typesetting-devel] Page n of m? References: <142101c4a727$b0585a80$0a02a8c0@marcxp><149101c4a72d$99ef24d0$0a02a8c0@marcxp><70EB07C2-1323-11D9-985D-000A95728F12@recursive.ca><14da01c4a733$5cb987d0$0a02a8c0@marcxp><156c01c4a73a$ca59a1b0$0a02a8c0@marcxp><15bc01c4a73d$bb9d2c20$0a02a8c0@marcxp><169d01c4a791$13068f30$0a02a8c0@marcxp> Message-ID: <189f01c4a7bc$c8cdfe90$0a02a8c0@marcxp> Bob Hutchison wrote: > On Oct 1, 2004, at 4:31 AM, Marc Battyani wrote: > > > The new version is on the repositories.(get cl-pdf also) > > Please tell me if this works in your case now. > > I've checked this out, and it works for all of my other examples as > well. Thanks. Great. ... > It looks as though we can have a stack of values with contextual > variables, so I guess this means that I could keep track of the current > section title, pushing and popping as the sections nest. What did you > have in mind for these? Exactly this kind of stuff. > I also see that there are contextual actions. What did you have in mind > for these? What kind of thing can you do here? When are these called? > They are triggered by the stroke method, so these are executed at > drawing time? It's to be able to execute arbitrary lisp code when we reach some point on the page. Like putting a mark or a symbol in the margin for instance. I'm not sure this will be used every day but who knows? ;-) Marc From peter at javamonkey.com Fri Oct 1 17:43:33 2004 From: peter at javamonkey.com (Peter Seibel) Date: Fri, 01 Oct 2004 10:43:33 -0700 Subject: [cl-typesetting-devel] Page n of m? In-Reply-To: <169d01c4a791$13068f30$0a02a8c0@marcxp> (Marc Battyani's message of "Fri, 1 Oct 2004 10:31:39 +0200") References: <142101c4a727$b0585a80$0a02a8c0@marcxp> <149101c4a72d$99ef24d0$0a02a8c0@marcxp> <70EB07C2-1323-11D9-985D-000A95728F12@recursive.ca> <14da01c4a733$5cb987d0$0a02a8c0@marcxp> <156c01c4a73a$ca59a1b0$0a02a8c0@marcxp> <15bc01c4a73d$bb9d2c20$0a02a8c0@marcxp> <169d01c4a791$13068f30$0a02a8c0@marcxp> Message-ID: "Marc Battyani" writes: > Marc Battyani wrote: >> Peter Seibel writes: >> > >> > Okay, that makes sense. So is my workaround the Right Way or a nasty >> > kludge? >> >> You really want to know ? ;-) >> >> I will have a deeper look at all this tomorow. > > I've looked at it. the reason why it worked well for me and not for you was > because I used the reference in the text while you were using it only in the > footer. It turn out that the footer can be called in a rather out of order > way relative to the normal flow of the text (at stroking time). So the right > way is to add a located-p to the ref class as a ref can be defined but not > yet located when it is seen from a footer. > I hope I'm clear enough. Anyway now Bob' example works. > > The new version is on the repositories.(get cl-pdf also) > Please tell me if this works in your case now. I haven't tried your new version yet because I had an idea last night about what the problem might be. The thing that lead me down the path to my workaround of yesterday was noticing that while my reference got correctly located (page-number, x, and y set) in stroke, that on the second pass it would get replaced by a new, unlocated reference when mark-ref-point was called. My workaround was a kludge but I think the idea was right--if mark-ref-point is called because a subsequent pass is being processed (so the ref is not in *reference-table* but is in *previous-reference-table*) then instead of making a new ref-point we should copy the previous ref-point. Then the test in stroke to determine whether the ref-point has been changed is more straightforward--if the current values are different than the ones actually stored in the reference it is changing. Below is a patch. I'll revert this and try your new code but you can feel free to fold it in if appropriate. > Another nice stuff related to references is the contextual variables. Have > you looked at it ? Nope. Someday in my copious free time. ;-) -Peter -Peter Index: references.lisp =================================================================== --- references.lisp (revision 63) +++ references.lisp (working copy) @@ -18,31 +18,35 @@ (y :accessor y :initform nil))) (defmethod stroke ((ref-point ref-point) x y) - (let ((previous-ref (and *previous-reference-table* - (gethash (id ref-point) *previous-reference-table*))) - (page-number pdf:*page-number*)) - (when (and previous-ref (/= page-number (page-number previous-ref))) - (push (id ref-point) *changed-references*)) - (setf (page-number ref-point) page-number - (x ref-point) x - (y ref-point) y))) + (let ((page-number pdf:*page-number*)) + (when (or (/= page-number (page-number ref-point)) + (/= x (x ref-point)) + (/= y (y ref-point))) + (push (id ref-point) *changed-references*) + (setf (page-number ref-point) page-number + (x ref-point) x + (y ref-point) y)))) (defun mark-ref-point (id &rest args &key (type 'ref-point)) (when (gethash id *reference-table*) - (error "Reference ~s redefined" id)) + (error "Reference ~s redefined within single pass." id)) (remf args :type) - (let* ((ref-point (apply #'make-instance type :id id args))) + (let* ((ref-point (or (find-previous-ref-point id) + (apply #'make-instance type :id id args)))) (setf (gethash id *reference-table*) ref-point) (add-box ref-point))) (defun find-ref-point (id) (let ((ref-point (or (gethash id *reference-table*) - (and *previous-reference-table* - (gethash id *previous-reference-table*))))) + (find-previous-ref-point id)))) (unless ref-point (pushnew id *undefined-references*)) ref-point)) +(defun find-previous-ref-point (id) + (and *previous-reference-table* + (gethash id *previous-reference-table*))) + (defun find-ref-point-page-number (id) (let ((ref-point (find-ref-point id))) (if ref-point -- Peter Seibel peter at javamonkey.com Lisp is the red pill. -- John Fraser, comp.lang.lisp From marc.battyani at fractalconcept.com Fri Oct 1 19:10:55 2004 From: marc.battyani at fractalconcept.com (Marc Battyani) Date: Fri, 1 Oct 2004 21:10:55 +0200 Subject: [cl-typesetting-devel] Page n of m? References: <142101c4a727$b0585a80$0a02a8c0@marcxp><149101c4a72d$99ef24d0$0a02a8c0@marcxp><70EB07C2-1323-11D9-985D-000A95728F12@recursive.ca><14da01c4a733$5cb987d0$0a02a8c0@marcxp> <156c01c4a73a$ca59a1b0$0a02a8c0@marcxp><15bc01c4a73d$bb9d2c20$0a02a8c0@marcxp><169d01c4a791$13068f30$0a02a8c0@marcxp> Message-ID: <199f01c4a7ea$615ae830$0a02a8c0@marcxp> Peter Seibel writes: > > I haven't tried your new version yet because I had an idea last night > about what the problem might be. The thing that lead me down the path > to my workaround of yesterday was noticing that while my reference got > correctly located (page-number, x, and y set) in stroke, that on the > second pass it would get replaced by a new, unlocated reference when > mark-ref-point was called. My workaround was a kludge but I think the > idea was right--if mark-ref-point is called because a subsequent pass > is being processed (so the ref is not in *reference-table* but is in > *previous-reference-table*) then instead of making a new ref-point we > should copy the previous ref-point. Then the test in stroke to > determine whether the ref-point has been changed is more > straightforward--if the current values are different than the ones > actually stored in the reference it is changing. Below is a patch. > I'll revert this and try your new code but you can feel free to fold > it in if appropriate. The located-p stuff I added is still needed because of the header/footer and other out of order things. But your idea of copying the previous ref makes me think that reusing the reference is a good idea. In fact looking at your code make me think that this previous-ref stuff in not needed at all now that there is located-p I will look at this now. Checking if the x and y coordonates have changed is probably too strict and will give many redefined refs IMO. > > Another nice stuff related to references is the contextual variables. Have > > you looked at it ? > > Nope. Someday in my copious free time. ;-) He he... I can understand that. The 24h/day limit is a nuisance. ;-) Marc From peter at javamonkey.com Fri Oct 1 19:18:16 2004 From: peter at javamonkey.com (Peter Seibel) Date: Fri, 01 Oct 2004 12:18:16 -0700 Subject: [cl-typesetting-devel] Page n of m? In-Reply-To: <199f01c4a7ea$615ae830$0a02a8c0@marcxp> (Marc Battyani's message of "Fri, 1 Oct 2004 21:10:55 +0200") References: <142101c4a727$b0585a80$0a02a8c0@marcxp> <149101c4a72d$99ef24d0$0a02a8c0@marcxp> <70EB07C2-1323-11D9-985D-000A95728F12@recursive.ca> <14da01c4a733$5cb987d0$0a02a8c0@marcxp> <156c01c4a73a$ca59a1b0$0a02a8c0@marcxp> <15bc01c4a73d$bb9d2c20$0a02a8c0@marcxp> <169d01c4a791$13068f30$0a02a8c0@marcxp> <199f01c4a7ea$615ae830$0a02a8c0@marcxp> Message-ID: "Marc Battyani" writes: > Peter Seibel writes: >> >> I haven't tried your new version yet because I had an idea last night >> about what the problem might be. The thing that lead me down the path >> to my workaround of yesterday was noticing that while my reference got >> correctly located (page-number, x, and y set) in stroke, that on the >> second pass it would get replaced by a new, unlocated reference when >> mark-ref-point was called. My workaround was a kludge but I think the >> idea was right--if mark-ref-point is called because a subsequent pass >> is being processed (so the ref is not in *reference-table* but is in >> *previous-reference-table*) then instead of making a new ref-point we >> should copy the previous ref-point. Then the test in stroke to >> determine whether the ref-point has been changed is more >> straightforward--if the current values are different than the ones >> actually stored in the reference it is changing. Below is a patch. >> I'll revert this and try your new code but you can feel free to fold >> it in if appropriate. > > The located-p stuff I added is still needed because of the > header/footer and other out of order things. But your idea of > copying the previous ref makes me think that reusing the reference > is a good idea. In fact looking at your code make me think that this > previous-ref stuff in not needed at all now that there is located-p > I will look at this now. Cool. BTW, my code also genenerated headers out of order. At least I think so--I compile-text the main body of my document which includes the mark-ref-point call and then I loop using compile-text to build a header and drawing the individual pages. And that worked with just my patch. (You can see my code in earlier messages.) > Checking if the x and y coordonates have changed is probably too > strict and will give many redefined refs IMO. Yes. I did have to bump up *max-number-of-passes* to get it to actually settle down. (Took three passes instead of two.) -Peter -- Peter Seibel peter at javamonkey.com Lisp is the red pill. -- John Fraser, comp.lang.lisp From hutch at recursive.ca Fri Oct 1 20:16:50 2004 From: hutch at recursive.ca (Bob Hutchison) Date: Fri, 1 Oct 2004 16:16:50 -0400 Subject: [cl-typesetting-devel] Page n of m? In-Reply-To: References: <142101c4a727$b0585a80$0a02a8c0@marcxp> <149101c4a72d$99ef24d0$0a02a8c0@marcxp> <70EB07C2-1323-11D9-985D-000A95728F12@recursive.ca> <14da01c4a733$5cb987d0$0a02a8c0@marcxp> <156c01c4a73a$ca59a1b0$0a02a8c0@marcxp> <15bc01c4a73d$bb9d2c20$0a02a8c0@marcxp> <169d01c4a791$13068f30$0a02a8c0@marcxp> <199f01c4a7ea$615ae830$0a02a8c0@marcxp> Message-ID: On Oct 1, 2004, at 3:18 PM, Peter Seibel wrote: > >> Checking if the x and y coordonates have changed is probably too >> strict and will give many redefined refs IMO. > > Yes. I did have to bump up *max-number-of-passes* to get it to > actually settle down. (Took three passes instead of two.) > > I hate to bring this up, but it would be very good to minimise the number of passes. I've attached the output of extended-time (lispworks on a mac) for a 173 page test. The elapsed time was almost 4 minutes (more like 3.5 minutes of actual work though). This is already a lot of time, I think, and a third pass would take another couple of minutes. More importantly is that half the execution time is in the garbage collector with 1.3 *billion* bytes allocated to generate a 1.5 million byte pdf -- a 1000x factor. (and I've done some things to try to reduce the amount of memory used) user time = 204.700 system time = 3.500 Elapsed time = 0:03:52 Allocation = 1,288,097,632 bytes 0 Page faults total / user / system total gc activity = 101.130000 / 99.300000 / 1.830000 main promote ( 43 calls) = 49.860000 / 48.670000 / 1.190000 mark and sweep ( 250 calls) = 50.230000 / 49.600000 / 0.630000 internal promote ( 16 calls) = 16.640000 / 15.750000 / 0.890000 promote ( 0 calls) = 0.000000 / 0.000000 / 0.000000 fixup ( 128 calls) = 24.740000 / 24.560000 / 0.180000 compact ( 19 calls) = 1.040000 / 1.030000 / 0.010000 From marc.battyani at fractalconcept.com Fri Oct 1 20:27:42 2004 From: marc.battyani at fractalconcept.com (Marc Battyani) Date: Fri, 1 Oct 2004 22:27:42 +0200 Subject: [cl-typesetting-devel] Page n of m? References: <142101c4a727$b0585a80$0a02a8c0@marcxp><149101c4a72d$99ef24d0$0a02a8c0@marcxp><70EB07C2-1323-11D9-985D-000A95728F12@recursive.ca><14da01c4a733$5cb987d0$0a02a8c0@marcxp> <156c01c4a73a$ca59a1b0$0a02a8c0@marcxp><15bc01c4a73d$bb9d2c20$0a02a8c0@marcxp><169d01c4a791$13068f30$0a02a8c0@marcxp><199f01c4a7ea$615ae830$0a02a8c0@marcxp> Message-ID: <19f001c4a7f5$1ac9dec0$0a02a8c0@marcxp> Bob Hutchison wrote: > > I hate to bring this up, but it would be very good to minimise the > number of passes. I've attached the output of extended-time (lispworks > on a mac) for a 173 page test. The elapsed time was almost 4 minutes > (more like 3.5 minutes of actual work though). This is already a lot of > time, I think, and a third pass would take another couple of minutes. > More importantly is that half the execution time is in the garbage > collector with 1.3 *billion* bytes allocated to generate a 1.5 million > byte pdf -- a 1000x factor. (and I've done some things to try to reduce > the amount of memory used) Generally 2 passes are enough. Anway it's far from being optimized. In particular, when it's not the final pass it should be avoided to really generate the pdf as we will discard it at the end. The biggest document I generate has 1300+ pages with thousands or refs (TOC + index) It takes 12 minutes and 2 passes. Marc From marc.battyani at fractalconcept.com Fri Oct 1 20:33:28 2004 From: marc.battyani at fractalconcept.com (Marc Battyani) Date: Fri, 1 Oct 2004 22:33:28 +0200 Subject: [cl-typesetting-devel] Page n of m? References: <142101c4a727$b0585a80$0a02a8c0@marcxp><149101c4a72d$99ef24d0$0a02a8c0@marcxp><70EB07C2-1323-11D9-985D-000A95728F12@recursive.ca><14da01c4a733$5cb987d0$0a02a8c0@marcxp> <156c01c4a73a$ca59a1b0$0a02a8c0@marcxp><15bc01c4a73d$bb9d2c20$0a02a8c0@marcxp><169d01c4a791$13068f30$0a02a8c0@marcxp><199f01c4a7ea$615ae830$0a02a8c0@marcxp> Message-ID: <19fc01c4a7f5$e9651b00$0a02a8c0@marcxp> Peter Seibel writes: > > Cool. BTW, my code also genenerated headers out of order. At least I > think so--I compile-text the main body of my document which includes > the mark-ref-point call and then I loop using compile-text to build a > header and drawing the individual pages. And that worked with just my > patch. (You can see my code in earlier messages.) > > > Checking if the x and y coordonates have changed is probably too > > strict and will give many redefined refs IMO. > > Yes. I did have to bump up *max-number-of-passes* to get it to > actually settle down. (Took three passes instead of two.) It can potentially never completely settle with the floats computations. I finished the rewriting of the references processing with only one ref table. I discarded all the "previous" stuff. Can you please tests if it still work for you. Marc From peter at javamonkey.com Fri Oct 1 20:55:48 2004 From: peter at javamonkey.com (Peter Seibel) Date: Fri, 01 Oct 2004 13:55:48 -0700 Subject: [cl-typesetting-devel] Page n of m? In-Reply-To: <19fc01c4a7f5$e9651b00$0a02a8c0@marcxp> (Marc Battyani's message of "Fri, 1 Oct 2004 22:33:28 +0200") References: <142101c4a727$b0585a80$0a02a8c0@marcxp> <149101c4a72d$99ef24d0$0a02a8c0@marcxp> <70EB07C2-1323-11D9-985D-000A95728F12@recursive.ca> <14da01c4a733$5cb987d0$0a02a8c0@marcxp> <156c01c4a73a$ca59a1b0$0a02a8c0@marcxp> <15bc01c4a73d$bb9d2c20$0a02a8c0@marcxp> <169d01c4a791$13068f30$0a02a8c0@marcxp> <199f01c4a7ea$615ae830$0a02a8c0@marcxp> <19fc01c4a7f5$e9651b00$0a02a8c0@marcxp> Message-ID: "Marc Battyani" writes: > Peter Seibel writes: >> >> Cool. BTW, my code also genenerated headers out of order. At least I >> think so--I compile-text the main body of my document which includes >> the mark-ref-point call and then I loop using compile-text to build a >> header and drawing the individual pages. And that worked with just my >> patch. (You can see my code in earlier messages.) >> >> > Checking if the x and y coordonates have changed is probably too >> > strict and will give many redefined refs IMO. >> >> Yes. I did have to bump up *max-number-of-passes* to get it to >> actually settle down. (Took three passes instead of two.) > > It can potentially never completely settle with the floats computations. > > I finished the rewriting of the references processing with only one ref > table. I discarded all the "previous" stuff. > > Can you please tests if it still work for you. Yup, looks good. Thanks. In the meantime I gave contextual variables a whirl, trying to add the name of the current chapter to my headers. And it works great except the very first time I call get-contextual-variable it returns NIL. Basically I modified this function that emits the chapter headers. (defmethod emit-pdf-by-type ((type (eql 'text-parser::chapter)) children) (typeset::fresh-page) (typeset::set-contextual-variable 'chapter-name (first children)) ;; <--- new (typeset::paragraph (:h-align :left :font "Helvetica" :font-size 24) (typeset::vspace 24) (dolist (c children) (emit-pdf c)))) and then changed my sexp->pdf function to use get-contextual-variable to get at the chapter when compiling the header: (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 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" (typeset::get-contextual-variable 'chapter-name) +mdash+ (1+ 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)) It works fine for all but the first page. Even when the chapter changes--the header on the first page of all the chapters after the first gets the right title. Any suggestions. -Peter -- Peter Seibel peter at javamonkey.com Lisp is the red pill. -- John Fraser, comp.lang.lisp From peter at javamonkey.com Fri Oct 1 21:53:02 2004 From: peter at javamonkey.com (Peter Seibel) Date: Fri, 01 Oct 2004 14:53:02 -0700 Subject: [cl-typesetting-devel] Page n of m? In-Reply-To: (Peter Seibel's message of "Fri, 01 Oct 2004 13:55:48 -0700") References: <142101c4a727$b0585a80$0a02a8c0@marcxp> <149101c4a72d$99ef24d0$0a02a8c0@marcxp> <70EB07C2-1323-11D9-985D-000A95728F12@recursive.ca> <14da01c4a733$5cb987d0$0a02a8c0@marcxp> <156c01c4a73a$ca59a1b0$0a02a8c0@marcxp> <15bc01c4a73d$bb9d2c20$0a02a8c0@marcxp> <169d01c4a791$13068f30$0a02a8c0@marcxp> <199f01c4a7ea$615ae830$0a02a8c0@marcxp> <19fc01c4a7f5$e9651b00$0a02a8c0@marcxp> Message-ID: Peter Seibel writes: > It works fine for all but the first page. Even when the chapter > changes--the header on the first page of all the chapters after the > first gets the right title. Actually I take that back--the variable doesn't change until the second page of each chapter. Which actually makes more sense. So the question is how do I generate the header so that it sees the value of the variable even before the header on the first page has been emitted? -Peter -- Peter Seibel peter at javamonkey.com Lisp is the red pill. -- John Fraser, comp.lang.lisp From marc.battyani at fractalconcept.com Sat Oct 2 08:33:10 2004 From: marc.battyani at fractalconcept.com (Marc Battyani) Date: Sat, 2 Oct 2004 10:33:10 +0200 Subject: [cl-typesetting-devel] Page n of m? References: <142101c4a727$b0585a80$0a02a8c0@marcxp><149101c4a72d$99ef24d0$0a02a8c0@marcxp><70EB07C2-1323-11D9-985D-000A95728F12@recursive.ca><14da01c4a733$5cb987d0$0a02a8c0@marcxp> <156c01c4a73a$ca59a1b0$0a02a8c0@marcxp><15bc01c4a73d$bb9d2c20$0a02a8c0@marcxp><169d01c4a791$13068f30$0a02a8c0@marcxp><199f01c4a7ea$615ae830$0a02a8c0@marcxp><19fc01c4a7f5$e9651b00$0a02a8c0@marcxp> Message-ID: <1ac001c4a85a$73cc0510$0a02a8c0@marcxp> Peter Seibel wrote: > Actually I take that back--the variable doesn't change until the > second page of each chapter. Which actually makes more sense. So the > question is how do I generate the header so that it sees the value of > the variable even before the header on the first page has been > emitted? Do you stroke the header and footer after the page content ? The contextual variables are set by #'stroke. Marc From peter at javamonkey.com Sat Oct 2 20:59:04 2004 From: peter at javamonkey.com (Peter Seibel) Date: Sat, 02 Oct 2004 13:59:04 -0700 Subject: [cl-typesetting-devel] Page n of m? In-Reply-To: <1ac001c4a85a$73cc0510$0a02a8c0@marcxp> (Marc Battyani's message of "Sat, 2 Oct 2004 10:33:10 +0200") References: <142101c4a727$b0585a80$0a02a8c0@marcxp> <149101c4a72d$99ef24d0$0a02a8c0@marcxp> <70EB07C2-1323-11D9-985D-000A95728F12@recursive.ca> <14da01c4a733$5cb987d0$0a02a8c0@marcxp> <156c01c4a73a$ca59a1b0$0a02a8c0@marcxp> <15bc01c4a73d$bb9d2c20$0a02a8c0@marcxp> <169d01c4a791$13068f30$0a02a8c0@marcxp> <199f01c4a7ea$615ae830$0a02a8c0@marcxp> <19fc01c4a7f5$e9651b00$0a02a8c0@marcxp> <1ac001c4a85a$73cc0510$0a02a8c0@marcxp> Message-ID: "Marc Battyani" writes: > Peter Seibel wrote: > >> Actually I take that back--the variable doesn't change until the >> second page of each chapter. Which actually makes more sense. So the >> question is how do I generate the header so that it sees the value of >> the variable even before the header on the first page has been >> emitted? > > Do you stroke the header and footer after the page content ? > The contextual variables are set by #'stroke. Ah, I see. I was calling compile-text before anything got stroked. I moved some stuff around and now it is working. Thanks. -Peter -- Peter Seibel peter at javamonkey.com Lisp is the red pill. -- John Fraser, comp.lang.lisp From hutch at recursive.ca Sun Oct 3 13:48:25 2004 From: hutch at recursive.ca (Bob Hutchison) Date: Sun, 3 Oct 2004 09:48:25 -0400 Subject: [cl-typesetting-devel] Page n of m? In-Reply-To: <189f01c4a7bc$c8cdfe90$0a02a8c0@marcxp> References: <142101c4a727$b0585a80$0a02a8c0@marcxp><149101c4a72d$99ef24d0$0a02a8c0@marcxp><70EB07C2-1323-11D9-985D-000A95728F12@recursive.ca><14da01c4a733$5cb987d0$0a02a8c0@marcxp><156c01c4a73a$ca59a1b0$0a02a8c0@marcxp><15bc01c4a73d$bb9d2c20$0a02a8c0@marcxp><169d01c4a791$13068f30$0a02a8c0@marcxp> <189f01c4a7bc$c8cdfe90$0a02a8c0@marcxp> Message-ID: On Oct 1, 2004, at 9:44 AM, Marc Battyani wrote: >> I also see that there are contextual actions. What did you have in >> mind >> for these? What kind of thing can you do here? When are these called? >> They are triggered by the stroke method, so these are executed at >> drawing time? > > It's to be able to execute arbitrary lisp code when we reach some > point on > the page. > Like putting a mark or a symbol in the margin for instance. > I'm not sure this will be used every day but who knows? ;-) I might have come up with an everyday use, unless you can think of a better way to do this. Say you wanted to put in the header of your document the range of paragraphs or sections appearing on the page. For now, lets count paragraphs rather than sections. I was able to use contextual variables to get the last paragraph appearing on the page and show it in the header without any difficulties. This doesn't appear to be the case for the first paragraph though. To get the first paragraph appearing on the page, it seems to me anyway, that you need to have a variable that is set by the first paragraph appearing on the page, not set by any other paragraph, and then used and reset by the header (the first paragraph knows it is first because the variable is reset). I tried this with contextual variables, but the logic to set/reset is executed too early -- during the generation phase -- while the logic to use the value is too late -- during the draw phase. So, enter contextual actions. I defined a variable first-paragraph-number-on-page in a let that wrapped all the code to generate the document (it could have been a special variable, of course, but this was easy in my example). I defined a header-action function: (header-action () (setf first-paragraph-number-on-page 0)) in a labels scope. Then in another function defined in the same labels scope added this line to the code that generates the header: (tt::add-contextual-action #'header-action) In that same labels scope is a function that generates each paragraph, into which I added the following code. (tt::set-contextual-variable :current-paragraph-number (1+ i)) (tt::add-contextual-action (lambda () (when (zerop first-paragraph-number-on-page) (setf first-paragraph-number-on-page (1+ i))))) The contextual action for the paragraph had to be a lambda to capture the local variable 'i' that contains the paragraph number. Anyway. Unless you have a better idea, this might be your every-day use :-) In fact, it might be every-day enough to introduce some kind of abstraction like a 'deferred-contextual-variable'. -- BTW, I don't think these posts are making their way onto the mailing list. There are no list related headers in the messages on this thread. Cheers, Bob From marc.battyani at fractalconcept.com Sun Oct 3 16:16:50 2004 From: marc.battyani at fractalconcept.com (Marc Battyani) Date: Sun, 3 Oct 2004 18:16:50 +0200 Subject: [cl-typesetting-devel] Page n of m? References: <142101c4a727$b0585a80$0a02a8c0@marcxp><149101c4a72d$99ef24d0$0a02a8c0@marcxp><70EB07C2-1323-11D9-985D-000A95728F12@recursive.ca><14da01c4a733$5cb987d0$0a02a8c0@marcxp><156c01c4a73a$ca59a1b0$0a02a8c0@marcxp><15bc01c4a73d$bb9d2c20$0a02a8c0@marcxp><169d01c4a791$13068f30$0a02a8c0@marcxp> <189f01c4a7bc$c8cdfe90$0a02a8c0@marcxp> Message-ID: <017501c4a964$646ceb60$0a02a8c0@marcxp> Bob Hutchison wrote: > On Oct 1, 2004, at 9:44 AM, Marc Battyani wrote: > > > I'm not sure this will be used every day but who knows? ;-) > > I might have come up with an everyday use, unless you can think of a > better way to do this. > > Say you wanted to put in the header of your document the range of > paragraphs or sections appearing on the page. For now, lets count > paragraphs rather than sections. I was able to use contextual variables > to get the last paragraph appearing on the page and show it in the > header without any difficulties. This doesn't appear to be the case for > the first paragraph though. > > To get the first paragraph appearing on the page, it seems to me > anyway, that you need to have a variable that is set by the first > paragraph appearing on the page, not set by any other paragraph, and > then used and reset by the header (the first paragraph knows it is > first because the variable is reset). I tried this with contextual > variables, but the logic to set/reset is executed too early -- during > the generation phase -- while the logic to use the value is too late -- > during the draw phase. > > So, enter contextual actions. I defined a variable > first-paragraph-number-on-page in a let that wrapped all the code to > generate the document (it could have been a special variable, of > course, but this was easy in my example). I defined a header-action > function: > > (header-action () > (setf first-paragraph-number-on-page 0)) > > in a labels scope. Then in another function defined in the same labels > scope added this line to the code that generates the header: > > (tt::add-contextual-action #'header-action) > > In that same labels scope is a function that generates each paragraph, > into which I added the following code. > > (tt::set-contextual-variable :current-paragraph-number (1+ i)) > (tt::add-contextual-action (lambda () > (when (zerop > first-paragraph-number-on-page) > (setf first-paragraph-number-on-page (1+ > i))))) > > The contextual action for the paragraph had to be a lambda to capture > the local variable 'i' that contains the paragraph number. > > Anyway. Unless you have a better idea, this might be your every-day use > :-) In fact, it might be every-day enough to introduce some kind of > abstraction like a 'deferred-contextual-variable'. Seems a good usage of contextual actions for me. But I don't see what would be a deferred-contextual-variable (ie deferred until what ?) Maybe a set-if-nil or something like that could be enough to do this. > BTW, I don't think these posts are making their way onto the mailing > list. There are no list related headers in the messages on this thread. The thread is visible in the archive, so it's probably good. You mean you don't receive messages from the list, only the direct messages? Marc From peter at javamonkey.com Tue Oct 5 18:31:32 2004 From: peter at javamonkey.com (Peter Seibel) Date: Tue, 05 Oct 2004 11:31:32 -0700 Subject: [cl-typesetting-devel] Anyway to measure the size of some text Message-ID: Is there any way to determine the "natural" size of some generated text? For instance I have this function that generates a header: (defun compile-header (content-width) (let ((cols 2)) (typeset:table (:col-widths (loop repeat cols collect (/ content-width cols)) :border 0 :padding 0 :cell-padding 0) (typeset::row () (typeset:cell () (typeset::paragraph (:h-align :left :font "Times-Italic" :font-size 10) (typeset::put-string (typeset::get-contextual-variable 'chapter-name)))) (typeset:cell () (typeset::paragraph (:h-align :right :font "Times-Italic" :font-size 10) (typeset::put-string (format nil "Page ~d of ~d" pdf:*page-number* (typeset:find-ref-point-page-number :the-end))))))))) But I want to layout the table based on the natural widths of the contents of the cells. In particular in this case I'd like to know the minimum width of the second cell in order to avoid wrapping the contents so I can then set :col-widths of the table to make the second column that wide and give the remainder to the first cell. -Peter -- Peter Seibel peter at javamonkey.com Lisp is the red pill. -- John Fraser, comp.lang.lisp From marc.battyani at fractalconcept.com Tue Oct 5 19:08:40 2004 From: marc.battyani at fractalconcept.com (Marc Battyani) Date: Tue, 5 Oct 2004 21:08:40 +0200 Subject: [cl-typesetting-devel] Anyway to measure the size of some text References: Message-ID: <041701c4ab0e$ba2168a0$0a04a8c0@marcxp> Peter Seibel wrote: > Is there any way to determine the "natural" size of some generated > text? For instance I have this function that generates a header: > > (defun compile-header (content-width) > (let ((cols 2)) > (typeset:table > (:col-widths (loop repeat cols collect (/ content-width cols)) > :border 0 > :padding 0 > :cell-padding 0) > (typeset::row () > (typeset:cell () > (typeset::paragraph > (:h-align :left :font "Times-Italic" :font-size 10) > (typeset::put-string > (typeset::get-contextual-variable 'chapter-name)))) > (typeset:cell () > (typeset::paragraph > (:h-align :right :font "Times-Italic" :font-size 10) > (typeset::put-string (format nil "Page ~d of ~d" > pdf:*page-number* > (typeset:find-ref-point-page-number :the-end))))))))) > > But I want to layout the table based on the natural widths of the > contents of the cells. In particular in this case I'd like to know the > minimum width of the second cell in order to avoid wrapping the > contents so I can then set :col-widths of the table to make the second > column that wide and give the remainder to the first cell. Automatic layout of tables is a very tough problem. It's a pity that I can't find some time to play with it. :( To compute the size of some content you just have to do something like this: META-WEB 19 > (defparameter *content* (typeset::compile-text () (typeset::paragraph (:h-align :right :font "Times-Italic" :font-size 10) (typeset::put-string (format nil "Page ~d of ~d" 12 15))))) *content* META-WEB 20 > (typeset::compute-boxes-natural-size (typeset::boxes *content*) 'typeset::dx) 54.83 META-WEB 21 > (typeset::compute-parallel-size (typeset::boxes *content*) 'typeset::dy) 12.0 10 This will only work on a single line content. If you add the following functions to typo.lisp you can then directly put the text-content in the cell. (warning: not tested, it it works I will add this to typo.lisp) (defun add-boxes-to-content (content boxes) (when content (setf (boxes-tail content) (setf (cdr (boxes-tail content)) boxes))) boxes) (defun add-text-content (content) (when content (add-boxes-to-content *content* (cdr (boxes content))) (clear-content content)) content) Marc From peter at javamonkey.com Tue Oct 5 20:19:20 2004 From: peter at javamonkey.com (Peter Seibel) Date: Tue, 05 Oct 2004 13:19:20 -0700 Subject: [cl-typesetting-devel] hyphenation patch Message-ID: There was a slight bug in hyphenation.lisp that caused it to sometimes hyphenate a word after the first character despite *left-hyphen-minimum* being 2. Below is a patch to hyphenatation.lisp (as well as a tiny bit of tidying to hyphenatation-fp.lisp to get rid of some unportable SETFs of undeclared variables.) If you wanted you might also get rid of the checks in hyphenatation that the string and word are greater than 4 characters long--since hyphen-find-hyphen-points observes *left-hyphen-minimum* and *right-hyphen-minimum* those checks aren't really needed. -Peter Index: hyphenation.lisp =================================================================== --- hyphenation.lisp (revision 66) +++ hyphenation.lisp (working copy) @@ -4,12 +4,13 @@ (in-package typeset) (defun hyphenate-string (string) -(when (> (length string) 4) - (loop with hyphen-points - for start = 0 then (position-if #'alpha-char-p string :start (1+ end)) - for end = (when start (position-if-not #'alpha-char-p string :start (1+ start))) - while end - when (> (- end start) 4) - nconc (mapcar #'(lambda (n) (+ start n)) - (nix::hyphen-find-hyphen-points - nix::*american-hyphen-trie* (subseq string start end)))))) + (when (> (length string) 4) + (loop + for prev-word-end = 0 then word-end + for word-start = (position-if #'alpha-char-p string :start prev-word-end) + for word-end = (when word-start (position-if-not #'alpha-char-p string :start word-start)) + while word-end + when (> (- word-end word-start) 4) + nconc (mapcar #'(lambda (n) (+ word-start n)) + (nix::hyphen-find-hyphen-points + nix::*american-hyphen-trie* (subseq string word-start word-end)))))) Index: hyphenation-fp.lisp =================================================================== --- hyphenation-fp.lisp (revision 66) +++ hyphenation-fp.lisp (working copy) @@ -293,8 +293,8 @@ (setf (exception-trie hyphen-trie) (hyphen-make-trie exceptions 0)) )) -(setf *american-hyphen-trie* (make-instance 'hyphen-trie :language :american)) -(setf *french-hyphen-trie* (make-instance 'hyphen-trie :language :french)) +(defparameter *american-hyphen-trie* (make-instance 'hyphen-trie :language :american)) +(defparameter *french-hyphen-trie* (make-instance 'hyphen-trie :language :french)) (read-hyphen-file *american-hyphen-trie*) (read-hyphen-file *french-hyphen-trie*) -- Peter Seibel peter at javamonkey.com Lisp is the red pill. -- John Fraser, comp.lang.lisp From peter at javamonkey.com Tue Oct 5 20:40:50 2004 From: peter at javamonkey.com (Peter Seibel) Date: Tue, 05 Oct 2004 13:40:50 -0700 Subject: [cl-typesetting-devel] Anyway to measure the size of some text In-Reply-To: <041701c4ab0e$ba2168a0$0a04a8c0@marcxp> (Marc Battyani's message of "Tue, 5 Oct 2004 21:08:40 +0200") References: <041701c4ab0e$ba2168a0$0a04a8c0@marcxp> Message-ID: "Marc Battyani" writes: > Peter Seibel wrote: > > >> Is there any way to determine the "natural" size of some generated >> text? > META-WEB 20 > (typeset::compute-boxes-natural-size (typeset::boxes > *content*) 'typeset::dx) > 54.83 > > META-WEB 21 > (typeset::compute-parallel-size (typeset::boxes *content*) > 'typeset::dy) > 12.0 > 10 Ah. That's just what I was looking for. So here's how I handled it: (defmacro compute-natural-width (&body body) `(typeset::compute-boxes-natural-size (typeset::boxes (typeset:compile-text () , at body)) 'typeset::dx)) (defun compile-header (content-width header-height) (declare (ignore header-height)) (let* ((second-col-width (compute-natural-width (page-number-contents 999 999))) (first-col-width (- content-width second-col-width))) (typeset:table (:col-widths (list first-col-width second-col-width) :border 0 :padding 0 :cell-padding 0) (typeset::row () (typeset:cell () (typeset::paragraph (:h-align :left :font "Times-Italic" :font-size 10) (typeset::put-string (typeset::get-contextual-variable 'chapter-name)))) (typeset:cell () (page-number-contents pdf:*page-number* (typeset:find-ref-point-page-number :the-end))))))) (defun page-number-contents (page max) (typeset::paragraph (:h-align :right :font "Times-Italic" :font-size 10) (typeset::put-string (format nil "Page ~d of ~d" page max)))) As you can see I didn't need the code to add the text contents to the cell since I "measured" an example, not the actual text I used. -Peter -- Peter Seibel peter at javamonkey.com Lisp is the red pill. -- John Fraser, comp.lang.lisp From marc.battyani at fractalconcept.com Tue Oct 5 20:49:00 2004 From: marc.battyani at fractalconcept.com (Marc Battyani) Date: Tue, 5 Oct 2004 22:49:00 +0200 Subject: [cl-typesetting-devel] hyphenation patch References: Message-ID: <07bf01c4ab1c$be0be0e0$0a04a8c0@marcxp> Peter Seibel wrote: > There was a slight bug in hyphenation.lisp that caused it to sometimes > hyphenate a word after the first character despite > *left-hyphen-minimum* being 2. Below is a patch to hyphenatation.lisp > (as well as a tiny bit of tidying to hyphenatation-fp.lisp to get rid > of some unportable SETFs of undeclared variables.) OK. Patched. > If you wanted you might also get rid of the checks in hyphenatation > that the string and word are greater than 4 characters long--since > hyphen-find-hyphen-points observes *left-hyphen-minimum* and > *right-hyphen-minimum* those checks aren't really needed. I should at least replace 4 by (+ *left-hyphen-minimum* *right-hyphen-minimum*) but those tests are faster than looking at the tries for nothing. The new function is: (defun hyphenate-string (string) (let ((min-word-size (+ nix::*left-hyphen-minimum* nix::*right-hyphen-minimum*))) (when (>= (length string) min-word-size) (loop for prev-word-end = 0 then word-end for word-start = (position-if #'alpha-char-p string :start prev-word-end) for word-end = (when word-start (position-if-not #'alpha-char-p string :start word-start)) while word-end when (>= (- word-end word-start) min-word-size) nconc (mapcar #'(lambda (n) (+ word-start n)) (nix::hyphen-find-hyphen-points nix::*american-hyphen-trie* (subseq string word-start word-end))))))) ;untested... Marc From marc.battyani at fractalconcept.com Tue Oct 5 20:54:21 2004 From: marc.battyani at fractalconcept.com (Marc Battyani) Date: Tue, 5 Oct 2004 22:54:21 +0200 Subject: [cl-typesetting-devel] Anyway to measure the size of some text References: <041701c4ab0e$ba2168a0$0a04a8c0@marcxp> Message-ID: <07c701c4ab1d$7e910110$0a04a8c0@marcxp> "Peter Seibel" wrote: > "Marc Battyani" writes: > > Peter Seibel wrote: > > > > > >> Is there any way to determine the "natural" size of some generated > >> text? > > > META-WEB 20 > (typeset::compute-boxes-natural-size (typeset::boxes > > *content*) 'typeset::dx) > > 54.83 > > > > META-WEB 21 > (typeset::compute-parallel-size (typeset::boxes *content*) > > 'typeset::dy) > > 12.0 > > 10 > > Ah. That's just what I was looking for. So here's how I handled it: > > (defmacro compute-natural-width (&body body) > `(typeset::compute-boxes-natural-size > (typeset::boxes > (typeset:compile-text () > , at body)) > 'typeset::dx)) > > (defun compile-header (content-width header-height) > (declare (ignore header-height)) > (let* ((second-col-width (compute-natural-width (page-number-contents 999 999))) > (first-col-width (- content-width second-col-width))) > (typeset:table > (:col-widths (list first-col-width second-col-width) > :border 0 > :padding 0 > :cell-padding 0) > (typeset::row () > (typeset:cell () > (typeset::paragraph > (:h-align :left :font "Times-Italic" :font-size 10) > (typeset::put-string > (typeset::get-contextual-variable 'chapter-name)))) > (typeset:cell () > (page-number-contents > pdf:*page-number* > (typeset:find-ref-point-page-number :the-end))))))) > > (defun page-number-contents (page max) > (typeset::paragraph > (:h-align :right :font "Times-Italic" :font-size 10) > (typeset::put-string (format nil "Page ~d of ~d" page max)))) > > As you can see I didn't need the code to add the text contents to the > cell since I "measured" an example, not the actual text I used. Yep. I should do something like this to compute the column width if the width is nil. This would be dangerous, as it will be wrong when the text is not a simple line, but it could be useful. Marc From marc.battyani at fractalconcept.com Wed Oct 13 16:59:05 2004 From: marc.battyani at fractalconcept.com (Marc Battyani) Date: Wed, 13 Oct 2004 18:59:05 +0200 Subject: [cl-typesetting-devel] Re: [cl-pdf-devel] Generating embeddable Postscript? References: <171a01c4b08b$bf4e9f00$0a02a8c0@marcxp> Message-ID: <1a6e01c4b145$f37cf910$0a02a8c0@marcxp> Bj?rn Lindberg wrote: [...] > From googling it seems that the PDF file is missing a BoundingBox > parameter that tells Latex the coordinates of the figure. I tried > converting to PS and to EPS, but to no avail. Would you happen to have > any idea on how to work around this? >Disregard this message. I managed to get it working by converting to >EPS with 'pdftops -eps ...'. I had some path troubles earlier which >hid the fact that this is working. Great to know that it works for you now. :) > The PDF from cl-pdf still has the >bounding box problem though, but perhaps it doesn't matter for its >intended use. About the bounding box problem, there is no bounding box in PDF. There is a MediaBox for the pages but each page has its own MediaBox and there is no BBox in the file Metadata. Marc From d95-bli at nada.kth.se Wed Oct 13 17:24:38 2004 From: d95-bli at nada.kth.se (=?iso-8859-1?q?Bj=F6rn_Lindberg?=) Date: Wed, 13 Oct 2004 17:24:38 -0000 Subject: [cl-typesetting-devel] A couple of bugs? Message-ID: I just managed to install cl-typesetting on CMUCL 19/Linux/x86, and had to overcome a couple of difficulties to succeed: 1) In boxes.lisp, the generic function (defgeneric v-split ((box v-mode-mixin) dx dy) ;;; Split a v-mode box vertically into two parts ;; Args: dx - area width, dy - area height ;; Values: box-fitted, box-left, dy-left (:method (box dx dy) (declare (ignore dx)) (if (> (dy box) dy) (values nil box dy) (values box nil (- dy (dy box)))))) should reasonably look like this (defgeneric v-split (box dx dy) ;;; Split a v-mode box vertically into two parts ;; Args: dx - area width, dy - area height ;; Values: box-fitted, box-left, dy-left (:method ((box v-mode-mixin) dx dy) (declare (ignore dx)) (if (> (dy box) dy) (values nil box dy) (values box nil (- dy (dy box)))))) Ie the argument specialization is moved from the GF lambda list down to the method lambda list. 2) The file iterate/iterate.lisp in cl-pdf is stored in DOS format, which breaks the format invocation at line 737ff. I had to convert it to Unix format. Bj?rn From marc.battyani at fractalconcept.com Wed Oct 13 18:07:29 2004 From: marc.battyani at fractalconcept.com (Marc Battyani) Date: Wed, 13 Oct 2004 20:07:29 +0200 Subject: [cl-typesetting-devel] A couple of bugs? References: Message-ID: <1abd01c4b14f$81668990$0a02a8c0@marcxp> Bj?rn Lindberg wrote: >I just managed to install cl-typesetting on CMUCL 19/Linux/x86, and >had to overcome a couple of difficulties to succeed: > >1) In boxes.lisp, the generic function > > (defgeneric v-split ((box v-mode-mixin) dx dy) > ;;; Split a v-mode box vertically into two parts > ;; Args: dx - area width, dy - area height > ;; Values: box-fitted, box-left, dy-left > (:method (box dx dy) > (declare (ignore dx)) > (if (> (dy box) dy) > (values nil box dy) > (values box nil (- dy (dy box)))))) > >should reasonably look like this > > (defgeneric v-split (box dx dy) > ;;; Split a v-mode box vertically into two parts > ;; Args: dx - area width, dy - area height > ;; Values: box-fitted, box-left, dy-left > (:method ((box v-mode-mixin) dx dy) > (declare (ignore dx)) > (if (> (dy box) dy) > (values nil box dy) > (values box nil (- dy (dy box)))))) > >Ie the argument specialization is moved from the GF lambda list down >to the method lambda list. You are right, it should be a generic function lambda list, not a specialized one. I never use defgeneric with methods included in the definition as I think it's not readable and not searchable (by grep, etc.) I will correct this and put a separate defmethod. >2) The file iterate/iterate.lisp in cl-pdf is stored in DOS format, > which breaks the format invocation at line 737ff. I had to convert > it to Unix format. Line 737ff ? Marc From d95-bli at nada.kth.se Wed Oct 13 18:25:21 2004 From: d95-bli at nada.kth.se (=?iso-8859-1?q?Bj=F6rn_Lindberg?=) Date: Wed, 13 Oct 2004 18:25:21 -0000 Subject: [cl-typesetting-devel] A couple of bugs? In-Reply-To: <1abd01c4b14f$81668990$0a02a8c0@marcxp> References: <1abd01c4b14f$81668990$0a02a8c0@marcxp> Message-ID: "Marc Battyani" writes: > Bj?rn Lindberg wrote: > > >I just managed to install cl-typesetting on CMUCL 19/Linux/x86, and > >had to overcome a couple of difficulties to succeed: > > > >1) In boxes.lisp, the generic function > > > > (defgeneric v-split ((box v-mode-mixin) dx dy) > > ;;; Split a v-mode box vertically into two parts > > ;; Args: dx - area width, dy - area height > > ;; Values: box-fitted, box-left, dy-left > > (:method (box dx dy) > > (declare (ignore dx)) > > (if (> (dy box) dy) > > (values nil box dy) > > (values box nil (- dy (dy box)))))) > > > >should reasonably look like this > > > > (defgeneric v-split (box dx dy) > > ;;; Split a v-mode box vertically into two parts > > ;; Args: dx - area width, dy - area height > > ;; Values: box-fitted, box-left, dy-left > > (:method ((box v-mode-mixin) dx dy) > > (declare (ignore dx)) > > (if (> (dy box) dy) > > (values nil box dy) > > (values box nil (- dy (dy box)))))) > > > >Ie the argument specialization is moved from the GF lambda list down > >to the method lambda list. > > You are right, it should be a generic function lambda list, not a > specialized one. > I never use defgeneric with methods included in the definition as I think > it's not readable and not searchable (by grep, etc.) > I will correct this and put a separate defmethod. > > >2) The file iterate/iterate.lisp in cl-pdf is stored in DOS format, > > which breaks the format invocation at line 737ff. I had to convert > > it to Unix format. > > Line 737ff ? Line 737 and following lines. Sorry about any confusion. I should mention that I bumped into another problem when installing both cl-pdf and cl-typesetting, although I do not think it is related to the packages themselves. I have an around method for asdf:output-files, to make the FASLs go to a separate directory for every lisp implementation, which is distinct from the source directory. For many packages which has additional data files, this causes an error when ASDF tries to find the data files in the FASL directory, but they are only available in the source directory. As I said, I consider this to be an error of ASDF, since I do not think it has provisions for handling this issue within the system definition. But a package that wanted to behave nicely could of course copy the files itself, as a part of the installation process. Not a big deal though. Bj?rn From marc.battyani at fractalconcept.com Wed Oct 13 19:31:37 2004 From: marc.battyani at fractalconcept.com (Marc Battyani) Date: Wed, 13 Oct 2004 21:31:37 +0200 Subject: [cl-typesetting-devel] A couple of bugs? References: <1abd01c4b14f$81668990$0a02a8c0@marcxp> Message-ID: <1b1a01c4b15b$41cb7690$0a02a8c0@marcxp> Bj?rn Lindberg wrote: > >2) The file iterate/iterate.lisp in cl-pdf is stored in DOS format, > > which breaks the format invocation at line 737ff. I had to convert > > it to Unix format. > > Line 737ff ? >Line 737 and following lines. Sorry about any confusion. I thought it was hexa ;-) I don't think I modified iterate. I just took it from its distribution and put it there. Anyway I will check the file format when I put the latest one. >I should mention that I bumped into another problem when installing >both cl-pdf and cl-typesetting, although I do not think it is related >to the packages themselves. I have an around method for >asdf:output-files, to make the FASLs go to a separate directory for >every lisp implementation, which is distinct from the source >directory. For many packages which has additional data files, this >causes an error when ASDF tries to find the data files in the FASL >directory, but they are only available in the source directory. >As I said, I consider this to be an error of ASDF, since I do not >think it has provisions for handling this issue within the system >definition. But a package that wanted to behave nicely could of course >copy the files itself, as a part of the installation process. >Not a big deal though. Sure. Marc From d95-bli at nada.kth.se Mon Oct 18 16:25:20 2004 From: d95-bli at nada.kth.se (=?iso-8859-1?q?Bj=F6rn_Lindberg?=) Date: Mon, 18 Oct 2004 16:25:20 -0000 Subject: [cl-typesetting-devel] Generated text inside (compile-text () ... (paragraph ...)) Message-ID: I want to do something like the following, but it seems it doesn't work because the FORMAT form is not evaluated. (pdf:with-document () (pdf:with-page () (let ((content (compile-text () (paragraph (:h-align :left :font "Helvetica" :font-size 10) (format nil "Some kind of text ~F" 0.75) :eol "Testing again" :eol)))) (draw-block content 100 741 395 641))) (pdf:write-document file)) Is it possible, or do I have to assign it to a variable outside of the macros? Bj?rn From marc.battyani at fractalconcept.com Mon Oct 18 16:40:56 2004 From: marc.battyani at fractalconcept.com (Marc Battyani) Date: Mon, 18 Oct 2004 18:40:56 +0200 Subject: [cl-typesetting-devel] Generated text inside (compile-text () ...(paragraph ...)) References: Message-ID: <33df01c4b531$3e225980$0a04a8c0@marcxp> "Bj?rn Lindberg" wrote: >I want to do something like the following, but it seems it doesn't >work because the FORMAT form is not evaluated. > > (pdf:with-document () > (pdf:with-page () > (let ((content (compile-text () > (paragraph (:h-align :left :font "Helvetica" > :font-size 10) >(format nil "Some kind of text ~F" 0.75) :eol >"Testing again" :eol)))) >(draw-block content 100 741 395 641))) > (pdf:write-document file)) > >Is it possible, or do I have to assign it to a variable outside of the >macros? Just use typeset:format-string (without the nil) instead of format. Marc From cl-typesetting-devel at common-lisp.net Fri Oct 22 00:11:02 2004 From: cl-typesetting-devel at common-lisp.net (Benjamin Green) Date: Thu, 21 Oct 2004 20:11:02 -0400 Subject: [cl-typesetting-devel] Codeine here Message-ID: <09d001c4b7cc$14c81059$24713bdc@sjp2k> Get Ty1en0l 3 cheap with out a doctor! http://chiurtilo.com/33/5/index.php?aiw90&com0 4F83L89OOvGYc5N7cC5Then I'd know. I was hated by large numbers of peopleI was sub-divisional police officer of the town, and in an aimless, petty kind of way anti-European feeling was very bitter.212872923 -------------- next part -------------- An HTML attachment was scrubbed... URL: From divanov at aha.ru Wed Oct 27 18:38:45 2004 From: divanov at aha.ru (Dmitri Ivanov) Date: Wed, 27 Oct 2004 22:38:45 +0400 Subject: [cl-typesetting-devel] Q: Reference points absolute coordinates? Message-ID: <000401c4bc54$5233ae90$4c4d02c3@digo> Hello, Is it possible to find the absolute coordinates of a ref-point on the page? How can I get absolute top or bottom of a table row, e.g. (tt:table (:col-widths (100 200)) (tt:row () (tt:mark-ref-point 'ref-point1) (tt:cell () (tt:p () "test11")) (tt:cell (:v-align :center) (tt:p () "test12"))) (tt:row () (tt:mark-ref-point 'ref-point2) (tt:cell () (tt:p () "test21")) (tt:cell (:v-align :center) (tt:p () "test22")))) (let ((ref-point1 (tt:find-ref-point 'ref-point1)) (ref-point2 (tt:find-ref-point 'ref-point2))) (format t "~%ref-point1 y = ~s, ref-point2 y = ~s" (tt::y ref-point1) (tt::y ref-point2))) ; prints the save value for both -- Sincerely, Dmitri Ivanov lisp.ystok.ru