@markuplint/parser-utils 4.0.0-alpha.3 → 4.0.0-alpha.4

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/const.js CHANGED
@@ -96,5 +96,5 @@ export const svgElementList = [
96
96
  ];
97
97
  export const reTag = /^<((?:.|\s|\n)+)>\s*$/;
98
98
  // eslint-disable-next-line no-control-regex
99
- export const reTagName = /^(?:[a-z][^\u0000\u0009\u000A\u000C\u0020/>]*)/i;
99
+ export const reTagName = /^[a-z][^\u0000\u0009\u000A\u000C />]*/i;
100
100
  export const reSplitterTag = /<[^>]+>/g;
package/lib/debugger.js CHANGED
@@ -1,21 +1,19 @@
1
1
  export function nodeListToDebugMaps(
2
2
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
3
3
  nodeList, withAttr = false) {
4
- return nodeList
5
- .map(n => {
4
+ return nodeList.flatMap(n => {
6
5
  const r = [];
7
- if (!n.isGhost) {
6
+ if (n.isGhost) {
7
+ r.push(`[N/A]>[N/A](N/A)${n.nodeName}: ${visibleWhiteSpace(n.raw)}`);
8
+ }
9
+ else {
8
10
  r.push(tokenDebug(n));
9
11
  if (withAttr && 'attributes' in n) {
10
12
  r.push(...attributesToDebugMaps(n.attributes).flat());
11
13
  }
12
14
  }
13
- else {
14
- r.push(`[N/A]>[N/A](N/A)${n.nodeName}: ${visibleWhiteSpace(n.raw)}`);
15
- }
16
15
  return r;
17
- })
18
- .flat();
16
+ });
19
17
  }
20
18
  export function attributesToDebugMaps(
21
19
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
@@ -28,16 +26,7 @@ attributes) {
28
26
  }),
29
27
  ];
30
28
  if (n.type === 'html-attr') {
31
- r.push(` ${tokenDebug(n.spacesBeforeName, 'bN')}`);
32
- r.push(` ${tokenDebug(n.name, 'name')}`);
33
- r.push(` ${tokenDebug(n.spacesBeforeEqual, 'bE')}`);
34
- r.push(` ${tokenDebug(n.equal, 'equal')}`);
35
- r.push(` ${tokenDebug(n.spacesAfterEqual, 'aE')}`);
36
- r.push(` ${tokenDebug(n.startQuote, 'sQ')}`);
37
- r.push(` ${tokenDebug(n.value, 'value')}`);
38
- r.push(` ${tokenDebug(n.endQuote, 'eQ')}`);
39
- r.push(` isDirective: ${!!n.isDirective}`);
40
- r.push(` isDynamicValue: ${!!n.isDynamicValue}`);
29
+ r.push(` ${tokenDebug(n.spacesBeforeName, 'bN')}`, ` ${tokenDebug(n.name, 'name')}`, ` ${tokenDebug(n.spacesBeforeEqual, 'bE')}`, ` ${tokenDebug(n.equal, 'equal')}`, ` ${tokenDebug(n.spacesAfterEqual, 'aE')}`, ` ${tokenDebug(n.startQuote, 'sQ')}`, ` ${tokenDebug(n.value, 'value')}`, ` ${tokenDebug(n.endQuote, 'eQ')}`, ` isDirective: ${!!n.isDirective}`, ` isDynamicValue: ${!!n.isDynamicValue}`);
41
30
  }
42
31
  if (n.potentialName != null) {
43
32
  r.push(` potentialName: ${visibleWhiteSpace(n.potentialName)}`);
@@ -54,5 +43,5 @@ function tokenDebug(n, type = '') {
54
43
  n.potentialName ?? n.nodeName ?? n.name ?? n.type ?? type}: ${visibleWhiteSpace(n.raw)}`;
55
44
  }
56
45
  function visibleWhiteSpace(chars) {
57
- return chars.replace(/\n/g, '⏎').replace(/\t/g, '→').replace(/\s/g, '␣');
46
+ return chars.replaceAll('\n', '⏎').replaceAll('\t', '→').replaceAll(/\s/g, '␣');
58
47
  }
@@ -25,7 +25,7 @@ function _distinguishAuthoredName(name, patterns) {
25
25
  });
26
26
  }
27
27
  function toRegexp(pattern) {
28
- const matched = pattern.match(/^\/(.+)\/([ig]*)$/i);
28
+ const matched = pattern.match(/^\/(.+)\/([gi]*)$/i);
29
29
  if (matched && matched[1]) {
30
30
  return new RegExp(matched[1], matched[2]);
31
31
  }
@@ -71,9 +71,9 @@ nodeTree, rawHtml, createLastText = true) {
71
71
  * create Last spaces
72
72
  */
73
73
  let lastOffset = 0;
74
- nodeOrders.forEach((node, i) => {
74
+ for (const node of nodeOrders) {
75
75
  lastOffset = Math.max(node.endOffset, lastOffset);
76
- });
76
+ }
77
77
  // console.log(lastOffset);
78
78
  const lastTextContent = rawHtml.slice(lastOffset);
79
79
  // console.log(`"${lastTextContent}"`);
@@ -110,8 +110,8 @@ nodeTree, rawHtml, createLastText = true) {
110
110
  * concat text nodes
111
111
  */
112
112
  const result = [];
113
- nodeOrders.forEach(node => {
114
- const prevNode = result[result.length - 1] ?? null;
113
+ for (const node of nodeOrders) {
114
+ const prevNode = result.at(-1) ?? null;
115
115
  if (node.type === 'text' && prevNode?.type === 'text') {
116
116
  prevNode.raw = prevNode.raw + node.raw;
117
117
  prevNode.endOffset = node.endOffset;
@@ -132,10 +132,10 @@ nodeTree, rawHtml, createLastText = true) {
132
132
  if (node.nextNode) {
133
133
  node.nextNode.prevNode = prevNode;
134
134
  }
135
- return;
135
+ continue;
136
136
  }
137
137
  result.push(node);
138
- });
138
+ }
139
139
  {
140
140
  /**
141
141
  * Correction prev/next/parent
@@ -168,10 +168,12 @@ nodeTree, rawHtml, createLastText = true) {
168
168
  // Children
169
169
  if (node.type === 'text') {
170
170
  const parent = node.parentNode;
171
- if (parent && parent.type === 'starttag' && parent.nodeName.toLowerCase() === 'html') {
172
- if (parent.childNodes && !parent.childNodes.some(n => n.uuid === node.uuid)) {
173
- parent.childNodes.push(node);
174
- }
171
+ if (parent &&
172
+ parent.type === 'starttag' &&
173
+ parent.nodeName.toLowerCase() === 'html' &&
174
+ parent.childNodes &&
175
+ !parent.childNodes.some(n => n.uuid === node.uuid)) {
176
+ parent.childNodes.push(node);
175
177
  }
176
178
  }
177
179
  prevToken = node;
@@ -241,5 +243,5 @@ nodeTree, rawHtml) {
241
243
  node.endOffset = node.endOffset ?? currentEndOffset;
242
244
  nodeOrders.push(node);
243
245
  });
244
- return nodeOrders.slice();
246
+ return [...nodeOrders];
245
247
  }
@@ -3,7 +3,7 @@ export function getLine(html, startOffset) {
3
3
  }
4
4
  export function getCol(html, startOffset) {
5
5
  const lines = html.slice(0, startOffset).split(/\n/g);
6
- return (lines[lines.length - 1] ?? '').length + 1;
6
+ return (lines.at(-1) ?? '').length + 1;
7
7
  }
8
8
  export function getEndLine(html, line) {
9
9
  return html.split(/\r?\n/).length - 1 + line;
@@ -428,8 +428,8 @@ export function searchIDLAttribute(name) {
428
428
  };
429
429
  }
430
430
  function camelize(str) {
431
- return str.replace(/[:-][a-z]/g, $0 => $0[1]?.toUpperCase() ?? '');
431
+ return str.replaceAll(/[:-][a-z]/g, $0 => $0[1]?.toUpperCase() ?? '');
432
432
  }
433
433
  function hyphenize(str) {
434
- return str.replace(/[A-Z]/g, $0 => `-${$0.toLowerCase()}`);
434
+ return str.replaceAll(/[A-Z]/g, $0 => `-${$0.toLowerCase()}`);
435
435
  }
@@ -9,7 +9,7 @@ export function ignoreBlock(source, tags, maskChar = MASK_CHAR) {
9
9
  // Replace tags in attributes
10
10
  const attr = maskText(prepend(tag.start, '(?<=(?:"|\'))'), append(tag.end, '(?=(?:"|\'))'), replaced, (startTag, taggedCode, endTag) => {
11
11
  const mask = maskChar.repeat(startTag.length) +
12
- taggedCode.replace(/[^\n]/g, maskChar) +
12
+ taggedCode.replaceAll(/[^\n]/g, maskChar) +
13
13
  maskChar.repeat((endTag ?? '').length);
14
14
  return mask;
15
15
  });
@@ -18,7 +18,7 @@ export function ignoreBlock(source, tags, maskChar = MASK_CHAR) {
18
18
  // Replace tags in other nodes
19
19
  const text = maskText(tag.start, tag.end, replaced, (startTag, taggedCode, endTag) => {
20
20
  const mask = maskChar.repeat(startTag.length) +
21
- taggedCode.replace(/[^\n]/g, maskChar) +
21
+ taggedCode.replaceAll(/[^\n]/g, maskChar) +
22
22
  maskChar.repeat((endTag ?? '').length);
23
23
  const taggedMask = `<!${mask.slice(2).slice(0, -1)}>`;
24
24
  return taggedMask;
@@ -63,7 +63,7 @@ function maskText(start, end, replaced, masking) {
63
63
  export function restoreNode(
64
64
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
65
65
  nodeList, ignoreBlock) {
66
- nodeList = nodeList.slice();
66
+ nodeList = [...nodeList];
67
67
  const { source, stack, maskChar } = ignoreBlock;
68
68
  for (const node of nodeList) {
69
69
  if (node.type === 'comment' || node.type === 'text' || node.type === 'psblock') {
@@ -71,7 +71,7 @@ nodeList, ignoreBlock) {
71
71
  continue;
72
72
  }
73
73
  const parentNode = node.parentNode;
74
- const index = nodeList.findIndex(n => n === node);
74
+ const index = nodeList.indexOf(node);
75
75
  const insertList = [];
76
76
  let text = node.raw;
77
77
  let pointer = 0;
@@ -12,6 +12,6 @@ export function ignoreFrontMatter(code) {
12
12
  const endPoint = startPoint + reEnd.index + reEnd[0].length;
13
13
  const frontMatter = code.slice(0, endPoint);
14
14
  const afterCode = code.slice(endPoint);
15
- const masked = frontMatter.replace(/[^\r\n]/g, ' ');
15
+ const masked = frontMatter.replaceAll(/[^\n\r]/g, ' ');
16
16
  return masked + afterCode;
17
17
  }
package/lib/parse-attr.js CHANGED
@@ -55,7 +55,7 @@ export function tokenize(raw, options) {
55
55
  const valueDelimiters = options?.valueDelimiters ?? defaultValueDelimiters;
56
56
  const equalDelimiter = options?.equal ?? defaultEqual;
57
57
  let state = 'b-name';
58
- const charactors = raw.split('');
58
+ const charactors = [...raw];
59
59
  let beforeName = '';
60
60
  let name = '';
61
61
  let afterName = '';
@@ -20,16 +20,16 @@ nodeOrders) {
20
20
  */
21
21
  const stack = {};
22
22
  const removeIndexes = [];
23
- nodeOrders.forEach((node, i) => {
23
+ for (const [i, node] of nodeOrders.entries()) {
24
24
  if (node.isGhost) {
25
- return;
25
+ continue;
26
26
  }
27
27
  const id = `${node.startLine}:${node.startCol}:${node.endLine}:${node.endCol}`;
28
28
  if (stack[id] != null) {
29
29
  removeIndexes.push(i);
30
30
  }
31
31
  stack[id] = i;
32
- });
32
+ }
33
33
  let r = nodeOrders.length;
34
34
  while (r-- > 0) {
35
35
  if (removeIndexes.includes(r)) {
@@ -8,7 +8,7 @@ function tagSplitterAsString(raw) {
8
8
  if (!tagMatches) {
9
9
  return [raw];
10
10
  }
11
- const tokens = Array.from(tagMatches);
11
+ const tokens = [...tagMatches];
12
12
  tokens.unshift(); // remove all match
13
13
  const nodes = [];
14
14
  let rest = raw;
@@ -31,15 +31,7 @@ function tagSplitterAsString(raw) {
31
31
  function withLocation(nodes, line, col) {
32
32
  const result = [];
33
33
  for (const node of nodes) {
34
- if (node[0] !== '<') {
35
- result.push({
36
- type: 'text',
37
- raw: node,
38
- line,
39
- col,
40
- });
41
- }
42
- else {
34
+ if (node[0] === '<') {
43
35
  const label = node.slice(1).slice(0, -1);
44
36
  if (reTagName.test(label)) {
45
37
  result.push({
@@ -49,39 +41,54 @@ function withLocation(nodes, line, col) {
49
41
  col,
50
42
  });
51
43
  }
52
- else if (label[0] === '/') {
53
- result.push({
54
- type: 'endtag',
55
- raw: node,
56
- line,
57
- col,
58
- });
59
- }
60
- else if (label[0] === '!') {
61
- result.push({
62
- type: 'comment',
63
- raw: node,
64
- line,
65
- col,
66
- });
67
- }
68
- else if (label[0] === '?') {
69
- result.push({
70
- type: 'boguscomment',
71
- raw: node,
72
- line,
73
- col,
74
- });
75
- }
76
44
  else {
77
- result.push({
78
- type: 'text',
79
- raw: node,
80
- line,
81
- col,
82
- });
45
+ switch (label[0]) {
46
+ case '/': {
47
+ result.push({
48
+ type: 'endtag',
49
+ raw: node,
50
+ line,
51
+ col,
52
+ });
53
+ break;
54
+ }
55
+ case '!': {
56
+ result.push({
57
+ type: 'comment',
58
+ raw: node,
59
+ line,
60
+ col,
61
+ });
62
+ break;
63
+ }
64
+ case '?': {
65
+ result.push({
66
+ type: 'boguscomment',
67
+ raw: node,
68
+ line,
69
+ col,
70
+ });
71
+ break;
72
+ }
73
+ default: {
74
+ result.push({
75
+ type: 'text',
76
+ raw: node,
77
+ line,
78
+ col,
79
+ });
80
+ }
81
+ }
83
82
  }
84
83
  }
84
+ else {
85
+ result.push({
86
+ type: 'text',
87
+ raw: node,
88
+ line,
89
+ col,
90
+ });
91
+ }
85
92
  line = getEndLine(node, line);
86
93
  col = getEndCol(node, col);
87
94
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markuplint/parser-utils",
3
- "version": "4.0.0-alpha.3",
3
+ "version": "4.0.0-alpha.4",
4
4
  "description": "Utility module for markuplint parser plugin",
5
5
  "repository": "git@github.com:markuplint/markuplint.git",
6
6
  "author": "Yusuke Hirao <yusukehirao@me.com>",
@@ -24,12 +24,11 @@
24
24
  "clean": "tsc --build --clean"
25
25
  },
26
26
  "dependencies": {
27
- "@markuplint/ml-ast": "4.0.0-alpha.3",
28
- "@markuplint/types": "4.0.0-alpha.3",
29
- "@types/uuid": "^9.0.4",
30
- "tslib": "^2.6.2",
31
- "type-fest": "^4.3.1",
27
+ "@markuplint/ml-ast": "4.0.0-alpha.4",
28
+ "@markuplint/types": "4.0.0-alpha.4",
29
+ "@types/uuid": "^9.0.6",
30
+ "type-fest": "^4.5.0",
32
31
  "uuid": "^9.0.1"
33
32
  },
34
- "gitHead": "380836f7adc1ff7e8eaf9d869e68d29eee8f3b7e"
33
+ "gitHead": "991b3aef77fde42c79343ee8c807257a35c589d7"
35
34
  }