From 474fc238647205566e40ae7205950e5106338cb7 Mon Sep 17 00:00:00 2001 From: Matthew Butterick Date: Fri, 18 Jan 2019 18:04:03 -0800 Subject: [PATCH] the break --- quad/qtest/markdown.rkt | 20 ++++++-------------- quad/quad/atomize.rkt | 17 +++++++++++------ quad/quad/quad.rkt | 3 --- 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/quad/qtest/markdown.rkt b/quad/qtest/markdown.rkt index 052a9a31..89818815 100644 --- a/quad/qtest/markdown.rkt +++ b/quad/qtest/markdown.rkt @@ -145,19 +145,11 @@ (pt-y (size (car pcs)))))])) (values (cons new-run runs) rest))) - -(struct line-break quad () #:transparent) -(define (line-break-copy x as es) - (struct-copy line-break x - [attrs #:parent quad as] - [elems #:parent quad es])) -(define lbr (q #:type line-break - #:copier line-break-copy - #:printable #f)) -(define pbr (q #:type line-break - #:copier line-break-copy - #:printable #f - #:elems '("¶¶"))) +(struct line-break quad ()) +(define lbr (q #:type line-break #:printable #f)) +;; treat paragraph break as special kind of line break +(struct para-break line-break ()) +(define pbr (q #:type para-break #:printable #f)) (module+ test (check-true (line-break? (second (quad-elems (q "foo" pbr "bar"))))) @@ -188,7 +180,7 @@ ;; when `line-heights` is empty, this is just h (pt w (apply max (cons h line-heights))))] [elems new-elems])) - (if (and q (line-break? q) (equal? (quad-elems q) '("¶¶"))) + (if (para-break? q) (list q:line-spacer) null))))) diff --git a/quad/quad/atomize.rkt b/quad/quad/atomize.rkt index f9c03e1b..ce712c25 100644 --- a/quad/quad/atomize.rkt +++ b/quad/quad/atomize.rkt @@ -62,14 +62,19 @@ (values next-key next-attrs)])) (match (quad-elems x) [(? pair? elems) + ;; we don't use `struct-copy` here because it needs to have the structure id at compile time. + ;; whereas with this technique, we can extract a constructor for any structure type. + ;; notice that the technique depends on + ;; 1) we only need to update attrs and elems + ;; 2) we make them the first two fields, so we know to drop the first two fields of x-tail + (define x-maker (let-values ([(x-structure-type _) (struct-info x)]) + (struct-type-make-constructor x-structure-type))) + (define x-tail (drop (struct->list x) 2)) (append* (for/list ([elem (in-list (merge-adjacent-strings elems 'isolate-white))]) - (match elem - [(? string?) - (define-values (xtype _) (struct-info x)) - (define x-constructor (struct-type-make-constructor xtype)) - (list (apply x-constructor (list* next-attrs (list elem) (cddr (struct->list x)))))] - [_ (loop elem next-attrs next-key)])))] + (if (string? elem) + (list (apply x-maker next-attrs (list elem) x-tail)) + (loop elem next-attrs next-key))))] [_ (list x)]))) (module+ test diff --git a/quad/quad/quad.rkt b/quad/quad/quad.rkt index 213a9f4b..b2c21936 100644 --- a/quad/quad/quad.rkt +++ b/quad/quad/quad.rkt @@ -72,9 +72,6 @@ ;; todo: convert immutable hashes to mutable on input? (define (make-quad #:type [type quad] - #:copier [copier (λ (x as es) (struct-copy quad x - [attrs as] - [elems es]))] #:attrs [attrs (make-hasheq)] #:elems [elems null] #:size [size '(0 0)]