main
Matthew Butterick 5 years ago
parent 7ef031b978
commit 93a3db10c0

@ -3,6 +3,9 @@
#:page-height "8in" #:page-height "8in"
#:page-width "6in" #:page-width "6in"
'(q ((flow "footnote")(fn-text "0")(font-size-adjust "80%")(line-heightr-adjust "70%")) "Leftover from previous footnote." (q ((break "para"))))
"Hello" '(q ((fn-ref "1")) "*") "Hello" '(q ((fn-ref "1")) "*")
'(q ((flow "footnote")(fn-text "1")(font-size-adjust "80%")(line-height-adjust "70%")) (q ((fn-text-start "1")) "*") "A convertible value in the sense of convertible? is used in a renderer-specific way, but values convertible to 'text renders the same as the resulting string. If a renderer is not able to convert the value to a known format, the value is converted to a string using write." (q ((break "para")))) '(q ((flow "footnote")(fn-text "1")(font-size-adjust "80%")(line-height-adjust "70%")) (q ((fn-text-start "1")) "*") "A convertible value in the sense of convertible? is used in a renderer-specific way, but values convertible to 'text renders the same as the resulting string. If a renderer is not able to convert the value to a known format, the value is converted to a string using write." (q ((break "para"))))

@ -1,7 +1,7 @@
#lang debug racket #lang debug racket
(require racket/list racket/match sugar/debug sugar/list (require racket/list racket/match sugar/debug sugar/list
"param.rkt" "quad.rkt" "atomize.rkt" "position.rkt" "ocm.rkt" "log.rkt") "param.rkt" "quad.rkt" "atomize.rkt" "position.rkt" "ocm.rkt" "log.rkt")
(provide wrap) (provide wrap sum-x sum-y)
(define-syntax (debug-report stx) (define-syntax (debug-report stx)
(syntax-case stx () (syntax-case stx ()
@ -23,6 +23,12 @@
['(()) '()] ; special case ['(()) '()] ; special case
[wraps wraps])) [wraps wraps]))
(define (sum-base xs which)
(for/sum ([x (in-list xs)])
(which (size x))))
(define (sum-y xs) (sum-base xs pt-y))
(define (sum-x xs) (sum-base xs pt-x))
(define (arg->proc arg [arity 1]) (define (arg->proc arg [arity 1])
(match arg (match arg
[(? procedure? proc) proc] [(? procedure? proc) proc]
@ -105,14 +111,30 @@
[next-wrap-tail null] ; list of unbreakable quads [next-wrap-tail null] ; list of unbreakable quads
[current-dist #false] ; #false (to indicate start) or integer [current-dist #false] ; #false (to indicate start) or integer
[previous-wrap-ender #f] [previous-wrap-ender #f]
[qs qs] [qs qs] ; list of quads
[footnote-qs footnote-qs-in] [footnote-qs footnote-qs-in] ; list of footnote quads
[footnote-wraps null]) ; list of quads [footnote-wraps null] ; list of footnote lines wrapped into footnote area for this col
[footnote-dist 0] ; dist consumed by footnotes in current footnote wrap
; this needs to be tracked separately from current-dist because #false is used to detect start
)
#| #|
1) If there are lines left over from a previous footnote, set as many of those lines on the current page as space allows. If the footnote zone is empty, this is a footnote continuation, so start with a continuation break. Loop without making a new column break. 1) If there are lines left over from a previous footnote, set as many of those lines on the current page as space allows. If the footnote zone is empty, this is a footnote continuation, so start with a continuation break. Loop without making a new column break.
|# |#
(match footnote-qs (match footnote-qs
[(list* (? footnote-start-pred leftover-lns) ..1 _) #R leftover-lns] [(list* (and (not (? footnote-start-pred)) fn-leftovers) ..1 other-fn-lines)
(define fn-nonblank (dropf fn-leftovers (λ (q) (and (soft-break? q)) (nonprinting-at-start? q))))
(define fn-non-blank-height (sum-y fn-nonblank))
(loop
wraps
wrap-idx
next-wrap-head
next-wrap-tail
current-dist
previous-wrap-ender
qs
other-fn-lines
(cons fn-nonblank footnote-wraps)
fn-non-blank-height)]
[_ (void)]) [_ (void)])
(match qs (match qs
[(or (== empty) (list (? hard-break?))) ; ignore single trailing hard break [(or (== empty) (list (? hard-break?))) ; ignore single trailing hard break
@ -134,7 +156,8 @@
q q
other-qs other-qs
footnote-qs footnote-qs
footnote-wraps)] footnote-wraps
footnote-dist)]
[(let ([at-start? (not current-dist)]) at-start?) [(let ([at-start? (not current-dist)]) at-start?)
(match q (match q
[(and (? soft-break?) (? nonprinting-at-start?)) [(and (? soft-break?) (? nonprinting-at-start?))
@ -147,7 +170,8 @@
previous-wrap-ender previous-wrap-ender
other-qs other-qs
footnote-qs footnote-qs
footnote-wraps)] footnote-wraps
footnote-dist)]
[_ (debug-report 'hard-quad-at-start) [_ (debug-report 'hard-quad-at-start)
(loop wraps (loop wraps
wrap-idx wrap-idx
@ -157,7 +181,8 @@
previous-wrap-ender previous-wrap-ender
other-qs other-qs
footnote-qs footnote-qs
footnote-wraps)])] footnote-wraps
footnote-dist)])]
[else ; cases that require computing distance [else ; cases that require computing distance
(define wrap-distance (distance-func q current-dist would-be-wrap-qs)) (define wrap-distance (distance-func q current-dist would-be-wrap-qs))
(define max-distance (max-distance-proc q wrap-idx)) (define max-distance (max-distance-proc q wrap-idx))
@ -177,7 +202,8 @@
previous-wrap-ender previous-wrap-ender
other-qs other-qs
footnote-qs footnote-qs
footnote-wraps)] footnote-wraps
footnote-dist)]
[(empty? next-wrap-head) [(empty? next-wrap-head)
(define-values (next-wrap-qs other-qs) (define-values (next-wrap-qs other-qs)
(cond (cond
@ -199,7 +225,8 @@
(car next-wrap-qs) (car next-wrap-qs)
other-qs other-qs
footnote-qs footnote-qs
footnote-wraps)] footnote-wraps
footnote-dist)]
[else ; finish the wrap & reset the line without consuming a quad [else ; finish the wrap & reset the line without consuming a quad
(loop (cons (finish-wrap next-wrap-head previous-wrap-ender wrap-idx) wraps) (loop (cons (finish-wrap next-wrap-head previous-wrap-ender wrap-idx) wraps)
(wrap-count wrap-idx q) (wrap-count wrap-idx q)
@ -209,7 +236,8 @@
(car next-wrap-head) (car next-wrap-head)
qs qs
footnote-qs footnote-qs
footnote-wraps)])] footnote-wraps
footnote-dist)])]
[(soft-break? q) [(soft-break? q)
(debug-report 'would-not-overflow-soft) (debug-report 'would-not-overflow-soft)
;; a soft break that fits, so move it on top of the next-wrap-head with the next-wrap-tail ;; a soft break that fits, so move it on top of the next-wrap-head with the next-wrap-tail
@ -221,7 +249,8 @@
previous-wrap-ender previous-wrap-ender
other-qs other-qs
footnote-qs footnote-qs
footnote-wraps)] footnote-wraps
footnote-dist)]
[else [else
(debug-report 'would-not-overflow) (debug-report 'would-not-overflow)
;; add to partial ;; add to partial
@ -233,7 +262,8 @@
previous-wrap-ender previous-wrap-ender
other-qs other-qs
footnote-qs footnote-qs
footnote-wraps)])])]))) footnote-wraps
footnote-dist)])])])))
(define last-line-can-be-short? #t) (define last-line-can-be-short? #t)
(define mega-penalty 1e8) (define mega-penalty 1e8)

@ -14,12 +14,6 @@
"log.rkt") "log.rkt")
(provide (all-defined-out)) (provide (all-defined-out))
(define (sum-base xs which)
(for/sum ([x (in-list xs)])
(which (size x))))
(define (sum-y xs) (sum-base xs pt-y))
(define (sum-x xs) (sum-base xs pt-x))
(define-quad string-quad quad) (define-quad string-quad quad)
(define (q:string-draw q doc (define (q:string-draw q doc
@ -700,8 +694,7 @@ https://github.com/mbutterick/typesetter/blob/882ec681ad1fa6eaee6287e53bc4320d96
(sum-y (insert-blocks (reverse wrap-qs)))) (sum-y (insert-blocks (reverse wrap-qs))))
#:finish-wrap (col-finish-wrap column-quad) #:finish-wrap (col-finish-wrap column-quad)
#:footnote-qs fn-lines #:footnote-qs fn-lines
#:footnote-start-pred (λ (q) (and (quad-ref q :fn-text) #:footnote-start-pred (λ (q) (quad-ref q :fn-text-start))))
(not (quad-ref q :fn-text-start))))))
(define reversed-fn-lines (define reversed-fn-lines
(from-parent (for/list ([fn-line (in-list (reverse fn-lines))]) (from-parent (for/list ([fn-line (in-list (reverse fn-lines))])
;; position bottom to top, in reverse ;; position bottom to top, in reverse

Loading…
Cancel
Save