@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.
@@ -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 = "never";
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
- node = nodes[nodes.length - 1];
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 = ASTTagNode | ASTTextNode | ASTCodeNode | ASTComment | ASTDoctype | ASTIncludeNode | ASTMixinNode | ASTMixinSlotNode | ASTFilterNode | ASTEachNode | ASTConditionalNode | ASTCaseNode | ASTCaseWhenNode;
4
- export type ASTTagNode = Omit<PugASTTagNode<ASTAttr, ASTBlock>, 'attributeBlocks' | 'selfClosing' | 'isInline'> & AdditionalASTData;
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
- block: ASTBlock;
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
- raw: string;
22
- offset: number;
23
- endOffset: number;
24
- endLine: number;
25
- endColumn: number;
35
+ raw: string;
36
+ offset: number;
37
+ endOffset: number;
38
+ endLine: number;
39
+ endColumn: number;
26
40
  };
27
41
  interface PugAST<N> {
28
- type: 'Block';
29
- nodes: N[];
30
- line: number;
42
+ type: 'Block';
43
+ nodes: N[];
44
+ line: number;
31
45
  }
32
46
  type PugASTTagNode<A, B> = {
33
- type: 'Tag';
34
- name: string;
35
- selfClosing: boolean;
36
- attrs: A[];
37
- attributeBlocks: never[];
38
- isInline: boolean;
39
- line: number;
40
- column: number;
41
- block: B;
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
- type: 'Text';
45
- val: string;
46
- isHtml?: true;
47
- line: number;
48
- column: number;
58
+ type: 'Text';
59
+ val: string;
60
+ isHtml?: true;
61
+ line: number;
62
+ column: number;
49
63
  };
50
64
  type PugASTCodeNode = {
51
- type: 'Code';
52
- val: string;
53
- buffer: boolean;
54
- mustEscape: boolean;
55
- isInline: boolean;
56
- line: number;
57
- column: number;
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
- type: 'Comment';
61
- val: string;
62
- buffer: boolean;
63
- line: number;
64
- column: number;
74
+ type: 'Comment';
75
+ val: string;
76
+ buffer: boolean;
77
+ line: number;
78
+ column: number;
65
79
  };
66
80
  type PugASTDoctypeNode = {
67
- type: 'Doctype';
68
- val: string;
69
- line: number;
70
- column: number;
81
+ type: 'Doctype';
82
+ val: string;
83
+ line: number;
84
+ column: number;
71
85
  };
72
86
  type PugASTIncludeNode<B> = {
73
- type: 'Include';
74
- file: {
75
- type: 'FileReference';
76
- path: string;
77
- line: number;
78
- column: number;
79
- };
80
- block: B;
81
- line: number;
82
- column: number;
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
- type: 'Each';
86
- obj: string;
87
- val: string;
88
- key: string | null;
89
- block: B;
90
- line: number;
91
- column: number;
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
- type: 'Mixin';
95
- name: string;
96
- args: string;
97
- call: boolean;
98
- block: B | null;
99
- attrs?: A[];
100
- attributeBlocks: never[];
101
- line: number;
102
- column: number;
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
- type: 'MixinBlock';
106
- line: number;
107
- column: number;
119
+ type: 'MixinBlock';
120
+ line: number;
121
+ column: number;
108
122
  };
109
123
  type PugASTFilterNode<A, B> = {
110
- type: 'Filter';
111
- name: string;
112
- block: B;
113
- attrs: A[];
114
- line: number;
115
- column: number;
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
- type: 'Conditional';
119
- test: string;
120
- consequent: B;
121
- alternate?: B | PugASTConditionalNode<B>;
122
- line: number;
123
- column: number;
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
- type: 'Case';
127
- expr: string;
128
- block: B;
129
- line: number;
130
- column: number;
140
+ type: 'Case';
141
+ expr: string;
142
+ block: B;
143
+ line: number;
144
+ column: number;
131
145
  };
132
146
  type PugASTCaseWhenNode<B> = {
133
- type: 'When';
134
- expr: string;
135
- block: B;
136
- line: number;
137
- column: number;
147
+ type: 'When';
148
+ expr: string;
149
+ block: B;
150
+ line: number;
151
+ column: number;
138
152
  };
139
153
  type PugASTAttr = {
140
- name: string;
141
- val: string | true;
142
- mustEscape: boolean;
143
- line: number;
144
- column: number;
154
+ name: string;
155
+ val: string | true;
156
+ mustEscape: boolean;
157
+ line: number;
158
+ column: number;
145
159
  };
146
160
  export {};
@@ -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.0",
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.3.0",
19
+ "@markuplint/html-parser": "3.4.0",
20
20
  "@markuplint/ml-ast": "3.0.0",
21
- "@markuplint/parser-utils": "3.3.0",
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": "791fb22a4df7acb985ced3808923fba0cd95c28a"
26
+ "gitHead": "a83e0f5f214a9bbcc0286b9e269074ddca6189e7"
27
27
  }