Skip to content

Commit

Permalink
Moved parsing into its own file.
Browse files Browse the repository at this point in the history
  • Loading branch information
nufyoot committed May 16, 2013
1 parent 0888fe9 commit a07499e
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 21 deletions.
30 changes: 9 additions & 21 deletions lib/main.js
@@ -1,4 +1,6 @@
var fs = require('fs');
var Parser = require('./parser.js');
var parser = Parser();

module.exports = function(config) {
config = config || {
Expand Down Expand Up @@ -44,30 +46,16 @@ module.exports = function(config) {
},

parse: function(contents) {
var tokens = parser.parseRazorContents(contents);
var result = '(function() { return { render: function(model) { var r = "";';
var i = 0;

while(i < contents.length) {
var nextToken = contents.indexOf('@', i);

if (nextToken == -1) {
var temp = contents.substr(i, contents.length - i).replace(/\"/gm, '\\"').replace(/\n/gm, '\\n');
if (temp) result += 'r+="' + temp + '";';
i = contents.length;
} else {
var temp = contents.substr(i, nextToken - i).replace(/\"/gm, '\\"').replace(/\n/gm, '\\n');
for (var i = 0; i < tokens.length; i++) {
var token = tokens[i];
if (token.type == 'string') {
var temp = token.contents.replace(/\"/gm, '\\"').replace(/\n/gm, '\\n');
if (temp) result += 'r+="' + temp + '";';
i = nextToken;

var token = '';
while (++i < contents.length) {
if (contents[i].match(/[A-Za-z\.]/)) {
token += contents[i];
} else {
break;
}
}
result += 'r+=' + token + ';';
} else if (token.type == 'razor') {
result += 'r+=' + token.token + ';';
}
}

Expand Down
71 changes: 71 additions & 0 deletions lib/parser.js
@@ -0,0 +1,71 @@
module.exports = function(config) {
return {
parseRazorContents: function(contents) {
var tokens = [];
var loopIterator = {
contents: contents,
pos: -1,
next: function() {
return ++this.pos < this.contents.length;
},
currentChar: function() {
return this.contents[this.pos];
}
}

var start = 0;
while (loopIterator.next()) {
if (loopIterator.currentChar() == '@') {
// If we have any content, let's add that to "tokens" first.
if (start != loopIterator.pos) {
tokens.push(this.createStringToken(loopIterator.contents.substr(start, loopIterator.pos - start)));
}

tokens.push(this.parseRazorToken(loopIterator));
start = loopIterator.pos;
}
}

// Add the content after the last token.
if (start != loopIterator.pos) {
tokens.push(this.createStringToken(loopIterator.contents.substr(start, loopIterator.pos - start)));
}

return tokens;
},

parseRazorToken: function(loopIterator) {
if (loopIterator.currentChar() != '@') {
throw new Error('The first character for a Razor token must be the @ symbol.');
}

var start = loopIterator.pos + 1;
while (loopIterator.next()) {
if (!loopIterator.currentChar().match(/[A-Za-z\.\@]/)) {
break;
}
}

var token = loopIterator.contents.substr(start, loopIterator.pos - start);
if (token == '@') {
return this.createStringToken('@');
} else {
return this.createRazorToken(token);
}
},

createStringToken: function(contents) {
return {
type: 'string',
contents: contents
};
},

createRazorToken: function(token) {
return {
type: 'razor',
token: token
}
}
};
}
18 changes: 18 additions & 0 deletions test/main.js
@@ -1,11 +1,13 @@
var libPath = process.env['KALLY_RAZOR_COV'] ? '../lib-cov/' : '../lib/';
var chai = require('chai');
var KallyRazor = require(libPath + 'main');
var Parser = require(libPath + 'parser');
var fs = require('fs');

var razor = KallyRazor({
root: __dirname
});
var parser = Parser();

var should = chai.should();

Expand All @@ -26,6 +28,10 @@ describe('KallyRazor', function() {
it('when a null file name is passed', function() {
should.Throw(function() { razor.renderFromFile(); });
});

it('when a razor token doesnt start with @', function() {
should.Throw(function() { parser.parseRazorToken({ currentChar: function() { return 't'; } }); });
});
});

describe('compiles', function() {
Expand Down Expand Up @@ -53,4 +59,16 @@ describe('KallyRazor', function() {
})
});
});

describe('parses', function() {
it('double @@', function() {
var result = parser.parseRazorToken({
contents: '@@',
pos: 0,
currentChar: function() { return this.contents[this.pos]; },
next: function() { return ++this.pos < this.contents.length; }
});
result.contents.should.equal('@');
});
});
});

0 comments on commit a07499e

Please sign in to comment.