Skip to content

Commit

Permalink
Implement enough of the html generator to pass the standard test.
Browse files Browse the repository at this point in the history
  • Loading branch information
creationix committed Jan 5, 2010
1 parent 0b65762 commit 6b462b2
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 55 deletions.
107 changes: 74 additions & 33 deletions lib/haml.js
Expand Up @@ -7,27 +7,88 @@ if (exports) {

var self_close_tags = ["area", "base", "basefont", "br", "hr", "input", "img", "link", "meta"];

Haml.execute = function (data) {
puts(inspect(data));
function instance_eval(text, context, locals) {
var block;
block = function () { with(context, locals || {}) { return eval("(" + text + ")"); } };
return block.call(context);
}

function html_escape(text) {
return text.
replace(/&/g, "&").
replace(/</g, "&lt;").
replace(/>/g, "&gt;").
replace(/\"/g, "&quot;");
}

Haml.execute = function (data, locals) {
if (!data) {
return "";
}
return data.map(function (part) {
var content;
var content, attribs = "";
if (typeof part === 'string') {

// Handle header shortcuts
if (part.substr(0, 3) === '!!!') {
switch (part.substr(4).toLowerCase()) {
case 'xml':
return "<?xml version='1.0' encoding='utf-8' ?>";
case '':
return '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
case '1.1':
return '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">';
case 'strict':
return '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
}
}

// Handle escaped lines
if (part[0] === '\\') {
return part.substr(1, part.length);
}

// Handle dynamic content
if (part[0] === '=') {
return instance_eval(part.substr(1, part.length), this, locals);
}

// Handle plain text
return part;
}

// Recursive call to render contents
if (part.$) {
content = Haml.execute(part.$);
content = Haml.execute.call(this, part.$, locals);
}
if (content.match(/\n/)) {
return "<" + part.tag + ">\n" + content + "\n</" + part.tag + ">";
} else {
if (content.length > 0 || self_close_tags.indexOf(part.tag) < 0) {
return "<" + part.tag + ">" + content + "</" + part.tag + ">";

if (part.attribs || part.id || part["class"]) {
if (part.attribs) {
// Activate the attribs
attribs = instance_eval(part.attribs, this, locals);
} else {
return "</" + part.tag + ">";
attribs = {};
}

if (part.id) {
attribs.id = attribs.id ? part.id + " " + attribs : part.id;
}

if (part['class']) {
attribs['class'] = attribs['class'] ? part['class'] + " " + attribs : part['class'];
}

attribs = " " + Object.keys(attribs).map(function (key) {
return key + "=\"" + html_escape(attribs[key]) + "\"";
}).join(" ");
}


// Format the output.
if (content.length > 0 || self_close_tags.indexOf(part.tag) < 0) {
return "<" + part.tag + attribs + ">" + content + "</" + part.tag + ">";
} else {
return "</" + part.tag + attribs + ">";
}
}).join("\n");
};
Expand All @@ -36,7 +97,7 @@ Haml.execute = function (data) {
function parse_attribs(line) {
if (!(line.length > 0 && line.charAt(0) === '{')) {
return {
content: line.substr(1, line.length)
content: line[0] === ' ' ? line.substr(1, line.length) : line
};
}
var l = line.length;
Expand Down Expand Up @@ -184,26 +245,6 @@ Haml.parse = function (lines) {

Haml.render = function(text, options) {
options = options || {};
var json = Haml.parse.call(options.context || GLOBAL, text, options.locals);
return Haml.to_html(json).replace(/\n\n+/g, '\n');
var json = Haml.parse(text);
return Haml.execute.call(options.context || GLOBAL, json, options.locals);
}


// Read the sample haml out of the comment in the source
process.mixin(require('sys'));
var file = require('file');
file.read(process.ARGV[1]).addCallback(function (source) {
var haml = (source.match(/HAML\n([\S\s]*)\nHAML/))[1];
var output = Haml.parse(haml);
puts("Output:");
puts(inspect(output));
puts(Haml.execute(output));
});

/*HAML
%div
Does not close properly
%div Nested same level as next div
%div
Will be nested, but should be top level
HAML*/
4 changes: 2 additions & 2 deletions test/div_nesting.haml
@@ -1,5 +1,5 @@
%div
%div
Does not close properly
%div Nested same level as next div
%div
%div
Will be nested, but should be top level
5 changes: 2 additions & 3 deletions test/div_nesting.html
@@ -1,4 +1,3 @@
<div>Does not close properly
<div>Nested same level as next div</div>
</div>
<div>Will be nested, but should be top level</div>
<div>Nested same level as next div</div></div>
<div>Will be nested, but should be top level</div>
22 changes: 5 additions & 17 deletions test/standard.html
@@ -1,19 +1,7 @@
<?xml version='1.0' encoding='utf-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Sample haml template</title>
</head>
<body>
<div class="profile">
<div class="left column">
<div id="date">January 1, 2009</div>
<div id="address">Richardson, TX</div>
</div>
<div class="right column">
<div id="email">tim@creationix.com</div>
<div id="bio">Experienced software professional...</div>
</div>
</div>
</body>
</html>
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Sample haml template</title></head>
<body><div class="profile"><div class="left column"><div id="date">January 1, 2009</div>
<div id="address">Richardson, TX</div></div>
<div class="right column"><div id="email">tim@creationix.com</div>
<div id="bio">Experienced software professional...</div></div></div></body></html>

0 comments on commit 6b462b2

Please sign in to comment.