@dominikcz/greg 0.9.38 → 0.9.39

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/README.md CHANGED
@@ -82,6 +82,9 @@ export default {
82
82
  srcDir: 'docs',
83
83
  docsBase: '',
84
84
  mainTitle: 'My Docs',
85
+ shiki: {
86
+ extraLangs: ['python', 'sql', 'csharp', 'pascal'],
87
+ },
85
88
  sidebar: [
86
89
  { text: 'Guide', auto: '/guide' },
87
90
  { text: 'GitHub', link: 'https://github.com/dominikcz/greg' }, // default: _self
@@ -21,6 +21,9 @@ export default {
21
21
  minMatchCharLength: 2,
22
22
  },
23
23
  },
24
+ shiki: {
25
+ extraLangs: ['python', 'sql', 'csharp', 'pascal'],
26
+ },
24
27
  // versioning: {
25
28
  // strategy: 'branches',
26
29
  // default: 'latest',
@@ -20,6 +20,9 @@ export default {
20
20
  minMatchCharLength: 2,
21
21
  },
22
22
  },
23
+ shiki: {
24
+ extraLangs: ['python', 'sql', 'csharp', 'pascal'],
25
+ },
23
26
  // versioning: {
24
27
  // strategy: 'branches',
25
28
  // default: 'latest',
@@ -150,6 +150,24 @@ export default {
150
150
  }
151
151
  ```
152
152
 
153
+ ### `shiki.extraLangs`
154
+
155
+ - **Type:** `string[]`
156
+ - **Default:** `[]`
157
+
158
+ Adds extra syntax-highlighting languages for runtime Shiki.
159
+ Unknown ids are ignored safely (code block falls back to plain text highlighting).
160
+
161
+ ```js
162
+ export default {
163
+ shiki: {
164
+ extraLangs: ['python', 'sql', 'csharp', 'pascal'],
165
+ },
166
+ }
167
+ ```
168
+
169
+ Useful aliases include: `py -> python`, `cs` / `c# -> csharp`, `delphi -> pascal`.
170
+
153
171
  ### `outline`
154
172
 
155
173
  - **Type:** `false | number | [number, number] | 'deep' | { level?: …, label?: string }`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dominikcz/greg",
3
- "version": "0.9.38",
3
+ "version": "0.9.39",
4
4
  "type": "module",
5
5
  "types": "./types/index.d.ts",
6
6
  "bin": {
@@ -168,6 +168,11 @@
168
168
  searchProvider?: (query: string, limit?: number) => Promise<any[]>;
169
169
  /** Render markdown images as thumbnails with click-to-preview overlay. */
170
170
  markdownImagePreview?: boolean;
171
+ /** Runtime syntax highlighting options. */
172
+ shiki?: {
173
+ /** Additional language ids to load for code highlighting (for example ['rust', 'go']). */
174
+ extraLangs?: string[];
175
+ };
171
176
  };
172
177
 
173
178
  type VersionManifestEntry = {
@@ -215,6 +220,7 @@
215
220
  mermaidTheme = (gregConfig as any).mermaidTheme,
216
221
  mermaidThemes,
217
222
  markdownImagePreview = (gregConfig as any).markdownImagePreview ?? true,
223
+ shiki = (gregConfig as any).shiki ?? {},
218
224
  breadcrumb = (gregConfig as any).breadcrumb ?? false,
219
225
  backToTop = (gregConfig as any).backToTop ?? false,
220
226
  lastModified: globalLastModified = (gregConfig as any).lastModified ?? false,
@@ -1762,6 +1768,7 @@
1762
1768
  {mermaidTheme}
1763
1769
  {mermaidThemes}
1764
1770
  enableImagePreview={markdownImagePreview}
1771
+ shikiExtraLangs={Array.isArray(shiki?.extraLangs) ? shiki.extraLangs : []}
1765
1772
  colorTheme={theme}
1766
1773
  />
1767
1774
  {#if lastModified && activeFrontmatter?._mtime}
@@ -34,13 +34,17 @@
34
34
  DEFAULT_MERMAID_THEME,
35
35
  getColorSchemeTheme,
36
36
  } from "./mermaidThemes.js";
37
- import { createHighlighter, type HighlighterGeneric } from "shiki";
37
+ import {
38
+ createBundledHighlighter,
39
+ type HighlighterGeneric,
40
+ } from "shiki/core";
41
+ import { createJavaScriptRegexEngine } from "shiki/engine/javascript";
38
42
 
39
43
  const shikiThemes = {
40
44
  light: "github-light",
41
45
  dark: "github-dark",
42
46
  } as const;
43
- const shikiDefaultLang = "txt";
47
+ const shikiDefaultLang = "text";
44
48
  const shikiLangAliases: Record<string, string> = {
45
49
  js: "javascript",
46
50
  ts: "typescript",
@@ -49,8 +53,31 @@
49
53
  zsh: "bash",
50
54
  yml: "yaml",
51
55
  md: "markdown",
56
+ txt: "text",
57
+ py: "python",
58
+ cs: "csharp",
59
+ "c#": "csharp",
60
+ delphi: "pascal",
61
+ };
62
+ const shikiBundledLangs = {
63
+ javascript: () => import("@shikijs/langs/javascript"),
64
+ typescript: () => import("@shikijs/langs/typescript"),
65
+ bash: () => import("@shikijs/langs/bash"),
66
+ json: () => import("@shikijs/langs/json"),
67
+ html: () => import("@shikijs/langs/html"),
68
+ css: () => import("@shikijs/langs/css"),
69
+ yaml: () => import("@shikijs/langs/yaml"),
70
+ markdown: () => import("@shikijs/langs/markdown"),
71
+ svelte: () => import("@shikijs/langs/svelte"),
72
+ csharp: () => import("@shikijs/langs/csharp"),
73
+ sql: () => import("@shikijs/langs/sql"),
74
+ ini: () => import("@shikijs/langs/ini"),
75
+ python: () => import("@shikijs/langs/python"),
76
+ pascal: () => import("@shikijs/langs/pascal"),
52
77
  };
53
- const shikiLangs = [
78
+ type ShikiBundledLang = keyof typeof shikiBundledLangs;
79
+
80
+ const shikiBaseLangs: ShikiBundledLang[] = [
54
81
  "javascript",
55
82
  "typescript",
56
83
  "bash",
@@ -60,20 +87,64 @@
60
87
  "yaml",
61
88
  "markdown",
62
89
  "svelte",
63
- "txt",
90
+ "csharp",
91
+ "sql",
92
+ "ini",
93
+ "python",
94
+ "pascal",
64
95
  ];
65
96
 
66
- let shikiHighlighterPromise: Promise<HighlighterGeneric<any, any>> | null =
67
- null;
97
+ const shikiBundledThemes = {
98
+ "github-light": () => import("@shikijs/themes/github-light"),
99
+ "github-dark": () => import("@shikijs/themes/github-dark"),
100
+ };
68
101
 
69
- function getShikiHighlighter() {
70
- if (!shikiHighlighterPromise) {
71
- shikiHighlighterPromise = createHighlighter({
72
- themes: [shikiThemes.light, shikiThemes.dark],
73
- langs: shikiLangs,
74
- });
102
+ const createShikiHighlighter = createBundledHighlighter({
103
+ langs: shikiBundledLangs,
104
+ themes: shikiBundledThemes,
105
+ engine: createJavaScriptRegexEngine,
106
+ });
107
+
108
+ const shikiHighlighterPromises = new Map<
109
+ string,
110
+ Promise<HighlighterGeneric<any, any>>
111
+ >();
112
+
113
+ function asBundledShikiLang(value: string): ShikiBundledLang | null {
114
+ if (Object.prototype.hasOwnProperty.call(shikiBundledLangs, value)) {
115
+ return value as ShikiBundledLang;
75
116
  }
76
- return shikiHighlighterPromise;
117
+ return null;
118
+ }
119
+
120
+ function normalizeShikiLang(value: string): string {
121
+ const raw = String(value || "")
122
+ .trim()
123
+ .toLowerCase();
124
+ return shikiLangAliases[raw] ?? raw;
125
+ }
126
+
127
+ function resolveConfiguredShikiLangs(extraLangs: string[] = []) {
128
+ const resolved = new Set<ShikiBundledLang>(shikiBaseLangs);
129
+ for (const candidate of extraLangs) {
130
+ const normalized = normalizeShikiLang(candidate);
131
+ const bundled = asBundledShikiLang(normalized);
132
+ if (bundled) resolved.add(bundled);
133
+ }
134
+ return Array.from(resolved);
135
+ }
136
+
137
+ function getShikiHighlighter(langs: ShikiBundledLang[]) {
138
+ const cacheKey = langs.slice().sort().join("|");
139
+ const cached = shikiHighlighterPromises.get(cacheKey);
140
+ if (cached) return cached;
141
+
142
+ const promise = createShikiHighlighter({
143
+ themes: [shikiThemes.light, shikiThemes.dark],
144
+ langs,
145
+ });
146
+ shikiHighlighterPromises.set(cacheKey, promise);
147
+ return promise;
77
148
  }
78
149
 
79
150
  function parseClassNameList(value: unknown): string[] {
@@ -105,10 +176,8 @@
105
176
  highlighter: HighlighterGeneric<any, any>,
106
177
  language: string,
107
178
  ) {
108
- const rawLang = String(language || "")
109
- .trim()
110
- .toLowerCase();
111
- const mapped = shikiLangAliases[rawLang] ?? rawLang;
179
+ const rawLang = normalizeShikiLang(language);
180
+ const mapped = rawLang;
112
181
  const loaded = highlighter.getLoadedLanguages();
113
182
  if (loaded.includes(mapped)) return mapped;
114
183
  if (loaded.includes(rawLang)) return rawLang;
@@ -205,6 +274,8 @@
205
274
  colorTheme?: "light" | "dark";
206
275
  /** Enable markdown image thumbnails + click-to-preview overlay. */
207
276
  enableImagePreview?: boolean;
277
+ /** Additional Shiki language ids loaded for runtime highlighting. */
278
+ shikiExtraLangs?: string[];
208
279
  };
209
280
  let {
210
281
  markdown,
@@ -214,8 +285,13 @@
214
285
  mermaidThemes: extraThemes = {},
215
286
  colorTheme,
216
287
  enableImagePreview = true,
288
+ shikiExtraLangs = [],
217
289
  }: Props = $props();
218
290
 
291
+ const configuredShikiLangs = $derived.by(() =>
292
+ resolveConfiguredShikiLangs(shikiExtraLangs),
293
+ );
294
+
219
295
  /** Combined theme map: built-ins overridden/extended by user-supplied themes. */
220
296
  const allMermaidThemes = $derived({ ...MERMAID_THEMES, ...extraThemes });
221
297
 
@@ -308,7 +384,7 @@
308
384
 
309
385
  function rehypeShiki() {
310
386
  return async (tree: any) => {
311
- const highlighter = await getShikiHighlighter();
387
+ const highlighter = await getShikiHighlighter(configuredShikiLangs);
312
388
 
313
389
  visit(tree, "element", (node: any, _index: any, parent: any) => {
314
390
  if (node.tagName !== "code") return;
package/types/index.d.ts CHANGED
@@ -344,6 +344,11 @@ export type GregConfig = {
344
344
  mainTitle?: string;
345
345
  /** Render markdown images as thumbnails with click-to-preview overlay. Default: true. */
346
346
  markdownImagePreview?: boolean;
347
+ /** Runtime syntax highlighting options. */
348
+ shiki?: {
349
+ /** Additional language ids loaded by Shiki runtime (e.g. ['rust', 'go']). */
350
+ extraLangs?: string[];
351
+ };
347
352
  /**
348
353
  * VitePress-compatible outline setting.
349
354
  * false – disable outline