Spaces:
Running
Running
type Position = [number, number]; | |
export default class TextSource { | |
source: string; | |
linePositions: number[]; | |
static matchPositions (regex: RegExp, source: string) { | |
const positions = []; | |
let match; | |
while(match = regex.exec(source)) | |
positions.push(match.index); | |
return positions; | |
} | |
constructor (source) { | |
this.source = source; | |
const newlines = TextSource.matchPositions(/\n/g, source); | |
this.linePositions = [0, ...newlines.map(p => p + 1)]; | |
} | |
slice (lines: number | Position, columns: Position): string { | |
if (!Array.isArray(lines)) | |
lines = [lines, lines]; | |
const start = this.linePositions[lines[0] - 1] + columns[0]; | |
const end = this.linePositions[lines[1] - 1] + columns[1]; | |
return this.source.substr(start, end - start); | |
} | |
charsToPosition (chars: number): Position { | |
let lines = this.linePositions.findIndex(p => p > chars); | |
lines = lines < 0 ? this.linePositions.length : lines; | |
const columns = chars - this.linePositions[lines - 1]; | |
return [lines, columns]; | |
} | |
positionToChars ([lines, columns]: Position): number { | |
if (lines >= this.linePositions.length) | |
return NaN; | |
return this.linePositions[lines - 1] + columns; | |
} | |
}; | |