add `attr-ref*`

typed-work
Matthew Butterick 10 years ago
parent b701ede767
commit 33db527d04

@ -1,6 +1,6 @@
#lang racket/base
(require (for-syntax racket/base))
(require racket/match xml racket/string)
(require racket/match xml racket/string racket/list racket/bool)
(module+ safe (require racket/contract))
@ -166,12 +166,6 @@
(any/c . -> . boolean?)
(ormap (λ(test) (test x)) (list txexpr-attr? txexpr-attrs? can-be-txexpr-attr-key? can-be-txexpr-attr-value?)))
(define (flatten orig-sexp)
(let loop ([sexp orig-sexp] [acc null])
(cond [(null? sexp) acc]
[(pair? sexp) (loop (car sexp) (loop (cdr sexp) acc))]
[else (cons sexp acc)])))
(define+provide+safe (attrs->hash . items)
(() #:rest (listof can-be-txexpr-attrs?) . ->* . hash?)
;; can be liberal with input because they're all just nested key/value pairs
@ -215,6 +209,15 @@
(with-handlers ([exn:fail? (λ(e) (error (format "attr-ref: no value found for key ~v" key)))])
(hash-ref (attrs->hash (get-attrs tx)) key)))
(define+provide+safe (attr-ref* tx key)
(txexpr? can-be-txexpr-attr-key? . -> . (listof txexpr-attr-value?))
(filter-not false?
(flatten
(let loop ([tx tx])
(and (txexpr? tx)
(cons (and (attrs-have-key? tx key)(attr-ref tx key))
(map loop (get-elements tx))))))))
;; convert list of alternating keys & values to attr
(define+provide+safe (merge-attrs . items)
(() #:rest (listof can-be-txexpr-attrs?) . ->* . txexpr-attrs?)

@ -343,6 +343,19 @@ Given a @racket[_key], look up the corresponding @racket[_value] in the attribut
(attr-ref tx 'nonexistent-key)
]
@defproc[
(attr-ref*
[tx txexpr?]
[key can-be-txexpr-attr-key?])
(listof txexpr-attr-value?)]
Like @racket[attr-ref], but returns a recursively gathered list of all the @racket[_value]s for that key within @racket[_tx]. Asking for a nonexistent key produces @racket[null].
@examples[#:eval my-eval
(define tx '(div [[class "red"]] "Hello" (em ([class "blue"]) "world")))
(attr-ref* tx 'class)
(attr-ref* tx 'nonexistent-key)
]
@defproc[
(attr-set

@ -137,6 +137,12 @@
'(p "boing" "boing" (em "boing")))
(check-equal? (attr-ref* '(root ((foo "bar")) "hello" "world" (meta ((foo "zam")) "bar2")
(em ((foo "zam")) "goodnight" "moon")) 'foo) '("bar" "zam" "zam"))
(check-equal? (attr-ref* '(root ((foo "bar")) "hello" "world" (meta ((foo "zam")) "bar2")
(em ((foo "zam")) "goodnight" "moon")) 'nonexistent-key) '())
(define split-this-tx '(root (meta "foo" "bar") "hello" "world" (meta "foo2" "bar2")
(em "goodnight" "moon" (meta "foo3" "bar3"))))

Loading…
Cancel
Save