Skip to content
This repository
Browse code

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

  • Loading branch information...
commit 6b462b2d3f531d67b911d931b3c97cf8f14b09dd 1 parent 0b65762
Tim Caswell authored January 05, 2010
107  lib/haml.js
@@ -7,27 +7,88 @@ if (exports) {
7 7
 
8 8
 var self_close_tags = ["area", "base", "basefont", "br", "hr", "input", "img", "link", "meta"];
9 9
 
10  
-Haml.execute = function (data) {
11  
-  puts(inspect(data));
  10
+function instance_eval(text, context, locals) {
  11
+  var block;
  12
+  block = function () { with(context, locals || {}) { return eval("(" + text + ")"); } };
  13
+  return block.call(context);
  14
+}
  15
+
  16
+function html_escape(text) {
  17
+  return text.
  18
+    replace(/&/g, "&").
  19
+    replace(/</g, "&lt;").
  20
+    replace(/>/g, "&gt;").
  21
+    replace(/\"/g, "&quot;");
  22
+}
  23
+
  24
+Haml.execute = function (data, locals) {
12 25
   if (!data) {
13 26
     return "";
14 27
   }
15 28
   return data.map(function (part) {
16  
-    var content;
  29
+    var content, attribs = "";
17 30
     if (typeof part === 'string') {
  31
+      
  32
+      // Handle header shortcuts
  33
+      if (part.substr(0, 3) === '!!!') {
  34
+        switch (part.substr(4).toLowerCase()) {
  35
+          case 'xml':
  36
+            return "<?xml version='1.0' encoding='utf-8' ?>";
  37
+          case '':
  38
+            return '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
  39
+          case '1.1':
  40
+            return '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">';
  41
+          case 'strict':
  42
+            return '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
  43
+        }
  44
+      }
  45
+
  46
+      // Handle escaped lines
  47
+      if (part[0] === '\\') {
  48
+        return part.substr(1, part.length);
  49
+      }
  50
+
  51
+      // Handle dynamic content
  52
+      if (part[0] === '=') {
  53
+        return instance_eval(part.substr(1, part.length), this, locals);
  54
+      }
  55
+      
  56
+      // Handle plain text
18 57
       return part;
19 58
     }
  59
+    
  60
+    // Recursive call to render contents
20 61
     if (part.$) {
21  
-      content = Haml.execute(part.$);
  62
+      content = Haml.execute.call(this, part.$, locals);
22 63
     }
23  
-    if (content.match(/\n/)) {
24  
-      return "<" + part.tag + ">\n" + content + "\n</" + part.tag + ">";
25  
-    } else {
26  
-      if (content.length > 0 || self_close_tags.indexOf(part.tag) < 0) {
27  
-        return "<" + part.tag + ">" + content + "</" + part.tag + ">";
  64
+    
  65
+    if (part.attribs || part.id || part["class"]) {
  66
+      if (part.attribs) {
  67
+        // Activate the attribs
  68
+        attribs = instance_eval(part.attribs, this, locals);
28 69
       } else {
29  
-        return "</" + part.tag + ">";
  70
+        attribs = {};
  71
+      }
  72
+
  73
+      if (part.id) {
  74
+        attribs.id = attribs.id ? part.id + " " + attribs : part.id;
30 75
       }
  76
+
  77
+      if (part['class']) {
  78
+        attribs['class'] = attribs['class'] ? part['class'] + " " + attribs : part['class'];
  79
+      }
  80
+
  81
+      attribs = " " + Object.keys(attribs).map(function (key) {
  82
+        return key + "=\"" + html_escape(attribs[key]) + "\"";
  83
+      }).join(" ");
  84
+    }
  85
+    
  86
+    
  87
+    // Format the output.
  88
+    if (content.length > 0 || self_close_tags.indexOf(part.tag) < 0) {
  89
+      return "<" + part.tag + attribs + ">" + content + "</" + part.tag + ">";
  90
+    } else {
  91
+      return "</" + part.tag + attribs + ">";
31 92
     }
32 93
   }).join("\n");
33 94
 };
@@ -36,7 +97,7 @@ Haml.execute = function (data) {
36 97
 function parse_attribs(line) {
37 98
   if (!(line.length > 0 && line.charAt(0) === '{')) {
38 99
     return {
39  
-      content: line.substr(1, line.length)
  100
+      content: line[0] === ' ' ? line.substr(1, line.length) : line
40 101
     };
41 102
   }
42 103
   var l = line.length;
@@ -184,26 +245,6 @@ Haml.parse = function (lines) {
184 245
 
185 246
 Haml.render = function(text, options) {
186 247
   options = options || {};
187  
-  var json = Haml.parse.call(options.context || GLOBAL, text, options.locals);
188  
-  return Haml.to_html(json).replace(/\n\n+/g, '\n');
  248
+  var json = Haml.parse(text);
  249
+  return Haml.execute.call(options.context || GLOBAL, json, options.locals);
189 250
 }
190  
-
191  
-
192  
-// Read the sample haml out of the comment in the source
193  
-process.mixin(require('sys'));
194  
-var file = require('file');
195  
-file.read(process.ARGV[1]).addCallback(function (source) {
196  
-  var haml = (source.match(/HAML\n([\S\s]*)\nHAML/))[1];
197  
-  var output = Haml.parse(haml);
198  
-  puts("Output:");
199  
-  puts(inspect(output));
200  
-  puts(Haml.execute(output));
201  
-});
202  
-
203  
-/*HAML
204  
-%div
205  
-  Does not close properly
206  
-  %div Nested same level as next div
207  
-%div
208  
-  Will be nested, but should be top level
209  
-HAML*/
4  test/div_nesting.haml
... ...
@@ -1,5 +1,5 @@
1  
-%div   
  1
+%div
2 2
   Does not close properly
3 3
   %div Nested same level as next div
4  
-%div   
  4
+%div
5 5
   Will be nested, but should be top level
5  test/div_nesting.html
... ...
@@ -1,4 +1,3 @@
1 1
 <div>Does not close properly
2  
-<div>Nested same level as next div</div>
3  
-</div>
4  
-<div>Will be nested, but should be top level</div>
  2
+<div>Nested same level as next div</div></div>
  3
+<div>Will be nested, but should be top level</div>
22  test/standard.html
... ...
@@ -1,19 +1,7 @@
1 1
 <?xml version='1.0' encoding='utf-8' ?>
2 2
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3  
-<html xmlns="http://www.w3.org/1999/xhtml">
4  
-<head>
5  
-<title>Sample haml template</title>
6  
-</head>
7  
-<body>
8  
-<div class="profile">
9  
-<div class="left column">
10  
-<div id="date">January 1, 2009</div>
11  
-<div id="address">Richardson, TX</div>
12  
-</div>
13  
-<div class="right column">
14  
-<div id="email">tim@creationix.com</div>
15  
-<div id="bio">Experienced software professional...</div>
16  
-</div>
17  
-</div>
18  
-</body>
19  
-</html>
  3
+<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Sample haml template</title></head>
  4
+<body><div class="profile"><div class="left column"><div id="date">January 1, 2009</div>
  5
+<div id="address">Richardson, TX</div></div>
  6
+<div class="right column"><div id="email">tim@creationix.com</div>
  7
+<div id="bio">Experienced software professional...</div></div></div></body></html>

0 notes on commit 6b462b2

Please sign in to comment.
Something went wrong with that request. Please try again.