// Markdown export and Claude prompt builders. import { formatChunkReference, getChunkVerseEntries, htmlToPlainText, } from './bibleUtils.jsx'; import { outlineToMarkdown, timeSummary } from './outline.js'; // --------------------------------------------------------------------------- // Export / prompt builders (exported for testing) // --------------------------------------------------------------------------- export function buildMarkdownExport(project) { const chapters = Array.isArray(project.chapters) ? project.chapters : []; const chapterSections = chapters.map((ch, chapterIndex) => { const chunkSections = ch.chunks.map((chunk) => { const scripture = formatChunkReference(project, chapterIndex, chunk, '-'); const versesText = getChunkVerseEntries(project, chapterIndex, chunk) .map((verse) => `> **${verse.chapter}:${verse.number}** ${verse.text}`) .join('\n>\n'); const observation = (chunk.observation ?? '').trim() || '_No observation._'; const interpretation = (chunk.interpretation ?? '').trim() || '_No interpretation._'; const application = (chunk.application ?? '').trim() || '_No application._'; const generalNotes = (chunk.generalNotes ?? '').trim(); const crossRefsLine = (chunk.crossReferences ?? []).length > 0 ? `**Cross-References:** ${chunk.crossReferences.join(', ')}\n\n` : ''; const greekSection = chunk.greekWords.length === 0 ? '' : `**Greek/Hebrew Words**\n\n${chunk.greekWords.map((word) => { const summary = [ word.strongNumber, word.lexeme, word.transliteration && `(${word.transliteration})`, word.partOfSpeech, word.shortDefinition, ].filter(Boolean).join(' — '); const definition = word.definitionHtml ? `\n ${htmlToPlainText(word.definitionHtml)}` : ''; return `- ${summary}${definition}`; }).join('\n')}\n\n`; const chunkOutline = (chunk.outline ?? []).length > 0 ? `**Outline**\n\n${outlineToMarkdown(chunk.outline)}\n\n` : ''; return `### ${scripture}\n\n${versesText}\n\n${chunkOutline}${generalNotes ? `**Background / Notes**\n\n${generalNotes}\n\n` : ''}**Observation**\n\n${observation}\n\n**Interpretation**\n\n${interpretation}\n\n**Application**\n\n${application}\n\n${crossRefsLine}${greekSection}`; }).join('---\n\n'); return `## ${ch.book} ${ch.chapter}\n\n${chunkSections}`; }).join('\n'); const outline = (project.outline ?? []).length > 0 ? `## Outline\n\n${timeSummary(project.outline) ? `*${timeSummary(project.outline)}*\n\n` : ''}${outlineToMarkdown(project.outline)}\n\n` : ''; return `# ${project.title}\n\n*${project.translation}*\n\n${outline}${chapterSections}`; } export function buildChunkBodies(project) { const chapters = Array.isArray(project.chapters) ? project.chapters : []; let chunkIndex = 0; return chapters.map((ch, chapterIndex) => { return ch.chunks.map((chunk) => { chunkIndex += 1; const ref = formatChunkReference(project, chapterIndex, chunk, '–'); const verses = getChunkVerseEntries(project, chapterIndex, chunk) .map((v) => `${v.chapter}:${v.number} ${v.text}`) .join('\n'); const observation = (chunk.observation ?? '').trim() || 'No observation.'; const interpretation = (chunk.interpretation ?? '').trim() || 'No interpretation.'; const application = (chunk.application ?? '').trim() || 'No application.'; const crossRefs = (chunk.crossReferences ?? []).length > 0 ? chunk.crossReferences.join(', ') : 'None.'; const generalNotes = (chunk.generalNotes ?? '').trim(); const episodeLabelLine = (chunk.episodeNumber ?? '').trim() || (chunk.episodeTitle ?? '').trim() ? `Session: ${[chunk.episodeNumber?.trim(), chunk.episodeTitle?.trim()].filter(Boolean).join(' — ')}\n` : ''; const greekWords = chunk.greekWords.length === 0 ? 'None.' : chunk.greekWords.map((word) => { const summary = [ word.strongNumber, word.lexeme, word.transliteration && `(${word.transliteration})`, word.partOfSpeech, word.shortDefinition, ].filter(Boolean).join(' | '); const definition = word.definitionHtml ? `\n ${htmlToPlainText(word.definitionHtml)}` : ''; return `• ${summary}${definition}`; }).join('\n'); return `=== CHUNK ${chunkIndex} — ${ref} ${episodeLabelLine} Scripture: ${verses} ${generalNotes ? `\nBackground / General Notes:\n${generalNotes}\n` : ''} Observation: ${observation} Interpretation: ${interpretation} Application: ${application} Cross-References: ${crossRefs} Greek Words: ${greekWords} `; }).join('\n'); }).join('\n'); } export function buildClaudePrompt(project) { const chapters = Array.isArray(project.chapters) ? project.chapters : []; const chapterLabel = chapters.map((ch) => `${ch.book} ${ch.chapter}`).join(', '); const header = `I've prepared a Bible study on ${chapterLabel} (${project.translation}) and need your help turning my notes into a polished study guide. Below is my work organised by passage chunk, including my OIA notes and Greek word research. Please create a clear, structured study guide that: - Synthesises my notes into coherent teaching points - Naturally integrates the Greek word insights - Includes 2–3 reflection questions per chunk - Preserves the passage-by-passage structure --- PROJECT: ${project.title} TRANSLATION: ${project.translation} PASSAGE: ${chapterLabel} `; return header + buildChunkBodies(project); } export function buildPodcastPrompt(project, podcastName) { const chapters = Array.isArray(project.chapters) ? project.chapters : []; const chapterLabel = chapters.map((ch) => `${ch.book} ${ch.chapter}`).join(', '); const episodeLabel = 'EPISODE'; const showName = (podcastName ?? '').trim(); const showLine = showName || 'MY BIBLE STUDY PODCAST'; const signOffLine = showName ? `Introduce yourself, then sign off with: "...and this is ${showName}."` : 'Introduce yourself and the name of the show as a sign-off.'; const header = `I'm recording an episode of my Bible study podcast${showName ? ` "${showName}"` : ''} and need a full script written from my study notes below. Please write the script in this exact structure, using the section markers and tone shown: ${showLine.toUpperCase()} ${episodeLabel} ${chapterLabel} (${project.translation}) · [estimate XX–XX minutes based on content] ✝ OPENING PRAYER [Pause before opening the text — invite God into the study] A short prayer (4-6 sentences) tying into the themes of this passage. — ✦ — 🎙️ COLD OPEN [Co-host delivers the cold open solo, if there is one — hands off to the host at the end] A few short punchy lines previewing the passage and its hook, ending with a hand-off line introducing the host and the show. — ✦ — 📖 SEGMENT [N] — [SEGMENT TITLE] [Brief stage direction in brackets] One segment per passage chunk (use the chunk reference, observation, interpretation, and application notes below as the raw material). Conversational, spoken-word style — not academic prose. Work through the text the way the host would talk it through out loud, weaving in the OIA notes and cross-references naturally. — ✦ — 📖 SEGMENT [N] — GREEK WORD STUDY [Work through the key terms — keep it vivid, help the words come alive] For each Greek/Hebrew word collected below, a block in this format: [English Gloss] — [English meaning] [DO NOT READ: original-language word (transliteration) — part of speech] 2-4 sentences unpacking the word's meaning and why it matters for this passage, conversational tone. — ✦ — 💬 DISCUSSION QUESTIONS [From the study guide — ${chapterLabel}] 3 reflection questions drawn from the application notes, numbered. — ✦ — ✦ CLOSING [Grounded and direct — send them away with something to carry] A closing reflection that ties the segments together, a short pull-quote from the passage with its reference, then close out. ${signOffLine} "Until next time — keep studying verse by verse." — End of Episode — ${showLine} · ${episodeLabel} · ${chapterLabel} --- Here are my study notes, organised by passage chunk, including my OIA notes, cross-references, and Greek/Hebrew word research: PROJECT: ${project.title} TRANSLATION: ${project.translation} PASSAGE: ${chapterLabel} `; return header + buildChunkBodies(project); }