Created
May 23, 2011 14:56
-
-
Save bengillies/986826 to your computer and use it in GitHub Desktop.
PEG based wikitext parser
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
})(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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