Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Implement enough of the html generator to pass the standard test.

  • Loading branch information...
commit 6b462b2d3f531d67b911d931b3c97cf8f14b09dd 1 parent 0b65762
@creationix authored
View
107 lib/haml.js
@@ -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");
};
@@ -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;
@@ -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*/
View
4 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
View
5 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>
View
22 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>
Please sign in to comment.
Something went wrong with that request. Please try again.