v6.0-exception
Matthew Butterick 6 years ago
parent 96287c1f59
commit b0352ee513

@ -10,8 +10,8 @@
;; so the whole attr is converted into a single string for sorting, which lets the attr value act as a tiebreaker. ;; so the whole attr is converted into a single string for sorting, which lets the attr value act as a tiebreaker.
;; it doesn't matter that this sort may not be correct (in the sense of a desirable ordering) ;; it doesn't matter that this sort may not be correct (in the sense of a desirable ordering)
;; it just needs to be stable (e.g., a certain set of attrs will always sort the same way) ;; it just needs to be stable (e.g., a certain set of attrs will always sort the same way)
(letrec ([stringify-attr (λ(attr) (string-append (symbol->string (car attr)) (cadr attr)))] (letrec ([stringify-attr (λ (attr) (string-append (symbol->string (car attr)) (cadr attr)))]
[sort-attrs (λ(x) [sort-attrs (λ (x)
(if (txexpr? x) (if (txexpr? x)
(let-values ([(tag attr elements) (txexpr->values x)]) (let-values ([(tag attr elements) (txexpr->values x)])
(txexpr tag (sort attr #:key stringify-attr #:cache-keys? #t string<?) (map sort-attrs elements))) (txexpr tag (sort attr #:key stringify-attr #:cache-keys? #t string<?) (map sort-attrs elements)))

@ -437,7 +437,7 @@ Recursively apply @racket[_proc] to all elements, leaving tags and attributes al
@examples[#:eval my-eval @examples[#:eval my-eval
(define tx '(div "Hello!" (p "Welcome to" (strong "Mars")))) (define tx '(div "Hello!" (p "Welcome to" (strong "Mars"))))
(define upcaser (λ(x) (if (string? x) (string-upcase x) x))) (define upcaser (λ (x) (if (string? x) (string-upcase x) x)))
(map upcaser tx) (map upcaser tx)
(map-elements upcaser tx) (map-elements upcaser tx)
] ]
@ -447,7 +447,7 @@ In practice, most @racket[_txexpr-element]s are strings. But it's unwise to pass
@examples[#:eval my-eval @examples[#:eval my-eval
(define tx '(p "Welcome to" (strong "Mars" amp "Sons"))) (define tx '(p "Welcome to" (strong "Mars" amp "Sons")))
(map-elements string-upcase tx) (map-elements string-upcase tx)
(define upcaser (λ(x) (if (string? x) (string-upcase x) x))) (define upcaser (λ (x) (if (string? x) (string-upcase x) x)))
(map-elements upcaser tx) (map-elements upcaser tx)
] ]
@ -456,13 +456,13 @@ In practice, most @racket[_txexpr-element]s are strings. But it's unwise to pass
(splitf-txexpr (splitf-txexpr
[tx txexpr?] [tx txexpr?]
[pred procedure?] [pred procedure?]
[replace-proc procedure? (λ(x) null)]) [replace-proc procedure? (λ (x) null)])
(values txexpr? (listof txexpr-element?))] (values txexpr? (listof txexpr-element?))]
Recursively descend through @racket[_txexpr] and extract all elements that match @racket[_pred]. Returns two values: a @racket[_txexpr] with the matching elements removed, and the list of matching elements. Sort of esoteric, but I've needed it more than once, so here it is. Recursively descend through @racket[_txexpr] and extract all elements that match @racket[_pred]. Returns two values: a @racket[_txexpr] with the matching elements removed, and the list of matching elements. Sort of esoteric, but I've needed it more than once, so here it is.
@examples[#:eval my-eval @examples[#:eval my-eval
(define tx '(div "Wonderful day" (meta "weather" "good") "for a walk")) (define tx '(div "Wonderful day" (meta "weather" "good") "for a walk"))
(define is-meta? (λ(x) (and (txexpr? x) (equal? 'meta (get-tag x))))) (define is-meta? (λ (x) (and (txexpr? x) (equal? 'meta (get-tag x)))))
(splitf-txexpr tx is-meta?) (splitf-txexpr tx is-meta?)
] ]
@ -470,8 +470,8 @@ Ordinarily, the result of the split operation is to remove the elements that mat
@examples[#:eval my-eval @examples[#:eval my-eval
(define tx '(div "Wonderful day" (meta "weather" "good") "for a walk")) (define tx '(div "Wonderful day" (meta "weather" "good") "for a walk"))
(define is-meta? (λ(x) (and (txexpr? x) (equal? 'meta (get-tag x))))) (define is-meta? (λ (x) (and (txexpr? x) (equal? 'meta (get-tag x)))))
(define replace-meta (λ(x) '(em "meta was here"))) (define replace-meta (λ (x) '(em "meta was here")))
(splitf-txexpr tx is-meta? replace-meta) (splitf-txexpr tx is-meta? replace-meta)
] ]
@ -496,10 +496,10 @@ Like @racket[splitf-txexpr], but only retrieve the elements that match @racket[_
@examples[#:eval my-eval @examples[#:eval my-eval
(define tx '(div "Wonderful day" (meta "weather" "good") (define tx '(div "Wonderful day" (meta "weather" "good")
"for a walk" (meta "dog" "Roxy"))) "for a walk" (meta "dog" "Roxy")))
(define is-meta? (λ(x) (and (txexpr? x) (eq? 'meta (get-tag x))))) (define is-meta? (λ (x) (and (txexpr? x) (eq? 'meta (get-tag x)))))
(findf*-txexpr tx is-meta?) (findf*-txexpr tx is-meta?)
(findf-txexpr tx is-meta?) (findf-txexpr tx is-meta?)
(define is-zimzam? (λ(x) (and (txexpr? x) (eq? 'zimzam (get-tag x))))) (define is-zimzam? (λ (x) (and (txexpr? x) (eq? 'zimzam (get-tag x)))))
(findf*-txexpr tx is-zimzam?) (findf*-txexpr tx is-zimzam?)
(findf-txexpr tx is-zimzam?) (findf-txexpr tx is-zimzam?)
] ]

@ -189,7 +189,7 @@
(check-txexprs-equal? (remove-attrs '(p ((foo "bar")) "hi" (p ((foo "bar")) "hi"))) '(p "hi" (p "hi"))) (check-txexprs-equal? (remove-attrs '(p ((foo "bar")) "hi" (p ((foo "bar")) "hi"))) '(p "hi" (p "hi")))
(check-txexprs-equal? (map-elements (λ(x) (if (string? x) "boing" x)) (check-txexprs-equal? (map-elements (λ (x) (if (string? x) "boing" x))
'(p ((id "zam")) "foo" "bar" (em "square"))) '(p ((id "zam")) "foo" "bar" (em "square")))
'(p ((id "zam")) "boing" "boing" (em "boing"))) '(p ((id "zam")) "boing" "boing" (em "boing")))
@ -201,15 +201,15 @@
(define split-this-tx '(root (meta "foo" "bar") "hello" "world" (meta "foo2" "bar2") (define split-this-tx '(root (meta "foo" "bar") "hello" "world" (meta "foo2" "bar2")
(em "goodnight" "moon" (meta "foo3" "bar3")))) (em "goodnight" "moon" (meta "foo3" "bar3"))))
(define split-predicate (λ(x) (and (txexpr? x) (eq? 'meta (get-tag x))))) (define split-predicate (λ (x) (and (txexpr? x) (eq? 'meta (get-tag x)))))
(check-txexprs-equal? (call-with-values (λ() (splitf-txexpr split-this-tx split-predicate)) list) (check-txexprs-equal? (call-with-values (λ () (splitf-txexpr split-this-tx split-predicate)) list)
(list '(root "hello" "world" (em "goodnight" "moon")) '((meta "foo" "bar") (meta "foo2" "bar2") (meta "foo3" "bar3")))) (list '(root "hello" "world" (em "goodnight" "moon")) '((meta "foo" "bar") (meta "foo2" "bar2") (meta "foo3" "bar3"))))
(define split-proc (λ(x) '(div "foo"))) (define split-proc (λ (x) '(div "foo")))
(check-txexprs-equal? (call-with-values (λ() (splitf-txexpr split-this-tx split-predicate split-proc)) list) (check-txexprs-equal? (call-with-values (λ () (splitf-txexpr split-this-tx split-predicate split-proc)) list)
(list '(root (div "foo") "hello" "world" (div "foo") (em "goodnight" "moon" (div "foo"))) '((meta "foo" "bar") (meta "foo2" "bar2") (meta "foo3" "bar3")))) (list '(root (div "foo") "hello" "world" (div "foo") (em "goodnight" "moon" (div "foo"))) '((meta "foo" "bar") (meta "foo2" "bar2") (meta "foo3" "bar3"))))
(define false-pred (λ(x) (and (txexpr? x) (eq? 'nonexistent-tag (get-tag x))))) (define false-pred (λ (x) (and (txexpr? x) (eq? 'nonexistent-tag (get-tag x)))))
(check-equal? (findf*-txexpr split-this-tx split-predicate) '((meta "foo" "bar") (meta "foo2" "bar2") (meta "foo3" "bar3"))) (check-equal? (findf*-txexpr split-this-tx split-predicate) '((meta "foo" "bar") (meta "foo2" "bar2") (meta "foo3" "bar3")))
(check-false (findf*-txexpr split-this-tx false-pred)) (check-false (findf*-txexpr split-this-tx false-pred))
(check-equal? (findf-txexpr split-this-tx split-predicate) '(meta "foo" "bar")) (check-equal? (findf-txexpr split-this-tx split-predicate) '(meta "foo" "bar"))

Loading…
Cancel
Save