@shikijs/core 3.17.0 → 3.18.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.d.mts +27 -0
- package/dist/index.mjs +64 -27
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -229,6 +229,19 @@ declare function addClassToHast(node: Element, className: string | string[]): El
|
|
|
229
229
|
|
|
230
230
|
/**
|
|
231
231
|
* Split a string into lines, each line preserves the line ending.
|
|
232
|
+
*
|
|
233
|
+
* @param code - The code string to split into lines
|
|
234
|
+
* @param preserveEnding - Whether to preserve line endings in the result
|
|
235
|
+
* @returns Array of tuples containing [line content, offset index]
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* ```ts
|
|
239
|
+
* splitLines('hello\nworld', false)
|
|
240
|
+
* // => [['hello', 0], ['world', 6]]
|
|
241
|
+
*
|
|
242
|
+
* splitLines('hello\nworld', true)
|
|
243
|
+
* // => [['hello\n', 0], ['world', 6]]
|
|
244
|
+
* ```
|
|
232
245
|
*/
|
|
233
246
|
declare function splitLines(code: string, preserveEnding?: boolean): [string, number][];
|
|
234
247
|
/**
|
|
@@ -245,6 +258,20 @@ declare function createPositionConverter(code: string): {
|
|
|
245
258
|
* Guess embedded languages from given code and highlighter.
|
|
246
259
|
*
|
|
247
260
|
* When highlighter is provided, only bundled languages will be included.
|
|
261
|
+
*
|
|
262
|
+
* @param code - The code string to analyze
|
|
263
|
+
* @param _lang - The primary language of the code (currently unused)
|
|
264
|
+
* @param highlighter - Optional highlighter instance to validate languages
|
|
265
|
+
* @returns Array of detected language identifiers
|
|
266
|
+
*
|
|
267
|
+
* @example
|
|
268
|
+
* ```ts
|
|
269
|
+
* // Detects 'javascript' from Vue SFC
|
|
270
|
+
* guessEmbeddedLanguages('<script lang="javascript">')
|
|
271
|
+
*
|
|
272
|
+
* // Detects 'python' from markdown code block
|
|
273
|
+
* guessEmbeddedLanguages('```python\nprint("hi")\n```')
|
|
274
|
+
* ```
|
|
248
275
|
*/
|
|
249
276
|
declare function guessEmbeddedLanguages(code: string, _lang: string | undefined, highlighter?: HighlighterGeneric<any, any>): string[];
|
|
250
277
|
|
package/dist/index.mjs
CHANGED
|
@@ -57,6 +57,9 @@ function addClassToHast(node, className) {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
function splitLines(code, preserveEnding = false) {
|
|
60
|
+
if (code.length === 0) {
|
|
61
|
+
return [["", 0]];
|
|
62
|
+
}
|
|
60
63
|
const parts = code.split(/(\r?\n)/g);
|
|
61
64
|
let index = 0;
|
|
62
65
|
const lines = [];
|
|
@@ -102,14 +105,26 @@ function createPositionConverter(code) {
|
|
|
102
105
|
}
|
|
103
106
|
function guessEmbeddedLanguages(code, _lang, highlighter) {
|
|
104
107
|
const langs = /* @__PURE__ */ new Set();
|
|
105
|
-
for (const match of code.matchAll(
|
|
106
|
-
|
|
108
|
+
for (const match of code.matchAll(/:?lang=["']([^"']+)["']/g)) {
|
|
109
|
+
const lang = match[1].toLowerCase().trim();
|
|
110
|
+
if (lang)
|
|
111
|
+
langs.add(lang);
|
|
107
112
|
}
|
|
108
113
|
for (const match of code.matchAll(/(?:```|~~~)([\w-]+)/g)) {
|
|
109
|
-
|
|
114
|
+
const lang = match[1].toLowerCase().trim();
|
|
115
|
+
if (lang)
|
|
116
|
+
langs.add(lang);
|
|
110
117
|
}
|
|
111
118
|
for (const match of code.matchAll(/\\begin\{([\w-]+)\}/g)) {
|
|
112
|
-
|
|
119
|
+
const lang = match[1].toLowerCase().trim();
|
|
120
|
+
if (lang)
|
|
121
|
+
langs.add(lang);
|
|
122
|
+
}
|
|
123
|
+
for (const match of code.matchAll(/<script\s+(?:type|lang)=["']([^"']+)["']/gi)) {
|
|
124
|
+
const fullType = match[1].toLowerCase().trim();
|
|
125
|
+
const lang = fullType.includes("/") ? fullType.split("/").pop() : fullType;
|
|
126
|
+
if (lang)
|
|
127
|
+
langs.add(lang);
|
|
113
128
|
}
|
|
114
129
|
if (!highlighter)
|
|
115
130
|
return Array.from(langs);
|
|
@@ -844,15 +859,26 @@ function tokenizeAnsiWithTheme(theme, fileContents, options) {
|
|
|
844
859
|
);
|
|
845
860
|
}
|
|
846
861
|
function dimColor(color) {
|
|
847
|
-
const hexMatch = color.match(/#([0-9a-f]{3})
|
|
862
|
+
const hexMatch = color.match(/#([0-9a-f]{3,8})/i);
|
|
848
863
|
if (hexMatch) {
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
864
|
+
const hex = hexMatch[1];
|
|
865
|
+
if (hex.length === 8) {
|
|
866
|
+
const alpha = Math.round(Number.parseInt(hex.slice(6, 8), 16) / 2).toString(16).padStart(2, "0");
|
|
867
|
+
return `#${hex.slice(0, 6)}${alpha}`;
|
|
868
|
+
} else if (hex.length === 6) {
|
|
869
|
+
return `#${hex}80`;
|
|
870
|
+
} else if (hex.length === 4) {
|
|
871
|
+
const r = hex[0];
|
|
872
|
+
const g = hex[1];
|
|
873
|
+
const b = hex[2];
|
|
874
|
+
const a = hex[3];
|
|
875
|
+
const alpha = Math.round(Number.parseInt(`${a}${a}`, 16) / 2).toString(16).padStart(2, "0");
|
|
876
|
+
return `#${r}${r}${g}${g}${b}${b}${alpha}`;
|
|
877
|
+
} else if (hex.length === 3) {
|
|
878
|
+
const r = hex[0];
|
|
879
|
+
const g = hex[1];
|
|
880
|
+
const b = hex[2];
|
|
881
|
+
return `#${r}${r}${g}${g}${b}${b}80`;
|
|
856
882
|
}
|
|
857
883
|
}
|
|
858
884
|
const cssVarMatch = color.match(/var\((--[\w-]+-ansi-[\w-]+)\)/);
|
|
@@ -863,15 +889,15 @@ function dimColor(color) {
|
|
|
863
889
|
|
|
864
890
|
function codeToTokensBase(internal, code, options = {}) {
|
|
865
891
|
const {
|
|
866
|
-
lang = "text",
|
|
867
892
|
theme: themeName = internal.getLoadedThemes()[0]
|
|
868
893
|
} = options;
|
|
894
|
+
const lang = internal.resolveLangAlias(options.lang || "text");
|
|
869
895
|
if (isPlainLang(lang) || isNoneTheme(themeName))
|
|
870
896
|
return splitLines(code).map((line) => [{ content: line[0], offset: line[1] }]);
|
|
871
897
|
const { theme, colorMap } = internal.setTheme(themeName);
|
|
872
898
|
if (lang === "ansi")
|
|
873
899
|
return tokenizeAnsiWithTheme(theme, code, options);
|
|
874
|
-
const _grammar = internal.getLanguage(lang);
|
|
900
|
+
const _grammar = internal.getLanguage(options.lang || "text");
|
|
875
901
|
if (options.grammarState) {
|
|
876
902
|
if (options.grammarState.lang !== _grammar.name) {
|
|
877
903
|
throw new ShikiError$1(`Grammar state language "${options.grammarState.lang}" does not match highlight language "${_grammar.name}"`);
|
|
@@ -1448,12 +1474,12 @@ function mergeWhitespaceTokens(tokens) {
|
|
|
1448
1474
|
return tokens.map((line) => {
|
|
1449
1475
|
const newLine = [];
|
|
1450
1476
|
let carryOnContent = "";
|
|
1451
|
-
let firstOffset
|
|
1477
|
+
let firstOffset;
|
|
1452
1478
|
line.forEach((token, idx) => {
|
|
1453
1479
|
const isDecorated = token.fontStyle && (token.fontStyle & FontStyle.Underline || token.fontStyle & FontStyle.Strikethrough);
|
|
1454
1480
|
const couldMerge = !isDecorated;
|
|
1455
1481
|
if (couldMerge && token.content.match(/^\s+$/) && line[idx + 1]) {
|
|
1456
|
-
if (
|
|
1482
|
+
if (firstOffset === void 0)
|
|
1457
1483
|
firstOffset = token.offset;
|
|
1458
1484
|
carryOnContent += token.content;
|
|
1459
1485
|
} else {
|
|
@@ -1473,7 +1499,7 @@ function mergeWhitespaceTokens(tokens) {
|
|
|
1473
1499
|
token
|
|
1474
1500
|
);
|
|
1475
1501
|
}
|
|
1476
|
-
firstOffset = 0;
|
|
1502
|
+
firstOffset = void 0;
|
|
1477
1503
|
carryOnContent = "";
|
|
1478
1504
|
} else {
|
|
1479
1505
|
newLine.push(token);
|
|
@@ -1685,6 +1711,21 @@ class ShikiError extends Error {
|
|
|
1685
1711
|
}
|
|
1686
1712
|
}
|
|
1687
1713
|
|
|
1714
|
+
function resolveLangAlias(name, alias) {
|
|
1715
|
+
if (!alias)
|
|
1716
|
+
return name;
|
|
1717
|
+
if (alias[name]) {
|
|
1718
|
+
const resolved = /* @__PURE__ */ new Set([name]);
|
|
1719
|
+
while (alias[name]) {
|
|
1720
|
+
name = alias[name];
|
|
1721
|
+
if (resolved.has(name))
|
|
1722
|
+
throw new ShikiError(`Circular alias \`${Array.from(resolved).join(" -> ")} -> ${name}\``);
|
|
1723
|
+
resolved.add(name);
|
|
1724
|
+
}
|
|
1725
|
+
}
|
|
1726
|
+
return name;
|
|
1727
|
+
}
|
|
1728
|
+
|
|
1688
1729
|
class Registry extends Registry$1 {
|
|
1689
1730
|
constructor(_resolver, _themes, _langs, _alias = {}) {
|
|
1690
1731
|
super(_resolver);
|
|
@@ -1735,15 +1776,7 @@ class Registry extends Registry$1 {
|
|
|
1735
1776
|
this._syncRegistry.setTheme(textmateTheme);
|
|
1736
1777
|
}
|
|
1737
1778
|
getGrammar(name) {
|
|
1738
|
-
|
|
1739
|
-
const resolved = /* @__PURE__ */ new Set([name]);
|
|
1740
|
-
while (this._alias[name]) {
|
|
1741
|
-
name = this._alias[name];
|
|
1742
|
-
if (resolved.has(name))
|
|
1743
|
-
throw new ShikiError(`Circular alias \`${Array.from(resolved).join(" -> ")} -> ${name}\``);
|
|
1744
|
-
resolved.add(name);
|
|
1745
|
-
}
|
|
1746
|
-
}
|
|
1779
|
+
name = resolveLangAlias(name, this._alias);
|
|
1747
1780
|
return this._resolvedGrammars.get(name);
|
|
1748
1781
|
}
|
|
1749
1782
|
loadLanguage(lang) {
|
|
@@ -1879,6 +1912,9 @@ function createShikiInternalSync(options) {
|
|
|
1879
1912
|
const resolver = new Resolver(options.engine, langs);
|
|
1880
1913
|
const _registry = new Registry(resolver, themes, langs, options.langAlias);
|
|
1881
1914
|
let _lastTheme;
|
|
1915
|
+
function resolveLangAlias$1(name) {
|
|
1916
|
+
return resolveLangAlias(name, options.langAlias);
|
|
1917
|
+
}
|
|
1882
1918
|
function getLanguage(name) {
|
|
1883
1919
|
ensureNotDisposed();
|
|
1884
1920
|
const _lang = _registry.getGrammar(typeof name === "string" ? name : name.name);
|
|
@@ -1950,6 +1986,7 @@ function createShikiInternalSync(options) {
|
|
|
1950
1986
|
getLanguage,
|
|
1951
1987
|
getLoadedThemes,
|
|
1952
1988
|
getLoadedLanguages,
|
|
1989
|
+
resolveLangAlias: resolveLangAlias$1,
|
|
1953
1990
|
loadLanguage,
|
|
1954
1991
|
loadLanguageSync,
|
|
1955
1992
|
loadTheme,
|
|
@@ -2040,9 +2077,9 @@ function createBundledHighlighter(options) {
|
|
|
2040
2077
|
async function createHighlighter(options2) {
|
|
2041
2078
|
function resolveLang(lang) {
|
|
2042
2079
|
if (typeof lang === "string") {
|
|
2080
|
+
lang = options2.langAlias?.[lang] || lang;
|
|
2043
2081
|
if (isSpecialLang(lang))
|
|
2044
2082
|
return [];
|
|
2045
|
-
lang = options2.langAlias?.[lang] || lang;
|
|
2046
2083
|
const bundle = bundledLanguages[lang];
|
|
2047
2084
|
if (!bundle)
|
|
2048
2085
|
throw new ShikiError$1(`Language \`${lang}\` is not included in this bundle. You may want to load it from external source.`);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shikijs/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.18.0",
|
|
5
5
|
"description": "Core of Shiki",
|
|
6
6
|
"author": "Pine Wu <octref@gmail.com>; Anthony Fu <anthonyfu117@hotmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"@shikijs/vscode-textmate": "^10.0.2",
|
|
40
40
|
"@types/hast": "^3.0.4",
|
|
41
41
|
"hast-util-to-html": "^9.0.5",
|
|
42
|
-
"@shikijs/types": "3.
|
|
42
|
+
"@shikijs/types": "3.18.0"
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|
|
45
45
|
"build": "unbuild",
|