Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/floppy-shirts-beg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"htmljs-parser": minor
---

When parsing statements, consume any indented content without errors.
5,779 changes: 3,042 additions & 2,737 deletions package-lock.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,13 @@
4╭─
╰─ ╰─ openTagEnd
5╭─ import mod, { b as bar } from "./bar"
│ │ ╰─ openTagEnd
╰─ ╰─ tagName "import"
╰─ ╰─ tagName "import"
6╭─ export interface Input
│ ├─ openTagEnd
╰─ ╰─ tagName "export"
7├─ extends Pick<StarRatingInput, "value" | "a11y-text">,
8├─ Link,
9├─ BaseInput {
10├─ reviewCount: number;
11╭─ }
╰─ ╰─ openTagEnd
8 changes: 7 additions & 1 deletion src/__tests__/fixtures/commas-relax/input.marko
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,10 @@ static const x = {
hello: true
};

import mod, { b as bar } from "./bar"
import mod, { b as bar } from "./bar"
export interface Input
extends Pick<StarRatingInput, "value" | "a11y-text">,
Link,
BaseInput {
reviewCount: number;
}
28 changes: 14 additions & 14 deletions src/core/Parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,20 @@ export interface StateDefinition<P extends Meta = Meta> {
}

export class Parser {
public declare pos: number;
public declare maxPos: number;
public declare data: string;
public declare activeState: StateDefinition;
public declare activeRange: Meta;
public declare forward: number;
public declare activeTag: STATE.OpenTagMeta | undefined; // Used to reference the closest open tag
public declare activeAttr: STATE.AttrMeta | undefined; // Used to reference the current attribute that is being parsed
public declare indent: string; // Used to build the indent for the current concise line
public declare isConcise: boolean; // Set to true if parser is currently in concise mode
public declare beginMixedMode?: boolean; // Used as a flag to mark that the next HTML block should enter the parser into HTML mode
public declare endingMixedModeAtEOL?: boolean; // Used as a flag to record that the next EOL to exit HTML mode and go back to concise
public declare textPos: number; // Used to buffer text that is found within the body of a tag
public declare lines: undefined | number[]; // Keeps track of line indexes to provide line/column info.
declare public pos: number;
declare public maxPos: number;
declare public data: string;
declare public activeState: StateDefinition;
declare public activeRange: Meta;
declare public forward: number;
declare public activeTag: STATE.OpenTagMeta | undefined; // Used to reference the closest open tag
declare public activeAttr: STATE.AttrMeta | undefined; // Used to reference the current attribute that is being parsed
declare public indent: string; // Used to build the indent for the current concise line
declare public isConcise: boolean; // Set to true if parser is currently in concise mode
declare public beginMixedMode?: boolean; // Used as a flag to mark that the next HTML block should enter the parser into HTML mode
declare public endingMixedModeAtEOL?: boolean; // Used as a flag to record that the next EOL to exit HTML mode and go back to concise
declare public textPos: number; // Used to buffer text that is found within the body of a tag
declare public lines: undefined | number[]; // Keeps track of line indexes to provide line/column info.

constructor(public options: Options) {}

Expand Down
15 changes: 9 additions & 6 deletions src/states/EXPRESSION.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
Parser,
type Meta,
ErrorCode,
isIndentCode,
} from "../internal";

export interface ExpressionMeta extends Meta {
Expand All @@ -14,6 +15,7 @@ export interface ExpressionMeta extends Meta {
wasComment: boolean;
terminatedByEOL: boolean;
terminatedByWhitespace: boolean;
consumeIndentedContent: boolean;
shouldTerminate(code: number, data: string, pos: number): boolean;
}

Expand Down Expand Up @@ -54,6 +56,7 @@ export const EXPRESSION: StateDefinition<ExpressionMeta> = {
wasComment: false,
terminatedByEOL: false,
terminatedByWhitespace: false,
consumeIndentedContent: false,
};
},

Expand Down Expand Up @@ -163,11 +166,15 @@ export const EXPRESSION: StateDefinition<ExpressionMeta> = {
}
},

eol(_, expression) {
eol(len, expression) {
if (
!expression.groupStack.length &&
(expression.terminatedByEOL || expression.terminatedByWhitespace) &&
(expression.wasComment || !checkForOperators(this, expression, true))
(expression.wasComment || !checkForOperators(this, expression, true)) &&
!(
expression.consumeIndentedContent &&
isIndentCode(this.lookAtCharCodeAhead(len + 1))
)
) {
this.exitState();
}
Expand Down Expand Up @@ -430,10 +437,6 @@ function isWordCode(code: number) {
);
}

function isIndentCode(code: number) {
return code === CODE.TAB || code === CODE.SPACE;
}

function lookAheadWhile(
match: (code: number) => boolean,
data: string,
Expand Down
4 changes: 2 additions & 2 deletions src/states/OPEN_TAG.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
matchesPipe,
matchesCloseParen,
matchesCloseAngleBracket,
isIndentCode,
} from "../internal";

export enum TAG_STAGE {
Expand Down Expand Up @@ -207,8 +208,7 @@ export const OPEN_TAG: StateDefinition<OpenTagMeta> = {

// Count how many spaces/tabs we have after the newline.
while (curPos < maxPos) {
const nextCode = this.data.charCodeAt(curPos);
if (nextCode === CODE.SPACE || nextCode === CODE.TAB) {
if (isIndentCode(this.data.charCodeAt(curPos))) {
curPos++;
} else {
break;
Expand Down
1 change: 1 addition & 0 deletions src/states/TAG_NAME.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ export const TAG_NAME: StateDefinition<TagNameMeta> = {
const expr = this.enterState(STATE.EXPRESSION);
expr.operators = true;
expr.terminatedByEOL = true;
expr.consumeIndentedContent = true;
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/util/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ export function isWhitespaceCode(code: number) {
return code <= CODE.SPACE;
}

export function isIndentCode(code: number) {
return code === CODE.TAB || code === CODE.SPACE;
}

/**
* 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.
*/
Expand Down