From 87be4123ded1ff431b5dc0e863640c7e4a8cba42 Mon Sep 17 00:00:00 2001 From: Matthew Butterick Date: Tue, 7 May 2019 11:48:20 -0700 Subject: [PATCH] next: study bullets --- quad/qtest/fark.rkt | 5 ++--- quad/quad/position.rkt | 31 ++++++++++++++++++------------- quad/quad/quad.rkt | 15 +++++++-------- quad/quadwriter/attrs.rkt | 28 ++++++++++++++++++++-------- quad/quadwriter/core.rkt | 12 +++++------- quad/quadwriter/param.rkt | 4 +++- quad/quadwriter/tags.rkt | 10 +--------- 7 files changed, 56 insertions(+), 49 deletions(-) diff --git a/quad/qtest/fark.rkt b/quad/qtest/fark.rkt index d564913c..805c54ad 100644 --- a/quad/qtest/fark.rkt +++ b/quad/qtest/fark.rkt @@ -1,6 +1,5 @@ #lang quadwriter/markdown -# Hi +# And - -## There \ No newline at end of file +so \ No newline at end of file diff --git a/quad/quad/position.rkt b/quad/quad/position.rkt index c1d0d76c..77097e52 100644 --- a/quad/quad/position.rkt +++ b/quad/quad/position.rkt @@ -86,19 +86,24 @@ [origin shifted-origin] ;; set shift to zero because it's baked into new origin value [shift (pt 0 0)])) - (let ([parent-q positioned-q]) - (struct-copy quad parent-q - [elems - ;; can't use for/list here because previous quads provide context for later ones - (let loop ([prev-elems null] [elems (quad-elems parent-q)]) - (match elems - [(? null?) (reverse prev-elems)] - [(cons (? quad? this-q) rest) - (define ref-q (if (or (quad-from-parent this-q) (null? prev-elems)) - parent-q - (car prev-elems))) - (loop (cons (position this-q ref-q) prev-elems) rest)] - [(cons x rest) (loop (cons x prev-elems) rest)]))]))) + (define positioned-elems + ;; for purposes of positioning the elements, we want to also bake in the `shift-elements` value + ;; but we don't want this origin to be permanent on the parent. + ;; akin to `push` a graphics state and then `pop` afterwards. + (let ([parent-q (struct-copy quad positioned-q + [origin (pt+ (quad-origin positioned-q) (quad-shift-elements positioned-q))] + [shift-elements (pt 0 0)])]) + ;; can't use for/list here because previous quads provide context for later ones + (let loop ([prev-elems null] [elems (quad-elems parent-q)]) + (match elems + [(? null?) (reverse prev-elems)] + [(cons (? quad? this-q) rest) + (define ref-q (if (or (quad-from-parent this-q) (null? prev-elems)) + parent-q + (car prev-elems))) + (loop (cons (position this-q ref-q) prev-elems) rest)] + [(cons x rest) (loop (cons x prev-elems) rest)])))) + (struct-copy quad positioned-q [elems positioned-elems])) (define (distance q) (match (pt- (from-point q) (to-point q)) diff --git a/quad/quad/quad.rkt b/quad/quad/quad.rkt index d39e2dc3..1a98b2f1 100644 --- a/quad/quad/quad.rkt +++ b/quad/quad/quad.rkt @@ -36,7 +36,7 @@ (and ;; exclude attrs from initial comparison (for/and ([getter (in-list (list quad-elems quad-size quad-from-parent quad-from quad-to - quad-shift quad-offset quad-from-parent quad-origin quad-printable + quad-shift quad-shift-elements quad-from-parent quad-origin quad-printable quad-draw-start quad-draw-end quad-draw))]) (equal? (getter q1) (getter q2))) ;; and compare them key-by-key @@ -53,11 +53,10 @@ from-parent ; position on parent quad? from ; alignment point on ref quad to ; alignment point on this quad that is matched to `from` on previous quad - ;; offset, shift are two-dim pts - ;; offset= Similar to `relative` CSS positioning - ;; relocation of pen before quad is drawn. Does NOT change layout position. - ;; meaning, in and out points don't move, just the drawing. - offset + ;; shift-elements, shift are two-dim pts + ;; shift-elements = Similar to `relative` CSS positioning + ;; moves origin for elements . Does NOT change layout position of parent. + shift-elements ;; shift = shift between previous out point and current in point. ;; DOES change the layout position. shift @@ -118,7 +117,7 @@ #:from [from 'ne] #:to [to 'nw] #:shift [shift '(0 0)] - #:offset [offset '(0 0)] + #:shift-elements [shift-elements '(0 0)] #:origin [origin '(0 0)] #:printable [printable default-printable] #:draw-start [draw-start void] @@ -140,7 +139,7 @@ from-parent from to - offset + shift-elements shift origin printable diff --git a/quad/quadwriter/attrs.rkt b/quad/quadwriter/attrs.rkt index 766124fe..9fb2763d 100644 --- a/quad/quadwriter/attrs.rkt +++ b/quad/quadwriter/attrs.rkt @@ -20,21 +20,33 @@ Naming guidelines (define (parse-points x [round? #f]) (define val (match x - [(? number?) x] - [(? string? x) - (match (cdr (regexp-match #rx"^(-?[0-9\\.]+)([a-z]+)$" (string-downcase x))) - [(list num-string unit) - ((match unit - [(regexp #rx"in(ch)?") in->pts] - [(regexp #rx"cm") (compose1 in->pts cm->in)] - [(regexp #rx"mm") (compose1 in->pts cm->in mm->cm)]) (string->number num-string))])])) + [(? number?) x] + [(? string? x) + (match (cdr (regexp-match #rx"^(-?[0-9\\.]+)([a-z]+)$" (string-downcase x))) + [(list num-string unit) + ((match unit + [(regexp #rx"in(ch)?") in->pts] + [(regexp #rx"cm") (compose1 in->pts cm->in)] + [(regexp #rx"mm") (compose1 in->pts cm->in mm->cm)]) (string->number num-string))])])) (if round? (inexact->exact (floor val)) val)) (define block-attrs '(display + ;; inset values increase the layout size of the quad. + ;; they are relative to the natural layout box. inset-top inset-bottom inset-left inset-right + ;; border-inset values do not increase the layout size of the quad. + ;; they are relative to the layout size of the quad, with inset values included. + ;; this is different from CSS, where margin + padding increase the size of the layout. + ;; one has to be dependent on the other, so a choice must be made. + ;; I find this approach more sensible because + ;; borders are a styling element, not a layout element. + ;; this means that changing the inset values will change the position of the border. + ;; but this is preferable to the CSS model, where moving the border changes the layout. + ;; principle: minimize the number of values that affect the layout, + ;; so it's easier to reason about programmatically. border-inset-top border-inset-bottom border-inset-left diff --git a/quad/quadwriter/core.rkt b/quad/quadwriter/core.rkt index 0b5b56ef..f2d10418 100644 --- a/quad/quadwriter/core.rkt +++ b/quad/quadwriter/core.rkt @@ -310,7 +310,7 @@ [size (pt 0 0)]))]) (list (make-quad #:type offsetter - #:offset (pt (quad-ref elem 'inset-left 0) 0) + #:shift-elements (pt (quad-ref elem 'inset-left 0) 0) #:elems elems)))) (on-parent new-elems 'sw))]))] [_ null])])) @@ -455,13 +455,13 @@ (define first-line (car lines)) (q #:from 'sw #:to 'nw - #:offset (pt 0 (+ (quad-ref first-line 'inset-top 0))) #:elems (on-parent lines 'nw) #:size (delay (pt (pt-x (size first-line)) ; (+ (for/sum ([line (in-list lines)]) (pt-y (size line))) (quad-ref first-line 'inset-top 0) (quad-ref first-line 'inset-bottom 0)))) + #:shift-elements (pt 0 (+ (quad-ref first-line 'inset-top 0))) #:draw-start (block-draw-start first-line) #:draw-end (if (draw-debug-block?) (λ (q doc) (draw-debug q doc "#6c6" "#9c9")) @@ -595,17 +595,15 @@ (make-pdf #:compress #t #:auto-first-page #f #:output-path pdf-path - #:width #;page-width 400 - #:height #;page-height 400 + #:width (or (debug-page-width) page-width) + #:height (or (debug-page-height) page-height) #:size (quad-ref (car qs) 'page-size default-page-size) #:orientation (quad-ref (car qs) 'page-orientation default-page-orientation)))) (define default-x-margin (min (* 72 1.5) (floor (* .10 (pdf-width pdf))))) (define default-y-margin (min 72 (floor (* .10 (pdf-width pdf))))) (parameterize ([current-pdf pdf] - [verbose-quad-printing? #false] - [draw-debug? #true] - [zoom-factor 3]) + [verbose-quad-printing? #false]) (let* ([qs (time-name hyphenate (handle-hyphenate qs))] [qs (map ->string-quad qs)] [qs (insert-first-line-indents qs)] diff --git a/quad/quadwriter/param.rkt b/quad/quadwriter/param.rkt index a2c6f501..08efe8df 100644 --- a/quad/quadwriter/param.rkt +++ b/quad/quadwriter/param.rkt @@ -6,7 +6,9 @@ (define draw-debug? (make-parameter #false)) (define draw-debug-line? (make-parameter #true)) -(define draw-debug-block? (make-parameter #false)) +(define draw-debug-block? (make-parameter #true)) (define draw-debug-string? (make-parameter #true)) +(define debug-page-width (make-parameter #f)) +(define debug-page-height (make-parameter #f)) (define zoom-factor (make-parameter 1)) \ No newline at end of file diff --git a/quad/quadwriter/tags.rkt b/quad/quadwriter/tags.rkt index 3fefc363..73278842 100644 --- a/quad/quadwriter/tags.rkt +++ b/quad/quadwriter/tags.rkt @@ -57,15 +57,7 @@ (define-syntax-rule (attr-list . attrs) 'attrs) (define (heading-base font-size attrs exprs) - (qexpr (append `((font-family "fira-sans-light") (first-line-indent "0") (display "block") (font-size ,(number->string font-size))(line-height ,(number->string (* 1.2 font-size))) - (border-width-top "1") - (border-width-bottom "1") - (border-width-left "1") - (border-width-right "1") - (inset-top "0") - (inset-left "0") - - (keep-with-next "true")) attrs) exprs)) + (qexpr (append `((font-family "fira-sans-light") (first-line-indent "0") (display "block") (font-size ,(number->string font-size))(line-height ,(number->string (* 1.2 font-size))) (border-width-top "0.5")(border-inset-top "9") (inset-bottom "-3") (inset-top "6") (keep-with-next "true")) attrs) exprs)) (define-tag-function (h1 attrs exprs) (heading-base 20 (append '() attrs) exprs))