diff --git a/kjvstudy_org/server.py b/kjvstudy_org/server.py index f6d776e..87d46b4 100644 --- a/kjvstudy_org/server.py +++ b/kjvstudy_org/server.py @@ -493,6 +493,81 @@ def search_api(q: str = Query(..., description="Search query"), limit: Optional[ "is_direct_verse": is_direct_verse } + +@app.get("/concordance", response_class=HTMLResponse) +def concordance_page(request: Request, word: str = Query(None, description="Word to look up")): + """Concordance page showing all occurrences of a word""" + books = list(bible.iter_books()) + + if not word or len(word.strip()) < 2: + return templates.TemplateResponse( + "concordance.html", + { + "request": request, + "books": books, + "word": word or "", + "total_occurrences": 0, + "occurrences_by_book": {}, + "books_with_word": [] + } + ) + + search_word = word.strip() + occurrences = [] + occurrences_by_book = {} + books_with_word = set() + + # Search through all verses + import re + # Create a word boundary pattern for exact word matching + # This handles punctuation and word boundaries properly + pattern = re.compile(r'\b' + re.escape(search_word) + r'\b', re.IGNORECASE) + + for book in bible.iter_books(): + book_name = book.name + book_occurrences = [] + + for chapter_num in range(1, book.num_chapters + 1): + chapter = book.chapter(chapter_num) + + for verse in chapter.verses: + # Check if the word appears in this verse + if pattern.search(verse.text): + # Highlight the word in the text + highlighted_text = pattern.sub( + lambda m: f'{m.group()}', + verse.text + ) + + occurrence = { + 'book': book_name, + 'chapter': chapter_num, + 'verse': verse.verse, + 'text': verse.text, + 'highlighted_text': highlighted_text + } + + occurrences.append(occurrence) + book_occurrences.append(occurrence) + books_with_word.add(book_name) + + # Only add to occurrences_by_book if there are occurrences in this book + if book_occurrences: + occurrences_by_book[book_name] = book_occurrences + + return templates.TemplateResponse( + "concordance.html", + { + "request": request, + "books": books, + "word": search_word, + "total_occurrences": len(occurrences), + "occurrences_by_book": occurrences_by_book, + "books_with_word": sorted(books_with_word) + } + ) + + def parse_verse_reference(reference: str): """Parse a verse reference and return a URL for it. diff --git a/kjvstudy_org/templates/concordance.html b/kjvstudy_org/templates/concordance.html new file mode 100644 index 0000000..7712166 --- /dev/null +++ b/kjvstudy_org/templates/concordance.html @@ -0,0 +1,306 @@ +{% extends "base.html" %} + +{% block title %}{% if word %}Concordance: "{{ word }}" - {{ total_occurrences }} occurrences{% else %}Bible Concordance{% endif %} - KJV Study{% endblock %} +{% block description %}{% if word %}Complete concordance showing all {{ total_occurrences }} occurrences of "{{ word }}" in the King James Bible with context.{% else %}Search the complete KJV Bible concordance to find every occurrence of any word.{% endif %}{% endblock %} + +{% block head %} + +{% endblock %} + +{% block content %} +

Bible Concordance

+

Find every occurrence of any word in the King James Bible

+ +
+ + + {% if word %} + {% if total_occurrences > 0 %} +
+

The word "{{ word }}" appears {{ total_occurrences }} time{{ 's' if total_occurrences != 1 else '' }} in the King James Bible

+ {% if books_with_word %} +

Found in {{ books_with_word|length }} book{{ 's' if books_with_word|length != 1 else '' }}: {{ books_with_word|join(', ') }}

+ {% endif %} +
+ + {% if occurrences_by_book %} + {% for book_name, book_occurrences in occurrences_by_book.items() %} +
+

{{ book_name }} ({{ book_occurrences|length }} occurrence{{ 's' if book_occurrences|length != 1 else '' }})

+ +
+ {% for occurrence in book_occurrences %} +
+ +
{{ occurrence.highlighted_text | safe }}
+
+ {% endfor %} +
+
+ {% endfor %} + {% endif %} + {% else %} +
+

No occurrences found for "{{ word }}". Try a different word or check your spelling.

+

Note: The KJV uses older English spellings. Try words like "loveth" instead of "loves", "cometh" instead of "comes".

+
+ {% endif %} + {% endif %} + + {% if not word or total_occurrences == 0 %} + + +
+

Using the Concordance

+ +
+ {% endif %} +
+{% endblock %} diff --git a/kjvstudy_org/templates/index.html b/kjvstudy_org/templates/index.html index 45655c4..2645c57 100644 --- a/kjvstudy_org/templates/index.html +++ b/kjvstudy_org/templates/index.html @@ -522,7 +522,7 @@ document.addEventListener('keydown', function(e) {

Reading Plans — Structured Bible reading schedules for systematic Scripture study, including chronological, thematic, and testament-specific plans to guide sustained engagement with God's Word.

-

Concordance and Search — A comprehensive search facility allowing the reader to trace any word or phrase throughout the entire corpus of Scripture, after the manner of Cruden's Complete Concordance.

+

Concordance and Search — A comprehensive concordance showing every occurrence of any word in Scripture, and a search facility allowing the reader to trace any word or phrase throughout the entire corpus of Scripture, after the manner of Cruden's Complete Concordance.

Biblical GeographyMaps and descriptions of those places mentioned in Holy Writ, from the rivers of Babylon to the shores of Galilee, illuminating the geographical context of sacred history.