ramifications

main
Matthew Butterick 6 years ago
parent df871eb5d7
commit d7194e75f4

@ -16,6 +16,11 @@ We said `raco pkg install hyphenate` dude
What?!
```
Code block
Goes here
```
> Hyphenate `xexpr` by calculating hyphenation points and inserting
`joiner` at those points. By default, `joiner` is the soft hyphen
\(Unicode 00AD = decimal 173\). Words shorter than
@ -52,4 +57,4 @@ hyphens](http://practicaltypography.com/optional-hyphens.html) in their
text.A [list of web colors](https://en.wikipedia.org/wiki/Web_colors).
Certain word processors allow users to [insert soft
hyphens](http://practicaltypography.com/optional-hyphens.html) in their
text.
text.

@ -146,7 +146,6 @@
(struct line-break quad ())
(define lbr (q #:type line-break))
(define (line-wrap xs size)
(wrap xs size
@ -155,14 +154,8 @@
[_ #f]))
#:soft-break soft-break-for-line?
#:finish-wrap (λ (pcs q idx)
#R pcs
#R q
#R (= idx 1)
(define new-elems (consolidate-runs pcs))
(append
(if (and (= idx 1) #R (equal? (quad-elems q) '("¶¶")))
(list q:line-spacer)
null)
(list (struct-copy quad q:line
[attrs (let ([attrs (hash-copy (quad-attrs q:line))])
(define container-val (hash-ref (quad-attrs (car new-elems)) 'container #f))
@ -180,7 +173,10 @@
(match-define (list w h) (quad-size q:line))
;; when `line-heights` is empty, this is just h
(pt w (apply max (cons h line-heights))))]
[elems new-elems]))))))
[elems new-elems]))
(if (and q (equal? (quad-elems q) '("¶¶")))
(list q:line-spacer)
null)))))
(define top-margin 60)
(define bottom-margin 120)

@ -30,37 +30,39 @@
;; wrap-triggering-q is ordinarily the last accumulated q
;; unless it's the last wrap, in which case it's #f
;; but we capture it separately because it's likely to get trimmed away by `nonprinting-at-end?`
;; note: we don't trim `soft-break?` or `hard-break?` because that's an orthogonal consideration
;; for instance, a hyphen is `soft-break?` but shouldn't be trimmed.
(finish-wrap-proc (reverse (dropf qs nonprinting-at-end?)) wrap-triggering-q wrap-idx))
(let loop ([wraps null] ; list of (list of quads)
[wrap-idx 1] ; wrap count (could be (length wraps) but we'd rather avoid `length`)
[next-wrap-head null] ; list of quads ending in previous `soft-break?`
[next-wrap-head null] ; list of quads ending in previous `soft-break?` or `hard-break?`
[next-wrap-tail null] ; list of unbreakable quads
[current-dist #false] ; #false (to indicate start) or integer
[qs qs]) ; list of quads
(match qs
[(or (list (? hard-break?)) (== empty))
[(or (== empty) (list (? hard-break?))) ; ignore single trailing hard break
(define last-wrap (finish-wrap (wrap-append next-wrap-tail next-wrap-head) wrap-idx #f))
; append* because `finish-wrap-proc` returns a spliceable list
; reverse because wraps accumulated in reverse
; as a special case, '(()) is returned as just '()
(match (append* (reverse (cons last-wrap wraps)))
[(list (list)) (list)]
[val val])]
[(cons (? hard-break? hard-break-q) other-qs)
(debug-report 'hard-break)
;; a break is inevitable but we want to wait to finish the wrap until we see a hard quad
;; but we can move the current-partial into the current-wrap
(loop wraps
wrap-idx
(wrap-append (cons hard-break-q next-wrap-tail) next-wrap-head)
null
current-dist
other-qs)]
[wraps wraps])]
[(cons q other-qs)
(debug-report q 'next-q)
(debug-report (quad-elems q) 'next-q-elems)
(define at-start? (not current-dist))
(cond
[at-start?
[(hard-break? q)
(debug-report 'found-hard-break)
;; put hard break onto next-wrap-tail, and finish the wrap
(define wrap-qs (wrap-append (cons q next-wrap-tail) next-wrap-head))
(loop (cons (finish-wrap wrap-qs wrap-idx) wraps)
(add1 wrap-idx)
null
null
#false
other-qs)]
[(let ([at-start? (not current-dist)]) at-start?)
(match q
[(and (? soft-break?) (? nonprinting-at-start?))
(debug-report q 'skipping-soft-break-at-beginning)
@ -269,7 +271,7 @@
(test-case
"hard breaks and spurious spaces"
(check-equal? (linewrap (list a sp sp sp lbr b) 2) (list (list a) lbr (list b)))
(check-equal? (linewrap (list x sp lbr sp sp x x sp) 3) (list (list x) lbr (list x x)))
(check-equal? (linewrap (list a sp lbr sp sp b c sp) 3) (list (list a) lbr (list b c)))
(check-equal? (linewrap (list sp sp x x sp sp lbr sp sp sp x) 3) (list (list x x) lbr (list x)))
(check-equal? (linewrap (list a sp b sp sp lbr sp c) 3) (list (list a sp b) lbr (list c)))
(check-equal? (linewrap (list x x x x) 3) (list (list x x x) lbr (list x)))
@ -313,7 +315,9 @@
(wrap (flatten xs) size debug
#:hard-break (λ (x) (and (quad? x) (memv (car (quad-elems x)) '(#\page))))
#:soft-break (λ (x) (and (quad? x) (eq? x lbr)))) pbr))
(define pbr (q #:size #false #:elems '(#\page)))
(define pbr (q #:size #false
#:printable #false
#:elems '(#\page)))
(module+ test
(require rackunit)
@ -331,20 +335,20 @@
(module+ test
(test-case
"hard page breaks"
(check-equal? (pagewrap (list x pbr x x) 2) (list (list x) pbr (list x x)))
(check-equal? (pagewrap (list a pbr b c) 2) (list (list a) pbr (list b c)))
(check-equal? (pagewrap (list x pbr x x) 1) (list (list x) pbr (list x) pbr (list x)))
(check-equal? (pagewrap (list x pbr pbr x x) 1) (list (list x) pbr (list) pbr (list x) pbr (list x)))
(check-equal? (pagewrap (list x pbr pbr x x) 2) (list (list x) pbr (list) pbr (list x x)))
(check-equal? (pagewrap (list lbr x lbr lbr pbr lbr x x lbr) 2) (list (list x) pbr (list x x)))))
#;(module+ test
(test-case
"composed line breaks and page breaks"
(check-equal? (pagewrap (linewrap null 1) 2) (list))
(check-equal? (pagewrap (linewrap (list x) 1) 2) (list (list x)))
(check-equal? (pagewrap (linewrap (list x x x) 1) 2) (list (list x lbr x) pbr (list x)))
(check-equal? (pagewrap (linewrap (list x x x) 2) 2) (list (list x x) pbr (list x)))
(check-equal? (pagewrap (linewrap (list x x x) 2) 1) (list (list x) pbr (list x) pbr (list x)))))
(module+ test
(test-case
"composed line breaks and page breaks"
(check-equal? (pagewrap (linewrap null 1) 2) (list))
(check-equal? (pagewrap (linewrap (list x) 1) 2) (list (list x)))
(check-equal? (pagewrap (linewrap (list x x x) 1) 2) (list (list x lbr x) pbr (list x)))
(check-equal? (pagewrap (linewrap (list x x x) 2) 2) (list (list x x) pbr (list x)))
(check-equal? (pagewrap (linewrap (list x x x) 2) 1) (list (list x) pbr (list x) pbr (list x)))))
(define (linewrap2 xs size [debug #f])
(add-between
@ -379,3 +383,4 @@
(check-equal? (wrap qs 3 #:soft-break sp?) (list (list (qhard)) (list (qhard) (qhard))))
;; wraps anywhere, so two qhards fit onto first wrap with space
(check-equal? (wrap qs 3 #:soft-break sp? #:wrap-anywhere? #t) (list (list (qhard) (qsoft) (qhard)) (list (qhard))))))

Loading…
Cancel
Save