Skip to content

Instantly share code, notes, and snippets.

@bengillies
Created May 23, 2011 14:56
Show Gist options
  • Save bengillies/986826 to your computer and use it in GitHub Desktop.
Save bengillies/986826 to your computer and use it in GitHub Desktop.
PEG based wikitext parser
wikitext = (function(){
/* Generated by PEG.js 0.6.1 (http://pegjs.majda.cz/). */
var result = {
/*
* Parses the input with a generated parser. If the parsing is successfull,
* returns a value explicitly or implicitly specified by the grammar from
* which the parser was generated (see |PEG.buildParser|). If the parsing is
* unsuccessful, throws |PEG.parser.SyntaxError| describing the error.
*/
parse: function(input, startRule) {
var parseFunctions = {
"eol": parse_eol,
"heading": parse_heading,
"inline": parse_inline,
"line": parse_line,
"link": parse_link,
"list": parse_list,
"olist": parse_olist,
"space": parse_space,
"start": parse_start,
"text": parse_text,
"ulist": parse_ulist,
"word": parse_word
};
if (startRule !== undefined) {
if (parseFunctions[startRule] === undefined) {
throw new Error("Invalid rule name: " + quote(startRule) + ".");
}
} else {
startRule = "start";
}
var pos = 0;
var reportMatchFailures = true;
var rightmostMatchFailuresPos = 0;
var rightmostMatchFailuresExpected = [];
var cache = {};
function padLeft(input, padding, length) {
var result = input;
var padLength = length - input.length;
for (var i = 0; i < padLength; i++) {
result = padding + result;
}
return result;
}
function escape(ch) {
var charCode = ch.charCodeAt(0);
if (charCode <= 0xFF) {
var escapeChar = 'x';
var length = 2;
} else {
var escapeChar = 'u';
var length = 4;
}
return '\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), '0', length);
}
function quote(s) {
/*
* ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a
* string literal except for the closing quote character, backslash,
* carriage return, line separator, paragraph separator, and line feed.
* Any character may appear in the form of an escape sequence.
*/
return '"' + s
.replace(/\\/g, '\\\\') // backslash
.replace(/"/g, '\\"') // closing quote character
.replace(/\r/g, '\\r') // carriage return
.replace(/\n/g, '\\n') // line feed
.replace(/[\x80-\uFFFF]/g, escape) // non-ASCII characters
+ '"';
}
function matchFailed(failure) {
if (pos < rightmostMatchFailuresPos) {
return;
}
if (pos > rightmostMatchFailuresPos) {
rightmostMatchFailuresPos = pos;
rightmostMatchFailuresExpected = [];
}
rightmostMatchFailuresExpected.push(failure);
}
function parse_start() {
var cacheKey = 'start@' + pos;
var cachedResult = cache[cacheKey];
if (cachedResult) {
pos = cachedResult.nextPos;
return cachedResult.result;
}
var result1 = parse_line();
if (result1 !== null) {
var result0 = [];
while (result1 !== null) {
result0.push(result1);
var result1 = parse_line();
}
} else {
var result0 = null;
}
cache[cacheKey] = {
nextPos: pos,
result: result0
};
return result0;
}
function parse_line() {
var cacheKey = 'line@' + pos;
var cachedResult = cache[cacheKey];
if (cachedResult) {
pos = cachedResult.nextPos;
return cachedResult.result;
}
var result4 = parse_heading();
if (result4 !== null) {
var result0 = result4;
} else {
var result3 = parse_list();
if (result3 !== null) {
var result0 = result3;
} else {
var result2 = parse_text();
if (result2 !== null) {
var result0 = result2;
} else {
var result1 = parse_eol();
if (result1 !== null) {
var result0 = result1;
} else {
var result0 = null;;
};
};
};
}
cache[cacheKey] = {
nextPos: pos,
result: result0
};
return result0;
}
function parse_heading() {
var cacheKey = 'heading@' + pos;
var cachedResult = cache[cacheKey];
if (cachedResult) {
pos = cachedResult.nextPos;
return cachedResult.result;
}
var savedPos0 = pos;
if (input.substr(pos, 1) === "!") {
var result2 = "!";
pos += 1;
} else {
var result2 = null;
if (reportMatchFailures) {
matchFailed("\"!\"");
}
}
if (result2 !== null) {
var result3 = parse_text();
if (result3 !== null) {
var result1 = [result2, result3];
} else {
var result1 = null;
pos = savedPos0;
}
} else {
var result1 = null;
pos = savedPos0;
}
var result0 = result1 !== null
? (function(bang, text) { return {type: "HEADING", value: text}; })(result1[0], result1[1])
: null;
cache[cacheKey] = {
nextPos: pos,
result: result0
};
return result0;
}
function parse_text() {
var cacheKey = 'text@' + pos;
var cachedResult = cache[cacheKey];
if (cachedResult) {
pos = cachedResult.nextPos;
return cachedResult.result;
}
var savedPos0 = pos;
var result4 = parse_word();
if (result4 !== null) {
var result6 = parse_space();
var result5 = result6 !== null ? result6 : '';
if (result5 !== null) {
var result3 = [result4, result5];
} else {
var result3 = null;
pos = savedPos0;
}
} else {
var result3 = null;
pos = savedPos0;
}
var result2 = result3 !== null
? (function(word, space) {
return (typeof word === 'string') ? word + space :
((space) ? [word, space] : word);
})(result3[0], result3[1])
: null;
if (result2 !== null) {
var result1 = [];
while (result2 !== null) {
result1.push(result2);
var savedPos0 = pos;
var result4 = parse_word();
if (result4 !== null) {
var result6 = parse_space();
var result5 = result6 !== null ? result6 : '';
if (result5 !== null) {
var result3 = [result4, result5];
} else {
var result3 = null;
pos = savedPos0;
}
} else {
var result3 = null;
pos = savedPos0;
}
var result2 = result3 !== null
? (function(word, space) {
return (typeof word === 'string') ? word + space :
((space) ? [word, space] : word);
})(result3[0], result3[1])
: null;
}
} else {
var result1 = null;
}
var result0 = result1 !== null
? (function(text) {
var result = (function() {
var res = [], bufStr = '';
for (var i = 0; i < text.length; i++) {
if (typeof text[i] !== 'string') {
if (bufStr) {
res.push(bufStr);
bufStr = '';
}
res.push(text[i]);
} else {
bufStr += text[i];
}
}
if (bufStr) {
res.push(bufStr);
}
if (res.length === 1 && typeof res[0] === 'string') {
return { type: 'TEXT', value: res[0] }
} else if (res.length === 1) {
return res[0];
} else {
return res;
}
}());
return result;
})(result1)
: null;
cache[cacheKey] = {
nextPos: pos,
result: result0
};
return result0;
}
function parse_eol() {
var cacheKey = 'eol@' + pos;
var cachedResult = cache[cacheKey];
if (cachedResult) {
pos = cachedResult.nextPos;
return cachedResult.result;
}
if (input.substr(pos, 1) === "\n") {
var result1 = "\n";
pos += 1;
} else {
var result1 = null;
if (reportMatchFailures) {
matchFailed("\"\\n\"");
}
}
var result0 = result1 !== null
? (function(end) { return "EOL"; })(result1)
: null;
cache[cacheKey] = {
nextPos: pos,
result: result0
};
return result0;
}
function parse_space() {
var cacheKey = 'space@' + pos;
var cachedResult = cache[cacheKey];
if (cachedResult) {
pos = cachedResult.nextPos;
return cachedResult.result;
}
if (input.substr(pos).match(/^[ ]/) !== null) {
var result2 = input.charAt(pos);
pos++;
} else {
var result2 = null;
if (reportMatchFailures) {
matchFailed("[ ]");
}
}
if (result2 !== null) {
var result1 = [];
while (result2 !== null) {
result1.push(result2);
if (input.substr(pos).match(/^[ ]/) !== null) {
var result2 = input.charAt(pos);
pos++;
} else {
var result2 = null;
if (reportMatchFailures) {
matchFailed("[ ]");
}
}
}
} else {
var result1 = null;
}
var result0 = result1 !== null
? (function(ws) { return ws.join(''); })(result1)
: null;
cache[cacheKey] = {
nextPos: pos,
result: result0
};
return result0;
}
function parse_word() {
var cacheKey = 'word@' + pos;
var cachedResult = cache[cacheKey];
if (cachedResult) {
pos = cachedResult.nextPos;
return cachedResult.result;
}
var result5 = parse_inline();
var result4 = result5 !== null
? (function(inline) { return inline; })(result5)
: null;
if (result4 !== null) {
var result0 = result4;
} else {
if (input.substr(pos).match(/^[^ \n]/) !== null) {
var result3 = input.charAt(pos);
pos++;
} else {
var result3 = null;
if (reportMatchFailures) {
matchFailed("[^ \\n]");
}
}
if (result3 !== null) {
var result2 = [];
while (result3 !== null) {
result2.push(result3);
if (input.substr(pos).match(/^[^ \n]/) !== null) {
var result3 = input.charAt(pos);
pos++;
} else {
var result3 = null;
if (reportMatchFailures) {
matchFailed("[^ \\n]");
}
}
}
} else {
var result2 = null;
}
var result1 = result2 !== null
? (function(text) { return text.join(''); })(result2)
: null;
if (result1 !== null) {
var result0 = result1;
} else {
var result0 = null;;
};
}
cache[cacheKey] = {
nextPos: pos,
result: result0
};
return result0;
}
function parse_inline() {
var cacheKey = 'inline@' + pos;
var cachedResult = cache[cacheKey];
if (cachedResult) {
pos = cachedResult.nextPos;
return cachedResult.result;
}
var savedPos0 = pos;
if (input.substr(pos, 2) === "<<") {
var result5 = "<<";
pos += 2;
} else {
var result5 = null;
if (reportMatchFailures) {
matchFailed("\"<<\"");
}
}
if (result5 !== null) {
if (input.substr(pos).match(/^[^>>]/) !== null) {
var result8 = input.charAt(pos);
pos++;
} else {
var result8 = null;
if (reportMatchFailures) {
matchFailed("[^>>]");
}
}
if (result8 !== null) {
var result6 = [];
while (result8 !== null) {
result6.push(result8);
if (input.substr(pos).match(/^[^>>]/) !== null) {
var result8 = input.charAt(pos);
pos++;
} else {
var result8 = null;
if (reportMatchFailures) {
matchFailed("[^>>]");
}
}
}
} else {
var result6 = null;
}
if (result6 !== null) {
if (input.substr(pos, 2) === ">>") {
var result7 = ">>";
pos += 2;
} else {
var result7 = null;
if (reportMatchFailures) {
matchFailed("\">>\"");
}
}
if (result7 !== null) {
var result4 = [result5, result6, result7];
} else {
var result4 = null;
pos = savedPos0;
}
} else {
var result4 = null;
pos = savedPos0;
}
} else {
var result4 = null;
pos = savedPos0;
}
var result3 = result4 !== null
? (function(text) { return {type: 'TRANSCLUDE', value: text.join('')}; })(result4[1])
: null;
if (result3 !== null) {
var result0 = result3;
} else {
var result2 = parse_link();
var result1 = result2 !== null
? (function(link) { return link; })(result2)
: null;
if (result1 !== null) {
var result0 = result1;
} else {
var result0 = null;;
};
}
cache[cacheKey] = {
nextPos: pos,
result: result0
};
return result0;
}
function parse_link() {
var cacheKey = 'link@' + pos;
var cachedResult = cache[cacheKey];
if (cachedResult) {
pos = cachedResult.nextPos;
return cachedResult.result;
}
var savedPos2 = pos;
if (input.substr(pos, 2) === "[[") {
var result21 = "[[";
pos += 2;
} else {
var result21 = null;
if (reportMatchFailures) {
matchFailed("\"[[\"");
}
}
if (result21 !== null) {
if (input.substr(pos).match(/^[^\]\]|]/) !== null) {
var result24 = input.charAt(pos);
pos++;
} else {
var result24 = null;
if (reportMatchFailures) {
matchFailed("[^\\]\\]|]");
}
}
if (result24 !== null) {
var result22 = [];
while (result24 !== null) {
result22.push(result24);
if (input.substr(pos).match(/^[^\]\]|]/) !== null) {
var result24 = input.charAt(pos);
pos++;
} else {
var result24 = null;
if (reportMatchFailures) {
matchFailed("[^\\]\\]|]");
}
}
}
} else {
var result22 = null;
}
if (result22 !== null) {
if (input.substr(pos, 2) === "]]") {
var result23 = "]]";
pos += 2;
} else {
var result23 = null;
if (reportMatchFailures) {
matchFailed("\"]]\"");
}
}
if (result23 !== null) {
var result20 = [result21, result22, result23];
} else {
var result20 = null;
pos = savedPos2;
}
} else {
var result20 = null;
pos = savedPos2;
}
} else {
var result20 = null;
pos = savedPos2;
}
var result19 = result20 !== null
? (function(text) { return {type: 'LINK', value: text.join('')}; })(result20[1])
: null;
if (result19 !== null) {
var result0 = result19;
} else {
var savedPos1 = pos;
if (input.substr(pos, 2) === "[[") {
var result12 = "[[";
pos += 2;
} else {
var result12 = null;
if (reportMatchFailures) {
matchFailed("\"[[\"");
}
}
if (result12 !== null) {
if (input.substr(pos).match(/^[^|]/) !== null) {
var result18 = input.charAt(pos);
pos++;
} else {
var result18 = null;
if (reportMatchFailures) {
matchFailed("[^|]");
}
}
if (result18 !== null) {
var result13 = [];
while (result18 !== null) {
result13.push(result18);
if (input.substr(pos).match(/^[^|]/) !== null) {
var result18 = input.charAt(pos);
pos++;
} else {
var result18 = null;
if (reportMatchFailures) {
matchFailed("[^|]");
}
}
}
} else {
var result13 = null;
}
if (result13 !== null) {
if (input.substr(pos, 1) === "|") {
var result14 = "|";
pos += 1;
} else {
var result14 = null;
if (reportMatchFailures) {
matchFailed("\"|\"");
}
}
if (result14 !== null) {
if (input.substr(pos).match(/^[^\]\]]/) !== null) {
var result17 = input.charAt(pos);
pos++;
} else {
var result17 = null;
if (reportMatchFailures) {
matchFailed("[^\\]\\]]");
}
}
if (result17 !== null) {
var result15 = [];
while (result17 !== null) {
result15.push(result17);
if (input.substr(pos).match(/^[^\]\]]/) !== null) {
var result17 = input.charAt(pos);
pos++;
} else {
var result17 = null;
if (reportMatchFailures) {
matchFailed("[^\\]\\]]");
}
}
}
} else {
var result15 = null;
}
if (result15 !== null) {
if (input.substr(pos, 2) === "]]") {
var result16 = "]]";
pos += 2;
} else {
var result16 = null;
if (reportMatchFailures) {
matchFailed("\"]]\"");
}
}
if (result16 !== null) {
var result11 = [result12, result13, result14, result15, result16];
} else {
var result11 = null;
pos = savedPos1;
}
} else {
var result11 = null;
pos = savedPos1;
}
} else {
var result11 = null;
pos = savedPos1;
}
} else {
var result11 = null;
pos = savedPos1;
}
} else {
var result11 = null;
pos = savedPos1;
}
var result10 = result11 !== null
? (function(name, link) { return {type: 'LINK', value: {TITLE: name.join(''), LINK: link.join('')}}; })(result11[1], result11[3])
: null;
if (result10 !== null) {
var result0 = result10;
} else {
var savedPos0 = pos;
if (input.substr(pos).match(/^[A-Z]/) !== null) {
var result3 = input.charAt(pos);
pos++;
} else {
var result3 = null;
if (reportMatchFailures) {
matchFailed("[A-Z]");
}
}
if (result3 !== null) {
var result4 = [];
if (input.substr(pos).match(/^[a-z0-9]/) !== null) {
var result9 = input.charAt(pos);
pos++;
} else {
var result9 = null;
if (reportMatchFailures) {
matchFailed("[a-z0-9]");
}
}
while (result9 !== null) {
result4.push(result9);
if (input.substr(pos).match(/^[a-z0-9]/) !== null) {
var result9 = input.charAt(pos);
pos++;
} else {
var result9 = null;
if (reportMatchFailures) {
matchFailed("[a-z0-9]");
}
}
}
if (result4 !== null) {
if (input.substr(pos).match(/^[A-Z]/) !== null) {
var result8 = input.charAt(pos);
pos++;
} else {
var result8 = null;
if (reportMatchFailures) {
matchFailed("[A-Z]");
}
}
if (result8 !== null) {
var result5 = [];
while (result8 !== null) {
result5.push(result8);
if (input.substr(pos).match(/^[A-Z]/) !== null) {
var result8 = input.charAt(pos);
pos++;
} else {
var result8 = null;
if (reportMatchFailures) {
matchFailed("[A-Z]");
}
}
}
} else {
var result5 = null;
}
if (result5 !== null) {
if (input.substr(pos).match(/^[0-9a-zA-Z]/) !== null) {
var result7 = input.charAt(pos);
pos++;
} else {
var result7 = null;
if (reportMatchFailures) {
matchFailed("[0-9a-zA-Z]");
}
}
if (result7 !== null) {
var result6 = [];
while (result7 !== null) {
result6.push(result7);
if (input.substr(pos).match(/^[0-9a-zA-Z]/) !== null) {
var result7 = input.charAt(pos);
pos++;
} else {
var result7 = null;
if (reportMatchFailures) {
matchFailed("[0-9a-zA-Z]");
}
}
}
} else {
var result6 = null;
}
if (result6 !== null) {
var result2 = [result3, result4, result5, result6];
} else {
var result2 = null;
pos = savedPos0;
}
} else {
var result2 = null;
pos = savedPos0;
}
} else {
var result2 = null;
pos = savedPos0;
}
} else {
var result2 = null;
pos = savedPos0;
}
var result1 = result2 !== null
? (function(firstCap, firstText, secondCap, lastText) { return {type: 'WIKILINK', value: firstCap + firstText.join('') + secondCap.join('') + lastText.join('')}; })(result2[0], result2[1], result2[2], result2[3])
: null;
if (result1 !== null) {
var result0 = result1;
} else {
var result0 = null;;
};
};
}
cache[cacheKey] = {
nextPos: pos,
result: result0
};
return result0;
}
function parse_list() {
var cacheKey = 'list@' + pos;
var cachedResult = cache[cacheKey];
if (cachedResult) {
pos = cachedResult.nextPos;
return cachedResult.result;
}
var result6 = parse_ulist();
if (result6 !== null) {
var result5 = [];
while (result6 !== null) {
result5.push(result6);
var result6 = parse_ulist();
}
} else {
var result5 = null;
}
var result4 = result5 !== null
? (function(list) { return {type: 'ULIST', value: list}; })(result5)
: null;
if (result4 !== null) {
var result0 = result4;
} else {
var result3 = parse_olist();
if (result3 !== null) {
var result2 = [];
while (result3 !== null) {
result2.push(result3);
var result3 = parse_olist();
}
} else {
var result2 = null;
}
var result1 = result2 !== null
? (function(list) {return {type: 'OLIST', value: list}; })(result2)
: null;
if (result1 !== null) {
var result0 = result1;
} else {
var result0 = null;;
};
}
cache[cacheKey] = {
nextPos: pos,
result: result0
};
return result0;
}
function parse_ulist() {
var cacheKey = 'ulist@' + pos;
var cachedResult = cache[cacheKey];
if (cachedResult) {
pos = cachedResult.nextPos;
return cachedResult.result;
}
var savedPos0 = pos;
if (input.substr(pos, 1) === "*") {
var result2 = "*";
pos += 1;
} else {
var result2 = null;
if (reportMatchFailures) {
matchFailed("\"*\"");
}
}
if (result2 !== null) {
var result8 = parse_space();
var result3 = result8 !== null ? result8 : '';
if (result3 !== null) {
var result7 = parse_text();
var result4 = result7 !== null ? result7 : '';
if (result4 !== null) {
var result6 = parse_eol();
var result5 = result6 !== null ? result6 : '';
if (result5 !== null) {
var result1 = [result2, result3, result4, result5];
} else {
var result1 = null;
pos = savedPos0;
}
} else {
var result1 = null;
pos = savedPos0;
}
} else {
var result1 = null;
pos = savedPos0;
}
} else {
var result1 = null;
pos = savedPos0;
}
var result0 = result1 !== null
? (function(text) { return {type: 'ULI', value: text}; })(result1[2])
: null;
cache[cacheKey] = {
nextPos: pos,
result: result0
};
return result0;
}
function parse_olist() {
var cacheKey = 'olist@' + pos;
var cachedResult = cache[cacheKey];
if (cachedResult) {
pos = cachedResult.nextPos;
return cachedResult.result;
}
var savedPos0 = pos;
if (input.substr(pos, 1) === "#") {
var result2 = "#";
pos += 1;
} else {
var result2 = null;
if (reportMatchFailures) {
matchFailed("\"#\"");
}
}
if (result2 !== null) {
var result8 = parse_space();
var result3 = result8 !== null ? result8 : '';
if (result3 !== null) {
var result7 = parse_text();
var result4 = result7 !== null ? result7 : '';
if (result4 !== null) {
var result6 = parse_eol();
var result5 = result6 !== null ? result6 : '';
if (result5 !== null) {
var result1 = [result2, result3, result4, result5];
} else {
var result1 = null;
pos = savedPos0;
}
} else {
var result1 = null;
pos = savedPos0;
}
} else {
var result1 = null;
pos = savedPos0;
}
} else {
var result1 = null;
pos = savedPos0;
}
var result0 = result1 !== null
? (function(text) { return {type: 'OLI', value: text}; })(result1[2])
: null;
cache[cacheKey] = {
nextPos: pos,
result: result0
};
return result0;
}
function buildErrorMessage() {
function buildExpected(failuresExpected) {
failuresExpected.sort();
var lastFailure = null;
var failuresExpectedUnique = [];
for (var i = 0; i < failuresExpected.length; i++) {
if (failuresExpected[i] !== lastFailure) {
failuresExpectedUnique.push(failuresExpected[i]);
lastFailure = failuresExpected[i];
}
}
switch (failuresExpectedUnique.length) {
case 0:
return 'end of input';
case 1:
return failuresExpectedUnique[0];
default:
return failuresExpectedUnique.slice(0, failuresExpectedUnique.length - 1).join(', ')
+ ' or '
+ failuresExpectedUnique[failuresExpectedUnique.length - 1];
}
}
var expected = buildExpected(rightmostMatchFailuresExpected);
var actualPos = Math.max(pos, rightmostMatchFailuresPos);
var actual = actualPos < input.length
? quote(input.charAt(actualPos))
: 'end of input';
return 'Expected ' + expected + ' but ' + actual + ' found.';
}
function computeErrorPosition() {
/*
* The first idea was to use |String.split| to break the input up to the
* error position along newlines and derive the line and column from
* there. However IE's |split| implementation is so broken that it was
* enough to prevent it.
*/
var line = 1;
var column = 1;
var seenCR = false;
for (var i = 0; i < rightmostMatchFailuresPos; i++) {
var ch = input.charAt(i);
if (ch === '\n') {
if (!seenCR) { line++; }
column = 1;
seenCR = false;
} else if (ch === '\r' | ch === '\u2028' || ch === '\u2029') {
line++;
column = 1;
seenCR = true;
} else {
column++;
seenCR = false;
}
}
return { line: line, column: column };
}
var result = parseFunctions[startRule]();
/*
* The parser is now in one of the following three states:
*
* 1. The parser successfully parsed the whole input.
*
* - |result !== null|
* - |pos === input.length|
* - |rightmostMatchFailuresExpected| may or may not contain something
*
* 2. The parser successfully parsed only a part of the input.
*
* - |result !== null|
* - |pos < input.length|
* - |rightmostMatchFailuresExpected| may or may not contain something
*
* 3. The parser did not successfully parse any part of the input.
*
* - |result === null|
* - |pos === 0|
* - |rightmostMatchFailuresExpected| contains at least one failure
*
* All code following this comment (including called functions) must
* handle these states.
*/
if (result === null || pos !== input.length) {
var errorPosition = computeErrorPosition();
throw new this.SyntaxError(
buildErrorMessage(),
errorPosition.line,
errorPosition.column
);
}
return result;
},
/* Returns the parser source code. */
toSource: function() { return this._source; }
};
/* Thrown when a parser encounters a syntax error. */
result.SyntaxError = function(message, line, column) {
this.name = 'SyntaxError';
this.message = message;
this.line = line;
this.column = column;
};
result.SyntaxError.prototype = Error.prototype;
return result;
})();
start = line+
line = heading / list / text / eol
heading = bang:"!" text:text { return {type: "HEADING", value: text}; }
text = text:(word:word space:space? {
return (typeof word === 'string') ? word + space :
((space) ? [word, space] : word);
})+ {
var result = (function() {
var res = [], bufStr = '';
for (var i = 0; i < text.length; i++) {
if (typeof text[i] !== 'string') {
if (bufStr) {
res.push(bufStr);
bufStr = '';
}
res.push(text[i]);
} else {
bufStr += text[i];
}
}
if (bufStr) {
res.push(bufStr);
}
if (res.length === 1 && typeof res[0] === 'string') {
return { type: 'TEXT', value: res[0] }
} else if (res.length === 1) {
return res[0];
} else {
return res;
}
}());
return result;
}
eol = end:"\n" { return "EOL"; }
space = ws:[ \t]+ { return ws.join(''); }
word = inline:inline { return inline; } /
text:[^ \t\n]+ { return text.join(''); }
inline = "<<" text:[^>>]+ ">>" { return {type: 'TRANSCLUDE', value: text.join('')}; } /
link:link { return link; }
link = "[[" text:[^\]\]|]+ "]]" { return {type: 'LINK', value: text.join('')}; } /
"[[" name:[^\|]+ "|" link:[^\]\]]+ "]]" { return {type: 'LINK', value: {TITLE: name.join(''), LINK: link.join('')}}; } /
firstCap:[A-Z] firstText:[a-z0-9]* secondCap:[A-Z]+ lastText:[0-9a-zA-Z]+ { return {type: 'WIKILINK', value: firstCap + firstText.join('') + secondCap.join('') + lastText.join('')}; }
list = list:ulist+ { return {type: 'ULIST', value: list}; } / list:olist+ {return {type: 'OLIST', value: list}; }
ulist = "*" space? text:text? eol? { return {type: 'ULI', value: text}; }
olist = "#" space? text:text? eol? { return {type: 'OLI', value: text}; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment