import type { NoteType } from '@/types/note' export interface GuidedField { command: { command: string description: string example: string } snippet: { language: string code: string description: string } decision: { context: string decision: string alternatives: string consequences: string } recipe: { ingredients: string steps: string time: string } procedure: { objective: string steps: string requirements: string } inventory: { item: string quantity: string location: string } note: Record } export type GuidedType = keyof GuidedField export function isGuidedType(type: NoteType): type is GuidedType { return type !== 'note' } export function isFreeMarkdown(content: string): boolean { if (!content) return false const lines = content.trim().split('\n') const guidedPatterns = [ /^##\s*(Comando|Qué hace|Cuando usarlo|Ejemplo)$/, /^##\s*(Snippet|Lenguaje|Qué resuelve|Notas)$/, /^##\s*(Contexto|Decisión|Alternativas|を考慮|Consecuencias)$/, /^##\s*(Ingredientes|Pasos|Tiempo|Notas)$/, /^##\s*(Objetivo|Requisitos|Problemas comunes)$/, /^##\s*(Item|Cantidad|Ubicación|Notas)$/, /^##\s*Notas$/, ] let matchCount = 0 for (const line of lines) { for (const pattern of guidedPatterns) { if (pattern.test(line)) { matchCount++ break } } } return matchCount < 3 } export function serializeToMarkdown(type: NoteType, fields: Record): string { switch (type) { case 'command': return `## Comando ${fields.command || ''} ## Qué hace ${fields.description || ''} ## Ejemplo \`\`\`bash ${fields.example || ''} \`\`\` ` case 'snippet': return `## Snippet ## Lenguaje ${fields.language || ''} ## Código \`\`\`${fields.language || ''} ${fields.code || ''} \`\`\` ## Descripción ${fields.description || ''} ` case 'decision': return `## Contexto ${fields.context || ''} ## Decisión ${fields.decision || ''} ## Alternativas consideradas ${fields.alternatives || ''} ## Consecuencias ${fields.consequences || ''} ` case 'recipe': return `## Ingredientes ${fields.ingredients || ''} ## Pasos ${fields.steps || ''} ## Tiempo ${fields.time || ''} ` case 'procedure': return `## Objetivo ${fields.objective || ''} ## Pasos ${fields.steps || ''} ## Requisitos ${fields.requirements || ''} ` case 'inventory': return `## Item ${fields.item || ''} ## Cantidad ${fields.quantity || ''} ## Ubicación ${fields.location || ''} ` case 'note': default: return fields.content || '' } } export function parseMarkdownToFields(type: NoteType, content: string): Record { const fields: Record = {} if (!content) return fields const sectionPattern = /^##\s+(.+)$/gm const sections: { title: string; content: string }[] = [] let lastIndex = 0 let match while ((match = sectionPattern.exec(content)) !== null) { if (lastIndex !== 0) { const prevMatch = sectionPattern.exec(content) if (prevMatch) { sections.push({ title: prevMatch[1], content: content.slice(lastIndex, match.index).trim() }) } } lastIndex = match.index + match[0].length } const remainingContent = content.slice(lastIndex).trim() if (remainingContent) { sections.push({ title: sections.length > 0 ? sections[sections.length - 1].title : '', content: remainingContent }) } switch (type) { case 'command': fields.command = extractSection(content, 'Comando') fields.description = extractSection(content, 'Qué hace') fields.example = extractCodeBlock(content) break case 'snippet': fields.language = extractSection(content, 'Lenguaje') fields.code = extractCodeBlock(content) fields.description = extractSection(content, 'Descripción') break case 'decision': fields.context = extractSection(content, 'Contexto') fields.decision = extractSection(content, 'Decisión') fields.alternatives = extractSection(content, 'Alternativas') fields.consequences = extractSection(content, 'Consecuencias') break case 'recipe': fields.ingredients = extractSection(content, 'Ingredientes') fields.steps = extractSection(content, 'Pasos') fields.time = extractSection(content, 'Tiempo') break case 'procedure': fields.objective = extractSection(content, 'Objetivo') fields.steps = extractSection(content, 'Pasos') fields.requirements = extractSection(content, 'Requisitos') break case 'inventory': fields.item = extractSection(content, 'Item') fields.quantity = extractSection(content, 'Cantidad') fields.location = extractSection(content, 'Ubicación') break case 'note': default: fields.content = content } return fields } function extractSection(content: string, sectionName: string): string { const pattern = new RegExp(`##\\s+${sectionName}\\s*\\n([\\s\\S]*?)(?=##\\s+|\\z)`, 'i') const match = content.match(pattern) return match ? match[1].trim() : '' } function extractCodeBlock(content: string): string { const match = content.match(/```[\w]*\n?([\s\S]*?)```/) return match ? match[1].trim() : '' }