Skip to content

Commit

Permalink
feat: expose position / location / line internal apis
Browse files Browse the repository at this point in the history
  • Loading branch information
DylanPiercey committed Jul 29, 2022
1 parent 18a377a commit 617d33c
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 31 deletions.
5 changes: 5 additions & 0 deletions .changeset/proud-worms-unite.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"htmljs-parser": minor
---

Expose some apis for generating position and location information.
17 changes: 12 additions & 5 deletions src/core/Parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import {
Range,
ParserOptions as Options,
getLines,
getLoc,
getPos,
getLocation,
getPosition,
ErrorCode,
} from "../internal";

Expand Down Expand Up @@ -53,12 +53,19 @@ export class Parser {
return this.data.slice(range.start, range.end);
}

positionAt(index: number) {
return getPos(this.lines || (this.lines = getLines(this.data)), 0, index);
positionAt(offset: number) {
return getPosition(
this.lines || (this.lines = getLines(this.data)),
offset
);
}

locationAt(range: Range) {
return getLoc(this.lines || (this.lines = getLines(this.data)), range);
return getLocation(
this.lines || (this.lines = getLines(this.data)),
range.start,
range.end
);
}

enterState<P extends Meta>(state: StateDefinition<P>): P {
Expand Down
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import { type ParserOptions, type Range, Parser } from "./internal";
export {
TagType,
ErrorCode,
getLines,
getLocation,
getPosition,
type ParserOptions as Handlers,
type Position,
type Location,
Expand Down
72 changes: 46 additions & 26 deletions src/util/util.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CODE, type Parser } from "../internal";
import { ErrorCode, Location, Position, Range } from "./constants";
import { ErrorCode, Location, Position } from "./constants";

export function isWhitespaceCode(code: number) {
// For all practical purposes, the space character (32) and all the
Expand All @@ -9,37 +9,33 @@ export function isWhitespaceCode(code: number) {
return code <= CODE.SPACE;
}

export function getLoc(lines: number[], range: Range): Location {
const start = getPos(lines, 0, range.start);
/**
* Given a source code line offsets, a start offset and an end offset, returns a Location object with line & character information for the start and end offsets.
*/
export function getLocation(
lines: number[],
startOffset: number,
endOffset: number
): Location {
const start = getPosition(lines, startOffset);
const end =
range.start === range.end ? start : getPos(lines, start.line, range.end);
startOffset === endOffset
? start
: getPosAfterLine(lines, start.line, endOffset);
return { start, end };
}

export function getPos(
lines: number[],
startLine: number,
index: number
): Position {
let max = lines.length - 1;
let line = startLine;

while (line < max) {
const mid = (1 + line + max) >>> 1;

if (lines[mid] <= index) {
line = mid;
} else {
max = mid - 1;
}
}

return {
line,
character: index - lines[line],
};
/**
* Given a source code line offsets and an offset, returns a Position object with line & character information.
*/
export function getPosition(lines: number[], offset: number): Position {
return getPosAfterLine(lines, 0, offset);
}

/**
* Scan through some source code and generate an array of offsets for each newline.
* Useful for generating line/column information for source code.
*/
export function getLines(src: string) {
const lines = [0];
for (let i = 0; i < src.length; i++) {
Expand Down Expand Up @@ -71,3 +67,27 @@ export function htmlEOF(this: Parser) {
}
}
}

function getPosAfterLine(
lines: number[],
startLine: number,
index: number
): Position {
let max = lines.length - 1;
let line = startLine;

while (line < max) {
const mid = (1 + line + max) >>> 1;

if (lines[mid] <= index) {
line = mid;
} else {
max = mid - 1;
}
}

return {
line,
character: index - lines[line],
};
}

0 comments on commit 617d33c

Please sign in to comment.