Checkin before I destroy everything.
This commit is contained in:
@@ -11,16 +11,16 @@ var mediawiki = {
|
|||||||
'nowiki': [rr.Literal('<nowiki>'), rr.MultiLineText(), rr.Literal('</nowiki>')],
|
'nowiki': [rr.Literal('<nowiki>'), rr.MultiLineText(), rr.Literal('</nowiki>')],
|
||||||
'text': [rr.MultiLineText()],
|
'text': [rr.MultiLineText()],
|
||||||
'wikichunk': [rr.Or(
|
'wikichunk': [rr.Or(
|
||||||
'b',
|
// 'b',
|
||||||
'del',
|
// 'del',
|
||||||
'h2',
|
// 'h2',
|
||||||
'h3',
|
'h3',
|
||||||
'h4',
|
// 'h4',
|
||||||
'h5',
|
// 'h5',
|
||||||
'h6',
|
// 'h6',
|
||||||
'hr',
|
// 'hr',
|
||||||
'i',
|
// 'i',
|
||||||
'nowiki',
|
// 'nowiki',
|
||||||
'text'
|
'text'
|
||||||
)],
|
)],
|
||||||
'wikidoc': [rr.ZeroOrMore('wikichunk')],
|
'wikidoc': [rr.ZeroOrMore('wikichunk')],
|
||||||
|
|||||||
225
recentrunes.js
225
recentrunes.js
@@ -6,16 +6,18 @@ rr.Literal_ = function(value) {
|
|||||||
this.value_ = value;
|
this.value_ = value;
|
||||||
};
|
};
|
||||||
|
|
||||||
rr.Literal_.prototype.match = function(input) {
|
rr.Literal_.prototype.match = function(context) {
|
||||||
if (input.slice(0, this.value_.length) == this.value_) {
|
if (context.stringAfter(this.value_.length) == this.value_) {
|
||||||
return [this.value_.length, null];
|
context.advance(this.value_.length);
|
||||||
|
return [];
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
rr.Literal_.prototype.search = function(input) {
|
rr.Literal_.prototype.search = function(context) {
|
||||||
var index = input.indexOf(this.value_);
|
console.log(context.stringAfter());
|
||||||
|
var index = context.stringAfter().indexOf(this.value_);
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
@@ -39,8 +41,8 @@ rr.Ref_.prototype.minimize = function(parser) {
|
|||||||
return parser.minimize(this.key_);
|
return parser.minimize(this.key_);
|
||||||
};
|
};
|
||||||
|
|
||||||
rr.Ref_.prototype.match = function(input, fullInput, inputIndex, parser) {
|
rr.Ref_.prototype.match = function(context) {
|
||||||
return parser.parse(this.key_, input);
|
return context.parser.parse(this.key_, context);
|
||||||
};
|
};
|
||||||
|
|
||||||
rr.Ref = function(key) {
|
rr.Ref = function(key) {
|
||||||
@@ -54,26 +56,27 @@ rr.Ref.cache = {};
|
|||||||
rr.EndOfLine_ = function() {
|
rr.EndOfLine_ = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
rr.EndOfLine_.prototype.match = function(input, fullInput, inputIndex) {
|
rr.EndOfLine_.prototype.match = function(context) {
|
||||||
if (input.length == 0) {
|
if (context.atEnd()) {
|
||||||
return [0, null];
|
return [];
|
||||||
}
|
}
|
||||||
if (input[0] == '\n') {
|
if (context.stringAfter(1) == '\n') {
|
||||||
return [1, null];
|
context.advance(1);
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
if (inputIndex > 0 && fullInput[inputIndex - 1] == '\n') {
|
if (context.stringBefore(1) == '\n') {
|
||||||
return [0, null];
|
return [];
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
rr.EndOfLine_.prototype.search = function(input, fullInput, inputIndex) {
|
rr.EndOfLine_.prototype.search = function(context) {
|
||||||
if (input.length == 0) {
|
if (context.atEnd()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
var loc = input.indexOf('\n');
|
var loc = context.stringAfter().indexOf('\n');
|
||||||
if (loc == -1) {
|
if (loc == -1) {
|
||||||
return input.length;
|
return context.remaining();
|
||||||
} else {
|
} else {
|
||||||
return loc;
|
return loc;
|
||||||
}
|
}
|
||||||
@@ -89,16 +92,16 @@ rr.EndOfLine.cache = new rr.EndOfLine_();
|
|||||||
rr.EndOfText_ = function() {
|
rr.EndOfText_ = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
rr.EndOfText_.prototype.match = function(input) {
|
rr.EndOfText_.prototype.match = function(context) {
|
||||||
if (input.length) {
|
if (context.atEnd()) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return [0, null];
|
return [];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
rr.EndOfText_.prototype.search = function(input) {
|
rr.EndOfText_.prototype.search = function(context) {
|
||||||
return input.length;
|
return context.remaining();
|
||||||
};
|
};
|
||||||
|
|
||||||
rr.EndOfText = function() {
|
rr.EndOfText = function() {
|
||||||
@@ -115,8 +118,10 @@ rr.MultiLineText_.prototype.minimize = function() {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
rr.MultiLineText_.prototype.match = function(input) {
|
rr.MultiLineText_.prototype.match = function(context) {
|
||||||
return [input.length, document.createTextNode(input)];
|
var ret = [document.createTextNode(context.stringAfter())];
|
||||||
|
context.advance(context.remaining());
|
||||||
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
rr.MultiLineText = function() {
|
rr.MultiLineText = function() {
|
||||||
@@ -135,15 +140,15 @@ rr.Or_.prototype.minimize = function(parser) {
|
|||||||
var option = this.options_[i];
|
var option = this.options_[i];
|
||||||
if (parser.minimize(option)) {
|
if (parser.minimize(option)) {
|
||||||
return true;
|
return true;
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
rr.Or_.prototype.match = function(input, fullInput, inputIndex, parser) {
|
rr.Or_.prototype.match = function(context) {
|
||||||
for (var i = 0; i < this.options_.length; i++) {
|
for (var i = 0; i < this.options_.length; i++) {
|
||||||
var option = this.options_[i];
|
var option = this.options_[i];
|
||||||
var result = parser.parse(option, input);
|
var result = context.parser.parse(option, context);
|
||||||
if (result) {
|
if (result) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -164,13 +169,14 @@ rr.SingleLineText_.prototype.minimize = function() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
rr.SingleLineText_.prototype.match = function(input) {
|
rr.SingleLineText_.prototype.match = function(context) {
|
||||||
var newLine = input.indexOf('\n');
|
var newLine = context.stringAfter().indexOf('\n');
|
||||||
if (newLine == -1) {
|
if (newLine == -1) {
|
||||||
return [input.length, document.createTextNode(input)];
|
newLine = context.remaining();
|
||||||
} else {
|
|
||||||
return [newLine, document.createTextNode(input.slice(0, newLine))];
|
|
||||||
}
|
}
|
||||||
|
var ret = [document.createTextNode(context.stringAfter(newLine))];
|
||||||
|
context.advance(newLine);
|
||||||
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
rr.SingleLineText = function() {
|
rr.SingleLineText = function() {
|
||||||
@@ -183,24 +189,25 @@ rr.SingleLineText.cache = new rr.SingleLineText_();
|
|||||||
rr.StartOfLine_ = function() {
|
rr.StartOfLine_ = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
rr.StartOfLine_.prototype.match = function(input, fullInput, inputIndex) {
|
rr.StartOfLine_.prototype.match = function(context) {
|
||||||
if (inputIndex == 0) {
|
if (context.atStart()) {
|
||||||
return [0, null];
|
return [];
|
||||||
}
|
}
|
||||||
if (input[0] == '\n') {
|
if (context.stringAfter(1) == '\n') {
|
||||||
return [1, null];
|
context.advance(1);
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
if (fullInput[inputIndex - 1] == '\n') {
|
if (context.stringBefore(1) == '\n') {
|
||||||
return [0, null];
|
return [];
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
rr.StartOfLine_.prototype.search = function(input, fullInput, inputIndex) {
|
rr.StartOfLine_.prototype.search = function(context) {
|
||||||
if (inputIndex == 0) {
|
if (context.atStart()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
var loc = input.indexOf('\n');
|
var loc = context.stringAfter().indexOf('\n');
|
||||||
if (loc == -1) {
|
if (loc == -1) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -222,20 +229,18 @@ rr.ZeroOrMore_.prototype.minimize = function(parser) {
|
|||||||
return parser.minimize(this.key_);
|
return parser.minimize(this.key_);
|
||||||
};
|
};
|
||||||
|
|
||||||
rr.ZeroOrMore_.prototype.match = function(input, fullInput, inputIndex, parser) {
|
rr.ZeroOrMore_.prototype.match = function(context) {
|
||||||
var ret = document.createElement('group');
|
var ret = [];
|
||||||
var parseIndex = 0;
|
while (context.inputIndex < context.input.length) {
|
||||||
while (parseIndex < input.length - 1) {
|
var result = context.parser.parse(this.key_, context);
|
||||||
var result = parser.parse(this.key_, input.slice(parseIndex));
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
parseIndex += result[0];
|
result.forEach(function(child) {
|
||||||
if (result[1]) {
|
ret.push(child);
|
||||||
ret.appendChild(result[1]);
|
});
|
||||||
}
|
|
||||||
};
|
};
|
||||||
return [parseIndex, ret];
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
rr.ZeroOrMore = function(key) {
|
rr.ZeroOrMore = function(key) {
|
||||||
@@ -245,11 +250,68 @@ rr.ZeroOrMore = function(key) {
|
|||||||
rr.ZeroOrMore.cache = {};
|
rr.ZeroOrMore.cache = {};
|
||||||
|
|
||||||
|
|
||||||
|
rr.Context = function(parser, input, inputIndex) {
|
||||||
|
this.parser = parser;
|
||||||
|
this.input = input;
|
||||||
|
this.inputIndex = inputIndex || 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
rr.Context.prototype.copy = function() {
|
||||||
|
return new rr.Context(this.parser, this.input, this.inputIndex);
|
||||||
|
};
|
||||||
|
|
||||||
|
rr.Context.prototype.truncate = function(numChars) {
|
||||||
|
this.input = this.input.slice(this.inputIndex, this.inputIndex + numChars);
|
||||||
|
};
|
||||||
|
|
||||||
|
rr.Context.prototype.stringAfter = function(numChars) {
|
||||||
|
if (numChars == null) {
|
||||||
|
numChars = this.remaining();
|
||||||
|
}
|
||||||
|
return this.input.slice(this.inputIndex, this.inputIndex + numChars);
|
||||||
|
};
|
||||||
|
|
||||||
|
rr.Context.prototype.stringBefore = function(numChars) {
|
||||||
|
var start = this.inputIndex - numChars;
|
||||||
|
if (start < 0) {
|
||||||
|
numChars += start;
|
||||||
|
start = 0;
|
||||||
|
}
|
||||||
|
return this.input.slice(start, numChars);
|
||||||
|
};
|
||||||
|
|
||||||
|
rr.Context.prototype.atStart = function() {
|
||||||
|
return this.inputIndex == 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
rr.Context.prototype.atEnd = function() {
|
||||||
|
return this.inputIndex == this.input.length;
|
||||||
|
};
|
||||||
|
|
||||||
|
rr.Context.prototype.remaining = function() {
|
||||||
|
return this.input.length - this.inputIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
rr.Context.prototype.advance = function(numChars) {
|
||||||
|
console.log('advance', numChars);
|
||||||
|
this.inputIndex += numChars;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
var RecentRunes = function(dictionary) {
|
var RecentRunes = function(dictionary) {
|
||||||
this.dictionary_ = dictionary;
|
this.dictionary_ = dictionary;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
RecentRunes.prototype.parseString = function(nodeType, input) {
|
||||||
|
var context = new rr.Context(this, input);
|
||||||
|
var ret = this.parse(nodeType, context);
|
||||||
|
if (ret) {
|
||||||
|
return ret[0];
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
RecentRunes.prototype.minimize = function(nodeType) {
|
RecentRunes.prototype.minimize = function(nodeType) {
|
||||||
var rules = this.dictionary_[nodeType];
|
var rules = this.dictionary_[nodeType];
|
||||||
for (var i = 0; i < rules.length; i++) {
|
for (var i = 0; i < rules.length; i++) {
|
||||||
@@ -260,12 +322,14 @@ RecentRunes.prototype.minimize = function(nodeType) {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
RecentRunes.prototype.parse = function(nodeType, input) {
|
RecentRunes.prototype.parse = function(nodeType, origContext) {
|
||||||
|
var context = origContext.copy();
|
||||||
var ret = document.createElement(nodeType);
|
var ret = document.createElement(nodeType);
|
||||||
var rules = this.dictionary_[nodeType];
|
var rules = this.dictionary_[nodeType];
|
||||||
var inputIndex = 0;
|
rules = [];
|
||||||
var lastRuleMinimize = false;
|
var lastRuleMinimize = false;
|
||||||
for (var i = 0; i < rules.length; i++) {
|
for (var i = 0; i < rules.length; i++) {
|
||||||
|
console.log('nodeType:', nodeType, 'rule:', i);
|
||||||
var rule = rules[i];
|
var rule = rules[i];
|
||||||
if (rule.minimize && rule.minimize(this)) {
|
if (rule.minimize && rule.minimize(this)) {
|
||||||
if (lastRuleMinimize) {
|
if (lastRuleMinimize) {
|
||||||
@@ -277,47 +341,54 @@ RecentRunes.prototype.parse = function(nodeType, input) {
|
|||||||
}
|
}
|
||||||
if (lastRuleMinimize) {
|
if (lastRuleMinimize) {
|
||||||
// Check if this rule can find a match in the string
|
// Check if this rule can find a match in the string
|
||||||
var loc = rule.search(input.slice(inputIndex));
|
var loc = rule.search(context);
|
||||||
if (loc == null) {
|
if (loc == null) {
|
||||||
|
console.log('search fail');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the previous rule will match the interim data
|
// Check if the previous rule will match the interim data
|
||||||
var prevMatch = lastRuleMinimize.match(
|
var prevContext = context.copy();
|
||||||
input.slice(inputIndex, inputIndex + loc),
|
prevContext.truncate(loc);
|
||||||
input, inputIndex, this);
|
var prevMatch = lastRuleMinimize.match(prevContext);
|
||||||
if (!prevMatch || prevMatch[0] != loc) {
|
if (!prevMatch) {
|
||||||
|
console.log('prevMatch fail');
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
inputIndex += prevMatch[0];
|
context.advance(prevContext.inputIndex - context.inputIndex);
|
||||||
if (prevMatch[1]) {
|
prevMatch.forEach(function(child) {
|
||||||
ret.appendChild(prevMatch[1]);
|
ret.appendChild(child);
|
||||||
}
|
});
|
||||||
|
|
||||||
lastRuleMinimize = false;
|
lastRuleMinimize = false;
|
||||||
}
|
}
|
||||||
var match = rule.match(
|
console.log(context);
|
||||||
input.slice(inputIndex), input, inputIndex, this);
|
var match = rule.match(context);
|
||||||
if (!match) {
|
if (!match) {
|
||||||
|
console.log('rule fail');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
inputIndex += match[0];
|
match.forEach(function(child) {
|
||||||
if (match[1]) {
|
ret.appendChild(child);
|
||||||
ret.appendChild(match[1]);
|
});
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (lastRuleMinimize) {
|
if (lastRuleMinimize) {
|
||||||
var lastMatch = lastRuleMinimize.match(
|
var prevContext = context.copy();
|
||||||
input.slice(inputIndex), input, inputIndex, this);
|
prevContext.truncate(loc);
|
||||||
|
var lastMatch = lastRuleMinimize.match(prevContext);
|
||||||
if (!lastMatch) {
|
if (!lastMatch) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
inputIndex += lastMatch[0];
|
context.advance(prevContext.inputIndex - context.inputIndex);
|
||||||
if (lastMatch[1]) {
|
lastMatch.forEach(function(child) {
|
||||||
ret.appendChild(lastMatch[1]);
|
ret.appendChild(child);
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return [inputIndex, ret];
|
console.log('nodeType:', nodeType, 'context:', context);
|
||||||
|
|
||||||
|
origContext.advance(context.inputIndex - origContext.inputIndex);
|
||||||
|
|
||||||
|
return [ret];
|
||||||
};
|
};
|
||||||
|
|||||||
9
test.js
9
test.js
@@ -1,11 +1,12 @@
|
|||||||
test('Simple', function() {
|
asyncTest('Simple', function() {
|
||||||
expect(0);
|
// expect(1);
|
||||||
var parser = new RecentRunes(mediawiki);
|
var parser = new RecentRunes(mediawiki);
|
||||||
var result = parser.parse('wikidoc',
|
console.log('foo');
|
||||||
|
var result = parser.parseString('wikidoc',
|
||||||
'=== Heading ===\n\
|
'=== Heading ===\n\
|
||||||
This is a wiki doc.\n\
|
This is a wiki doc.\n\
|
||||||
How about some <b>bold and <i>bold italic</i></b>.\n\
|
How about some <b>bold and <i>bold italic</i></b>.\n\
|
||||||
I would also love some <nowiki>nowiki <b>foo</b></nowiki>');
|
I would also love some <nowiki>nowiki <b>foo</b></nowiki>');
|
||||||
console.log(result);
|
console.log(result);
|
||||||
document.body.appendChild(result[1]);
|
document.body.appendChild(result);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user