Create a Parser object that can package up rules and filters.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
var mediawiki = {
|
||||
var mediawiki = rr.Parser({
|
||||
'list-blockquote1': rr.Node('blockquote', rr.Sequence(
|
||||
rr.StartOfLine(),
|
||||
rr.Literal(': '),
|
||||
@@ -290,12 +290,9 @@ var mediawiki = {
|
||||
rr.Sequence(rr.EndOfLine(), rr.Literal('\n')),
|
||||
rr.EndOfText()))),
|
||||
|
||||
'wikidoc': rr.Node('wikidoc', rr.Sequence(
|
||||
'main': rr.Node('wikidoc', rr.Sequence(
|
||||
rr.ZeroOrMore(rr.Ref('paragraph')),
|
||||
rr.EndOfText()))
|
||||
};
|
||||
|
||||
|
||||
var mediawiki_filters = {
|
||||
}, {
|
||||
'bi': rr.SplitTagAndNest('b', 'i')
|
||||
};
|
||||
});
|
||||
|
||||
@@ -4,6 +4,12 @@ var rr = {};
|
||||
/* ============ typedefs ============ */
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {function(Node)}
|
||||
*/
|
||||
rr.typeFilter;
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{done: boolean,
|
||||
* value: *}}
|
||||
@@ -716,10 +722,14 @@ rr.SingleLineText = function() {
|
||||
|
||||
|
||||
|
||||
/* ============ Filters ============ */
|
||||
/* ============ Filter factories ============ */
|
||||
|
||||
|
||||
rr.SplitTagAndNest = function() {
|
||||
/**
|
||||
* @param {...string} var_args
|
||||
* @return {rr.typeFilter}
|
||||
*/
|
||||
rr.SplitTagAndNest = function(var_args) {
|
||||
var hierarchy = Array.prototype.slice.call(arguments);
|
||||
return function(node) {
|
||||
var outerNode, innerNode;
|
||||
@@ -744,7 +754,6 @@ rr.SplitTagAndNest = function() {
|
||||
/* ============ Scaffolding ============ */
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @param {Object.<string, rr.typeFilter>} filters
|
||||
@@ -766,12 +775,12 @@ rr.ApplyFilters = function(node, filters) {
|
||||
*
|
||||
* @param {Object.<string, rr.typeMatcher>} rules
|
||||
* @param {string} input
|
||||
* @param {number} inputIndex
|
||||
* @param {number=} opt_inputIndex
|
||||
*/
|
||||
rr.Context = function(rules, input, inputIndex) {
|
||||
rr.Context = function(rules, input, opt_inputIndex) {
|
||||
this.rules = rules;
|
||||
this.input = input;
|
||||
this.inputIndex = inputIndex || 0;
|
||||
this.inputIndex = opt_inputIndex || 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -845,3 +854,44 @@ rr.Context.prototype.advance = function(numChars) {
|
||||
context.inputIndex += numChars;
|
||||
return context;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @param {Object.<string, rr.typeMatcher>} rules
|
||||
* @param {Object.<string, rr.typeFilter>} filters
|
||||
* @private
|
||||
*/
|
||||
rr.Parser_ = function(rules, filters) {
|
||||
this.rules_ = rules;
|
||||
this.filters_ = filters;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @return {?Node}
|
||||
*/
|
||||
rr.Parser_.prototype.parseFromString = function(input) {
|
||||
var context = new rr.Context(this.rules_, input);
|
||||
var iterable = context.rules['main'].match(context);
|
||||
var next = iterable.next();
|
||||
if (next['done']) {
|
||||
return null;
|
||||
}
|
||||
var rootNode = next['value']['nodes'][0];
|
||||
rr.ApplyFilters(rootNode, this.filters_);
|
||||
return rootNode;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Object.<string, rr.typeMatcher>} rules
|
||||
* @param {Object.<string, rr.typeFilter>} filters
|
||||
* @return {rr.Parser_}
|
||||
*/
|
||||
rr.Parser = function(rules, filters) {
|
||||
return new rr.Parser_(rules, filters);
|
||||
};
|
||||
|
||||
18
test.js
18
test.js
@@ -59,11 +59,7 @@ QUnit.test('Base', function(assert) {
|
||||
'</pre></p>'
|
||||
].join('');
|
||||
|
||||
var context = new rr.Context(mediawiki, content);
|
||||
var iterable = context.rules['wikidoc'].match(context);
|
||||
var rootNode = iterable.next().value.nodes[0];
|
||||
rr.ApplyFilters(rootNode, mediawiki_filters);
|
||||
assert.equal(rootNode.innerHTML, expected);
|
||||
assert.equal(mediawiki.parseFromString(content).innerHTML, expected);
|
||||
});
|
||||
|
||||
QUnit.test('singleline-wikichunk', function(assert) {
|
||||
@@ -78,9 +74,7 @@ QUnit.test('singleline-wikichunk', function(assert) {
|
||||
'<h3>Header 3 <i>with italics</i></h3></p>'
|
||||
].join('');
|
||||
|
||||
var context = new rr.Context(mediawiki, content);
|
||||
var iterable = context.rules['wikidoc'].match(context);
|
||||
assert.equal(iterable.next().value.nodes[0].innerHTML, expected);
|
||||
assert.equal(mediawiki.parseFromString(content).innerHTML, expected);
|
||||
});
|
||||
|
||||
QUnit.test('Link', function(assert) {
|
||||
@@ -94,9 +88,7 @@ QUnit.test('Link', function(assert) {
|
||||
'Test text <i>with formatting</i></a></p>'
|
||||
].join('');
|
||||
|
||||
var context = new rr.Context(mediawiki, content);
|
||||
var iterable = context.rules['wikidoc'].match(context);
|
||||
assert.equal(iterable.next().value.nodes[0].innerHTML, expected);
|
||||
assert.equal(mediawiki.parseFromString(content).innerHTML, expected);
|
||||
});
|
||||
|
||||
QUnit.test('Image', function(assert) {
|
||||
@@ -110,7 +102,5 @@ QUnit.test('Image', function(assert) {
|
||||
'<caption>Test image <i>with formatting</i></caption></imgtemp></p>'
|
||||
].join('');
|
||||
|
||||
var context = new rr.Context(mediawiki, content);
|
||||
var iterable = context.rules['wikidoc'].match(context);
|
||||
assert.equal(iterable.next().value.nodes[0].innerHTML, expected);
|
||||
assert.equal(mediawiki.parseFromString(content).innerHTML, expected);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user