@gmickel/gno 0.27.1 → 0.27.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gmickel/gno",
3
- "version": "0.27.1",
3
+ "version": "0.27.3",
4
4
  "description": "Local semantic search for your documents. Index Markdown, PDF, and Office files with hybrid BM25 + vector search.",
5
5
  "keywords": [
6
6
  "embeddings",
@@ -8,14 +8,15 @@ import {
8
8
  useRef,
9
9
  useState,
10
10
  } from "react";
11
- import { type BundledLanguage, codeToHtml, type ShikiTransformer } from "shiki";
11
+ import { codeToHtml, type ShikiTransformer } from "shiki";
12
12
 
13
+ import { resolveCodeLanguage } from "../../lib/code-language";
13
14
  import { cn } from "../../lib/utils";
14
15
  import { Button } from "../ui/button";
15
16
 
16
17
  type CodeBlockProps = HTMLAttributes<HTMLDivElement> & {
17
18
  code: string;
18
- language: BundledLanguage;
19
+ language: string;
19
20
  showLineNumbers?: boolean;
20
21
  highlightedLines?: number[];
21
22
  scrollToLine?: number;
@@ -78,27 +79,43 @@ function createLineTransformer(
78
79
 
79
80
  export async function highlightCode(
80
81
  code: string,
81
- language: BundledLanguage,
82
+ language: string,
82
83
  showLineNumbers = false,
83
84
  highlightedLines: number[] = []
84
85
  ) {
86
+ const resolvedLanguage = resolveCodeLanguage(language);
85
87
  const transformers: ShikiTransformer[] =
86
88
  showLineNumbers || highlightedLines.length > 0
87
89
  ? [createLineTransformer(showLineNumbers, highlightedLines)]
88
90
  : [];
89
91
 
90
- return await Promise.all([
91
- codeToHtml(code, {
92
- lang: language,
93
- theme: "one-light",
94
- transformers,
95
- }),
96
- codeToHtml(code, {
97
- lang: language,
98
- theme: "one-dark-pro",
99
- transformers,
100
- }),
101
- ]);
92
+ try {
93
+ return await Promise.all([
94
+ codeToHtml(code, {
95
+ lang: resolvedLanguage,
96
+ theme: "one-light",
97
+ transformers,
98
+ }),
99
+ codeToHtml(code, {
100
+ lang: resolvedLanguage,
101
+ theme: "one-dark-pro",
102
+ transformers,
103
+ }),
104
+ ]);
105
+ } catch {
106
+ return await Promise.all([
107
+ codeToHtml(code, {
108
+ lang: "text",
109
+ theme: "one-light",
110
+ transformers,
111
+ }),
112
+ codeToHtml(code, {
113
+ lang: "text",
114
+ theme: "one-dark-pro",
115
+ transformers,
116
+ }),
117
+ ]);
118
+ }
102
119
  }
103
120
 
104
121
  export const CodeBlock = ({
@@ -6,7 +6,6 @@
6
6
  */
7
7
 
8
8
  import type { ComponentProps, FC, ReactNode } from "react";
9
- import type { BundledLanguage } from "shiki";
10
9
 
11
10
  import { ExternalLinkIcon } from "lucide-react";
12
11
  import { memo } from "react";
@@ -14,6 +13,10 @@ import ReactMarkdown from "react-markdown";
14
13
  import rehypeSanitize from "rehype-sanitize";
15
14
  import remarkGfm from "remark-gfm";
16
15
 
16
+ import {
17
+ extractMarkdownCodeLanguage,
18
+ resolveCodeLanguage,
19
+ } from "../../lib/code-language";
17
20
  import { cn } from "../../lib/utils";
18
21
  import { CodeBlock, CodeBlockCopyButton } from "../ai-elements/code-block";
19
22
 
@@ -106,8 +109,7 @@ const Pre: FC<ComponentProps<"pre">> = ({ children, ...props }) => {
106
109
  const code = String(codeElement.props.children ?? "").trim();
107
110
 
108
111
  // Extract language from className (e.g., "language-typescript")
109
- const match = /language-(\w+)/.exec(className);
110
- const language = (match?.[1] ?? "plaintext") as BundledLanguage;
112
+ const language = resolveCodeLanguage(extractMarkdownCodeLanguage(className));
111
113
 
112
114
  return (
113
115
  <div className="group/code my-4">
@@ -0,0 +1,49 @@
1
+ import { bundledLanguages, type BundledLanguage } from "shiki";
2
+
3
+ export type CodeLanguage = BundledLanguage | "text";
4
+
5
+ const LANGUAGE_CLASS_PATTERN = /language-([A-Za-z0-9_+-]+)/;
6
+
7
+ const LANGUAGE_ALIASES = {
8
+ cjs: "javascript",
9
+ js: "javascript",
10
+ md: "markdown",
11
+ mts: "typescript",
12
+ plain: "text",
13
+ plaintext: "text",
14
+ py: "python",
15
+ shell: "bash",
16
+ tasks: "markdown",
17
+ text: "text",
18
+ ts: "typescript",
19
+ txt: "text",
20
+ yml: "yaml",
21
+ zsh: "bash",
22
+ } as const satisfies Record<string, CodeLanguage>;
23
+
24
+ export function extractMarkdownCodeLanguage(
25
+ className: string | undefined
26
+ ): string {
27
+ return className?.match(LANGUAGE_CLASS_PATTERN)?.[1]?.toLowerCase() ?? "text";
28
+ }
29
+
30
+ export function resolveCodeLanguage(
31
+ language: string | null | undefined
32
+ ): CodeLanguage {
33
+ const normalized = language?.trim().toLowerCase();
34
+ if (!normalized) {
35
+ return "text";
36
+ }
37
+
38
+ const aliased =
39
+ LANGUAGE_ALIASES[normalized as keyof typeof LANGUAGE_ALIASES] ?? normalized;
40
+ if (aliased === "text") {
41
+ return "text";
42
+ }
43
+
44
+ if (aliased in bundledLanguages) {
45
+ return aliased as BundledLanguage;
46
+ }
47
+
48
+ return "text";
49
+ }