r104679 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r104678‎ | r104679 | r104680 >
Date:13:42, 30 November 2011
Author:gwicke
Status:deferred
Tags:
Comment:
Expand tabs in grammar.
Modified paths:
  • /trunk/extensions/VisualEditor/modules/parser/pegParser.pegjs.txt (modified) (history)

Diff [purge]

Index: trunk/extensions/VisualEditor/modules/parser/pegParser.pegjs.txt
@@ -1,37 +1,37 @@
22 /* Produces output more or less compatible with FakeParser; plug it into FP's output and see */
33 {
4 - /* Fixme: use static functions to separate module! Unfortunately, this
5 - * does not work:
6 - * var tu = require('./mediawiki.tokenizer.utils.js');
7 - * console.log(tu.flatten([]));
8 - * Using exports in the module gets a bit further, but accesses to
9 - * tu.flatten in productions still fail. Thus, I just moved the functions
10 - * here until a solution is found:
11 - */
12 -
13 - /* Static utilities */
 4+ /* Fixme: use static functions to separate module! Unfortunately, this
 5+ * does not work:
 6+ * var tu = require('./mediawiki.tokenizer.utils.js');
 7+ * console.log(tu.flatten([]));
 8+ * Using exports in the module gets a bit further, but accesses to
 9+ * tu.flatten in productions still fail. Thus, I just moved the functions
 10+ * here until a solution is found:
 11+ */
1412
15 - // Flatten a list of lists.
16 - var flatten = function ( e ) {
17 - var es = [];
18 - // flatten sub-arrays
19 - for(var i = 0, length = e.length; i < length; i++) {
20 - var ei = e[i];
21 - if ($.isArray(ei))
22 - es = es.concat(flatten(ei));
23 - else
24 - es.push(ei);
25 - };
26 - return es;
27 - };
 13+ /* Static utilities */
2814
29 - // Remove escaped quotes from attributes etc
30 - var unquote = function (quotec, text) {
31 - return text.replace('\\' + quotec, quotec);
32 - };
33 -
 15+ // Flatten a list of lists.
 16+ var flatten = function ( e ) {
 17+ var es = [];
 18+ // flatten sub-arrays
 19+ for(var i = 0, length = e.length; i < length; i++) {
 20+ var ei = e[i];
 21+ if ($.isArray(ei))
 22+ es = es.concat(flatten(ei));
 23+ else
 24+ es.push(ei);
 25+ };
 26+ return es;
 27+ };
3428
35 - // Debug print with global switch
 29+ // Remove escaped quotes from attributes etc
 30+ var unquote = function (quotec, text) {
 31+ return text.replace('\\' + quotec, quotec);
 32+ };
 33+
 34+
 35+ // Debug print with global switch
3636 var dp = function ( msg ) {
3737 if ( false ) {
3838 console.log(msg);
@@ -40,285 +40,285 @@
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
 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
5757
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 - };
 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+ };
6666
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 - };
 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+ };
7373
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 - };
 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+ };
8282
83 - var isDlDd = function (a, b) {
84 - var ab = [a,b].sort();
85 - return (ab[0] === ':' && ab[1] === ';');
86 - };
 83+ var isDlDd = function (a, b) {
 84+ var ab = [a,b].sort();
 85+ return (ab[0] === ':' && ab[1] === ';');
 86+ };
8787
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 {
 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 {
111111 popTags(bs.length - prefixLen);
112 - for(var i = prefixLen; i < bn.length; i++) {
113 - switch (bn[i]) {
114 - case '*':
115 - pushList('ul', 'li');
116 - break;
117 - case '#':
118 - pushList('ol', 'li');
119 - break;
120 - case ';':
121 - pushList('dl', 'dt');
122 - break;
123 - case ':':
124 - pushList('dl', 'dd');
125 - break;
126 - default:
127 - throw("Unknown node prefix " + prefix[i]);
128 - }
129 - }
130 - }
131 - };
 112+ for(var i = prefixLen; i < bn.length; i++) {
 113+ switch (bn[i]) {
 114+ case '*':
 115+ pushList('ul', 'li');
 116+ break;
 117+ case '#':
 118+ pushList('ol', 'li');
 119+ break;
 120+ case ';':
 121+ pushList('dl', 'dt');
 122+ break;
 123+ case ':':
 124+ pushList('dl', 'dd');
 125+ break;
 126+ default:
 127+ throw("Unknown node prefix " + prefix[i]);
 128+ }
 129+ }
 130+ }
 131+ };
132132
133 - for (var i = 0, length = tokens.length; i < length; i++) {
134 - var token = tokens[i];
135 - switch ( token.type ) {
136 - case 'TAG':
137 - switch (token.name) {
138 - case 'list':
139 - // ignore token
140 - break;
141 - case 'listItem':
142 - // convert listItem to list and list item tokens
143 - bnext = token.bullets;
144 - doListItem( bstack, bnext );
145 - bstack = bnext;
146 - break;
147 - default:
148 - // pass through all remaining start tags
149 - out.push(token);
150 - break;
151 - }
152 - break;
153 - case 'ENDTAG':
154 - if ( token.name == 'list' ) {
155 - // pop all open list item tokens
156 - popTags(bstack.length);
157 - bstack = "";
158 - } else {
159 - out.push(token);
160 - }
161 - break;
162 - default:
163 - out.push(token);
164 - break;
165 - }
166 - }
167 - return out;
168 - };
 133+ for (var i = 0, length = tokens.length; i < length; i++) {
 134+ var token = tokens[i];
 135+ switch ( token.type ) {
 136+ case 'TAG':
 137+ switch (token.name) {
 138+ case 'list':
 139+ // ignore token
 140+ break;
 141+ case 'listItem':
 142+ // convert listItem to list and list item tokens
 143+ bnext = token.bullets;
 144+ doListItem( bstack, bnext );
 145+ bstack = bnext;
 146+ break;
 147+ default:
 148+ // pass through all remaining start tags
 149+ out.push(token);
 150+ break;
 151+ }
 152+ break;
 153+ case 'ENDTAG':
 154+ if ( token.name == 'list' ) {
 155+ // pop all open list item tokens
 156+ popTags(bstack.length);
 157+ bstack = "";
 158+ } else {
 159+ out.push(token);
 160+ }
 161+ break;
 162+ default:
 163+ out.push(token);
 164+ break;
 165+ }
 166+ }
 167+ return out;
 168+ };
169169
170 - /*
171 - * Italic/Bold handling.
172 - *
173 - * - list of tokens
174 - * - NEWLINE
175 - * - ticks (2+) -> list with link in line token list?
176 - * - process on newline
177 - * - need access to text nodes before/after for conversion back to text
178 - */
179 - var doQuotes = function ( tokens ) {
 170+ /*
 171+ * Italic/Bold handling.
 172+ *
 173+ * - list of tokens
 174+ * - NEWLINE
 175+ * - ticks (2+) -> list with link in line token list?
 176+ * - process on newline
 177+ * - need access to text nodes before/after for conversion back to text
 178+ */
 179+ var doQuotes = function ( tokens ) {
180180
181 - var italics = [],
182 - bolds = [],
183 - out = [],
184 - inserted = 0;
 181+ var italics = [],
 182+ bolds = [],
 183+ out = [],
 184+ inserted = 0;
185185
186 - var convertBold = function ( i ) {
187 - var index = bolds[i];
188 - var txt = out[index - 1];
189 - txt.value += "'";
190 - bolds = bolds.slice(0, i)
191 - .concat(bolds.slice(i + 1, bolds.length - i - 1));
192 - italics.push(index);
193 - italics.sort();
194 - };
 186+ var convertBold = function ( i ) {
 187+ var index = bolds[i];
 188+ var txt = out[index - 1];
 189+ txt.value += "'";
 190+ bolds = bolds.slice(0, i)
 191+ .concat(bolds.slice(i + 1, bolds.length - i - 1));
 192+ italics.push(index);
 193+ italics.sort();
 194+ };
195195
196 - // convert italics/bolds into tags
197 - var quotesToTags = function ( offsets, name ) {
198 - var toggle = true;
199 - for (var j = 0; j < offsets.length; j++) {
200 - var t = out[offsets[j]];
201 - if(toggle) {
202 - t.type = 'TAG';
203 - } else {
204 - t.type = 'ENDTAG';
205 - }
206 - t.name = name;
207 - delete t.value;
208 - toggle = !toggle;
209 - }
210 - if (!toggle) {
211 - // add end tag
212 - out.push({type: 'ENDTAG', name: name});
213 - inserted++;
214 - }
215 - toggle = true;
216 - };
 196+ // convert italics/bolds into tags
 197+ var quotesToTags = function ( offsets, name ) {
 198+ var toggle = true;
 199+ for (var j = 0; j < offsets.length; j++) {
 200+ var t = out[offsets[j]];
 201+ if(toggle) {
 202+ t.type = 'TAG';
 203+ } else {
 204+ t.type = 'ENDTAG';
 205+ }
 206+ t.name = name;
 207+ delete t.value;
 208+ toggle = !toggle;
 209+ }
 210+ if (!toggle) {
 211+ // add end tag
 212+ out.push({type: 'ENDTAG', name: name});
 213+ inserted++;
 214+ }
 215+ toggle = true;
 216+ };
217217
218 - for (var i = 0, length = tokens.length; i < length; i++) {
219 - var token = tokens[i];
220 - switch (token.type) {
221 - case 'QUOTE':
222 - // depending on length, add starting 's to preceding text node
223 - // (if any)
224 - // add token index to italic/bold lists
225 - // add placeholder for token
226 - var qlen = token.value.length;
227 - switch (qlen) {
228 - case 2: italics.push(i + inserted); out.push(token); break;
229 - case 3: bolds.push(i + inserted); out.push(token); break;
230 - case 4:
231 - token.value = "'''";
232 - if (i > 0 && tokens[i-1].type === 'TEXT') {
233 - tokens[i-1].value += "'";
234 - } else {
235 - out.push({type: 'TEXT', value: "'"});
236 - inserted++;
237 - }
238 - bolds.push(i + inserted);
239 - out.push(token);
240 - break;
241 - case 5:
242 - // order does not matter here, will be fixed
243 - // by HTML parser backend
244 - bolds.push(i + inserted);
245 - out.push({type: 'QUOTE', value: "'''"});
246 - inserted++;
247 - italics.push(i + inserted);
248 - out.push({type: 'QUOTE', value: "''"});
249 - break;
250 - default: // longer than 5, only use the last 5 ticks
251 - token.value = "'''''";
252 - var newvalue = token.value.substr(0, qlen - 5 );
253 - if (i > 0 && tokens[i-1].type === 'TEXT') {
254 - tokens[i-1].value += newvalue;
255 - } else {
256 - out.push({type: 'TEXT', value: newvalue});
257 - inserted++;
258 - }
259 - bolds.push(i + inserted);
260 - out.push({type: 'QUOTE', value: "'''"});
261 - inserted++;
262 - italics.push(i + inserted);
263 - out.push({type: 'QUOTE', value: "''"});
264 - break;
265 - }
266 - break;
 218+ for (var i = 0, length = tokens.length; i < length; i++) {
 219+ var token = tokens[i];
 220+ switch (token.type) {
 221+ case 'QUOTE':
 222+ // depending on length, add starting 's to preceding text node
 223+ // (if any)
 224+ // add token index to italic/bold lists
 225+ // add placeholder for token
 226+ var qlen = token.value.length;
 227+ switch (qlen) {
 228+ case 2: italics.push(i + inserted); out.push(token); break;
 229+ case 3: bolds.push(i + inserted); out.push(token); break;
 230+ case 4:
 231+ token.value = "'''";
 232+ if (i > 0 && tokens[i-1].type === 'TEXT') {
 233+ tokens[i-1].value += "'";
 234+ } else {
 235+ out.push({type: 'TEXT', value: "'"});
 236+ inserted++;
 237+ }
 238+ bolds.push(i + inserted);
 239+ out.push(token);
 240+ break;
 241+ case 5:
 242+ // order does not matter here, will be fixed
 243+ // by HTML parser backend
 244+ bolds.push(i + inserted);
 245+ out.push({type: 'QUOTE', value: "'''"});
 246+ inserted++;
 247+ italics.push(i + inserted);
 248+ out.push({type: 'QUOTE', value: "''"});
 249+ break;
 250+ default: // longer than 5, only use the last 5 ticks
 251+ token.value = "'''''";
 252+ var newvalue = token.value.substr(0, qlen - 5 );
 253+ if (i > 0 && tokens[i-1].type === 'TEXT') {
 254+ tokens[i-1].value += newvalue;
 255+ } else {
 256+ out.push({type: 'TEXT', value: newvalue});
 257+ inserted++;
 258+ }
 259+ bolds.push(i + inserted);
 260+ out.push({type: 'QUOTE', value: "'''"});
 261+ inserted++;
 262+ italics.push(i + inserted);
 263+ out.push({type: 'QUOTE', value: "''"});
 264+ break;
 265+ }
 266+ break;
267267
268 - case 'NEWLINE':
269 - // balance out tokens, convert placeholders into tags
270 - if (italics.length % 2 && bolds.length % 2) {
271 - dp("balancing!");
272 - var firstsingleletterword = -1,
273 - firstmultiletterword = -1,
274 - firstspace = -1;
275 - for (var j = 0; j < bolds.length; j++) {
276 - var ticki = bolds[j];
277 - if (ticki > 0 && out[ticki - 1].type === 'TEXT') {
278 - var txt = out[ticki - 1],
279 - lastchar = txt.value[txt.value.length - 1],
280 - secondtolastchar = txt.value[txt.value.length - 2];
281 - dp('txt: ' + pp(txt));
282 - if (lastchar === ' ' && firstspace === -1) {
283 - firstspace = j;
284 - } else if (lastchar !== ' ') {
285 - if ( secondtolastchar === ' ' &&
286 - firstsingleletterword === -1) {
287 - firstsingleletterword = j;
288 - } else if ( secondtolastchar &&
289 - secondtolastchar !== ' ') {
290 - firstmultiletterword = j;
291 - }
292 - }
293 - }
294 - }
 268+ case 'NEWLINE':
 269+ // balance out tokens, convert placeholders into tags
 270+ if (italics.length % 2 && bolds.length % 2) {
 271+ dp("balancing!");
 272+ var firstsingleletterword = -1,
 273+ firstmultiletterword = -1,
 274+ firstspace = -1;
 275+ for (var j = 0; j < bolds.length; j++) {
 276+ var ticki = bolds[j];
 277+ if (ticki > 0 && out[ticki - 1].type === 'TEXT') {
 278+ var txt = out[ticki - 1],
 279+ lastchar = txt.value[txt.value.length - 1],
 280+ secondtolastchar = txt.value[txt.value.length - 2];
 281+ dp('txt: ' + pp(txt));
 282+ if (lastchar === ' ' && firstspace === -1) {
 283+ firstspace = j;
 284+ } else if (lastchar !== ' ') {
 285+ if ( secondtolastchar === ' ' &&
 286+ firstsingleletterword === -1) {
 287+ firstsingleletterword = j;
 288+ } else if ( secondtolastchar &&
 289+ secondtolastchar !== ' ') {
 290+ firstmultiletterword = j;
 291+ }
 292+ }
 293+ }
 294+ }
295295
296296
297 - // now see if we can convert a bold to an italic and
298 - // an apostrophe
299 - if (firstsingleletterword > -1) {
300 - convertBold(firstsingleletterword);
301 - } else if (firstmultiletterword > -1) {
302 - convertBold(firstmultiletterword);
303 - } else if (firstspace > -1) {
304 - convertBold(firstspace);
305 - }
306 - }
 297+ // now see if we can convert a bold to an italic and
 298+ // an apostrophe
 299+ if (firstsingleletterword > -1) {
 300+ convertBold(firstsingleletterword);
 301+ } else if (firstmultiletterword > -1) {
 302+ convertBold(firstmultiletterword);
 303+ } else if (firstspace > -1) {
 304+ convertBold(firstspace);
 305+ }
 306+ }
307307
308 - quotesToTags(bolds, 'b');
309 - quotesToTags(italics, 'i');
310 - bolds = [];
311 - italics = [];
312 - out.push(token);
313 - break;
314 - default:
315 - out.push(token);
316 - }
317 - }
318 - return out;
319 - };
 308+ quotesToTags(bolds, 'b');
 309+ quotesToTags(italics, 'i');
 310+ bolds = [];
 311+ italics = [];
 312+ out.push(token);
 313+ break;
 314+ default:
 315+ out.push(token);
 316+ }
 317+ }
 318+ return out;
 319+ };
320320
321321
322 - /* End static utilities */
 322+ /* End static utilities */
323323
324324 /*
325325 * Flags for specific parse environments (inside tables, links etc). Flags
@@ -412,9 +412,9 @@
413413 bs.attribs = [];
414414 }
415415 bs.attribs.push(['data-sourcePos', blockStart + ':' + pos]);
416 - // XXX: only run this for lines that actually need it!
417 - b.push({type: 'NEWLINE'});
418 - b = doQuotes(b);
 416+ // XXX: only run this for lines that actually need it!
 417+ b.push({type: 'NEWLINE'});
 418+ b = doQuotes(b);
419419 return b;
420420 }
421421
@@ -968,8 +968,8 @@
969969 lists = e:(dtdd / li) es:(sol (dtdd / li))*
970970 {
971971 return annotateList( [ { type: 'TAG', name: 'list'} ]
972 - .concat(flatten([e].concat(es))
973 - ,[{ type: 'ENDTAG', name: 'list' }]));
 972+ .concat(flatten([e].concat(es))
 973+ ,[{ type: 'ENDTAG', name: 'list' }]));
974974 }
975975
976976 li = bullets:list_char+

Status & tagging log