@markuplint/pug-parser 3.5.0 → 3.6.1
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/lib/attr-tokenizer.js +4 -3
- package/lib/index.d.ts +1 -1
- package/lib/parse.js +3 -3
- package/lib/pug-parser/index.d.ts +111 -97
- package/lib/pug-parser/index.js +12 -13
- package/package.json +4 -4
package/lib/attr-tokenizer.js
CHANGED
|
@@ -4,10 +4,11 @@ const parser_utils_1 = require("@markuplint/parser-utils");
|
|
|
4
4
|
function attrTokenizer(
|
|
5
5
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
6
6
|
attr) {
|
|
7
|
+
var _a, _b, _c;
|
|
7
8
|
if (attr.raw[0] === '#' || attr.raw[0] === '.') {
|
|
8
9
|
let value = '';
|
|
9
10
|
if (typeof attr.val === 'string') {
|
|
10
|
-
[, , value] = attr.val.match(/(['"`]?)([^\1]+)(\1)/)
|
|
11
|
+
[, , value] = (_a = attr.val.match(/(['"`]?)([^\1]+)(\1)/)) !== null && _a !== void 0 ? _a : ['', '', ''];
|
|
11
12
|
}
|
|
12
13
|
else {
|
|
13
14
|
value = `${attr.val}`;
|
|
@@ -53,8 +54,8 @@ attr) {
|
|
|
53
54
|
const withoutName = attr.raw.slice(attr.name.length);
|
|
54
55
|
const valueOffset = withoutName.indexOf(attr.val);
|
|
55
56
|
const equalAndBeforeSpaceAfterSpace = withoutName.slice(0, valueOffset);
|
|
56
|
-
const [, before, equal, after] = equalAndBeforeSpaceAfterSpace.match(/^(\s*)(=)(\s*)$/)
|
|
57
|
-
const [, quote, coreValue] = attr.val.match(/(['"`]?)([^\1]+)(\1)/)
|
|
57
|
+
const [, before, equal, after] = (_b = equalAndBeforeSpaceAfterSpace.match(/^(\s*)(=)(\s*)$/)) !== null && _b !== void 0 ? _b : ['', '', '', ''];
|
|
58
|
+
const [, quote, coreValue] = (_c = attr.val.match(/(['"`]?)([^\1]+)(\1)/)) !== null && _c !== void 0 ? _c : ['', '', ''];
|
|
58
59
|
spacesBeforeEqualChars = before !== null && before !== void 0 ? before : '';
|
|
59
60
|
equalChars = equal !== null && equal !== void 0 ? equal : '';
|
|
60
61
|
spacesAfterEqualChars = after !== null && after !== void 0 ? after : '';
|
package/lib/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { parse } from './parse';
|
|
2
|
-
export declare const endTag =
|
|
2
|
+
export declare const endTag = 'never';
|
package/lib/parse.js
CHANGED
|
@@ -81,7 +81,7 @@ class Parser {
|
|
|
81
81
|
return {
|
|
82
82
|
uuid: (0, parser_utils_1.uuid)(),
|
|
83
83
|
raw: originNode.raw,
|
|
84
|
-
name: originNode.val
|
|
84
|
+
name: (_a = originNode.val) !== null && _a !== void 0 ? _a : '',
|
|
85
85
|
// TODO:
|
|
86
86
|
publicId: '',
|
|
87
87
|
// TODO:
|
|
@@ -182,7 +182,7 @@ class Parser {
|
|
|
182
182
|
tagOpenChar: '',
|
|
183
183
|
tagCloseChar: '',
|
|
184
184
|
};
|
|
185
|
-
if (originNode.block.nodes.length) {
|
|
185
|
+
if (originNode.block.nodes.length > 0) {
|
|
186
186
|
tag.childNodes = this.traverse(originNode.block.nodes, tag);
|
|
187
187
|
}
|
|
188
188
|
return tag;
|
|
@@ -205,7 +205,7 @@ class Parser {
|
|
|
205
205
|
isFragment: true,
|
|
206
206
|
isGhost: false,
|
|
207
207
|
};
|
|
208
|
-
if ('block' in originNode &&
|
|
208
|
+
if ('block' in originNode && originNode.block && originNode.block.nodes.length > 0) {
|
|
209
209
|
tag.childNodes = this.traverse(originNode.block.nodes, tag);
|
|
210
210
|
}
|
|
211
211
|
return tag;
|
|
@@ -1,7 +1,21 @@
|
|
|
1
1
|
export declare function pugParse(pug: string): ASTBlock;
|
|
2
2
|
export type ASTBlock = PugAST<ASTNode>;
|
|
3
|
-
export type ASTNode =
|
|
4
|
-
|
|
3
|
+
export type ASTNode =
|
|
4
|
+
| ASTTagNode
|
|
5
|
+
| ASTTextNode
|
|
6
|
+
| ASTCodeNode
|
|
7
|
+
| ASTComment
|
|
8
|
+
| ASTDoctype
|
|
9
|
+
| ASTIncludeNode
|
|
10
|
+
| ASTMixinNode
|
|
11
|
+
| ASTMixinSlotNode
|
|
12
|
+
| ASTFilterNode
|
|
13
|
+
| ASTEachNode
|
|
14
|
+
| ASTConditionalNode
|
|
15
|
+
| ASTCaseNode
|
|
16
|
+
| ASTCaseWhenNode;
|
|
17
|
+
export type ASTTagNode = Omit<PugASTTagNode<ASTAttr, ASTBlock>, 'attributeBlocks' | 'selfClosing' | 'isInline'> &
|
|
18
|
+
AdditionalASTData;
|
|
5
19
|
export type ASTTextNode = Omit<PugASTTextNode, 'val'> & AdditionalASTData;
|
|
6
20
|
export type ASTCodeNode = PugASTCodeNode & AdditionalASTData;
|
|
7
21
|
export type ASTComment = PugASTCommentNode & AdditionalASTData;
|
|
@@ -12,135 +26,135 @@ export type ASTMixinSlotNode = PugASTMixinSlotNode & AdditionalASTData;
|
|
|
12
26
|
export type ASTFilterNode = PugASTFilterNode<ASTAttr, ASTBlock> & AdditionalASTData;
|
|
13
27
|
export type ASTEachNode = PugASTEachNode<ASTBlock> & AdditionalASTData;
|
|
14
28
|
export type ASTConditionalNode = Omit<PugASTConditionalNode<ASTBlock>, 'consequent' | 'alternate'> & {
|
|
15
|
-
|
|
29
|
+
block: ASTBlock;
|
|
16
30
|
} & AdditionalASTData;
|
|
17
31
|
export type ASTCaseNode = PugASTCaseNode<ASTBlock> & AdditionalASTData;
|
|
18
32
|
export type ASTCaseWhenNode = PugASTCaseWhenNode<ASTBlock> & AdditionalASTData;
|
|
19
33
|
export type ASTAttr = PugASTAttr & AdditionalASTData;
|
|
20
34
|
type AdditionalASTData = {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
35
|
+
raw: string;
|
|
36
|
+
offset: number;
|
|
37
|
+
endOffset: number;
|
|
38
|
+
endLine: number;
|
|
39
|
+
endColumn: number;
|
|
26
40
|
};
|
|
27
41
|
interface PugAST<N> {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
42
|
+
type: 'Block';
|
|
43
|
+
nodes: N[];
|
|
44
|
+
line: number;
|
|
31
45
|
}
|
|
32
46
|
type PugASTTagNode<A, B> = {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
47
|
+
type: 'Tag';
|
|
48
|
+
name: string;
|
|
49
|
+
selfClosing: boolean;
|
|
50
|
+
attrs: A[];
|
|
51
|
+
attributeBlocks: never[];
|
|
52
|
+
isInline: boolean;
|
|
53
|
+
line: number;
|
|
54
|
+
column: number;
|
|
55
|
+
block: B;
|
|
42
56
|
};
|
|
43
57
|
type PugASTTextNode = {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
58
|
+
type: 'Text';
|
|
59
|
+
val: string;
|
|
60
|
+
isHtml?: true;
|
|
61
|
+
line: number;
|
|
62
|
+
column: number;
|
|
49
63
|
};
|
|
50
64
|
type PugASTCodeNode = {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
65
|
+
type: 'Code';
|
|
66
|
+
val: string;
|
|
67
|
+
buffer: boolean;
|
|
68
|
+
mustEscape: boolean;
|
|
69
|
+
isInline: boolean;
|
|
70
|
+
line: number;
|
|
71
|
+
column: number;
|
|
58
72
|
};
|
|
59
73
|
type PugASTCommentNode = {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
74
|
+
type: 'Comment';
|
|
75
|
+
val: string;
|
|
76
|
+
buffer: boolean;
|
|
77
|
+
line: number;
|
|
78
|
+
column: number;
|
|
65
79
|
};
|
|
66
80
|
type PugASTDoctypeNode = {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
81
|
+
type: 'Doctype';
|
|
82
|
+
val: string;
|
|
83
|
+
line: number;
|
|
84
|
+
column: number;
|
|
71
85
|
};
|
|
72
86
|
type PugASTIncludeNode<B> = {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
87
|
+
type: 'Include';
|
|
88
|
+
file: {
|
|
89
|
+
type: 'FileReference';
|
|
90
|
+
path: string;
|
|
91
|
+
line: number;
|
|
92
|
+
column: number;
|
|
93
|
+
};
|
|
94
|
+
block: B;
|
|
95
|
+
line: number;
|
|
96
|
+
column: number;
|
|
83
97
|
};
|
|
84
98
|
type PugASTEachNode<B> = {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
99
|
+
type: 'Each';
|
|
100
|
+
obj: string;
|
|
101
|
+
val: string;
|
|
102
|
+
key: string | null;
|
|
103
|
+
block: B;
|
|
104
|
+
line: number;
|
|
105
|
+
column: number;
|
|
92
106
|
};
|
|
93
107
|
type PugASTMixinNode<A, B> = {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
108
|
+
type: 'Mixin';
|
|
109
|
+
name: string;
|
|
110
|
+
args: string;
|
|
111
|
+
call: boolean;
|
|
112
|
+
block: B | null;
|
|
113
|
+
attrs?: A[];
|
|
114
|
+
attributeBlocks: never[];
|
|
115
|
+
line: number;
|
|
116
|
+
column: number;
|
|
103
117
|
};
|
|
104
118
|
type PugASTMixinSlotNode = {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
119
|
+
type: 'MixinBlock';
|
|
120
|
+
line: number;
|
|
121
|
+
column: number;
|
|
108
122
|
};
|
|
109
123
|
type PugASTFilterNode<A, B> = {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
124
|
+
type: 'Filter';
|
|
125
|
+
name: string;
|
|
126
|
+
block: B;
|
|
127
|
+
attrs: A[];
|
|
128
|
+
line: number;
|
|
129
|
+
column: number;
|
|
116
130
|
};
|
|
117
131
|
type PugASTConditionalNode<B> = {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
132
|
+
type: 'Conditional';
|
|
133
|
+
test: string;
|
|
134
|
+
consequent: B;
|
|
135
|
+
alternate?: B | PugASTConditionalNode<B>;
|
|
136
|
+
line: number;
|
|
137
|
+
column: number;
|
|
124
138
|
};
|
|
125
139
|
type PugASTCaseNode<B> = {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
140
|
+
type: 'Case';
|
|
141
|
+
expr: string;
|
|
142
|
+
block: B;
|
|
143
|
+
line: number;
|
|
144
|
+
column: number;
|
|
131
145
|
};
|
|
132
146
|
type PugASTCaseWhenNode<B> = {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
147
|
+
type: 'When';
|
|
148
|
+
expr: string;
|
|
149
|
+
block: B;
|
|
150
|
+
line: number;
|
|
151
|
+
column: number;
|
|
138
152
|
};
|
|
139
153
|
type PugASTAttr = {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
154
|
+
name: string;
|
|
155
|
+
val: string | true;
|
|
156
|
+
mustEscape: boolean;
|
|
157
|
+
line: number;
|
|
158
|
+
column: number;
|
|
145
159
|
};
|
|
146
160
|
export {};
|
package/lib/pug-parser/index.js
CHANGED
|
@@ -29,9 +29,10 @@ function getOffsetsFromLines(pug) {
|
|
|
29
29
|
function mergeTextNode(
|
|
30
30
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
31
31
|
nodes, pug) {
|
|
32
|
+
var _a;
|
|
32
33
|
const baseNodes = [];
|
|
33
34
|
for (const node of nodes) {
|
|
34
|
-
const prevNode = baseNodes[baseNodes.length - 1]
|
|
35
|
+
const prevNode = (_a = baseNodes[baseNodes.length - 1]) !== null && _a !== void 0 ? _a : null;
|
|
35
36
|
if (prevNode && prevNode.type === 'Text' && node.type === 'Text') {
|
|
36
37
|
prevNode.raw = pug.slice(prevNode.offset, node.endOffset);
|
|
37
38
|
prevNode.endColumn = node.endColumn;
|
|
@@ -60,7 +61,7 @@ tokens, pug) {
|
|
|
60
61
|
const line = node.line;
|
|
61
62
|
const column = node.column;
|
|
62
63
|
const offsets = getOffsetsFromLines(pug);
|
|
63
|
-
const lineOffset = Math.max((_a = offsets[line - 2]) !== null && _a !== void 0 ? _a : 0, 0)
|
|
64
|
+
const lineOffset = Math.max((_a = offsets[line - 2]) !== null && _a !== void 0 ? _a : 0, 0);
|
|
64
65
|
const offset = lineOffset + column - 1;
|
|
65
66
|
const { endLine, endColumn, endOffset } = getLocationFromToken(offset, line, column, tokens);
|
|
66
67
|
const raw = pug.slice(offset, endOffset);
|
|
@@ -326,7 +327,7 @@ tokens, pug, offsets, depth) {
|
|
|
326
327
|
}
|
|
327
328
|
if (tokenOfCurrentNode) {
|
|
328
329
|
// console.log(JSON.stringify(node, null, 2));
|
|
329
|
-
const lineOffset = Math.max((_a = offsets[node.line - 2]) !== null && _a !== void 0 ? _a : 0, 0)
|
|
330
|
+
const lineOffset = Math.max((_a = offsets[node.line - 2]) !== null && _a !== void 0 ? _a : 0, 0);
|
|
330
331
|
const offset = lineOffset + node.column - 1;
|
|
331
332
|
const length = tokenOfCurrentNode.loc.end.column - tokenOfCurrentNode.loc.start.column;
|
|
332
333
|
const endOffset = offset + length;
|
|
@@ -358,7 +359,7 @@ tokens, pug, offsets, depth) {
|
|
|
358
359
|
if (!tokenOfCurrentNode) {
|
|
359
360
|
return [];
|
|
360
361
|
}
|
|
361
|
-
const lineOffset = Math.max((_b = offsets[tokenOfCurrentNode.loc.start.line - 2]) !== null && _b !== void 0 ? _b : 0, 0)
|
|
362
|
+
const lineOffset = Math.max((_b = offsets[tokenOfCurrentNode.loc.start.line - 2]) !== null && _b !== void 0 ? _b : 0, 0);
|
|
362
363
|
const offset = lineOffset + tokenOfCurrentNode.loc.start.column - 1;
|
|
363
364
|
const length = tokenOfCurrentNode.loc.end.column - tokenOfCurrentNode.loc.start.column;
|
|
364
365
|
const endOffset = offset + length;
|
|
@@ -388,14 +389,11 @@ tokens, pug, offsets, depth) {
|
|
|
388
389
|
}
|
|
389
390
|
function getLocationFromToken(offset, line, column,
|
|
390
391
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
391
|
-
tokens, tokenType
|
|
392
|
+
tokens, tokenType) {
|
|
393
|
+
const tokenTypes = typeof tokenType === 'string' ? (tokenType !== '' ? [tokenType] : null) : tokenType !== null && tokenType !== void 0 ? tokenType : null;
|
|
392
394
|
let tokenOfCurrentNode = null;
|
|
393
395
|
for (const token of tokens) {
|
|
394
|
-
if ((
|
|
395
|
-
? Array.isArray(tokenType)
|
|
396
|
-
? tokenType.includes(token.type)
|
|
397
|
-
: tokenType === token.type
|
|
398
|
-
: true) &&
|
|
396
|
+
if ((tokenTypes == null || tokenTypes.includes(token.type)) &&
|
|
399
397
|
token.loc.start.line === line &&
|
|
400
398
|
token.loc.start.column === column) {
|
|
401
399
|
tokenOfCurrentNode = token;
|
|
@@ -418,9 +416,10 @@ function getAttrs(
|
|
|
418
416
|
originalAttrs,
|
|
419
417
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
420
418
|
tokens, offsets, pug) {
|
|
419
|
+
var _a;
|
|
421
420
|
const attrs = [];
|
|
422
421
|
for (const attr of originalAttrs) {
|
|
423
|
-
const attrLineOffset = offsets[attr.line - 2]
|
|
422
|
+
const attrLineOffset = (_a = offsets[attr.line - 2]) !== null && _a !== void 0 ? _a : 0;
|
|
424
423
|
const attrOffset = attrLineOffset + attr.column - 1;
|
|
425
424
|
let tokenOfCurrentAttr = null;
|
|
426
425
|
for (const token of tokens) {
|
|
@@ -464,7 +463,7 @@ tokens, offsets) {
|
|
|
464
463
|
token.type !== 'end-attributes' &&
|
|
465
464
|
token.type !== 'id' &&
|
|
466
465
|
token.type !== 'class') {
|
|
467
|
-
const endAttrLineOffset = Math.max((_a = offsets[beforeNewlineToken.loc.end.line - 2]) !== null && _a !== void 0 ? _a : 0, 0)
|
|
466
|
+
const endAttrLineOffset = Math.max((_a = offsets[beforeNewlineToken.loc.end.line - 2]) !== null && _a !== void 0 ? _a : 0, 0);
|
|
468
467
|
const endAttrOffset = endAttrLineOffset + beforeNewlineToken.loc.end.column - 1;
|
|
469
468
|
return {
|
|
470
469
|
endOffset: endAttrOffset,
|
|
@@ -529,7 +528,7 @@ tokens, offsets, pug) {
|
|
|
529
528
|
token.type !== 'text-html' &&
|
|
530
529
|
token.type !== 'indent' &&
|
|
531
530
|
token.type !== 'outdent') {
|
|
532
|
-
const endAttrLineOffset = Math.max((_a = offsets[beforeNewlineToken.loc.end.line - 2]) !== null && _a !== void 0 ? _a : 0, 0)
|
|
531
|
+
const endAttrLineOffset = Math.max((_a = offsets[beforeNewlineToken.loc.end.line - 2]) !== null && _a !== void 0 ? _a : 0, 0);
|
|
533
532
|
const endAttrOffset = endAttrLineOffset + beforeNewlineToken.loc.end.column - 1;
|
|
534
533
|
return {
|
|
535
534
|
endOffset: endAttrOffset,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markuplint/pug-parser",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.6.1",
|
|
4
4
|
"description": "Pug parser for markuplint",
|
|
5
5
|
"repository": "git@github.com:markuplint/markuplint.git",
|
|
6
6
|
"author": "Yusuke Hirao <yusukehirao@me.com>",
|
|
@@ -16,12 +16,12 @@
|
|
|
16
16
|
"clean": "tsc --build --clean"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@markuplint/html-parser": "3.
|
|
19
|
+
"@markuplint/html-parser": "3.6.1",
|
|
20
20
|
"@markuplint/ml-ast": "3.1.0",
|
|
21
|
-
"@markuplint/parser-utils": "3.
|
|
21
|
+
"@markuplint/parser-utils": "3.6.1",
|
|
22
22
|
"pug-lexer": "^5.0.1",
|
|
23
23
|
"pug-parser": "^6.0.0",
|
|
24
24
|
"tslib": "^2.4.1"
|
|
25
25
|
},
|
|
26
|
-
"gitHead": "
|
|
26
|
+
"gitHead": "3cdf5a088b2da03773d5d4461d0e65ec32290a00"
|
|
27
27
|
}
|