From cb5ac72fb494955197fffcc70c448a1179c5e970 Mon Sep 17 00:00:00 2001 From: WebFreak001 Date: Tue, 19 Aug 2025 20:16:27 +0200 Subject: [PATCH] Allow using filenames in codeblocks - If there is a dot in the language name, we instead treat the first line after ``` as the filename and everything after the last dot as the language - we use a custom "data-label" attribute on the code block to specify the name of the file (so only compatible with cinny from this point onwards) --- src/app/plugins/markdown/block/rules.ts | 8 ++++++-- src/app/plugins/react-custom-html-parser.tsx | 7 ++++--- src/app/utils/sanitize.ts | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/app/plugins/markdown/block/rules.ts b/src/app/plugins/markdown/block/rules.ts index f598ee63..e0a727ee 100644 --- a/src/app/plugins/markdown/block/rules.ts +++ b/src/app/plugins/markdown/block/rules.ts @@ -16,8 +16,12 @@ export const CodeBlockRule: BlockMDRule = { match: (text) => text.match(CODEBLOCK_REG_1), html: (match) => { const [, g1, g2] = match; - const classNameAtt = g1 ? ` class="language-${g1}"` : ''; - return `
${g2}
`; + // use last identifier after dot, e.g. for "example.json" gets us "json" as language code. + const langCode = g1 ? g1.substring(g1.lastIndexOf('.') + 1) : null; + const filename = g1 != langCode ? g1 : null; + const classNameAtt = langCode ? ` class="language-${langCode}"` : ''; + const filenameAtt = filename ? ` data-label="${filename}"` : ''; + return `
${g2}
`; }, }; diff --git a/src/app/plugins/react-custom-html-parser.tsx b/src/app/plugins/react-custom-html-parser.tsx index ba40c978..961131d9 100644 --- a/src/app/plugins/react-custom-html-parser.tsx +++ b/src/app/plugins/react-custom-html-parser.tsx @@ -232,8 +232,9 @@ export function CodeBlock({ opts: HTMLReactParserOptions; }) { const code = children[0]; - const languageClass = - code instanceof Element && code.name === 'code' ? code.attribs.class : undefined; + const attribs = code instanceof Element && code.name === 'code' ? code.attribs : undefined; + const languageClass = attribs?.class; + const customLabel = attribs?.['data-label']; const language = languageClass && languageClass.startsWith('language-') ? languageClass.replace('language-', '') @@ -262,7 +263,7 @@ export function CodeBlock({
- {language ?? 'Code'} + {customLabel ?? language ?? 'Code'} diff --git a/src/app/utils/sanitize.ts b/src/app/utils/sanitize.ts index 985c47b1..2ea5dbc0 100644 --- a/src/app/utils/sanitize.ts +++ b/src/app/utils/sanitize.ts @@ -71,7 +71,7 @@ const permittedTagToAttributes = { ul: ['data-md'], a: ['name', 'target', 'href', 'rel', 'data-md'], img: ['width', 'height', 'alt', 'title', 'src', 'data-mx-emoticon'], - code: ['class', 'data-md'], + code: ['class', 'data-md', 'data-label'], strong: ['data-md'], i: ['data-md'], em: ['data-md'],