@shikijs/transformers 4.0.2 → 4.2.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.
- package/dist/index.mjs +35 -31
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
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*)$/;
|
|
4
|
+
const RE_V3_END_COMMENT_PREFIX = /(?:\/\/|#|;{1,2}|%{1,2}|--)(\s*)$/;
|
|
2
5
|
/**
|
|
3
6
|
* some comment formats have to be located at the end of line
|
|
4
7
|
* hence we can skip matching them for other tokens
|
|
@@ -24,7 +27,7 @@ function parseComments(lines, jsx, matchAlgorithm) {
|
|
|
24
27
|
if (token.type !== "text") return element;
|
|
25
28
|
const isLast = idx === line.children.length - 1;
|
|
26
29
|
if (!matchToken(token.value, isLast)) return element;
|
|
27
|
-
const rawSplits = token.value.split(
|
|
30
|
+
const rawSplits = token.value.split(RE_SPLIT_COMMENT);
|
|
28
31
|
if (rawSplits.length <= 1) return element;
|
|
29
32
|
let splits = [rawSplits[0]];
|
|
30
33
|
for (let i = 1; i < rawSplits.length; i += 2) splits.push(rawSplits[i] + (rawSplits[i + 1] || ""));
|
|
@@ -130,15 +133,24 @@ function matchToken(text, isLast) {
|
|
|
130
133
|
* For matchAlgorithm v1
|
|
131
134
|
*/
|
|
132
135
|
function v1ClearEndCommentPrefix(text) {
|
|
133
|
-
const match = text.match(
|
|
136
|
+
const match = text.match(RE_V1_END_COMMENT_PREFIX);
|
|
134
137
|
if (match && match[1].trim().length === 0) return text.slice(0, match.index);
|
|
135
138
|
return text;
|
|
136
139
|
}
|
|
137
|
-
|
|
140
|
+
/**
|
|
141
|
+
* Remove empty comment prefixes at line end, e.g. `// `
|
|
142
|
+
*
|
|
143
|
+
* For matchAlgorithm v3
|
|
144
|
+
*/
|
|
145
|
+
function v3ClearEndCommentPrefix(text) {
|
|
146
|
+
const match = text.match(RE_V3_END_COMMENT_PREFIX);
|
|
147
|
+
if (match && match[1].trim().length === 0) return text.slice(0, match.index).trimEnd();
|
|
148
|
+
return text;
|
|
149
|
+
}
|
|
138
150
|
//#endregion
|
|
139
151
|
//#region src/shared/notation-transformer.ts
|
|
140
152
|
function createCommentNotationTransformer(name, regex, onMatch, matchAlgorithm) {
|
|
141
|
-
|
|
153
|
+
matchAlgorithm ??= "v3";
|
|
142
154
|
return {
|
|
143
155
|
name,
|
|
144
156
|
code(code) {
|
|
@@ -162,6 +174,7 @@ function createCommentNotationTransformer(name, regex, onMatch, matchAlgorithm)
|
|
|
162
174
|
});
|
|
163
175
|
if (!replaced) continue;
|
|
164
176
|
if (matchAlgorithm === "v1") comment.info[1] = v1ClearEndCommentPrefix(comment.info[1]);
|
|
177
|
+
else if (matchAlgorithm === "v3") comment.info[1] = v3ClearEndCommentPrefix(comment.info[1]);
|
|
165
178
|
const isEmpty = comment.info[1].trim().length === 0;
|
|
166
179
|
if (isEmpty) comment.info[1] = "";
|
|
167
180
|
if (isEmpty && comment.isLineCommentOnly) linesToRemove.push(comment.line);
|
|
@@ -194,7 +207,6 @@ function createCommentNotationTransformer(name, regex, onMatch, matchAlgorithm)
|
|
|
194
207
|
}
|
|
195
208
|
};
|
|
196
209
|
}
|
|
197
|
-
|
|
198
210
|
//#endregion
|
|
199
211
|
//#region src/transformers/compact-line-options.ts
|
|
200
212
|
/**
|
|
@@ -210,12 +222,12 @@ function transformerCompactLineOptions(lineOptions = []) {
|
|
|
210
222
|
}
|
|
211
223
|
};
|
|
212
224
|
}
|
|
213
|
-
|
|
214
225
|
//#endregion
|
|
215
226
|
//#region src/transformers/meta-highlight.ts
|
|
227
|
+
const RE_HIGHLIGHT_LINES = /\{([\d,-]+)\}/;
|
|
216
228
|
function parseMetaHighlightString(meta) {
|
|
217
229
|
if (!meta) return null;
|
|
218
|
-
const match = meta.match(
|
|
230
|
+
const match = meta.match(RE_HIGHLIGHT_LINES);
|
|
219
231
|
if (!match) return null;
|
|
220
232
|
return match[1].split(",").flatMap((v) => {
|
|
221
233
|
const range = v.split("-").map((n) => Number.parseInt(n, 10));
|
|
@@ -241,12 +253,13 @@ function transformerMetaHighlight(options = {}) {
|
|
|
241
253
|
}
|
|
242
254
|
};
|
|
243
255
|
}
|
|
244
|
-
|
|
245
256
|
//#endregion
|
|
246
257
|
//#region src/transformers/meta-highlight-word.ts
|
|
258
|
+
const RE_WORD_MATCH = /\/((?:\\.|[^/])+)\//g;
|
|
259
|
+
const RE_ESCAPE_BACKSLASH = /\\(.)/g;
|
|
247
260
|
function parseMetaHighlightWords(meta) {
|
|
248
261
|
if (!meta) return [];
|
|
249
|
-
return
|
|
262
|
+
return [...meta.matchAll(RE_WORD_MATCH)].map((v) => v[1].replace(RE_ESCAPE_BACKSLASH, "$1"));
|
|
250
263
|
}
|
|
251
264
|
/**
|
|
252
265
|
* Allow using `/word/` in the code snippet meta to mark highlighted words.
|
|
@@ -282,11 +295,11 @@ function findAllSubstringIndexes(str, substr) {
|
|
|
282
295
|
}
|
|
283
296
|
return indexes;
|
|
284
297
|
}
|
|
285
|
-
|
|
286
298
|
//#endregion
|
|
287
299
|
//#region src/transformers/notation-map.ts
|
|
300
|
+
const RE_ESCAPE_SPECIAL = /[.*+?^${}()|[\]\\]/g;
|
|
288
301
|
function escapeRegExp(str) {
|
|
289
|
-
return str.replace(
|
|
302
|
+
return str.replace(RE_ESCAPE_SPECIAL, "\\$&");
|
|
290
303
|
}
|
|
291
304
|
function transformerNotationMap(options = {}, name = "@shikijs/transformers:notation-map") {
|
|
292
305
|
const { classMap = {}, classActivePre = void 0, classActiveCode = void 0 } = options;
|
|
@@ -298,7 +311,6 @@ function transformerNotationMap(options = {}, name = "@shikijs/transformers:nota
|
|
|
298
311
|
return true;
|
|
299
312
|
}, options.matchAlgorithm);
|
|
300
313
|
}
|
|
301
|
-
|
|
302
314
|
//#endregion
|
|
303
315
|
//#region src/transformers/notation-diff.ts
|
|
304
316
|
/**
|
|
@@ -316,7 +328,6 @@ function transformerNotationDiff(options = {}) {
|
|
|
316
328
|
matchAlgorithm: options.matchAlgorithm
|
|
317
329
|
}, "@shikijs/transformers:notation-diff");
|
|
318
330
|
}
|
|
319
|
-
|
|
320
331
|
//#endregion
|
|
321
332
|
//#region src/transformers/notation-error-level.ts
|
|
322
333
|
/**
|
|
@@ -335,7 +346,6 @@ function transformerNotationErrorLevel(options = {}) {
|
|
|
335
346
|
matchAlgorithm: options.matchAlgorithm
|
|
336
347
|
}, "@shikijs/transformers:notation-error-level");
|
|
337
348
|
}
|
|
338
|
-
|
|
339
349
|
//#endregion
|
|
340
350
|
//#region src/transformers/notation-focus.ts
|
|
341
351
|
/**
|
|
@@ -350,7 +360,6 @@ function transformerNotationFocus(options = {}) {
|
|
|
350
360
|
matchAlgorithm: options.matchAlgorithm
|
|
351
361
|
}, "@shikijs/transformers:notation-focus");
|
|
352
362
|
}
|
|
353
|
-
|
|
354
363
|
//#endregion
|
|
355
364
|
//#region src/transformers/notation-highlight.ts
|
|
356
365
|
/**
|
|
@@ -368,7 +377,6 @@ function transformerNotationHighlight(options = {}) {
|
|
|
368
377
|
matchAlgorithm: options.matchAlgorithm
|
|
369
378
|
}, "@shikijs/transformers:notation-highlight");
|
|
370
379
|
}
|
|
371
|
-
|
|
372
380
|
//#endregion
|
|
373
381
|
//#region src/shared/highlight-word.ts
|
|
374
382
|
function highlightWordInLine(line, ignoredElement, word, className) {
|
|
@@ -433,20 +441,20 @@ function inheritElement(original, overrides) {
|
|
|
433
441
|
...overrides
|
|
434
442
|
};
|
|
435
443
|
}
|
|
436
|
-
|
|
437
444
|
//#endregion
|
|
438
445
|
//#region src/transformers/notation-highlight-word.ts
|
|
446
|
+
const RE_CODE_WORD = /\s*\[!code word:((?:\\.|[^:\]])+)(:\d+)?\]/;
|
|
447
|
+
const RE_UNESCAPE = /\\(.)/g;
|
|
439
448
|
function transformerNotationWordHighlight(options = {}) {
|
|
440
449
|
const { classActiveWord = "highlighted-word", classActivePre = void 0 } = options;
|
|
441
|
-
return createCommentNotationTransformer("@shikijs/transformers:notation-highlight-word",
|
|
450
|
+
return createCommentNotationTransformer("@shikijs/transformers:notation-highlight-word", RE_CODE_WORD, function([_, word, range], _line, comment, lines, index) {
|
|
442
451
|
const lineNum = range ? Number.parseInt(range.slice(1), 10) : lines.length;
|
|
443
|
-
word = word.replace(
|
|
452
|
+
word = word.replace(RE_UNESCAPE, "$1");
|
|
444
453
|
for (let i = index; i < Math.min(index + lineNum, lines.length); i++) highlightWordInLine.call(this, lines[i], comment, word, classActiveWord);
|
|
445
454
|
if (classActivePre) this.addClassToHast(this.pre, classActivePre);
|
|
446
455
|
return true;
|
|
447
456
|
}, options.matchAlgorithm);
|
|
448
457
|
}
|
|
449
|
-
|
|
450
458
|
//#endregion
|
|
451
459
|
//#region src/transformers/remove-comments.ts
|
|
452
460
|
/**
|
|
@@ -475,7 +483,6 @@ function transformerRemoveComments(options = {}) {
|
|
|
475
483
|
}
|
|
476
484
|
};
|
|
477
485
|
}
|
|
478
|
-
|
|
479
486
|
//#endregion
|
|
480
487
|
//#region src/transformers/remove-line-breaks.ts
|
|
481
488
|
/**
|
|
@@ -490,7 +497,6 @@ function transformerRemoveLineBreak() {
|
|
|
490
497
|
}
|
|
491
498
|
};
|
|
492
499
|
}
|
|
493
|
-
|
|
494
500
|
//#endregion
|
|
495
501
|
//#region src/transformers/remove-notation-escape.ts
|
|
496
502
|
/**
|
|
@@ -511,9 +517,10 @@ function transformerRemoveNotationEscape() {
|
|
|
511
517
|
}
|
|
512
518
|
};
|
|
513
519
|
}
|
|
514
|
-
|
|
515
520
|
//#endregion
|
|
516
521
|
//#region src/transformers/render-indent-guides.ts
|
|
522
|
+
const RE_INDENT_META = /\{indent:(\d+|false)\}/;
|
|
523
|
+
const RE_NON_BLANK = /[^ \t]/;
|
|
517
524
|
/**
|
|
518
525
|
* Render indentations as separate tokens.
|
|
519
526
|
* Apply with CSS, it can be used to render indent guides visually.
|
|
@@ -522,7 +529,7 @@ function transformerRenderIndentGuides(options = {}) {
|
|
|
522
529
|
return {
|
|
523
530
|
name: "@shikijs/transformers:render-indent-guides",
|
|
524
531
|
code(hast) {
|
|
525
|
-
const indent = Number(this.options.meta?.indent ?? this.options.meta?.__raw?.match(
|
|
532
|
+
const indent = Number(this.options.meta?.indent ?? this.options.meta?.__raw?.match(RE_INDENT_META)?.[1] ?? options.indent ?? 2);
|
|
526
533
|
if (Number.isNaN(indent) || indent <= 0) return hast;
|
|
527
534
|
const indentRegex = new RegExp(` {${indent}}| {0,${indent - 1}}\t| {1,}$`, "g");
|
|
528
535
|
const emptyLines = [];
|
|
@@ -535,7 +542,7 @@ function transformerRenderIndentGuides(options = {}) {
|
|
|
535
542
|
continue;
|
|
536
543
|
}
|
|
537
544
|
const text = first.children[0];
|
|
538
|
-
const blanks = text.value.split(
|
|
545
|
+
const blanks = text.value.split(RE_NON_BLANK, 1)[0];
|
|
539
546
|
const ranges = [];
|
|
540
547
|
for (const match of blanks.matchAll(indentRegex)) {
|
|
541
548
|
const start = match.index;
|
|
@@ -570,7 +577,6 @@ function transformerRenderIndentGuides(options = {}) {
|
|
|
570
577
|
}
|
|
571
578
|
};
|
|
572
579
|
}
|
|
573
|
-
|
|
574
580
|
//#endregion
|
|
575
581
|
//#region src/shared/utils.ts
|
|
576
582
|
function isTab(part) {
|
|
@@ -613,9 +619,9 @@ function splitSpaces(parts, type, renderContinuousSpaces = true) {
|
|
|
613
619
|
...parts.slice(parts.length - rightCount)
|
|
614
620
|
];
|
|
615
621
|
}
|
|
616
|
-
|
|
617
622
|
//#endregion
|
|
618
623
|
//#region src/transformers/render-whitespace.ts
|
|
624
|
+
const RE_SPACE_OR_TAB = /([ \t])/;
|
|
619
625
|
/**
|
|
620
626
|
* Render whitespaces as separate tokens.
|
|
621
627
|
* Apply with CSS, it can be used to render tabs and spaces visually.
|
|
@@ -643,7 +649,7 @@ function transformerRenderWhitespace(options = {}) {
|
|
|
643
649
|
if (position === "leading" && index !== 0) return token;
|
|
644
650
|
const node = token.children[0];
|
|
645
651
|
if (node.type !== "text" || !node.value) return token;
|
|
646
|
-
const parts = splitSpaces(node.value.split(
|
|
652
|
+
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
653
|
if (parts.length <= 1) return token;
|
|
648
654
|
return parts.map((part) => {
|
|
649
655
|
const clone = {
|
|
@@ -665,7 +671,6 @@ function transformerRenderWhitespace(options = {}) {
|
|
|
665
671
|
}
|
|
666
672
|
};
|
|
667
673
|
}
|
|
668
|
-
|
|
669
674
|
//#endregion
|
|
670
675
|
//#region src/transformers/style-to-class.ts
|
|
671
676
|
/**
|
|
@@ -734,6 +739,5 @@ function cyrb53(str, seed = 0) {
|
|
|
734
739
|
h2 ^= Math.imul(h1 ^ h1 >>> 13, 3266489909);
|
|
735
740
|
return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(36).slice(0, 6);
|
|
736
741
|
}
|
|
737
|
-
|
|
738
742
|
//#endregion
|
|
739
|
-
export { createCommentNotationTransformer, findAllSubstringIndexes, parseMetaHighlightString, parseMetaHighlightWords, transformerCompactLineOptions, transformerMetaHighlight, transformerMetaWordHighlight, transformerNotationDiff, transformerNotationErrorLevel, transformerNotationFocus, transformerNotationHighlight, transformerNotationMap, transformerNotationWordHighlight, transformerRemoveComments, transformerRemoveLineBreak, transformerRemoveNotationEscape, transformerRenderIndentGuides, transformerRenderWhitespace, transformerStyleToClass };
|
|
743
|
+
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
|
|
4
|
+
"version": "4.2.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
|
|
34
|
-
"@shikijs/types": "4.0
|
|
33
|
+
"@shikijs/core": "4.2.0",
|
|
34
|
+
"@shikijs/types": "4.2.0"
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
37
|
"build": "tsdown",
|