expand input contract for `->html`

pull/102/head
Matthew Butterick 9 years ago
parent 2f85a1955f
commit 9d39494b4b

@ -15,12 +15,12 @@ This module also provides everything from @racketmodname[sugar/coerce].
@defproc[
(->html
[xexpr xexpr?]
[xexpr-or-xexprs (or/c xexpr? (listof xexpr?))]
[#:tag html-tag (or/c #f txexpr-tag?) #f]
[#:attrs html-attrs (or/c #f txexpr-attrs?) #f]
[#:splice splice-html? boolean? #f])
string?]
Convert @racket[_xexpr] to an HTML string. Similar to @racket[xexpr->string], but consistent with the HTML spec, text that appears within @code{script} or @code{style} blocks will not be escaped.
Convert @racket[_xexpr-or-xexprs] to an HTML string. Similar to @racket[xexpr->string], but consistent with the HTML spec, text that appears within @code{script} or @code{style} blocks will not be escaped.
@examples[#:eval my-eval
(define tx '(root (script "3 > 2") "Why is 3 > 2?"))
@ -28,7 +28,7 @@ Convert @racket[_xexpr] to an HTML string. Similar to @racket[xexpr->string], bu
(->html tx)
]
The optional keyword arguments @racket[_html-tag] and @racket[_html-attrs] let you set the outer tag and attributes for the generated HTML. If @racket[_xexpr] already has an outer tag or attributes, they will be replaced.
The optional keyword arguments @racket[_html-tag] and @racket[_html-attrs] let you set the outer tag and attributes for the generated HTML. If @racket[_xexpr-or-xexprs] already has an outer tag or attributes, they will be replaced.
@examples[#:eval my-eval
(define tx '(root ((id "huff")) "Bunk beds"))
@ -38,7 +38,7 @@ The optional keyword arguments @racket[_html-tag] and @racket[_html-attrs] let y
(->html tx #:tag 'div #:attrs '((id "doback")))
]
Whereas if @racket[_xexpr] has no tag or attributes, they will be added. If you supply attributes without a tag, you'll get an error.
Whereas if @racket[_xexpr-or-xexprs] has no tag or attributes, they will be added. If you supply attributes without a tag, you'll get an error.
@examples[#:eval my-eval
(define x "Drum kit")
@ -68,11 +68,22 @@ If the generated HTML has an outer tag, the @racket[_splice-html?] option will s
Be careful not to pass existing HTML strings into this function, because the angle brackets will be escaped. Fine if that's what you want, but you probably don't.
@examples[#:eval my-eval
(define tx '(p "You did" (em "what?")))
(define tx '(p "You did " (em "what?")))
(->html tx)
(->html (->html tx))
]
As the input contract suggests, this function can take either a single @racket[xexpr?] or a list of @racket[xexpr?], with the expected results.
@examples[#:eval my-eval
(define tx '(p "You did " (em "what?")))
(->html tx)
(define txs '("You " "did " (em "what?")))
(->html txs)
(->html #:tag 'p txs)
]
@deftogether[(
@defproc[

@ -105,11 +105,18 @@
(define paren-match (cadr matches))
paren-match)
(define+provide/contract (->html x #:tag [tag #f] #:attrs [attrs #f] #:splice [splice? #f])
((xexpr?) (#:tag (or/c #f txexpr-tag?) #:attrs (or/c #f txexpr-attrs?) #:splice boolean?) . ->* . string?)
(define placeholder-tag (gensym))
(define+provide/contract (->html x-in #:tag [tag #f] #:attrs [attrs #f] #:splice [splice? #f])
(((or/c xexpr? (listof xexpr?))) (#:tag (or/c #f txexpr-tag?) #:attrs (or/c #f txexpr-attrs?) #:splice boolean?) . ->* . string?)
(define x (cond
[(txexpr? x-in) x-in]
[(list? x-in) (cons 'html x-in)]
[else x-in]))
(when (and (not (txexpr? x)) attrs (not tag))
(error '->html "can't use attribute list '~a without a #:tag argument" attrs))
(raise-argument-error '->html (format "can't use attribute list ~v without a #:tag argument" attrs)))
(if (or tag (txexpr? x))
(let ()
@ -117,7 +124,7 @@
(define html-attrs (or attrs (and (txexpr? x) (get-attrs x)) null))
(define html-elements (or (and (txexpr? x) (get-elements x)) (list x)))
(define html (xexpr->html (make-txexpr html-tag html-attrs html-elements)))
(if splice?
(if (or splice? (and (list? x-in) (not (txexpr? x-in)) (not tag)))
(trim-outer-tag html)
html))
(xexpr->html x)))
@ -136,7 +143,12 @@
(check-exn exn:fail? (λ() (->html #:attrs '((id "dale")) x) "hello")) ;; won't work without tag
(check-equal? (->html #:splice #t x) "hello")
(check-equal? (->html #:tag 'brennan #:attrs '((id "dale")) x) "<brennan id=\"dale\">hello</brennan>")
(check-equal? (->html #:tag 'brennan #:attrs '((id "dale")) #:splice #t x) "hello"))
(check-equal? (->html #:tag 'brennan #:attrs '((id "dale")) #:splice #t x) "hello")
(define xs '("hello " (em "you") " " 42))
(check-equal? (->html xs) "hello <em>you</em> &#42;")
(check-equal? (->html #:splice #t xs) "hello <em>you</em> &#42;")
(check-equal? (->html #:tag 'div xs) "<div>hello <em>you</em> &#42;</div>"))
(provide when/block)
(define-syntax (when/block stx)

Loading…
Cancel
Save