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(
|
'list-blockquote1': rr.Node('blockquote', rr.Sequence(
|
||||||
rr.StartOfLine(),
|
rr.StartOfLine(),
|
||||||
rr.Literal(': '),
|
rr.Literal(': '),
|
||||||
@@ -290,12 +290,9 @@ var mediawiki = {
|
|||||||
rr.Sequence(rr.EndOfLine(), rr.Literal('\n')),
|
rr.Sequence(rr.EndOfLine(), rr.Literal('\n')),
|
||||||
rr.EndOfText()))),
|
rr.EndOfText()))),
|
||||||
|
|
||||||
'wikidoc': rr.Node('wikidoc', rr.Sequence(
|
'main': rr.Node('wikidoc', rr.Sequence(
|
||||||
rr.ZeroOrMore(rr.Ref('paragraph')),
|
rr.ZeroOrMore(rr.Ref('paragraph')),
|
||||||
rr.EndOfText()))
|
rr.EndOfText()))
|
||||||
};
|
}, {
|
||||||
|
|
||||||
|
|
||||||
var mediawiki_filters = {
|
|
||||||
'bi': rr.SplitTagAndNest('b', 'i')
|
'bi': rr.SplitTagAndNest('b', 'i')
|
||||||
};
|
});
|
||||||
|
|||||||
@@ -4,6 +4,12 @@ var rr = {};
|
|||||||
/* ============ typedefs ============ */
|
/* ============ typedefs ============ */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {function(Node)}
|
||||||
|
*/
|
||||||
|
rr.typeFilter;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {{done: boolean,
|
* @typedef {{done: boolean,
|
||||||
* value: *}}
|
* 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);
|
var hierarchy = Array.prototype.slice.call(arguments);
|
||||||
return function(node) {
|
return function(node) {
|
||||||
var outerNode, innerNode;
|
var outerNode, innerNode;
|
||||||
@@ -744,7 +754,6 @@ rr.SplitTagAndNest = function() {
|
|||||||
/* ============ Scaffolding ============ */
|
/* ============ Scaffolding ============ */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Node} node
|
* @param {Node} node
|
||||||
* @param {Object.<string, rr.typeFilter>} filters
|
* @param {Object.<string, rr.typeFilter>} filters
|
||||||
@@ -766,12 +775,12 @@ rr.ApplyFilters = function(node, filters) {
|
|||||||
*
|
*
|
||||||
* @param {Object.<string, rr.typeMatcher>} rules
|
* @param {Object.<string, rr.typeMatcher>} rules
|
||||||
* @param {string} input
|
* @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.rules = rules;
|
||||||
this.input = input;
|
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;
|
context.inputIndex += numChars;
|
||||||
return context;
|
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>'
|
'</pre></p>'
|
||||||
].join('');
|
].join('');
|
||||||
|
|
||||||
var context = new rr.Context(mediawiki, content);
|
assert.equal(mediawiki.parseFromString(content).innerHTML, expected);
|
||||||
var iterable = context.rules['wikidoc'].match(context);
|
|
||||||
var rootNode = iterable.next().value.nodes[0];
|
|
||||||
rr.ApplyFilters(rootNode, mediawiki_filters);
|
|
||||||
assert.equal(rootNode.innerHTML, expected);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test('singleline-wikichunk', function(assert) {
|
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>'
|
'<h3>Header 3 <i>with italics</i></h3></p>'
|
||||||
].join('');
|
].join('');
|
||||||
|
|
||||||
var context = new rr.Context(mediawiki, content);
|
assert.equal(mediawiki.parseFromString(content).innerHTML, expected);
|
||||||
var iterable = context.rules['wikidoc'].match(context);
|
|
||||||
assert.equal(iterable.next().value.nodes[0].innerHTML, expected);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test('Link', function(assert) {
|
QUnit.test('Link', function(assert) {
|
||||||
@@ -94,9 +88,7 @@ QUnit.test('Link', function(assert) {
|
|||||||
'Test text <i>with formatting</i></a></p>'
|
'Test text <i>with formatting</i></a></p>'
|
||||||
].join('');
|
].join('');
|
||||||
|
|
||||||
var context = new rr.Context(mediawiki, content);
|
assert.equal(mediawiki.parseFromString(content).innerHTML, expected);
|
||||||
var iterable = context.rules['wikidoc'].match(context);
|
|
||||||
assert.equal(iterable.next().value.nodes[0].innerHTML, expected);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test('Image', function(assert) {
|
QUnit.test('Image', function(assert) {
|
||||||
@@ -110,7 +102,5 @@ QUnit.test('Image', function(assert) {
|
|||||||
'<caption>Test image <i>with formatting</i></caption></imgtemp></p>'
|
'<caption>Test image <i>with formatting</i></caption></imgtemp></p>'
|
||||||
].join('');
|
].join('');
|
||||||
|
|
||||||
var context = new rr.Context(mediawiki, content);
|
assert.equal(mediawiki.parseFromString(content).innerHTML, expected);
|
||||||
var iterable = context.rules['wikidoc'].match(context);
|
|
||||||
assert.equal(iterable.next().value.nodes[0].innerHTML, expected);
|
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user