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.
%attrsembed tag, like id, class, xml:lang, etc.pluginspageembed” version of the codebase attribute for object. We define it as URIsrctype%ContentType; is used to allow for regular HTML types being addedqualitytext type (high, low), so we define it as textheight, width%Length;namename 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:
autohrefautoplaycachecontrollercorrectiondontflattenwhensavingenablejavascriptendtimefovgotonhiddenhotspotnhrefkioskmodeloopmoveidmovienamenodepanplayeveryframeqtextnqtsrcqtsrcchokespeedqtsrcdontusebrowserscalestarttimetargettargetcachetilturlsubstitutevolumeA hefty list! Let us sort our 31 attributes by their meaning. The attributes that use plain text as value are:
autohrefautoplaycachecontrollercorrectionenablejavascriptkioskmodeloopplayeveryframescaletargettargetcacheThe attributes that use integers as values are:
fovmoveidnodepanqtsrcchokespeedtiltvolumeThe attributes that use URI as a value are:
gotonhotspotnqtextnqtsrcThe attributes that are compact are:
dontflattenwhensavinghiddenqtsrcdontusebrowser
The moviename is defined as the regular name, which leaves us with
three problematic attributes:
endtimestarttimeurlsubstitute
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
URLSUBSTITUTEparameter 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.