Added handling of comments inside html parser
MODIFY
packages/@romefrontend/formatter/builders/common/comments/CommentBlock.ts
packages/@romefrontend/formatter/builders/common/comments/CommentBlock.ts
* LICENSE file in the root directory of this source tree.
*/
-import {Token} from "@romefrontend/formatter";
+import {Builder, Token, concat} from "@romefrontend/formatter";
+import {AnyComment} from "@romefrontend/ast";
-export default function CommentBlock(): Token {
- throw new Error("unimplemented");
+export default function CommentBlock(builder: Builder, node: AnyComment): Token {
+ // TODO to review this part
+ return concat(["<!-- ", node.value, " -->"]);
}

MODIFY
packages/@romefrontend/html-parser/index.ts
packages/@romefrontend/html-parser/index.ts
@@ -22,6 +22,7 @@ import {Number0, ob1Add, ob1Get0, ob1Inc} from "@romefrontend/ob1";
import {isEscaped} from "@romefrontend/string-utils";
import {isSelfClosingTagName} from "./tags";
import {descriptions} from "@romefrontend/diagnostics";
+import {consumeComment} from "@romefrontend/html-parser/utils.ts";
type Tokens = BaseTokens & {
Text: ValueToken<"Text", string>;
@@ -31,6 +32,7 @@ type Tokens = BaseTokens & {
Greater: SimpleToken<"Greater">;
Identifier: ValueToken<"Identifier", string>;
String: ValueToken<"String", string>;
+ Comment: ValueToken<"Comment", string>;
};
type State = ParserCoreState & {
@@ -58,6 +60,14 @@ function isTextChar(char: string, index: Number0, input: string): boolean {
return !isTagStartChar(index, input);
}
+function isTagComment(index: Number0, input: string): boolean {
+ const first = input[ob1Get0(index)];
+ const second = input[ob1Get0(index) + 1];
+ const third = input[ob1Get0(index) + 2];
+ const fourth = input[ob1Get0(index) + 3];
+ return first === "<" && second === "!" && third === "-" && fourth === "-";
+}
+
const createHTMLParser = createParser((ParserCore, ParserWithRequiredPath) =>
class HTMLParser extends ParserWithRequiredPath<Tokens, State> {
constructor(opts: ParserOptionsWithRequiredPath) {
@@ -138,6 +148,18 @@ const createHTMLParser = createParser((ParserCore, ParserWithRequiredPath) =>
}
}
+ if (isTagComment(index, this.input)) {
+ const startingIndex = ob1Add(index, 2);
+ const [endIndex, value] = consumeComment(startingIndex, this.input);
+ return {
+ state: {
+ ...state,
+ inTagHead: false,
+ },
+ token: this.finishValueToken("Comment", value, endIndex),
+ };
+ }
+
if (isTagStartChar(index, this.input)) {
return {
state: {
@@ -204,12 +226,20 @@ const createHTMLParser = createParser((ParserCore, ParserWithRequiredPath) =>
return this.matchToken("Less") && this.lookahead().token.type === "Slash";
}
+ atComment(): boolean {
+ return this.lookahead().token.type === "Comment";
+ }
+
parseTag(): HTMLElement {
const headStart = this.getPosition();
+ if (this.atComment()) {
+ this.parseComment();
+ }
this.expectToken("Less");
const attributes: HTMLElement["attributes"] = [];
const children: HTMLElement["children"] = [];
+
const name = this.parseIdentifier();
const tagName = name.name;
let selfClosing = isSelfClosingTagName(tagName);
@@ -291,6 +321,18 @@ const createHTMLParser = createParser((ParserCore, ParserWithRequiredPath) =>
);
}
+ parseComment(): undefined {
+ const start = this.getPosition();
+ const token = this.expectToken("Comment");
+
+ this.comments.addComment({
+ value: token.value,
+ type: "CommentBlock",
+ loc: this.finishLoc(start),
+ });
+ return undefined;
+ }
+
parseText(): HTMLText {
const start = this.getPosition();
const token = this.expectToken("Text");
@@ -355,6 +397,9 @@ const createHTMLParser = createParser((ParserCore, ParserWithRequiredPath) =>
case "Text":
return this.parseText();
+ case "Comment":
+ return this.parseComment();
+
default:
throw this.unexpected();
}

MODIFY
packages/@romefrontend/html-parser/test-fixtures/smoke/input.html
packages/@romefrontend/html-parser/test-fixtures/smoke/input.html
+<!-- I am a comment -->
<foo>
<input placeholder="ok" >
yes
ok <span><span><span>lol</span></span></span>
<yeah>mate</yeah>
+ <!-- I am another comment -->
+
</foo>

MODIFY
packages/@romefrontend/html-parser/test-fixtures/smoke/input.test.md
packages/@romefrontend/html-parser/test-fixtures/smoke/input.test.md
@@ -15,8 +15,8 @@ HTMLRoot {
filename: "input.html"
end: Object {
column: 6
- index: 161
- line: 16
+ index: 218
+ line: 19
}
start: Object {
column: 0
@@ -32,13 +32,13 @@ HTMLRoot {
filename: "input.html"
end: Object {
column: 4
- index: 4
- line: 1
+ index: 28
+ line: 2
}
start: Object {
column: 1
- index: 1
- line: 1
+ index: 25
+ line: 2
}
}
}
@@ -48,13 +48,13 @@ HTMLRoot {
filename: "input.html"
end: Object {
column: 6
- index: 161
- line: 16
+ index: 218
+ line: 19
}
start: Object {
column: 0
- index: 0
- line: 1
+ index: 24
+ line: 2
}
}
children: Array [
@@ -65,13 +65,13 @@ HTMLRoot {
filename: "input.html"
end: Object {
column: 7
- index: 13
- line: 2
+ index: 37
+ line: 3
}
start: Object {
column: 2
- index: 8
- line: 2
+ index: 32
+ line: 3
}
}
}
@@ -80,14 +80,14 @@ HTMLRoot {
loc: Object {
filename: "input.html"
end: Object {
- column: 25
- index: 31
- line: 2
+ column: 26
+ index: 56
+ line: 3
}
start: Object {
column: 1
- index: 7
- line: 2
+ index: 31
+ line: 3
}
}
attributes: Array [
@@ -98,13 +98,13 @@ HTMLRoot {
filename: "input.html"
end: Object {
column: 19
- index: 25
- line: 2
+ index: 49
+ line: 3
}
start: Object {
column: 8
- index: 14
- line: 2
+ index: 38
+ line: 3
}
}
}
@@ -114,13 +114,13 @@ HTMLRoot {
filename: "input.html"
end: Object {
column: 24
- index: 30
- line: 2
+ index: 54
+ line: 3
}
start: Object {
column: 20
- index: 26
- line: 2
+ index: 50
+ line: 3
}
}
}
@@ -128,13 +128,13 @@ HTMLRoot {
filename: "input.html"
end: Object {
column: 24
- index: 30
- line: 2
+ index: 54
+ line: 3
}
start: Object {
column: 8
- index: 14
- line: 2
+ index: 38
+ line: 3
}
}
}
@@ -146,13 +146,13 @@ HTMLRoot {
filename: "input.html"
end: Object {
column: 6
- index: 92
- line: 13
+ index: 117
+ line: 14
}
start: Object {
column: 1
- index: 33
- line: 3
+ index: 58
+ line: 4
}
}
}
@@ -163,13 +163,13 @@ HTMLRoot {
filename: "input.html"
end: Object {
column: 11
- index: 97
- line: 13
+ index: 122
+ line: 14
}
start: Object {
column: 7
- index: 93
- line: 13
+ index: 118
+ line: 14
}
}
}
@@ -179,13 +179,13 @@ HTMLRoot {
filename: "input.html"
end: Object {
column: 48
- index: 134
- line: 13
+ index: 159
+ line: 14
}
start: Object {
column: 6
- index: 92
- line: 13
+ index: 117
+ line: 14
}
}
children: Array [
@@ -196,13 +196,13 @@ HTMLRoot {
filename: "input.html"
end: Object {
column: 17
- index: 103
- line: 13
+ index: 128
+ line: 14
}
start: Object {
column: 13
- index: 99
- line: 13
+ index: 124
+ line: 14
}
}
}
@@ -212,13 +212,13 @@ HTMLRoot {
filename: "input.html"
end: Object {
column: 41
- index: 127
- line: 13
+ index: 152
+ line: 14
}
start: Object {
column: 12
- index: 98
- line: 13
+ index: 123
+ line: 14
}
}
children: Array [
@@ -229,13 +229,13 @@ HTMLRoot {
filename: "input.html"
end: Object {
column: 23
- index: 109
- line: 13
+ index: 134
+ line: 14
}
start: Object {
column: 19
- index: 105
- line: 13
+ index: 130
+ line: 14
}
}
}
@@ -245,13 +245,13 @@ HTMLRoot {
filename: "input.html"
end: Object {
column: 34
- index: 120
- line: 13
+ index: 145
+ line: 14
}
start: Object {
column: 18
- index: 104
- line: 13
+ index: 129
+ line: 14
}
}
children: Array [
@@ -261,13 +261,13 @@ HTMLRoot {
filename: "input.html"
end: Object {
column: 27
- index: 113
- line: 13
+ index: 138
+ line: 14
}
start: Object {
column: 24
- index: 110
- line: 13
+ index: 135
+ line: 14
}
}
}
@@ -284,13 +284,13 @@ HTMLRoot {
filename: "input.html"
end: Object {
column: 6
- index: 142
- line: 15
+ index: 167
+ line: 16
}
start: Object {
column: 2
- index: 138
- line: 15
+ index: 163
+ line: 16
}
}
}
@@ -300,13 +300,13 @@ HTMLRoot {
filename: "input.html"
end: Object {
column: 18
- index: 154
- line: 15
+ index: 179
+ line: 16
}
start: Object {
column: 1
- index: 137
- line: 15
+ index: 162
+ line: 16
}
}
children: Array [
@@ -316,13 +316,13 @@ HTMLRoot {
filename: "input.html"
end: Object {
column: 11
- index: 147
- line: 15
+ index: 172
+ line: 16
}
start: Object {
column: 7
- index: 143
- line: 15
+ index: 168
+ line: 16
}
}
}

ADD
packages/@romefrontend/html-parser/utils.ts
+import {Number0, ob1Add, ob1Get} from "@romefrontend/ob1";
+
+export function getChar(index: Number0, input: string, offset = 0): string {
+ const targetIndex = ob1Get(index) + offset;
+ return input[targetIndex];
+}
+
+export function consumeComment(index: Number0, input: string): [Number0, string] {
+ let value = "";
+ while (getChar(index, input) !== ">") {
+ const char = getChar(index, input);
+ if (char !== "-") {
+ value += getChar(index, input);
+ }
+ index = ob1Add(index, 1);
+ }
+
+ return [ob1Add(index, 1), value.trim()];
+}

Added handling of comments inside html parser (#712)