@unified-latex/unified-latex-util-catcode 1.3.2 → 1.4.2

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 CHANGED
@@ -51,8 +51,246 @@ function findRegionInArray(tree, start, end) {
51
51
  return ret;
52
52
  }
53
53
 
54
- // libs/special-regions.ts
55
- var import_unified_latex_util_match2 = require("@unified-latex/unified-latex-util-match");
54
+ // ../unified-latex-util-print-raw/dist/index.js
55
+ var linebreak = Symbol("linebreak");
56
+ var ESCAPE = "\\";
57
+ function _printRaw(node) {
58
+ if (typeof node === "string") {
59
+ return [node];
60
+ }
61
+ if (Array.isArray(node)) {
62
+ return [].concat(
63
+ ...node.map((n) => _printRaw(n))
64
+ );
65
+ }
66
+ let argsString, escape;
67
+ switch (node.type) {
68
+ case "root":
69
+ return _printRaw(node.content);
70
+ case "argument":
71
+ return [node.openMark, ..._printRaw(node.content), node.closeMark];
72
+ case "comment":
73
+ var suffix = node.suffixParbreak ? "" : linebreak;
74
+ var leadingWhitespace = "";
75
+ if (node.sameline && node.leadingWhitespace) {
76
+ leadingWhitespace = " ";
77
+ }
78
+ if (node.sameline) {
79
+ return [
80
+ leadingWhitespace,
81
+ "%",
82
+ ..._printRaw(node.content),
83
+ suffix
84
+ ];
85
+ }
86
+ return [linebreak, "%", ..._printRaw(node.content), suffix];
87
+ case "environment":
88
+ case "mathenv":
89
+ case "verbatim":
90
+ var env = _printRaw(node.env);
91
+ var envStart = [ESCAPE + "begin{", ...env, "}"];
92
+ var envEnd = [ESCAPE + "end{", ...env, "}"];
93
+ argsString = node.args == null ? [] : _printRaw(node.args);
94
+ return [
95
+ ...envStart,
96
+ ...argsString,
97
+ ..._printRaw(node.content),
98
+ ...envEnd
99
+ ];
100
+ case "displaymath":
101
+ return [ESCAPE + "[", ..._printRaw(node.content), ESCAPE + "]"];
102
+ case "group":
103
+ return ["{", ..._printRaw(node.content), "}"];
104
+ case "inlinemath":
105
+ return ["$", ..._printRaw(node.content), "$"];
106
+ case "macro":
107
+ argsString = node.args == null ? [] : _printRaw(node.args);
108
+ escape = node.escapeToken == null ? ESCAPE : node.escapeToken;
109
+ return [escape, ..._printRaw(node.content), ...argsString];
110
+ case "parbreak":
111
+ return [linebreak, linebreak];
112
+ case "string":
113
+ return [node.content];
114
+ case "verb":
115
+ return [
116
+ ESCAPE,
117
+ node.env,
118
+ node.escape,
119
+ ..._printRaw(node.content),
120
+ node.escape
121
+ ];
122
+ case "whitespace":
123
+ return [" "];
124
+ default:
125
+ console.warn(
126
+ "Cannot find render for node ",
127
+ node,
128
+ `(of type ${typeof node})`
129
+ );
130
+ return ["" + node];
131
+ }
132
+ }
133
+ function printRaw(node, options) {
134
+ const asArray = options != null ? options.asArray : false;
135
+ const printedTokens = _printRaw(node);
136
+ if (asArray) {
137
+ return printedTokens;
138
+ }
139
+ return printedTokens.map((x) => x === linebreak ? "\n" : x).join("");
140
+ }
141
+
142
+ // ../unified-latex-util-match/dist/index.js
143
+ function createMacroMatcher(macros) {
144
+ const macrosHash = Array.isArray(macros) ? macros.length > 0 ? typeof macros[0] === "string" ? Object.fromEntries(
145
+ macros.map((macro2) => {
146
+ if (typeof macro2 !== "string") {
147
+ throw new Error("Wrong branch of map function");
148
+ }
149
+ return [macro2, {}];
150
+ })
151
+ ) : Object.fromEntries(
152
+ macros.map((macro2) => {
153
+ if (typeof macro2 === "string") {
154
+ throw new Error("Wrong branch of map function");
155
+ }
156
+ if (macro2.escapeToken != null) {
157
+ return [
158
+ macro2.content,
159
+ { escapeToken: macro2.escapeToken }
160
+ ];
161
+ }
162
+ return [macro2.content, {}];
163
+ })
164
+ ) : {} : macros;
165
+ return function matchAgainstMacros(node) {
166
+ if (node == null || node.type !== "macro") {
167
+ return false;
168
+ }
169
+ const spec = macrosHash[node.content];
170
+ if (!spec) {
171
+ return false;
172
+ }
173
+ if (typeof spec === "object" && "escapeToken" in spec) {
174
+ return spec.escapeToken == null || spec.escapeToken === node.escapeToken;
175
+ }
176
+ return true;
177
+ };
178
+ }
179
+ function createEnvironmentMatcher(macros) {
180
+ const environmentsHash = Array.isArray(macros) ? Object.fromEntries(
181
+ macros.map((str) => {
182
+ return [str, {}];
183
+ })
184
+ ) : macros;
185
+ return function matchAgainstEnvironments(node) {
186
+ if (!match.anyEnvironment(node)) {
187
+ return false;
188
+ }
189
+ const envName = printRaw(node.env);
190
+ const spec = environmentsHash[envName];
191
+ if (!spec) {
192
+ return false;
193
+ }
194
+ return true;
195
+ };
196
+ }
197
+ var match = {
198
+ macro(node, macroName) {
199
+ if (node == null) {
200
+ return false;
201
+ }
202
+ return node.type === "macro" && (macroName == null || node.content === macroName);
203
+ },
204
+ anyMacro(node) {
205
+ return match.macro(node);
206
+ },
207
+ environment(node, envName) {
208
+ if (node == null) {
209
+ return false;
210
+ }
211
+ return (node.type === "environment" || node.type === "mathenv") && (envName == null || printRaw(node.env) === envName);
212
+ },
213
+ anyEnvironment(node) {
214
+ return match.environment(node);
215
+ },
216
+ comment(node) {
217
+ if (node == null) {
218
+ return false;
219
+ }
220
+ return node.type === "comment";
221
+ },
222
+ parbreak(node) {
223
+ if (node == null) {
224
+ return false;
225
+ }
226
+ return node.type === "parbreak";
227
+ },
228
+ whitespace(node) {
229
+ if (node == null) {
230
+ return false;
231
+ }
232
+ return node.type === "whitespace";
233
+ },
234
+ /**
235
+ * Matches whitespace or a comment with leading whitespace.
236
+ */
237
+ whitespaceLike(node) {
238
+ if (node == null) {
239
+ return false;
240
+ }
241
+ return node.type === "whitespace" || node.type === "whitespace" && node.leadingWhitespace === true;
242
+ },
243
+ string(node, value) {
244
+ if (node == null) {
245
+ return false;
246
+ }
247
+ return node.type === "string" && (value == null || node.content === value);
248
+ },
249
+ anyString(node) {
250
+ return match.string(node);
251
+ },
252
+ group(node) {
253
+ if (node == null) {
254
+ return false;
255
+ }
256
+ return node.type === "group";
257
+ },
258
+ argument(node) {
259
+ if (node == null) {
260
+ return false;
261
+ }
262
+ return node.type === "argument";
263
+ },
264
+ blankArgument(node) {
265
+ if (!match.argument(node)) {
266
+ return false;
267
+ }
268
+ return node.openMark === "" && node.closeMark === "" && node.content.length === 0;
269
+ },
270
+ math(node) {
271
+ if (node == null) {
272
+ return false;
273
+ }
274
+ return node.type === "displaymath" || node.type === "inlinemath";
275
+ },
276
+ createMacroMatcher,
277
+ createEnvironmentMatcher
278
+ };
279
+ var {
280
+ anyEnvironment,
281
+ anyMacro,
282
+ anyString,
283
+ argument,
284
+ blankArgument,
285
+ comment,
286
+ environment,
287
+ group,
288
+ macro,
289
+ math,
290
+ parbreak,
291
+ string,
292
+ whitespace
293
+ } = match;
56
294
 
57
295
  // libs/regions.ts
58
296
  function refineRegions(regions) {
@@ -119,12 +357,171 @@ function splitByRegions(array, regionsRecord) {
119
357
  return ret;
120
358
  }
121
359
 
122
- // libs/special-regions.ts
123
- var import_unified_latex_util_visit2 = require("@unified-latex/unified-latex-util-visit");
360
+ // ../unified-latex-util-visit/dist/index.js
361
+ function listMathChildren(node) {
362
+ const NULL_RETURN = { enter: [], leave: [] };
363
+ if (Array.isArray(node)) {
364
+ return NULL_RETURN;
365
+ }
366
+ if (match.math(node)) {
367
+ return { enter: ["content"], leave: [] };
368
+ }
369
+ const renderInfo = node._renderInfo || {};
370
+ if (renderInfo.inMathMode == null) {
371
+ return NULL_RETURN;
372
+ }
373
+ if (match.macro(node)) {
374
+ if (renderInfo.inMathMode === true) {
375
+ return { enter: ["args"], leave: [] };
376
+ } else if (renderInfo.inMathMode === false) {
377
+ return { enter: [], leave: ["args"] };
378
+ }
379
+ }
380
+ if (match.environment(node)) {
381
+ if (renderInfo.inMathMode === true) {
382
+ return { enter: ["content"], leave: [] };
383
+ } else {
384
+ return { enter: [], leave: ["content"] };
385
+ }
386
+ }
387
+ return NULL_RETURN;
388
+ }
389
+ var CONTINUE = Symbol("continue");
390
+ var SKIP = Symbol("skip");
391
+ var EXIT = Symbol("exit");
392
+ var DEFAULT_CONTEXT = {
393
+ inMathMode: false,
394
+ hasMathModeAncestor: false
395
+ };
396
+ function visit(tree, visitor, options) {
397
+ const {
398
+ startingContext = DEFAULT_CONTEXT,
399
+ test = () => true,
400
+ includeArrays = false
401
+ } = options || {};
402
+ let enter;
403
+ let leave;
404
+ if (typeof visitor === "function") {
405
+ enter = visitor;
406
+ } else if (visitor && typeof visitor === "object") {
407
+ enter = visitor.enter;
408
+ leave = visitor.leave;
409
+ }
410
+ walk(tree, {
411
+ key: void 0,
412
+ index: void 0,
413
+ parents: [],
414
+ containingArray: void 0,
415
+ context: { ...startingContext }
416
+ });
417
+ function walk(node, { key, index, parents, context, containingArray }) {
418
+ const nodePassesTest = includeArrays ? test(node, { key, index, parents, context, containingArray }) : !Array.isArray(node) && test(node, { key, index, parents, context, containingArray });
419
+ const result = enter && nodePassesTest ? toResult(
420
+ enter(node, {
421
+ key,
422
+ index,
423
+ parents,
424
+ context,
425
+ containingArray
426
+ })
427
+ ) : [CONTINUE];
428
+ if (result[0] === EXIT) {
429
+ return result;
430
+ }
431
+ if (result[0] === SKIP) {
432
+ return leave && nodePassesTest ? toResult(
433
+ leave(node, {
434
+ key,
435
+ index,
436
+ parents,
437
+ context,
438
+ containingArray
439
+ })
440
+ ) : result;
441
+ }
442
+ if (Array.isArray(node)) {
443
+ for (let index2 = 0; index2 > -1 && index2 < node.length; index2++) {
444
+ const item = node[index2];
445
+ const result2 = walk(item, {
446
+ key,
447
+ index: index2,
448
+ parents,
449
+ context,
450
+ containingArray: node
451
+ });
452
+ if (result2[0] === EXIT) {
453
+ return result2;
454
+ }
455
+ if (typeof result2[1] === "number") {
456
+ index2 = result2[1] - 1;
457
+ }
458
+ }
459
+ } else {
460
+ let childProps = ["content", "args"];
461
+ switch (node.type) {
462
+ case "macro":
463
+ childProps = ["args"];
464
+ break;
465
+ case "comment":
466
+ case "string":
467
+ case "verb":
468
+ case "verbatim":
469
+ childProps = [];
470
+ break;
471
+ default:
472
+ break;
473
+ }
474
+ const mathModeProps = listMathChildren(node);
475
+ for (const key2 of childProps) {
476
+ const value = node[key2];
477
+ const grandparents = [node].concat(parents);
478
+ if (value == null) {
479
+ continue;
480
+ }
481
+ const newContext = { ...context };
482
+ if (mathModeProps.enter.includes(key2)) {
483
+ newContext.inMathMode = true;
484
+ newContext.hasMathModeAncestor = true;
485
+ } else if (mathModeProps.leave.includes(key2)) {
486
+ newContext.inMathMode = false;
487
+ }
488
+ const result2 = walk(value, {
489
+ key: key2,
490
+ index: void 0,
491
+ parents: grandparents,
492
+ context: newContext,
493
+ containingArray: void 0
494
+ });
495
+ if (result2[0] === EXIT) {
496
+ return result2;
497
+ }
498
+ }
499
+ }
500
+ return leave && nodePassesTest ? toResult(
501
+ leave(node, {
502
+ key,
503
+ index,
504
+ parents,
505
+ context,
506
+ containingArray
507
+ })
508
+ ) : result;
509
+ }
510
+ }
511
+ function toResult(value) {
512
+ if (value == null) {
513
+ return [CONTINUE];
514
+ }
515
+ if (Array.isArray(value)) {
516
+ return value;
517
+ }
518
+ if (typeof value === "number") {
519
+ return [CONTINUE, value];
520
+ }
521
+ return [value];
522
+ }
124
523
 
125
524
  // libs/reparse-macro-names.ts
126
- var import_unified_latex_util_match = require("@unified-latex/unified-latex-util-match");
127
- var import_unified_latex_util_visit = require("@unified-latex/unified-latex-util-visit");
128
525
  function escapeRegExp(str) {
129
526
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
130
527
  }
@@ -134,12 +531,12 @@ function buildWordRegex(allowedSet) {
134
531
  }
135
532
  function hasReparsableMacroNamesInArray(tree, allowedTokens) {
136
533
  for (let i = 0; i < tree.length; i++) {
137
- const macro = tree[i];
138
- const string = tree[i + 1];
139
- if (import_unified_latex_util_match.match.anyMacro(macro) && import_unified_latex_util_match.match.anyString(string)) {
534
+ const macro2 = tree[i];
535
+ const string2 = tree[i + 1];
536
+ if (match.anyMacro(macro2) && match.anyString(string2)) {
140
537
  if (allowedTokens.has(
141
- macro.content.charAt(macro.content.length - 1)
142
- ) || allowedTokens.has(string.content.charAt(0))) {
538
+ macro2.content.charAt(macro2.content.length - 1)
539
+ ) || allowedTokens.has(string2.content.charAt(0))) {
143
540
  return true;
144
541
  }
145
542
  }
@@ -159,12 +556,12 @@ function hasReparsableMacroNames(tree, allowedTokens) {
159
556
  }
160
557
  }
161
558
  let ret = false;
162
- (0, import_unified_latex_util_visit.visit)(
559
+ visit(
163
560
  tree,
164
561
  (nodes) => {
165
562
  if (hasReparsableMacroNamesInArray(nodes, _allowedTokens)) {
166
563
  ret = true;
167
- return import_unified_latex_util_visit.EXIT;
564
+ return EXIT;
168
565
  }
169
566
  },
170
567
  { includeArrays: true, test: Array.isArray }
@@ -176,34 +573,34 @@ function reparseMacroNamesInArray(tree, allowedTokens) {
176
573
  const regex = buildWordRegex(allowedTokens);
177
574
  let i = 0;
178
575
  while (i < tree.length) {
179
- const macro = tree[i];
180
- const string = tree[i + 1];
181
- if (import_unified_latex_util_match.match.anyMacro(macro) && // The _^ macros in math mode should not be extended no-matter what;
576
+ const macro2 = tree[i];
577
+ const string2 = tree[i + 1];
578
+ if (match.anyMacro(macro2) && // The _^ macros in math mode should not be extended no-matter what;
182
579
  // So we check to make sure that the macro we're dealing with has the default escape token.
183
- (macro.escapeToken == null || macro.escapeToken === "\\") && import_unified_latex_util_match.match.anyString(string) && // There are two options. Either the macro ends with the special character,
580
+ (macro2.escapeToken == null || macro2.escapeToken === "\\") && match.anyString(string2) && // There are two options. Either the macro ends with the special character,
184
581
  // e.g. `\@foo` or the special character starts the next string, e.g. `\foo@`.
185
582
  (allowedTokens.has(
186
- macro.content.charAt(macro.content.length - 1)
187
- ) || allowedTokens.has(string.content.charAt(0)))) {
188
- const match3 = string.content.match(regex);
189
- const takeable = match3 ? match3[0] : "";
583
+ macro2.content.charAt(macro2.content.length - 1)
584
+ ) || allowedTokens.has(string2.content.charAt(0)))) {
585
+ const match2 = string2.content.match(regex);
586
+ const takeable = match2 ? match2[0] : "";
190
587
  if (takeable.length > 0) {
191
- if (takeable.length === string.content.length) {
192
- macro.content += string.content;
588
+ if (takeable.length === string2.content.length) {
589
+ macro2.content += string2.content;
193
590
  tree.splice(i + 1, 1);
194
- if (macro.position && ((_a = string.position) == null ? void 0 : _a.end)) {
195
- macro.position.end = string.position.end;
591
+ if (macro2.position && ((_a = string2.position) == null ? void 0 : _a.end)) {
592
+ macro2.position.end = string2.position.end;
196
593
  }
197
594
  } else {
198
- macro.content += takeable;
199
- string.content = string.content.slice(takeable.length);
200
- if ((_b = macro.position) == null ? void 0 : _b.end) {
201
- macro.position.end.offset += takeable.length;
202
- macro.position.end.column += takeable.length;
595
+ macro2.content += takeable;
596
+ string2.content = string2.content.slice(takeable.length);
597
+ if ((_b = macro2.position) == null ? void 0 : _b.end) {
598
+ macro2.position.end.offset += takeable.length;
599
+ macro2.position.end.column += takeable.length;
203
600
  }
204
- if ((_c = string.position) == null ? void 0 : _c.start) {
205
- string.position.start.offset += takeable.length;
206
- string.position.start.column += takeable.length;
601
+ if ((_c = string2.position) == null ? void 0 : _c.start) {
602
+ string2.position.start.offset += takeable.length;
603
+ string2.position.start.column += takeable.length;
207
604
  }
208
605
  }
209
606
  } else {
@@ -226,7 +623,7 @@ function reparseMacroNames(tree, allowedTokens) {
226
623
  );
227
624
  }
228
625
  }
229
- (0, import_unified_latex_util_visit.visit)(
626
+ visit(
230
627
  tree,
231
628
  (nodes) => {
232
629
  reparseMacroNamesInArray(nodes, _allowedTokens);
@@ -237,12 +634,12 @@ function reparseMacroNames(tree, allowedTokens) {
237
634
 
238
635
  // libs/special-regions.ts
239
636
  var expl3Find = {
240
- start: import_unified_latex_util_match2.match.createMacroMatcher(["ExplSyntaxOn"]),
241
- end: import_unified_latex_util_match2.match.createMacroMatcher(["ExplSyntaxOff"])
637
+ start: match.createMacroMatcher(["ExplSyntaxOn"]),
638
+ end: match.createMacroMatcher(["ExplSyntaxOff"])
242
639
  };
243
640
  var atLetterFind = {
244
- start: import_unified_latex_util_match2.match.createMacroMatcher(["makeatletter"]),
245
- end: import_unified_latex_util_match2.match.createMacroMatcher(["makeatother"])
641
+ start: match.createMacroMatcher(["makeatletter"]),
642
+ end: match.createMacroMatcher(["makeatother"])
246
643
  };
247
644
  function findExpl3AndAtLetterRegionsInArray(tree) {
248
645
  const expl3 = findRegionInArray(tree, expl3Find.start, expl3Find.end);
@@ -286,7 +683,7 @@ var atLetterSet = /* @__PURE__ */ new Set(["@"]);
286
683
  var explSet = /* @__PURE__ */ new Set(["_", ":"]);
287
684
  var bothSet = /* @__PURE__ */ new Set(["_", ":", "@"]);
288
685
  function reparseExpl3AndAtLetterRegions(tree) {
289
- (0, import_unified_latex_util_visit2.visit)(
686
+ visit(
290
687
  tree,
291
688
  {
292
689
  leave: (nodes) => {
@@ -322,7 +719,7 @@ function reparseExpl3AndAtLetterRegions(tree) {
322
719
  }
323
720
  nodes.length = 0;
324
721
  nodes.push(...processed);
325
- return import_unified_latex_util_visit2.SKIP;
722
+ return SKIP;
326
723
  }
327
724
  },
328
725
  { includeArrays: true, test: Array.isArray }
package/index.cjs.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../index.ts", "../libs/find-region.ts", "../libs/special-regions.ts", "../libs/regions.ts", "../libs/reparse-macro-names.ts"],
4
- "sourcesContent": ["export * from \"./libs/find-region\";\nexport * from \"./libs/special-regions\";\nexport * from \"./libs/reparse-macro-names\";\n\n// NOTE: The docstring comment must be the last item in the index.ts file!\n/**\n * ## What is this?\n *\n * Functions to identify regions of a `unified-latex` Abstract Syntax Tree (AST) that need to be reparsed because of different\n * category codes. For example, regions between `\\makeatletter` and `\\makeatother`.\n *\n * ## When should I use this?\n *\n * If you need to identify regions of the AST that need to be reparsed.\n */\n", "import * as Ast from \"@unified-latex/unified-latex-types\";\nimport { Region } from \"./regions\";\n\n/**\n * Find all contiguous segments in the array that are between start and end blocks.\n * The `start` and `end` are functions that determine when a region starts and ends.\n */\nexport function findRegionInArray(\n tree: Ast.Node[],\n start: (node: Ast.Node) => boolean,\n end: (node: Ast.Node) => boolean\n): Region[] {\n const ret: Region[] = [];\n let currRegion: Region = { start: undefined as any, end: tree.length };\n for (let i = 0; i < tree.length; i++) {\n const node = tree[i];\n if (start(node)) {\n currRegion.start = i;\n }\n if (end(node)) {\n currRegion.end = i + 1;\n ret.push(currRegion);\n currRegion = { start: undefined as any, end: tree.length };\n }\n }\n\n if (currRegion.start != null) {\n // Regions don't necessarily have to encounter an `end` to end.\n ret.push(currRegion);\n }\n return ret;\n}\n", "import * as Ast from \"@unified-latex/unified-latex-types\";\nimport { match } from \"@unified-latex/unified-latex-util-match\";\nimport { findRegionInArray } from \"./find-region\";\nimport { refineRegions, Region, splitByRegions } from \"./regions\";\nimport { SKIP, visit } from \"@unified-latex/unified-latex-util-visit\";\nimport { reparseMacroNames } from \"./reparse-macro-names\";\n\nconst expl3Find = {\n start: match.createMacroMatcher([\"ExplSyntaxOn\"]),\n end: match.createMacroMatcher([\"ExplSyntaxOff\"]),\n};\nconst atLetterFind = {\n start: match.createMacroMatcher([\"makeatletter\"]),\n end: match.createMacroMatcher([\"makeatother\"]),\n};\n\n/**\n * Find regions between `\\ExplSyntaxOn...\\ExplSyntaxOff` and `\\makeatletter...\\makeatother`.\n * Returns an object containing regions where one or both syntax's apply.\n */\nexport function findExpl3AndAtLetterRegionsInArray(tree: Ast.Node[]): {\n explOnly: Region[];\n atLetterOnly: Region[];\n both: Region[];\n} {\n const expl3 = findRegionInArray(tree, expl3Find.start, expl3Find.end);\n const atLetter = findRegionInArray(\n tree,\n atLetterFind.start,\n atLetterFind.end\n );\n\n const regionMap = new Map([\n ...(expl3.map((x) => [x, \"expl\"]) as [Region, \"expl\"][]),\n ...(atLetter.map((x) => [x, \"atLetter\"]) as [Region, \"atLetter\"][]),\n ]);\n const all = refineRegions([...expl3, ...atLetter]);\n\n const ret = {\n explOnly: [] as Region[],\n atLetterOnly: [] as Region[],\n both: [] as Region[],\n };\n\n for (let i = 0; i < all.regions.length; i++) {\n const region = all.regions[i];\n const containedIn = all.regionsContainedIn[i];\n if (containedIn.size === 2) {\n ret.both.push(region);\n continue;\n }\n for (const v of containedIn.values()) {\n if (regionMap.get(v) === \"expl\") {\n ret.explOnly.push(region);\n }\n if (regionMap.get(v) === \"atLetter\") {\n ret.atLetterOnly.push(region);\n }\n }\n }\n\n // Regions of size 1 only contain the starting/stopping macro, so they should be discarded\n ret.explOnly = ret.explOnly.filter((r) => r.end - r.start > 1);\n ret.atLetterOnly = ret.atLetterOnly.filter((r) => r.end - r.start > 1);\n ret.both = ret.both.filter((r) => r.end - r.start > 1);\n\n return ret;\n}\n\nconst atLetterSet = new Set([\"@\"]);\nconst explSet = new Set([\"_\", \":\"]);\nconst bothSet = new Set([\"_\", \":\", \"@\"]);\n\n/**\n * Find regions between `\\ExplSyntaxOn...\\ExplSyntaxOff` and `\\makeatletter...\\makeatother`\n * and reparse their contents so that the relevant characters (e.g., `@`, `_`, and `:`) become\n * part of the macro names.\n */\nexport function reparseExpl3AndAtLetterRegions(tree: Ast.Ast) {\n visit(\n tree,\n {\n leave: (nodes) => {\n const regions = findExpl3AndAtLetterRegionsInArray(nodes);\n // In all likelihood, we don't need to do any reparsing, so bail early here\n const totalNumRegions =\n regions.both.length +\n regions.atLetterOnly.length +\n regions.explOnly.length;\n if (totalNumRegions === 0) {\n return;\n }\n\n const splits = splitByRegions(nodes, regions);\n const processed: typeof nodes = [];\n for (const [key, slice] of splits) {\n switch (key) {\n case null:\n processed.push(...slice);\n continue;\n case \"atLetterOnly\":\n reparseMacroNames(slice, atLetterSet);\n processed.push(...slice);\n continue;\n case \"explOnly\":\n reparseMacroNames(slice, explSet);\n processed.push(...slice);\n continue;\n case \"both\":\n reparseMacroNames(slice, bothSet);\n processed.push(...slice);\n continue;\n default:\n throw new Error(\n `Unexpected case when splitting ${key}`\n );\n }\n }\n\n nodes.length = 0;\n nodes.push(...processed);\n return SKIP;\n },\n },\n { includeArrays: true, test: Array.isArray }\n );\n}\n", "import * as Ast from \"@unified-latex/unified-latex-types\";\n\nexport type Region = { start: number; end: number };\n\n/**\n * Given `regions`, a list of `Region`s (not necessarily ordered, possibly overlapping), return a list of in-order,\n * non-overlapping regions and a corresponding list containing a set of the original `Region`s that the new region\n * is a subset of.\n */\nexport function refineRegions(regions: Region[]): {\n regions: Region[];\n regionsContainedIn: Set<Region>[];\n} {\n const _regions = [...regions];\n _regions.sort((a, b) => a.start - b.start);\n const cutPointsSet = new Set(_regions.flatMap((r) => [r.start, r.end]));\n const cutPoints = Array.from(cutPointsSet);\n cutPoints.sort((a, b) => a - b);\n\n const retRegions: Region[] = [];\n const retRegionsContainedIn: Set<Region>[] = [];\n\n // We will be checking what regions we are completely contained in.\n // Because `_regions` is sorted by start, `seekIndex` will be incremented\n // by end, so that we don't do too much array testing.\n let seekIndex = 0;\n for (let i = 0; i < cutPoints.length - 1; i++) {\n const start = cutPoints[i];\n const end = cutPoints[i + 1];\n const region = { start, end };\n const regionContainedIn: Set<Region> = new Set();\n\n let encounteredEndPastStart = false;\n for (let j = seekIndex; j < _regions.length; j++) {\n const superRegion = _regions[j];\n if (superRegion.end >= region.start) {\n encounteredEndPastStart = true;\n }\n if (!encounteredEndPastStart && superRegion.end < region.start) {\n // In this case, the region (and all regions that came before)\n // end before the region we are testing, so we may safely skip past it\n // from here on out.\n seekIndex = j + 1;\n continue;\n }\n\n if (superRegion.start > end) {\n // Because `_regions` is sorted, we can stop here\n break;\n }\n if (\n superRegion.start <= region.start &&\n superRegion.end >= region.end\n ) {\n encounteredEndPastStart = true;\n regionContainedIn.add(superRegion);\n }\n }\n\n if (regionContainedIn.size > 0) {\n // We only count if we are contained in a subregion\n retRegions.push(region);\n retRegionsContainedIn.push(regionContainedIn);\n }\n }\n\n return { regions: retRegions, regionsContainedIn: retRegionsContainedIn };\n}\n\n/**\n * Split an array up into the disjoint regions specified by `regionRecord`.\n * Returned is a list of tuples, the first item being the key of `regionRecord` if there\n * was a corresponding region, or `null` if there was no corresponding region.\n *\n * This function assumes that the regions in `regionRecord` are disjoint and fully contained\n * within the bounds of `array`.\n */\nexport function splitByRegions<\n T extends unknown,\n RegionRecord extends Record<string, Region[]>\n>(array: T[], regionsRecord: RegionRecord) {\n const ret: [keyof RegionRecord | null, T[]][] = [];\n\n const indices = [0, array.length];\n const reverseMap: Record<string, keyof RegionRecord> = {};\n for (const [key, records] of Object.entries(regionsRecord)) {\n indices.push(\n ...records.flatMap((r) => {\n reverseMap[\"\" + [r.start, r.end]] = key;\n return [r.start, r.end];\n })\n );\n }\n indices.sort((a, b) => a - b);\n\n for (let i = 0; i < indices.length - 1; i++) {\n const start = indices[i];\n const end = indices[i + 1];\n if (start === end) {\n continue;\n }\n const regionKey = reverseMap[\"\" + [start, end]];\n\n ret.push([regionKey || null, array.slice(start, end)]);\n }\n\n return ret;\n}\n", "import * as Ast from \"@unified-latex/unified-latex-types\";\nimport { match } from \"@unified-latex/unified-latex-util-match\";\nimport { EXIT, visit } from \"@unified-latex/unified-latex-util-visit\";\n\n/**\n * Escape a string so that it can be used to build a regular expression.\n *\n * From: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions\n */\nfunction escapeRegExp(str: string) {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"); // $& means the whole matched string\n}\n\n/**\n * Build a regular expression that matches everything up to the first non-allowed symbol.\n */\nfunction buildWordRegex(allowedSet: Set<string>): RegExp {\n // /\\p{L}/ matches all letters, including unicode letters. We join this with\n // everything allowed in our set to form a regexp like\n // /(\\p{L}|_|:)*/u\n // The `u` at the end allows unicode characters to be matched.\n const regexpStr = `^(${[\"\\\\p{L}\"]\n .concat(Array.from(allowedSet).map(escapeRegExp))\n .join(\"|\")})*`;\n return new RegExp(regexpStr, \"u\");\n}\n\n/**\n * Checks whether the array has a macro that could be reparsed given the `allowedTokens` but\n * do not do any reparsing. This function can be used in auto-detection schemes to determine if\n * macro names should actually be reparsed.\n */\nexport function hasReparsableMacroNamesInArray(\n tree: Ast.Node[],\n allowedTokens: Set<string>\n): boolean {\n for (let i = 0; i < tree.length; i++) {\n const macro = tree[i];\n const string = tree[i + 1];\n if (match.anyMacro(macro) && match.anyString(string)) {\n // There are two options. Either the macro ends with the special character,\n // e.g. `\\@foo` or the special character starts the next string, e.g. `\\foo@`.\n if (\n allowedTokens.has(\n macro.content.charAt(macro.content.length - 1)\n ) ||\n allowedTokens.has(string.content.charAt(0))\n ) {\n return true;\n }\n }\n }\n return false;\n}\n\n/**\n * Checks whether `tree` has a macro that could be reparsed given the `allowedTokens` but\n * do not do any reparsing. This function can be used in auto-detection schemes to determine if\n * macro names should actually be reparsed.\n */\nexport function hasReparsableMacroNames(\n tree: Ast.Ast,\n allowedTokens: string | Set<string>\n): boolean {\n if (typeof allowedTokens === \"string\") {\n allowedTokens = new Set(allowedTokens.split(\"\"));\n }\n // Recast so typescript doesn't complain\n const _allowedTokens = allowedTokens;\n for (const v of _allowedTokens) {\n if (v.length > 1) {\n throw new Error(\n `Only single characters are allowed as \\`allowedTokens\\` when reparsing macro names, not \\`${v}\\`.`\n );\n }\n }\n\n let ret = false;\n visit(\n tree,\n (nodes) => {\n if (hasReparsableMacroNamesInArray(nodes, _allowedTokens)) {\n ret = true;\n return EXIT;\n }\n },\n { includeArrays: true, test: Array.isArray }\n );\n return ret;\n}\n\n/**\n * Reparses all macro names in the array so that they may optionally include characters listed in `allowedTokens`.\n * This is used, for example, when parsing expl3 syntax which allows `_` to be used in a macro name (even though\n * `_` is normally stops the parsing for a macro name).\n */\nexport function reparseMacroNamesInArray(\n tree: Ast.Node[],\n allowedTokens: Set<string>\n) {\n const regex = buildWordRegex(allowedTokens);\n let i = 0;\n while (i < tree.length) {\n const macro = tree[i];\n const string = tree[i + 1];\n if (\n match.anyMacro(macro) &&\n // The _^ macros in math mode should not be extended no-matter what;\n // So we check to make sure that the macro we're dealing with has the default escape token.\n (macro.escapeToken == null || macro.escapeToken === \"\\\\\") &&\n match.anyString(string) &&\n // There are two options. Either the macro ends with the special character,\n // e.g. `\\@foo` or the special character starts the next string, e.g. `\\foo@`.\n (allowedTokens.has(\n macro.content.charAt(macro.content.length - 1)\n ) ||\n allowedTokens.has(string.content.charAt(0)))\n ) {\n // There might be a number somewhere in the string. If so, we should\n // break the string apart at that number\n const match = string.content.match(regex);\n const takeable = match ? match[0] : \"\";\n if (takeable.length > 0) {\n if (takeable.length === string.content.length) {\n // The whole string can be appended to the macro name\n macro.content += string.content;\n tree.splice(i + 1, 1);\n\n // Preserve the source location if available\n if (macro.position && string.position?.end) {\n macro.position.end = string.position.end;\n }\n } else {\n // Only part of the string can be appended to the macro name\n macro.content += takeable;\n string.content = string.content.slice(takeable.length);\n\n // Preserve the source location if available\n if (macro.position?.end) {\n macro.position.end.offset += takeable.length;\n macro.position.end.column += takeable.length;\n }\n if (string.position?.start) {\n string.position.start.offset += takeable.length;\n string.position.start.column += takeable.length;\n }\n }\n } else {\n i++;\n }\n } else {\n ++i;\n }\n }\n}\n\n/**\n * Reparses all macro names so that they may optionally include characters listed in `allowedTokens`.\n * This is used, for example, when parsing expl3 syntax which allows `_` to be used in a macro name (even though\n * `_` is normally stops the parsing for a macro name). Thus, a macro `\\foo_bar:Nn` would be parsed as having\n * the name `foo_bar:Nn` rather than as `foo` followed by the strings `_`, `bar`, `:`, `Nn`.\n */\nexport function reparseMacroNames(\n tree: Ast.Ast,\n allowedTokens: string | Set<string>\n) {\n if (typeof allowedTokens === \"string\") {\n allowedTokens = new Set(allowedTokens.split(\"\"));\n }\n // Recast so typescript doesn't complain\n const _allowedTokens = allowedTokens;\n for (const v of _allowedTokens) {\n if (v.length > 1) {\n throw new Error(\n `Only single characters are allowed as \\`allowedTokens\\` when reparsing macro names, not \\`${v}\\`.`\n );\n }\n }\n\n visit(\n tree,\n (nodes) => {\n reparseMacroNamesInArray(nodes, _allowedTokens);\n },\n { includeArrays: true, test: Array.isArray }\n );\n}\n"],
5
- "mappings": "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",
6
- "names": ["import_unified_latex_util_match", "import_unified_latex_util_visit", "match"]
3
+ "sources": ["../index.ts", "../libs/find-region.ts", "../../unified-latex-util-print-raw/libs/print-raw.ts", "../../unified-latex-util-match/libs/match.ts", "../libs/regions.ts", "../../unified-latex-util-visit/libs/list-math-children.ts", "../../unified-latex-util-visit/libs/visit.ts", "../libs/reparse-macro-names.ts", "../libs/special-regions.ts"],
4
+ "sourcesContent": ["export * from \"./libs/find-region\";\nexport * from \"./libs/special-regions\";\nexport * from \"./libs/reparse-macro-names\";\n\n// NOTE: The docstring comment must be the last item in the index.ts file!\n/**\n * ## What is this?\n *\n * Functions to identify regions of a `unified-latex` Abstract Syntax Tree (AST) that need to be reparsed because of different\n * category codes. For example, regions between `\\makeatletter` and `\\makeatother`.\n *\n * ## When should I use this?\n *\n * If you need to identify regions of the AST that need to be reparsed.\n */\n", "import * as Ast from \"@unified-latex/unified-latex-types\";\nimport { Region } from \"./regions\";\n\n/**\n * Find all contiguous segments in the array that are between start and end blocks.\n * The `start` and `end` are functions that determine when a region starts and ends.\n */\nexport function findRegionInArray(\n tree: Ast.Node[],\n start: (node: Ast.Node) => boolean,\n end: (node: Ast.Node) => boolean\n): Region[] {\n const ret: Region[] = [];\n let currRegion: Region = { start: undefined as any, end: tree.length };\n for (let i = 0; i < tree.length; i++) {\n const node = tree[i];\n if (start(node)) {\n currRegion.start = i;\n }\n if (end(node)) {\n currRegion.end = i + 1;\n ret.push(currRegion);\n currRegion = { start: undefined as any, end: tree.length };\n }\n }\n\n if (currRegion.start != null) {\n // Regions don't necessarily have to encounter an `end` to end.\n ret.push(currRegion);\n }\n return ret;\n}\n", "import * as Ast from \"@unified-latex/unified-latex-types\";\n\ntype Printable = Ast.Node | Ast.Argument | string;\ntype PrintToken = string | typeof linebreak;\n\nexport const linebreak = Symbol(\"linebreak\");\nconst ESCAPE = \"\\\\\";\n\n/**\n * Renders the AST to an array inserting `linebreak` where needed;\n * This array may be nested.\n *\n * @param {*} node\n */\nfunction _printRaw(node: Printable | Printable[]): PrintToken[] {\n if (typeof node === \"string\") {\n return [node];\n }\n if (Array.isArray(node)) {\n return ([] as PrintToken[]).concat(\n ...node.map((n: Printable) => _printRaw(n))\n );\n }\n // tmp variables\n let argsString, escape;\n switch (node.type) {\n case \"root\":\n return _printRaw(node.content);\n case \"argument\":\n return [node.openMark, ..._printRaw(node.content), node.closeMark];\n case \"comment\":\n var suffix = node.suffixParbreak ? \"\" : linebreak;\n // A comment is responsible for printing its own leading whitespace\n var leadingWhitespace = \"\";\n if (node.sameline && node.leadingWhitespace) {\n leadingWhitespace = \" \";\n }\n if (node.sameline) {\n return [\n leadingWhitespace,\n \"%\",\n ..._printRaw(node.content),\n suffix,\n ];\n }\n return [linebreak, \"%\", ..._printRaw(node.content), suffix];\n case \"environment\":\n case \"mathenv\":\n case \"verbatim\":\n var env = _printRaw(node.env);\n var envStart: PrintToken[] = [ESCAPE + \"begin{\", ...env, \"}\"];\n var envEnd: PrintToken[] = [ESCAPE + \"end{\", ...env, \"}\"];\n argsString =\n (node as any).args == null ? [] : _printRaw((node as any).args);\n return [\n ...envStart,\n ...argsString,\n ..._printRaw(node.content),\n ...envEnd,\n ];\n case \"displaymath\":\n return [ESCAPE + \"[\", ..._printRaw(node.content), ESCAPE + \"]\"];\n case \"group\":\n return [\"{\", ..._printRaw(node.content), \"}\"];\n case \"inlinemath\":\n return [\"$\", ..._printRaw(node.content), \"$\"];\n case \"macro\":\n argsString = node.args == null ? [] : _printRaw(node.args);\n escape = node.escapeToken == null ? ESCAPE : node.escapeToken;\n return [escape, ..._printRaw(node.content), ...argsString];\n case \"parbreak\":\n return [linebreak, linebreak];\n case \"string\":\n return [node.content];\n case \"verb\":\n return [\n ESCAPE,\n node.env,\n node.escape,\n ..._printRaw(node.content),\n node.escape,\n ];\n case \"whitespace\":\n return [\" \"];\n\n default:\n console.warn(\n \"Cannot find render for node \",\n node,\n `(of type ${typeof node})`\n );\n return [\"\" + node];\n }\n}\n\n/**\n * Renders the AST to a string without any pretty printing.\n *\n * @param {*} node\n * @param {*} options - Setting `asArray` to `true` will return an array of strings and the symbol `linebreak`, so that printing can be customized.\n */\nexport function printRaw(\n node: Printable | Printable[],\n options?: { asArray: false }\n): string;\nexport function printRaw(\n node: Printable | Printable[],\n options: { asArray: true }\n): PrintToken[];\nexport function printRaw(node: Printable | Printable[], options?: object): any {\n const asArray = options != null ? (options as any).asArray : false;\n const printedTokens = _printRaw(node);\n if (asArray) {\n return printedTokens;\n }\n return printedTokens.map((x) => (x === linebreak ? \"\\n\" : x)).join(\"\");\n}\n", "import * as Ast from \"@unified-latex/unified-latex-types\";\nimport {\n EnvInfo,\n MacroInfo,\n MacroInfoRecord,\n} from \"@unified-latex/unified-latex-types\";\nimport { printRaw } from \"@unified-latex/unified-latex-util-print-raw\";\n\n/**\n * Creates a macro matching function that uses a `SpecialMacroSpec` or list of macros\n * and generates a hash for quick lookup.\n */\nfunction createMacroMatcher<S extends string>(\n macros: Ast.Macro[] | S[] | Record<S, unknown>\n) {\n // We first make sure we have a record type with keys being the macro's contents\n const macrosHash: Record<string, unknown> = Array.isArray(macros)\n ? macros.length > 0\n ? typeof macros[0] === \"string\"\n ? Object.fromEntries(\n macros.map((macro) => {\n if (typeof macro !== \"string\") {\n throw new Error(\"Wrong branch of map function\");\n }\n return [macro, {}] as [string, MacroInfo];\n })\n )\n : Object.fromEntries(\n macros.map((macro) => {\n if (typeof macro === \"string\") {\n throw new Error(\"Wrong branch of map function\");\n }\n if (macro.escapeToken != null) {\n return [\n macro.content,\n { escapeToken: macro.escapeToken },\n ] as [string, MacroInfo];\n }\n return [macro.content, {}] as [string, MacroInfo];\n })\n )\n : {}\n : macros;\n\n return function matchAgainstMacros(node: any | Ast.Macro) {\n if (node == null || node.type !== \"macro\") {\n return false;\n }\n // At this point we have a macro type\n const spec = macrosHash[node.content];\n if (!spec) {\n return false;\n }\n\n if (typeof spec === \"object\" && \"escapeToken\" in spec) {\n return (\n (spec as MacroInfoRecord).escapeToken == null ||\n (spec as MacroInfoRecord).escapeToken === node.escapeToken\n );\n }\n return true;\n } as Ast.TypeGuard<Ast.Macro & { content: S }>;\n}\n\n/**\n * Creates a macro matching function that uses a `SpecialMacroSpec` or list of macros\n * and generates a hash for quick lookup.\n */\nfunction createEnvironmentMatcher(macros: string[] | Record<string, unknown>) {\n // We first make sure we have a record type with keys being the macro's contents\n const environmentsHash = Array.isArray(macros)\n ? Object.fromEntries(\n macros.map((str) => {\n return [str, {}] as [string, EnvInfo];\n })\n )\n : macros;\n\n return function matchAgainstEnvironments(node: any | Ast.Environment) {\n if (!match.anyEnvironment(node)) {\n return false;\n }\n // At this point we have an environment type\n const envName = printRaw(node.env);\n const spec = environmentsHash[envName];\n if (!spec) {\n return false;\n }\n\n return true;\n } as Ast.TypeGuard<Ast.Environment>;\n}\n\n/**\n * Functions to match different types of nodes.\n */\nexport const match = {\n macro(node: any, macroName?: string): node is Ast.Macro {\n if (node == null) {\n return false;\n }\n return (\n node.type === \"macro\" &&\n (macroName == null || node.content === macroName)\n );\n },\n anyMacro(node: any): node is Ast.Macro {\n return match.macro(node);\n },\n environment(node: any, envName?: string): node is Ast.Environment {\n if (node == null) {\n return false;\n }\n return (\n (node.type === \"environment\" || node.type === \"mathenv\") &&\n (envName == null || printRaw(node.env) === envName)\n );\n },\n anyEnvironment(node: any): node is Ast.Environment {\n return match.environment(node);\n },\n comment(node: any): node is Ast.Comment {\n if (node == null) {\n return false;\n }\n return node.type === \"comment\";\n },\n parbreak(node: any): node is Ast.Parbreak {\n if (node == null) {\n return false;\n }\n return node.type === \"parbreak\";\n },\n whitespace(node: any): node is Ast.Whitespace {\n if (node == null) {\n return false;\n }\n return node.type === \"whitespace\";\n },\n /**\n * Matches whitespace or a comment with leading whitespace.\n */\n whitespaceLike(\n node: any\n ): node is Ast.Whitespace | (Ast.Comment & { leadingWhitespace: true }) {\n if (node == null) {\n return false;\n }\n return (\n node.type === \"whitespace\" ||\n (node.type === \"whitespace\" && node.leadingWhitespace === true)\n );\n },\n string(node: any, value?: string): node is Ast.String {\n if (node == null) {\n return false;\n }\n return (\n node.type === \"string\" && (value == null || node.content === value)\n );\n },\n anyString(node: any): node is Ast.String {\n return match.string(node);\n },\n group(node: any): node is Ast.Group {\n if (node == null) {\n return false;\n }\n return node.type === \"group\";\n },\n argument(node: any): node is Ast.Argument {\n if (node == null) {\n return false;\n }\n return node.type === \"argument\";\n },\n blankArgument(node: any): boolean {\n if (!match.argument(node)) {\n return false;\n }\n return (\n node.openMark === \"\" &&\n node.closeMark === \"\" &&\n node.content.length === 0\n );\n },\n math(node: any): node is Ast.DisplayMath | Ast.InlineMath {\n if (node == null) {\n return false;\n }\n return node.type === \"displaymath\" || node.type === \"inlinemath\";\n },\n createMacroMatcher,\n createEnvironmentMatcher,\n};\n\nexport const {\n anyEnvironment,\n anyMacro,\n anyString,\n argument,\n blankArgument,\n comment,\n environment,\n group,\n macro,\n math,\n parbreak,\n string,\n whitespace,\n} = match;\n", "import * as Ast from \"@unified-latex/unified-latex-types\";\n\nexport type Region = { start: number; end: number };\n\n/**\n * Given `regions`, a list of `Region`s (not necessarily ordered, possibly overlapping), return a list of in-order,\n * non-overlapping regions and a corresponding list containing a set of the original `Region`s that the new region\n * is a subset of.\n */\nexport function refineRegions(regions: Region[]): {\n regions: Region[];\n regionsContainedIn: Set<Region>[];\n} {\n const _regions = [...regions];\n _regions.sort((a, b) => a.start - b.start);\n const cutPointsSet = new Set(_regions.flatMap((r) => [r.start, r.end]));\n const cutPoints = Array.from(cutPointsSet);\n cutPoints.sort((a, b) => a - b);\n\n const retRegions: Region[] = [];\n const retRegionsContainedIn: Set<Region>[] = [];\n\n // We will be checking what regions we are completely contained in.\n // Because `_regions` is sorted by start, `seekIndex` will be incremented\n // by end, so that we don't do too much array testing.\n let seekIndex = 0;\n for (let i = 0; i < cutPoints.length - 1; i++) {\n const start = cutPoints[i];\n const end = cutPoints[i + 1];\n const region = { start, end };\n const regionContainedIn: Set<Region> = new Set();\n\n let encounteredEndPastStart = false;\n for (let j = seekIndex; j < _regions.length; j++) {\n const superRegion = _regions[j];\n if (superRegion.end >= region.start) {\n encounteredEndPastStart = true;\n }\n if (!encounteredEndPastStart && superRegion.end < region.start) {\n // In this case, the region (and all regions that came before)\n // end before the region we are testing, so we may safely skip past it\n // from here on out.\n seekIndex = j + 1;\n continue;\n }\n\n if (superRegion.start > end) {\n // Because `_regions` is sorted, we can stop here\n break;\n }\n if (\n superRegion.start <= region.start &&\n superRegion.end >= region.end\n ) {\n encounteredEndPastStart = true;\n regionContainedIn.add(superRegion);\n }\n }\n\n if (regionContainedIn.size > 0) {\n // We only count if we are contained in a subregion\n retRegions.push(region);\n retRegionsContainedIn.push(regionContainedIn);\n }\n }\n\n return { regions: retRegions, regionsContainedIn: retRegionsContainedIn };\n}\n\n/**\n * Split an array up into the disjoint regions specified by `regionRecord`.\n * Returned is a list of tuples, the first item being the key of `regionRecord` if there\n * was a corresponding region, or `null` if there was no corresponding region.\n *\n * This function assumes that the regions in `regionRecord` are disjoint and fully contained\n * within the bounds of `array`.\n */\nexport function splitByRegions<\n T extends unknown,\n RegionRecord extends Record<string, Region[]>\n>(array: T[], regionsRecord: RegionRecord) {\n const ret: [keyof RegionRecord | null, T[]][] = [];\n\n const indices = [0, array.length];\n const reverseMap: Record<string, keyof RegionRecord> = {};\n for (const [key, records] of Object.entries(regionsRecord)) {\n indices.push(\n ...records.flatMap((r) => {\n reverseMap[\"\" + [r.start, r.end]] = key;\n return [r.start, r.end];\n })\n );\n }\n indices.sort((a, b) => a - b);\n\n for (let i = 0; i < indices.length - 1; i++) {\n const start = indices[i];\n const end = indices[i + 1];\n if (start === end) {\n continue;\n }\n const regionKey = reverseMap[\"\" + [start, end]];\n\n ret.push([regionKey || null, array.slice(start, end)]);\n }\n\n return ret;\n}\n", "import * as Ast from \"@unified-latex/unified-latex-types\";\nimport { match } from \"@unified-latex/unified-latex-util-match\";\n\n/**\n * List all props of the current node that should be processed\n * in math mode or not in math mode. If math mode is not specified in the node's render\n * info, empty lists are returned.\n *\n * For example `\\text{foo}` will report that `args` should *not* be processed in math mode,\n * since it's contents should always be processed in text mode.\n */\nexport function listMathChildren(node: Ast.Ast): {\n enter: string[];\n leave: string[];\n} {\n const NULL_RETURN = { enter: [], leave: [] };\n if (Array.isArray(node)) {\n return NULL_RETURN;\n }\n if (match.math(node)) {\n // When we enter a math environment, our content is always\n // considered math mode\n return { enter: [\"content\"], leave: [] };\n }\n\n const renderInfo: { inMathMode?: boolean } = node._renderInfo || {};\n if (renderInfo.inMathMode == null) {\n return NULL_RETURN;\n }\n if (match.macro(node)) {\n if (renderInfo.inMathMode === true) {\n return { enter: [\"args\"], leave: [] };\n } else if (renderInfo.inMathMode === false) {\n return { enter: [], leave: [\"args\"] };\n }\n }\n if (match.environment(node)) {\n if (renderInfo.inMathMode === true) {\n return { enter: [\"content\"], leave: [] };\n } else {\n return { enter: [], leave: [\"content\"] };\n }\n }\n return NULL_RETURN;\n}\n", "import * as Ast from \"@unified-latex/unified-latex-types\";\nimport { listMathChildren } from \"./list-math-children\";\n\nexport type VisitorContext = {\n /**\n * Whether the node is being processed in math mode.\n *\n * This happens when the node is a director or indirect child\n * of a math environment (e.g. `$abc$`), but not when an environment\n * re-establishes text mode (e.g. `$\\text{abc}$`)\n */\n inMathMode?: boolean;\n /**\n * Whether the node has any ancestor that is processed in math mode.\n */\n hasMathModeAncestor?: boolean;\n};\n\ntype GetGuard<T> = T extends (x: any, ...y: any[]) => x is infer R ? R : never;\n/**\n * Gets the type that a type-guard function is guarding. If\n * the guard type cannot be determined, the input type is returned.\n */\ntype GuardTypeOf<T extends (x: any, ...y: any[]) => boolean> = GetGuard<T> extends never\n ? T extends (x: infer A) => any\n ? A\n : never\n : GetGuard<T>;\n\n/**\n * Extracts the guard type from the `test` function provided in a\n * `VisitOptions` argument.\n */\ntype GuardFromOptions<\n Opts extends VisitOptions,\n PossibleTypes = Ast.Ast\n> = Opts extends {\n test: infer R;\n}\n ? R extends (x: any, ...y: any[]) => boolean\n ? // A guard like `typeof Array.isArray` will return `any[]` as the type.\n // This type cannot be narrowed, so instead we use it to pick from\n // the set of all possible types.\n Extract<PossibleTypes, GuardTypeOf<R>>\n : PossibleTypes\n : PossibleTypes;\n\n/**\n * Narrow the type `T` based on the `VisitOptions` supplied. If `{includeArrays: false}`\n * is specified in the `VisitOptions`, then arrays are excluded from `T`.\n */\ntype NarrowArraysBasedOnOptions<T, Opts extends VisitOptions> = Opts extends {\n includeArrays: infer A;\n}\n ? A extends true\n ? T\n : Exclude<T, any[]>\n : Exclude<T, any[]>;\n\n/**\n * Get the type of the parameter to the `Visitor` function based on the\n * `VisitOptions` that are supplied.\n */\ntype VisitorTypeFromOptions<Opts extends VisitOptions> =\n NarrowArraysBasedOnOptions<GuardFromOptions<Opts>, Opts>;\n\n/**\n * Continue traversing as normal\n */\nexport const CONTINUE = Symbol(\"continue\");\n/**\n * Do not traverse this node\u2019s children\n */\nexport const SKIP = Symbol(\"skip\");\n/**\n * Stop traversing immediately\n */\nexport const EXIT = Symbol(\"exit\");\n\ntype Action = typeof CONTINUE | typeof SKIP | typeof EXIT;\ntype Index = number;\ntype ActionTuple = [Action] | [typeof SKIP, Index] | [typeof CONTINUE, Index];\n\n/**\n * A visitor takes a `node`, `key`, `index`, and ...\n *\n * @param key - The key of the parent that we were accessed through.\n */\ntype Visitor<T> = (\n node: T,\n info: VisitInfo\n) => null | undefined | Action | Index | ActionTuple | void;\ntype Visitors<T> = { enter?: Visitor<T>; leave?: Visitor<T> };\n\ntype VisitOptions = {\n startingContext?: VisitorContext;\n /**\n * Type guard for types that are passed to the `visitor` function.\n */\n test?: (node: Ast.Ast, info: VisitInfo) => boolean;\n /**\n * Whether arrays will be sent to the `visitor` function. If falsy,\n * only nodes will be past to `visitor`.\n */\n includeArrays?: boolean;\n};\n\nconst DEFAULT_CONTEXT: VisitorContext = {\n inMathMode: false,\n hasMathModeAncestor: false,\n};\n\nexport type VisitInfo = {\n /**\n * If the element was accessed via an attribute, the attribute key is specified.\n */\n readonly key: string | undefined;\n /**\n * If the element was accessed in an array, the index is specified.\n */\n readonly index: number | undefined;\n /**\n * A list of ancestor nodes, `[parent, grandparent, great-grandparent, ...]`\n */\n readonly parents: (Ast.Node | Ast.Argument)[];\n /**\n * If the element was accessed in an array, the array that it is part of.\n */\n readonly containingArray: (Ast.Node | Ast.Argument)[] | undefined;\n /**\n * The LaTeX context of the current match.\n */\n readonly context: VisitorContext;\n};\n\n/**\n * Visit children of tree which pass a test\n *\n * @param {Node} tree Abstract syntax tree to walk\n * @param {Visitor|Visitors} [visitor] Function to run for each node\n */\nexport function visit<Opts extends VisitOptions>(\n tree: Ast.Ast,\n visitor:\n | Visitor<VisitorTypeFromOptions<Opts>>\n | Visitors<VisitorTypeFromOptions<Opts>>,\n options?: Opts\n) {\n const {\n startingContext = DEFAULT_CONTEXT,\n test = () => true,\n includeArrays = false,\n } = options || {};\n let enter: Visitor<VisitorTypeFromOptions<Opts>> | undefined;\n let leave: Visitor<VisitorTypeFromOptions<Opts>> | undefined;\n\n if (typeof visitor === \"function\") {\n enter = visitor;\n } else if (visitor && typeof visitor === \"object\") {\n enter = visitor.enter;\n leave = visitor.leave;\n }\n\n walk(tree, {\n key: undefined,\n index: undefined,\n parents: [],\n containingArray: undefined,\n context: { ...startingContext },\n });\n\n /**\n * @param {Node} node\n * @param {string?} key\n * @param {number?} index\n * @param {Array.<Node>} parents\n */\n function walk(\n node: Ast.Ast,\n { key, index, parents, context, containingArray }: VisitInfo\n ): ActionTuple {\n const nodePassesTest = includeArrays\n ? test(node, { key, index, parents, context, containingArray })\n : !Array.isArray(node) &&\n test(node, { key, index, parents, context, containingArray });\n\n const result: ActionTuple =\n enter && nodePassesTest\n ? toResult(\n enter(node as any, {\n key,\n index,\n parents,\n context,\n containingArray,\n })\n )\n : [CONTINUE];\n\n if (result[0] === EXIT) {\n return result;\n }\n\n if (result[0] === SKIP) {\n return leave && nodePassesTest\n ? toResult(\n leave(node as any, {\n key,\n index,\n parents,\n context,\n containingArray,\n })\n )\n : result;\n }\n\n if (Array.isArray(node)) {\n // The `value` array might be modified in place as we traverse it, so\n // we use a traditional for loop.\n for (let index = 0; index > -1 && index < node.length; index++) {\n const item = node[index];\n const result = walk(item, {\n key,\n index,\n parents,\n context,\n containingArray: node,\n });\n if (result[0] === EXIT) {\n return result;\n }\n if (typeof result[1] === \"number\") {\n // The for loop will increment i every pass. However,\n // if an index was returned, that's where we want to start next time.\n index = result[1] - 1;\n }\n }\n } else {\n // We don't want to recursively apply to the `content`\n // of all types (e.g., comments and macros), so specify\n // a blacklist.\n let childProps: (\"content\" | \"args\")[] = [\"content\", \"args\"];\n switch (node.type) {\n case \"macro\":\n childProps = [\"args\"];\n break;\n case \"comment\":\n case \"string\":\n case \"verb\":\n case \"verbatim\":\n childProps = [];\n break;\n default:\n break;\n }\n\n const mathModeProps = listMathChildren(node);\n for (const key of childProps) {\n const value = node[key as keyof typeof node] as\n | Ast.Ast\n | undefined;\n const grandparents = [node].concat(parents);\n\n if (value == null) {\n continue;\n }\n\n // We may switch in/out of math mode as we pass to node[key]\n const newContext = { ...context };\n if (mathModeProps.enter.includes(key)) {\n newContext.inMathMode = true;\n newContext.hasMathModeAncestor = true;\n } else if (mathModeProps.leave.includes(key)) {\n newContext.inMathMode = false;\n }\n\n const result = walk(value, {\n key,\n index: undefined,\n parents: grandparents,\n context: newContext,\n containingArray: undefined,\n });\n if (result[0] === EXIT) {\n return result;\n }\n }\n }\n\n return leave && nodePassesTest\n ? toResult(\n leave(node as any, {\n key,\n index,\n parents,\n context,\n containingArray,\n })\n )\n : result;\n }\n}\n\n/**\n * Ensures a result is an `ActionTuple`s\n */\nfunction toResult(\n value: null | undefined | void | Action | Index | ActionTuple\n): ActionTuple {\n if (value == null) {\n return [CONTINUE];\n }\n\n if (Array.isArray(value)) {\n return value;\n }\n\n if (typeof value === \"number\") {\n return [CONTINUE, value];\n }\n\n return [value];\n}\n", "import * as Ast from \"@unified-latex/unified-latex-types\";\nimport { match } from \"@unified-latex/unified-latex-util-match\";\nimport { EXIT, visit } from \"@unified-latex/unified-latex-util-visit\";\n\n/**\n * Escape a string so that it can be used to build a regular expression.\n *\n * From: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions\n */\nfunction escapeRegExp(str: string) {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"); // $& means the whole matched string\n}\n\n/**\n * Build a regular expression that matches everything up to the first non-allowed symbol.\n */\nfunction buildWordRegex(allowedSet: Set<string>): RegExp {\n // /\\p{L}/ matches all letters, including unicode letters. We join this with\n // everything allowed in our set to form a regexp like\n // /(\\p{L}|_|:)*/u\n // The `u` at the end allows unicode characters to be matched.\n const regexpStr = `^(${[\"\\\\p{L}\"]\n .concat(Array.from(allowedSet).map(escapeRegExp))\n .join(\"|\")})*`;\n return new RegExp(regexpStr, \"u\");\n}\n\n/**\n * Checks whether the array has a macro that could be reparsed given the `allowedTokens` but\n * do not do any reparsing. This function can be used in auto-detection schemes to determine if\n * macro names should actually be reparsed.\n */\nexport function hasReparsableMacroNamesInArray(\n tree: Ast.Node[],\n allowedTokens: Set<string>\n): boolean {\n for (let i = 0; i < tree.length; i++) {\n const macro = tree[i];\n const string = tree[i + 1];\n if (match.anyMacro(macro) && match.anyString(string)) {\n // There are two options. Either the macro ends with the special character,\n // e.g. `\\@foo` or the special character starts the next string, e.g. `\\foo@`.\n if (\n allowedTokens.has(\n macro.content.charAt(macro.content.length - 1)\n ) ||\n allowedTokens.has(string.content.charAt(0))\n ) {\n return true;\n }\n }\n }\n return false;\n}\n\n/**\n * Checks whether `tree` has a macro that could be reparsed given the `allowedTokens` but\n * do not do any reparsing. This function can be used in auto-detection schemes to determine if\n * macro names should actually be reparsed.\n */\nexport function hasReparsableMacroNames(\n tree: Ast.Ast,\n allowedTokens: string | Set<string>\n): boolean {\n if (typeof allowedTokens === \"string\") {\n allowedTokens = new Set(allowedTokens.split(\"\"));\n }\n // Recast so typescript doesn't complain\n const _allowedTokens = allowedTokens;\n for (const v of _allowedTokens) {\n if (v.length > 1) {\n throw new Error(\n `Only single characters are allowed as \\`allowedTokens\\` when reparsing macro names, not \\`${v}\\`.`\n );\n }\n }\n\n let ret = false;\n visit(\n tree,\n (nodes) => {\n if (hasReparsableMacroNamesInArray(nodes, _allowedTokens)) {\n ret = true;\n return EXIT;\n }\n },\n { includeArrays: true, test: Array.isArray }\n );\n return ret;\n}\n\n/**\n * Reparses all macro names in the array so that they may optionally include characters listed in `allowedTokens`.\n * This is used, for example, when parsing expl3 syntax which allows `_` to be used in a macro name (even though\n * `_` is normally stops the parsing for a macro name).\n */\nexport function reparseMacroNamesInArray(\n tree: Ast.Node[],\n allowedTokens: Set<string>\n) {\n const regex = buildWordRegex(allowedTokens);\n let i = 0;\n while (i < tree.length) {\n const macro = tree[i];\n const string = tree[i + 1];\n if (\n match.anyMacro(macro) &&\n // The _^ macros in math mode should not be extended no-matter what;\n // So we check to make sure that the macro we're dealing with has the default escape token.\n (macro.escapeToken == null || macro.escapeToken === \"\\\\\") &&\n match.anyString(string) &&\n // There are two options. Either the macro ends with the special character,\n // e.g. `\\@foo` or the special character starts the next string, e.g. `\\foo@`.\n (allowedTokens.has(\n macro.content.charAt(macro.content.length - 1)\n ) ||\n allowedTokens.has(string.content.charAt(0)))\n ) {\n // There might be a number somewhere in the string. If so, we should\n // break the string apart at that number\n const match = string.content.match(regex);\n const takeable = match ? match[0] : \"\";\n if (takeable.length > 0) {\n if (takeable.length === string.content.length) {\n // The whole string can be appended to the macro name\n macro.content += string.content;\n tree.splice(i + 1, 1);\n\n // Preserve the source location if available\n if (macro.position && string.position?.end) {\n macro.position.end = string.position.end;\n }\n } else {\n // Only part of the string can be appended to the macro name\n macro.content += takeable;\n string.content = string.content.slice(takeable.length);\n\n // Preserve the source location if available\n if (macro.position?.end) {\n macro.position.end.offset += takeable.length;\n macro.position.end.column += takeable.length;\n }\n if (string.position?.start) {\n string.position.start.offset += takeable.length;\n string.position.start.column += takeable.length;\n }\n }\n } else {\n i++;\n }\n } else {\n ++i;\n }\n }\n}\n\n/**\n * Reparses all macro names so that they may optionally include characters listed in `allowedTokens`.\n * This is used, for example, when parsing expl3 syntax which allows `_` to be used in a macro name (even though\n * `_` is normally stops the parsing for a macro name). Thus, a macro `\\foo_bar:Nn` would be parsed as having\n * the name `foo_bar:Nn` rather than as `foo` followed by the strings `_`, `bar`, `:`, `Nn`.\n */\nexport function reparseMacroNames(\n tree: Ast.Ast,\n allowedTokens: string | Set<string>\n) {\n if (typeof allowedTokens === \"string\") {\n allowedTokens = new Set(allowedTokens.split(\"\"));\n }\n // Recast so typescript doesn't complain\n const _allowedTokens = allowedTokens;\n for (const v of _allowedTokens) {\n if (v.length > 1) {\n throw new Error(\n `Only single characters are allowed as \\`allowedTokens\\` when reparsing macro names, not \\`${v}\\`.`\n );\n }\n }\n\n visit(\n tree,\n (nodes) => {\n reparseMacroNamesInArray(nodes, _allowedTokens);\n },\n { includeArrays: true, test: Array.isArray }\n );\n}\n", "import * as Ast from \"@unified-latex/unified-latex-types\";\nimport { match } from \"@unified-latex/unified-latex-util-match\";\nimport { findRegionInArray } from \"./find-region\";\nimport { refineRegions, Region, splitByRegions } from \"./regions\";\nimport { SKIP, visit } from \"@unified-latex/unified-latex-util-visit\";\nimport { reparseMacroNames } from \"./reparse-macro-names\";\n\nconst expl3Find = {\n start: match.createMacroMatcher([\"ExplSyntaxOn\"]),\n end: match.createMacroMatcher([\"ExplSyntaxOff\"]),\n};\nconst atLetterFind = {\n start: match.createMacroMatcher([\"makeatletter\"]),\n end: match.createMacroMatcher([\"makeatother\"]),\n};\n\n/**\n * Find regions between `\\ExplSyntaxOn...\\ExplSyntaxOff` and `\\makeatletter...\\makeatother`.\n * Returns an object containing regions where one or both syntax's apply.\n */\nexport function findExpl3AndAtLetterRegionsInArray(tree: Ast.Node[]): {\n explOnly: Region[];\n atLetterOnly: Region[];\n both: Region[];\n} {\n const expl3 = findRegionInArray(tree, expl3Find.start, expl3Find.end);\n const atLetter = findRegionInArray(\n tree,\n atLetterFind.start,\n atLetterFind.end\n );\n\n const regionMap = new Map([\n ...(expl3.map((x) => [x, \"expl\"]) as [Region, \"expl\"][]),\n ...(atLetter.map((x) => [x, \"atLetter\"]) as [Region, \"atLetter\"][]),\n ]);\n const all = refineRegions([...expl3, ...atLetter]);\n\n const ret = {\n explOnly: [] as Region[],\n atLetterOnly: [] as Region[],\n both: [] as Region[],\n };\n\n for (let i = 0; i < all.regions.length; i++) {\n const region = all.regions[i];\n const containedIn = all.regionsContainedIn[i];\n if (containedIn.size === 2) {\n ret.both.push(region);\n continue;\n }\n for (const v of containedIn.values()) {\n if (regionMap.get(v) === \"expl\") {\n ret.explOnly.push(region);\n }\n if (regionMap.get(v) === \"atLetter\") {\n ret.atLetterOnly.push(region);\n }\n }\n }\n\n // Regions of size 1 only contain the starting/stopping macro, so they should be discarded\n ret.explOnly = ret.explOnly.filter((r) => r.end - r.start > 1);\n ret.atLetterOnly = ret.atLetterOnly.filter((r) => r.end - r.start > 1);\n ret.both = ret.both.filter((r) => r.end - r.start > 1);\n\n return ret;\n}\n\nconst atLetterSet = new Set([\"@\"]);\nconst explSet = new Set([\"_\", \":\"]);\nconst bothSet = new Set([\"_\", \":\", \"@\"]);\n\n/**\n * Find regions between `\\ExplSyntaxOn...\\ExplSyntaxOff` and `\\makeatletter...\\makeatother`\n * and reparse their contents so that the relevant characters (e.g., `@`, `_`, and `:`) become\n * part of the macro names.\n */\nexport function reparseExpl3AndAtLetterRegions(tree: Ast.Ast) {\n visit(\n tree,\n {\n leave: (nodes) => {\n const regions = findExpl3AndAtLetterRegionsInArray(nodes);\n // In all likelihood, we don't need to do any reparsing, so bail early here\n const totalNumRegions =\n regions.both.length +\n regions.atLetterOnly.length +\n regions.explOnly.length;\n if (totalNumRegions === 0) {\n return;\n }\n\n const splits = splitByRegions(nodes, regions);\n const processed: typeof nodes = [];\n for (const [key, slice] of splits) {\n switch (key) {\n case null:\n processed.push(...slice);\n continue;\n case \"atLetterOnly\":\n reparseMacroNames(slice, atLetterSet);\n processed.push(...slice);\n continue;\n case \"explOnly\":\n reparseMacroNames(slice, explSet);\n processed.push(...slice);\n continue;\n case \"both\":\n reparseMacroNames(slice, bothSet);\n processed.push(...slice);\n continue;\n default:\n throw new Error(\n `Unexpected case when splitting ${key}`\n );\n }\n }\n\n nodes.length = 0;\n nodes.push(...processed);\n return SKIP;\n },\n },\n { includeArrays: true, test: Array.isArray }\n );\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["macro", "index", "result", "key", "macro", "string", "match"]
7
7
  }
package/index.js.map CHANGED
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../libs/find-region.ts", "../libs/special-regions.ts", "../libs/regions.ts", "../libs/reparse-macro-names.ts"],
4
4
  "sourcesContent": ["import * as Ast from \"@unified-latex/unified-latex-types\";\nimport { Region } from \"./regions\";\n\n/**\n * Find all contiguous segments in the array that are between start and end blocks.\n * The `start` and `end` are functions that determine when a region starts and ends.\n */\nexport function findRegionInArray(\n tree: Ast.Node[],\n start: (node: Ast.Node) => boolean,\n end: (node: Ast.Node) => boolean\n): Region[] {\n const ret: Region[] = [];\n let currRegion: Region = { start: undefined as any, end: tree.length };\n for (let i = 0; i < tree.length; i++) {\n const node = tree[i];\n if (start(node)) {\n currRegion.start = i;\n }\n if (end(node)) {\n currRegion.end = i + 1;\n ret.push(currRegion);\n currRegion = { start: undefined as any, end: tree.length };\n }\n }\n\n if (currRegion.start != null) {\n // Regions don't necessarily have to encounter an `end` to end.\n ret.push(currRegion);\n }\n return ret;\n}\n", "import * as Ast from \"@unified-latex/unified-latex-types\";\nimport { match } from \"@unified-latex/unified-latex-util-match\";\nimport { findRegionInArray } from \"./find-region\";\nimport { refineRegions, Region, splitByRegions } from \"./regions\";\nimport { SKIP, visit } from \"@unified-latex/unified-latex-util-visit\";\nimport { reparseMacroNames } from \"./reparse-macro-names\";\n\nconst expl3Find = {\n start: match.createMacroMatcher([\"ExplSyntaxOn\"]),\n end: match.createMacroMatcher([\"ExplSyntaxOff\"]),\n};\nconst atLetterFind = {\n start: match.createMacroMatcher([\"makeatletter\"]),\n end: match.createMacroMatcher([\"makeatother\"]),\n};\n\n/**\n * Find regions between `\\ExplSyntaxOn...\\ExplSyntaxOff` and `\\makeatletter...\\makeatother`.\n * Returns an object containing regions where one or both syntax's apply.\n */\nexport function findExpl3AndAtLetterRegionsInArray(tree: Ast.Node[]): {\n explOnly: Region[];\n atLetterOnly: Region[];\n both: Region[];\n} {\n const expl3 = findRegionInArray(tree, expl3Find.start, expl3Find.end);\n const atLetter = findRegionInArray(\n tree,\n atLetterFind.start,\n atLetterFind.end\n );\n\n const regionMap = new Map([\n ...(expl3.map((x) => [x, \"expl\"]) as [Region, \"expl\"][]),\n ...(atLetter.map((x) => [x, \"atLetter\"]) as [Region, \"atLetter\"][]),\n ]);\n const all = refineRegions([...expl3, ...atLetter]);\n\n const ret = {\n explOnly: [] as Region[],\n atLetterOnly: [] as Region[],\n both: [] as Region[],\n };\n\n for (let i = 0; i < all.regions.length; i++) {\n const region = all.regions[i];\n const containedIn = all.regionsContainedIn[i];\n if (containedIn.size === 2) {\n ret.both.push(region);\n continue;\n }\n for (const v of containedIn.values()) {\n if (regionMap.get(v) === \"expl\") {\n ret.explOnly.push(region);\n }\n if (regionMap.get(v) === \"atLetter\") {\n ret.atLetterOnly.push(region);\n }\n }\n }\n\n // Regions of size 1 only contain the starting/stopping macro, so they should be discarded\n ret.explOnly = ret.explOnly.filter((r) => r.end - r.start > 1);\n ret.atLetterOnly = ret.atLetterOnly.filter((r) => r.end - r.start > 1);\n ret.both = ret.both.filter((r) => r.end - r.start > 1);\n\n return ret;\n}\n\nconst atLetterSet = new Set([\"@\"]);\nconst explSet = new Set([\"_\", \":\"]);\nconst bothSet = new Set([\"_\", \":\", \"@\"]);\n\n/**\n * Find regions between `\\ExplSyntaxOn...\\ExplSyntaxOff` and `\\makeatletter...\\makeatother`\n * and reparse their contents so that the relevant characters (e.g., `@`, `_`, and `:`) become\n * part of the macro names.\n */\nexport function reparseExpl3AndAtLetterRegions(tree: Ast.Ast) {\n visit(\n tree,\n {\n leave: (nodes) => {\n const regions = findExpl3AndAtLetterRegionsInArray(nodes);\n // In all likelihood, we don't need to do any reparsing, so bail early here\n const totalNumRegions =\n regions.both.length +\n regions.atLetterOnly.length +\n regions.explOnly.length;\n if (totalNumRegions === 0) {\n return;\n }\n\n const splits = splitByRegions(nodes, regions);\n const processed: typeof nodes = [];\n for (const [key, slice] of splits) {\n switch (key) {\n case null:\n processed.push(...slice);\n continue;\n case \"atLetterOnly\":\n reparseMacroNames(slice, atLetterSet);\n processed.push(...slice);\n continue;\n case \"explOnly\":\n reparseMacroNames(slice, explSet);\n processed.push(...slice);\n continue;\n case \"both\":\n reparseMacroNames(slice, bothSet);\n processed.push(...slice);\n continue;\n default:\n throw new Error(\n `Unexpected case when splitting ${key}`\n );\n }\n }\n\n nodes.length = 0;\n nodes.push(...processed);\n return SKIP;\n },\n },\n { includeArrays: true, test: Array.isArray }\n );\n}\n", "import * as Ast from \"@unified-latex/unified-latex-types\";\n\nexport type Region = { start: number; end: number };\n\n/**\n * Given `regions`, a list of `Region`s (not necessarily ordered, possibly overlapping), return a list of in-order,\n * non-overlapping regions and a corresponding list containing a set of the original `Region`s that the new region\n * is a subset of.\n */\nexport function refineRegions(regions: Region[]): {\n regions: Region[];\n regionsContainedIn: Set<Region>[];\n} {\n const _regions = [...regions];\n _regions.sort((a, b) => a.start - b.start);\n const cutPointsSet = new Set(_regions.flatMap((r) => [r.start, r.end]));\n const cutPoints = Array.from(cutPointsSet);\n cutPoints.sort((a, b) => a - b);\n\n const retRegions: Region[] = [];\n const retRegionsContainedIn: Set<Region>[] = [];\n\n // We will be checking what regions we are completely contained in.\n // Because `_regions` is sorted by start, `seekIndex` will be incremented\n // by end, so that we don't do too much array testing.\n let seekIndex = 0;\n for (let i = 0; i < cutPoints.length - 1; i++) {\n const start = cutPoints[i];\n const end = cutPoints[i + 1];\n const region = { start, end };\n const regionContainedIn: Set<Region> = new Set();\n\n let encounteredEndPastStart = false;\n for (let j = seekIndex; j < _regions.length; j++) {\n const superRegion = _regions[j];\n if (superRegion.end >= region.start) {\n encounteredEndPastStart = true;\n }\n if (!encounteredEndPastStart && superRegion.end < region.start) {\n // In this case, the region (and all regions that came before)\n // end before the region we are testing, so we may safely skip past it\n // from here on out.\n seekIndex = j + 1;\n continue;\n }\n\n if (superRegion.start > end) {\n // Because `_regions` is sorted, we can stop here\n break;\n }\n if (\n superRegion.start <= region.start &&\n superRegion.end >= region.end\n ) {\n encounteredEndPastStart = true;\n regionContainedIn.add(superRegion);\n }\n }\n\n if (regionContainedIn.size > 0) {\n // We only count if we are contained in a subregion\n retRegions.push(region);\n retRegionsContainedIn.push(regionContainedIn);\n }\n }\n\n return { regions: retRegions, regionsContainedIn: retRegionsContainedIn };\n}\n\n/**\n * Split an array up into the disjoint regions specified by `regionRecord`.\n * Returned is a list of tuples, the first item being the key of `regionRecord` if there\n * was a corresponding region, or `null` if there was no corresponding region.\n *\n * This function assumes that the regions in `regionRecord` are disjoint and fully contained\n * within the bounds of `array`.\n */\nexport function splitByRegions<\n T extends unknown,\n RegionRecord extends Record<string, Region[]>\n>(array: T[], regionsRecord: RegionRecord) {\n const ret: [keyof RegionRecord | null, T[]][] = [];\n\n const indices = [0, array.length];\n const reverseMap: Record<string, keyof RegionRecord> = {};\n for (const [key, records] of Object.entries(regionsRecord)) {\n indices.push(\n ...records.flatMap((r) => {\n reverseMap[\"\" + [r.start, r.end]] = key;\n return [r.start, r.end];\n })\n );\n }\n indices.sort((a, b) => a - b);\n\n for (let i = 0; i < indices.length - 1; i++) {\n const start = indices[i];\n const end = indices[i + 1];\n if (start === end) {\n continue;\n }\n const regionKey = reverseMap[\"\" + [start, end]];\n\n ret.push([regionKey || null, array.slice(start, end)]);\n }\n\n return ret;\n}\n", "import * as Ast from \"@unified-latex/unified-latex-types\";\nimport { match } from \"@unified-latex/unified-latex-util-match\";\nimport { EXIT, visit } from \"@unified-latex/unified-latex-util-visit\";\n\n/**\n * Escape a string so that it can be used to build a regular expression.\n *\n * From: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions\n */\nfunction escapeRegExp(str: string) {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"); // $& means the whole matched string\n}\n\n/**\n * Build a regular expression that matches everything up to the first non-allowed symbol.\n */\nfunction buildWordRegex(allowedSet: Set<string>): RegExp {\n // /\\p{L}/ matches all letters, including unicode letters. We join this with\n // everything allowed in our set to form a regexp like\n // /(\\p{L}|_|:)*/u\n // The `u` at the end allows unicode characters to be matched.\n const regexpStr = `^(${[\"\\\\p{L}\"]\n .concat(Array.from(allowedSet).map(escapeRegExp))\n .join(\"|\")})*`;\n return new RegExp(regexpStr, \"u\");\n}\n\n/**\n * Checks whether the array has a macro that could be reparsed given the `allowedTokens` but\n * do not do any reparsing. This function can be used in auto-detection schemes to determine if\n * macro names should actually be reparsed.\n */\nexport function hasReparsableMacroNamesInArray(\n tree: Ast.Node[],\n allowedTokens: Set<string>\n): boolean {\n for (let i = 0; i < tree.length; i++) {\n const macro = tree[i];\n const string = tree[i + 1];\n if (match.anyMacro(macro) && match.anyString(string)) {\n // There are two options. Either the macro ends with the special character,\n // e.g. `\\@foo` or the special character starts the next string, e.g. `\\foo@`.\n if (\n allowedTokens.has(\n macro.content.charAt(macro.content.length - 1)\n ) ||\n allowedTokens.has(string.content.charAt(0))\n ) {\n return true;\n }\n }\n }\n return false;\n}\n\n/**\n * Checks whether `tree` has a macro that could be reparsed given the `allowedTokens` but\n * do not do any reparsing. This function can be used in auto-detection schemes to determine if\n * macro names should actually be reparsed.\n */\nexport function hasReparsableMacroNames(\n tree: Ast.Ast,\n allowedTokens: string | Set<string>\n): boolean {\n if (typeof allowedTokens === \"string\") {\n allowedTokens = new Set(allowedTokens.split(\"\"));\n }\n // Recast so typescript doesn't complain\n const _allowedTokens = allowedTokens;\n for (const v of _allowedTokens) {\n if (v.length > 1) {\n throw new Error(\n `Only single characters are allowed as \\`allowedTokens\\` when reparsing macro names, not \\`${v}\\`.`\n );\n }\n }\n\n let ret = false;\n visit(\n tree,\n (nodes) => {\n if (hasReparsableMacroNamesInArray(nodes, _allowedTokens)) {\n ret = true;\n return EXIT;\n }\n },\n { includeArrays: true, test: Array.isArray }\n );\n return ret;\n}\n\n/**\n * Reparses all macro names in the array so that they may optionally include characters listed in `allowedTokens`.\n * This is used, for example, when parsing expl3 syntax which allows `_` to be used in a macro name (even though\n * `_` is normally stops the parsing for a macro name).\n */\nexport function reparseMacroNamesInArray(\n tree: Ast.Node[],\n allowedTokens: Set<string>\n) {\n const regex = buildWordRegex(allowedTokens);\n let i = 0;\n while (i < tree.length) {\n const macro = tree[i];\n const string = tree[i + 1];\n if (\n match.anyMacro(macro) &&\n // The _^ macros in math mode should not be extended no-matter what;\n // So we check to make sure that the macro we're dealing with has the default escape token.\n (macro.escapeToken == null || macro.escapeToken === \"\\\\\") &&\n match.anyString(string) &&\n // There are two options. Either the macro ends with the special character,\n // e.g. `\\@foo` or the special character starts the next string, e.g. `\\foo@`.\n (allowedTokens.has(\n macro.content.charAt(macro.content.length - 1)\n ) ||\n allowedTokens.has(string.content.charAt(0)))\n ) {\n // There might be a number somewhere in the string. If so, we should\n // break the string apart at that number\n const match = string.content.match(regex);\n const takeable = match ? match[0] : \"\";\n if (takeable.length > 0) {\n if (takeable.length === string.content.length) {\n // The whole string can be appended to the macro name\n macro.content += string.content;\n tree.splice(i + 1, 1);\n\n // Preserve the source location if available\n if (macro.position && string.position?.end) {\n macro.position.end = string.position.end;\n }\n } else {\n // Only part of the string can be appended to the macro name\n macro.content += takeable;\n string.content = string.content.slice(takeable.length);\n\n // Preserve the source location if available\n if (macro.position?.end) {\n macro.position.end.offset += takeable.length;\n macro.position.end.column += takeable.length;\n }\n if (string.position?.start) {\n string.position.start.offset += takeable.length;\n string.position.start.column += takeable.length;\n }\n }\n } else {\n i++;\n }\n } else {\n ++i;\n }\n }\n}\n\n/**\n * Reparses all macro names so that they may optionally include characters listed in `allowedTokens`.\n * This is used, for example, when parsing expl3 syntax which allows `_` to be used in a macro name (even though\n * `_` is normally stops the parsing for a macro name). Thus, a macro `\\foo_bar:Nn` would be parsed as having\n * the name `foo_bar:Nn` rather than as `foo` followed by the strings `_`, `bar`, `:`, `Nn`.\n */\nexport function reparseMacroNames(\n tree: Ast.Ast,\n allowedTokens: string | Set<string>\n) {\n if (typeof allowedTokens === \"string\") {\n allowedTokens = new Set(allowedTokens.split(\"\"));\n }\n // Recast so typescript doesn't complain\n const _allowedTokens = allowedTokens;\n for (const v of _allowedTokens) {\n if (v.length > 1) {\n throw new Error(\n `Only single characters are allowed as \\`allowedTokens\\` when reparsing macro names, not \\`${v}\\`.`\n );\n }\n }\n\n visit(\n tree,\n (nodes) => {\n reparseMacroNamesInArray(nodes, _allowedTokens);\n },\n { includeArrays: true, test: Array.isArray }\n );\n}\n"],
5
- "mappings": "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",
5
+ "mappings": "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",
6
6
  "names": ["match", "visit", "match", "match", "visit"]
7
7
  }
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@unified-latex/unified-latex-util-catcode",
3
- "version": "1.3.2",
3
+ "version": "1.4.2",
4
4
  "description": "Tools for manipulating unified-latex ASTs",
5
5
  "main": "index.js",
6
6
  "type": "module",
7
7
  "dependencies": {
8
- "@unified-latex/unified-latex-types": "^1.3.1",
9
- "@unified-latex/unified-latex-util-match": "^1.3.1",
10
- "@unified-latex/unified-latex-util-visit": "^1.3.2"
8
+ "@unified-latex/unified-latex-types": "^1.4.2",
9
+ "@unified-latex/unified-latex-util-match": "^1.4.2",
10
+ "@unified-latex/unified-latex-util-visit": "^1.4.2"
11
11
  },
12
12
  "repository": {
13
13
  "type": "git",