1 |
|
2 | (function() {
|
3 | var GrammarCreator, makeGrammar;
|
4 |
|
5 | GrammarCreator = (function() {
|
6 | function GrammarCreator(grammar, print) {
|
7 | this.grammar = grammar;
|
8 | this.print = print != null ? print : false;
|
9 | }
|
10 |
|
11 | GrammarCreator.prototype.process = function() {
|
12 | var CSON, G, all_done, grammar, k, macros, n, pats, print, v, _i, _len, _ref, _ref1, _ref2;
|
13 | grammar = this.grammar;
|
14 | print = this.print;
|
15 | G = {};
|
16 | _ref = ["comment", "fileTypes", "firstLineMatch", "keyEquivalent", "name", "scopeName"];
|
17 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
18 | n = _ref[_i];
|
19 | if (grammar[n] != null) {
|
20 | G[n] = grammar[n];
|
21 | }
|
22 | }
|
23 | this.autoAppendScopeName = grammar.autoAppendScopeName, this.macros = grammar.macros;
|
24 | if (typeof this.autoAppendScopeName === "undefined") {
|
25 | this.autoAppendScopeName = true;
|
26 | }
|
27 | if (typeof this.macros === "undefined") {
|
28 | this.macros = {};
|
29 | }
|
30 | this.grammarScopeName = G.scopeName.replace(/.*\./, '');
|
31 | this.hasGrammarScopeName = new RegExp("\\." + this.grammarScopeName + "$");
|
32 | macros = this.macros;
|
33 | for (k in macros) {
|
34 | v = macros[k];
|
35 | if (v instanceof RegExp) {
|
36 | macros[k] = v.source;
|
37 | }
|
38 | }
|
39 | for (k in macros) {
|
40 | v = macros[k];
|
41 | macros[k] = this.resolveMacros(v);
|
42 | }
|
43 | while (true) {
|
44 | all_done = true;
|
45 | for (k in macros) {
|
46 | v = macros[k];
|
47 | macros[k] = this.resolveMacros(v);
|
48 | if (/\{[a-zA-Z_]\w*\}/.test(macros[k])) {
|
49 | all_done = false;
|
50 | if (v === macros[k]) {
|
51 | throw "unresolved macro in " + v;
|
52 | }
|
53 | }
|
54 | }
|
55 | if (all_done) {
|
56 | break;
|
57 | }
|
58 | }
|
59 | _ref1 = this.makePattern(grammar);
|
60 | for (k in _ref1) {
|
61 | v = _ref1[k];
|
62 | G[k] = v;
|
63 | }
|
64 | if (grammar.repository != null) {
|
65 | G.repository = {};
|
66 | _ref2 = grammar.repository;
|
67 | for (k in _ref2) {
|
68 | v = _ref2[k];
|
69 | pats = this.makePattern(v, macros);
|
70 | if ((pats.begin != null) || (pats.match != null)) {
|
71 | pats = {
|
72 | "patterns": [pats]
|
73 | };
|
74 | } else if (pats instanceof Array) {
|
75 | pats = {
|
76 | "patterns": pats
|
77 | };
|
78 | }
|
79 | G.repository[k] = pats;
|
80 | }
|
81 | }
|
82 | if (print) {
|
83 | if (print === "CSON") {
|
84 | CSON = require("CSON");
|
85 | process.stdout.write(CSON.stringify(G));
|
86 | } else {
|
87 | process.stdout.write(JSON.stringify(G, null, " "));
|
88 | }
|
89 | }
|
90 | return G;
|
91 | };
|
92 |
|
93 | GrammarCreator.prototype.resolveMacros = function(regex) {
|
94 | var macros;
|
95 | if (regex instanceof RegExp) {
|
96 | regex = regex.source;
|
97 | }
|
98 | macros = this.macros;
|
99 | return regex.replace(/\{\w+\}/g, function(mob) {
|
100 | var s;
|
101 | s = mob.slice(1, -1);
|
102 | if (typeof macros[s] !== "undefined") {
|
103 | return macros[s];
|
104 | } else {
|
105 | return mob;
|
106 | }
|
107 | });
|
108 | };
|
109 |
|
110 | GrammarCreator.prototype.makeScopeName = function(name) {
|
111 | name = this.resolveMacros(name);
|
112 | if (this.autoAppendScopeName) {
|
113 | if (!this.hasGrammarScopeName.test(name)) {
|
114 | return "" + name + "." + this.grammarScopeName;
|
115 | }
|
116 | }
|
117 | return name;
|
118 | };
|
119 |
|
120 | GrammarCreator.prototype.makePattern = function(pattern) {
|
121 | var P, c, ck, cv, k, p, pat, v;
|
122 | pat = pattern;
|
123 | P = {};
|
124 | if (typeof pattern === "string") {
|
125 | P.include = pattern;
|
126 | return P;
|
127 | }
|
128 | if (pattern instanceof Array) {
|
129 | return (function() {
|
130 | var _i, _len, _results;
|
131 | _results = [];
|
132 | for (_i = 0, _len = pattern.length; _i < _len; _i++) {
|
133 | p = pattern[_i];
|
134 | _results.push(this.makePattern(p));
|
135 | }
|
136 | return _results;
|
137 | }).call(this);
|
138 | }
|
139 | for (k in pat) {
|
140 | v = pat[k];
|
141 | switch (k) {
|
142 | case "N":
|
143 | case "contentName":
|
144 | P.contentName = this.makeScopeName(v);
|
145 | break;
|
146 | case "i":
|
147 | case "include":
|
148 | P.include = v;
|
149 | break;
|
150 | case "n":
|
151 | case "name":
|
152 | P.name = this.makeScopeName(v);
|
153 | break;
|
154 | case "m":
|
155 | case "match":
|
156 | P.match = this.resolveMacros(v);
|
157 | break;
|
158 | case "b":
|
159 | case "begin":
|
160 | P.begin = this.resolveMacros(v);
|
161 | break;
|
162 | case "e":
|
163 | case "end":
|
164 | P.end = this.resolveMacros(v);
|
165 | break;
|
166 | case "c":
|
167 | case "captures":
|
168 | case "beginCaptures":
|
169 | if (P.begin != null) {
|
170 | P.beginCaptures = c = {};
|
171 | } else {
|
172 | P.captures = c = {};
|
173 | }
|
174 | if (typeof v === "string") {
|
175 | c[0] = {
|
176 | name: this.makeScopeName(v)
|
177 | };
|
178 | } else {
|
179 | for (ck in v) {
|
180 | cv = v[ck];
|
181 | if (typeof cv !== "string") {
|
182 | c[ck] = this.makePattern(cv);
|
183 | } else {
|
184 | c[ck] = {
|
185 | name: this.makeScopeName(cv)
|
186 | };
|
187 | }
|
188 | }
|
189 | }
|
190 | break;
|
191 | case "C":
|
192 | case "endCaptures":
|
193 | P.endCaptures = c = {};
|
194 | if (typeof v === "string") {
|
195 | c[0] = {
|
196 | name: this.makeScopeName(v)
|
197 | };
|
198 | } else {
|
199 | for (ck in v) {
|
200 | cv = v[ck];
|
201 | if (typeof cv !== "string") {
|
202 | c[ck] = this.makePattern(cv);
|
203 | } else {
|
204 | c[ck] = {
|
205 | name: this.makeScopeName(cv)
|
206 | };
|
207 | }
|
208 | }
|
209 | }
|
210 | break;
|
211 | case "p":
|
212 | case "patterns":
|
213 | if (!(v instanceof Array)) {
|
214 | v = [v];
|
215 | }
|
216 | P.patterns = (function() {
|
217 | var _i, _len, _results;
|
218 | _results = [];
|
219 | for (_i = 0, _len = v.length; _i < _len; _i++) {
|
220 | p = v[_i];
|
221 | _results.push(this.makePattern(p));
|
222 | }
|
223 | return _results;
|
224 | }).call(this);
|
225 | break;
|
226 | case "L":
|
227 | case "applyEndPatternLast":
|
228 | P.applyEndPatternLast = v;
|
229 | break;
|
230 | default:
|
231 | P[k] = v;
|
232 | }
|
233 | }
|
234 | return P;
|
235 | };
|
236 |
|
237 | return GrammarCreator;
|
238 |
|
239 | })();
|
240 |
|
241 | makeGrammar = function(grammar, print) {
|
242 | if (print == null) {
|
243 | print = false;
|
244 | }
|
245 | return (new GrammarCreator(grammar, print)).process();
|
246 | };
|
247 |
|
248 | module.exports = makeGrammar;
|
249 |
|
250 | }).call(this);
|