@shikijs/core 1.6.4 → 1.7.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.
@@ -1005,6 +1005,11 @@ interface HighlighterCoreOptions {
1005
1005
  * Load wasm file from a custom path or using a custom function.
1006
1006
  */
1007
1007
  loadWasm?: LoadWasmOptions;
1008
+ /**
1009
+ * Emit console warnings to alert users of potential issues.
1010
+ * @default true
1011
+ */
1012
+ warnings?: boolean;
1008
1013
  }
1009
1014
  interface BundledHighlighterOptions<L extends string, T extends string> {
1010
1015
  /**
package/dist/index.mjs CHANGED
@@ -537,6 +537,26 @@ function tokenizeWithTheme(code, grammar, theme, colorMap, options) {
537
537
  let ruleStack = INITIAL;
538
538
  let actual = [];
539
539
  const final = [];
540
+ const themeSettingsSelectors = [];
541
+ if (options.includeExplanation) {
542
+ for (const setting of theme.settings) {
543
+ let selectors;
544
+ switch (typeof setting.scope) {
545
+ case 'string':
546
+ selectors = setting.scope.split(/,/).map(scope => scope.trim());
547
+ break;
548
+ case 'object':
549
+ selectors = setting.scope;
550
+ break;
551
+ default:
552
+ continue;
553
+ }
554
+ themeSettingsSelectors.push({
555
+ settings: setting,
556
+ selectors: selectors.map(selector => selector.split(/ /)),
557
+ });
558
+ }
559
+ }
540
560
  for (let i = 0, len = lines.length; i < len; i++) {
541
561
  const [line, lineOffset] = lines[i];
542
562
  if (line === '') {
@@ -588,7 +608,7 @@ function tokenizeWithTheme(code, grammar, theme, colorMap, options) {
588
608
  offset += tokenWithScopesText.length;
589
609
  token.explanation.push({
590
610
  content: tokenWithScopesText,
591
- scopes: explainThemeScopes(theme, tokenWithScopes.scopes),
611
+ scopes: explainThemeScopes(themeSettingsSelectors, tokenWithScopes.scopes),
592
612
  });
593
613
  tokensWithScopesIndex += 1;
594
614
  }
@@ -601,31 +621,29 @@ function tokenizeWithTheme(code, grammar, theme, colorMap, options) {
601
621
  }
602
622
  return final;
603
623
  }
604
- function explainThemeScopes(theme, scopes) {
624
+ function explainThemeScopes(themeSelectors, scopes) {
605
625
  const result = [];
606
626
  for (let i = 0, len = scopes.length; i < len; i++) {
607
627
  const parentScopes = scopes.slice(0, i);
608
628
  const scope = scopes[i];
609
629
  result[i] = {
610
630
  scopeName: scope,
611
- themeMatches: explainThemeScope(theme, scope, parentScopes),
631
+ themeMatches: explainThemeScope(themeSelectors, scope, parentScopes),
612
632
  };
613
633
  }
614
634
  return result;
615
635
  }
616
636
  function matchesOne(selector, scope) {
617
- const selectorPrefix = `${selector}.`;
618
- if (selector === scope || scope.substring(0, selectorPrefix.length) === selectorPrefix)
619
- return true;
620
- return false;
637
+ return selector === scope
638
+ || (scope.substring(0, selector.length) === selector && scope[selector.length] === '.');
621
639
  }
622
- function matches(selector, selectorParentScopes, scope, parentScopes) {
623
- if (!matchesOne(selector, scope))
640
+ function matches(selectors, scope, parentScopes) {
641
+ if (!matchesOne(selectors[selectors.length - 1], scope))
624
642
  return false;
625
- let selectorParentIndex = selectorParentScopes.length - 1;
643
+ let selectorParentIndex = selectors.length - 2;
626
644
  let parentIndex = parentScopes.length - 1;
627
645
  while (selectorParentIndex >= 0 && parentIndex >= 0) {
628
- if (matchesOne(selectorParentScopes[selectorParentIndex], parentScopes[parentIndex]))
646
+ if (matchesOne(selectors[selectorParentIndex], parentScopes[parentIndex]))
629
647
  selectorParentIndex -= 1;
630
648
  parentIndex -= 1;
631
649
  }
@@ -633,28 +651,13 @@ function matches(selector, selectorParentScopes, scope, parentScopes) {
633
651
  return true;
634
652
  return false;
635
653
  }
636
- function explainThemeScope(theme, scope, parentScopes) {
654
+ function explainThemeScope(themeSettingsSelectors, scope, parentScopes) {
637
655
  const result = [];
638
- let resultLen = 0;
639
- for (let i = 0, len = theme.settings.length; i < len; i++) {
640
- const setting = theme.settings[i];
641
- let selectors;
642
- if (typeof setting.scope === 'string')
643
- selectors = setting.scope.split(/,/).map(scope => scope.trim());
644
- else if (Array.isArray(setting.scope))
645
- selectors = setting.scope;
646
- else
647
- continue;
648
- for (let j = 0, lenJ = selectors.length; j < lenJ; j++) {
649
- const rawSelector = selectors[j];
650
- const rawSelectorPieces = rawSelector.split(/ /);
651
- const selector = rawSelectorPieces[rawSelectorPieces.length - 1];
652
- const selectorParentScopes = rawSelectorPieces.slice(0, rawSelectorPieces.length - 1);
653
- if (matches(selector, selectorParentScopes, scope, parentScopes)) {
654
- // match!
655
- result[resultLen++] = setting;
656
- // break the loop
657
- j = lenJ;
656
+ for (const { selectors, settings } of themeSettingsSelectors) {
657
+ for (const selectorPieces of selectors) {
658
+ if (matches(selectorPieces, scope, parentScopes)) {
659
+ result.push(settings);
660
+ break; // continue to the next theme settings
658
661
  }
659
662
  }
660
663
  }
@@ -4648,6 +4651,50 @@ async function main(init) {
4648
4651
  }
4649
4652
  return false;
4650
4653
  }
4654
+ const UTF8Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder('utf8') : undefined;
4655
+ function UTF8ArrayToString(heapOrArray, idx, maxBytesToRead = 1024) {
4656
+ const endIdx = idx + maxBytesToRead;
4657
+ let endPtr = idx;
4658
+ while (heapOrArray[endPtr] && !(endPtr >= endIdx))
4659
+ ++endPtr;
4660
+ if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) {
4661
+ return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr));
4662
+ }
4663
+ let str = '';
4664
+ while (idx < endPtr) {
4665
+ let u0 = heapOrArray[idx++];
4666
+ if (!(u0 & 128)) {
4667
+ str += String.fromCharCode(u0);
4668
+ continue;
4669
+ }
4670
+ const u1 = heapOrArray[idx++] & 63;
4671
+ if ((u0 & 224) === 192) {
4672
+ str += String.fromCharCode(((u0 & 31) << 6) | u1);
4673
+ continue;
4674
+ }
4675
+ const u2 = heapOrArray[idx++] & 63;
4676
+ if ((u0 & 240) === 224) {
4677
+ u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
4678
+ }
4679
+ else {
4680
+ u0 = ((u0 & 7) << 18)
4681
+ | (u1 << 12)
4682
+ | (u2 << 6)
4683
+ | (heapOrArray[idx++] & 63);
4684
+ }
4685
+ if (u0 < 65536) {
4686
+ str += String.fromCharCode(u0);
4687
+ }
4688
+ else {
4689
+ const ch = u0 - 65536;
4690
+ str += String.fromCharCode(55296 | (ch >> 10), 56320 | (ch & 1023));
4691
+ }
4692
+ }
4693
+ return str;
4694
+ }
4695
+ function UTF8ToString(ptr, maxBytesToRead) {
4696
+ return ptr ? UTF8ArrayToString(binding.HEAPU8, ptr, maxBytesToRead) : '';
4697
+ }
4651
4698
  const asmLibraryArg = {
4652
4699
  emscripten_get_now: _emscripten_get_now,
4653
4700
  emscripten_memcpy_big: _emscripten_memcpy_big,
@@ -4663,6 +4710,7 @@ async function main(init) {
4663
4710
  wasmMemory = exports.memory;
4664
4711
  updateGlobalBufferAndViews(wasmMemory.buffer);
4665
4712
  Object.assign(binding, exports);
4713
+ binding.UTF8ToString = UTF8ToString;
4666
4714
  }
4667
4715
  await createWasm();
4668
4716
  return binding;
@@ -5335,10 +5383,14 @@ let _defaultWasmLoader;
5335
5383
  function setDefaultWasmLoader(_loader) {
5336
5384
  _defaultWasmLoader = _loader;
5337
5385
  }
5386
+ let instancesCount = 0;
5338
5387
  /**
5339
5388
  * Get the minimal shiki context for rendering.
5340
5389
  */
5341
5390
  async function getShikiInternal(options = {}) {
5391
+ instancesCount += 1;
5392
+ if (options.warnings !== false && instancesCount >= 10 && instancesCount % 10 === 0)
5393
+ console.warn(`[Shiki] ${instancesCount} instances have been created. Shiki is supposed to be used as a singleton, consider refactoring your code to cache your highlighter instance.`);
5342
5394
  async function normalizeGetter(p) {
5343
5395
  return Promise.resolve(typeof p === 'function' ? p() : p).then(r => r.default || r);
5344
5396
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@shikijs/core",
3
3
  "type": "module",
4
- "version": "1.6.4",
4
+ "version": "1.7.0",
5
5
  "description": "Core of Shiki",
6
6
  "author": "Pine Wu <octref@gmail.com>; Anthony Fu <anthonyfu117@hotmail.com>",
7
7
  "license": "MIT",