Files
study-bible-project/src/utils/exportBuilders.js
T
nmemmertandClaude Sonnet 5.5 820886e3ab Outline: per-chunk outlines, richer points, print and share
- One outline for the whole study plus one per chunk (picker at the top);
  chunk outlines can start from the chunk's verses, each carrying its words
- Points can have a type (illustration, application, quote, question,
  transition), minutes (with a running total), a longer note, verse text
  fetched from a passage, and cross-references / word studies attached from
  the chunk
- Share (system share sheet, or copy), Print / PDF, Copy as text, Word and
  Markdown downloads for any one outline
- All of it included in the Markdown, HTML/PDF and Word study exports,
  with each chunk's outline under that chunk

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 14:24:28 -04:00

218 lines
8.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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);
}