http://www.mediawiki.org/wiki/Special:Code/MediaWiki/100271
Revision: 100271
Author: gwicke
Date: 2011-10-19 20:19:50 +0000 (Wed, 19 Oct 2011)
Log Message:
-----------
List handling in parser
List handling is pushed directly into the rule actions for now. Probably not
the most elegant way to do this, will revisit this later.
Modified Paths:
--------------
trunk/extensions/ParserPlayground/modules/ext.parserPlayground.renderer.js
trunk/extensions/ParserPlayground/modules/ext.parserPlayground.serializer.js
trunk/extensions/ParserPlayground/modules/pegParser.pegjs.txt
trunk/extensions/ParserPlayground/tests/parserTests.js
Modified:
trunk/extensions/ParserPlayground/modules/ext.parserPlayground.renderer.js
===================================================================
--- trunk/extensions/ParserPlayground/modules/ext.parserPlayground.renderer.js
2011-10-19 20:17:16 UTC (rev 100270)
+++ trunk/extensions/ParserPlayground/modules/ext.parserPlayground.renderer.js
2011-10-19 20:19:50 UTC (rev 100271)
@@ -123,6 +123,9 @@
case 'span':
case 'ol':
case 'ul':
+ case 'dl':
+ case 'dt':
+ case 'dd':
case 'li':
var $span = $('<' + tree.type + '>');
if ('attrs' in tree) {
Modified:
trunk/extensions/ParserPlayground/modules/ext.parserPlayground.serializer.js
===================================================================
---
trunk/extensions/ParserPlayground/modules/ext.parserPlayground.serializer.js
2011-10-19 20:17:16 UTC (rev 100270)
+++
trunk/extensions/ParserPlayground/modules/ext.parserPlayground.serializer.js
2011-10-19 20:19:50 UTC (rev 100271)
@@ -119,7 +119,14 @@
// @fixme validate that text doesn't contain '-->'
src = '<!--' + tree.text + '-->';
break;
+ case 'ul':
+ case 'ol':
+ case 'dl':
+ src = subParseArray(tree.content);
+ break;
case 'li':
+ case 'dt':
+ case 'dd':
src = tree.listStyle.join('');
src += subParseArray(tree.content) + '\n';
break;
Modified: trunk/extensions/ParserPlayground/modules/pegParser.pegjs.txt
===================================================================
--- trunk/extensions/ParserPlayground/modules/pegParser.pegjs.txt
2011-10-19 20:17:16 UTC (rev 100270)
+++ trunk/extensions/ParserPlayground/modules/pegParser.pegjs.txt
2011-10-19 20:19:50 UTC (rev 100271)
@@ -1,7 +1,61 @@
/* Produces output more or less compatible with FakeParser; plug it into FP's
output and see */
+{
+
+ /* Temporary debugging help */
+ var print_r = function (arr, level) {
+
+ var dumped_text = "";
+ if (!level) level = 0;
+
+ //The padding given at the beginning of the line.
+ var level_padding = "";
+ var bracket_level_padding = "";
+
+ for (var j = 0; j < level + 1; j++) level_padding += " ";
+ for (var b = 0; b < level; b++) bracket_level_padding += " ";
+
+ if (typeof(arr) == 'object') { //Array/Hashes/Objects
+ dumped_text += "Array\n";
+ dumped_text += bracket_level_padding + "(\n";
+ for (var item in arr) {
+
+ var value = arr[item];
+
+ if (typeof(value) == 'object') { //If it is an array,
+ dumped_text += level_padding + "[" + item + "] => ";
+ dumped_text += print_r(value, level + 2);
+ } else {
+ dumped_text += level_padding + "[" + item + "] => " +
value + "\n";
+ }
+
+ }
+ dumped_text += bracket_level_padding + ")\n\n";
+ } else { //Stings/Chars/Numbers etc.
+ dumped_text = "===>" + arr + "<===(" + typeof(arr) + ")";
+ }
+
+ return dumped_text;
+
+ }
+}
+
start
- = e:block* { return {type: 'page', content: e } }
+ = e:block* {
+ var es = [];
+ // flatten sub-arrays, as a list block can contain multiple lists
+ $.each(e, function(i, ei) {
+ if (ei.constructor == Array)
+ es = es.concat(ei);
+ else
+ es.push(ei);
+ });
+ //console.log(print_r(es, 10));
+ return {
+ type: 'page',
+ content: es
+ }
+ }
anything
= a:[A-Za-z0-9,._ -]+ { return a.join('') } / [^\n]
@@ -15,7 +69,7 @@
block
= br
/ h
- / li
+ / lists
/ para
h = h1 / h2 / h3 / h4 / h5 / h6
@@ -82,7 +136,7 @@
c:anything
inline
- = c:inline_element+ {
+ = c:(inline_element / anything)+ {
var out = [];
var text = '';
for (var i = 0; i < c.length; i++) {
@@ -116,7 +170,6 @@
/ link
/ bold
/ italic
- / anything
comment
= '<!--' c:comment_chars+ '-->' {
@@ -293,7 +346,7 @@
}
ref_content
- = !ref_end a:inline_element {
+ = !ref_end a:(inline_element / anything) {
return a;
}
@@ -337,7 +390,7 @@
}
references_content
- = !references_end a:inline_element {
+ = !references_end a:(inline_element / anything) {
return a;
}
@@ -358,20 +411,120 @@
/ "'" t:[^'>]+ "'" { return { quote: "'", text: t.join('') } }
/ '"' t:[^">]+ '"' { return { quote: '"', text: t.join('') } }
+lists = es:(dtdd / li)+
+{
+ var out = [], // List of list nodes
+ bstack = "", // Bullet stack, previous element's listStyle
+ bnext = "", // Next element's listStyle
+ nodes = []; // Stack of currently active, nested list nodes
+
+ var commonPrefixLength = function (x, y) {
+ var minLength = Math.min(x.length, y.length);
+ for(var i = 0; i < minLength; i++) {
+ if (x[i] != y[i])
+ break;
+ }
+ return i;
+ }
+
+ var pushN = function ( n ) {
+ if (nodes.length > 0) {
+ nodes[nodes.length - 1].content.push(n);
+ } else {
+ out.push(n);
+ nodes.push(n);
+ }
+ }
+
+ var openLists = function ( bs, bn ) {
+ var prefix = commonPrefixLength (bs, bn);
+ nodes = nodes.slice(0, prefix);
+ $.each(bn.slice(prefix, bn.length), function (i, c) {
+ switch (c) {
+ case '*':
+ pushN({type: 'ul', content: []});
+ break;
+ case '#':
+ pushN({type: 'ol', content: []});
+ break;
+ case ';':
+ case ':':
+ pushN({type: 'dl', content: []});
+ break;
+ default:
+ throw("Unknown node prefix " + c);
+ }
+ });
+ }
+
+
+ $.each(es, function(i, e) {
+ if (e.type == 'dtdd') {
+ bnext = e.content[0].listStyle;
+ lnode = openLists( bstack, bnext );
+
+ nodes[nodes.length - 1].content =
+ nodes[nodes.length - 1].content.concat(e.content);
+ } else {
+ bnext = e.listStyle;
+ openLists( bstack, bnext, nodes );
+ nodes[nodes.length - 1].content.push(e);
+ }
+ bstack = bnext;
+ });
+ //console.log("out: " + print_r(out, 5));
+ return out;
+
+
+
+}
+
li = bullets:list_char+
c:(inline / anything)
newline
{
+ var type;
+ switch (bullets[bullets.length - 1]) {
+ case '#':
+ case '*':
+ type = 'li'; break;
+ case ';': type = 'dt'; break;
+ case ':': type = 'dd'; break;
+ }
return {
- type: 'li',
+ type: type,
listStyle: bullets,
content: c
};
}
-list_char =
- '*' /
- '#' /
- ':' /
- ';'
+dtdd = bullets:list_char+
+ c:(inline_element / [^:\n])+
+ ":"
+ d:(inline / anything)
+ newline
+{
+ // reject rule if bullets do not end in colon
+ if (bullets[bullets.length - 1] != ';')
+ return null;
+ else
+ return { type: 'dtdd',
+ content: [
+ {
+ type: 'dt',
+ listStyle: bullets,
+ content: c
+ },
+ {
+ type: 'dd',
+ listStyle: bullets.slice(0, bullets.length - 1) + ':',
+ content: d
+ }
+
+ ]
+ };
+}
+
+
+list_char = [*#:;]
Modified: trunk/extensions/ParserPlayground/tests/parserTests.js
===================================================================
--- trunk/extensions/ParserPlayground/tests/parserTests.js 2011-10-19
20:17:16 UTC (rev 100270)
+++ trunk/extensions/ParserPlayground/tests/parserTests.js 2011-10-19
20:19:50 UTC (rev 100271)
@@ -128,6 +128,8 @@
if (err) {
console.log('RENDER FAIL', err);
} else {
+ console.log('INPUT:');
+ console.log(item.input + "\n");
console.log('EXPECTED:');
console.log(item.result + "\n");
_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs