@unified-latex/unified-latex-util-catcode 1.8.3 → 1.8.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/index.cjs +282 -263
- package/index.cjs.map +1 -1
- package/index.js +282 -270
- package/index.js.map +1 -1
- package/package.json +4 -4
package/index.cjs
CHANGED
|
@@ -1,290 +1,308 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
let _unified_latex_unified_latex_util_match = require("@unified-latex/unified-latex-util-match");
|
|
3
|
+
let _unified_latex_unified_latex_util_visit = require("@unified-latex/unified-latex-util-visit");
|
|
4
|
+
//#region libs/find-region.ts
|
|
5
|
+
/**
|
|
6
|
+
* Find all contiguous segments in the array that are between start and end blocks.
|
|
7
|
+
* The `start` and `end` are functions that determine when a region starts and ends.
|
|
8
|
+
*/
|
|
5
9
|
function findRegionInArray(tree, start, end) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
10
|
+
const ret = [];
|
|
11
|
+
let currRegion = {
|
|
12
|
+
start: void 0,
|
|
13
|
+
end: tree.length
|
|
14
|
+
};
|
|
15
|
+
for (let i = 0; i < tree.length; i++) {
|
|
16
|
+
const node = tree[i];
|
|
17
|
+
if (start(node)) currRegion.start = i;
|
|
18
|
+
if (end(node)) {
|
|
19
|
+
currRegion.end = i + 1;
|
|
20
|
+
ret.push(currRegion);
|
|
21
|
+
currRegion = {
|
|
22
|
+
start: void 0,
|
|
23
|
+
end: tree.length
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (currRegion.start != null) ret.push(currRegion);
|
|
28
|
+
return ret;
|
|
23
29
|
}
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region libs/regions.ts
|
|
32
|
+
/**
|
|
33
|
+
* Given `regions`, a list of `Region`s (not necessarily ordered, possibly overlapping), return a list of in-order,
|
|
34
|
+
* non-overlapping regions and a corresponding list containing a set of the original `Region`s that the new region
|
|
35
|
+
* is a subset of.
|
|
36
|
+
*/
|
|
24
37
|
function refineRegions(regions) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
38
|
+
const _regions = [...regions];
|
|
39
|
+
_regions.sort((a, b) => a.start - b.start);
|
|
40
|
+
const cutPointsSet = new Set(_regions.flatMap((r) => [r.start, r.end]));
|
|
41
|
+
const cutPoints = Array.from(cutPointsSet);
|
|
42
|
+
cutPoints.sort((a, b) => a - b);
|
|
43
|
+
const retRegions = [];
|
|
44
|
+
const retRegionsContainedIn = [];
|
|
45
|
+
let seekIndex = 0;
|
|
46
|
+
for (let i = 0; i < cutPoints.length - 1; i++) {
|
|
47
|
+
const start = cutPoints[i];
|
|
48
|
+
const end = cutPoints[i + 1];
|
|
49
|
+
const region = {
|
|
50
|
+
start,
|
|
51
|
+
end
|
|
52
|
+
};
|
|
53
|
+
const regionContainedIn = /* @__PURE__ */ new Set();
|
|
54
|
+
let encounteredEndPastStart = false;
|
|
55
|
+
for (let j = seekIndex; j < _regions.length; j++) {
|
|
56
|
+
const superRegion = _regions[j];
|
|
57
|
+
if (superRegion.end >= region.start) encounteredEndPastStart = true;
|
|
58
|
+
if (!encounteredEndPastStart && superRegion.end < region.start) {
|
|
59
|
+
seekIndex = j + 1;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (superRegion.start > end) break;
|
|
63
|
+
if (superRegion.start <= region.start && superRegion.end >= region.end) {
|
|
64
|
+
encounteredEndPastStart = true;
|
|
65
|
+
regionContainedIn.add(superRegion);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (regionContainedIn.size > 0) {
|
|
69
|
+
retRegions.push(region);
|
|
70
|
+
retRegionsContainedIn.push(regionContainedIn);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
regions: retRegions,
|
|
75
|
+
regionsContainedIn: retRegionsContainedIn
|
|
76
|
+
};
|
|
62
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Split an array up into the disjoint regions specified by `regionRecord`.
|
|
80
|
+
* Returned is a list of tuples, the first item being the key of `regionRecord` if there
|
|
81
|
+
* was a corresponding region, or `null` if there was no corresponding region.
|
|
82
|
+
*
|
|
83
|
+
* This function assumes that the regions in `regionRecord` are disjoint and fully contained
|
|
84
|
+
* within the bounds of `array`.
|
|
85
|
+
*/
|
|
63
86
|
function splitByRegions(array, regionsRecord) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
continue;
|
|
81
|
-
}
|
|
82
|
-
const regionKey = reverseMap["" + [start, end]];
|
|
83
|
-
ret.push([regionKey || null, array.slice(start, end)]);
|
|
84
|
-
}
|
|
85
|
-
return ret;
|
|
87
|
+
const ret = [];
|
|
88
|
+
const indices = [0, array.length];
|
|
89
|
+
const reverseMap = {};
|
|
90
|
+
for (const [key, records] of Object.entries(regionsRecord)) indices.push(...records.flatMap((r) => {
|
|
91
|
+
reverseMap["" + [r.start, r.end]] = key;
|
|
92
|
+
return [r.start, r.end];
|
|
93
|
+
}));
|
|
94
|
+
indices.sort((a, b) => a - b);
|
|
95
|
+
for (let i = 0; i < indices.length - 1; i++) {
|
|
96
|
+
const start = indices[i];
|
|
97
|
+
const end = indices[i + 1];
|
|
98
|
+
if (start === end) continue;
|
|
99
|
+
const regionKey = reverseMap["" + [start, end]];
|
|
100
|
+
ret.push([regionKey || null, array.slice(start, end)]);
|
|
101
|
+
}
|
|
102
|
+
return ret;
|
|
86
103
|
}
|
|
104
|
+
//#endregion
|
|
105
|
+
//#region libs/reparse-macro-names.ts
|
|
106
|
+
/**
|
|
107
|
+
* Escape a string so that it can be used to build a regular expression.
|
|
108
|
+
*
|
|
109
|
+
* From: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
|
|
110
|
+
*/
|
|
87
111
|
function escapeRegExp(str) {
|
|
88
|
-
|
|
112
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
89
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Build a regular expression that matches everything up to the first non-allowed symbol.
|
|
116
|
+
*/
|
|
90
117
|
function buildWordRegex(allowedSet) {
|
|
91
|
-
|
|
92
|
-
|
|
118
|
+
const regexpStr = `^(${["\\p{L}"].concat(Array.from(allowedSet).map(escapeRegExp)).join("|")})*`;
|
|
119
|
+
return new RegExp(regexpStr, "u");
|
|
93
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Checks whether the array has a macro that could be reparsed given the `allowedTokens` but
|
|
123
|
+
* do not do any reparsing. This function can be used in auto-detection schemes to determine if
|
|
124
|
+
* macro names should actually be reparsed.
|
|
125
|
+
*/
|
|
94
126
|
function hasReparsableMacroNamesInArray(tree, allowedTokens) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
return false;
|
|
127
|
+
for (let i = 0; i < tree.length; i++) {
|
|
128
|
+
const macro = tree[i];
|
|
129
|
+
const string = tree[i + 1];
|
|
130
|
+
if (_unified_latex_unified_latex_util_match.match.anyMacro(macro) && _unified_latex_unified_latex_util_match.match.anyString(string)) {
|
|
131
|
+
if (allowedTokens.has(macro.content.charAt(macro.content.length - 1)) || allowedTokens.has(string.content.charAt(0))) return true;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return false;
|
|
107
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* Checks whether `tree` has a macro that could be reparsed given the `allowedTokens` but
|
|
138
|
+
* do not do any reparsing. This function can be used in auto-detection schemes to determine if
|
|
139
|
+
* macro names should actually be reparsed.
|
|
140
|
+
*/
|
|
108
141
|
function hasReparsableMacroNames(tree, allowedTokens) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
(nodes) => {
|
|
124
|
-
if (hasReparsableMacroNamesInArray(nodes, _allowedTokens)) {
|
|
125
|
-
ret = true;
|
|
126
|
-
return unifiedLatexUtilVisit.EXIT;
|
|
127
|
-
}
|
|
128
|
-
},
|
|
129
|
-
{ includeArrays: true, test: Array.isArray }
|
|
130
|
-
);
|
|
131
|
-
return ret;
|
|
142
|
+
if (typeof allowedTokens === "string") allowedTokens = new Set(allowedTokens.split(""));
|
|
143
|
+
const _allowedTokens = allowedTokens;
|
|
144
|
+
for (const v of _allowedTokens) if (v.length > 1) throw new Error(`Only single characters are allowed as \`allowedTokens\` when reparsing macro names, not \`${v}\`.`);
|
|
145
|
+
let ret = false;
|
|
146
|
+
(0, _unified_latex_unified_latex_util_visit.visit)(tree, (nodes) => {
|
|
147
|
+
if (hasReparsableMacroNamesInArray(nodes, _allowedTokens)) {
|
|
148
|
+
ret = true;
|
|
149
|
+
return _unified_latex_unified_latex_util_visit.EXIT;
|
|
150
|
+
}
|
|
151
|
+
}, {
|
|
152
|
+
includeArrays: true,
|
|
153
|
+
test: Array.isArray
|
|
154
|
+
});
|
|
155
|
+
return ret;
|
|
132
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* Reparses all macro names in the array so that they may optionally include characters listed in `allowedTokens`.
|
|
159
|
+
* This is used, for example, when parsing expl3 syntax which allows `_` to be used in a macro name (even though
|
|
160
|
+
* `_` is normally stops the parsing for a macro name).
|
|
161
|
+
*/
|
|
133
162
|
function reparseMacroNamesInArray(tree, allowedTokens) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
macro.position.end.column += takeable.length;
|
|
162
|
-
}
|
|
163
|
-
if ((_c = string.position) == null ? void 0 : _c.start) {
|
|
164
|
-
string.position.start.offset += takeable.length;
|
|
165
|
-
string.position.start.column += takeable.length;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
} else {
|
|
169
|
-
i++;
|
|
170
|
-
}
|
|
171
|
-
} else {
|
|
172
|
-
++i;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
163
|
+
const regex = buildWordRegex(allowedTokens);
|
|
164
|
+
let i = 0;
|
|
165
|
+
while (i < tree.length) {
|
|
166
|
+
const macro = tree[i];
|
|
167
|
+
const string = tree[i + 1];
|
|
168
|
+
if (_unified_latex_unified_latex_util_match.match.anyMacro(macro) && (macro.escapeToken == null || macro.escapeToken === "\\") && _unified_latex_unified_latex_util_match.match.anyString(string) && (allowedTokens.has(macro.content.charAt(macro.content.length - 1)) || allowedTokens.has(string.content.charAt(0)))) {
|
|
169
|
+
const match = string.content.match(regex);
|
|
170
|
+
const takeable = match ? match[0] : "";
|
|
171
|
+
if (takeable.length > 0) if (takeable.length === string.content.length) {
|
|
172
|
+
macro.content += string.content;
|
|
173
|
+
tree.splice(i + 1, 1);
|
|
174
|
+
if (macro.position && string.position?.end) macro.position.end = string.position.end;
|
|
175
|
+
} else {
|
|
176
|
+
macro.content += takeable;
|
|
177
|
+
string.content = string.content.slice(takeable.length);
|
|
178
|
+
if (macro.position?.end) {
|
|
179
|
+
macro.position.end.offset += takeable.length;
|
|
180
|
+
macro.position.end.column += takeable.length;
|
|
181
|
+
}
|
|
182
|
+
if (string.position?.start) {
|
|
183
|
+
string.position.start.offset += takeable.length;
|
|
184
|
+
string.position.start.column += takeable.length;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else i++;
|
|
188
|
+
} else ++i;
|
|
189
|
+
}
|
|
175
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* Reparses all macro names so that they may optionally include characters listed in `allowedTokens`.
|
|
193
|
+
* This is used, for example, when parsing expl3 syntax which allows `_` to be used in a macro name (even though
|
|
194
|
+
* `_` is normally stops the parsing for a macro name). Thus, a macro `\foo_bar:Nn` would be parsed as having
|
|
195
|
+
* the name `foo_bar:Nn` rather than as `foo` followed by the strings `_`, `bar`, `:`, `Nn`.
|
|
196
|
+
*/
|
|
176
197
|
function reparseMacroNames(tree, allowedTokens) {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
unifiedLatexUtilVisit.visit(
|
|
189
|
-
tree,
|
|
190
|
-
(nodes) => {
|
|
191
|
-
reparseMacroNamesInArray(nodes, _allowedTokens);
|
|
192
|
-
},
|
|
193
|
-
{ includeArrays: true, test: Array.isArray }
|
|
194
|
-
);
|
|
198
|
+
if (typeof allowedTokens === "string") allowedTokens = new Set(allowedTokens.split(""));
|
|
199
|
+
const _allowedTokens = allowedTokens;
|
|
200
|
+
for (const v of _allowedTokens) if (v.length > 1) throw new Error(`Only single characters are allowed as \`allowedTokens\` when reparsing macro names, not \`${v}\`.`);
|
|
201
|
+
(0, _unified_latex_unified_latex_util_visit.visit)(tree, (nodes) => {
|
|
202
|
+
reparseMacroNamesInArray(nodes, _allowedTokens);
|
|
203
|
+
}, {
|
|
204
|
+
includeArrays: true,
|
|
205
|
+
test: Array.isArray
|
|
206
|
+
});
|
|
195
207
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
208
|
+
//#endregion
|
|
209
|
+
//#region libs/special-regions.ts
|
|
210
|
+
var expl3Find = {
|
|
211
|
+
start: _unified_latex_unified_latex_util_match.match.createMacroMatcher(["ExplSyntaxOn"]),
|
|
212
|
+
end: _unified_latex_unified_latex_util_match.match.createMacroMatcher(["ExplSyntaxOff"])
|
|
199
213
|
};
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
214
|
+
var atLetterFind = {
|
|
215
|
+
start: _unified_latex_unified_latex_util_match.match.createMacroMatcher(["makeatletter"]),
|
|
216
|
+
end: _unified_latex_unified_latex_util_match.match.createMacroMatcher(["makeatother"])
|
|
203
217
|
};
|
|
218
|
+
/**
|
|
219
|
+
* Find regions between `\ExplSyntaxOn...\ExplSyntaxOff` and `\makeatletter...\makeatother`.
|
|
220
|
+
* Returns an object containing regions where one or both syntax's apply.
|
|
221
|
+
*/
|
|
204
222
|
function findExpl3AndAtLetterRegionsInArray(tree) {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
ret.explOnly.push(region);
|
|
231
|
-
}
|
|
232
|
-
if (regionMap.get(v) === "atLetter") {
|
|
233
|
-
ret.atLetterOnly.push(region);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
ret.explOnly = ret.explOnly.filter((r) => r.end - r.start > 1);
|
|
238
|
-
ret.atLetterOnly = ret.atLetterOnly.filter((r) => r.end - r.start > 1);
|
|
239
|
-
ret.both = ret.both.filter((r) => r.end - r.start > 1);
|
|
240
|
-
return ret;
|
|
223
|
+
const expl3 = findRegionInArray(tree, expl3Find.start, expl3Find.end);
|
|
224
|
+
const atLetter = findRegionInArray(tree, atLetterFind.start, atLetterFind.end);
|
|
225
|
+
const regionMap = new Map([...expl3.map((x) => [x, "expl"]), ...atLetter.map((x) => [x, "atLetter"])]);
|
|
226
|
+
const all = refineRegions([...expl3, ...atLetter]);
|
|
227
|
+
const ret = {
|
|
228
|
+
explOnly: [],
|
|
229
|
+
atLetterOnly: [],
|
|
230
|
+
both: []
|
|
231
|
+
};
|
|
232
|
+
for (let i = 0; i < all.regions.length; i++) {
|
|
233
|
+
const region = all.regions[i];
|
|
234
|
+
const containedIn = all.regionsContainedIn[i];
|
|
235
|
+
if (containedIn.size === 2) {
|
|
236
|
+
ret.both.push(region);
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
for (const v of containedIn.values()) {
|
|
240
|
+
if (regionMap.get(v) === "expl") ret.explOnly.push(region);
|
|
241
|
+
if (regionMap.get(v) === "atLetter") ret.atLetterOnly.push(region);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
ret.explOnly = ret.explOnly.filter((r) => r.end - r.start > 1);
|
|
245
|
+
ret.atLetterOnly = ret.atLetterOnly.filter((r) => r.end - r.start > 1);
|
|
246
|
+
ret.both = ret.both.filter((r) => r.end - r.start > 1);
|
|
247
|
+
return ret;
|
|
241
248
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
249
|
+
var atLetterSet = new Set(["@"]);
|
|
250
|
+
var explSet = new Set(["_", ":"]);
|
|
251
|
+
var bothSet = new Set([
|
|
252
|
+
"_",
|
|
253
|
+
":",
|
|
254
|
+
"@"
|
|
255
|
+
]);
|
|
256
|
+
/**
|
|
257
|
+
* Find regions between `\ExplSyntaxOn...\ExplSyntaxOff` and `\makeatletter...\makeatother`
|
|
258
|
+
* and reparse their contents so that the relevant characters (e.g., `@`, `_`, and `:`) become
|
|
259
|
+
* part of the macro names.
|
|
260
|
+
*/
|
|
245
261
|
function reparseExpl3AndAtLetterRegions(tree) {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
`Unexpected case when splitting ${key}`
|
|
277
|
-
);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
nodes.length = 0;
|
|
281
|
-
nodes.push(...processed);
|
|
282
|
-
return unifiedLatexUtilVisit.SKIP;
|
|
283
|
-
}
|
|
284
|
-
},
|
|
285
|
-
{ includeArrays: true, test: Array.isArray }
|
|
286
|
-
);
|
|
262
|
+
(0, _unified_latex_unified_latex_util_visit.visit)(tree, { leave: (nodes) => {
|
|
263
|
+
const regions = findExpl3AndAtLetterRegionsInArray(nodes);
|
|
264
|
+
if (regions.both.length + regions.atLetterOnly.length + regions.explOnly.length === 0) return;
|
|
265
|
+
const splits = splitByRegions(nodes, regions);
|
|
266
|
+
const processed = [];
|
|
267
|
+
for (const [key, slice] of splits) switch (key) {
|
|
268
|
+
case null:
|
|
269
|
+
processed.push(...slice);
|
|
270
|
+
continue;
|
|
271
|
+
case "atLetterOnly":
|
|
272
|
+
reparseMacroNames(slice, atLetterSet);
|
|
273
|
+
processed.push(...slice);
|
|
274
|
+
continue;
|
|
275
|
+
case "explOnly":
|
|
276
|
+
reparseMacroNames(slice, explSet);
|
|
277
|
+
processed.push(...slice);
|
|
278
|
+
continue;
|
|
279
|
+
case "both":
|
|
280
|
+
reparseMacroNames(slice, bothSet);
|
|
281
|
+
processed.push(...slice);
|
|
282
|
+
continue;
|
|
283
|
+
default: throw new Error(`Unexpected case when splitting ${key}`);
|
|
284
|
+
}
|
|
285
|
+
nodes.length = 0;
|
|
286
|
+
nodes.push(...processed);
|
|
287
|
+
return _unified_latex_unified_latex_util_visit.SKIP;
|
|
288
|
+
} }, {
|
|
289
|
+
includeArrays: true,
|
|
290
|
+
test: Array.isArray
|
|
291
|
+
});
|
|
287
292
|
}
|
|
293
|
+
//#endregion
|
|
294
|
+
//#region index.ts
|
|
295
|
+
/**
|
|
296
|
+
* ## What is this?
|
|
297
|
+
*
|
|
298
|
+
* Functions to identify regions of a `unified-latex` Abstract Syntax Tree (AST) that need to be reparsed because of different
|
|
299
|
+
* category codes. For example, regions between `\makeatletter` and `\makeatother`.
|
|
300
|
+
*
|
|
301
|
+
* ## When should I use this?
|
|
302
|
+
*
|
|
303
|
+
* If you need to identify regions of the AST that need to be reparsed.
|
|
304
|
+
*/
|
|
305
|
+
//#endregion
|
|
288
306
|
exports.findExpl3AndAtLetterRegionsInArray = findExpl3AndAtLetterRegionsInArray;
|
|
289
307
|
exports.findRegionInArray = findRegionInArray;
|
|
290
308
|
exports.hasReparsableMacroNames = hasReparsableMacroNames;
|
|
@@ -292,4 +310,5 @@ exports.hasReparsableMacroNamesInArray = hasReparsableMacroNamesInArray;
|
|
|
292
310
|
exports.reparseExpl3AndAtLetterRegions = reparseExpl3AndAtLetterRegions;
|
|
293
311
|
exports.reparseMacroNames = reparseMacroNames;
|
|
294
312
|
exports.reparseMacroNamesInArray = reparseMacroNamesInArray;
|
|
295
|
-
|
|
313
|
+
|
|
314
|
+
//# sourceMappingURL=index.cjs.map
|