@markuplint/parser-utils 4.0.0-alpha.7 → 4.0.0-alpha.8
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/ignore-block.d.ts +1 -1
- package/lib/ignore-block.js +34 -121
- package/lib/types.d.ts +1 -0
- package/package.json +4 -4
package/lib/ignore-block.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { IgnoreBlock, IgnoreTag } from './types.js';
|
|
2
2
|
import type { MLASTNode } from '@markuplint/ml-ast';
|
|
3
3
|
export declare function ignoreBlock(source: string, tags: readonly IgnoreTag[], maskChar?: string): IgnoreBlock;
|
|
4
|
-
export declare function restoreNode(nodeList: MLASTNode[], ignoreBlock: IgnoreBlock): MLASTNode[];
|
|
4
|
+
export declare function restoreNode(nodeList: MLASTNode[], ignoreBlock: IgnoreBlock, throwErrorWhenTagHasUnresolved?: boolean): MLASTNode[];
|
package/lib/ignore-block.js
CHANGED
|
@@ -1,21 +1,11 @@
|
|
|
1
1
|
import { MASK_CHAR } from './const.js';
|
|
2
2
|
import { uuid } from './create-token.js';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { getCol, getLine } from './get-location.js';
|
|
4
|
+
import { ParserError } from './parser-error.js';
|
|
5
5
|
export function ignoreBlock(source, tags, maskChar = MASK_CHAR) {
|
|
6
6
|
let replaced = source;
|
|
7
7
|
const stack = [];
|
|
8
8
|
for (const tag of tags) {
|
|
9
|
-
// Replace tags in attributes
|
|
10
|
-
const attr = maskText(prepend(tag.start, '(?<=(?:"|\'))'), append(tag.end, '(?=(?:"|\'))'), replaced, (startTag, taggedCode, endTag) => {
|
|
11
|
-
const mask = maskChar.repeat(startTag.length) +
|
|
12
|
-
taggedCode.replaceAll(/[^\n]/g, maskChar) +
|
|
13
|
-
maskChar.repeat((endTag ?? '').length);
|
|
14
|
-
return mask;
|
|
15
|
-
});
|
|
16
|
-
replaced = attr.replaced;
|
|
17
|
-
stack.push(...attr.stack.map(res => ({ ...res, type: tag.type })));
|
|
18
|
-
// Replace tags in other nodes
|
|
19
9
|
const text = maskText(tag.start, tag.end, replaced, (startTag, taggedCode, endTag) => {
|
|
20
10
|
const mask = maskChar.repeat(startTag.length) +
|
|
21
11
|
taggedCode.replaceAll(/[^\n]/g, maskChar) +
|
|
@@ -49,6 +39,7 @@ function maskText(start, end, replaced, masking) {
|
|
|
49
39
|
startTag,
|
|
50
40
|
taggedCode,
|
|
51
41
|
endTag: endTag ?? null,
|
|
42
|
+
resolved: false,
|
|
52
43
|
});
|
|
53
44
|
/**
|
|
54
45
|
* It will not replace line breaks because detects line number.
|
|
@@ -62,7 +53,9 @@ function maskText(start, end, replaced, masking) {
|
|
|
62
53
|
}
|
|
63
54
|
export function restoreNode(
|
|
64
55
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
65
|
-
nodeList,
|
|
56
|
+
nodeList,
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
58
|
+
ignoreBlock, throwErrorWhenTagHasUnresolved = true) {
|
|
66
59
|
nodeList = [...nodeList];
|
|
67
60
|
const { source, stack, maskChar } = ignoreBlock;
|
|
68
61
|
for (const tag of stack) {
|
|
@@ -70,9 +63,6 @@ nodeList, ignoreBlock) {
|
|
|
70
63
|
if (!node) {
|
|
71
64
|
continue;
|
|
72
65
|
}
|
|
73
|
-
if (node.type !== 'comment') {
|
|
74
|
-
continue;
|
|
75
|
-
}
|
|
76
66
|
const psNode = {
|
|
77
67
|
uuid: uuid(),
|
|
78
68
|
type: 'psblock',
|
|
@@ -102,101 +92,9 @@ nodeList, ignoreBlock) {
|
|
|
102
92
|
}
|
|
103
93
|
const index = nodeList.indexOf(node);
|
|
104
94
|
nodeList.splice(index, 1, psNode);
|
|
95
|
+
tag.resolved = true;
|
|
105
96
|
}
|
|
106
97
|
for (const node of nodeList) {
|
|
107
|
-
if (node.type === 'comment' || node.type === 'text' || node.type === 'psblock') {
|
|
108
|
-
if (!hasIgnoreBlock(node.raw, maskChar)) {
|
|
109
|
-
continue;
|
|
110
|
-
}
|
|
111
|
-
const parentNode = node.parentNode;
|
|
112
|
-
const index = nodeList.indexOf(node);
|
|
113
|
-
const insertList = [];
|
|
114
|
-
let text = node.raw;
|
|
115
|
-
let pointer = 0;
|
|
116
|
-
for (const tag of stack) {
|
|
117
|
-
if (node.startOffset <= tag.index && tag.index < node.endOffset) {
|
|
118
|
-
const start = tag.index - node.startOffset;
|
|
119
|
-
const body = tag.startTag + tag.taggedCode + (tag.endTag ?? '');
|
|
120
|
-
const above = node.raw.slice(pointer, start);
|
|
121
|
-
const below = text.slice(above.length + body.length);
|
|
122
|
-
if (above) {
|
|
123
|
-
const offset = node.startOffset + pointer;
|
|
124
|
-
const { raw, startOffset, endOffset, startLine, endLine, startCol, endCol } = sliceFragment(source, offset, offset + above.length);
|
|
125
|
-
const textNode = {
|
|
126
|
-
...node,
|
|
127
|
-
uuid: uuid(),
|
|
128
|
-
type: 'text',
|
|
129
|
-
raw,
|
|
130
|
-
startOffset,
|
|
131
|
-
endOffset,
|
|
132
|
-
startLine,
|
|
133
|
-
endLine,
|
|
134
|
-
startCol,
|
|
135
|
-
endCol,
|
|
136
|
-
};
|
|
137
|
-
if (node.prevNode?.nextNode) {
|
|
138
|
-
node.prevNode.nextNode = textNode;
|
|
139
|
-
}
|
|
140
|
-
if (node.nextNode?.prevNode) {
|
|
141
|
-
node.nextNode.prevNode = textNode;
|
|
142
|
-
}
|
|
143
|
-
insertList.push(textNode);
|
|
144
|
-
}
|
|
145
|
-
if (body) {
|
|
146
|
-
const offset = node.startOffset + pointer + above.length;
|
|
147
|
-
const { raw, startOffset, endOffset, startLine, endLine, startCol, endCol } = sliceFragment(source, offset, offset + body.length);
|
|
148
|
-
const bodyNode = {
|
|
149
|
-
uuid: uuid(),
|
|
150
|
-
type: 'psblock',
|
|
151
|
-
nodeName: `#ps:${tag.type}`,
|
|
152
|
-
raw,
|
|
153
|
-
parentNode: node.parentNode,
|
|
154
|
-
prevNode: null,
|
|
155
|
-
nextNode: null,
|
|
156
|
-
isFragment: node.isFragment,
|
|
157
|
-
isGhost: false,
|
|
158
|
-
startOffset,
|
|
159
|
-
endOffset,
|
|
160
|
-
startLine,
|
|
161
|
-
endLine,
|
|
162
|
-
startCol,
|
|
163
|
-
endCol,
|
|
164
|
-
};
|
|
165
|
-
if (node.prevNode?.nextNode) {
|
|
166
|
-
node.prevNode.nextNode = bodyNode;
|
|
167
|
-
}
|
|
168
|
-
if (node.nextNode?.prevNode) {
|
|
169
|
-
node.nextNode.prevNode = bodyNode;
|
|
170
|
-
}
|
|
171
|
-
insertList.push(bodyNode);
|
|
172
|
-
}
|
|
173
|
-
text = below;
|
|
174
|
-
pointer = start + body.length;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
if (text) {
|
|
178
|
-
const offset = node.endOffset - text.length;
|
|
179
|
-
const { raw, startOffset, endOffset, startLine, endLine, startCol, endCol } = sliceFragment(source, offset, offset + text.length);
|
|
180
|
-
const textNode = {
|
|
181
|
-
...node,
|
|
182
|
-
uuid: uuid(),
|
|
183
|
-
type: 'text',
|
|
184
|
-
raw,
|
|
185
|
-
startOffset,
|
|
186
|
-
endOffset,
|
|
187
|
-
startLine,
|
|
188
|
-
endLine,
|
|
189
|
-
startCol,
|
|
190
|
-
endCol,
|
|
191
|
-
};
|
|
192
|
-
insertList.push(textNode);
|
|
193
|
-
}
|
|
194
|
-
siblingsCorrection(insertList);
|
|
195
|
-
if (parentNode) {
|
|
196
|
-
parentNode.childNodes = insertList;
|
|
197
|
-
}
|
|
198
|
-
nodeList.splice(index, 1, ...insertList);
|
|
199
|
-
}
|
|
200
98
|
if (node.type === 'starttag') {
|
|
201
99
|
for (const attr of node.attributes) {
|
|
202
100
|
if (attr.type === 'ps-attr' || attr.value.raw === '' || !hasIgnoreBlock(attr.value.raw, maskChar)) {
|
|
@@ -211,8 +109,35 @@ nodeList, ignoreBlock) {
|
|
|
211
109
|
const below = attr.value.raw.slice(offset + length);
|
|
212
110
|
attr.value.raw = above + raw + below;
|
|
213
111
|
attr.isDynamicValue = true;
|
|
112
|
+
tag.resolved = true;
|
|
214
113
|
}
|
|
114
|
+
attr.raw =
|
|
115
|
+
attr.spacesBeforeName.raw +
|
|
116
|
+
attr.name.raw +
|
|
117
|
+
attr.spacesBeforeEqual.raw +
|
|
118
|
+
attr.equal.raw +
|
|
119
|
+
attr.spacesAfterEqual.raw +
|
|
120
|
+
attr.startQuote.raw +
|
|
121
|
+
attr.value.raw +
|
|
122
|
+
attr.endQuote.raw;
|
|
215
123
|
}
|
|
124
|
+
// Update node raw
|
|
125
|
+
const length = attr.raw.length;
|
|
126
|
+
const offset = attr.startOffset - node.startOffset - attr.spacesBeforeName.raw.length;
|
|
127
|
+
const above = node.raw.slice(0, offset);
|
|
128
|
+
const below = node.raw.slice(offset + length);
|
|
129
|
+
node.raw = above + attr.raw + below;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (throwErrorWhenTagHasUnresolved) {
|
|
134
|
+
for (const tag of stack) {
|
|
135
|
+
if (!tag.resolved) {
|
|
136
|
+
throw new ParserError('Parsing failed. Unsupported syntax detected', {
|
|
137
|
+
line: getLine(source, tag.index),
|
|
138
|
+
col: getCol(source, tag.index),
|
|
139
|
+
raw: tag.startTag + tag.taggedCode + (tag.endTag ?? ''),
|
|
140
|
+
});
|
|
216
141
|
}
|
|
217
142
|
}
|
|
218
143
|
}
|
|
@@ -235,18 +160,6 @@ function removeGlobalOption(reg) {
|
|
|
235
160
|
}
|
|
236
161
|
return new RegExp(reg.source, reg.ignoreCase ? 'i' : '');
|
|
237
162
|
}
|
|
238
|
-
function prepend(reg, str) {
|
|
239
|
-
if (typeof reg === 'string') {
|
|
240
|
-
return new RegExp(str + escapeRegExpForStr(reg));
|
|
241
|
-
}
|
|
242
|
-
return new RegExp(str + reg.source, reg.ignoreCase ? 'i' : '');
|
|
243
|
-
}
|
|
244
|
-
function append(reg, str) {
|
|
245
|
-
if (typeof reg === 'string') {
|
|
246
|
-
return new RegExp(escapeRegExpForStr(reg) + str);
|
|
247
|
-
}
|
|
248
|
-
return new RegExp(reg.source + str, reg.ignoreCase ? 'i' : '');
|
|
249
|
-
}
|
|
250
163
|
function hasIgnoreBlock(textContent, maskChar) {
|
|
251
164
|
return textContent.includes(maskChar);
|
|
252
165
|
}
|
package/lib/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markuplint/parser-utils",
|
|
3
|
-
"version": "4.0.0-alpha.
|
|
3
|
+
"version": "4.0.0-alpha.8",
|
|
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,12 @@
|
|
|
24
24
|
"clean": "tsc --build --clean"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@markuplint/ml-ast": "4.0.0-alpha.
|
|
28
|
-
"@markuplint/types": "4.0.0-alpha.
|
|
27
|
+
"@markuplint/ml-ast": "4.0.0-alpha.8",
|
|
28
|
+
"@markuplint/types": "4.0.0-alpha.8",
|
|
29
29
|
"@types/uuid": "^9.0.7",
|
|
30
30
|
"espree": "^9.6.1",
|
|
31
31
|
"type-fest": "^4.9.0",
|
|
32
32
|
"uuid": "^9.0.1"
|
|
33
33
|
},
|
|
34
|
-
"gitHead": "
|
|
34
|
+
"gitHead": "5bcd25f13ff804af0d09aaabd87e495af668e6a8"
|
|
35
35
|
}
|