From 1462067e724e5abcdbad65fab24f65b0537e13f0 Mon Sep 17 00:00:00 2001 From: Benjamin Toby Date: Fri, 16 Oct 2026 06:46:19 +0100 Subject: [PATCH] Register Prism's common languages in twui CodeBlock - Load refractor's ~36 common languages plus docker, nginx, toml, powershell, jsx and tsx (was 6) - Expand TWUIPrismLanguages to 54 names/aliases for autocomplete; `language` now also accepts any registered refractor name - RemoteCodeBlock re-exports the list instead of keeping a stale copy Co-Authored-By: Claude Opus 5.5 --- .../(functions)/code-block/highlight-code.ts | 31 ++++---- src/components/twui/elements/CodeBlock.tsx | 72 +++++++++++++++++-- .../twui/elements/RemoteCodeBlock.tsx | 2 +- 3 files changed, 84 insertions(+), 21 deletions(-) diff --git a/src/components/twui/(functions)/code-block/highlight-code.ts b/src/components/twui/(functions)/code-block/highlight-code.ts index 6cad41c..c669148 100644 --- a/src/components/twui/(functions)/code-block/highlight-code.ts +++ b/src/components/twui/(functions)/code-block/highlight-code.ts @@ -1,18 +1,19 @@ -import { refractor } from "refractor/core"; -import bash from "refractor/bash"; -import ini from "refractor/ini"; -import javascript from "refractor/javascript"; -import json from "refractor/json"; -import typescript from "refractor/typescript"; -import yaml from "refractor/yaml"; +// `refractor` (not `refractor/core`) preloads Prism's ~36 common languages +import { refractor } from "refractor"; +import docker from "refractor/docker"; +import jsx from "refractor/jsx"; +import nginx from "refractor/nginx"; +import powershell from "refractor/powershell"; +import toml from "refractor/toml"; +import tsx from "refractor/tsx"; import type { Root } from "hast"; -refractor.register(bash); -refractor.register(ini); -refractor.register(javascript); -refractor.register(json); -refractor.register(typescript); -refractor.register(yaml); +refractor.register(docker); +refractor.register(jsx); +refractor.register(nginx); +refractor.register(powershell); +refractor.register(toml); +refractor.register(tsx); type Params = { code: string; @@ -23,7 +24,9 @@ type Params = { * # Highlight a code string with Prism (via refractor) * * Returns a hast tree of `.token` spans, or `null` when the - * language is missing or not registered. + * language is missing or not registered. More languages can be added + * app-side with `refractor.register(lang)` from `refractor/core` + * (same instance). */ export default function highlightCode({ code, language }: Params): Root | null { if (!language || !refractor.registered(language)) { diff --git a/src/components/twui/elements/CodeBlock.tsx b/src/components/twui/elements/CodeBlock.tsx index dfebe2b..d0d1074 100644 --- a/src/components/twui/elements/CodeBlock.tsx +++ b/src/components/twui/elements/CodeBlock.tsx @@ -12,16 +12,74 @@ import Divider from "../layout/Divider"; import highlightCode from "../(functions)/code-block/highlight-code"; import CodeBlockHastNode from "../(partials)/CodeBlockHastNode"; +/** + * Languages (and aliases) registered in `highlight-code.ts`, listed for + * autocomplete. Any other name refractor knows also works; unknown names + * render as plain text. + */ export const TWUIPrismLanguages = [ - "shell", + // Shell & config "bash", + "sh", + "shell", + "powershell", "ini", - "javascript", - "typescript", - "json", + "toml", "yaml", + "yml", + "json", + "docker", + "dockerfile", + "nginx", + "makefile", + "diff", + // Web + "markup", + "html", + "xml", + "svg", + "css", + "scss", + "sass", + "less", + "javascript", + "js", + "jsx", + "typescript", + "ts", + "tsx", + "php", + // General purpose + "c", + "cpp", + "csharp", + "cs", + "go", + "java", + "kotlin", + "lua", + "perl", + "python", + "py", + "r", + "ruby", + "rb", + "rust", + "swift", + "objectivec", + "objc", + "basic", + "vbnet", + "arduino", + // Data & docs + "sql", + "markdown", + "md", + "regex", ] as const; +export type TWUIPrismLanguage = (typeof TWUIPrismLanguages)[number]; + /** `auto` follows the `.dark` class on ``; `light`/`dark` pin the palette */ export const TWUICodeBlockThemes = ["auto", "light", "dark"] as const; @@ -36,7 +94,7 @@ type Props = PropsWithChildren & "data-title"?: string; backgroundColor?: string; singleBlock?: boolean; - language?: (typeof TWUIPrismLanguages)[number]; + language?: TWUIPrismLanguage | (string & {}); /** Colour palette. Defaults to `auto` (follows the page theme) */ theme?: TWUICodeBlockTheme; }; @@ -92,7 +150,9 @@ export default function CodeBlock({ ? "0 0 10px 10px rgba(18, 139, 99, 0.2)" : undefined, ...(backgroundColor - ? ({ "--twui-code-bg": backgroundColor } as React.CSSProperties) + ? ({ + "--twui-code-bg": backgroundColor, + } as React.CSSProperties) : {}), ...wrapperProps?.style, }} diff --git a/src/components/twui/elements/RemoteCodeBlock.tsx b/src/components/twui/elements/RemoteCodeBlock.tsx index bed3298..bcb0065 100644 --- a/src/components/twui/elements/RemoteCodeBlock.tsx +++ b/src/components/twui/elements/RemoteCodeBlock.tsx @@ -5,7 +5,7 @@ import rehypePrismPlus from "rehype-prism-plus"; import { MDXRemote, type MDXRemoteSerializeResult } from "next-mdx-remote"; import { useMDXComponents } from "../mdx/mdx-components"; -export const TWUIPrismLanguages = ["shell", "javascript"] as const; +export { TWUIPrismLanguages } from "./CodeBlock"; type Props = { content: string;