diff --git a/scribblings/template.scrbl b/scribblings/template.scrbl index 7b00201..032e976 100644 --- a/scribblings/template.scrbl +++ b/scribblings/template.scrbl @@ -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[ diff --git a/template.rkt b/template.rkt index d75f8d4..f53f3f1 100644 --- a/template.rkt +++ b/template.rkt @@ -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) "hello") - (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 you *") + (check-equal? (->html #:splice #t xs) "hello you *") + (check-equal? (->html #:tag 'div xs) "
hello you *
")) (provide when/block) (define-syntax (when/block stx)