Skip to content

Commit

Permalink
got rid of line/column tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
tmont committed Jun 5, 2012
1 parent 47a7e8a commit d2e8c23
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 168 deletions.
83 changes: 11 additions & 72 deletions src/parser.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
function createParseContext(raw, options) {
var index = 0, line = 1, column = 1;
var nextReadIncrementsLine = false;
var index = 0;
var context = {
text: {
value: '',
line: 0,
column: 0
value: ''
},
peek: function(count) {
count = count || 1;
Expand All @@ -16,22 +13,11 @@ function createParseContext(raw, options) {
return '';
}
count = count || 1;
if (nextReadIncrementsLine) {
line++;
column = 0;
nextReadIncrementsLine = false;
}

var next = this.peek(count);
if (next) {
column++;

if (next === '\n') {
nextReadIncrementsLine = true;
}
}

index += count;
if (index > this.length) {
index = this.length;
}
return next;
},
readUntilNonWhitespace: function() {
Expand All @@ -51,14 +37,6 @@ function createParseContext(raw, options) {
},
readRegex: function(regex) {
var value = (regex.exec(this.raw.substring(this.index)) || [''])[0];
var lineBreaks = value.replace(/[^\n]/g, '').length;
line += lineBreaks;
if (lineBreaks) {
column = value.substring(Math.max(value.lastIndexOf('\n'), 0)).length;
} else {
column += value.length;
}

index += value.length;
return value;
},
Expand Down Expand Up @@ -91,12 +69,6 @@ function createParseContext(raw, options) {
context.__defineGetter__('index', function() {
return index;
});
context.__defineGetter__('line', function() {
return line;
});
context.__defineGetter__('column', function() {
return column;
});
context.__defineGetter__('substring', function() {
return this.raw.substring(this.index);
});
Expand All @@ -115,16 +87,8 @@ var regexes = {

regexes.attributeName = regexes.elementName;

function createCallbackContext(context) {
return {
line: context.line,
column: context.column
};
}

function parseOpenElement(context) {
function readAttribute() {
var cbContext = createCallbackContext(context);
var name = context.readRegex(regexes.attributeName);
var value = null;
if (context.current === '=' || context.peekIgnoreWhitespace() === '=') {
Expand All @@ -139,15 +103,11 @@ function parseOpenElement(context) {
context.read(match[0].length);
}

context.callbacks.attribute(name, value, cbContext);
context.callbacks.attribute(name, value);
}

var line = context.line, column = context.column;
var name = context.readRegex(regexes.elementName);
context.callbacks.openElement(name, {
line: line,
column: column
});
context.callbacks.openElement(name);

//read attributes
var next = context.current;
Expand All @@ -166,60 +126,39 @@ function parseOpenElement(context) {
}

function parseEndElement(context) {
var line = context.line, column = context.column;
var name = context.readRegex(regexes.elementName);
context.callbacks.closeElement(name, {
line: line,
column: column
});

context.callbacks.closeElement(name);
context.readRegex(/.*?(?:>|$)/);
}

function parseCData(context) {
var cbContext = createCallbackContext(context);

//we already read the "<"
cbContext.column--;

//read "![CDATA["
context.read(8);

var match = /^([\s\S]*?)(?:$|]]>)/.exec(context.substring);
var value = match[1];
context.read(value.length + match[0].length);
context.callbacks.cdata(value, cbContext);
context.callbacks.cdata(value);
}

function parseComment(context) {
var cbContext = createCallbackContext(context);

//we already read the "<"
cbContext.column--;

//read "!--"
context.read(3);

var match = /^([\s\S]*?)(?:$|-->)/.exec(context.substring);
var value = match[1];
context.read(value.length + match[0].length);
context.callbacks.comment(value, cbContext);
context.callbacks.comment(value);
}

function appendText(value, context) {
if (!context.text.value) {
context.text.line = context.line;
context.text.column = context.column;
}
context.text.value += value;
}

function callbackText(context) {
if (context.text.value) {
context.callbacks.text(context.text.value, createCallbackContext(context.text));
context.callbacks.text(context.text.value);
context.text.value = '';
context.text.line = 0;
context.text.column = 0;
}
}

Expand Down
48 changes: 16 additions & 32 deletions tests/attribute-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,14 @@ describe('attributes', function() {
it('with value, without quotes', function() {
var openCount = 0, attrCount = 0;
helpers.parseString('<foo bar=baz>', {
openElement: function(name, context) {
openElement: function(name) {
name.should.equal('foo');
helpers.verifyContext(1, 2, context);
openCount++;
},

attribute: function(name, value, context) {
attribute: function(name, value) {
name.should.equal('bar');
value.should.equal('baz');
helpers.verifyContext(1, 6, context);
attrCount++;
}
});
Expand All @@ -26,16 +24,14 @@ describe('attributes', function() {
it('with value, with double quotes', function() {
var openCount = 0, attrCount = 0;
helpers.parseString('<foo bar="baz">', {
openElement: function(name, context) {
openElement: function(name) {
name.should.equal('foo');
helpers.verifyContext(1, 2, context);
openCount++;
},

attribute: function(name, value, context) {
attribute: function(name, value) {
name.should.equal('bar');
value.should.equal('baz');
helpers.verifyContext(1, 6, context);
attrCount++;
}
});
Expand All @@ -47,16 +43,14 @@ describe('attributes', function() {
it('with value, with single quotes', function() {
var openCount = 0, attrCount = 0;
helpers.parseString('<foo bar=\'baz\'>', {
openElement: function(name, context) {
openElement: function(name) {
name.should.equal('foo');
helpers.verifyContext(1, 2, context);
openCount++;
},

attribute: function(name, value, context) {
attribute: function(name, value) {
name.should.equal('bar');
value.should.equal('baz');
helpers.verifyContext(1, 6, context);
attrCount++;
}
});
Expand All @@ -68,16 +62,14 @@ describe('attributes', function() {
it('without value', function() {
var openCount = 0, attrCount = 0;
helpers.parseString('<foo bar baz>', {
openElement: function(name, context) {
openElement: function(name) {
name.should.equal('foo');
helpers.verifyContext(1, 2, context);
openCount++;
},

attribute: function(name, value, context) {
attribute: function(name, value) {
name.should.equal(attrCount === 0 ? 'bar' : 'baz');
should.not.exist(value);
helpers.verifyContext(1, (attrCount === 0 ? 6 : 10), context);
attrCount++;
}
});
Expand All @@ -89,16 +81,14 @@ describe('attributes', function() {
it('with value, without quotes should be terminated by line break', function() {
var openCount = 0, attrCount = 0;
helpers.parseString('<foo bar\n>', {
openElement: function(name, context) {
openElement: function(name) {
name.should.equal('foo');
helpers.verifyContext(1, 2, context);
openCount++;
},

attribute: function(name, value, context) {
attribute: function(name, value) {
name.should.equal('bar');
should.not.exist(value);
helpers.verifyContext(1, 6, context);
attrCount++;
}
});
Expand All @@ -110,16 +100,14 @@ describe('attributes', function() {
it('with and without quotes in same element', function() {
var openCount = 0, attrCount = 0;
helpers.parseString('<foo width=0 height="12">', {
openElement: function(name, context) {
openElement: function(name) {
name.should.equal('foo');
helpers.verifyContext(1, 2, context);
openCount++;
},

attribute: function(name, value, context) {
attribute: function(name, value) {
name.should.equal(attrCount === 0 ? 'width' : 'height');
value.should.equal(attrCount === 0 ? '0' : '12');
helpers.verifyContext(1, (attrCount === 0 ? 6 : 13), context);
attrCount++;
}
});
Expand All @@ -131,16 +119,14 @@ describe('attributes', function() {
it('with value and funky whitespace', function() {
var openCount = 0, attrCount = 0;
helpers.parseString('<foo bar = "baz" >', {
openElement: function(name, context) {
openElement: function(name) {
name.should.equal('foo');
helpers.verifyContext(1, 2, context);
openCount++;
},

attribute: function(name, value, context) {
attribute: function(name, value) {
name.should.equal('bar');
value.should.equal('baz');
helpers.verifyContext(1, 6, context);
attrCount++;
}
});
Expand All @@ -152,16 +138,14 @@ describe('attributes', function() {
it('with value on different lines', function() {
var openCount = 0, attrCount = 0;
helpers.parseString('<foo bar \n=\n "baz" >', {
openElement: function(name, context) {
openElement: function(name) {
name.should.equal('foo');
helpers.verifyContext(1, 2, context);
openCount++;
},

attribute: function(name, value, context) {
attribute: function(name, value) {
name.should.equal('bar');
value.should.equal('baz');
helpers.verifyContext(1, 6, context);
attrCount++;
}
});
Expand Down
21 changes: 7 additions & 14 deletions tests/cdata-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ describe('CDATA', function() {
it('inside tags', function() {
var cdataCount = 0;
helpers.parseString('<foo><![CDATA[ this is cdata ]]></foo>', {
cdata: function(value, context) {
cdata: function(value) {
value.should.equal(' this is cdata ');
helpers.verifyContext(1, 6, context);
cdataCount++;
}
});
Expand All @@ -18,9 +17,8 @@ describe('CDATA', function() {
it('does not parse elements or entities', function() {
var cdataCount = 0;
helpers.parseString('<![CDATA[ <foo> &amp; ]]>', {
cdata: function(value, context) {
cdata: function(value) {
value.should.equal(' <foo> &amp; ');
helpers.verifyContext(1, 1, context);
cdataCount++;
}
});
Expand All @@ -31,9 +29,8 @@ describe('CDATA', function() {
it('does not parse as text', function() {
var cdataCount = 0, textCount = 0;
helpers.parseString('<![CDATA[ foo ]]>', {
cdata: function(value, context) {
cdata: function(value) {
value.should.equal(' foo ');
helpers.verifyContext(1, 1, context);
cdataCount++;
},

Expand All @@ -49,9 +46,8 @@ describe('CDATA', function() {
it('respects line breaks', function() {
var cdataCount = 0;
helpers.parseString('<![CDATA[ \nlol ]]>', {
cdata: function(value, context) {
cdata: function(value) {
value.should.equal(' \nlol ');
helpers.verifyContext(1, 1, context);
cdataCount++;
}
});
Expand All @@ -62,9 +58,8 @@ describe('CDATA', function() {
it('reads to end if no ]]> is found', function() {
var cdataCount = 0;
helpers.parseString('<![CDATA[ foobar', {
cdata: function(value, context) {
cdata: function(value) {
value.should.equal(' foobar');
helpers.verifyContext(1, 1, context);
cdataCount++;
}
});
Expand All @@ -75,16 +70,14 @@ describe('CDATA', function() {
it('outputs buffered text node before cdata', function() {
var cdataCount = 0, textCount = 0;
helpers.parseString('foo<![CDATA[bar]]>', {
cdata: function(value, context) {
cdata: function(value) {
textCount.should.equal(1);
value.should.equal('bar');
helpers.verifyContext(1, 4, context);
cdataCount++;
},

text: function(value, context) {
text: function(value) {
value.should.equal('foo');
helpers.verifyContext(1, 1, context);
textCount++;
}
});
Expand Down
Loading

0 comments on commit d2e8c23

Please sign in to comment.