mirror of
https://github.com/CompassConnections/Compass.git
synced 2026-01-25 06:07:57 -05:00
90 lines
2.2 KiB
TypeScript
90 lines
2.2 KiB
TypeScript
import type { JSONContent } from '@tiptap/core'
|
|
|
|
export function jsonToMarkdown(node: JSONContent): string {
|
|
if (!node) return ''
|
|
|
|
// Text node
|
|
if (node.type === 'text') {
|
|
let text = node.text || ''
|
|
|
|
if (node.marks) {
|
|
for (const mark of node.marks) {
|
|
switch (mark.type) {
|
|
case 'bold':
|
|
text = `**${text}**`
|
|
break
|
|
case 'italic':
|
|
text = `*${text}*`
|
|
break
|
|
case 'strike':
|
|
text = `~~${text}~~`
|
|
break
|
|
case 'code':
|
|
text = `\`${text}\``
|
|
break
|
|
case 'link':
|
|
text = `[${text}](${mark.attrs?.href ?? ''})`
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
return text
|
|
}
|
|
|
|
// Non-text nodes: recursively process children
|
|
const content = (node.content || []).map(jsonToMarkdown).join('')
|
|
|
|
switch (node.type) {
|
|
case 'paragraph':
|
|
return `${content}\n`
|
|
case 'heading': {
|
|
const level = node.attrs?.level || 1
|
|
return `${'#'.repeat(level)} ${content}\n`
|
|
}
|
|
case 'bulletList':
|
|
return `${content}`
|
|
case 'orderedList':
|
|
return `${content}`
|
|
case 'listItem':
|
|
return `- ${content}`
|
|
case 'blockquote':
|
|
return content
|
|
.split('\n')
|
|
.map((line) => (line ? `> ${line}` : ''))
|
|
.join('\n') + '\n\n'
|
|
case 'codeBlock':
|
|
return `\`\`\`\n${content}\n\`\`\`\n\n`
|
|
case 'horizontalRule':
|
|
return `---\n\n`
|
|
case 'hardBreak':
|
|
return ` \n`
|
|
default:
|
|
return content
|
|
}
|
|
}
|
|
|
|
// function extractTextFromJsonb(bio: JSONContent): string {
|
|
// try {
|
|
// const texts: string[] = []
|
|
// const visit = (node: any) => {
|
|
// if (!node) return
|
|
// if (Array.isArray(node)) {
|
|
// for (const item of node) visit(item)
|
|
// return
|
|
// }
|
|
// if (typeof node === 'object') {
|
|
// for (const [k, v] of Object.entries(node)) {
|
|
// if (k === 'text' && typeof v === 'string') texts.push(v)
|
|
// else visit(v as any)
|
|
// }
|
|
// }
|
|
// }
|
|
// visit(bio)
|
|
// // Remove extra whitespace and join
|
|
// return texts.map((t) => t.trim()).filter(Boolean).join(' ')
|
|
// } catch {
|
|
// return ''
|
|
// }
|
|
// }
|