function pushText(out: string[], value: unknown) { const s = typeof value === "string" ? value : null; if (!s) return; const trimmed = s.replace(/\s+/g, " ").trim(); if (!trimmed) return; out.push(trimmed); } export function extractTextFromDocumentContent(content: unknown, maxChars = 60000): string { const out: string[] = []; const readPropText = (value: unknown) => { if (!value || typeof value !== "object") return null; const t = (value as Record).text; return typeof t === "string" ? t : null; }; const walk = (node: unknown) => { if (out.join("\n").length >= maxChars) return; if (node == null) return; if (typeof node === "string") { pushText(out, node); return; } if (typeof node === "number" || typeof node === "boolean") return; if (Array.isArray(node)) { for (const item of node) { walk(item); if (out.join("\n").length >= maxChars) return; } return; } if (typeof node === "object") { const obj = node as Record; // 兼容常见 BlockNote 结构: // - block.props.text // - block.content: [{ text: "..." }, ...] // - block.children: [...] pushText(out, obj.text); pushText(out, readPropText(obj.props)); const maybeContent = obj.content; if (Array.isArray(maybeContent)) { for (const seg of maybeContent) { if (typeof seg === "string") pushText(out, seg); else if (seg && typeof seg === "object") pushText(out, readPropText(seg)); if (out.join("\n").length >= maxChars) return; } } const children = obj.children; if (Array.isArray(children)) { for (const c of children) { walk(c); if (out.join("\n").length >= maxChars) return; } } // 兜底:遍历其它字段(避免遗漏 title/caption 等) for (const [k, v] of Object.entries(obj)) { if (k === "children" || k === "content" || k === "props" || k === "text") continue; if (typeof v === "string") pushText(out, v); else if (Array.isArray(v) || (v && typeof v === "object")) walk(v); if (out.join("\n").length >= maxChars) return; } } }; walk(content); const joined = out.join("\n").trim(); return joined.length > maxChars ? `${joined.slice(0, maxChars)}…` : joined; } type MindmapNode = { data?: { text?: unknown }; children?: unknown[] }; export function extractTextFromMindmapData(data: unknown, maxChars = 60000): string { const out: string[] = []; const walk = (node: unknown) => { if (out.join("\n").length >= maxChars) return; if (!node || typeof node !== "object") return; const n = node as MindmapNode; pushText(out, n.data?.text); if (Array.isArray(n.children)) { for (const c of n.children) { walk(c); if (out.join("\n").length >= maxChars) return; } } }; walk(data); const joined = out.join("\n").trim(); return joined.length > maxChars ? `${joined.slice(0, maxChars)}…` : joined; }