improved gramatical handling and spelling result orders
This commit is contained in:
@@ -105,6 +105,7 @@ cached: dict = {
|
|||||||
"chapter_list": [],
|
"chapter_list": [],
|
||||||
"books_chapter_lengths": {},
|
"books_chapter_lengths": {},
|
||||||
"json_dictionary": json.load(open("data/1828_Webster_KJV.json", "r")),
|
"json_dictionary": json.load(open("data/1828_Webster_KJV.json", "r")),
|
||||||
|
"grammatical_variants": json.load(open("data/grammatical_variants.json", "r")),
|
||||||
"html_response": open("html/response.html", "r").read(),
|
"html_response": open("html/response.html", "r").read(),
|
||||||
"html_navbar": open("html/navbar.html", "r").read(),
|
"html_navbar": open("html/navbar.html", "r").read(),
|
||||||
"css_navbar": open("styles/header.css", "r").read(),
|
"css_navbar": open("styles/header.css", "r").read(),
|
||||||
@@ -773,10 +774,31 @@ def search():
|
|||||||
return send_file("html/search.html")
|
return send_file("html/search.html")
|
||||||
results = lookup_fts(cleaned_keywords)
|
results = lookup_fts(cleaned_keywords)
|
||||||
if not results:
|
if not results:
|
||||||
h = hunspell.HunSpell("data/kjv.dic", "data/kjv.aff")
|
# PRIORITY 1: Try grammatical variant expansion first
|
||||||
|
|
||||||
# Split query into words and correct each one
|
|
||||||
words = cleaned_keywords.split()
|
words = cleaned_keywords.split()
|
||||||
|
|
||||||
|
for word in words:
|
||||||
|
variants = cached["grammatical_variants"].get(word.lower(), [])
|
||||||
|
if variants:
|
||||||
|
# Try each variant individually
|
||||||
|
for variant in variants:
|
||||||
|
variant_query = cleaned_keywords.replace(word, variant, 1)
|
||||||
|
results = lookup_fts(variant_query)
|
||||||
|
if results:
|
||||||
|
response_list = scripture_response(results)
|
||||||
|
arg_view = request.args.get("view", None)
|
||||||
|
if arg_view == "plain":
|
||||||
|
response = f"Showing results for '{variant_query}' (grammatical variant of '{cleaned_keywords}')\n<br>" + "<br>".join(response_list)
|
||||||
|
elif arg_view == "rich":
|
||||||
|
variant_notice = f"<div class='variant-notice'>Showing results for '<strong>{variant_query}</strong>' (grammatical variant of '{cleaned_keywords}')</div>"
|
||||||
|
response_str = "".join(response_list)
|
||||||
|
response = response_str.replace("<div class='responses'>", f"<div class='responses'>{variant_notice}", 1)
|
||||||
|
else:
|
||||||
|
response = jsonify({"original": cleaned_keywords, "variant": variant_query, "results": response_list})
|
||||||
|
return response
|
||||||
|
|
||||||
|
# PRIORITY 2: If grammatical variants didn't help, try spell-check
|
||||||
|
h = hunspell.HunSpell("data/kjv.dic", "data/kjv.aff")
|
||||||
corrected_words = []
|
corrected_words = []
|
||||||
had_corrections = False
|
had_corrections = False
|
||||||
|
|
||||||
@@ -798,19 +820,19 @@ def search():
|
|||||||
corrected_keyword = " ".join(corrected_words)
|
corrected_keyword = " ".join(corrected_words)
|
||||||
results = lookup_fts(corrected_keyword)
|
results = lookup_fts(corrected_keyword)
|
||||||
if results:
|
if results:
|
||||||
# Prepend correction notice to results
|
|
||||||
response_list = scripture_response(results)
|
response_list = scripture_response(results)
|
||||||
correction_notice = f"<div class='correction-notice'>Showing results for '<strong>{corrected_keyword}</strong>' (corrected from '{cleaned_keywords}')</div>"
|
|
||||||
arg_view = request.args.get("view", None)
|
arg_view = request.args.get("view", None)
|
||||||
if arg_view == "plain":
|
if arg_view == "plain":
|
||||||
response = f"Showing results for '{corrected_keyword}' (corrected from '{cleaned_keywords}')\n<br>" + "<br>".join(response_list)
|
response = f"Showing results for '{corrected_keyword}' (corrected from '{cleaned_keywords}')\n<br>" + "<br>".join(response_list)
|
||||||
elif arg_view == "rich":
|
elif arg_view == "rich":
|
||||||
response = correction_notice + "".join(response_list)
|
correction_notice = f"<div class='correction-notice'>Showing results for '<strong>{corrected_keyword}</strong>' (corrected from '{cleaned_keywords}')</div>"
|
||||||
|
response_str = "".join(response_list)
|
||||||
|
response = response_str.replace("<div class='responses'>", f"<div class='responses'>{correction_notice}", 1)
|
||||||
else:
|
else:
|
||||||
response = jsonify({"corrected_from": cleaned_keywords, "corrected_to": corrected_keyword, "results": response_list})
|
response = jsonify({"corrected_from": cleaned_keywords, "corrected_to": corrected_keyword, "results": response_list})
|
||||||
return response
|
return response
|
||||||
|
|
||||||
# If we still have no results, show suggestions
|
# PRIORITY 3: If we still have no results, show spelling suggestions
|
||||||
suggestions = h.suggest(cleaned_keywords)
|
suggestions = h.suggest(cleaned_keywords)
|
||||||
return "{} not found, try one of the following: {}".format(
|
return "{} not found, try one of the following: {}".format(
|
||||||
cleaned_keywords, ", ".join(suggestions) if suggestions else "No suggestions available"
|
cleaned_keywords, ", ".join(suggestions) if suggestions else "No suggestions available"
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"you": ["ye", "thee", "thou"],
|
||||||
|
"ye": ["you", "thee", "thou"],
|
||||||
|
"thee": ["you", "ye", "thou"],
|
||||||
|
"thou": ["you", "ye", "thee"],
|
||||||
|
"your": ["thy", "thine"],
|
||||||
|
"thy": ["your", "thine"],
|
||||||
|
"thine": ["your", "thy"],
|
||||||
|
"has": ["hath"],
|
||||||
|
"hath": ["has", "have"],
|
||||||
|
"have": ["hath"],
|
||||||
|
"does": ["doth"],
|
||||||
|
"doth": ["does", "do"],
|
||||||
|
"do": ["doth"],
|
||||||
|
"says": ["saith"],
|
||||||
|
"saith": ["says", "said"],
|
||||||
|
"said": ["saith"],
|
||||||
|
"are": ["art"],
|
||||||
|
"art": ["are"]
|
||||||
|
}
|
||||||
+20
-1
@@ -89,11 +89,30 @@ body {
|
|||||||
max-width: var(--content-max-width);
|
max-width: var(--content-max-width);
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: var(--space-md);
|
padding: var(--space-md);
|
||||||
margin-top: var(--header-height);
|
margin-top: calc(var(--header-height) + var(--space-md));
|
||||||
color: var(--color-text-primary);
|
color: var(--color-text-primary);
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Correction & Variant Notices */
|
||||||
|
.correction-notice,
|
||||||
|
.variant-notice {
|
||||||
|
font-family: var(--font-ui);
|
||||||
|
font-size: 0.95rem;
|
||||||
|
padding: var(--space-md) var(--space-lg);
|
||||||
|
margin-bottom: var(--space-lg);
|
||||||
|
background-color: var(--color-bg-tertiary);
|
||||||
|
border-left: 4px solid var(--color-accent-primary);
|
||||||
|
border-radius: var(--border-radius-sm);
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.correction-notice strong,
|
||||||
|
.variant-notice strong {
|
||||||
|
color: var(--color-accent-primary);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
/* Results Count */
|
/* Results Count */
|
||||||
.results-count {
|
.results-count {
|
||||||
font-family: var(--font-ui);
|
font-family: var(--font-ui);
|
||||||
|
|||||||
Reference in New Issue
Block a user