From 02a7441ed722bf93f32f236cc90521549a5e0a9f Mon Sep 17 00:00:00 2001 From: Emma Hamilton Date: Wed, 20 Nov 2024 12:28:24 +1000 Subject: [PATCH] Use first word only from info string to match language in code block highlighting (#1354) --- .changeset/mighty-apples-tan.md | 5 +++++ .../markdoc/editor/code-block-highlighting.ts | 18 ++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 .changeset/mighty-apples-tan.md diff --git a/.changeset/mighty-apples-tan.md b/.changeset/mighty-apples-tan.md new file mode 100644 index 000000000..679f1e1d6 --- /dev/null +++ b/.changeset/mighty-apples-tan.md @@ -0,0 +1,5 @@ +--- +'@keystatic/core': patch +--- + +Improve syntax highlighting in the `fields.mdx`/`fields.markdoc` editor to only use the first word in the info string to match the language. This is primarily for `fields.mdx` to allow additional information in the info string beyond the editor. In `fields.markdoc` additional content after the first word will be stripped since Markdoc expresses additional information using Markdoc annotations which Keystatic already exposes UI for if `options.codeBlock.schema` is configured. diff --git a/packages/keystatic/src/form/fields/markdoc/editor/code-block-highlighting.ts b/packages/keystatic/src/form/fields/markdoc/editor/code-block-highlighting.ts index 54076c86d..43c72b0e4 100644 --- a/packages/keystatic/src/form/fields/markdoc/editor/code-block-highlighting.ts +++ b/packages/keystatic/src/form/fields/markdoc/editor/code-block-highlighting.ts @@ -17,15 +17,21 @@ function getDecorationsForIndividualNode(node: Node): InlineDecorationSpec[] { if (!node.type.spec.code || !node.childCount) return emptyDecorations; const text = node.content.child(0).text; if (!text) return emptyDecorations; - const lang = node.attrs.language; - if ( - typeof lang !== 'string' || - !Object.prototype.hasOwnProperty.call(Prism.languages, node.attrs.language) - ) { + let lang = node.attrs.language; + if (typeof lang !== 'string') return emptyDecorations; + lang = lang.trim(); + const spaceIndex = lang.indexOf(' '); + if (spaceIndex !== -1) { + lang = lang.slice(0, spaceIndex); + } + lang = lang.toLowerCase(); + if (!Object.prototype.hasOwnProperty.call(Prism.languages, lang)) { return emptyDecorations; } + const prismLang = Prism.languages[lang]; + if (typeof prismLang !== 'object') return emptyDecorations; const decorations: InlineDecorationSpec[] = []; - const tokens = Prism.tokenize(text, Prism.languages[node.attrs.language]); + const tokens = Prism.tokenize(text, prismLang); function consumeTokens(start: number, tokens: (string | Prism.Token)[]) { for (const token of tokens) { const length = getPrismTokenLength(token);