-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcompile.js
122 lines (117 loc) · 4.18 KB
/
compile.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* Contributor(s):
* Jamon Terrell <[email protected]>
*/
var parser = require('./soyparser'), fs = require('fs'), util = require('util');
var SoyCompiler = function(soy) {
this.soy = soy;
this.parse();
this._code = [];
};
SoyCompiler.prototype.indentString = " ";
SoyCompiler.prototype.newline = "\n";
SoyCompiler.prototype._indentCount = 0;
SoyCompiler.prototype.parse = function() {
this.parsed = parser.parse(this.soy);
};
SoyCompiler.prototype.compile = function() {
// @TODO add namespace handlers (to allow for AMD/commonJS loader, goog.load, or namespaced globals, etc)
var p = this.parsed;
this
._("/**").nl()
._(" * Automatically generated from soy template").nl()
._(" * -- ", p.namespace).nl()
._(" */").nl()
._("var template = function() {};").nl()
.compileTemplates(p);
return this._code.join("");
};
SoyCompiler.prototype.compileTemplates = function(p) {
for(var i = 0; i < p.templates.length; i++) {
this.nl().compileTemplate(p.templates[i]);
}
};
SoyCompiler.prototype.compileTemplate = function(t) {
this
._("/**").nl()
._(" * ", t.description).nl()
._(" */").nl()
._("template.", t.name, " = function(o) {").i()
._("var output = [];").nl()
.compileContent(t.content).u()
._("};");
return this;
};
SoyCompiler.prototype.compileContent = function(c) {
for(var i = 0; i < c.length; i++) {
if(i > 0) this.nl();
this.compileCommand(c[i]);
};
return this;
};
SoyCompiler.prototype.compileCommand = function(c) {
switch(c.command) {
case "print_text":
// @todo add output buffering on print statements, to combine multiples
this._('output.push("', c.content, '");');
break;
case "if":
// @TODO add ternary when appropriate
// if statement
this._('if (').compileExpression(c.conditions[0].expression)._(') {').i()
.compileContent(c.conditions[0].content).u();
for(var i = 1; i < c.conditions.length; i++) {
this._('} else if (').compileExpression(c.conditions[i].expression)._(') {').i()
.compileContent(c.conditions[i].content).u();
}
if(c.else_content !== "") {
this._('} else {').i()
.compileContent(c.else_content).u();
}
this._('}');
break;
default:
break;
}
return this;
};
SoyCompiler.prototype.compileExpression = function(e) {
this.code(e);
return this;
};
SoyCompiler.prototype.indent = function(omitNewline) {
this._indentCount++;
return this.code((omitNewline ? "" : this.newline) + this.calculateIndent());
};
SoyCompiler.prototype.i = SoyCompiler.prototype.indent; // alias
SoyCompiler.prototype.unindent = function(omitNewline) {
this._indentCount--;
return this.code((omitNewline ? "" : this.newline) + this.calculateIndent());
};
SoyCompiler.prototype.u = SoyCompiler.prototype.unindent; // alias
SoyCompiler.prototype.nl = function() {
return this.code(this.newline, this._indent);
};
SoyCompiler.prototype.calculateIndent = function() {
return this._indent = new Array(this._indentCount + 1).join(this.indentString);
};
SoyCompiler.prototype.code = function() {
Array.prototype.push.apply(this._code, arguments);
return this;
};
SoyCompiler.prototype._ = SoyCompiler.prototype.code; // alias
fs.readFile('./example.soy', 'utf8', function(err, data) {
console.log(util.inspect(parser.parse(data), false, 100));
console.log("-------------------------");
var sc = new SoyCompiler(data);
console.log(sc.compile());
});