The Literary Moose (sic) wrote this explanation for this activity in 2004. The original site has since been deleted, and the replacement site does not contain this explanation or any of the examples it linked to. Those examples have been removed from this restored document. Perhaps the original author will restore the origian documents. (2006.07.11)
It is very easy to modify an existing XHTML 1.0 document type. There are many methods of including non-standard content in your documents, including extending the standard. This article outlines the simplest method, that of modifying the DTD directly. To this end, we consider a set of applications that are nonstandard, yet used everywhere from Kamchatka to the Aleuts and back again: the old-style embed
tag used by Flash, Windows Media, QuickTime, Real, SMIL, and SAMI.
This article is not maimed by any flavor of evangelism, in any direction. It is a technical manual you may wish to follow or not. Yet if you do, it would be recommended that you know what you are doing, and why.
We choose the XHTML 1.0 Strict DTD, since it allows for identifiers to be added to the root element, thus enabling users worldwide to use the CSS signature in a most efficient manner. [...]
embed
tag to the DTD
The regular object
tag is included in the special elements group in our DTD:
<!ENTITY % special "%special.pre; | object | img">
Therefore it is natural that we add embed
as one more special element:
<!ENTITY % special "%special.pre; | object | img | embed ">
Now, once this is added, embed
is already permitted as content, but it
isn’t yet defined. It makes sense to try to make it similar to the
definition of the object, hence we search the long (and horribly
white-space-formatted) original DTD for the definition of object
.
Alongside, we will add the definition for embed
. We find this
defintion:
<!ELEMENT object (#PCDATA | param | %block; | form | %inline; | %misc;)*>
The embed
tag, to my knowledge, is not used for forms, nor does it
have the param
child element, so we delete this from the list when we
create a definition for embed
, like so:
<!ELEMENT embed (#PCDATA | %block; | %inline; | %misc;)*>
This is an element definition. It says that pure text can appear
within the embed
tag, as do block-level elements (but not forms),
inline elements, and miscellanea. Now we need to add attributes.
<!ATTLIST embed
%attrs;
pluginspage %URI; #IMPLIED
src %URI; #IMPLIED
type %ContentType; #IMPLIED
quality %Text; #IMPLIED
height %Length; #IMPLIED
width %Length; #IMPLIED
name NMTOKEN #IMPLIED
tabindex %Number; #IMPLIED
>
This list of attributes, like the element definition, reflects the
definition of object
, with redundant attributes removed.
%attrs
embed
tag, like id
, class
, xml:lang,
etc.pluginspage
embed
” version of the codebase attribute for object
. We define it as URIsrc
type
%ContentType;
is used to allow for regular HTML types being addedquality
text
type (high
, low
), so we define it as text
height
, width
%Length;
name
name
is actually used for embed
, but I included it just in case. If it is not used, one may delete it easilytabindex
%Number;
, the regular tabindex
The end result is that we have a custom DTD that will enable us to
validate our pages that include the infernal embed
tag.
DOCTYPE
[Note: The DTD URL below does not work as of July 2006.]
Including the modified DTD in a document is easy, and requires few modifications:
<!DOCTYPE html PUBLIC
"-//LiteraryMoose//DTD XHTML-Enhanced//EN"
"http://www.literarymoose.info/=/dtd/embed/xhtml1-strict-embed.dtd"
>
The DTD is public. The first address is
"-//identity-of-dtd-creating-entity//DTD XHTML-desired-suffix//EN"
.
Then, we add an absolute URI where the DTD resides, so that the
validator can parse the DTD upon validation.
[...] What follows is a series of examples encompassing other technologies that are in common use.
The list of QuickTime-specific attributes is very long. Once we have
an embed
element defined, what remains to be done is to define the
attributes. Recall the existing attribute list:
<!ATTLIST embed
%attrs;
pluginspage %URI; #IMPLIED
src %URI; #IMPLIED
type %ContentType; #IMPLIED
quality %Text; #IMPLIED
height %Length; #IMPLIED
width %Length; #IMPLIED
name NMTOKEN #IMPLIED
tabindex %Number; #IMPLIED
>
The new attributes are:
autohref
autoplay
cache
controller
correction
dontflattenwhensaving
enablejavascript
endtime
fov
goton
hidden
hotspotn
href
kioskmode
loop
moveid
moviename
node
pan
playeveryframe
qtextn
qtsrc
qtsrcchokespeed
qtsrcdontusebrowser
scale
starttime
target
targetcache
tilt
urlsubstitute
volume
A hefty list! Let us sort our 31 attributes by their meaning. The attributes that use plain text as value are:
autohref
autoplay
cache
controller
correction
enablejavascript
kioskmode
loop
playeveryframe
scale
target
targetcache
The attributes that use integers as values are:
fov
moveid
node
pan
qtsrcchokespeed
tilt
volume
The attributes that use URI as a value are:
goton
hotspotn
qtextn
qtsrc
The attributes that are compact are:
dontflattenwhensaving
hidden
qtsrcdontusebrowser
The moviename
is defined as the regular name
, which leaves us with
three problematic attributes:
endtime
starttime
urlsubstitute
The first two require us to add a new entity: <!ENTITY % Time "CDATA">
.
There is no method that I know of that would enable us to use angle
brackets inside values, hence the urlsubstitute
attribute remains
undefined. Quoting Apple:
Replaces every instance of String with SubstituteURL inside any HREF tracks, sprite action URLs, or VR hotspot URLs. Both String and SubstituteURL must be surrounded by angle brackets, and the two must be separated by a colon. The value n may be any integer from 1 to 999, and may be omitted if only one
URLSUBSTITUTE
parameter is specified. Use this parameter to repurpose QuickTime movies with embedded URLs without editing the movies.
The following is an attribute list that includes all Apple-specific attributes bar one:
<!ATTLIST embed
%attrs;
autohref %Text; #IMPLIED
autoplay %Text; #IMPLIED
cache %Text; #IMPLIED
controller %Text; #IMPLIED
correction %Text; #IMPLIED
dontflattenwhensaving (dontflattenwhensaving) #IMPLIED
enablejavascript %Text; #IMPLIED
endtime %Time; #IMPLIED
fov %Number; #IMPLIED
goto1 %URI; #IMPLIED
height %Length; #REQUIRED
hidden (hidden) #IMPLIED
hotspot1 %URI; #IMPLIED
kioskmode %Text; #IMPLIED
loop %Text; #IMPLIED
movieid %Number; #IMPLIED
name NMTOKEN #IMPLIED
node %Number; #IMPLIED
pan %Number; #IMPLIED
playeveryframe %Text; #IMPLIED
pluginspage %URI; #IMPLIED
qtext1 %URI; #IMPLIED
qtsrc %URI; #IMPLIED
qtsrcchokespeed %Number; #IMPLIED
qtsrcdontusebrowser (qtsrcdontusebrowser) #IMPLIED
quality %Text; #IMPLIED
scale %Text; #IMPLIED
src %URI; #REQUIRED
starttime %Time; #IMPLIED
tabindex %Number; #IMPLIED
target %Text; #IMPLIED
targetcache %Text; #IMPLIED
tilt %Number; #IMPLIED
type %ContentType; #IMPLIED
volume %Number; #IMPLIED
width %Length; #REQUIRED
>
Note: I added only one attribute for hotspot, goto
, and qtext
. The sad fact is that if you want to have more than one, you will have to add each of them by hand to your DTD. Hey, don’t blame me, I wasn’t the one who wrote the software!
The good news is that Windows Media Player uses the param
element to
define switches, therefore there is nothing to add in our DTD.
RealPlayer uses the param
element to define switches within the object
tag, yet it also uses the embed
tag, with a handful of custom attributes: controls and console, both of which take the value of text.
<!ATTLIST embed
%attrs;
autohref %Text; #IMPLIED
autoplay %Text; #IMPLIED
cache %Text; #IMPLIED
console %Text; #IMPLIED
controller %Text; #IMPLIED
controls %Text; #IMPLIED
correction %Text; #IMPLIED
dontflattenwhensaving (dontflattenwhensaving) #IMPLIED
enablejavascript %Text; #IMPLIED
endtime %Time; #IMPLIED
fov %Number; #IMPLIED
goto1 %URI; #IMPLIED
height %Length; #REQUIRED
hidden (hidden) #IMPLIED
hotspot1 %URI; #IMPLIED
kioskmode %Text; #IMPLIED
loop %Text; #IMPLIED
movieid %Number; #IMPLIED
name NMTOKEN #IMPLIED
node %Number; #IMPLIED
pan %Number; #IMPLIED
playeveryframe %Text; #IMPLIED
pluginspage %URI; #IMPLIED
qtext1 %URI; #IMPLIED
qtsrc %URI; #IMPLIED
qtsrcchokespeed %Number; #IMPLIED
qtsrcdontusebrowser (qtsrcdontusebrowser) #IMPLIED
quality %Text; #IMPLIED
scale %Text; #IMPLIED
src %URI; #REQUIRED
starttime %Time; #IMPLIED
tabindex %Number; #IMPLIED
target %Text; #IMPLIED
targetcache %Text; #IMPLIED
tilt %Number; #IMPLIED
type %ContentType; #IMPLIED
volume %Number; #IMPLIED
width %Length; #REQUIRED
>
Ready to go.
This set of applications requires a different document-type declaration, and content delivery, and therefore is outside of the scope of this small article.