handlebars 0.0.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -1
- data/.gitmodules +3 -0
- data/.rspec +1 -0
- data/Gemfile +1 -1
- data/README.mdown +44 -0
- data/Rakefile +3 -0
- data/handlebars.gemspec +19 -13
- data/lib/handlebars.rb +4 -3
- data/lib/handlebars/context.rb +37 -0
- data/lib/handlebars/version.rb +1 -1
- data/spec/handlebars_spec.rb +40 -0
- data/spike.rb +17 -0
- data/vendor/handlebars/.gitignore +6 -0
- data/vendor/handlebars/.jshintrc +50 -0
- data/vendor/handlebars/.npmignore +11 -0
- data/vendor/handlebars/Gemfile +5 -0
- data/vendor/handlebars/LICENSE +20 -0
- data/vendor/handlebars/README.markdown +315 -0
- data/vendor/handlebars/Rakefile +116 -0
- data/vendor/handlebars/bench/benchwarmer.js +149 -0
- data/vendor/handlebars/bench/handlebars.js +163 -0
- data/vendor/handlebars/bin/handlebars +139 -0
- data/vendor/handlebars/lib/handlebars.js +14 -0
- data/vendor/handlebars/lib/handlebars/base.js +101 -0
- data/vendor/handlebars/lib/handlebars/compiler/ast.js +103 -0
- data/vendor/handlebars/lib/handlebars/compiler/base.js +27 -0
- data/vendor/handlebars/lib/handlebars/compiler/compiler.js +808 -0
- data/vendor/handlebars/lib/handlebars/compiler/index.js +7 -0
- data/vendor/handlebars/lib/handlebars/compiler/printer.js +137 -0
- data/vendor/handlebars/lib/handlebars/compiler/visitor.js +13 -0
- data/vendor/handlebars/lib/handlebars/runtime.js +68 -0
- data/vendor/handlebars/lib/handlebars/utils.js +68 -0
- data/vendor/handlebars/package.json +25 -0
- data/vendor/handlebars/spec/acceptance_spec.rb +101 -0
- data/vendor/handlebars/spec/parser_spec.rb +264 -0
- data/vendor/handlebars/spec/qunit_spec.js +1067 -0
- data/vendor/handlebars/spec/spec_helper.rb +157 -0
- data/vendor/handlebars/spec/tokenizer_spec.rb +254 -0
- data/vendor/handlebars/src/handlebars.l +42 -0
- data/vendor/handlebars/src/handlebars.yy +99 -0
- metadata +93 -77
- data/README.md +0 -39
- data/lib/handlebars/generator.rb +0 -4
- data/lib/handlebars/parser.rb +0 -240
- data/spec/generator_spec.rb +0 -5
- data/spec/parser_spec.rb +0 -163
- data/spec/spec_helper.rb +0 -17
@@ -0,0 +1,116 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler/setup"
|
3
|
+
|
4
|
+
def compile_parser
|
5
|
+
system "jison src/handlebars.yy src/handlebars.l"
|
6
|
+
if $?.success?
|
7
|
+
File.open("lib/handlebars/compiler/parser.js", "w") do |file|
|
8
|
+
file.puts File.read("handlebars.js") + ";"
|
9
|
+
end
|
10
|
+
|
11
|
+
sh "rm handlebars.js"
|
12
|
+
else
|
13
|
+
puts "Failed to run Jison."
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
file "lib/handlebars/compiler/parser.js" => ["src/handlebars.yy","src/handlebars.l"] do
|
18
|
+
if ENV['PATH'].split(':').any? {|folder| File.exists?(folder+'/jison')}
|
19
|
+
compile_parser
|
20
|
+
else
|
21
|
+
puts "Jison is not installed. Trying `npm install jison`."
|
22
|
+
sh "npm install jison -g"
|
23
|
+
compile_parser
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
task :compile => "lib/handlebars/compiler/parser.js"
|
28
|
+
|
29
|
+
desc "run the spec suite"
|
30
|
+
task :spec => [:release] do
|
31
|
+
system "rspec -cfs spec"
|
32
|
+
end
|
33
|
+
|
34
|
+
task :default => [:compile, :spec]
|
35
|
+
|
36
|
+
def remove_exports(string)
|
37
|
+
match = string.match(%r{^// BEGIN\(BROWSER\)\n(.*)\n^// END\(BROWSER\)}m)
|
38
|
+
match ? match[1] : string
|
39
|
+
end
|
40
|
+
|
41
|
+
minimal_deps = %w(base compiler/parser compiler/base compiler/ast utils compiler/compiler runtime).map do |file|
|
42
|
+
"lib/handlebars/#{file}.js"
|
43
|
+
end
|
44
|
+
|
45
|
+
runtime_deps = %w(base utils runtime).map do |file|
|
46
|
+
"lib/handlebars/#{file}.js"
|
47
|
+
end
|
48
|
+
|
49
|
+
directory "dist"
|
50
|
+
|
51
|
+
minimal_deps.unshift "dist"
|
52
|
+
|
53
|
+
def build_for_task(task)
|
54
|
+
FileUtils.rm_rf("dist/*") if File.directory?("dist")
|
55
|
+
FileUtils.mkdir_p("dist")
|
56
|
+
|
57
|
+
contents = []
|
58
|
+
task.prerequisites.each do |filename|
|
59
|
+
next if filename == "dist"
|
60
|
+
|
61
|
+
contents << "// #{filename}\n" + remove_exports(File.read(filename)) + ";"
|
62
|
+
end
|
63
|
+
|
64
|
+
File.open(task.name, "w") do |file|
|
65
|
+
file.puts contents.join("\n")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
file "dist/handlebars.js" => minimal_deps do |task|
|
70
|
+
build_for_task(task)
|
71
|
+
end
|
72
|
+
|
73
|
+
file "dist/handlebars.runtime.js" => runtime_deps do |task|
|
74
|
+
build_for_task(task)
|
75
|
+
end
|
76
|
+
|
77
|
+
task :build => [:compile, "dist/handlebars.js"]
|
78
|
+
task :runtime => [:compile, "dist/handlebars.runtime.js"]
|
79
|
+
|
80
|
+
desc "build the build and runtime version of handlebars"
|
81
|
+
task :release => [:build, :runtime]
|
82
|
+
|
83
|
+
directory "vendor"
|
84
|
+
|
85
|
+
desc "benchmark against dust.js and mustache.js"
|
86
|
+
task :bench => "vendor" do
|
87
|
+
require "open-uri"
|
88
|
+
#File.open("vendor/mustache.js", "w") do |file|
|
89
|
+
#file.puts open("https://github.com/janl/mustache.js/raw/master/mustache.js").read
|
90
|
+
#file.puts "module.exports = Mustache;"
|
91
|
+
#end
|
92
|
+
|
93
|
+
File.open("vendor/benchmark.js", "w") do |file|
|
94
|
+
file.puts open("https://raw.github.com/bestiejs/benchmark.js/master/benchmark.js").read
|
95
|
+
end
|
96
|
+
|
97
|
+
#if File.directory?("vendor/dustjs")
|
98
|
+
#system "cd vendor/dustjs && git pull"
|
99
|
+
#else
|
100
|
+
#system "git clone git://github.com/akdubya/dustjs.git vendor/dustjs"
|
101
|
+
#end
|
102
|
+
|
103
|
+
#if File.directory?("vendor/coffee")
|
104
|
+
#system "cd vendor/coffee && git pull"
|
105
|
+
#else
|
106
|
+
#system "git clone git://github.com/jashkenas/coffee-script.git vendor/coffee"
|
107
|
+
#end
|
108
|
+
|
109
|
+
#if File.directory?("vendor/eco")
|
110
|
+
#system "cd vendor/eco && git pull && npm update"
|
111
|
+
#else
|
112
|
+
#system "git clone git://github.com/sstephenson/eco.git vendor/eco && cd vendor/eco && npm update"
|
113
|
+
#end
|
114
|
+
|
115
|
+
system "node bench/handlebars.js"
|
116
|
+
end
|
@@ -0,0 +1,149 @@
|
|
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
|
+
print("\n");
|
117
|
+
},
|
118
|
+
startLine: function(name) {
|
119
|
+
var winners = Benchmark.map(this.winners(this.currentBenches), function(bench) {
|
120
|
+
return bench.name.split(": ")[1];
|
121
|
+
});
|
122
|
+
|
123
|
+
this.currentBenches = [];
|
124
|
+
|
125
|
+
print(winners.join(", "));
|
126
|
+
print("\n");
|
127
|
+
var padding = this.nameSize - name.length + 1;
|
128
|
+
name = name + new Array(padding).join(" ");
|
129
|
+
print(name);
|
130
|
+
},
|
131
|
+
writeBench: function(bench) {
|
132
|
+
var out;
|
133
|
+
|
134
|
+
if(!bench.error) {
|
135
|
+
var count = bench.hz,
|
136
|
+
moe = count * bench.stats.RME / 100;
|
137
|
+
|
138
|
+
out = Math.round(count / 1000) + " ±" + Math.round(moe / 1000) + " (" + bench.cycles + ")";
|
139
|
+
} else {
|
140
|
+
out = "E";
|
141
|
+
}
|
142
|
+
|
143
|
+
var padding = this.benchSize - out.length + 1;
|
144
|
+
out = out + new Array(padding).join(" ");
|
145
|
+
print(out);
|
146
|
+
}
|
147
|
+
};
|
148
|
+
|
149
|
+
module.exports = BenchWarmer;
|
@@ -0,0 +1,163 @@
|
|
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
|
+
return ecoExports(str);
|
17
|
+
}
|
18
|
+
|
19
|
+
var benchDetails = {
|
20
|
+
string: {
|
21
|
+
context: {},
|
22
|
+
handlebars: "Hello world",
|
23
|
+
dust: "Hello world",
|
24
|
+
mustache: "Hello world",
|
25
|
+
eco: "Hello world"
|
26
|
+
},
|
27
|
+
variables: {
|
28
|
+
context: {name: "Mick", count: 30},
|
29
|
+
handlebars: "Hello {{name}}! You have {{count}} new messages.",
|
30
|
+
dust: "Hello {name}! You have {count} new messages.",
|
31
|
+
mustache: "Hello {{name}}! You have {{count}} new messages.",
|
32
|
+
eco: "Hello <%= @name %>! You have <%= @count %> new messages."
|
33
|
+
},
|
34
|
+
object: {
|
35
|
+
context: { person: { name: "Larry", age: 45 } },
|
36
|
+
handlebars: "{{#with person}}{{name}}{{age}}{{/with}}",
|
37
|
+
dust: "{#person}{name}{age}{/person}",
|
38
|
+
mustache: "{{#person}}{{name}}{{age}}{{/person}}"
|
39
|
+
},
|
40
|
+
array: {
|
41
|
+
context: { names: [{name: "Moe"}, {name: "Larry"}, {name: "Curly"}, {name: "Shemp"}] },
|
42
|
+
handlebars: "{{#each names}}{{name}}{{/each}}",
|
43
|
+
dust: "{#names}{name}{/names}",
|
44
|
+
mustache: "{{#names}}{{name}}{{/names}}",
|
45
|
+
eco: "<% for item in @names: %><%= item.name %><% end %>"
|
46
|
+
},
|
47
|
+
partial: {
|
48
|
+
context: { peeps: [{name: "Moe", count: 15}, {name: "Larry", count: 5}, {name: "Curly", count: 1}] },
|
49
|
+
partials: {
|
50
|
+
mustache: { variables: "Hello {{name}}! You have {{count}} new messages." },
|
51
|
+
handlebars: { variables: "Hello {{name}}! You have {{count}} new messages." }
|
52
|
+
},
|
53
|
+
handlebars: "{{#each peeps}}{{>variables}}{{/each}}",
|
54
|
+
dust: "{#peeps}{>variables/}{/peeps}",
|
55
|
+
mustache: "{{#peeps}}{{>variables}}{{/peeps}}"
|
56
|
+
},
|
57
|
+
recursion: {
|
58
|
+
context: { name: '1', kids: [{ name: '1.1', kids: [{name: '1.1.1', kids: []}] }] },
|
59
|
+
partials: {
|
60
|
+
mustache: { recursion: "{{name}}{{#kids}}{{>recursion}}{{/kids}}" },
|
61
|
+
handlebars: { recursion: "{{name}}{{#each kids}}{{>recursion}}{{/each}}" }
|
62
|
+
},
|
63
|
+
handlebars: "{{name}}{{#each kids}}{{>recursion}}{{/each}}",
|
64
|
+
dust: "{name}{#kids}{>recursion:./}{/kids}",
|
65
|
+
mustache: "{{name}}{{#kids}}{{>recursion}}{{/kids}}"
|
66
|
+
},
|
67
|
+
complex: {
|
68
|
+
handlebars: "<h1>{{header}}</h1>{{#if items}}<ul>{{#each items}}{{#if current}}" +
|
69
|
+
"<li><strong>{{name}}</strong></li>{{^}}" +
|
70
|
+
"<li><a href=\"{{url}}\">{{name}}</a></li>{{/if}}" +
|
71
|
+
"{{/each}}</ul>{{^}}<p>The list is empty.</p>{{/if}}",
|
72
|
+
|
73
|
+
dust: "<h1>{header}</h1>\n" +
|
74
|
+
"{?items}\n" +
|
75
|
+
" <ul>\n" +
|
76
|
+
" {#items}\n" +
|
77
|
+
" {#current}\n" +
|
78
|
+
" <li><strong>{name}</strong></li>\n" +
|
79
|
+
" {:else}\n" +
|
80
|
+
" <li><a href=\"{url}\">{name}</a></li>\n" +
|
81
|
+
" {/current}\n" +
|
82
|
+
" {/items}\n" +
|
83
|
+
" </ul>\n" +
|
84
|
+
"{:else}\n" +
|
85
|
+
" <p>The list is empty.</p>\n" +
|
86
|
+
"{/items}",
|
87
|
+
context: {
|
88
|
+
header: function() {
|
89
|
+
return "Colors";
|
90
|
+
},
|
91
|
+
items: [
|
92
|
+
{name: "red", current: true, url: "#Red"},
|
93
|
+
{name: "green", current: false, url: "#Green"},
|
94
|
+
{name: "blue", current: false, url: "#Blue"}
|
95
|
+
]
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
};
|
100
|
+
|
101
|
+
handlebarsTemplates = {};
|
102
|
+
ecoTemplates = {};
|
103
|
+
|
104
|
+
var warmer = new BenchWarmer();
|
105
|
+
|
106
|
+
var makeSuite = function(name) {
|
107
|
+
warmer.suite(name, function(bench) {
|
108
|
+
var templateName = name;
|
109
|
+
var details = benchDetails[templateName];
|
110
|
+
var mustachePartials = details.partials && details.partials.mustache;
|
111
|
+
var mustacheSource = details.mustache;
|
112
|
+
var context = details.context;
|
113
|
+
|
114
|
+
var error = function() { throw new Error("EWOT"); };
|
115
|
+
|
116
|
+
|
117
|
+
//bench("dust", function() {
|
118
|
+
//dust.render(templateName, context, function(err, out) { });
|
119
|
+
//});
|
120
|
+
|
121
|
+
bench("handlebars", function() {
|
122
|
+
handlebarsTemplates[templateName](context);
|
123
|
+
});
|
124
|
+
|
125
|
+
//if(ecoTemplates[templateName]) {
|
126
|
+
//bench("eco", function() {
|
127
|
+
//ecoTemplates[templateName](context);
|
128
|
+
//});
|
129
|
+
//} else {
|
130
|
+
//bench("eco", error);
|
131
|
+
//}
|
132
|
+
|
133
|
+
//if(mustacheSource) {
|
134
|
+
//bench("mustache", function() {
|
135
|
+
//Mustache.to_html(mustacheSource, context, mustachePartials);
|
136
|
+
//});
|
137
|
+
//} else {
|
138
|
+
//bench("mustache", error);
|
139
|
+
//}
|
140
|
+
});
|
141
|
+
}
|
142
|
+
|
143
|
+
for(var name in benchDetails) {
|
144
|
+
if(benchDetails.hasOwnProperty(name)) {
|
145
|
+
dust.loadSource(dust.compile(benchDetails[name].dust, name));
|
146
|
+
handlebarsTemplates[name] = Handlebars.compile(benchDetails[name].handlebars);
|
147
|
+
|
148
|
+
if(benchDetails[name].eco) { ecoTemplates[name] = eco(benchDetails[name].eco); }
|
149
|
+
|
150
|
+
var partials = benchDetails[name].partials;
|
151
|
+
if(partials) {
|
152
|
+
for(var partialName in partials.handlebars) {
|
153
|
+
if(partials.handlebars.hasOwnProperty(partialName)) {
|
154
|
+
Handlebars.registerPartial(partialName, partials.handlebars[partialName]);
|
155
|
+
}
|
156
|
+
}
|
157
|
+
}
|
158
|
+
|
159
|
+
makeSuite(name);
|
160
|
+
}
|
161
|
+
}
|
162
|
+
|
163
|
+
warmer.bench();
|
@@ -0,0 +1,139 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
|
3
|
+
var optimist = require('optimist')
|
4
|
+
.usage('Precompile handlebar templates.\nUsage: $0 template...', {
|
5
|
+
'f': {
|
6
|
+
'type': 'string',
|
7
|
+
'description': 'Output File',
|
8
|
+
'alias': 'output'
|
9
|
+
},
|
10
|
+
'k': {
|
11
|
+
'type': 'string',
|
12
|
+
'description': 'Known helpers',
|
13
|
+
'alias': 'known'
|
14
|
+
},
|
15
|
+
'o': {
|
16
|
+
'type': 'boolean',
|
17
|
+
'description': 'Known helpers only',
|
18
|
+
'alias': 'knownOnly'
|
19
|
+
},
|
20
|
+
'm': {
|
21
|
+
'type': 'boolean',
|
22
|
+
'description': 'Minimize output',
|
23
|
+
'alias': 'min'
|
24
|
+
},
|
25
|
+
's': {
|
26
|
+
'type': 'boolean',
|
27
|
+
'description': 'Output template function only.',
|
28
|
+
'alias': 'simple'
|
29
|
+
},
|
30
|
+
'r': {
|
31
|
+
'type': 'string',
|
32
|
+
'description': 'Template root. Base value that will be stripped from template names.',
|
33
|
+
'alias': 'root'
|
34
|
+
}
|
35
|
+
})
|
36
|
+
|
37
|
+
.check(function(argv) {
|
38
|
+
var template = [0];
|
39
|
+
if (!argv._.length) {
|
40
|
+
throw 'Must define at least one template or directory.';
|
41
|
+
}
|
42
|
+
|
43
|
+
argv._.forEach(function(template) {
|
44
|
+
try {
|
45
|
+
fs.statSync(template);
|
46
|
+
} catch (err) {
|
47
|
+
throw 'Unable to open template file "' + template + '"';
|
48
|
+
}
|
49
|
+
});
|
50
|
+
})
|
51
|
+
.check(function(argv) {
|
52
|
+
if (argv.simple && argv.min) {
|
53
|
+
throw 'Unable to minimze simple output';
|
54
|
+
}
|
55
|
+
if (argv.simple && (argv._.length !== 1 || fs.statSync(argv._[0]).isDirectory())) {
|
56
|
+
throw 'Unable to output multiple templates in simple mode';
|
57
|
+
}
|
58
|
+
});
|
59
|
+
|
60
|
+
var fs = require('fs'),
|
61
|
+
handlebars = require('../lib/handlebars'),
|
62
|
+
basename = require('path').basename,
|
63
|
+
uglify = require('uglify-js');
|
64
|
+
|
65
|
+
var argv = optimist.argv,
|
66
|
+
template = argv._[0];
|
67
|
+
|
68
|
+
// Convert the known list into a hash
|
69
|
+
var known = {};
|
70
|
+
if (argv.known && !Array.isArray(argv.known)) {
|
71
|
+
argv.known = [argv.known];
|
72
|
+
}
|
73
|
+
if (argv.known) {
|
74
|
+
for (var i = 0, len = argv.known.length; i < len; i++) {
|
75
|
+
known[argv.known[i]] = true;
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
var output = [];
|
80
|
+
if (!argv.simple) {
|
81
|
+
output.push('(function() {\n var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};\n');
|
82
|
+
}
|
83
|
+
function processTemplate(template, root) {
|
84
|
+
var path = template,
|
85
|
+
stat = fs.statSync(path);
|
86
|
+
if (stat.isDirectory()) {
|
87
|
+
fs.readdirSync(template).map(function(file) {
|
88
|
+
var path = template + '/' + file;
|
89
|
+
|
90
|
+
if (/\.handlebars$/.test(path) || fs.statSync(path).isDirectory()) {
|
91
|
+
processTemplate(path, root || template);
|
92
|
+
}
|
93
|
+
});
|
94
|
+
} else {
|
95
|
+
var data = fs.readFileSync(path, 'utf8');
|
96
|
+
|
97
|
+
var options = {
|
98
|
+
knownHelpers: known,
|
99
|
+
knownHelpersOnly: argv.o
|
100
|
+
};
|
101
|
+
|
102
|
+
// Clean the template name
|
103
|
+
if (!root) {
|
104
|
+
template = basename(template);
|
105
|
+
} else if (template.indexOf(root) === 0) {
|
106
|
+
template = template.substring(root.length+1);
|
107
|
+
}
|
108
|
+
template = template.replace(/\.handlebars$/, '');
|
109
|
+
|
110
|
+
if (argv.simple) {
|
111
|
+
output.push(handlebars.precompile(data, options) + '\n');
|
112
|
+
} else {
|
113
|
+
output.push('templates[\'' + template + '\'] = template(' + handlebars.precompile(data, options) + ');\n');
|
114
|
+
}
|
115
|
+
}
|
116
|
+
}
|
117
|
+
|
118
|
+
argv._.forEach(function(template) {
|
119
|
+
processTemplate(template, argv.root);
|
120
|
+
});
|
121
|
+
|
122
|
+
// Output the content
|
123
|
+
if (!argv.simple) {
|
124
|
+
output.push('})();');
|
125
|
+
}
|
126
|
+
output = output.join('');
|
127
|
+
|
128
|
+
if (argv.min) {
|
129
|
+
var ast = uglify.parser.parse(output);
|
130
|
+
ast = uglify.uglify.ast_mangle(ast);
|
131
|
+
ast = uglify.uglify.ast_squeeze(ast);
|
132
|
+
output = uglify.uglify.gen_code(ast);
|
133
|
+
}
|
134
|
+
|
135
|
+
if (argv.output) {
|
136
|
+
fs.writeFileSync(argv.output, output, 'utf8');
|
137
|
+
} else {
|
138
|
+
console.log(output);
|
139
|
+
}
|