From e1157db843521c70077f24cffe9b4718f70d00eb Mon Sep 17 00:00:00 2001 From: Matthew Butterick Date: Tue, 4 Feb 2020 12:21:22 -0800 Subject: [PATCH] remove `line-align-last` attribute --- quad/quad/scribblings/quad.scrbl | 7 ++++--- quad/quadwriter/attrs.rkt | 1 - quad/quadwriter/layout.rkt | 32 ++++++++++++++++---------------- quad/quadwriter/render.rkt | 4 ++-- quad/quadwriter/tags.rkt | 2 +- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/quad/quad/scribblings/quad.scrbl b/quad/quad/scribblings/quad.scrbl index d081a139..e164efb8 100644 --- a/quad/quad/scribblings/quad.scrbl +++ b/quad/quad/scribblings/quad.scrbl @@ -586,11 +586,12 @@ How many lines of the quad are kept together near a page break. @racket[keep-fir Whether a quad appears on the same page with the following quad. Activated only when value is @racket["true"]. Essentially this is the ``nonbreaking paragraph space''. } -@deftogether[(@defthing[#:kind "attribute" line-align symbol?] - @defthing[#:kind "attribute" line-align-last symbol?])]{ -How the lines are aligned horizontally in the quad. Possibilities are @racket["left"], @racket["center"], @racket["left"], @racket["justify"], @racket["inner"], and @racket["outer"]. @racket[line-align-last] controls the alignment of the last line; @racket[line-align] controls the others. +@defthing[#:kind "attribute" line-align symbol?]{ +How the lines are aligned horizontally in the quad. Possibilities are @racket["left"], @racket["center"], @racket["left"], @racket["justify"], @racket["inner"], and @racket["outer"]. @racket["inner"] and @racket["outer"] align the line toward (or away from) the gutter. So on right-hand pages, @racket["inner"] alignment is the same as @racket["left"], and @racket["outer"] is the same as @racket["right"]. On left-hand pages, vice versa. + +The last line of a paragraph with @racket["justify"] alignment will only be justified if the space left over is reasonably small. Otherwise it will be left-aligned. This is because the last line of the paragraph may only have a few words on it. } @defthing[#:kind "attribute" first-line-indent symbol?]{ diff --git a/quad/quadwriter/attrs.rkt b/quad/quadwriter/attrs.rkt index 9523f543..15949be7 100644 --- a/quad/quadwriter/attrs.rkt +++ b/quad/quadwriter/attrs.rkt @@ -149,7 +149,6 @@ Naming guidelines keep-with-next line-align - line-align-last ; separate from line-align because last line is usually short first-line-indent diff --git a/quad/quadwriter/layout.rkt b/quad/quadwriter/layout.rkt index 4889bee5..d97ab644 100644 --- a/quad/quadwriter/layout.rkt +++ b/quad/quadwriter/layout.rkt @@ -349,14 +349,13 @@ [(? string-quad?) (/ (quad-ref q :font-tracking 0) 2.0)] [_ 0])) -(define (fill-line-wrap qs q-after line-prototype) +(define (fill-line-wrap qs line-prototype last-line-in-paragraph?) ;; happens during the finish of a line wrap, before consolidation of runs (unless (pair? qs) (raise-argument-error 'fill-line-wrap "nonempty list of quads" qs)) (match-define (and (cons q-first other-qs) (list _ ... q-last)) qs) - (define last-line-in-paragraph? (not q-after)) - (define align-value (quad-ref q-first (if last-line-in-paragraph? :line-align-last :line-align) "left")) + (define align-value (quad-ref q-first :line-align "left")) ;; words may still be in hyphenated fragments ;; (though soft hyphens would have been removed) @@ -388,11 +387,15 @@ #:attrs (quad-attrs q-first))) (cond - [(or (equal? align-value "justify") - (let ([line-overfull? (negative? (- empty-hspace space-total-width))]) - ;; force justification upon overfull lines, - ;; which amounts to shrinking the word spaces till the line fits - (and line-overfull? (> nonspacess-count 1)))) + [(or + (and (equal? align-value "justify") (or (not last-line-in-paragraph?) + ;; don't justify the last line in a paragraph + ;; unless empty space is less than 17% of width (an arbitrary visual threshold) + (< (/ empty-hspace line-prototype-width 1.0) .17))) + (let ([line-overfull? (negative? (- empty-hspace space-total-width))]) + ;; force justification upon overfull lines, + ;; which amounts to shrinking the word spaces till the line fits + (and line-overfull? (> nonspacess-count 1)))) (define justified-space-width (/ empty-hspace (sub1 nonspacess-count))) (cons (make-left-edge-filler) (apply append (add-between hung-nonspacess (list (make-quad @@ -402,11 +405,12 @@ #:size (pt justified-space-width line-prototype-height))))))] [else (define space-multiplier (match align-value - ["left" 0] ["center" 0.5] ;; fill inner & outer as if they were right, ;; they will be corrected later, when pagination is known. - [(or "right" "inner" "outer") 1])) + [(or "right" "inner" "outer") 1] + ;; "left" and "justify" are handled here + [_ 0])) ;; subtact space-width because that appears between words ;; we only care about redistributing the space on the ends (define end-hspace (- empty-hspace space-total-width)) @@ -447,7 +451,8 @@ (define pcs-with-hyphen (render-hyphen wrap-qs-printing q-after)) ;; fill wrap so that consolidate-runs works properly ;; (justified lines won't be totally consolidated) - (define pcs (fill-line-wrap pcs-with-hyphen q-after line-prototype-q)) + (define last-line-in-paragraph? (not q-after)) + (define pcs (fill-line-wrap pcs-with-hyphen line-prototype-q last-line-in-paragraph?)) (match (consolidate-runs pcs) [(and (cons elem-first _) elems) (match-define (list line-width line-height) (quad-size line-prototype-q)) @@ -460,11 +465,6 @@ ;; so that it will be wrapped as a block later. ;; we only set this if there is no value for :display. (hash-ref! h :display default-block-id) - ;; move the line-align-last into the line-align slot - ;; so subsequent operations don't have to care about last-ness. - (define last-line? (not q-after)) - (when last-line? - (hash-set! h :line-align (hash-ref h :line-align-last "left"))) h)] ;; line width is static ;; line height is the max 'line-height value or the natural height of q:line diff --git a/quad/quadwriter/render.rkt b/quad/quadwriter/render.rkt index 8b2015b2..4a9303b1 100644 --- a/quad/quadwriter/render.rkt +++ b/quad/quadwriter/render.rkt @@ -123,9 +123,9 @@ complete-every-path! resolve-font-path! resolve-font-size! + ;; we resolve font tracking & line height after font size + ;; because they can be denoted relative to font size resolve-font-tracking! - ;; we resolve line height after font size - ;; because line height might be dependent resolve-line-height! parse-font-features!))]) (proc attrs))) diff --git a/quad/quadwriter/tags.rkt b/quad/quadwriter/tags.rkt index 2d118d31..f5f4e5bd 100644 --- a/quad/quadwriter/tags.rkt +++ b/quad/quadwriter/tags.rkt @@ -34,7 +34,7 @@ (qexpr (list->attrs :line-height "false" :image-height "150" - :line-align-last "center" ; need `last` because img is a block-level element. + :line-align "center" ; need `last` because img is a block-level element. :image-file (second (assq 'src attrs)) :image-alt (second (assq 'alt attrs)) :display "block") exprs))