handlebars 0.0.2 → 0.2.0
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.
- 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
|
+
}
|