diff --git a/src/components/blog/TextEditor.tsx b/src/components/blog/TextEditor.tsx index 4f7e4d2..d55ef30 100644 --- a/src/components/blog/TextEditor.tsx +++ b/src/components/blog/TextEditor.tsx @@ -231,6 +231,7 @@ const KEYBOARD_SHORTCUTS: ShortcutCategory[] = [ name: "Insert", shortcuts: [ { keys: "⌘ K", keysAlt: "Ctrl K", description: "Insert/Edit Link" }, + { keys: "⌘ R", keysAlt: "Ctrl R", description: "Insert Reference [n]" }, { keys: "⌘ ⇧ C", keysAlt: "Ctrl Shift C", description: "Code Block" }, { keys: "⌘ Enter", keysAlt: "Ctrl Enter", description: "Hard Break" }, { keys: "⌘ ⇧ -", keysAlt: "Ctrl Shift -", description: "Horizontal Rule" } @@ -500,6 +501,15 @@ export default function TextEditor(props: TextEditorProps) { attributes: { class: "focus:outline-none" }, + handleKeyDown(view, event) { + // Cmd/Ctrl+R for inserting reference + if ((event.metaKey || event.ctrlKey) && event.key === "r") { + event.preventDefault(); + insertReference(); + return true; + } + return false; + }, handleClickOn(view, pos, node, nodePos, event) { const target = event.target as HTMLElement; @@ -747,6 +757,50 @@ export default function TextEditor(props: TextEditorProps) { .run(); }; + const insertReference = () => { + const instance = editor(); + if (!instance) return; + + // Get next reference number by scanning document + const doc = instance.state.doc; + const foundRefs = new Set(); + + doc.descendants((node: any) => { + if (node.isText && node.marks) { + const hasSuperscript = node.marks.some( + (mark: any) => mark.type.name === "superscript" + ); + if (hasSuperscript) { + const text = node.text || ""; + const match = text.match(/^\[(.+?)\]$/); + if (match) { + foundRefs.add(match[1]); + } + } + } + }); + + // Calculate next number + const numericRefs = Array.from(foundRefs) + .map((ref) => parseInt(ref)) + .filter((num) => !isNaN(num)); + const nextNum = numericRefs.length > 0 ? Math.max(...numericRefs) + 1 : 1; + + const refNum = window.prompt("Reference number:", nextNum.toString()); + if (refNum === null || refNum.trim() === "") return; + + // Insert [n] with superscript + instance + .chain() + .focus() + .insertContent({ + type: "text", + text: `[${refNum.trim()}]`, + marks: [{ type: "superscript" }] + }) + .run(); + }; + const addIframe = () => { const instance = editor(); if (!instance) return; @@ -1781,27 +1835,6 @@ export default function TextEditor(props: TextEditorProps) { }} >
- {/* Undo/Redo buttons - critical for mobile */} - - -
- +
+ +