63 lines
1.9 KiB
TypeScript
63 lines
1.9 KiB
TypeScript
import type { Note } from '@/lib/types'
|
|
|
|
const MD_IMG = /!\[[^\]]*\]\(([^)\s]+)\)/g
|
|
const HTML_IMG = /<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)
|
|
}
|