Skip to content

Commit bafe713

Browse files
committed
fix: allow indented content within statement tags
1 parent 96b14d6 commit bafe713

File tree

9 files changed

+3094
-2762
lines changed

9 files changed

+3094
-2762
lines changed

.changeset/floppy-shirts-beg.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"htmljs-parser": minor
3+
---
4+
5+
When parsing statements, consume any indented content without errors.

package-lock.json

Lines changed: 3042 additions & 2737 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/__tests__/fixtures/commas-relax/__snapshots__/commas-relax.expected.txt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,13 @@
55
4╭─
66
╰─ ╰─ openTagEnd
77
5╭─ import mod, { b as bar } from "./bar"
8-
│ │ ╰─ openTagEnd
9-
╰─ ╰─ tagName "import"
8+
╰─ ╰─ tagName "import"
9+
6╭─ export interface Input
10+
│ ├─ openTagEnd
11+
╰─ ╰─ tagName "export"
12+
7├─ extends Pick<StarRatingInput, "value" | "a11y-text">,
13+
8├─ Link,
14+
9├─ BaseInput {
15+
10├─ reviewCount: number;
16+
11╭─ }
17+
╰─ ╰─ openTagEnd

src/__tests__/fixtures/commas-relax/input.marko

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,10 @@ static const x = {
22
hello: true
33
};
44

5-
import mod, { b as bar } from "./bar"
5+
import mod, { b as bar } from "./bar"
6+
export interface Input
7+
extends Pick<StarRatingInput, "value" | "a11y-text">,
8+
Link,
9+
BaseInput {
10+
reviewCount: number;
11+
}

src/core/Parser.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,20 @@ export interface StateDefinition<P extends Meta = Meta> {
3030
}
3131

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

4848
constructor(public options: Options) {}
4949

src/states/EXPRESSION.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
Parser,
77
type Meta,
88
ErrorCode,
9+
isIndentCode,
910
} from "../internal";
1011

1112
export interface ExpressionMeta extends Meta {
@@ -14,6 +15,7 @@ export interface ExpressionMeta extends Meta {
1415
wasComment: boolean;
1516
terminatedByEOL: boolean;
1617
terminatedByWhitespace: boolean;
18+
consumeIndentedContent: boolean;
1719
shouldTerminate(code: number, data: string, pos: number): boolean;
1820
}
1921

@@ -54,6 +56,7 @@ export const EXPRESSION: StateDefinition<ExpressionMeta> = {
5456
wasComment: false,
5557
terminatedByEOL: false,
5658
terminatedByWhitespace: false,
59+
consumeIndentedContent: false,
5760
};
5861
},
5962

@@ -163,11 +166,15 @@ export const EXPRESSION: StateDefinition<ExpressionMeta> = {
163166
}
164167
},
165168

166-
eol(_, expression) {
169+
eol(len, expression) {
167170
if (
168171
!expression.groupStack.length &&
169172
(expression.terminatedByEOL || expression.terminatedByWhitespace) &&
170-
(expression.wasComment || !checkForOperators(this, expression, true))
173+
(expression.wasComment || !checkForOperators(this, expression, true)) &&
174+
!(
175+
expression.consumeIndentedContent &&
176+
isIndentCode(this.lookAtCharCodeAhead(len + 1))
177+
)
171178
) {
172179
this.exitState();
173180
}
@@ -430,10 +437,6 @@ function isWordCode(code: number) {
430437
);
431438
}
432439

433-
function isIndentCode(code: number) {
434-
return code === CODE.TAB || code === CODE.SPACE;
435-
}
436-
437440
function lookAheadWhile(
438441
match: (code: number) => boolean,
439442
data: string,

src/states/OPEN_TAG.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
matchesPipe,
1111
matchesCloseParen,
1212
matchesCloseAngleBracket,
13+
isIndentCode,
1314
} from "../internal";
1415

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

208209
// Count how many spaces/tabs we have after the newline.
209210
while (curPos < maxPos) {
210-
const nextCode = this.data.charCodeAt(curPos);
211-
if (nextCode === CODE.SPACE || nextCode === CODE.TAB) {
211+
if (isIndentCode(this.data.charCodeAt(curPos))) {
212212
curPos++;
213213
} else {
214214
break;

src/states/TAG_NAME.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ export const TAG_NAME: StateDefinition<TagNameMeta> = {
9999
const expr = this.enterState(STATE.EXPRESSION);
100100
expr.operators = true;
101101
expr.terminatedByEOL = true;
102+
expr.consumeIndentedContent = true;
102103
}
103104
}
104105

src/util/util.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ export function isWhitespaceCode(code: number) {
99
return code <= CODE.SPACE;
1010
}
1111

12+
export function isIndentCode(code: number) {
13+
return code === CODE.TAB || code === CODE.SPACE;
14+
}
15+
1216
/**
1317
* 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.
1418
*/

0 commit comments

Comments
 (0)