#lang debug racket (require "struct.rkt" "attrs.rkt" "param.rkt" "debug.rkt" "font.rkt" "string.rkt" quad/base racket/date pitfall) (provide (all-defined-out)) (define default-page-size "letter") (define default-page-orientation "tall") (define (page-draw-start q doc) (match-define (list page-width page-height) (parse-page-size q)) (add-page doc page-width page-height) (scale doc (zoom-factor) (zoom-factor)) (draw-debug q doc "purple" "purple" 1)) (define q:page (make-quad #:type page-quad #:tag 'page #:from-parent 'nw #:draw-start page-draw-start)) (define (parse-page-size q) ;; page size can be specified by name, or measurements. ;; explicit measurements from page-height and page-width supersede those from page-size. (match-define (list page-width page-height) (for/list ([k (list :page-width :page-height)]) (and (quad? q) (match (quad-ref q k) [#false #false] [val (inexact->exact (floor val))])))) (resolve-page-size (or (debug-page-width) page-width) (or (debug-page-height) page-height) (quad-ref q :page-size default-page-size) (quad-ref q :page-orientation default-page-orientation))) (define (draw-page-footer q doc) (match-define (list x y) (quad-origin q)) (font-size doc (quad-ref q :font-size)) (font doc (path->string (quad-ref q font-path-key default-font-face))) (fill-color doc default-font-color) (define str (or (quad-ref q :footer-text) (format "~a · ~a at ~a" (quad-ref q :page-number 0) (if (quadwriter-test-mode) "test" (quad-ref q :doc-title "untitled")) (date->string (if (quadwriter-test-mode) (seconds->date 0 #f) (current-date)) #t)))) (text doc str x y) #;(set-quad-size! q (make-size-promise-for-string q str))) (define (make-footer-quad col-q page-idx path) (define-values (dir name _) (split-path (path-replace-extension path #""))) (define attrs (let ([attrs (make-hasheq)] [cltq (current-top-level-quad)]) (hash-set*! attrs :footer-text (quad-ref col-q :footer-text) :page-number (+ (quad-ref col-q :page-number-start (add1 (section-pages-used))) (sub1 page-idx)) :doc-title (string-titlecase (path->string name)) ;; we get font & line-height from cltq ;; because these are not block attrs ;; so they are not propagated upward from col-q :font-size (* 0.8 (quad-ref cltq :font-size)) :line-height (quad-ref cltq :line-height) :font-path (quad-ref cltq :font-path)) attrs)) (make-quad #:size (pt 50 default-line-height) #:attrs attrs #:from-parent 'sw #:to 'nw #:elems null #:shift (pt 0 (* 1.5 default-line-height)) #:printable #true #:draw draw-page-footer #:draw-end (λ (q doc) (when draw-debug-line? (draw-debug q doc "goldenrod" "goldenrod"))))) (define ((page-wrap-finish make-page-quad path) cols q-before q-after page-idx) (define pq (make-page-quad (+ (section-pages-used) page-idx))) ;; get attrs from cols if we can, otherwise try q-after or q-before (define q-for-attrs (cond [(pair? cols) (car cols)] [q-after] [q-before] [else (raise-argument-error 'page-wrap-finish "quad with attrs" (list cols q-after q-before))])) (define elems (append (match (quad-ref q-for-attrs :footer-display #false) [(or #false "none") null] [_ (list (make-footer-quad q-for-attrs page-idx path))]) (from-parent cols 'nw))) (list (quad-update! pq [elems elems] [attrs (copy-block-attrs (cond [q-for-attrs => quad-attrs] [else (hash)]) (hash-copy (quad-attrs pq)))]))) (define (page-wrap qs width [make-page-quad (λ (x) (quad-copy page-quad q:page))]) (unless (positive? width) (raise-argument-error 'page-wrap "positive number" width)) (wrap qs width #:soft-break #true #:hard-break page-break-quad? #:no-break (λ (q) (quad-ref q :no-pbr)) #:distance (λ (q dist-so-far wrap-qs) (sum-x wrap-qs)) #:finish-wrap (page-wrap-finish make-page-quad (pdf-output-path (current-pdf)))))