Module:VerseCalculations
From Psalms: Layer by Layer
Documentation for this module may be created at Module:VerseCalculations/doc
local p = {} -- Function to process verse numbers and adjust for letter suffixes local function normalizeV(verse) -- Extract the base number and optional letter suffix local baseNumber, letters = verse:match("^(%d+)([a-z]*)$") if baseNumber then baseNumber = tonumber(baseNumber) or 0 -- Convert base number to integer if letters ~= "" then local letterValue = 0 for i = 1, #letters do local char = letters:sub(i, i) letterValue = letterValue + (char:byte() - string.byte("a") + 1) * (0.1 ^ i) -- Scale each letter's value end baseNumber = baseNumber + letterValue end return baseNumber end return "Error: Invalid verse format" end function p.normalizeVerse(frame) local verse = nil if frame.args then verse = frame.args[1] end if not verse then verse = frame end return normalizeV(verse) end function p.normalizeVerse2(frame) local verse = nil if frame.args then verse = frame.args[1] end if not verse then verse = frame end return normalizeV(verse) * 10 end function p.rangeMinimum(frame) -- Ensure input is a string local input = frame.args[1] or "" -- Normalize and clean the input string local cleanInput = input:lower() :gsub("vv%.?", "") -- Remove "vv." :gsub("v%.?", "") -- Remove "v." :gsub("verses", "") -- Remove "verses" :gsub("verse", "") -- Remove "verse" (handles singular form) :gsub("%s+", " ") -- Normalize spaces :gsub("^%s*(.-)%s*$", "%1") -- Trim leading/trailing spaces -- Match different range formats (supports multi-digit numbers and suffixes like "123b") local startVerse, endVerse = cleanInput:match("(%d+%a*)%s*-%s*(%d+%a*)") -- Handles "100-123b" if not startVerse then startVerse, endVerse = cleanInput:match("(%d+%a*)%s+to%s+(%d+%a*)") -- Handles "3 to 5" end -- Handle single verse (e.g., "verse 3", "v. 100") if not startVerse then startVerse = cleanInput:match("(%d+%a*)") return normalizeV(startVerse) -- endVerse = startVerse -- Single verse means start = end end -- Return extracted values or error if no match if startVerse and endVerse then return normalizeV(startVerse) else return "Error: Could not extract range" end end function p.rangeMaximum(frame) -- Ensure input is a string local input = frame.args[1] or "" -- Normalize and clean the input string local cleanInput = input:lower() :gsub("vv%.?", "") -- Remove "vv." :gsub("v%.?", "") -- Remove "v." :gsub("verses", "") -- Remove "verses" :gsub("verse", "") -- Remove "verse" (handles singular form) :gsub("%s+", " ") -- Normalize spaces :gsub("^%s*(.-)%s*$", "%1") -- Trim leading/trailing spaces -- Match different range formats (supports multi-digit numbers and suffixes like "123b") local startVerse, endVerse = cleanInput:match("(%d+%a*)%s*-%s*(%d+%a*)") -- Handles "100-123b" if not startVerse then startVerse, endVerse = cleanInput:match("(%d+%a*)%s+to%s+(%d+%a*)") -- Handles "3 to 5" end -- Handle single verse (e.g., "verse 3", "v. 100") if not startVerse then startVerse = cleanInput:match("(%d+%a*)") endVerse = startVerse -- Single verse means start = end end -- Return extracted values or error if no match if endVerse then return normalizeV(endVerse) else return "Error: Could not extract range" end end function p.expandVerses(frame) local input = frame.args[1] or "" local output = {} local seen = {} -- Remove common verse prefixes input = input:gsub("^[Vv][Vv]?%.?%s*", "") input = input:gsub("^[Vv]erse?s?%s*", "") input = input:gsub("%s+and%s+", ", ") for part in input:gmatch("[^,]+") do part = part:match("^%s*(.-)%s*$") -- Trim whitespace -- Handle range (e.g. "44a-45b") local start_v, end_v = part:match("^(%d+)[a-zA-Z]*%s*%-%s*(%d+)[a-zA-Z]*$") if start_v and end_v then start_v, end_v = tonumber(start_v), tonumber(end_v) if start_v and end_v then for i = start_v, end_v do if not seen[i] then table.insert(output, i) seen[i] = true end end end else -- Single value: extract just the number part local num = part:match("^(%d+)") num = tonumber(num) if num and not seen[num] then table.insert(output, num) seen[num] = true end end end return table.concat(output, ", ") end return p