1 | var util = require("util");
|
2 |
|
3 | var StringSource = module.exports = function(string, description) {
|
4 | var self = {
|
5 | asString: function() {
|
6 | return string;
|
7 | },
|
8 | range: function(startIndex, endIndex) {
|
9 | return new StringSourceRange(string, description, startIndex, endIndex);
|
10 | }
|
11 | };
|
12 | return self;
|
13 | };
|
14 |
|
15 | var StringSourceRange = function(string, description, startIndex, endIndex) {
|
16 | this._string = string;
|
17 | this._description = description;
|
18 | this._startIndex = startIndex;
|
19 | this._endIndex = endIndex;
|
20 | };
|
21 |
|
22 | StringSourceRange.prototype.to = function(otherRange) {
|
23 |
|
24 | return new StringSourceRange(this._string, this._description, this._startIndex, otherRange._endIndex);
|
25 | };
|
26 |
|
27 | StringSourceRange.prototype.describe = function() {
|
28 | var self = this;
|
29 | var index = 0;
|
30 | var nextNewLine = function() {
|
31 | return self._string.indexOf("\n", index);
|
32 | };
|
33 |
|
34 | var lineNumber = 1;
|
35 | while (nextNewLine() !== -1 && nextNewLine() < this._startIndex) {
|
36 | index = nextNewLine() + 1;
|
37 | lineNumber += 1;
|
38 | }
|
39 | var characterNumber = this._startIndex - index + 1;
|
40 | var description = this._description ? this._description + "\n" : "";
|
41 | return util.format("%sLine number: %s\nCharacter number: %s", description, lineNumber, characterNumber);
|
42 | };
|