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 | P;
|
127 | }
|
128 | for (k in pat) {
|
129 | v = pat[k];
|
130 | switch (k) {
|
131 | case "N":
|
132 | case "contentName":
|
133 | P.contentName = this.makeScopeName(v);
|
134 | break;
|
135 | case "i":
|
136 | case "include":
|
137 | P.include = v;
|
138 | break;
|
139 | case "n":
|
140 | case "name":
|
141 | P.name = this.makeScopeName(v);
|
142 | break;
|
143 | case "m":
|
144 | case "match":
|
145 | P.match = this.resolveMacros(v);
|
146 | break;
|
147 | case "b":
|
148 | case "begin":
|
149 | P.begin = this.resolveMacros(v);
|
150 | break;
|
151 | case "e":
|
152 | case "end":
|
153 | P.end = this.resolveMacros(v);
|
154 | break;
|
155 | case "c":
|
156 | case "captures":
|
157 | case "beginCaptures":
|
158 | if (P.begin != null) {
|
159 | P.beginCaptures = c = {};
|
160 | } else {
|
161 | P.captures = c = {};
|
162 | }
|
163 | for (ck in v) {
|
164 | cv = v[ck];
|
165 | if (typeof cv !== "string") {
|
166 | c[ck] = this.makePattern(cv);
|
167 | } else {
|
168 | c[ck] = {
|
169 | name: this.makeScopeName(cv)
|
170 | };
|
171 | }
|
172 | }
|
173 | break;
|
174 | case "C":
|
175 | case "endCaptures":
|
176 | P.endCaptures = c = {};
|
177 | for (ck in v) {
|
178 | cv = v[ck];
|
179 | if (typeof cv !== "string") {
|
180 | c[ck] = this.makePattern(cv);
|
181 | } else {
|
182 | c[ck] = {
|
183 | name: this.makeScopeName(cv)
|
184 | };
|
185 | }
|
186 | }
|
187 | break;
|
188 | case "p":
|
189 | case "patterns":
|
190 | if (!v instanceof Array) {
|
191 | v = [v];
|
192 | }
|
193 | P.patterns = (function() {
|
194 | var _i, _len, _results;
|
195 | _results = [];
|
196 | for (_i = 0, _len = v.length; _i < _len; _i++) {
|
197 | p = v[_i];
|
198 | _results.push(this.makePattern(p));
|
199 | }
|
200 | return _results;
|
201 | }).call(this);
|
202 | break;
|
203 | case "L":
|
204 | case "applyPatternLast":
|
205 | P.applyPatternLast = v;
|
206 | }
|
207 | }
|
208 | return P;
|
209 | };
|
210 |
|
211 | return GrammarCreator;
|
212 |
|
213 | })();
|
214 |
|
215 | makeGrammar = function(grammar, print) {
|
216 | if (print == null) {
|
217 | print = false;
|
218 | }
|
219 | return (new GrammarCreator(grammar, print)).process();
|
220 | };
|
221 |
|
222 | module.exports = makeGrammar;
|
223 |
|
224 | }).call(this);
|