From 6b462b2d3f531d67b911d931b3c97cf8f14b09dd Mon Sep 17 00:00:00 2001 From: Tim Caswell Date: Tue, 5 Jan 2010 11:39:10 -0600 Subject: [PATCH] Implement enough of the html generator to pass the standard test. --- lib/haml.js | 107 +++++++++++++++++++++++++++++------------- test/div_nesting.haml | 4 +- test/div_nesting.html | 5 +- test/standard.html | 22 ++------- 4 files changed, 83 insertions(+), 55 deletions(-) diff --git a/lib/haml.js b/lib/haml.js index 742209d..ab6f1ab 100644 --- a/lib/haml.js +++ b/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, ">"). + replace(/\"/g, """); +} + +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 ""; + case '': + return ''; + case '1.1': + return ''; + case 'strict': + return ''; + } + } + + // 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"; - } else { - if (content.length > 0 || self_close_tags.indexOf(part.tag) < 0) { - return "<" + part.tag + ">" + content + ""; + + if (part.attribs || part.id || part["class"]) { + if (part.attribs) { + // Activate the attribs + attribs = instance_eval(part.attribs, this, locals); } else { - return ""; + 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 + ""; + } else { + return ""; } }).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*/ diff --git a/test/div_nesting.haml b/test/div_nesting.haml index 40efd6b..ac22bdc 100644 --- a/test/div_nesting.haml +++ b/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 \ No newline at end of file diff --git a/test/div_nesting.html b/test/div_nesting.html index 9c34a8e..f24c492 100644 --- a/test/div_nesting.html +++ b/test/div_nesting.html @@ -1,4 +1,3 @@
Does not close properly -
Nested same level as next div
-
-
Will be nested, but should be top level
+
Nested same level as next div
+
Will be nested, but should be top level
\ No newline at end of file diff --git a/test/standard.html b/test/standard.html index f783a68..0976f84 100644 --- a/test/standard.html +++ b/test/standard.html @@ -1,19 +1,7 @@ - - -Sample haml template - - -
-
-
January 1, 2009
-
Richardson, TX
-
-
-
tim@creationix.com
-
Experienced software professional...
-
-
- - +Sample haml template +
January 1, 2009
+
Richardson, TX
+
tim@creationix.com
+
Experienced software professional...
\ No newline at end of file