Skip to content

Instantly share code, notes, and snippets.

@fb55
Created September 17, 2012 12:28
Show Gist options
  • Save fb55/3737020 to your computer and use it in GitHub Desktop.
Save fb55/3737020 to your computer and use it in GitHub Desktop.
ClosingTags
/*
Tags that have a special meaning in HTML
Every tag can have the following properties:
* parent: A list of all possible parent nodes. If none is present, the tag is wrapped in the first one.
* prev: A list of tags that need to preceed the tag. If they don't exist, they are created.
* past: A list of tags that needs to follow the tag.
* close: A list of elements that are closed when the tag appears. Only walks until it finds the next required parent.
* children: The possible child nodes. Can be a list, false or "text".
* If a list, it's a list of elements that need to be included in the tag. If they don't exist, they are created.
* If "text", all content is handled as text.
* If false, the tag closes immediately.
* unique: Can only exist once. Is ignored after the first time.
* whitespace: Whitespace is significant.
*/
//Tags that close others
module.exports = {
__proto__: null,
html: {
children: ["head", "body"]
//TODO mark this as the root element
},
//descendants of <html>
//direct descendants
head: {
//children: ["title"], //must have a <title> //not enforced
parent: ["html"],
past: ["body"]
},
body: {
prev: ["head"] //must follow a <head> (also enforces <html>)
},
//can appear everywhere
script: {
children: "text",
parent: ["html"]
},
style: {
children: "text",
parent: ["html"]
},
noscript: {
parent: ["html"],
close: ["noscript"]
},
//descendants of <head>
title: {
parent: ["head"],
unique: true
},
base: {
parent: ["head"],
unique: true,
children: false
},
meta: {
parent: ["head"],
children: false
},
link: {
parent: ["head"],
children: false
},
//descendants of <body>
//tags without a special meaning
section: { parent: ["body"] },
article: { parent: ["body"] },
nav: { parent: ["body"] },
aside: { parent: ["body"] },
header: { parent: ["body"] },
footer: { parent: ["body"] },
address: { parent: ["body"] },
//headers
hgroup: { parent: ["body"] },
h1: { parent: ["body"], close: ["h1", "h2", "h3", "h4", "h5", "h6"] },
h2: { parent: ["body"], close: ["h1", "h2", "h3", "h4", "h5", "h6"] },
h3: { parent: ["body"], close: ["h1", "h2", "h3", "h4", "h5", "h6"] },
h4: { parent: ["body"], close: ["h1", "h2", "h3", "h4", "h5", "h6"] },
h5: { parent: ["body"], close: ["h1", "h2", "h3", "h4", "h5", "h6"] },
h6: { parent: ["body"], close: ["h1", "h2", "h3", "h4", "h5", "h6"] },
//empty elements
hr: {
children: false,
parent: ["body"]
},
br: {
children: false,
parent: ["body"]
},
wbr: {
children: false,
parent: ["body"]
},
//embeded content
img: {
children: false,
parent: ["body"]
},
embed: {
children: false,
parent: ["body"]
},
object: { parent: ["body"] },
param: {
children: false,
parent: ["object"]
},
video: { parent: ["body"] },
audio: { parent: ["body"] },
source: {
children: false,
parent: ["audio", "video"]
},
track: {
children: false,
parent: ["audio", "video"]
},
//embedded documents
iframe: { parent: ["body"] },
math: {
//MathML
//children: "text",
parent: ["body"]
},
svg: {
//scalable vector graphics
//children: "text",
parent: ["body"]
},
canvas: {
parent: ["body"]
},
//grouping content
p: {
parent: ["body"],
close: ["p"]
},
blockquote: {
parent: ["body"],
close: ["p"]
},
div: { parent: ["body"] },
span: { parent: ["body"] },
//tags with significant whitespace
pre: {
whitespace: true
},
//lists
ol: {
parent: ["body"],
close: ["p"]
},
ul: {
parent: ["body"],
close: ["p"]
},
dl: {
parent: ["body"],
close: ["p"]
},
//list elements
li: {
close: ["li"],
parent: ["ul", "ol", "menu"]
},
dt: {
close: ["dd", "dt"],
parent: ["dl"],
past: ["dd"]
},
dd: {
close: ["dd", "dt"],
parent: ["dl"],
prev: ["dt"]
},
//figures
figure: {
parent: ["body"]
},
figcaption: {
parent: ["figure"]
},
//links
a: { parent: ["body"] },
//diverse elements
em: { parent: ["body"] },
strong: { parent: ["body"] },
small: { parent: ["body"] },
s: { parent: ["body"] },
cite: { parent: ["body"] },
q: { parent: ["body"] },
dfn: { parent: ["body"] },
abbr: { parent: ["body"] },
data: { parent: ["body"] },
time: { parent: ["body"] },
code: { parent: ["body"] },
var: { parent: ["body"] },
samp: { parent: ["body"] },
kbd: { parent: ["body"] },
sub: { parent: ["body"] },
sup: { parent: ["body"] },
i: { parent: ["body"] },
b: { parent: ["body"] },
u: { parent: ["body"] },
mark: { parent: ["body"] },
bdi: { parent: ["body"] },
bdo: { parent: ["body"] },
map: { parent: ["body"] },
area: {
parent: ["body"],
children: false
},
//ruby element
ruby: { parent: ["body"], children: ["rt"] },
rt: { parent: ["ruby"] },
rp: { parent: ["ruby"] },
//edits
ins: { parent: ["body"] },
del: { parent: ["body"] },
//tables
table: {
parent: ["body"],
children: ["tbody", "thead", "tfoot"]
},
caption: { parent: ["table"], unique: true },
colgroup: { parent: ["table"], unique: true, close: ["caption"] },
thead: { parent: ["table"], unique: true, close: ["caption", "colgroup"] },
tbody: { parent: ["table"], unique: true, close: ["caption", "colgroup", "thead"] },
tfoot: { parent: ["table"], unique: true, close: ["caption", "colgroup", "thead", "tbody"] },
col: {
children: false,
parent: ["colgroup"]
},
tr: {
close: ["tr"],
parent: ["tbody", "thead", "tfoot"]
},
td: {
close: ["td", "th"],
parent: ["tr"]
},
th: {
close: ["td", "th"],
parent: ["tr"]
},
//forms
form: { parent: ["body"] },
fieldset: { parent: ["body"] },
legend: { parent: ["fieldset"] },
label: { parent: ["body"] },
button: { parent: ["body"] },
input: {
children: false,
parent: ["body"]
},
datalist: { parent: ["body"] },
select: { parent: ["body"] },
optgroup: { parent: ["select"] },
option: { parent: ["select", "optgroup", "datalist"] },
textarea: {
whitespace: true,
children: "text",
parent: ["body"]
},
keygen: {
children: false,
parent: ["body"]
},
output: { parent: ["body"] },
progress: { parent: ["body"] },
meter: { parent: ["body"] },
//non-conforming-features (not complete)
applet: { parent: ["body"] },
marquee: { parent: ["body"] },
big: { parent: ["body"] },
center: { parent: ["body"] },
font: { parent: ["body"] },
blink: { parent: ["body"] },
acronym: { parent: ["body"] },
frameset: { parent: ["body"] },
frame: {
parent: ["frameset"],
children: false
},
basefont: {
parent: ["body"],
children: false
}
isindex: {
parent: ["body"],
children: false
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment