From ce731754271ad64afb2260ec34ae80fde75f9bf9 Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Wed, 25 Jan 2012 16:09:09 -0700 Subject: [PATCH] Changing the defaults for empty tag shorthand in XML --- collects/tests/xml/test.rkt | 1 + collects/web-server/scribblings/faq.scrbl | 53 +++++++++++++++-------- collects/xml/private/writer.rkt | 16 ++++--- collects/xml/xml.scrbl | 8 ++-- 4 files changed, 50 insertions(+), 28 deletions(-) diff --git a/collects/tests/xml/test.rkt b/collects/tests/xml/test.rkt index af4243278d..b7287770ba 100644 --- a/collects/tests/xml/test.rkt +++ b/collects/tests/xml/test.rkt @@ -60,6 +60,7 @@ (define xml-tests (test-suite "XML" + #:before (λ () (empty-tag-shorthand 'always)) (test-suite "Legacy tests" diff --git a/collects/web-server/scribblings/faq.scrbl b/collects/web-server/scribblings/faq.scrbl index 61d03a9baf..867aa41c2e 100644 --- a/collects/web-server/scribblings/faq.scrbl +++ b/collects/web-server/scribblings/faq.scrbl @@ -76,7 +76,7 @@ easily built into an application via URLs. @section{My browser displays my page strangely: my CSS is ignored, sections are missing, etc.} @(require (for-label xml - web-server/http/response-structs)) + web-server/http)) @(define xexpr @tech[#:doc '(lib "xml/xml.scrbl")]{X-expression}) @@ -84,26 +84,45 @@ Most @web-server developers use @|xexpr|s for representing the HTML of their page. However, @|xexpr|s only represent XML and HTML is not exactly XML. This is a common source of problems. -For example, XML allows the "empty tag shorthand", e.g. @litchar{}, -on every tag, while HTML occasionally requires an end tag, e.g. @link["http://www.w3.org/TR/html401/interact/forms.html#h-17.7"]{TEXTAREA}. -Similarly, XML allows an end tag, e.g. @litchar{}, on every tag, while -HTML occasionally forbides an end tag, e.g. @link["http://www.w3.org/TR/html401/struct/objects.html#h-13.2"]{IMG}. -(Of course, browsers do not necessarily implement their HTML parsing as specified and may be more or less lenient towards -XML-like HTML, so your test browser may not treat these forms as problematic.) +For example, XML allows the "empty tag shorthand", e.g. @litchar{}, on every tag, while HTML occasionally requires an end +tag, +e.g. @link["http://www.w3.org/TR/html401/interact/forms.html#h-17.7"]{TEXTAREA}. +Similarly, XML allows an end tag, e.g. @litchar{}, on every tag, while HTML occasionally forbides an +end tag, +e.g. @link["http://www.w3.org/TR/html401/struct/objects.html#h-13.2"]{IMG}. +(Of course, browsers do not necessarily implement their HTML parsing +as specified and may be more or less lenient towards XML-like HTML, so +your test browser may not treat these forms as problematic.) -Since the @web-server uses @racketmodname[xml] to format @|xexpr|s, it inherits @racketmodname[xml]'s default rendering behavior -in general and its use of "empty tag shorthand" in particular. @racketmodname[xml]'s is to always use this short hand. You -can change it with the @racket[empty-tag-shorthand] parameter. +Since the @web-server uses @racketmodname[xml] to format @|xexpr|s, it +inherits @racketmodname[xml]'s default rendering behavior in general +and its use of "empty tag shorthand" in +particular. @racketmodname[xml]'s default is always use the shorthand +with the tags from @racket[html-empty-tags] and never otherwise. This +list should contain the W3C's approved list. You can change it with +the @racket[empty-tag-shorthand] parameter. -You can also change your @xexpr so that an end tag is forced. For example, @racket['(textarea [(name "text")])] renders as -@litchar{}, because of the string content in the @|xexpr|. +You can also change your @xexpr so that an end tag is forced. For +example, @racket['(textarea [(name "text")])] renders as +@litchar{}, +because of the string content in the @|xexpr|. In this case, the end +tag will always be present regardless of the value of +@racket[empty-tag-shorthand]. It is not possible to force the other +possibility; i.e., never include an end tag. -You may think the @web-server could do a better job advertising that the contents it serves is more like XML by default. Unfortunately, -browser support for such @link["http://www.w3.org/TR/xhtml-media-types/#media-types"]{advertisement} is @link["http://www.w3.org/MarkUp/2004/xhtml-faq#ie"]{lacking}. -You can use @racket[make-xexpr-response] to easily customize your application's MIME type and response headers. +You may think the @web-server could do a better job advertising that +the contents it serves is more like XML by default. Unfortunately, +browser support for such +@link["http://www.w3.org/TR/xhtml-media-types/#media-types"]{advertisement} +is @link["http://www.w3.org/MarkUp/2004/xhtml-faq#ie"]{lacking}. You +can use @racket[response/xexpr] to easily customize your +application's MIME type and response headers. -Finally, you may find Web browser inspectors such as the Safari Inspector, Firebug, and the Google Chrome error console to be useful +Finally, you may find Web browser inspectors such as the Safari +Inspector, Firebug, and the Google Chrome error console to be useful tools in identifying offending tags. @section{How do I use templates ``dynamically"?} diff --git a/collects/xml/private/writer.rkt b/collects/xml/private/writer.rkt index 1abc891e7a..b3ad03ed35 100644 --- a/collects/xml/private/writer.rkt +++ b/collects/xml/private/writer.rkt @@ -9,15 +9,17 @@ [empty-tag-shorthand (parameter/c (or/c (symbols 'always 'never) (listof symbol?)))] [html-empty-tags (listof symbol?)]) +(define html-empty-tags + '(param meta link isindex input img hr frame col br basefont base area)) + ;; (empty-tag-shorthand) : (U 'always 'never (listof Symbol)) (define empty-tag-shorthand - (make-parameter 'always - (lambda (x) - (if (or (eq? x 'always) (eq? x 'never) (and (list? x) (andmap symbol? x))) - x - (error 'empty-tag-shorthand "expected 'always, 'never, or a list of symbols: received ~e" x))))) - -(define html-empty-tags '(param meta link isindex input img hr frame col br basefont base area)) + (make-parameter + html-empty-tags + (lambda (x) + (if (or (eq? x 'always) (eq? x 'never) (and (list? x) (andmap symbol? x))) + x + (error 'empty-tag-shorthand "expected 'always, 'never, or a list of symbols: received ~e" x))))) ;; gen-write/display-xml/content : (Nat Output-port -> Void) -> Content [Output-Port]-> Void (define (gen-write/display-xml/content dent) diff --git a/collects/xml/xml.scrbl b/collects/xml/xml.scrbl index 04575e9838..584946bdc9 100644 --- a/collects/xml/xml.scrbl +++ b/collects/xml/xml.scrbl @@ -335,14 +335,14 @@ for elements that have no content. When the parameter is set to @racket['always], the abbreviated notation is always used. When set of @racket['never], the abbreviated notation is never generated. when set to a list of symbols is -provided, tags with names in the list are abbreviated. The default is -@racket['always]. +provided, tags with names in the list are abbreviated. The abbreviated form is the preferred XML notation. However, most browsers designed for HTML will only properly render XHTML if the document uses a mixture of the two formats. The @racket[html-empty-tags] constant contains the W3 consortium's -recommended list of XHTML tags that should use the shorthand.} +recommended list of XHTML tags that should use the shorthand. This +list is the default value of @racket[empty-tag-shorthand].} @defthing[html-empty-tags (listof symbol?)]{ @@ -509,4 +509,4 @@ This library provides a simple path query library for X-expressions. (se-path* '(p #:class) some-page) (se-path*/list '(body) some-page) (se-path*/list '() some-page) -] \ No newline at end of file +]