import type { Note } from '@/lib/types' const MD_IMG = /!\[[^\]]*\]\(([^)\s]+)\)/g const HTML_IMG = /]+src=["']([^"']+)["'][^>]*>/gi /** * Plain-text preview for list view (light markdown stripping). */ export function stripMarkdownPreview(raw: string, maxLen = 180): string { if (!raw?.trim()) return '' let t = raw .replace(/^#{1,6}\s+/gm, '') .replace(/```[\s\S]*?```/g, ' ') .replace(/\*\*([^*]+)\*\*/g, '$1') .replace(/\*([^*]+)\*/g, '$1') .replace(/`([^`]+)`/g, '$1') .replace(/\[(.+?)]\([^)]+\)/g, '$1') .replace(/^\s*[-*+]\s+/gm, '') .replace(/^\s*\d+\.\s+/gm, '') .replace(/\n+/g, ' ') .replace(/\s+/g, ' ') .trim() if (t.length > maxLen) { return `${t.slice(0, maxLen).trim()}…` } return t } export function getNoteDisplayTitle(note: { title: string | null; content: string; type: string }, untitled: string): string { const title = note.title?.trim() if (title) return title if (note.type === 'checklist') { const line = note.content?.split('\n').find((l) => l.trim()) if (line) return stripMarkdownPreview(line, 80) || untitled } const preview = stripMarkdownPreview(note.content || '', 100) return preview || untitled } export function getNoteFeedImage(note: Note): string | null { const first = note.images?.[0]?.trim() if (first) return first const content = note.content || '' MD_IMG.lastIndex = 0 const md = MD_IMG.exec(content) if (md?.[1]) return md[1] HTML_IMG.lastIndex = 0 const html = HTML_IMG.exec(content) if (html?.[1]) return html[1] return null } /** Plain excerpt for collection cards (HTML + markdown noise stripped). */ export function getNotePlainExcerpt(note: Note, maxLen = 240): string { let raw = note.content || '' raw = raw.replace(/!\[[^\]]*\]\([^)]+\)/g, ' ') raw = raw.replace(/<[^>]+>/g, ' ') return stripMarkdownPreview(raw, maxLen) }