diff --git a/kjvstudy_org/server.py b/kjvstudy_org/server.py index 25fac55..ba5884e 100644 --- a/kjvstudy_org/server.py +++ b/kjvstudy_org/server.py @@ -1142,7 +1142,11 @@ def format_numbered_lists(text): templates.env.filters['format_lists'] = format_numbered_lists +def number_format(value): + """Format a number with commas (e.g., 31102 -> 31,102)""" + return f"{value:,}" +templates.env.filters['number_format'] = number_format def get_biblical_timeline_context(): @@ -2269,6 +2273,94 @@ async def chapter_pdf(request: Request, book: str, chapter: int): ) +@app.get("/bible/pdf") +async def bible_pdf(request: Request): + """Generate a PDF export of the complete Bible with cross-references and word studies.""" + if not WEASYPRINT_AVAILABLE: + raise HTTPException( + status_code=503, + detail="PDF generation is not available. WeasyPrint system libraries are not installed." + ) + + from .data import bible_metadata + + books = bible.get_books() + old_testament = bible_metadata.old_testament_books + new_testament = bible_metadata.new_testament_books + + # Prepare data for all books + books_data = [] + total_verses = 0 + + for book_name in books: + chapters_dict = {} + commentaries_dict = {} + shown_words = set() # Track word studies per book + + # Get all chapters for this book + chapters = bible.get_chapters_for_book(book_name) + + for chapter_num in chapters: + verses = bible.get_verses_by_book_chapter(book_name, chapter_num) + chapters_dict[chapter_num] = verses + total_verses += len(verses) + + # Generate commentaries for this chapter + chapter_commentaries = {} + for verse in verses: + commentary = generate_commentary(book_name, chapter_num, verse) + + # Add word study sidenotes (avoiding repetition within book) + word_studies = generate_word_study_sidenotes( + verse.text, book_name, chapter_num, verse.verse, shown_words + ) + commentary['word_studies'] = word_studies + for study in word_studies: + shown_words.add(study['word'].lower()) + + # Add cross-references grouped by description + from collections import defaultdict + cross_refs = get_cross_references(book_name, chapter_num, verse.verse) + grouped_refs = defaultdict(list) + for ref in cross_refs: + description = ref['note'] if ref['note'] else 'Related' + grouped_refs[description].append(ref['ref']) + + commentary['cross_reference_groups'] = [ + {'description': desc, 'refs': refs} + for desc, refs in grouped_refs.items() + ] + + chapter_commentaries[verse.verse] = commentary + + commentaries_dict[chapter_num] = chapter_commentaries + + books_data.append({ + 'name': book_name, + 'chapter_count': len(chapters), + 'chapters': chapters_dict, + 'commentaries': commentaries_dict + }) + + # Render HTML + html_content = templates.get_template("bible_pdf.html").render( + books=books_data, + old_testament=old_testament, + new_testament=new_testament, + total_verses=total_verses, + ) + + # Generate PDF (this will take a while for the full Bible!) + pdf_buffer = await render_html_to_pdf_async(html_content) + filename = "kjv-complete-bible.pdf" + + return StreamingResponse( + pdf_buffer, + media_type="application/pdf", + headers={"Content-Disposition": f"attachment; filename={filename}"} + ) + + @app.get("/book/{book}/chapter/{chapter}/verse/{verse_num}", response_class=HTMLResponse) def read_verse(request: Request, book: str, chapter: int, verse_num: int): """Display a single verse with detailed commentary""" diff --git a/kjvstudy_org/templates/bible_pdf.html b/kjvstudy_org/templates/bible_pdf.html new file mode 100644 index 0000000..c8acfe6 --- /dev/null +++ b/kjvstudy_org/templates/bible_pdf.html @@ -0,0 +1,251 @@ + + +
+ +Authorized King James Version
+
+ 1769 Cambridge Edition
+ Complete with Cross-References and Word Studies
+ {{ total_verses|number_format }} verses across 66 books
+
{{ book_data.chapter_count }} {% if book_data.chapter_count == 1 %}chapter{% else %}chapters{% endif %}
+ + {% for chapter_num, verses in book_data.chapters.items() %} +