@gmickel/gno 0.27.0 → 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
|
@@ -8,14 +8,15 @@ import {
|
|
|
8
8
|
useRef,
|
|
9
9
|
useState,
|
|
10
10
|
} from "react";
|
|
11
|
-
import {
|
|
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:
|
|
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:
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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
|
|
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
|
+
}
|
package/src/serve/routes/api.ts
CHANGED
|
@@ -1423,7 +1423,8 @@ export async function handleCreateDoc(
|
|
|
1423
1423
|
await atomicWrite(fullPath, contentToWrite);
|
|
1424
1424
|
|
|
1425
1425
|
// Build gno:// URI for the created document
|
|
1426
|
-
const
|
|
1426
|
+
const posixRelPath = normalizedRelPath.split(nodePath.sep).join("/");
|
|
1427
|
+
const gnoUri = `gno://${collection.name}/${posixRelPath}`;
|
|
1427
1428
|
|
|
1428
1429
|
// Run sync via job system (non-blocking)
|
|
1429
1430
|
// Note: embedding handled separately by embed-scheduler (not inline)
|