From a493f7ddaf2e3378df08a5ff803e164905b75fe2 Mon Sep 17 00:00:00 2001 From: Joshua Laymon Date: Tue, 2 Sep 2025 02:20:58 +0000 Subject: [PATCH] Update web/templates/entry_edit.html --- web/templates/entry_edit.html | 39 ++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/web/templates/entry_edit.html b/web/templates/entry_edit.html index 0423b23..3963cc7 100644 --- a/web/templates/entry_edit.html +++ b/web/templates/entry_edit.html @@ -212,7 +212,21 @@ ["jude","Jude"],["revelation","Re"] ]); - // Numbered-series acceptance (prose abbreviations like "2 Sam.", "1 Chron.", "2 Cor.", "1 Thes.", "2 Tim.", "1 Pet.", "1 Jn.") + // Common short full-name forms (with or without period) → WOL code + const ALIAS = new Map([ + // OT shorts + ["gen","Ge"],["exod","Ex"],["lev","Le"],["num","Nu"],["deut","De"], + ["josh","Jos"],["judg","Jg"],["ps","Ps"],["prov","Pr"],["eccl","Ec"],["song","Ca"],["cant","Ca"], + ["isa","Isa"],["jer","Jer"],["lam","La"],["ezek","Eze"],["dan","Da"],["hos","Ho"],["joel","Joe"], + ["amos","Am"],["obad","Ob"],["jon","Jon"],["mic","Mic"],["nah","Na"],["hab","Hab"],["zeph","Zep"], + ["hag","Hag"],["zech","Zec"],["mal","Mal"], + // NT shorts + ["matt","Mt"],["mark","Mr"],["luke","Lu"],["john","Joh"],["acts","Ac"],["rom","Ro"], + ["gal","Ga"],["eph","Eph"],["phil","Php"],["col","Col"],["heb","Heb"],["jas","Jas"], + ["jude","Jude"],["rev","Re"] + ]); + + // Numbered-series prose forms like "2 Sam.", "1 Chron.", "2 Cor.", "1 Thes.", "2 Tim.", "1 Pet.", "1 Jn." const NUMBERED = [ { prefixes: ["sam","samu","samuel"], codes: {1:"1Sa",2:"2Sa"} }, { prefixes: ["ki","king","kings","kgs"], codes: {1:"1Ki",2:"2Ki"} }, @@ -231,15 +245,18 @@ } function lookupBookCode(bookRaw) { - // Trim and strip trailing period(s), collapse whitespace + // 1) trim, strip trailing periods, collapse spaces let b = bookRaw.trim().replace(/\.+$/, "").replace(/\s+/g, " "); + const lower = b.toLowerCase(); - // 1) Full-name match (case-insensitive) - const fullKey = b.toLowerCase(); - if (FULL.has(fullKey)) return FULL.get(fullKey); + // 2) Full-name match + if (FULL.has(lower)) return FULL.get(lower); - // 2) Numbered-series prose abbreviations: e.g., "2 Sam", "1 Chron", "2 Cor", "1 Thes", "2 Tim", "1 Pet", "1 Jn" - const m = b.toLowerCase().match(/^([1-3])\s*([a-z]+)$/); + // 3) Short full-name alias (un-numbered) + if (ALIAS.has(lower)) return ALIAS.get(lower); + + // 4) Numbered series, prose short forms (e.g., "2 Sam", "1 Chron", "1 Jn") + const m = lower.match(/^([1-3])\s*([a-z]+)$/); if (m) { const num = parseInt(m[1], 10); const base = m[2]; @@ -251,17 +268,19 @@ } } - // 3) WOL abbreviation (allow optional space after number and allow trailing period) + // 5) WOL abbreviations (allow optional space after number) const abbr = b.replace(/^([1-3])\s+([A-Za-z]+)/, (_, n, letters) => n + letters); if (WOL.has(abbr)) return abbr; - // Also try without spaces just in case const abbrTight = b.replace(/\s+/g, ""); if (WOL.has(abbrTight)) return abbrTight; return null; } - // Chapter only | chapter:verses | lists | ranges | cross-chapter range + // Accept: + // - chapter only: "Ps 23" + // - chapter:verse list: "1 John 4:8, 16, 19" + // - verse ranges and cross-chapter ranges: "Joh 3:16-4:2", "Ro 12:1-3, 5" const versesRe = /^(\d{1,3})$|^(\d{1,3}):\s*(\d{1,3}(?:\s*-\s*(?:\d{1,3}|\d{1,3}:\d{1,3}))?(?:\s*,\s*\d{1,3}(?:\s*-\s*(?:\d{1,3}|\d{1,3}:\d{1,3}))?)*)$/;