diff --git a/frontend/src/components/shared/markdown-editor/markdown-editor-extensions.test.ts b/frontend/src/components/shared/markdown-editor/markdown-editor-extensions.test.ts index 3717c7aa..72b5bc80 100644 --- a/frontend/src/components/shared/markdown-editor/markdown-editor-extensions.test.ts +++ b/frontend/src/components/shared/markdown-editor/markdown-editor-extensions.test.ts @@ -223,7 +223,7 @@ describe('nesting & sequencing — content preserved and converges (≤2 saves)' // A code block nested in a list (ordered > bullet > code) has an indented opening fence, so // @tiptap/extension-code-block's `startsWith('```')` gate used to drop it — the same root cause as a -// top-level indented fence, fixed by parseFaithfulCodeBlock (see markdown-editor-extensions.ts). This was +// top-level indented fence, fixed by parseTunedCodeBlock (see markdown-editor-extensions.ts). This was // once a pinned KNOWN-BUG test asserting the loss; the fix now keeps the code. describe('ordered > bullet > code — indented nested code survives', () => { it('keeps the deeply-nested code block', () => { diff --git a/frontend/src/components/shared/markdown-editor/markdown-editor-extensions.ts b/frontend/src/components/shared/markdown-editor/markdown-editor-extensions.ts index ffc292ef..a30fe077 100644 --- a/frontend/src/components/shared/markdown-editor/markdown-editor-extensions.ts +++ b/frontend/src/components/shared/markdown-editor/markdown-editor-extensions.ts @@ -37,7 +37,7 @@ const longestBacktickRun = (text: string): number => // contains a ``` line (a doc demonstrating fenced markdown — common in knowledge/prompt examples) re-parses as // TWO blocks on the next load: the inner fence closes the outer one. CommonMark requires the fence to be longer // than any backtick run inside — widen it. Otherwise identical to upstream. -const renderFaithfulCodeBlock = (node: MarkdownRenderNode, h: MarkdownRenderHelpers): string => { +const renderTunedCodeBlock = (node: MarkdownRenderNode, h: MarkdownRenderHelpers): string => { const language = node.attrs?.language || ''; if (!node.content) { @@ -55,7 +55,7 @@ const renderFaithfulCodeBlock = (node: MarkdownRenderNode, h: MarkdownRenderHelp // token whose `raw` starts with that whitespace, the gate rejects it, and the block is dropped on load. When // a document mixes fences at different indents the mis-detection cascades and everything after the first // dropped fence vanishes too. Trim the leading indent before the gate; otherwise identical to upstream. -const parseFaithfulCodeBlock = (token: MarkdownCodeToken, helpers: MarkdownParseHelpers): unknown => { +const parseTunedCodeBlock = (token: MarkdownCodeToken, helpers: MarkdownParseHelpers): unknown => { const fence = token.raw?.trimStart() ?? ''; if (!fence.startsWith('```') && !fence.startsWith('~~~') && token.codeBlockStyle !== 'indented') { @@ -74,7 +74,7 @@ const parseFaithfulCodeBlock = (token: MarkdownCodeToken, helpers: MarkdownParse // `__init__`/`_word_` would emphasize (→ `**init**`/`*word*`) while the same text loaded stays literal, // breaking identifiers. Drop only the underscore rules (their `find` regex mentions `_`; the `*` rules stay) // so typing matches load. codeBlock gets the indented-fence fix above. (Underline off below.) -const StarterKitFaithful = StarterKit.extend({ +const StarterKitTuned = StarterKit.extend({ addExtensions() { return (this.parent?.() ?? []).map((extension) => { if (extension.name === 'bold' || extension.name === 'italic') { @@ -90,8 +90,8 @@ const StarterKitFaithful = StarterKit.extend({ if (extension.name === 'codeBlock') { return extension.extend({ - parseMarkdown: parseFaithfulCodeBlock, - renderMarkdown: renderFaithfulCodeBlock, + parseMarkdown: parseTunedCodeBlock, + renderMarkdown: renderTunedCodeBlock, } as Parameters[0]); } @@ -109,7 +109,7 @@ const StarterKitFaithful = StarterKit.extend({ // symmetric with the marked layer (which no longer neutralises autolink/url). Do NOT set false: it // diverges typing from load and re-freezes bare URLs as text. export const createMarkdownExtensions = (placeholder?: string) => [ - StarterKitFaithful.configure({ + StarterKitTuned.configure({ codeBlock: { HTMLAttributes: { class: 'hljs' } }, link: { autolink: true, linkOnPaste: true }, underline: false, diff --git a/frontend/src/components/shared/markdown-editor/markdown-editor-marked.ts b/frontend/src/components/shared/markdown-editor/markdown-editor-marked.ts index 232c7d9a..47ed862c 100644 --- a/frontend/src/components/shared/markdown-editor/markdown-editor-marked.ts +++ b/frontend/src/components/shared/markdown-editor/markdown-editor-marked.ts @@ -10,7 +10,7 @@ import { Marked } from 'marked'; // that must survive verbatim; marked silently swallows the ones whose names match real HTML elements // (``, `
`, …). Neutralising marked's block (`html`) and inline (`tag`) HTML tokenizers makes // every `<...>` fall through to plain text, recreating markdown-it's `html: false`. -const createFaithfulMarked = () => { +const createTunedMarked = () => { const instance = new Marked(); instance.use({ @@ -41,7 +41,7 @@ const createFaithfulMarked = () => { return instance; }; -// The serialize-side counterpart to createFaithfulMarked. @tiptap/markdown's MarkdownManager +// The serialize-side counterpart to createTunedMarked. @tiptap/markdown's MarkdownManager // .encodeTextForMarkdown HTML-entity-encodes text (`<` → `<`) and backslash-escapes ``` ` * _ [ ] ~ \ ```. // Both are wrong here: the load side keeps `\`+punct literal (escape tokenizer off), so re-escaping on save // would double every backslash; and named HTML entities are DECODED on load (`<`→`<`), so re-encoding @@ -49,8 +49,8 @@ const createFaithfulMarked = () => { // replace that one method with identity — save emits exactly the text the doc holds. type ManagerWithEncode = { encodeTextForMarkdown: (text: string) => string }; -const FaithfulMarkdownText = Extension.create({ - name: 'faithfulMarkdownText', +const TunedMarkdownText = Extension.create({ + name: 'tunedMarkdownText', onBeforeCreate() { const manager = this.editor.markdown as unknown as ManagerWithEncode | undefined; @@ -86,6 +86,6 @@ export const MarkdownTable = Table.extend({ }); export const createMarkdownLayer = () => [ - Markdown.configure({ marked: createFaithfulMarked() as unknown as typeof import('marked').marked }), - FaithfulMarkdownText, + Markdown.configure({ marked: createTunedMarked() as unknown as typeof import('marked').marked }), + TunedMarkdownText, ]; diff --git a/frontend/src/components/shared/markdown-editor/markdown-editor-paste.test.ts b/frontend/src/components/shared/markdown-editor/markdown-editor-paste.test.ts index 4b0486d0..0e353be1 100644 --- a/frontend/src/components/shared/markdown-editor/markdown-editor-paste.test.ts +++ b/frontend/src/components/shared/markdown-editor/markdown-editor-paste.test.ts @@ -40,7 +40,7 @@ describe('shouldParseMarkdownOnPaste — markdown-parse plain text, defer rich s }); }); -describe('MarkdownPaste — the parsed payload matches load (same faithful markdown layer)', () => { +describe('MarkdownPaste — the parsed payload matches load (same tuned markdown layer)', () => { const pasteEvent = (text: string, html = ''): ClipboardEvent => ({ clipboardData: {