@markuplint/pug-parser 4.6.7 → 4.6.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -4
- package/lib/parser.js +20 -1
- package/lib/pug-parser/index.d.ts +25 -14
- package/lib/pug-parser/index.js +95 -57
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -3,21 +3,30 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
-
## [4.6.
|
|
6
|
+
## [4.6.9](https://github.com/markuplint/markuplint/compare/@markuplint/pug-parser@4.6.8...@markuplint/pug-parser@4.6.9) (2024-10-15)
|
|
7
7
|
|
|
8
|
-
**Note:** Version bump only for package @markuplint/pug-parser
|
|
9
8
|
|
|
9
|
+
### Bug Fixes
|
|
10
10
|
|
|
11
|
+
* **pug-parser:** fix parsing outdent code ([dd50bb4](https://github.com/markuplint/markuplint/commit/dd50bb423bbd1c466fe10c59a1778b5572d60457))
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
|
|
14
|
-
## [4.6.6](https://github.com/markuplint/markuplint/compare/@markuplint/pug-parser@4.6.5...@markuplint/pug-parser@4.6.6) (2024-09-02)
|
|
15
15
|
|
|
16
|
-
**Note:** Version bump only for package @markuplint/pug-parser
|
|
17
16
|
|
|
17
|
+
## [4.6.8](https://github.com/markuplint/markuplint/compare/@markuplint/pug-parser@4.6.7...@markuplint/pug-parser@4.6.8) (2024-10-14)
|
|
18
18
|
|
|
19
|
+
### Bug Fixes
|
|
19
20
|
|
|
21
|
+
- **pug-parser:** fix to support `BlockComment` node ([afa721c](https://github.com/markuplint/markuplint/commit/afa721cd29cab8a47fa27cefe808d3fb7066b42e))
|
|
20
22
|
|
|
23
|
+
## [4.6.7](https://github.com/markuplint/markuplint/compare/@markuplint/pug-parser@4.6.6...@markuplint/pug-parser@4.6.7) (2024-09-23)
|
|
24
|
+
|
|
25
|
+
**Note:** Version bump only for package @markuplint/pug-parser
|
|
26
|
+
|
|
27
|
+
## [4.6.6](https://github.com/markuplint/markuplint/compare/@markuplint/pug-parser@4.6.5...@markuplint/pug-parser@4.6.6) (2024-09-02)
|
|
28
|
+
|
|
29
|
+
**Note:** Version bump only for package @markuplint/pug-parser
|
|
21
30
|
|
|
22
31
|
## [4.6.5](https://github.com/markuplint/markuplint/compare/@markuplint/pug-parser@4.6.4...@markuplint/pug-parser@4.6.5) (2024-06-25)
|
|
23
32
|
|
package/lib/parser.js
CHANGED
|
@@ -95,6 +95,18 @@ class PugParser extends Parser {
|
|
|
95
95
|
isBogus: false,
|
|
96
96
|
});
|
|
97
97
|
}
|
|
98
|
+
case 'BlockComment': {
|
|
99
|
+
const lastBlock = originNode.block.nodes.at(-1);
|
|
100
|
+
const endOffset = lastBlock ? lastBlock.endOffset : originNode.endOffset;
|
|
101
|
+
const token = this.sliceFragment(originNode.offset, endOffset);
|
|
102
|
+
return this.visitComment({
|
|
103
|
+
...token,
|
|
104
|
+
depth,
|
|
105
|
+
parentNode,
|
|
106
|
+
}, {
|
|
107
|
+
isBogus: false,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
98
110
|
case 'Tag': {
|
|
99
111
|
const namespace = getNamespace(originNode.name, parentNamespace);
|
|
100
112
|
const attrs = originNode.attrs.map(attr => {
|
|
@@ -142,8 +154,15 @@ class PugParser extends Parser {
|
|
|
142
154
|
});
|
|
143
155
|
}
|
|
144
156
|
default: {
|
|
157
|
+
let tokenIncludesFile = token;
|
|
158
|
+
if ('file' in originNode) {
|
|
159
|
+
const interval = originNode.file.column - originNode.endColumn;
|
|
160
|
+
const fileOffset = originNode.endOffset + interval;
|
|
161
|
+
const fileEndOffset = fileOffset + originNode.file.path.length;
|
|
162
|
+
tokenIncludesFile = this.sliceFragment(originNode.offset, fileEndOffset);
|
|
163
|
+
}
|
|
145
164
|
return this.visitPsBlock({
|
|
146
|
-
...
|
|
165
|
+
...tokenIncludesFile,
|
|
147
166
|
depth,
|
|
148
167
|
parentNode,
|
|
149
168
|
nodeName: originNode.type,
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
export declare function pugParse(pug: string, useOffset?: boolean): ASTBlock;
|
|
2
2
|
export type ASTBlock = PugAST<ASTNode>;
|
|
3
|
-
export type ASTNode = ASTTagNode | ASTTextNode |
|
|
3
|
+
export type ASTNode = ASTTagNode | ASTTextNode | ASTCodeNode | ASTComment | ASTBlockComment | ASTDoctype | ASTIncludeNode | ASTRawIncludeNode | ASTMixinNode | ASTMixinSlotNode | ASTNamedBlockNode | ASTFilterNode | ASTEachNode | ASTConditionalNode | ASTCaseNode | ASTCaseWhenNode;
|
|
4
4
|
export type ASTTagNode = Omit<PugASTTagNode<ASTAttr, ASTBlock>, 'selfClosing' | 'isInline'> & AdditionalASTData;
|
|
5
5
|
export type ASTTextNode = Omit<PugASTTextNode, 'val'> & AdditionalASTData;
|
|
6
|
-
export type ASTEmptyPipeNode = PugASTEmptyPipeNode & AdditionalASTData;
|
|
7
6
|
export type ASTCodeNode = PugASTCodeNode & AdditionalASTData;
|
|
8
7
|
export type ASTComment = PugASTCommentNode & AdditionalASTData;
|
|
8
|
+
export type ASTBlockComment = PugASTBlockCommentNode<ASTBlock> & AdditionalASTData;
|
|
9
9
|
export type ASTDoctype = PugASTDoctypeNode & AdditionalASTData;
|
|
10
10
|
export type ASTIncludeNode = PugASTIncludeNode<ASTBlock> & AdditionalASTData;
|
|
11
|
+
export type ASTRawIncludeNode = PugASTRawIncludeNode & AdditionalASTData;
|
|
11
12
|
export type ASTMixinNode = Omit<PugASTMixinNode<ASTAttr, ASTBlock>, 'attributeBlocks'> & AdditionalASTData;
|
|
12
13
|
export type ASTMixinSlotNode = PugASTMixinSlotNode & AdditionalASTData;
|
|
13
14
|
export type ASTNamedBlockNode = PugASTNamedBlockNode<ASTNode> & AdditionalASTData;
|
|
@@ -54,12 +55,6 @@ type PugASTTextNode = {
|
|
|
54
55
|
line: number;
|
|
55
56
|
column: number;
|
|
56
57
|
};
|
|
57
|
-
type PugASTEmptyPipeNode = {
|
|
58
|
-
type: 'EmptyPipe';
|
|
59
|
-
val: string;
|
|
60
|
-
line: number;
|
|
61
|
-
column: number;
|
|
62
|
-
};
|
|
63
58
|
type PugASTCodeNode = {
|
|
64
59
|
type: 'Code';
|
|
65
60
|
val: string;
|
|
@@ -76,6 +71,14 @@ type PugASTCommentNode = {
|
|
|
76
71
|
line: number;
|
|
77
72
|
column: number;
|
|
78
73
|
};
|
|
74
|
+
type PugASTBlockCommentNode<B> = {
|
|
75
|
+
type: 'BlockComment';
|
|
76
|
+
val: string;
|
|
77
|
+
block: B;
|
|
78
|
+
buffer: boolean;
|
|
79
|
+
line: number;
|
|
80
|
+
column: number;
|
|
81
|
+
};
|
|
79
82
|
type PugASTDoctypeNode = {
|
|
80
83
|
type: 'Doctype';
|
|
81
84
|
val: string;
|
|
@@ -84,16 +87,24 @@ type PugASTDoctypeNode = {
|
|
|
84
87
|
};
|
|
85
88
|
type PugASTIncludeNode<B> = {
|
|
86
89
|
type: 'Include';
|
|
87
|
-
file:
|
|
88
|
-
type: 'FileReference';
|
|
89
|
-
path: string;
|
|
90
|
-
line: number;
|
|
91
|
-
column: number;
|
|
92
|
-
};
|
|
90
|
+
file: RugASTIncludeFile;
|
|
93
91
|
block: B;
|
|
94
92
|
line: number;
|
|
95
93
|
column: number;
|
|
96
94
|
};
|
|
95
|
+
type PugASTRawIncludeNode = {
|
|
96
|
+
type: 'RawInclude';
|
|
97
|
+
file: RugASTIncludeFile;
|
|
98
|
+
line: number;
|
|
99
|
+
column: number;
|
|
100
|
+
filters: unknown[];
|
|
101
|
+
};
|
|
102
|
+
type RugASTIncludeFile = {
|
|
103
|
+
type: 'FileReference';
|
|
104
|
+
path: string;
|
|
105
|
+
line: number;
|
|
106
|
+
column: number;
|
|
107
|
+
};
|
|
97
108
|
type PugASTEachNode<B> = {
|
|
98
109
|
type: 'Each';
|
|
99
110
|
obj: string;
|
package/lib/pug-parser/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import lexer from 'pug-lexer';
|
|
|
2
2
|
// @ts-ignore
|
|
3
3
|
import parser from 'pug-parser';
|
|
4
4
|
import { getOffsetFromLineAndCol } from '../utils/get-offset-from-line-and-col.js';
|
|
5
|
+
import { getOffsetsFromCode } from '@markuplint/parser-utils/location';
|
|
5
6
|
export function pugParse(pug, useOffset = false) {
|
|
6
7
|
let lexOrigin = lexer(pug);
|
|
7
8
|
/**
|
|
@@ -146,6 +147,22 @@ tokens, pug) {
|
|
|
146
147
|
nodes.push(includeNode);
|
|
147
148
|
continue;
|
|
148
149
|
}
|
|
150
|
+
case 'RawInclude': {
|
|
151
|
+
const includeNode = {
|
|
152
|
+
type: node.type,
|
|
153
|
+
file: node.file,
|
|
154
|
+
raw,
|
|
155
|
+
offset,
|
|
156
|
+
endOffset,
|
|
157
|
+
line,
|
|
158
|
+
endLine,
|
|
159
|
+
column,
|
|
160
|
+
endColumn,
|
|
161
|
+
filters: node.filters,
|
|
162
|
+
};
|
|
163
|
+
nodes.push(includeNode);
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
149
166
|
case 'Mixin': {
|
|
150
167
|
// TODO: Attributes when call mixin
|
|
151
168
|
// const attrs = getAttrs(node.attrs, tokens, offsets, pug);
|
|
@@ -222,6 +239,24 @@ tokens, pug) {
|
|
|
222
239
|
nodes.push(commentNode);
|
|
223
240
|
continue;
|
|
224
241
|
}
|
|
242
|
+
case 'BlockComment': {
|
|
243
|
+
const block = optimizeAST(node.block, tokens, pug);
|
|
244
|
+
const commentNode = {
|
|
245
|
+
type: node.type,
|
|
246
|
+
val: node.val,
|
|
247
|
+
buffer: node.buffer,
|
|
248
|
+
block,
|
|
249
|
+
raw,
|
|
250
|
+
offset,
|
|
251
|
+
endOffset,
|
|
252
|
+
line,
|
|
253
|
+
endLine,
|
|
254
|
+
column,
|
|
255
|
+
endColumn,
|
|
256
|
+
};
|
|
257
|
+
nodes.push(commentNode);
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
225
260
|
case 'Code': {
|
|
226
261
|
const newNode = {
|
|
227
262
|
type: node.type,
|
|
@@ -250,41 +285,8 @@ tokens, pug) {
|
|
|
250
285
|
nodes.push(textNode);
|
|
251
286
|
break;
|
|
252
287
|
}
|
|
253
|
-
const
|
|
254
|
-
|
|
255
|
-
// console.log({ v: node.val, r: raw });
|
|
256
|
-
/**
|
|
257
|
-
*
|
|
258
|
-
* Empty piped line
|
|
259
|
-
*
|
|
260
|
-
* @see https://pugjs.org/language/plain-text.html#recommended-solutions
|
|
261
|
-
*/
|
|
262
|
-
if (raw === '|') {
|
|
263
|
-
const newNode = {
|
|
264
|
-
type: 'EmptyPipe',
|
|
265
|
-
raw,
|
|
266
|
-
val: node.val,
|
|
267
|
-
offset,
|
|
268
|
-
endOffset,
|
|
269
|
-
line,
|
|
270
|
-
endLine,
|
|
271
|
-
column,
|
|
272
|
-
endColumn,
|
|
273
|
-
};
|
|
274
|
-
nodes.push(newNode);
|
|
275
|
-
continue;
|
|
276
|
-
}
|
|
277
|
-
const textNode = {
|
|
278
|
-
type: node.type,
|
|
279
|
-
raw,
|
|
280
|
-
offset,
|
|
281
|
-
endOffset,
|
|
282
|
-
line,
|
|
283
|
-
endLine,
|
|
284
|
-
column,
|
|
285
|
-
endColumn,
|
|
286
|
-
};
|
|
287
|
-
nodes.push(textNode);
|
|
288
|
+
const textNodes = getRawTextAndLocationEnd(node.val, offset, line, column, tokens, pug);
|
|
289
|
+
nodes.push(...textNodes);
|
|
288
290
|
continue;
|
|
289
291
|
}
|
|
290
292
|
case 'Doctype': {
|
|
@@ -558,29 +560,65 @@ tokens) {
|
|
|
558
560
|
}
|
|
559
561
|
function getRawTextAndLocationEnd(val, offset, line, column,
|
|
560
562
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
561
|
-
tokens,
|
|
562
|
-
|
|
563
|
+
tokens, pug) {
|
|
564
|
+
if (val.trim() === '') {
|
|
565
|
+
return [];
|
|
566
|
+
}
|
|
567
|
+
let depth = 0;
|
|
568
|
+
let endLine = line;
|
|
569
|
+
let endColumn = column;
|
|
570
|
+
const result = [];
|
|
563
571
|
for (const token of tokens) {
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
}
|
|
572
|
+
if (token.loc.start.line < line || (token.loc.start.line === line && token.loc.start.column < column)) {
|
|
573
|
+
continue;
|
|
574
|
+
}
|
|
575
|
+
switch (token.type) {
|
|
576
|
+
case 'text':
|
|
577
|
+
case 'text-html': {
|
|
578
|
+
endLine = token.loc.end.line;
|
|
579
|
+
endColumn = token.loc.end.column;
|
|
580
|
+
break;
|
|
581
|
+
}
|
|
582
|
+
case 'indent': {
|
|
583
|
+
depth++;
|
|
584
|
+
break;
|
|
585
|
+
}
|
|
586
|
+
case 'outdent': {
|
|
587
|
+
depth--;
|
|
588
|
+
break;
|
|
589
|
+
}
|
|
590
|
+
case 'newline': {
|
|
591
|
+
break;
|
|
592
|
+
}
|
|
593
|
+
default: {
|
|
594
|
+
depth = -1;
|
|
595
|
+
break;
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
const rawLoc = getOffsetsFromCode(pug, line, column, endLine, endColumn);
|
|
599
|
+
const raw = pug.slice(offset, rawLoc.endOffset);
|
|
600
|
+
if (raw.trim().startsWith('|')) {
|
|
601
|
+
// It is a piped text
|
|
602
|
+
break;
|
|
603
|
+
}
|
|
604
|
+
if (raw !== '') {
|
|
605
|
+
result.push({
|
|
606
|
+
type: 'Text',
|
|
607
|
+
raw,
|
|
608
|
+
offset,
|
|
609
|
+
endOffset: rawLoc.endOffset,
|
|
610
|
+
line,
|
|
611
|
+
endLine,
|
|
612
|
+
column,
|
|
613
|
+
endColumn,
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
offset = rawLoc.endOffset;
|
|
617
|
+
line = endLine;
|
|
618
|
+
column = endColumn;
|
|
619
|
+
if (depth <= -1) {
|
|
620
|
+
break;
|
|
578
621
|
}
|
|
579
|
-
beforeNewlineToken = token;
|
|
580
622
|
}
|
|
581
|
-
return
|
|
582
|
-
endOffset: offset + val.length,
|
|
583
|
-
endLine: line,
|
|
584
|
-
endColumn: column + val.length,
|
|
585
|
-
};
|
|
623
|
+
return result;
|
|
586
624
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markuplint/pug-parser",
|
|
3
|
-
"version": "4.6.
|
|
3
|
+
"version": "4.6.9",
|
|
4
4
|
"description": "Pug parser for markuplint",
|
|
5
5
|
"repository": "git@github.com:markuplint/markuplint.git",
|
|
6
6
|
"author": "Yusuke Hirao <yusukehirao@me.com>",
|
|
@@ -21,11 +21,11 @@
|
|
|
21
21
|
"clean": "tsc --build --clean"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@markuplint/html-parser": "4.6.
|
|
25
|
-
"@markuplint/ml-ast": "4.4.
|
|
26
|
-
"@markuplint/parser-utils": "4.
|
|
24
|
+
"@markuplint/html-parser": "4.6.9",
|
|
25
|
+
"@markuplint/ml-ast": "4.4.6",
|
|
26
|
+
"@markuplint/parser-utils": "4.7.0",
|
|
27
27
|
"pug-lexer": "5.0.1",
|
|
28
28
|
"pug-parser": "6.0.0"
|
|
29
29
|
},
|
|
30
|
-
"gitHead": "
|
|
30
|
+
"gitHead": "c8c82d36c2e48d191091cbc22ca1b99ed0704b9f"
|
|
31
31
|
}
|