r91281 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r91280‎ | r91281 | r91282 >
Date:19:29, 1 July 2011
Author:brion
Status:deferred
Tags:
Comment:
ParserPlayground: drop the manually-created parser portion of FakeParser since it won't keep up with the PEG version, split its rendering & round-trip modes to MWTreeRenderer and MWTreeSerializer.
Modified paths:
  • /trunk/extensions/ParserPlayground/ParserPlayground.php (modified) (history)
  • /trunk/extensions/ParserPlayground/modules/ext.parserPlayground.fakeParser.js (deleted) (history)
  • /trunk/extensions/ParserPlayground/modules/ext.parserPlayground.js (modified) (history)
  • /trunk/extensions/ParserPlayground/modules/ext.parserPlayground.pegParser.js (modified) (history)
  • /trunk/extensions/ParserPlayground/modules/ext.parserPlayground.renderer.js (added) (history)
  • /trunk/extensions/ParserPlayground/modules/ext.parserPlayground.serializer.js (added) (history)

Diff [purge]

Index: trunk/extensions/ParserPlayground/ParserPlayground.php
@@ -65,8 +65,9 @@
6666 'lib.pegjs.js',
6767 'jquery.nodetree.js',
6868 'ext.parserPlayground.hashMap.js',
69 - 'ext.parserPlayground.fakeParser.js',
7069 'ext.parserPlayground.classicParser.js',
 70+ 'ext.parserPlayground.serializer.js',
 71+ 'ext.parserPlayground.renderer.js',
7172 'ext.parserPlayground.pegParser.js',
7273 'ext.parserPlayground.js',
7374 ),
Index: trunk/extensions/ParserPlayground/modules/ext.parserPlayground.fakeParser.js
@@ -1,396 +0,0 @@
2 -/**
3 - * @param {ParserContext} context
4 - */
5 -function FakeParser(context) {
6 - // whee
7 - this.context = context || {};
8 -}
9 -
10 -/**
11 - * @param {string} text
12 - * @param {function(tree, error)} callback
13 - */
14 -FakeParser.prototype.parseToTree = function(text, callback) {
15 - // quick and crappy :D
16 - var lines = text.split("\n");
17 - var blocks = [];
18 - var matches;
19 - /**
20 - * Subparse of inline links within a paragraph etc.
21 - * @param {string} line
22 - * @return {object[]} list of content subblocks
23 - */
24 - var linksParse = function(line) {
25 - var bits = line.split('[['),
26 - parts = [];
27 - if (bits[0] != '') {
28 - parts.push({
29 - type: 'text',
30 - text: bits[0]
31 - });
32 - }
33 - for (var i = 1; i < bits.length; i++) {
34 - var bit = bits[i];
35 - var bracketPos = bit.indexOf(']]');
36 - if (bracketPos === -1) {
37 - // not a link oh noooooo
38 - parts.push({
39 - type: 'text',
40 - text: '[[' + bit
41 - });
42 - } else {
43 - var link = bit.substr(0, bracketPos);
44 - var tail = bit.substr(bracketPos + 2);
45 - var linkbits = link.split('|');
46 - if (linkbits.length == 1) {
47 - parts.push({
48 - type: 'link',
49 - target: link
50 - });
51 - } else {
52 - parts.push({
53 - type: 'link',
54 - target: linkbits[0],
55 - text: linkbits.slice(1).join('|') // @fixme multiples for images etc
56 - });
57 - }
58 - if (tail !== '') {
59 - parts.push({
60 - type: 'text',
61 - text: tail
62 - });
63 - }
64 - }
65 - }
66 - return parts;
67 - };
68 - /**
69 - * Subparse of all inline stuff within a paragraph etc.
70 - * @param {string} line
71 - * @return {object[]} list of content subblocks
72 - */
73 - var inlineParse = function(line) {
74 - var parts = [];
75 - var bits = line.split('<ref');
76 - var re = /^([^>]*)>(.*)<\/ref\s*>(.*)/;
77 - var re2 = /^([^>]*)\/>(.*)/;
78 - if (bits[0] != '') {
79 - // text before...
80 - $.merge(parts, linksParse(bits[0]));
81 - }
82 - $.each(bits.slice(1), function(i, bit) {
83 - var matches;
84 - var after;
85 - if ((matches = re.exec(bit)) != null) {
86 - var params = matches[1], text = matches[2];
87 - after = matches[3];
88 - parts.push({
89 - type: 'ext',
90 - name: 'ref',
91 - params: params,
92 - content: (text == '') ? [] : linksParse(text)
93 - });
94 - } else if ((matches = re2.exec(bit)) != null) {
95 - var params = matches[1];
96 - after = matches[2];
97 - parts.push({
98 - type: 'ext',
99 - name: 'ref',
100 - params: params
101 - });
102 - } else {
103 - after = '<ref' + bit;
104 - }
105 - if (after != '') {
106 - $.merge(parts, linksParse(after));
107 - }
108 - });
109 - return parts;
110 - };
111 - $.each(lines, function(i, line) {
112 - if (line == '') {
113 - blocks.push({
114 - type: 'break'
115 - });
116 - } else if (matches = /^(={1,6})(.*)\1$/.exec(line)) {
117 - blocks.push({
118 - type: 'h',
119 - level: matches[1].length,
120 - text: matches[2]
121 - });
122 - } else {
123 - var parts = inlineParse(line);
124 - blocks.push({
125 - type: 'para',
126 - content: parts
127 - });
128 - }
129 - });
130 - var tree = {
131 - type: 'page',
132 - content: blocks
133 - };
134 - callback(tree, null);
135 -};
136 -
137 -/**
138 - * @param {object} tree
139 - * @param {function(tree, error)} callback
140 - */
141 -FakeParser.prototype.expandTree = function(tree, callback) {
142 - // no-op!
143 - callback(tree, null);
144 -};
145 -
146 -/**
147 - * @param {object} tree
148 - * @param {function(domnode, error)} callback
149 - * @param {HashMap} inspectorMap
150 - */
151 -FakeParser.prototype.treeToHtml = function(tree, callback, inspectorMap) {
152 - var self = this;
153 - var subParseArray = function(listOfTrees, node) {
154 - $.each(listOfTrees, function(i, subtree) {
155 - self.treeToHtml(subtree, function(subnode, err) {
156 - if (subnode) {
157 - node.append(subnode);
158 - }
159 - }, inspectorMap);
160 - });
161 - };
162 - var node;
163 - switch (tree.type) {
164 - case 'page':
165 - // A sequence of block-level elements...
166 - var page = $('<div class="parseNode"></div>');
167 - subParseArray(tree.content, page);
168 - if (self.context.refs) {
169 - // We're at the end; drop all the remaining refs!
170 - subParseArray([{
171 - type: 'ext',
172 - name: 'references'
173 - }], page);
174 - }
175 - node = page[0];
176 - break;
177 - case 'para':
178 - // A single-line paragraph.
179 - var para = $('<p class="parseNode"></p>');
180 - subParseArray(tree.content, para);
181 - node = para[0];
182 - break;
183 - case 'break':
184 - // Just a stub in the parse tree.
185 - break;
186 - case 'text':
187 - // hack hack
188 - node = document.createTextNode(tree.text);
189 - break;
190 - case 'link':
191 - var link = $('<a class="parseNode"></a>');
192 - link.text(tree.text || tree.target);
193 - link.attr('href', '/wiki/' + tree.target); // hack
194 - node = link[0];
195 - break;
196 - case 'extlink':
197 - var link = $('<a class="parseNode"></a>');
198 - link.text(tree.text || tree.target); // fixme? #d links, freelinks etc
199 - link.attr('href', tree.target); // hack: validate etc
200 - node = link[0];
201 - break;
202 - case 'h':
203 - var h = $('<h' + tree.level + ' class="parseNode"></h' + tree.level + '>').text(tree.text);
204 - node = h[0];
205 - break;
206 - case 'i':
207 - var h = $('<i class="parseNode"></i>').text(tree.text); // hack -- use contents[]
208 - node = h[0];
209 - break;
210 - case 'template':
211 - var t = $('<span class="parseNode template"></span>').text('{{' + tree.target);
212 - if ('params' in tree) {
213 - $.each(tree.params, function(i, param) {
214 - var str = param.contents;
215 - if ('name' in param) {
216 - str = param.name + '=' + str;
217 - }
218 - var p = $('<span></span>').text('|' + str);
219 - t.append(p);
220 - });
221 - }
222 - t.append('}}');
223 - node = t[0];
224 - break;
225 - case 'ext':
226 - if (tree.name == 'ref') {
227 - // Save the reference for later!
228 - // @fixme names etc?
229 - if (self.context.refs === undefined) {
230 - self.context.refs = [];
231 - }
232 - self.context.refs.push(tree);
233 - var refNum = self.context.refs.length;
234 - var ref = $('<span class="ref parseNode">[</span>');
235 - $('<a></a>')
236 - .text(refNum + '')
237 - .attr('src', '#ref-' + refNum)
238 - .appendTo(ref);
239 - ref.append(']');
240 - node = ref[0];
241 - } else if (tree.name == 'references') {
242 - // Force inline expansion of references with a given group
243 - // @fixme support multiple groups etc
244 - var references = $('<ol class="references parseNode"></ol>');
245 - var oldRefs = self.context.refs;
246 - self.context.refs = [];
247 - $.each(oldRefs, function(i, subtree) {
248 - var ref = $('<li class="ref parseNode" id="ref-' + i + '"></li>');
249 - if ('content' in subtree) {
250 - subParseArray(subtree.content, ref);
251 - }
252 - references.append(ref);
253 - });
254 - node = references[0];
255 - } else if (tree.name == 'cite') {
256 - // Kinda like a ref but inline.
257 - // @fixme validate and output the tag parameters
258 - var cite = $('<span class="cite parseNode"></span>');
259 - if ('content' in tree) {
260 - subParseArray(tree.content, cite);
261 - }
262 - node = cite[0];
263 - } else {
264 - // @fixme unrecognized exts should output as text + rendered contents?
265 - callback(null, 'Unrecognized extension in parse tree');
266 - return;
267 - }
268 - break;
269 - default:
270 - callback(null, 'Unrecognized parse tree node');
271 - return;
272 - }
273 - if (node) {
274 - if (node.nodeType == 1) {
275 - $(node).data('parseNode', tree); // assign the node for the tree inspector
276 - if (inspectorMap) {
277 - inspectorMap.put(tree, node); // store for reverse lookup
278 - }
279 - }
280 - callback(node);
281 - } else {
282 - callback(null); // hmmmm
283 - }
284 -};
285 -
286 -/**
287 - * Collapse a parse tree back to source, if possible.
288 - * Ideally should exactly match the original source;
289 - * at minimum the resulting source should parse into
290 - * a tree that's identical to the current one.
291 - *
292 - * @param {object} tree
293 - * @param {function(text, error)} callback
294 - */
295 -FakeParser.prototype.treeToSource = function(tree, callback) {
296 - var self = this;
297 - var subParseArray = function(listOfTrees) {
298 - var str = '';
299 - $.each(listOfTrees, function(i, subtree) {
300 - self.treeToSource(subtree, function(substr, err) {
301 - if (substr) {
302 - str += substr;
303 - }
304 - });
305 - });
306 - return str;
307 - };
308 - var src;
309 - if (typeof tree === "string") {
310 - callback(tree);
311 - return;
312 - }
313 - switch (tree.type) {
314 - case 'page':
315 - src = subParseArray(tree.content);
316 - break;
317 - case 'para':
318 - // A single-line paragraph.
319 - src = subParseArray(tree.content) + '\n';
320 - break;
321 - case 'break':
322 - src = '\n';
323 - break;
324 - case 'text':
325 - // In the real world, there might be escaping.
326 - src = tree.text;
327 - break;
328 - case 'link':
329 - src = '[[';
330 - src += tree.target;
331 - if (tree.text) {
332 - src += '|';
333 - src += tree.text;
334 - }
335 - src += ']]';
336 - break;
337 - case 'h':
338 - var stub = '';
339 - for (var i = 0; i < tree.level; i++) {
340 - stub += '=';
341 - }
342 - src = stub + tree.text + stub + '\n';
343 - break;
344 - case 'ext':
345 - src = '<' + tree.name;
346 - if (tree.params) {
347 - for (var i = 0; i < tree.params.length; i++) {
348 - var param = tree.params[i];
349 - src += ' ';
350 - src += param.name + '=';
351 - if ('quote' in param) {
352 - src += param.quote;
353 - }
354 - src += param.text;
355 - if ('quote' in param) {
356 - src += param.quote;
357 - }
358 - }
359 - }
360 - if ('content' in tree) {
361 - src += '>';
362 - src += subParseArray(tree.content);
363 - src += '</' + tree.name + '>';
364 - } else {
365 - src += '/>';
366 - }
367 - break;
368 - case 'template':
369 - src = '{{' + tree.target;
370 - if (tree.params) {
371 - for (var i = 0; i < tree.params.length; i++) {
372 - var param = tree.params[i];
373 - src += '|';
374 - if ('name' in param) {
375 - src += param.name + '=';
376 - }
377 - src += param.contents;
378 - }
379 - }
380 - src += '}}';
381 - break;
382 - case 'i':
383 - src = "''" + tree.text + "''";
384 - break;
385 - case 'extlink':
386 - src = '[' + tree.target + ' ' + tree.text + ']';
387 - break;
388 - default:
389 - callback(null, 'Unrecognized parse tree node');
390 - return;
391 - }
392 - if (src) {
393 - callback(src);
394 - } else {
395 - callback(null); // hmmmm
396 - }
397 -};
Index: trunk/extensions/ParserPlayground/modules/ext.parserPlayground.renderer.js
@@ -0,0 +1,147 @@
 2+/**
 3+ * @param {ParserContext} context
 4+ */
 5+function MWTreeRenderer(context) {
 6+ // whee
 7+ this.context = context || {};
 8+}
 9+
 10+/**
 11+ * @param {object} tree
 12+ * @param {function(domnode, error)} callback
 13+ * @param {HashMap} inspectorMap
 14+ */
 15+MWTreeRenderer.prototype.treeToHtml = function(tree, callback, inspectorMap) {
 16+ var self = this;
 17+ var subParseArray = function(listOfTrees, node) {
 18+ $.each(listOfTrees, function(i, subtree) {
 19+ self.treeToHtml(subtree, function(subnode, err) {
 20+ if (subnode) {
 21+ node.append(subnode);
 22+ }
 23+ }, inspectorMap);
 24+ });
 25+ };
 26+ var node;
 27+ switch (tree.type) {
 28+ case 'page':
 29+ // A sequence of block-level elements...
 30+ var page = $('<div class="parseNode"></div>');
 31+ subParseArray(tree.content, page);
 32+ if (self.context.refs) {
 33+ // We're at the end; drop all the remaining refs!
 34+ subParseArray([{
 35+ type: 'ext',
 36+ name: 'references'
 37+ }], page);
 38+ }
 39+ node = page[0];
 40+ break;
 41+ case 'para':
 42+ // A single-line paragraph.
 43+ var para = $('<p class="parseNode"></p>');
 44+ subParseArray(tree.content, para);
 45+ node = para[0];
 46+ break;
 47+ case 'break':
 48+ // Just a stub in the parse tree.
 49+ break;
 50+ case 'text':
 51+ // hack hack
 52+ node = document.createTextNode(tree.text);
 53+ break;
 54+ case 'link':
 55+ var link = $('<a class="parseNode"></a>');
 56+ link.text(tree.text || tree.target);
 57+ link.attr('href', '/wiki/' + tree.target); // hack
 58+ node = link[0];
 59+ break;
 60+ case 'extlink':
 61+ var link = $('<a class="parseNode"></a>');
 62+ link.text(tree.text || tree.target); // fixme? #d links, freelinks etc
 63+ link.attr('href', tree.target); // hack: validate etc
 64+ node = link[0];
 65+ break;
 66+ case 'h':
 67+ var h = $('<h' + tree.level + ' class="parseNode"></h' + tree.level + '>').text(tree.text);
 68+ node = h[0];
 69+ break;
 70+ case 'i':
 71+ var h = $('<i class="parseNode"></i>').text(tree.text); // hack -- use contents[]
 72+ node = h[0];
 73+ break;
 74+ case 'template':
 75+ var t = $('<span class="parseNode template"></span>').text('{{' + tree.target);
 76+ if ('params' in tree) {
 77+ $.each(tree.params, function(i, param) {
 78+ var str = param.contents;
 79+ if ('name' in param) {
 80+ str = param.name + '=' + str;
 81+ }
 82+ var p = $('<span></span>').text('|' + str);
 83+ t.append(p);
 84+ });
 85+ }
 86+ t.append('}}');
 87+ node = t[0];
 88+ break;
 89+ case 'ext':
 90+ if (tree.name == 'ref') {
 91+ // Save the reference for later!
 92+ // @fixme names etc?
 93+ if (self.context.refs === undefined) {
 94+ self.context.refs = [];
 95+ }
 96+ self.context.refs.push(tree);
 97+ var refNum = self.context.refs.length;
 98+ var ref = $('<span class="ref parseNode">[</span>');
 99+ $('<a></a>')
 100+ .text(refNum + '')
 101+ .attr('src', '#ref-' + refNum)
 102+ .appendTo(ref);
 103+ ref.append(']');
 104+ node = ref[0];
 105+ } else if (tree.name == 'references') {
 106+ // Force inline expansion of references with a given group
 107+ // @fixme support multiple groups etc
 108+ var references = $('<ol class="references parseNode"></ol>');
 109+ var oldRefs = self.context.refs;
 110+ self.context.refs = [];
 111+ $.each(oldRefs, function(i, subtree) {
 112+ var ref = $('<li class="ref parseNode" id="ref-' + i + '"></li>');
 113+ if ('content' in subtree) {
 114+ subParseArray(subtree.content, ref);
 115+ }
 116+ references.append(ref);
 117+ });
 118+ node = references[0];
 119+ } else if (tree.name == 'cite') {
 120+ // Kinda like a ref but inline.
 121+ // @fixme validate and output the tag parameters
 122+ var cite = $('<span class="cite parseNode"></span>');
 123+ if ('content' in tree) {
 124+ subParseArray(tree.content, cite);
 125+ }
 126+ node = cite[0];
 127+ } else {
 128+ // @fixme unrecognized exts should output as text + rendered contents?
 129+ callback(null, 'Unrecognized extension in parse tree');
 130+ return;
 131+ }
 132+ break;
 133+ default:
 134+ callback(null, 'Unrecognized parse tree node');
 135+ return;
 136+ }
 137+ if (node) {
 138+ if (node.nodeType == 1) {
 139+ $(node).data('parseNode', tree); // assign the node for the tree inspector
 140+ if (inspectorMap) {
 141+ inspectorMap.put(tree, node); // store for reverse lookup
 142+ }
 143+ }
 144+ callback(node);
 145+ } else {
 146+ callback(null); // hmmmm
 147+ }
 148+};
Property changes on: trunk/extensions/ParserPlayground/modules/ext.parserPlayground.renderer.js
___________________________________________________________________
Added: svn:eol-style
1149 + native
Index: trunk/extensions/ParserPlayground/modules/ext.parserPlayground.pegParser.js
@@ -1,17 +1,18 @@
22 /**
3 - * Wrap a parser generated with pegjs into the FakeParser class,
4 - * so will use FakeParser's HTML output and round-tripping functions.
 3+ * Parser for wikitext to provisional temp structure, using PEG.js and
 4+ * a separate PEG grammar file (pegParser.pegjs.txt)
55 *
 6+ * Use along with the MWTreeRenderer and MWTreeSerializer classes for
 7+ * HTML output and source round-tripping.
 8+ *
69 * If installed as a user script or to customize, set parserPlaygroundPegPage
710 * to point at the MW page name containing the parser peg definition; default
811 * is 'MediaWiki:Gadget-ParserPlayground-PegParser.pegjs'.
912 */
1013 function PegParser(options) {
11 - FakeParser.call(this, options);
 14+ this.options = options;
1215 }
1316
14 -$.extend(PegParser.prototype, FakeParser.prototype);
15 -
1617 PegParser.src = false;
1718
1819 PegParser.prototype.parseToTree = function(text, callback) {
@@ -28,6 +29,15 @@
2930 });
3031 }
3132
 33+/**
 34+ * @param {object} tree
 35+ * @param {function(tree, error)} callback
 36+ */
 37+PegParser.prototype.expandTree = function(tree, callback) {
 38+ // no-op!
 39+ callback(tree, null);
 40+};
 41+
3242 PegParser.prototype.initSource = function(callback) {
3343 if (PegParser.src) {
3444 callback();
Index: trunk/extensions/ParserPlayground/modules/ext.parserPlayground.serializer.js
@@ -0,0 +1,121 @@
 2+/**
 3+ * @param {ParserContext} context
 4+ */
 5+function MWTreeSerializer(context) {
 6+ // whee
 7+ this.context = context || {};
 8+}
 9+
 10+
 11+/**
 12+ * Collapse a parse tree back to source, if possible.
 13+ * Ideally should exactly match the original source;
 14+ * at minimum the resulting source should parse into
 15+ * a tree that's identical to the current one.
 16+ *
 17+ * @param {object} tree
 18+ * @param {function(text, error)} callback
 19+ */
 20+MWTreeSerializer.prototype.treeToSource = function(tree, callback) {
 21+ var self = this;
 22+ var subParseArray = function(listOfTrees) {
 23+ var str = '';
 24+ $.each(listOfTrees, function(i, subtree) {
 25+ self.treeToSource(subtree, function(substr, err) {
 26+ if (substr) {
 27+ str += substr;
 28+ }
 29+ });
 30+ });
 31+ return str;
 32+ };
 33+ var src;
 34+ if (typeof tree === "string") {
 35+ callback(tree);
 36+ return;
 37+ }
 38+ switch (tree.type) {
 39+ case 'page':
 40+ src = subParseArray(tree.content);
 41+ break;
 42+ case 'para':
 43+ // A single-line paragraph.
 44+ src = subParseArray(tree.content) + '\n';
 45+ break;
 46+ case 'break':
 47+ src = '\n';
 48+ break;
 49+ case 'text':
 50+ // In the real world, there might be escaping.
 51+ src = tree.text;
 52+ break;
 53+ case 'link':
 54+ src = '[[';
 55+ src += tree.target;
 56+ if (tree.text) {
 57+ src += '|';
 58+ src += tree.text;
 59+ }
 60+ src += ']]';
 61+ break;
 62+ case 'h':
 63+ var stub = '';
 64+ for (var i = 0; i < tree.level; i++) {
 65+ stub += '=';
 66+ }
 67+ src = stub + tree.text + stub + '\n';
 68+ break;
 69+ case 'ext':
 70+ src = '<' + tree.name;
 71+ if (tree.params) {
 72+ for (var i = 0; i < tree.params.length; i++) {
 73+ var param = tree.params[i];
 74+ src += ' ';
 75+ src += param.name + '=';
 76+ if ('quote' in param) {
 77+ src += param.quote;
 78+ }
 79+ src += param.text;
 80+ if ('quote' in param) {
 81+ src += param.quote;
 82+ }
 83+ }
 84+ }
 85+ if ('content' in tree) {
 86+ src += '>';
 87+ src += subParseArray(tree.content);
 88+ src += '</' + tree.name + '>';
 89+ } else {
 90+ src += '/>';
 91+ }
 92+ break;
 93+ case 'template':
 94+ src = '{{' + tree.target;
 95+ if (tree.params) {
 96+ for (var i = 0; i < tree.params.length; i++) {
 97+ var param = tree.params[i];
 98+ src += '|';
 99+ if ('name' in param) {
 100+ src += param.name + '=';
 101+ }
 102+ src += param.contents;
 103+ }
 104+ }
 105+ src += '}}';
 106+ break;
 107+ case 'i':
 108+ src = "''" + tree.text + "''";
 109+ break;
 110+ case 'extlink':
 111+ src = '[' + tree.target + ' ' + tree.text + ']';
 112+ break;
 113+ default:
 114+ callback(null, 'Unrecognized parse tree node');
 115+ return;
 116+ }
 117+ if (src) {
 118+ callback(src);
 119+ } else {
 120+ callback(null); // hmmmm
 121+ }
 122+};
Property changes on: trunk/extensions/ParserPlayground/modules/ext.parserPlayground.serializer.js
___________________________________________________________________
Added: svn:eol-style
1123 + native
Index: trunk/extensions/ParserPlayground/modules/ext.parserPlayground.js
@@ -8,11 +8,9 @@
99 *
1010 * Adds a fold-out section in the editor (using enhanced toolbar) to swap view of:
1111 * - Source (your regular editable text)
12 - * - MediaWiki parser (parsed page as full HTML)
13 - * - Preprocessor tree (tree view of XML preprocessor tree; shows limited pre-parsing breakdown)
14 - * - FakeParser (a very primitive parser class in this gadget)
15 - * - FakeParser's parse tree
16 - * - FakeParser's output and parse tree side-by-side.
 12+ * - MediaWiki parser (parsed page as full HTML, with XML parse tree inspector)
 13+ * - PegParser (a very primitive parser class in this gadget), with
 14+ * tree inspector and primitive editing
1715 *
1816 * The parsed views update to match the current editor state when you bump over to them.
1917 * In side-by-side view, matching items are highlighted on the two sides, and clicking
@@ -123,7 +121,16 @@
124122 'action': {
125123 'type': 'callback',
126124 'execute': function( context ) {
127 - context.parserPlayground.parser = new parserClass();
 125+ var pp = context.parserPlayground;
 126+ pp.parser = new parserClass();
 127+ // hack
 128+ if (pp.parser instanceof MediaWikiParser) {
 129+ pp.serializer = pp.parser;
 130+ pp.renderer = pp.parser;
 131+ } else {
 132+ pp.serializer = new MWTreeSerializer();
 133+ pp.renderer = new MWTreeRenderer();
 134+ }
128135 context.parserPlayground.fn.initDisplay();
129136 $.cookie('pp-editmode', className, {
130137 expires: 30,
@@ -152,13 +159,12 @@
153160 }
154161 };
155162 addParserModes(listItems, MediaWikiParser, 'MediaWikiParser');
156 - addParserModes(listItems, FakeParser, 'FakeParser');
157163 addParserModes(listItems, PegParser, 'PegParser', '<p>Peg-based parser plus FakeParser\'s output. <a href="http://pegjs.majda.cz/documentation">pegjs documentation</a>; edit and reselect to reparse with updated parser</p>');
158164
159165 window.setTimeout(function() {
160166 var context = editor.data('wikiEditor-context');
161167 var pp = context.parserPlayground = {
162 - parser: new FakeParser(),
 168+ parser: undefined,
163169 tree: undefined,
164170 useInspector: false,
165171 fn: {
@@ -196,7 +202,7 @@
197203 pp.treeMap.put( node, el );
198204 });
199205 }
200 - pp.parser.treeToHtml(pp.tree, function(node, err) {
 206+ pp.renderer.treeToHtml(pp.tree, function(node, err) {
201207 var $dest = context.$parserContainer.find('div');
202208 $dest.empty().append(node);
203209 context.parserPlayground.fn.setupEditor(context.$parserContainer);
@@ -224,7 +230,7 @@
225231 pp.fn.hide();
226232 };
227233 if (pp.parser && pp.tree) {
228 - pp.parser.treeToSource( pp.tree, function( src, err ) {
 234+ pp.serializer.treeToSource( pp.tree, function( src, err ) {
229235 context.$textarea.val( src );
230236 finish();
231237 });
@@ -257,8 +263,7 @@
258264 var node = $(this).data('parseNode');
259265 if ( node ) {
260266 // Ok, not 100% kosher right now but... :D
261 - var parser = context.parserPlayground.parser;
262 - parser.treeToSource(node, function(src, err) {
 267+ pp.serializer.treeToSource(node, function(src, err) {
263268 //alert( src );
264269 pp.sel = {
265270 node: node,

Status & tagging log