@markuplint/pug-parser 3.3.0 → 3.4.0
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 +6 -6
- package/lib/index.d.ts +1 -1
- package/lib/parse.js +5 -1
- package/lib/pug-parser/index.d.ts +111 -97
- package/lib/pug-parser/index.js +9 -5
- package/package.json +4 -4
package/lib/attr-tokenizer.js
CHANGED
|
@@ -21,7 +21,7 @@ function attrTokenizer(attr) {
|
|
|
21
21
|
startCol: attr.column,
|
|
22
22
|
endCol: attr.endColumn,
|
|
23
23
|
potentialName: attr.name,
|
|
24
|
-
potentialValue: value,
|
|
24
|
+
potentialValue: value !== null && value !== void 0 ? value : '',
|
|
25
25
|
valueType: 'string',
|
|
26
26
|
isDuplicatable: attr.raw[0] === '.',
|
|
27
27
|
nodeName: '#pug-special-attr',
|
|
@@ -53,11 +53,11 @@ function attrTokenizer(attr) {
|
|
|
53
53
|
const equalAndBeforeSpaceAfterSpace = withoutName.slice(0, valueOffset);
|
|
54
54
|
const [, before, equal, after] = equalAndBeforeSpaceAfterSpace.match(/^(\s*)(=)(\s*)$/) || ['', '', '', ''];
|
|
55
55
|
const [, quote, coreValue] = attr.val.match(/(['"`]?)([^\1]+)(\1)/) || ['', '', ''];
|
|
56
|
-
spacesBeforeEqualChars = before;
|
|
57
|
-
equalChars = equal;
|
|
58
|
-
spacesAfterEqualChars = after;
|
|
59
|
-
quoteChars = quote;
|
|
60
|
-
valueChars = coreValue;
|
|
56
|
+
spacesBeforeEqualChars = before !== null && before !== void 0 ? before : '';
|
|
57
|
+
equalChars = equal !== null && equal !== void 0 ? equal : '';
|
|
58
|
+
spacesAfterEqualChars = after !== null && after !== void 0 ? after : '';
|
|
59
|
+
quoteChars = quote !== null && quote !== void 0 ? quote : '';
|
|
60
|
+
valueChars = coreValue !== null && coreValue !== void 0 ? coreValue : '';
|
|
61
61
|
if (quote === '`' || quote === '') {
|
|
62
62
|
isDynamicValue = true;
|
|
63
63
|
}
|
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
|
@@ -214,7 +214,11 @@ class Parser {
|
|
|
214
214
|
}
|
|
215
215
|
let node;
|
|
216
216
|
if (Array.isArray(nodes)) {
|
|
217
|
-
|
|
217
|
+
const lastNode = nodes[nodes.length - 1];
|
|
218
|
+
if (!lastNode) {
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
node = lastNode;
|
|
218
222
|
}
|
|
219
223
|
else {
|
|
220
224
|
node = nodes;
|
|
@@ -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
|
@@ -48,12 +48,13 @@ function mergeTextNode(nodes, pug) {
|
|
|
48
48
|
* @param pug Raw code
|
|
49
49
|
*/
|
|
50
50
|
function optimizeAST(originalAST, tokens, pug) {
|
|
51
|
+
var _a;
|
|
51
52
|
const nodes = [];
|
|
52
53
|
for (const node of originalAST.nodes) {
|
|
53
54
|
const line = node.line;
|
|
54
55
|
const column = node.column;
|
|
55
56
|
const offsets = getOffsetsFromLines(pug);
|
|
56
|
-
const lineOffset = Math.max(offsets[line - 2], 0) || 0;
|
|
57
|
+
const lineOffset = Math.max((_a = offsets[line - 2]) !== null && _a !== void 0 ? _a : 0, 0) || 0;
|
|
57
58
|
const offset = lineOffset + column - 1;
|
|
58
59
|
const { endLine, endColumn, endOffset } = getLocationFromToken(offset, line, column, tokens);
|
|
59
60
|
const raw = pug.slice(offset, endOffset);
|
|
@@ -304,6 +305,7 @@ function optimizeAST(originalAST, tokens, pug) {
|
|
|
304
305
|
};
|
|
305
306
|
}
|
|
306
307
|
function optimizeASTOfConditionalNode(node, tokens, pug, offsets, depth) {
|
|
308
|
+
var _a, _b;
|
|
307
309
|
const altNodes = [];
|
|
308
310
|
let tokenOfCurrentNode = null;
|
|
309
311
|
for (const token of tokens) {
|
|
@@ -314,7 +316,7 @@ function optimizeASTOfConditionalNode(node, tokens, pug, offsets, depth) {
|
|
|
314
316
|
}
|
|
315
317
|
if (tokenOfCurrentNode) {
|
|
316
318
|
// console.log(JSON.stringify(node, null, 2));
|
|
317
|
-
const lineOffset = Math.max(offsets[node.line - 2], 0) || 0;
|
|
319
|
+
const lineOffset = Math.max((_a = offsets[node.line - 2]) !== null && _a !== void 0 ? _a : 0, 0) || 0;
|
|
318
320
|
const offset = lineOffset + node.column - 1;
|
|
319
321
|
const length = tokenOfCurrentNode.loc.end.column - tokenOfCurrentNode.loc.start.column;
|
|
320
322
|
const endOffset = offset + length;
|
|
@@ -346,7 +348,7 @@ function optimizeASTOfConditionalNode(node, tokens, pug, offsets, depth) {
|
|
|
346
348
|
if (!tokenOfCurrentNode) {
|
|
347
349
|
return [];
|
|
348
350
|
}
|
|
349
|
-
const lineOffset = Math.max(offsets[tokenOfCurrentNode.loc.start.line - 2], 0) || 0;
|
|
351
|
+
const lineOffset = Math.max((_b = offsets[tokenOfCurrentNode.loc.start.line - 2]) !== null && _b !== void 0 ? _b : 0, 0) || 0;
|
|
350
352
|
const offset = lineOffset + tokenOfCurrentNode.loc.start.column - 1;
|
|
351
353
|
const length = tokenOfCurrentNode.loc.end.column - tokenOfCurrentNode.loc.start.column;
|
|
352
354
|
const endOffset = offset + length;
|
|
@@ -433,6 +435,7 @@ function getAttrs(originalAttrs, tokens, offsets, pug) {
|
|
|
433
435
|
return attrs;
|
|
434
436
|
}
|
|
435
437
|
function getEndAttributeLocation(nodeName, offset, line, column, tokens, offsets) {
|
|
438
|
+
var _a;
|
|
436
439
|
let beforeNewlineToken = null;
|
|
437
440
|
for (const token of tokens) {
|
|
438
441
|
// Searching token after the tag node.
|
|
@@ -443,7 +446,7 @@ function getEndAttributeLocation(nodeName, offset, line, column, tokens, offsets
|
|
|
443
446
|
token.type !== 'end-attributes' &&
|
|
444
447
|
token.type !== 'id' &&
|
|
445
448
|
token.type !== 'class') {
|
|
446
|
-
const endAttrLineOffset = Math.max(offsets[beforeNewlineToken.loc.end.line - 2], 0) || 0;
|
|
449
|
+
const endAttrLineOffset = Math.max((_a = offsets[beforeNewlineToken.loc.end.line - 2]) !== null && _a !== void 0 ? _a : 0, 0) || 0;
|
|
447
450
|
const endAttrOffset = endAttrLineOffset + beforeNewlineToken.loc.end.column - 1;
|
|
448
451
|
return {
|
|
449
452
|
endOffset: endAttrOffset,
|
|
@@ -492,6 +495,7 @@ function getPipelessText(node, pug, tokens) {
|
|
|
492
495
|
return null;
|
|
493
496
|
}
|
|
494
497
|
function getRawTextAndLocationEnd(val, offset, line, column, tokens, offsets, pug) {
|
|
498
|
+
var _a;
|
|
495
499
|
let beforeNewlineToken = null;
|
|
496
500
|
for (const token of tokens) {
|
|
497
501
|
// Searching token after the text.
|
|
@@ -501,7 +505,7 @@ function getRawTextAndLocationEnd(val, offset, line, column, tokens, offsets, pu
|
|
|
501
505
|
token.type !== 'text-html' &&
|
|
502
506
|
token.type !== 'indent' &&
|
|
503
507
|
token.type !== 'outdent') {
|
|
504
|
-
const endAttrLineOffset = Math.max(offsets[beforeNewlineToken.loc.end.line - 2], 0) || 0;
|
|
508
|
+
const endAttrLineOffset = Math.max((_a = offsets[beforeNewlineToken.loc.end.line - 2]) !== null && _a !== void 0 ? _a : 0, 0) || 0;
|
|
505
509
|
const endAttrOffset = endAttrLineOffset + beforeNewlineToken.loc.end.column - 1;
|
|
506
510
|
return {
|
|
507
511
|
endOffset: endAttrOffset,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markuplint/pug-parser",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
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.4.0",
|
|
20
20
|
"@markuplint/ml-ast": "3.0.0",
|
|
21
|
-
"@markuplint/parser-utils": "3.
|
|
21
|
+
"@markuplint/parser-utils": "3.4.0",
|
|
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": "a83e0f5f214a9bbcc0286b9e269074ddca6189e7"
|
|
27
27
|
}
|