Or see the list of project sponsors.
This is the library for PDF generation and parsing.
Today I'm too lazy to provided step by step examples, but I have a real task to do with this library.
Some time ago I've read the article about productivity which recommended to print a "life calendar". This calendar should remind you: "The life is limited and the time's price is high."
The calendar is a grid where every box is one week of you life. The article suggested to buy a poster with the calendar, but I don't want to wait for a parcel with the poster! I want to print it now!
And here is where cl-pdf comes on the scene!
I wrote this simple function to generate the poster of A1 format:
(defun render (&optional (filename "life.pdf")) (flet ((to-ppt (size-in-mm) (/ size-in-mm 1/72 25.4))) (let* ((width (to-ppt 594)) ;; This is A1 page size in mm (height (to-ppt 841)) (margin-top (to-ppt 70)) (margin-bottom (to-ppt 30)) (span (to-ppt 2)) (year-weeks 52) (years 90) (box-size (/ (- (- height (+ margin-top margin-bottom)) (* span (1- years))) years)) (boxes-width (+ (* box-size year-weeks) (* span (1- year-weeks)))) (boxes-height (+ (* box-size years) (* span (1- years)))) ;; horizontal margin depends on box size, ;; because we need to center them (margin-h (/ (- width boxes-width) 2)) (box-radius (/ box-size 3)) (helvetica (pdf:get-font "Helvetica"))) (pdf:with-document () (pdf:with-page (:bounds (rutils:vec 0 0 width height)) ;; For debug ;; (pdf:rectangle margin-h margin-bottom ;; boxes-width ;; boxes-height ;; :radius box-radius) (loop for year from 0 below years do (loop for week from 0 below year-weeks for x = (+ margin-h (* week (+ box-size span))) for y = (+ margin-bottom (* year (+ box-size span))) do (pdf:rectangle x y box-size box-size :radius box-radius))) ;; The title (pdf:draw-centered-text (/ width 2) (+ margin-bottom boxes-height ;; space between text and boxes in mm (to-ppt 15)) "LIFE CALENDAR" helvetica ;; font-size in mm (to-ppt 30)) ;; Labels for weeks (let ((font-size ;; We want labels to be slightly smaller than boxes (* box-size 2/3))) (pdf:draw-right-text (+ margin-h (/ box-size 4)) (+ margin-bottom boxes-height ;; space between text and boxes in mm (to-ppt 10)) "Weeks of the year" helvetica font-size) (loop for week below year-weeks do (pdf:draw-centered-text (+ margin-h (/ box-size 2) (* week (+ box-size span))) (+ margin-bottom boxes-height ;; space between text and boxes in mm (to-ppt 3)) (rutils:fmt "~A" (1+ week)) helvetica font-size)) ;; Labels for years (pdf:with-saved-state (pdf:translate (- margin-h (to-ppt 10)) (- (+ margin-bottom boxes-height) (/ box-size 4))) (pdf:rotate 90) (pdf:draw-left-text 0 0 "Years of your life" helvetica font-size)) (loop for year below years do (pdf:draw-left-text (- margin-h ;; space between text and boxes in mm (to-ppt 3)) (+ margin-bottom (/ box-size 4) (* year (+ box-size span))) (rutils:fmt "~A" (- years year)) helvetica font-size)) ;; The Question. (pdf:draw-left-text (- width margin-h) (- margin-bottom (to-ppt 10)) "Is this the End?" helvetica (* font-size 2)) (pdf:close-and-stroke))) (pdf:write-document filename)))))
Here is how result will look like:
The PDF can be downloaded here.
This program demonstrates a few features of cl-pdf:
There are a lot more features but all of them aren't documented, only several examples :(
GitHub shows 4 forks with some patches. And some of them are turned into a pull-request, but maintainer is inactive on the GitHub since 2019 :(