r104037 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r104036‎ | r104037 | r104038 >
Date:14:27, 23 November 2011
Author:gwicke
Status:deferred
Tags:
Comment:
Re-add modified wiki list handling to tokenizer.
Modified paths:
  • /trunk/extensions/VisualEditor/modules/parser/pegParser.pegjs.txt (modified) (history)

Diff [purge]

Index: trunk/extensions/VisualEditor/modules/parser/pegParser.pegjs.txt
@@ -40,6 +40,132 @@
4141
4242 var pp = function ( s ) { return JSON.stringify(s, null, 2); }
4343
 44+ /*
 45+ * Annotate a token stream with list items with appropriate list tokens
 46+ *
 47+ * @static
 48+ * @method
 49+ * @param {[tokens]} Token stream with li tokens
 50+ * @returns {[tokens]} Token stream, possibly with additional list tokens
 51+ * */
 52+ var annotateList = function ( tokens ) {
 53+ var out = [], // List of tokens
 54+ bstack = [], // Bullet stack, previous element's listStyle
 55+ bnext = [], // Next element's listStyle
 56+ endtags = []; // Stack of end tags
 57+
 58+ var commonPrefixLength = function (x, y) {
 59+ var minLength = Math.min(x.length, y.length);
 60+ for(var i = 0; i < minLength; i++) {
 61+ if (x[i] != y[i])
 62+ break;
 63+ }
 64+ return i;
 65+ };
 66+
 67+ var pushList = function ( listName, itemName ) {
 68+ out.push({type: 'TAG', name: listName});
 69+ out.push({type: 'TAG', name: itemName});
 70+ endtags.push({type: 'ENDTAG', name: listName});
 71+ endtags.push({type: 'ENDTAG', name: itemName});
 72+ };
 73+
 74+ var popTags = function ( n ) {
 75+ for(;n > 0; n--) {
 76+ // push list item..
 77+ out.push(endtags.pop());
 78+ // and the list end tag
 79+ out.push(endtags.pop());
 80+ }
 81+ };
 82+
 83+ var isDlDd = function (a, b) {
 84+ var ab = [a,b].sort();
 85+ return (ab[0] === ':' && ab[1] === ';');
 86+ };
 87+
 88+ var doListItem = function ( bs, bn ) {
 89+ var prefixLen = commonPrefixLength (bs, bn);
 90+ var changeLen = bn.length - prefixLen;
 91+ var prefix = bn.slice(0, prefixLen);
 92+ // emit close tag tokens for closed lists
 93+ if (changeLen === 0) {
 94+ var itemToken = endtags.pop();
 95+ out.push(itemToken);
 96+ out.push({type: 'TAG', name: itemToken.name});
 97+ endtags.push({type: 'ENDTAG', name: itemToken.name});
 98+ } else if ( bs.length == bn.length
 99+ && changeLen == 1
 100+ && isDlDd( bs[prefixLen], bn[prefixLen] ) ) {
 101+ // handle dd/dt transitions
 102+ out.push(endtags.pop());
 103+ if( bn[prefixLen] == ';') {
 104+ var newName = 'dt';
 105+ } else {
 106+ var newName = 'dd';
 107+ }
 108+ out.push({type: 'TAG', name: newName});
 109+ endtags.push({type: 'ENDTAG', name: newName});
 110+ } else {
 111+ for(var i = prefixLen; i < bn.length; i++) {
 112+ switch (bn[i]) {
 113+ case '*':
 114+ pushList('ul', 'li');
 115+ break;
 116+ case '#':
 117+ pushList('ol', 'li');
 118+ break;
 119+ case ';':
 120+ pushList('dl', 'dt');
 121+ break;
 122+ case ':':
 123+ pushList('dl', 'dd');
 124+ break;
 125+ default:
 126+ throw("Unknown node prefix " + prefix[i]);
 127+ }
 128+ }
 129+ }
 130+ };
 131+
 132+ for (var i = 0, length = tokens.length; i < length; i++) {
 133+ var token = tokens[i];
 134+ switch ( token.type ) {
 135+ case 'TAG':
 136+ switch (token.name) {
 137+ case 'list':
 138+ // ignore token
 139+ break;
 140+ case 'listItem':
 141+ // convert listItem to list and list item tokens
 142+ bnext = token.bullets;
 143+ doListItem( bstack, bnext );
 144+ bstack = bnext;
 145+ break;
 146+ default:
 147+ // pass through all remaining start tags
 148+ out.push(token);
 149+ break;
 150+ }
 151+ break;
 152+ case 'ENDTAG':
 153+ if ( token.name == 'list' ) {
 154+ // pop all open list item tokens
 155+ popTags(bstack.length);
 156+ bstack = "";
 157+ } else {
 158+ out.push(token);
 159+ }
 160+ break;
 161+ default:
 162+ out.push(token);
 163+ break;
 164+ }
 165+ }
 166+ return out;
 167+ };
 168+
 169+
44170 /* End static utilities */
45171
46172 /*
@@ -560,10 +686,9 @@
561687
562688 lists = es:(dtdd / li)+
563689 {
564 - return [ { type: 'TAG',
565 - name: 'ul'} ] // XXX!!
566 - .concat(flatten(es)
567 - ,[{ type: 'ENDTAG', name: 'ul' }]);
 690+ return annotateList( [ { type: 'TAG', name: 'list'} ]
 691+ .concat(flatten(es)
 692+ ,[{ type: 'ENDTAG', name: 'list' }]));
568693 }
569694
570695 li = sol
@@ -572,11 +697,9 @@
573698 &newline
574699 {
575700 return [ { type: 'TAG',
576 - name: 'li',
577 - attribs: [['data-styles', bullets]] }
578 - , c
579 - , { type: 'ENDTAG', name: 'li' }
580 - ];
 701+ name: 'listItem',
 702+ bullets: bullets }
 703+ , c ];
581704 }
582705
583706 dtdd = sol
@@ -590,14 +713,12 @@
591714 if (bullets[bullets.length - 1] != ';') {
592715 return null;
593716 } else {
594 - return [ { type: 'TAG', name: 'dl', attribs: [['data-styles', bullets]] }
595 - , { type: 'TAG', name: 'dt' } ]
 717+ var dtbullets = bullets.slice(0, bullets.length - 1);
 718+ dtbullets.push(':');
 719+ return [ { type: 'TAG', name: 'listItem', bullets: bullets } ]
596720 .concat( c
597 - , [ {type: 'ENDTAG', name: 'dt'}
598 - , {type: 'TAG', name: 'dd'} ]
599 - , d
600 - , [ {type: 'ENDTAG', name: 'dd'}
601 - , {type: 'ENDTAG', name: 'dl'} ]);
 721+ ,[{ type: 'TAG', name: 'listItem', bullets: dtbullets } ]
 722+ , d );
602723 }
603724 }
604725

Status & tagging log