hbs_plus 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,147 @@
1
+
2
+ var Benchmark = require("benchmark");
3
+
4
+ var BenchWarmer = function(names) {
5
+ this.benchmarks = [];
6
+ this.currentBenches = [];
7
+ this.names = [];
8
+ this.errors = {};
9
+ };
10
+
11
+ var print = require("sys").print;
12
+
13
+ BenchWarmer.prototype = {
14
+ winners: function(benches) {
15
+ var result = Benchmark.filter(benches, function(bench) { return bench.cycles; });
16
+
17
+ if (result.length > 1) {
18
+ result.sort(function(a, b) { return b.compare(a); });
19
+ first = result[0];
20
+ last = result[result.length - 1];
21
+
22
+ var winners = [];
23
+
24
+ Benchmark.each(result, function(bench) {
25
+ if (bench.compare(first) === 0) {
26
+ winners.push(bench);
27
+ }
28
+ });
29
+
30
+ return winners;
31
+ } else {
32
+ return result;
33
+ }
34
+ },
35
+ suite: function(suite, fn) {
36
+ this.suiteName = suite;
37
+ this.first = true;
38
+
39
+ var self = this;
40
+
41
+ fn(function(name, benchFn) {
42
+ self.push(name, benchFn);
43
+ });
44
+ },
45
+ push: function(name, fn) {
46
+ if(this.names.indexOf(name) == -1) {
47
+ this.names.push(name);
48
+ }
49
+
50
+ var first = this.first, suiteName = this.suiteName, self = this;
51
+ this.first = false;
52
+
53
+ var bench = new Benchmark(function() {
54
+ fn();
55
+ }, {
56
+ name: this.suiteName + ": " + name,
57
+ onComplete: function() {
58
+ if(first) { self.startLine(suiteName); }
59
+ self.writeBench(bench);
60
+ self.currentBenches.push(bench);
61
+ }, onError: function() {
62
+ self.errors[this.name] = this;
63
+ }
64
+ });
65
+
66
+ this.benchmarks.push(bench);
67
+ },
68
+ bench: function() {
69
+ var benchSize = 0, names = this.names, self = this, i, l;
70
+
71
+ for(i=0, l=names.length; i<l; i++) {
72
+ var name = names[i];
73
+
74
+ if(benchSize < name.length) { benchSize = name.length; }
75
+ }
76
+
77
+ this.nameSize = benchSize + 2;
78
+ this.benchSize = 20;
79
+ var horSize = 0;
80
+
81
+ this.startLine("ops/msec");
82
+ horSize = horSize + "ops/msec ".length;
83
+ for(i=0, l=names.length; i<l; i++) {
84
+ print(names[i] + new Array(this.benchSize - names[i].length + 1).join(" "));
85
+ horSize = horSize + this.benchSize;
86
+ }
87
+
88
+ print("WINNER(S)");
89
+ horSize = horSize + "WINNER(S)".length;
90
+
91
+ print("\n" + new Array(horSize + 1).join("-"));
92
+
93
+ Benchmark.invoke(this.benchmarks, {
94
+ name: "run",
95
+ onComplete: function() {
96
+ var errors = false, prop, bench;
97
+ for(prop in self.errors) { if(self.errors.hasOwnProperty(prop)) { errors = true; break; } }
98
+
99
+ if(errors) {
100
+ print("\n\nErrors:\n");
101
+ for(prop in self.errors) {
102
+ if(self.errors.hasOwnProperty(prop)) {
103
+ bench = self.errors[prop];
104
+ print("\n" + bench.name + ":\n");
105
+ print(bench.error.message);
106
+ if(bench.error.stack) {
107
+ print(bench.error.stack.join("\n"));
108
+ }
109
+ print("\n");
110
+ }
111
+ }
112
+ }
113
+ }
114
+ });
115
+ },
116
+ startLine: function(name) {
117
+ var winners = Benchmark.map(this.winners(this.currentBenches), function(bench) {
118
+ return bench.name.split(": ")[1];
119
+ });
120
+
121
+ this.currentBenches = [];
122
+
123
+ print(winners.join(", "));
124
+ print("\n");
125
+ var padding = this.nameSize - name.length + 1;
126
+ name = name + new Array(padding).join(" ");
127
+ print(name);
128
+ },
129
+ writeBench: function(bench) {
130
+ var out;
131
+
132
+ if(!bench.error) {
133
+ var count = bench.hz,
134
+ moe = count * bench.stats.RME / 100;
135
+
136
+ out = Math.round(count / 1000) + " ±" + Math.round(moe / 1000) + " (" + bench.cycles + ")";
137
+ } else {
138
+ out = "E";
139
+ }
140
+
141
+ var padding = this.benchSize - out.length + 1;
142
+ out = out + new Array(padding).join(" ");
143
+ print(out);
144
+ }
145
+ };
146
+
147
+ module.exports = BenchWarmer;
@@ -0,0 +1,166 @@
1
+ require.paths.push("lib");
2
+ require.paths.push("vendor");
3
+ require.paths.push("vendor/dustjs/lib");
4
+ require.paths.push("vendor/coffee/lib");
5
+ require.paths.push("vendor/eco/lib");
6
+
7
+
8
+ var BenchWarmer = require("./benchwarmer");
9
+ Handlebars = require("handlebars");
10
+
11
+ var dust = require("dust");
12
+ var Mustache = require("mustache");
13
+ var ecoExports = require("eco");
14
+
15
+ eco = function(str) {
16
+ var module = {};
17
+ var template = new Function("module", ecoExports.compile(str));
18
+ template(module);
19
+ return module.exports;
20
+ }
21
+
22
+ var benchDetails = {
23
+ string: {
24
+ context: {},
25
+ handlebars: "Hello world",
26
+ dust: "Hello world",
27
+ mustache: "Hello world",
28
+ eco: "Hello world"
29
+ },
30
+ variables: {
31
+ context: {name: "Mick", count: 30},
32
+ handlebars: "Hello {{name}}! You have {{count}} new messages.",
33
+ dust: "Hello {name}! You have {count} new messages.",
34
+ mustache: "Hello {{name}}! You have {{count}} new messages.",
35
+ eco: "Hello <%= @name %>! You have <%= @count %> new messages."
36
+ },
37
+ object: {
38
+ context: { person: { name: "Larry", age: 45 } },
39
+ handlebars: "{{#with person}}{{name}}{{age}}{{/with}}",
40
+ dust: "{#person}{name}{age}{/person}",
41
+ mustache: "{{#person}}{{name}}{{age}}{{/person}}"
42
+ },
43
+ array: {
44
+ context: { names: [{name: "Moe"}, {name: "Larry"}, {name: "Curly"}, {name: "Shemp"}] },
45
+ handlebars: "{{#each names}}{{name}}{{/each}}",
46
+ dust: "{#names}{name}{/names}",
47
+ mustache: "{{#names}}{{name}}{{/names}}",
48
+ eco: "<% for item in @names: %><%= item.name %><% end %>"
49
+ },
50
+ partial: {
51
+ context: { peeps: [{name: "Moe", count: 15}, {name: "Larry", count: 5}, {name: "Curly", count: 1}] },
52
+ partials: {
53
+ mustache: { variables: "Hello {{name}}! You have {{count}} new messages." },
54
+ handlebars: { variables: "Hello {{name}}! You have {{count}} new messages." }
55
+ },
56
+ handlebars: "{{#each peeps}}{{>variables}}{{/each}}",
57
+ dust: "{#peeps}{>variables/}{/peeps}",
58
+ mustache: "{{#peeps}}{{>variables}}{{/peeps}}"
59
+ },
60
+ recursion: {
61
+ context: { name: '1', kids: [{ name: '1.1', kids: [{name: '1.1.1', kids: []}] }] },
62
+ partials: {
63
+ mustache: { recursion: "{{name}}{{#kids}}{{>recursion}}{{/kids}}" },
64
+ handlebars: { recursion: "{{name}}{{#each kids}}{{>recursion}}{{/each}}" }
65
+ },
66
+ handlebars: "{{name}}{{#each kids}}{{>recursion}}{{/each}}",
67
+ dust: "{name}{#kids}{>recursion:./}{/kids}",
68
+ mustache: "{{name}}{{#kids}}{{>recursion}}{{/kids}}"
69
+ },
70
+ complex: {
71
+ handlebars: "<h1>{{header}}</h1>{{#if items}}<ul>{{#each items}}{{#if current}}" +
72
+ "<li><strong>{{name}}</strong></li>{{^}}" +
73
+ "<li><a href=\"{{url}}\">{{name}}</a></li>{{/if}}" +
74
+ "{{/each}}</ul>{{^}}<p>The list is empty.</p>{{/if}}",
75
+
76
+ dust: "<h1>{header}</h1>\n" +
77
+ "{?items}\n" +
78
+ " <ul>\n" +
79
+ " {#items}\n" +
80
+ " {#current}\n" +
81
+ " <li><strong>{name}</strong></li>\n" +
82
+ " {:else}\n" +
83
+ " <li><a href=\"{url}\">{name}</a></li>\n" +
84
+ " {/current}\n" +
85
+ " {/items}\n" +
86
+ " </ul>\n" +
87
+ "{:else}\n" +
88
+ " <p>The list is empty.</p>\n" +
89
+ "{/items}",
90
+ context: {
91
+ header: function() {
92
+ return "Colors";
93
+ },
94
+ items: [
95
+ {name: "red", current: true, url: "#Red"},
96
+ {name: "green", current: false, url: "#Green"},
97
+ {name: "blue", current: false, url: "#Blue"}
98
+ ]
99
+ }
100
+ }
101
+
102
+ };
103
+
104
+ handlebarsTemplates = {};
105
+ ecoTemplates = {};
106
+
107
+ var warmer = new BenchWarmer();
108
+
109
+ var makeSuite = function(name) {
110
+ warmer.suite(name, function(bench) {
111
+ var templateName = name;
112
+ var details = benchDetails[templateName];
113
+ var mustachePartials = details.partials && details.partials.mustache;
114
+ var mustacheSource = details.mustache;
115
+ var context = details.context;
116
+
117
+ var error = function() { throw new Error("EWOT"); };
118
+
119
+
120
+ //bench("dust", function() {
121
+ //dust.render(templateName, context, function(err, out) { });
122
+ //});
123
+
124
+ bench("handlebars", function() {
125
+ handlebarsTemplates[templateName](context);
126
+ });
127
+
128
+ //if(ecoTemplates[templateName]) {
129
+ //bench("eco", function() {
130
+ //ecoTemplates[templateName](context);
131
+ //});
132
+ //} else {
133
+ //bench("eco", error);
134
+ //}
135
+
136
+ //if(mustacheSource) {
137
+ //bench("mustache", function() {
138
+ //Mustache.to_html(mustacheSource, context, mustachePartials);
139
+ //});
140
+ //} else {
141
+ //bench("mustache", error);
142
+ //}
143
+ });
144
+ }
145
+
146
+ for(var name in benchDetails) {
147
+ if(benchDetails.hasOwnProperty(name)) {
148
+ dust.loadSource(dust.compile(benchDetails[name].dust, name));
149
+ handlebarsTemplates[name] = Handlebars.compile(benchDetails[name].handlebars);
150
+
151
+ if(benchDetails[name].eco) { ecoTemplates[name] = eco(benchDetails[name].eco); }
152
+
153
+ var partials = benchDetails[name].partials;
154
+ if(partials) {
155
+ for(var partialName in partials.handlebars) {
156
+ if(partials.handlebars.hasOwnProperty(partialName)) {
157
+ Handlebars.registerPartial(partialName, partials.handlebars[partialName]);
158
+ }
159
+ }
160
+ }
161
+
162
+ makeSuite(name);
163
+ }
164
+ }
165
+
166
+ warmer.bench();
@@ -0,0 +1,15 @@
1
+ var Handlebars = require("handlebars/base");
2
+ module.exports = Handlebars;
3
+
4
+ require("handlebars/utils");
5
+
6
+ require("handlebars/ast");
7
+ require("handlebars/printer");
8
+ require("handlebars/visitor");
9
+
10
+ require("handlebars/compiler");
11
+
12
+ // BEGIN(BROWSER)
13
+
14
+ // END(BROWSER)
15
+
@@ -0,0 +1,103 @@
1
+ var Handlebars = require("handlebars");
2
+
3
+ // BEGIN(BROWSER)
4
+ (function() {
5
+
6
+ Handlebars.AST = {};
7
+
8
+ Handlebars.AST.ProgramNode = function(statements, inverse) {
9
+ this.type = "program";
10
+ this.statements = statements;
11
+ if(inverse) { this.inverse = new Handlebars.AST.ProgramNode(inverse); }
12
+ };
13
+
14
+ Handlebars.AST.MustacheNode = function(params, hash, unescaped) {
15
+ this.type = "mustache";
16
+ this.id = params[0];
17
+ this.params = params.slice(1);
18
+ this.hash = hash;
19
+ this.escaped = !unescaped;
20
+ };
21
+
22
+ Handlebars.AST.PartialNode = function(id, context) {
23
+ this.type = "partial";
24
+
25
+ // TODO: disallow complex IDs
26
+
27
+ this.id = id;
28
+ this.context = context;
29
+ };
30
+
31
+ var verifyMatch = function(open, close) {
32
+ if(open.original !== close.original) {
33
+ throw new Handlebars.Exception(open.original + " doesn't match " + close.original);
34
+ }
35
+ };
36
+
37
+ Handlebars.AST.BlockNode = function(mustache, program, close) {
38
+ verifyMatch(mustache.id, close);
39
+ this.type = "block";
40
+ this.mustache = mustache;
41
+ this.program = program;
42
+ };
43
+
44
+ Handlebars.AST.InverseNode = function(mustache, program, close) {
45
+ verifyMatch(mustache.id, close);
46
+ this.type = "inverse";
47
+ this.mustache = mustache;
48
+ this.program = program;
49
+ };
50
+
51
+ Handlebars.AST.ContentNode = function(string) {
52
+ this.type = "content";
53
+ this.string = string;
54
+ };
55
+
56
+ Handlebars.AST.HashNode = function(pairs) {
57
+ this.type = "hash";
58
+ this.pairs = pairs;
59
+ };
60
+
61
+ Handlebars.AST.IdNode = function(parts) {
62
+ this.type = "ID";
63
+ this.original = parts.join(".");
64
+
65
+ var dig = [], depth = 0;
66
+
67
+ for(var i=0,l=parts.length; i<l; i++) {
68
+ var part = parts[i];
69
+
70
+ if(part === "..") { depth++; }
71
+ else if(part === "." || part === "this") { continue; }
72
+ else { dig.push(part); }
73
+ }
74
+
75
+ this.parts = dig;
76
+ this.string = dig.join('.');
77
+ this.depth = depth;
78
+ this.isSimple = (dig.length === 1) && (depth === 0);
79
+ };
80
+
81
+ Handlebars.AST.StringNode = function(string) {
82
+ this.type = "STRING";
83
+ this.string = string;
84
+ };
85
+
86
+ Handlebars.AST.IntegerNode = function(integer) {
87
+ this.type = "INTEGER";
88
+ this.integer = integer;
89
+ };
90
+
91
+ Handlebars.AST.BooleanNode = function(bool) {
92
+ this.type = "BOOLEAN";
93
+ this.bool = bool;
94
+ };
95
+
96
+ Handlebars.AST.CommentNode = function(comment) {
97
+ this.type = "comment";
98
+ this.comment = comment;
99
+ };
100
+
101
+ })();
102
+ // END(BROWSER)
103
+
@@ -0,0 +1,114 @@
1
+ var handlebars = require("handlebars/parser").parser;
2
+
3
+ // BEGIN(BROWSER)
4
+ var Handlebars = {};
5
+
6
+ Handlebars.VERSION = "1.0.beta.2";
7
+
8
+ Handlebars.Parser = handlebars;
9
+
10
+ Handlebars.parse = function(string) {
11
+ Handlebars.Parser.yy = Handlebars.AST;
12
+ return Handlebars.Parser.parse(string);
13
+ };
14
+
15
+ Handlebars.print = function(ast) {
16
+ return new Handlebars.PrintVisitor().accept(ast);
17
+ };
18
+
19
+ Handlebars.helpers = {};
20
+ Handlebars.partials = {};
21
+
22
+ Handlebars.registerHelper = function(name, fn, inverse) {
23
+ if(inverse) { fn.not = inverse; }
24
+ this.helpers[name] = fn;
25
+ };
26
+
27
+ Handlebars.registerPartial = function(name, str) {
28
+ this.partials[name] = str;
29
+ };
30
+
31
+ Handlebars.registerHelper('helperMissing', function(arg) {
32
+ if(arguments.length === 2) {
33
+ return undefined;
34
+ } else {
35
+ throw new Error("Could not find property '" + arg + "'");
36
+ }
37
+ });
38
+
39
+ Handlebars.registerHelper('blockHelperMissing', function(context, options) {
40
+ var inverse = options.inverse || function() {}, fn = options.fn;
41
+
42
+
43
+ var ret = "";
44
+ var type = Object.prototype.toString.call(context);
45
+
46
+ if(type === "[object Function]") {
47
+ context = context();
48
+ }
49
+
50
+ if(context === true) {
51
+ return fn(this);
52
+ } else if(context === false || context == null) {
53
+ return inverse(this);
54
+ } else if(type === "[object Array]") {
55
+ if(context.length > 0) {
56
+ for(var i=0, j=context.length; i<j; i++) {
57
+ ret = ret + fn(context[i]);
58
+ }
59
+ } else {
60
+ ret = inverse(this);
61
+ }
62
+ return ret;
63
+ } else {
64
+ return fn(context);
65
+ }
66
+ });
67
+
68
+ Handlebars.registerHelper('each', function(context, options) {
69
+ var fn = options.fn, inverse = options.inverse;
70
+ var ret = "";
71
+
72
+ if(context && context.length > 0) {
73
+ for(var i=0, j=context.length; i<j; i++) {
74
+ ret = ret + fn(context[i]);
75
+ }
76
+ } else {
77
+ ret = inverse(this);
78
+ }
79
+ return ret;
80
+ });
81
+
82
+ Handlebars.registerHelper('if', function(context, options) {
83
+ if(!context || Handlebars.Utils.isEmpty(context)) {
84
+ return options.inverse(this);
85
+ } else {
86
+ return options.fn(this);
87
+ }
88
+ });
89
+
90
+ Handlebars.registerHelper('unless', function(context, options) {
91
+ var fn = options.fn, inverse = options.inverse;
92
+ options.fn = inverse;
93
+ options.inverse = fn;
94
+
95
+ return Handlebars.helpers['if'].call(this, context, options);
96
+ });
97
+
98
+ Handlebars.registerHelper('with', function(context, options) {
99
+ return options.fn(context);
100
+ });
101
+
102
+ Handlebars.logger = {
103
+ DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,
104
+
105
+ // override in the host environment
106
+ log: function(level, str) {}
107
+ };
108
+
109
+ Handlebars.log = function(level, str) { Handlebars.logger.log(level, str); };
110
+
111
+ // END(BROWSER)
112
+
113
+ module.exports = Handlebars;
114
+