Index: trunk/extensions/ParserPlayground/modules/ext.parserPlayground.pegParser.js |
— | — | @@ -9,8 +9,8 @@ |
10 | 10 | * to point at the MW page name containing the parser peg definition; default |
11 | 11 | * is 'MediaWiki:Gadget-ParserPlayground-PegParser.pegjs'. |
12 | 12 | */ |
13 | | -function PegParser(env) { |
14 | | - this.env = env || {}; |
| 13 | +function PegParser(options) { |
| 14 | + this.options = options; |
15 | 15 | } |
16 | 16 | |
17 | 17 | PegParser.src = false; |
— | — | @@ -34,58 +34,8 @@ |
35 | 35 | * @param {function(tree, error)} callback |
36 | 36 | */ |
37 | 37 | PegParser.prototype.expandTree = function(tree, callback) { |
38 | | - var self = this; |
39 | | - var subParseArray = function(listOfTrees) { |
40 | | - var content = []; |
41 | | - $.each(listOfTrees, function(i, subtree) { |
42 | | - self.expandTree(subtree, function(substr, err) { |
43 | | - content.push(tree); |
44 | | - }); |
45 | | - }); |
46 | | - return content; |
47 | | - }; |
48 | | - var src; |
49 | | - if (typeof tree === "string") { |
50 | | - callback(tree); |
51 | | - return; |
52 | | - } |
53 | | - if (tree.type == 'template') { |
54 | | - // expand a template node! |
55 | | - |
56 | | - // Resolve a possibly relative link |
57 | | - var templateName = this.env.resolveTitle( tree.target, 'Template' ); |
58 | | - this.env.fetchTemplate( tree.target, tree.params || {}, function( templateSrc, error ) { |
59 | | - // @fixme should pre-parse/cache these too? |
60 | | - self.parseToTree( templateSrc, function( templateTree, error ) { |
61 | | - if ( error ) { |
62 | | - callback({ |
63 | | - type: 'placeholder', |
64 | | - orig: tree, |
65 | | - content: [ |
66 | | - { |
67 | | - // @fixme broken link? |
68 | | - type: 'link', |
69 | | - target: templateName |
70 | | - } |
71 | | - ] |
72 | | - }); |
73 | | - } else { |
74 | | - callback({ |
75 | | - type: 'placeholder', |
76 | | - orig: tree, |
77 | | - content: self.env.expandTemplateArgs( templateTree, tree.params ) |
78 | | - }); |
79 | | - } |
80 | | - }) |
81 | | - } ); |
82 | | - // Wait for async... |
83 | | - return; |
84 | | - } |
85 | | - var out = $.extend( tree ); // @fixme prefer a deep copy? |
86 | | - if (tree.content) { |
87 | | - out.content = subParseArray(tree.content); |
88 | | - } |
89 | | - callback(out); |
| 38 | + // no-op! |
| 39 | + callback(tree, null); |
90 | 40 | }; |
91 | 41 | |
92 | 42 | PegParser.prototype.initSource = function(callback) { |
Index: trunk/extensions/ParserPlayground/modules/mediawiki.parser.environment.js |
— | — | @@ -1,8 +1,7 @@ |
2 | 2 | var MWParserEnvironment = function(opts) { |
3 | 3 | var options = { |
4 | 4 | tagHooks: {}, |
5 | | - parserFunctions: {}, |
6 | | - pageCache: {} // @fixme use something with managed space |
| 5 | + parserFunctions: {} |
7 | 6 | }; |
8 | 7 | $.extend(options, opts); |
9 | 8 | this.tagHooks = options.tagHooks; |
— | — | @@ -39,323 +38,12 @@ |
40 | 39 | } else { |
41 | 40 | return null; |
42 | 41 | } |
43 | | - }, |
44 | | - |
45 | | - /** |
46 | | - * @fixme do this for real eh |
47 | | - */ |
48 | | - resolveTitle: function( name, namespace ) { |
49 | | - // hack! |
50 | | - if (name.indexOf(':') == 0 && typeof namespace ) { |
51 | | - // hack hack hack |
52 | | - name = namespace + ':' + name; |
53 | | - } |
54 | | - return name; |
55 | | - }, |
56 | | - |
57 | | - /** |
58 | | - * Async. |
59 | | - * |
60 | | - * @todo make some optimizations for fetching multiple at once |
61 | | - * |
62 | | - * @param string name |
63 | | - * @param function(text, err) callback |
64 | | - */ |
65 | | - fetchTemplate: function( title, callback ) { |
66 | | - this.fetchTemplateAndTitle( title, function( text, title, err ) { |
67 | | - callback(title, err); |
68 | | - }); |
69 | | - }, |
70 | | - |
71 | | - fetchTemplateAndTitle: function( title, callback ) { |
72 | | - // @fixme normalize name? |
73 | | - if (title in this.pageCache) { |
74 | | - // @fixme should this be forced to run on next event? |
75 | | - callback( this.pageCache[title] ); |
76 | | - } else { |
77 | | - // whee fun hack! |
78 | | - $.ajax({ |
79 | | - url: wgScriptPath + '/api' + wgScriptExtension, |
80 | | - data: { |
81 | | - format: 'json', |
82 | | - action: 'query', |
83 | | - prop: 'revisions', |
84 | | - rvprop: 'content', |
85 | | - titles: name |
86 | | - }, |
87 | | - success: function(data, xhr) { |
88 | | - var src = null, title = null; |
89 | | - $.each(data.query.pages, function(i, page) { |
90 | | - if (page.revisions && page.revisions.length) { |
91 | | - src = page.revisions[0]['*']; |
92 | | - title = page.title; |
93 | | - } |
94 | | - }); |
95 | | - if (typeof src !== 'string') { |
96 | | - callback(null, null, 'Page not found'); |
97 | | - } else { |
98 | | - callback(src, title); |
99 | | - } |
100 | | - }, |
101 | | - error: function(msg) { |
102 | | - callback(null, null, 'Page/template fetch failure'); |
103 | | - }, |
104 | | - dataType: 'json', |
105 | | - cache: false // @fixme caching, versions etc? |
106 | | - }, 'json'); |
107 | | - } |
108 | | - }, |
109 | | - |
110 | | - getTemplateDom: function( title, callback ) { |
111 | | - var self = this; |
112 | | - this.fetchTemplateAndTitle( title, function( text, title, err ) { |
113 | | - if (err) { |
114 | | - callback(null, err); |
115 | | - return; |
116 | | - } |
117 | | - self.pageCache[title] = text; |
118 | | - self.parser.parseToTree( text, function( templateTree, err ) { |
119 | | - // @fixme cache these too :) |
120 | | - callback(templateTree, err); |
121 | | - }); |
122 | | - }); |
123 | | - }, |
124 | | - |
125 | | - braceSubstitution: function( templateNode, frame, callback ) { |
126 | | - // stuff in Parser.braceSubstitution |
127 | | - // expand/flatten the 'title' piece (to get the template reference) |
128 | | - frame.flatten(templateNode.name, function(templateName, err) { |
129 | | - if (err) { |
130 | | - callback(null, err); |
131 | | - return; |
132 | | - } |
133 | | - var out = { |
134 | | - type: 'placeholder', |
135 | | - orig: templateNode, |
136 | | - contents: [] |
137 | | - }; |
138 | | - |
139 | | - // check for 'subst:' |
140 | | - // check for variable magic names |
141 | | - // check for msg, msgnw, raw magics |
142 | | - // check for parser functions |
143 | | - |
144 | | - // resolve template name |
145 | | - // load template w/ canonical name |
146 | | - // load template w/ variant names |
147 | | - // recursion depth check |
148 | | - // fetch from DB or interwiki |
149 | | - // infinte loop check |
150 | | - this.getTemplateDom(templateName, function(dom, err) { |
151 | | - // Expand in-place! |
152 | | - var templateFrame = frame.newChild(templateName.params || []); |
153 | | - templateFrame.expand(dom, 0, function(expandedTemplateNode) { |
154 | | - out.contents = expandedTemplateNode.contents; |
155 | | - callback(out); |
156 | | - return; // done |
157 | | - }); |
158 | | - return; // wait for async |
159 | | - }); |
160 | | - }); |
161 | | - }, |
162 | | - |
163 | | - argSubstitution: function( argNode, frame, callback ) { |
164 | | - frame.flatten(argNode.name, function(argName, err) { |
165 | | - if (err) { |
166 | | - callback(null, err); |
167 | | - return; |
168 | | - } |
169 | | - |
170 | | - var arg = frame.getArgument(argName); |
171 | | - if (arg === false && 'params' in argNode && argNode.params.length) { |
172 | | - // No match in frame, use the supplied default |
173 | | - arg = argNode.params[0].val; |
174 | | - } |
175 | | - var out = { |
176 | | - type: 'placeholder', |
177 | | - orig: argNode, |
178 | | - contents: [arg] |
179 | | - }; |
180 | | - callback(out); |
181 | | - }); |
182 | 42 | } |
183 | | - |
184 | | - |
| 43 | + |
185 | 44 | }); |
186 | 45 | |
187 | | -function PPFrame(env) { |
188 | | - this.env = env; |
189 | | - this.loopCheckHash = []; |
190 | | - this.depth = 0; |
191 | | -} |
192 | 46 | |
193 | | -// Flag constants |
194 | | -$.extend(PPFrame, { |
195 | | - NO_ARGS: 1, |
196 | | - NO_TEMPLATES: 2, |
197 | | - STRIP_COMMENTS: 4, |
198 | | - NO_IGNORE: 8, |
199 | | - RECOVER_COMMENTS: 16 |
200 | | -}); |
201 | | -PPFrame.RECOVER_ORIG = PPFrame.NO_ARGS |
202 | | - | PPFrame.NO_TEMPLATES |
203 | | - | PPFrame.STRIP_COMMENTS |
204 | | - | PPFrame.NO_IGNORE |
205 | | - | PPFrame.RECOVER_COMMENTS; |
206 | 47 | |
207 | | -$.extend(PPFrame.prototype, { |
208 | | - newChild: function(args, title) { |
209 | | - // |
210 | | - }, |
211 | | - |
212 | | - /** |
213 | | - * Using simple recursion for now -- PHP version is a little fancier |
214 | | - * @param {object} tree |
215 | | - * @param {number} flags |
216 | | - * @param {function(tree, error)} callback |
217 | | - */ |
218 | | - expand: function(root, flags, callback) { |
219 | | - var self = this, |
220 | | - expansionDepth = 0, |
221 | | - outStack = [Array(), Array()], |
222 | | - iteratorStack = [false, root], |
223 | | - indexStack = [0, 0], |
224 | | - contextNode = false, |
225 | | - newIterator = false; |
226 | | - |
227 | | - var iteration = function() { |
228 | | - var level = outStack.length - 1, |
229 | | - iteratorNode = iteratorStack[level], |
230 | | - out = outStack[level], |
231 | | - index = indexStack[level]; // ???? |
232 | | - |
233 | | - if ($.isArray(iteratorNode)) { |
234 | | - if (index >= iteratorNode.length) { |
235 | | - // All done with this iterator. |
236 | | - iteratorStack[level] = false; |
237 | | - contextNode = false; |
238 | | - } else { |
239 | | - contextNode = iteratorNode[index]; |
240 | | - indexStack[level]++; |
241 | | - } |
242 | | - } else { |
243 | | - // Copy to contextNode and then delete from iterator stack, |
244 | | - // because this is not an iterator but we do have to execute it once |
245 | | - contextNode = iteratorStack[level]; |
246 | | - iteratorStack[level] = false; |
247 | | - } |
248 | | - |
249 | | - if (contextNode === false) { |
250 | | - // nothing to do |
251 | | - } else if (typeof contextNode === 'string') { |
252 | | - out.push(contextNode); |
253 | | - } else if (contextNode.type === 'template') { |
254 | | - // Double-brace expansion |
255 | | - self.env.braceSubstitution(contextNode, self, function(replacementNode, err) { |
256 | | - out.push(replacementNode); |
257 | | - // ... and continue on the next node! |
258 | | - iteration(); |
259 | | - }); |
260 | | - } else if (contextNode.type == 'tplarg') { |
261 | | - // Triple-brace expansion |
262 | | - self.env.argSubstitution(contextNode, self, function(replacementNode, err) { |
263 | | - out.push(replacementNode); |
264 | | - // ... and continue on the next node! |
265 | | - iteration(); |
266 | | - }); |
267 | | - } else if (contextNode.type === 'comment') { |
268 | | - // HTML-style comment |
269 | | - } else if (contextNode.type === 'ignore') { |
270 | | - // |
271 | | - } else if (contextNode.type === 'ext') { |
272 | | - // |
273 | | - } else if (contextNode.type === 'h') { |
274 | | - // |
275 | | - } else { |
276 | | - if ('content' in contextNode) { |
277 | | - newIterator = contextNode.content; |
278 | | - } |
279 | | - } |
280 | | - |
281 | | - if (newIterator !== false) { |
282 | | - outStack.push([]); |
283 | | - iteratorStack.push(newIterator); |
284 | | - indexStack.push(0); |
285 | | - } else if ( iteratorStack[level] === false) { |
286 | | - // Return accumulated value to parent |
287 | | - // With tail recursion |
288 | | - while (iteratorStack[level] === false && level > 0) { |
289 | | - outStack[level - 1]; |
290 | | - } |
291 | | - } |
292 | | - }; |
293 | | - iteration(); |
294 | | - |
295 | | - if (typeof tree === "string") { |
296 | | - callback(tree); |
297 | | - return; |
298 | | - } |
299 | | - if (tree.type == 'template') { |
300 | | - // expand a template node! |
301 | | - // Resolve a possibly relative link |
302 | | - } |
303 | | - if (tree.type == 'tplarg') { |
304 | | - |
305 | | - } |
306 | | - var out = $.extend( tree ); // @fixme prefer a deep copy? |
307 | | - if (tree.content) { |
308 | | - out.content = subParseArray(tree.content); |
309 | | - } |
310 | | - callback(out); |
311 | | - }, |
312 | | - |
313 | | - implodeWithFlags: function(sep, flags) { |
314 | | - |
315 | | - }, |
316 | | - |
317 | | - implode: function(sep) { |
318 | | - |
319 | | - }, |
320 | | - |
321 | | - virtualImport: function(sep) { |
322 | | - |
323 | | - }, |
324 | | - |
325 | | - virtualBracketedImplode: function(start, sep, end /*, ... */ ) { |
326 | | - |
327 | | - }, |
328 | | - |
329 | | - isEmpty: function() { |
330 | | - |
331 | | - }, |
332 | | - |
333 | | - getArguments: function() { |
334 | | - |
335 | | - }, |
336 | | - |
337 | | - getNumberedArguments: function() { |
338 | | - |
339 | | - }, |
340 | | - |
341 | | - getNamedArguments: function() { |
342 | | - |
343 | | - }, |
344 | | - |
345 | | - getArgument: function( name ) { |
346 | | - |
347 | | - }, |
348 | | - |
349 | | - loopCheck: function(title) { |
350 | | - }, |
351 | | - |
352 | | - isTemplate: function() { |
353 | | - |
354 | | - } |
355 | | - |
356 | | -}); |
357 | | - |
358 | | - |
359 | | - |
360 | 48 | /** |
361 | 49 | * @parm MWParserEnvironment env |
362 | 50 | * @constructor |
Index: trunk/extensions/ParserPlayground/modules/pegParser.pegjs.txt |
— | — | @@ -174,17 +174,6 @@ |
175 | 175 | }; |
176 | 176 | } |
177 | 177 | |
178 | | -tplarg = "{{{" name:link_target params:("|" p:template_param { return p })* "}}}" { |
179 | | - var obj = { |
180 | | - type: 'tplarg', |
181 | | - name: name |
182 | | - }; |
183 | | - if (params && params.length) { |
184 | | - obj.params = params; |
185 | | - } |
186 | | - return obj; |
187 | | -} |
188 | | - |
189 | 178 | template_param_name |
190 | 179 | = h:( !"}}" x:([^=|]) { return x } )* { return h.join(''); } |
191 | 180 | |