Skip to content

Commit

Permalink
Use ware to support async parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
blakeembrey committed Sep 17, 2014
1 parent 9d98c9f commit 27dbfd7
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 100 deletions.
3 changes: 2 additions & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
"license": "MIT",
"dependencies": {
"parse-latin": "^0.1.0-rc.6",
"textom": "^0.1.0-rc.3"
"textom": "^0.1.0-rc.3",
"ware": "[email protected]:segmentio/ware.git#1.0.1"
},
"main": "index.js",
"ignore": [
Expand Down
1 change: 1 addition & 0 deletions component.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"textom"
],
"dependencies": {
"segmentio/ware": "^1.0.1",
"wooorm/parse-latin": "^0.1.0-rc.6",
"wooorm/textom": "^0.1.0-rc.3"
},
Expand Down
52 changes: 15 additions & 37 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
'use strict';

var TextOMConstructor = require('textom'),
ParseLatin = require('parse-latin');
ParseLatin = require('parse-latin'),
Ware = require('ware');

function fromAST(TextOM, ast) {
var iterator = -1,
Expand Down Expand Up @@ -34,21 +35,6 @@ function fromAST(TextOM, ast) {
return node;
}

function useImmediately(rootNode, use) {
return function (plugin) {
var self = this,
length = self.plugins.length;

use.apply(self, arguments);

if (length !== self.plugins.length) {
plugin(rootNode, self);
}

return self;
};
}

/**
* Define `Retext`. Exported above, and used to instantiate a new
* `Retext`.
Expand All @@ -64,10 +50,10 @@ function Retext(parser) {
parser = new ParseLatin();
}

self.ware = new Ware();
self.parser = parser;
self.TextOM = parser.TextOM = new TextOMConstructor();
self.TextOM.parser = parser;
self.plugins = [];
}

/**
Expand All @@ -94,14 +80,14 @@ Retext.prototype.use = function (plugin) {
}

var self = this,
plugins = self.plugins;
ware = self.ware;

if (plugins.indexOf(plugin) === -1) {
if (ware.fns.indexOf(plugin) === -1) {
if (plugin.attach) {
plugin.attach(self);
}

plugins.push(plugin);
ware.use(plugin);
}

return self;
Expand All @@ -113,16 +99,15 @@ Retext.prototype.use = function (plugin) {
* TextOM tree created by the parser.
*
* @param {String?} source - The source to convert.
* @return {Node} - A RootNode containing the tokenised source.
* @param {Function<Error, Node>} done - Callback with a RootNode containing
* the tokenized source.
* @public
*/
Retext.prototype.parse = function (source) {
Retext.prototype.parse = function (source, done) {
var self = this,
rootNode = fromAST(self.TextOM, self.parser.tokenizeRoot(source));

self.applyPlugins(rootNode);

return rootNode;
self.applyPlugins(rootNode, done);
};

/**
Expand All @@ -134,21 +119,14 @@ Retext.prototype.parse = function (source) {
* on with its parent plugin.
*
* @param {Node} tree - The tree to apply plugins to.
* @param {Function<Error, Node>} done - Callback with the result of
* parsing the tree.
* @public
*/
Retext.prototype.applyPlugins = function (tree) {
var self = this,
plugins = self.plugins.concat(),
iterator = -1,
use = self.use;

self.use = useImmediately(tree, use);

while (plugins[++iterator]) {
plugins[iterator](tree, this);
}
Retext.prototype.applyPlugins = function (tree, done) {
var self = this;

self.use = use;
self.ware.run(tree, self, done);
};

/**
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"license": "MIT",
"dependencies": {
"parse-latin": "^0.1.0-rc.6",
"textom": "^0.1.0-rc.3"
"textom": "^0.1.0-rc.3",
"ware": "^1.0.1"
},
"devDependencies": {
"eslint": "^0.8.0",
Expand Down
111 changes: 50 additions & 61 deletions spec/retext.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,24 +34,19 @@ describe('Retext()', function () {
);

it('should create a new context/parser/textom when required, thus ' +
'not requiring from memory', function () {
var rootNode1 = new Retext().parse(),
rootNode2 = new Retext().parse();

assert(rootNode1 instanceof rootNode1.constructor);
assert(!(rootNode1 instanceof rootNode2.constructor));
assert(rootNode2 instanceof rootNode2.constructor);
assert(!(rootNode2 instanceof rootNode1.constructor));
'not requiring from memory', function (done) {
new Retext().parse(null, function (err, rootNode1) {
new Retext().parse(null, function (err, rootNode2) {
assert(rootNode1 instanceof rootNode1.constructor);
assert(!(rootNode1 instanceof rootNode2.constructor));
assert(rootNode2 instanceof rootNode2.constructor);
assert(!(rootNode2 instanceof rootNode1.constructor));

done(err);
});
});
}
);

it('should set the `plugins` attribute to an empty array', function () {
var retext = new Retext();
assert('plugins' in retext);
assert(retext.plugins instanceof Array);
assert(retext.hasOwnProperty('plugins'));
assert(retext.plugins.length === 0);
});
});

describe('Retext#use', function () {
Expand Down Expand Up @@ -93,17 +88,17 @@ describe('Retext#use', function () {

it('should attach `use`d plugins', function () {
var retext = new Retext();
assert(retext.plugins.length === 0);
assert(retext.ware.fns.length === 0);
retext.use(noop);
assert(retext.plugins.length === 1);
assert(retext.ware.fns.length === 1);
});

it('should not attach `use`d plugins multiple times', function () {
var retext = new Retext();
retext.use(noop);
assert(retext.plugins.length === 1);
assert(retext.ware.fns.length === 1);
retext.use(noop);
assert(retext.plugins.length === 1);
assert(retext.ware.fns.length === 1);
});
});

Expand All @@ -113,9 +108,14 @@ describe('Retext#parse', function () {
assert(typeof (new Retext()).parse === 'function');
});

it('should return an instance of RootNode', function () {
it('should return an instance of RootNode', function (done) {
var retext = new Retext();
assert(retext.parse() instanceof retext.parser.TextOM.RootNode);

retext.parse(null, function (err, rootNode) {
assert(rootNode instanceof retext.parser.TextOM.RootNode);

done(err);
});
});

it('should immediately call the `attach` method on a plugin, when ' +
Expand All @@ -137,7 +137,7 @@ describe('Retext#parse', function () {
);

it('should not call the `attach` method, when `parse` is called',
function () {
function (done) {
var retext = new Retext(),
isCalled = false;

Expand All @@ -151,13 +151,15 @@ describe('Retext#parse', function () {

isCalled = false;

retext.parse();
retext.parse(null, function (err) {
assert(isCalled === false);

assert(isCalled === false);
done(err);
});
}
);

it('should call `use`d plugins, when `parse` is called', function () {
it('should call `use`d plugins, when `parse` is called', function (done) {
var retext = new Retext(),
isCalled = false;

Expand All @@ -169,72 +171,59 @@ describe('Retext#parse', function () {

assert(isCalled === false);

retext.parse();
retext.parse(null, function (err) {
assert(isCalled === true);

assert(isCalled === true);
done(err);
});
});

it('should call `use`d plugins with an instance of RootNode and ' +
'Retext, when `parse` is called', function () {
'Retext, when `parse` is called', function (done) {
var retext = new Retext(),
args = null,
tree;
args;

function plugin () {
args = arguments;
}

retext.use(plugin);

tree = retext.parse();

assert(args[0] === tree);
assert(args[1] === retext);
}
);

it('should immediately call (during parsing) `use`d plugins, with ' +
'an instance of RootNode and Retext', function () {
var retext = new Retext(),
args = null;

function nestedPlugin () {
args = arguments;
}

function plugin (tree, retext) {
retext.use(nestedPlugin);
retext.parse(null, function (err, tree) {
assert(args[0] === tree);
assert(args[1] === retext);
}
assert(args.length === 2);

retext.use(plugin).parse();
done(err);
});
}
);

it('should not call (during parsing) `use`d plugins, when already used',
function () {
function (done) {
var retext = new Retext();

function nestedPlugin () {}

function plugin (tree, retext) {
var length = retext.plugins.length;
var length = retext.ware.fns.length;
retext.use(nestedPlugin);
assert(length === retext.plugins.length);
assert(length === retext.ware.fns.length);
}

retext.use(nestedPlugin).use(plugin).parse();
retext.use(nestedPlugin).use(plugin).parse(null, done);
}
);

it('should parse something into a Text Object Model', function () {
var root = new Retext().parse('Something something');
it('should parse something into a Text Object Model', function (done) {
new Retext().parse('Something something', function (err, root) {
assert('head' in root);
assert('tail' in root);
assert(root.head.parent === root);
assert('TextOM' in root);

assert('head' in root);
assert('tail' in root);
assert(root.head.parent === root);
assert('TextOM' in root);
done(err);
});
});
});

Expand Down

0 comments on commit 27dbfd7

Please sign in to comment.