@shikijs/transformers 4.0.1 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.mjs +23 -31
  2. package/package.json +3 -3
package/dist/index.mjs CHANGED
@@ -1,4 +1,6 @@
1
1
  //#region src/shared/parse-comments.ts
2
+ const RE_SPLIT_COMMENT = /(\s+\/\/)/;
3
+ const RE_V1_END_COMMENT_PREFIX = /(?:\/\/|["'#]|;{1,2}|%{1,2}|--)(\s*)$/;
2
4
  /**
3
5
  * some comment formats have to be located at the end of line
4
6
  * hence we can skip matching them for other tokens
@@ -24,7 +26,7 @@ function parseComments(lines, jsx, matchAlgorithm) {
24
26
  if (token.type !== "text") return element;
25
27
  const isLast = idx === line.children.length - 1;
26
28
  if (!matchToken(token.value, isLast)) return element;
27
- const rawSplits = token.value.split(/(\s+\/\/)/);
29
+ const rawSplits = token.value.split(RE_SPLIT_COMMENT);
28
30
  if (rawSplits.length <= 1) return element;
29
31
  let splits = [rawSplits[0]];
30
32
  for (let i = 1; i < rawSplits.length; i += 2) splits.push(rawSplits[i] + (rawSplits[i + 1] || ""));
@@ -130,15 +132,14 @@ function matchToken(text, isLast) {
130
132
  * For matchAlgorithm v1
131
133
  */
132
134
  function v1ClearEndCommentPrefix(text) {
133
- const match = text.match(/(?:\/\/|["'#]|;{1,2}|%{1,2}|--)(\s*)$/);
135
+ const match = text.match(RE_V1_END_COMMENT_PREFIX);
134
136
  if (match && match[1].trim().length === 0) return text.slice(0, match.index);
135
137
  return text;
136
138
  }
137
-
138
139
  //#endregion
139
140
  //#region src/shared/notation-transformer.ts
140
141
  function createCommentNotationTransformer(name, regex, onMatch, matchAlgorithm) {
141
- if (matchAlgorithm == null) matchAlgorithm = "v3";
142
+ matchAlgorithm ??= "v3";
142
143
  return {
143
144
  name,
144
145
  code(code) {
@@ -194,7 +195,6 @@ function createCommentNotationTransformer(name, regex, onMatch, matchAlgorithm)
194
195
  }
195
196
  };
196
197
  }
197
-
198
198
  //#endregion
199
199
  //#region src/transformers/compact-line-options.ts
200
200
  /**
@@ -210,12 +210,12 @@ function transformerCompactLineOptions(lineOptions = []) {
210
210
  }
211
211
  };
212
212
  }
213
-
214
213
  //#endregion
215
214
  //#region src/transformers/meta-highlight.ts
215
+ const RE_HIGHLIGHT_LINES = /\{([\d,-]+)\}/;
216
216
  function parseMetaHighlightString(meta) {
217
217
  if (!meta) return null;
218
- const match = meta.match(/\{([\d,-]+)\}/);
218
+ const match = meta.match(RE_HIGHLIGHT_LINES);
219
219
  if (!match) return null;
220
220
  return match[1].split(",").flatMap((v) => {
221
221
  const range = v.split("-").map((n) => Number.parseInt(n, 10));
@@ -241,12 +241,13 @@ function transformerMetaHighlight(options = {}) {
241
241
  }
242
242
  };
243
243
  }
244
-
245
244
  //#endregion
246
245
  //#region src/transformers/meta-highlight-word.ts
246
+ const RE_WORD_MATCH = /\/((?:\\.|[^/])+)\//g;
247
+ const RE_ESCAPE_BACKSLASH = /\\(.)/g;
247
248
  function parseMetaHighlightWords(meta) {
248
249
  if (!meta) return [];
249
- return Array.from(meta.matchAll(/\/((?:\\.|[^/])+)\//g)).map((v) => v[1].replace(/\\(.)/g, "$1"));
250
+ return [...meta.matchAll(RE_WORD_MATCH)].map((v) => v[1].replace(RE_ESCAPE_BACKSLASH, "$1"));
250
251
  }
251
252
  /**
252
253
  * Allow using `/word/` in the code snippet meta to mark highlighted words.
@@ -282,11 +283,11 @@ function findAllSubstringIndexes(str, substr) {
282
283
  }
283
284
  return indexes;
284
285
  }
285
-
286
286
  //#endregion
287
287
  //#region src/transformers/notation-map.ts
288
+ const RE_ESCAPE_SPECIAL = /[.*+?^${}()|[\]\\]/g;
288
289
  function escapeRegExp(str) {
289
- return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
290
+ return str.replace(RE_ESCAPE_SPECIAL, "\\$&");
290
291
  }
291
292
  function transformerNotationMap(options = {}, name = "@shikijs/transformers:notation-map") {
292
293
  const { classMap = {}, classActivePre = void 0, classActiveCode = void 0 } = options;
@@ -298,7 +299,6 @@ function transformerNotationMap(options = {}, name = "@shikijs/transformers:nota
298
299
  return true;
299
300
  }, options.matchAlgorithm);
300
301
  }
301
-
302
302
  //#endregion
303
303
  //#region src/transformers/notation-diff.ts
304
304
  /**
@@ -316,7 +316,6 @@ function transformerNotationDiff(options = {}) {
316
316
  matchAlgorithm: options.matchAlgorithm
317
317
  }, "@shikijs/transformers:notation-diff");
318
318
  }
319
-
320
319
  //#endregion
321
320
  //#region src/transformers/notation-error-level.ts
322
321
  /**
@@ -335,7 +334,6 @@ function transformerNotationErrorLevel(options = {}) {
335
334
  matchAlgorithm: options.matchAlgorithm
336
335
  }, "@shikijs/transformers:notation-error-level");
337
336
  }
338
-
339
337
  //#endregion
340
338
  //#region src/transformers/notation-focus.ts
341
339
  /**
@@ -350,7 +348,6 @@ function transformerNotationFocus(options = {}) {
350
348
  matchAlgorithm: options.matchAlgorithm
351
349
  }, "@shikijs/transformers:notation-focus");
352
350
  }
353
-
354
351
  //#endregion
355
352
  //#region src/transformers/notation-highlight.ts
356
353
  /**
@@ -368,7 +365,6 @@ function transformerNotationHighlight(options = {}) {
368
365
  matchAlgorithm: options.matchAlgorithm
369
366
  }, "@shikijs/transformers:notation-highlight");
370
367
  }
371
-
372
368
  //#endregion
373
369
  //#region src/shared/highlight-word.ts
374
370
  function highlightWordInLine(line, ignoredElement, word, className) {
@@ -433,20 +429,20 @@ function inheritElement(original, overrides) {
433
429
  ...overrides
434
430
  };
435
431
  }
436
-
437
432
  //#endregion
438
433
  //#region src/transformers/notation-highlight-word.ts
434
+ const RE_CODE_WORD = /\s*\[!code word:((?:\\.|[^:\]])+)(:\d+)?\]/;
435
+ const RE_UNESCAPE = /\\(.)/g;
439
436
  function transformerNotationWordHighlight(options = {}) {
440
437
  const { classActiveWord = "highlighted-word", classActivePre = void 0 } = options;
441
- return createCommentNotationTransformer("@shikijs/transformers:notation-highlight-word", /\s*\[!code word:((?:\\.|[^:\]])+)(:\d+)?\]/, function([_, word, range], _line, comment, lines, index) {
438
+ return createCommentNotationTransformer("@shikijs/transformers:notation-highlight-word", RE_CODE_WORD, function([_, word, range], _line, comment, lines, index) {
442
439
  const lineNum = range ? Number.parseInt(range.slice(1), 10) : lines.length;
443
- word = word.replace(/\\(.)/g, "$1");
440
+ word = word.replace(RE_UNESCAPE, "$1");
444
441
  for (let i = index; i < Math.min(index + lineNum, lines.length); i++) highlightWordInLine.call(this, lines[i], comment, word, classActiveWord);
445
442
  if (classActivePre) this.addClassToHast(this.pre, classActivePre);
446
443
  return true;
447
444
  }, options.matchAlgorithm);
448
445
  }
449
-
450
446
  //#endregion
451
447
  //#region src/transformers/remove-comments.ts
452
448
  /**
@@ -475,7 +471,6 @@ function transformerRemoveComments(options = {}) {
475
471
  }
476
472
  };
477
473
  }
478
-
479
474
  //#endregion
480
475
  //#region src/transformers/remove-line-breaks.ts
481
476
  /**
@@ -490,7 +485,6 @@ function transformerRemoveLineBreak() {
490
485
  }
491
486
  };
492
487
  }
493
-
494
488
  //#endregion
495
489
  //#region src/transformers/remove-notation-escape.ts
496
490
  /**
@@ -511,9 +505,10 @@ function transformerRemoveNotationEscape() {
511
505
  }
512
506
  };
513
507
  }
514
-
515
508
  //#endregion
516
509
  //#region src/transformers/render-indent-guides.ts
510
+ const RE_INDENT_META = /\{indent:(\d+|false)\}/;
511
+ const RE_NON_BLANK = /[^ \t]/;
517
512
  /**
518
513
  * Render indentations as separate tokens.
519
514
  * Apply with CSS, it can be used to render indent guides visually.
@@ -522,7 +517,7 @@ function transformerRenderIndentGuides(options = {}) {
522
517
  return {
523
518
  name: "@shikijs/transformers:render-indent-guides",
524
519
  code(hast) {
525
- const indent = Number(this.options.meta?.indent ?? this.options.meta?.__raw?.match(/\{indent:(\d+|false)\}/)?.[1] ?? options.indent ?? 2);
520
+ const indent = Number(this.options.meta?.indent ?? this.options.meta?.__raw?.match(RE_INDENT_META)?.[1] ?? options.indent ?? 2);
526
521
  if (Number.isNaN(indent) || indent <= 0) return hast;
527
522
  const indentRegex = new RegExp(` {${indent}}| {0,${indent - 1}}\t| {1,}$`, "g");
528
523
  const emptyLines = [];
@@ -535,7 +530,7 @@ function transformerRenderIndentGuides(options = {}) {
535
530
  continue;
536
531
  }
537
532
  const text = first.children[0];
538
- const blanks = text.value.split(/[^ \t]/, 1)[0];
533
+ const blanks = text.value.split(RE_NON_BLANK, 1)[0];
539
534
  const ranges = [];
540
535
  for (const match of blanks.matchAll(indentRegex)) {
541
536
  const start = match.index;
@@ -570,7 +565,6 @@ function transformerRenderIndentGuides(options = {}) {
570
565
  }
571
566
  };
572
567
  }
573
-
574
568
  //#endregion
575
569
  //#region src/shared/utils.ts
576
570
  function isTab(part) {
@@ -613,9 +607,9 @@ function splitSpaces(parts, type, renderContinuousSpaces = true) {
613
607
  ...parts.slice(parts.length - rightCount)
614
608
  ];
615
609
  }
616
-
617
610
  //#endregion
618
611
  //#region src/transformers/render-whitespace.ts
612
+ const RE_SPACE_OR_TAB = /([ \t])/;
619
613
  /**
620
614
  * Render whitespaces as separate tokens.
621
615
  * Apply with CSS, it can be used to render tabs and spaces visually.
@@ -643,7 +637,7 @@ function transformerRenderWhitespace(options = {}) {
643
637
  if (position === "leading" && index !== 0) return token;
644
638
  const node = token.children[0];
645
639
  if (node.type !== "text" || !node.value) return token;
646
- const parts = splitSpaces(node.value.split(/([ \t])/).filter((i) => i.length), position === "boundary" && index === last && last !== 0 ? "trailing" : position, position !== "trailing" && position !== "leading");
640
+ const parts = splitSpaces(node.value.split(RE_SPACE_OR_TAB).filter((i) => i.length), position === "boundary" && index === last && last !== 0 ? "trailing" : position, position !== "trailing" && position !== "leading");
647
641
  if (parts.length <= 1) return token;
648
642
  return parts.map((part) => {
649
643
  const clone = {
@@ -665,7 +659,6 @@ function transformerRenderWhitespace(options = {}) {
665
659
  }
666
660
  };
667
661
  }
668
-
669
662
  //#endregion
670
663
  //#region src/transformers/style-to-class.ts
671
664
  /**
@@ -734,6 +727,5 @@ function cyrb53(str, seed = 0) {
734
727
  h2 ^= Math.imul(h1 ^ h1 >>> 13, 3266489909);
735
728
  return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(36).slice(0, 6);
736
729
  }
737
-
738
730
  //#endregion
739
- export { createCommentNotationTransformer, findAllSubstringIndexes, parseMetaHighlightString, parseMetaHighlightWords, transformerCompactLineOptions, transformerMetaHighlight, transformerMetaWordHighlight, transformerNotationDiff, transformerNotationErrorLevel, transformerNotationFocus, transformerNotationHighlight, transformerNotationMap, transformerNotationWordHighlight, transformerRemoveComments, transformerRemoveLineBreak, transformerRemoveNotationEscape, transformerRenderIndentGuides, transformerRenderWhitespace, transformerStyleToClass };
731
+ export { createCommentNotationTransformer, findAllSubstringIndexes, parseMetaHighlightString, parseMetaHighlightWords, transformerCompactLineOptions, transformerMetaHighlight, transformerMetaWordHighlight, transformerNotationDiff, transformerNotationErrorLevel, transformerNotationFocus, transformerNotationHighlight, transformerNotationMap, transformerNotationWordHighlight, transformerRemoveComments, transformerRemoveLineBreak, transformerRemoveNotationEscape, transformerRenderIndentGuides, transformerRenderWhitespace, transformerStyleToClass };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@shikijs/transformers",
3
3
  "type": "module",
4
- "version": "4.0.1",
4
+ "version": "4.1.0",
5
5
  "description": "Collective of common transformers transformers for Shiki",
6
6
  "author": "Anthony Fu <anthonyfu117@hotmail.com>",
7
7
  "license": "MIT",
@@ -30,8 +30,8 @@
30
30
  "node": ">=20"
31
31
  },
32
32
  "dependencies": {
33
- "@shikijs/core": "4.0.1",
34
- "@shikijs/types": "4.0.1"
33
+ "@shikijs/types": "4.1.0",
34
+ "@shikijs/core": "4.1.0"
35
35
  },
36
36
  "scripts": {
37
37
  "build": "tsdown",