views:

84

answers:

2

I'm trying to use cl-pdf for some fairly basic PDF generation, but I'm getting tripped up at the examples (which is embarassing to say the least).

When I run the first example included in the package

(defun example1 (&optional (file #P"/tmp/ex1.pdf"))
  (pdf:with-document ()
    (pdf:with-page ()
      (pdf:with-outline-level ("Example" (pdf:register-page-reference))
        (let ((helvetica (pdf:get-font "Helvetica")))
          (pdf:in-text-mode
           (pdf:set-font helvetica 36.0)
           (pdf:move-text 100 800)
           (pdf:draw-text "cl-pdf: Example 1"))
          (pdf:translate 230 500)
          (loop repeat 150
         for i = 0.67 then (* i 1.045)
         do (pdf:in-text-mode
             (pdf:set-font helvetica i)
             (pdf:set-rgb-fill (/ (random 255) 255.0)
                               (/ (random 255) 255.0)
                               (/ (random 255) 255.0))
             (pdf:move-text (* i 3) 0)
             (pdf:show-text "cl-typesetting"))
           (pdf:rotate 13)))))
    (pdf:write-document file)))

by running (example1 #P"/home/inaimathi/Desktop/ex1.pdf") it gives me this error

#<SB-SYS:FD-STREAM for "file /home/inaimathi/Desktop/test.pdf" 
{CF9D931}> is not a binary output stream. 
    [Condition of type SIMPLE-TYPE-ERROR]

Restarts:
 0: [ABORT] Exit debugger, returning to top level.

The same thing happens when I call (example1), or when I do

(with-open-file 
     (test-file #P"/home/inaimathi/Desktop/ex1.pdf" 
     :direction :output :if-does-not-exist :create) 
   (example1 test-file))

Finally, if I try

(with-open-file 
     (test-file #P"/home/inaimathi/Desktop/ex1.pdf" 
     :direction :output :if-does-not-exist :create 
     :element-type '(unsigned-byte 8)) 
   (example1 test-file))

I get the error

#<SB-SYS:FD-STREAM for "file /home/inaimathi/Desktop/test.pdf" 
{D197C99}> is not a character output stream.
   [Condition of type SIMPLE-TYPE-ERROR]

Restarts:
 0: [ABORT] Exit debugger, returning to top level.

Is there a way to declare a binary character stream? How do I get simple output out of cl-pdf? I'm using SBCL straight out of the debian repos (which is 1.0.29, I think), in case it matters.

+1  A: 

EDIT: This is what I ended up doing. The solution by xach above would also work.

In the end I had to git svn clone http://www.fractalconcept.com:8000/public/open-source/cl-pdf and install that.

For the newbs (since I remember how frustrating it is for someone new to Common Lisp to hear "just do a checkout and install it"):

1.Do the checkout as above (I assume you've done this in your home directory from now on)

2.Type in tar -czvf ~/cl-pdf.tar.gz ~/cl-pdf (the point is to get a tarball of the folder. You can do this through the GUI too, it makes no difference)

3.Hop into your SBCL prompt and enter

(require 'asdf)
(require 'asdf-install)

4.If you already installed cl-pdf using (asdf-install:install 'cl-pdf), then you'll need to enter (asdf-install:uninstall 'cl-pdf)

5.Type (asdf-install:install "/home/[your home folder name]/cl-pdf.tar.gz")

I got one compilation error throughout this process, which I just selected [Accept] for. It still seems to work fine.

Hopefully the upcoming release of quicklisp will reduce the need for this sort of package hunting.

Inaimathi
+2  A: 

(setf pdf:*compress-streams* nil) should help. It's trying to write binary data to a character stream, and while that works on LispWorks and some other systems, it doesn't work everywhere and particularly not on SBCL.

Xach
Which makes sense given the error output I was getting. I think I still have the old version of `cl-pdf` on my machine at home; I'll test this out when I get out of the office.
Inaimathi
Turns out I don't still have the old version. Oddly, having installed the SVN checkout, if I just `(asdf-install:uninstall 'cl-pdf)`, then `(asdf-install:install 'cl-pdf)` (which downloads the cl-pdf-current tarball from fractalconcept), and try the example function, it still works. I assume there's state left behind from the old install that `asdf-install:uninstall` doesn't get rid of. I'll try it on a clean machine today to see what happens.
Inaimathi
Yup, it works. If you use the default version installed by ASDF, it runs properly as long as you evaluate the above first. Oddly enough, you need to do this even if you set `*compress-streams*` to `nil` in config.lisp
Inaimathi