diff --git a/src/lib/types/index.ts b/src/lib/types/index.ts index 2feb68e..a00bb66 100644 --- a/src/lib/types/index.ts +++ b/src/lib/types/index.ts @@ -18,6 +18,12 @@ export interface Note { isOwner?: boolean; isShared?: boolean; shareToken?: string; + backlinks?: NoteBacklink[]; +} + +export interface NoteBacklink { + id: string; + title: string; } export interface Collaborator { diff --git a/src/lib/utils/markdown.test.ts b/src/lib/utils/markdown.test.ts index 00efdbb..d8c7152 100644 --- a/src/lib/utils/markdown.test.ts +++ b/src/lib/utils/markdown.test.ts @@ -85,3 +85,16 @@ describe('stripMarkdown', () => { expect(stripMarkdown('')).toBe(''); }); }); + +describe('renderMarkdown note-link handling', () => { + it('should render a crumb-note:// link as plain text, not a clickable anchor', () => { + const html = renderMarkdown('See [Grocery List](crumb-note://abc-123) for details'); + expect(html).not.toContain(' { + const html = renderMarkdown('See [Example](https://example.com) for details'); + expect(html).toContain(' { } }); +md.core.ruler.after('task-lists', 'note-links', (state) => { + for (const token of state.tokens) { + if (token.type !== 'inline' || !token.children) continue; + + const children = token.children; + for (let i = 0; i < children.length; i++) { + if (children[i].type !== 'link_open') continue; + const href = children[i].attrGet('href') ?? ''; + if (!href.startsWith('crumb-note://')) continue; + + let closeIndex = i + 1; + while (closeIndex < children.length && children[closeIndex].type !== 'link_close') closeIndex++; + children.splice(closeIndex, 1); + children.splice(i, 1); + i -= 1; + } + } +}); + export function renderMarkdown(content: string): string { return md.render(content); }