mirror of
https://github.com/AstrBotDevs/AstrBot.git
synced 2026-10-16 15:06:04 +08:00
Fix/expand chatui code highlighting 扩展 chatui 代码高亮 (#9892)
* fix: expand common language syntax highlighting * fix: wire limited Shiki languages into ChatUI * fix: register bundled aliases for chat code blocks * fix: include Go grammar in T2I Shiki runtime
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -23,15 +23,28 @@ const shikiRequire = createRequire(require.resolve("shiki/package.json"));
|
||||
|
||||
const languageSpecs = [
|
||||
["bash", "bash"],
|
||||
["c", "c"],
|
||||
["css", "css"],
|
||||
["cpp", "cpp"],
|
||||
["csharp", "csharp"],
|
||||
["dart", "dart"],
|
||||
["go", "go"],
|
||||
["html", "html"],
|
||||
["javascript", "javascript"],
|
||||
["json", "json"],
|
||||
["jsx", "jsx"],
|
||||
["kotlin", "kotlin"],
|
||||
["lua", "lua"],
|
||||
["markdown", "markdown"],
|
||||
["php", "php"],
|
||||
["powershell", "powershell"],
|
||||
["python", "python"],
|
||||
["r", "r"],
|
||||
["ruby", "ruby"],
|
||||
["rust", "rust"],
|
||||
["scala", "scala"],
|
||||
["sql", "sql"],
|
||||
["swift", "swift"],
|
||||
["tsx", "tsx"],
|
||||
["typescript", "typescript"],
|
||||
["xml", "xml"],
|
||||
@@ -49,13 +62,24 @@ const builtInLanguageSpecs = ["text"];
|
||||
|
||||
const languageAliases = {
|
||||
bat: "powershell",
|
||||
"c++": "cpp",
|
||||
cc: "cpp",
|
||||
cjs: "javascript",
|
||||
cxx: "cpp",
|
||||
console: "bash",
|
||||
cts: "typescript",
|
||||
cs: "csharp",
|
||||
dockerfile: "bash",
|
||||
golang: "go",
|
||||
h: "c",
|
||||
"h++": "cpp",
|
||||
hh: "cpp",
|
||||
hpp: "cpp",
|
||||
env: "bash",
|
||||
htm: "html",
|
||||
js: "javascript",
|
||||
kt: "kotlin",
|
||||
kts: "kotlin",
|
||||
md: "markdown",
|
||||
mjs: "javascript",
|
||||
mts: "typescript",
|
||||
@@ -64,6 +88,7 @@ const languageAliases = {
|
||||
ps1: "powershell",
|
||||
pwsh: "powershell",
|
||||
py: "python",
|
||||
rs: "rust",
|
||||
shell: "bash",
|
||||
shellscript: "bash",
|
||||
sh: "bash",
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
import { computed, inject, type Ref, useAttrs } from "vue";
|
||||
import { MarkdownCodeBlockNode } from "markstream-vue";
|
||||
import { copyToClipboard } from "@/utils/clipboard";
|
||||
import { LIMITED_SHIKI_LANGUAGES, LIMITED_SHIKI_LANGUAGE_ALIASES } from "@/utils/shikiLimitedBundle";
|
||||
|
||||
defineOptions({
|
||||
inheritAttrs: false,
|
||||
@@ -57,6 +58,10 @@ const attrs = useAttrs();
|
||||
const forwardedBindings = computed(() => ({
|
||||
...attrs,
|
||||
...props,
|
||||
langs: Array.from(new Set([
|
||||
...LIMITED_SHIKI_LANGUAGES.map((language) => language.name),
|
||||
...Object.values(LIMITED_SHIKI_LANGUAGE_ALIASES),
|
||||
])),
|
||||
isDark: effectiveIsDark.value,
|
||||
}));
|
||||
const themeRenderKey = computed(() => (effectiveIsDark.value ? "dark" : "light"));
|
||||
|
||||
@@ -1,19 +1,32 @@
|
||||
import { createHighlighterCore } from "shiki/core";
|
||||
import { createJavaScriptRegexEngine } from "shiki/engine/javascript";
|
||||
import bash from "shiki/langs/bash.mjs";
|
||||
import c from "shiki/langs/c.mjs";
|
||||
import css from "shiki/langs/css.mjs";
|
||||
import cpp from "shiki/langs/cpp.mjs";
|
||||
import csharp from "shiki/langs/csharp.mjs";
|
||||
import dart from "shiki/langs/dart.mjs";
|
||||
import diff from "shiki/langs/diff.mjs";
|
||||
import dockerfile from "shiki/langs/dockerfile.mjs";
|
||||
import go from "shiki/langs/go.mjs";
|
||||
import html from "shiki/langs/html.mjs";
|
||||
import ini from "shiki/langs/ini.mjs";
|
||||
import java from "shiki/langs/java.mjs";
|
||||
import javascript from "shiki/langs/javascript.mjs";
|
||||
import json from "shiki/langs/json.mjs";
|
||||
import jsx from "shiki/langs/jsx.mjs";
|
||||
import kotlin from "shiki/langs/kotlin.mjs";
|
||||
import lua from "shiki/langs/lua.mjs";
|
||||
import markdown from "shiki/langs/markdown.mjs";
|
||||
import php from "shiki/langs/php.mjs";
|
||||
import powershell from "shiki/langs/powershell.mjs";
|
||||
import python from "shiki/langs/python.mjs";
|
||||
import r from "shiki/langs/r.mjs";
|
||||
import ruby from "shiki/langs/ruby.mjs";
|
||||
import rust from "shiki/langs/rust.mjs";
|
||||
import scala from "shiki/langs/scala.mjs";
|
||||
import sql from "shiki/langs/sql.mjs";
|
||||
import swift from "shiki/langs/swift.mjs";
|
||||
import tsx from "shiki/langs/tsx.mjs";
|
||||
import typescript from "shiki/langs/typescript.mjs";
|
||||
import vue from "shiki/langs/vue.mjs";
|
||||
@@ -26,19 +39,32 @@ import vitesseLight from "shiki/themes/vitesse-light.mjs";
|
||||
|
||||
export const LIMITED_SHIKI_LANGUAGES = [
|
||||
...bash,
|
||||
...c,
|
||||
...css,
|
||||
...cpp,
|
||||
...csharp,
|
||||
...dart,
|
||||
...diff,
|
||||
...dockerfile,
|
||||
...go,
|
||||
...html,
|
||||
...ini,
|
||||
...java,
|
||||
...javascript,
|
||||
...json,
|
||||
...jsx,
|
||||
...kotlin,
|
||||
...lua,
|
||||
...markdown,
|
||||
...php,
|
||||
...powershell,
|
||||
...python,
|
||||
...r,
|
||||
...ruby,
|
||||
...rust,
|
||||
...scala,
|
||||
...sql,
|
||||
...swift,
|
||||
...tsx,
|
||||
...typescript,
|
||||
...vue,
|
||||
@@ -57,12 +83,23 @@ const BUILT_IN_LANGUAGES = ["text", "plaintext", "plain"];
|
||||
|
||||
export const LIMITED_SHIKI_LANGUAGE_ALIASES = {
|
||||
bat: "powershell",
|
||||
"c++": "cpp",
|
||||
cc: "cpp",
|
||||
cjs: "javascript",
|
||||
cxx: "cpp",
|
||||
console: "bash",
|
||||
cts: "typescript",
|
||||
cs: "csharp",
|
||||
docker: "dockerfile",
|
||||
golang: "go",
|
||||
h: "c",
|
||||
"h++": "cpp",
|
||||
hh: "cpp",
|
||||
hpp: "cpp",
|
||||
htm: "html",
|
||||
js: "javascript",
|
||||
kt: "kotlin",
|
||||
kts: "kotlin",
|
||||
md: "markdown",
|
||||
mjs: "javascript",
|
||||
mts: "typescript",
|
||||
@@ -71,6 +108,7 @@ export const LIMITED_SHIKI_LANGUAGE_ALIASES = {
|
||||
ps1: "powershell",
|
||||
pwsh: "powershell",
|
||||
py: "python",
|
||||
rs: "rust",
|
||||
shell: "bash",
|
||||
shellscript: "bash",
|
||||
sh: "bash",
|
||||
@@ -120,6 +158,7 @@ export function normalizeLimitedShikiLanguage(language) {
|
||||
const normalized = String(language || "text")
|
||||
.trim()
|
||||
.split(/\s+/, 1)[0]
|
||||
.split(":", 1)[0]
|
||||
.toLowerCase();
|
||||
|
||||
if (!normalized) return "text";
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
|
||||
import {
|
||||
LIMITED_SHIKI_SUPPORTED_LANGUAGES,
|
||||
createHighlighter,
|
||||
normalizeLimitedShikiLanguage,
|
||||
} from "../src/utils/shikiLimitedBundle.js";
|
||||
|
||||
const languageCases = {
|
||||
c: ["c", "h"],
|
||||
cpp: ["cpp", "c++", "cc", "cxx", "h++", "hh", "hpp"],
|
||||
csharp: ["csharp", "cs"],
|
||||
dart: ["dart"],
|
||||
go: ["go", "golang"],
|
||||
kotlin: ["kotlin", "kt", "kts"],
|
||||
lua: ["lua"],
|
||||
php: ["php"],
|
||||
r: ["r"],
|
||||
ruby: ["ruby"],
|
||||
rust: ["rust", "rs"],
|
||||
scala: ["scala"],
|
||||
swift: ["swift"],
|
||||
};
|
||||
|
||||
test("normalizes aliases for the expanded language set", () => {
|
||||
for (const [language, aliases] of Object.entries(languageCases)) {
|
||||
assert.equal(normalizeLimitedShikiLanguage(language), language);
|
||||
for (const alias of aliases) {
|
||||
assert.equal(normalizeLimitedShikiLanguage(alias), language, alias);
|
||||
}
|
||||
assert.ok(LIMITED_SHIKI_SUPPORTED_LANGUAGES.has(language), language);
|
||||
}
|
||||
|
||||
assert.equal(normalizeLimitedShikiLanguage("unknown-language"), "text");
|
||||
assert.equal(normalizeLimitedShikiLanguage("c extra"), "c");
|
||||
assert.equal(normalizeLimitedShikiLanguage("rust:rust"), "rust");
|
||||
});
|
||||
|
||||
test("highlights every expanded language with Shiki tokens", async () => {
|
||||
const highlighter = await createHighlighter({ themes: ["github-light"] });
|
||||
const samples = {
|
||||
c: "int main() { return 0; }",
|
||||
cpp: "std::vector<int> values;",
|
||||
csharp: "public class Sample {}",
|
||||
dart: "void main() {}",
|
||||
go: "package main\nfunc main() {}",
|
||||
kotlin: "fun main() {}",
|
||||
lua: "local value = 1",
|
||||
php: "<?php echo 'ok';",
|
||||
r: "value <- 1",
|
||||
ruby: "puts 'ok'",
|
||||
rust: "fn main() {}",
|
||||
scala: "object Main extends App {}",
|
||||
swift: "let value = 1",
|
||||
};
|
||||
|
||||
for (const [language, code] of Object.entries(samples)) {
|
||||
assert.equal(highlighter.getLanguage(language)?.name, language, language);
|
||||
const html = highlighter.codeToHtml(code, {
|
||||
lang: language,
|
||||
theme: "github-light",
|
||||
});
|
||||
assert.match(html, /<span[^>]+style=/, language);
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user