יחידה:ספרי קודש
ניתן ליצור תיעוד על היחידה הזאת בדף יחידה:ספרי קודש/תיעוד
--[[
Module for handling Hebrew numerical values and scripture references
Provides functionality for converting between Hebrew letters and numbers,
and validating scripture references.
]]
local p = {}
-- Cached MediaWiki functions
local ustring = mw.ustring
local len = ustring.len
local sub = ustring.sub
local find = ustring.find
-- Constants
local MAX_HEBREW_NUMBER = 899
local USER_NAMESPACE = 3
local ARTICLE_NAMESPACE = 0
local TEMPLATE_NAME = ""
-- Hebrew number conversion table
local HEBREW_NUMBERS = {
["א"] = 1, ["ב"] = 2, ["ג"] = 3, ["ד"] = 4, ["ה"] = 5,
["ו"] = 6, ["ז"] = 7, ["ח"] = 8, ["ט"] = 9, ["י"] = 10,
["כ"] = 20, ["ל"] = 30, ["מ"] = 40, ["נ"] = 50, ["ס"] = 60,
["ע"] = 70, ["פ"] = 80, ["צ"] = 90, ["ק"] = 100, ["ר"] = 200,
["ש"] = 300, ["ת"] = 400, ["תק"] = 500, ["תר"] = 600,
["תש"] = 700, ["תת"] = 800
}
-- Error category prefix based on namespace
local function getErrorCategory()
local currentTitle = mw.title.getCurrentTitle()
if currentTitle["namespace"] == ARTICLE_NAMESPACE then
return "[[קטגוריה:שגיאות קריאה לתבניות ספרי קודש]] "
end
return "[[קטגוריה:שגיאות קריאה לתבניות ספרי קודש מחוץ למרחב הערכים]] "
end
-- Error handling
local function logAndThrowError(message)
local errorPrefix = getErrorCategory() .. " (בקריאה ל[[תבנית:" .. TEMPLATE_NAME .. "]]) "
mw.log(message)
error(errorPrefix .. message, 0)
end
-- String utility functions
local function safeLen(s)
return s and len(s) or 0
end
local function safeSub(str, from, to)
return sub(str, from, to)
end
local function safeFind(str, what, where)
return find(str, what, where, true) or 0
end
-- Hebrew number conversion functions
local function fromHebrewNumber(num)
local result = 0
local str = num
while safeLen(str) > 0 do
local firstChar = safeSub(str, 1, 1)
-- Check for invalid characters
if ustring.byte(firstChar) == 226 then
logAndThrowError("יש להקליד את כל התבנית מחדש")
end
local value = HEBREW_NUMBERS[firstChar]
if not value then
if firstChar == " " then
logAndThrowError("רווח מיותר בתוך פרמטר " .. firstChar)
else
logAndThrowError("אות עברית לא ידועה " .. firstChar)
end
end
result = result + value
str = safeSub(str, 2, safeLen(str))
end
return result
end
local function toHebrewDigit(digit)
if digit == 0 then
return ""
end
for hebrew, value in pairs(HEBREW_NUMBERS) do
if digit == value then
return hebrew
end
end
logAndThrowError("ספרה" .. digit .. "לא נמצאה")
end
local function toHebrewNumber(num)
if num > MAX_HEBREW_NUMBER then
logAndThrowError("המספר " .. num .. " גדול מדי")
end
local units = num % 10
local tens = (((num - units) / 10) % 10) * 10
local hundreds = num - units - tens
local result = {
toHebrewDigit(hundreds),
toHebrewDigit(tens),
toHebrewDigit(units)
}
-- Special cases for numbers 15 and 16
if tens == 10 then
if units == 5 then
result[2] = "ט"
result[3] = "ו"
elseif units == 6 then
result[2] = "ט"
result[3] = "ז"
end
end
return table.concat(result)
end
-- Validation functions
local function validateHebrewNumber(hebrewNum)
if hebrewNum == "שדמ" then
return fromHebrewNumber(hebrewNum)
elseif hebrewNum == "פתיחתא" then
return 0
end
local numericValue = fromHebrewNumber(hebrewNum)
if toHebrewNumber(numericValue) == hebrewNum then
return numericValue
end
logAndThrowError("מספר עברי " .. hebrewNum .. " לא מוכר")
end
local function validateBook(book, names, renames, syntax, suggestions)
local originalName = book
-- Check for invalid characters
local str = book
while safeLen(str) > 0 do
if ustring.byte(safeSub(str, 1, 1)) == 226 then
logAndThrowError("יש להקליד את כל התבנית מחדש")
end
str = safeSub(str, 2, safeLen(str))
end
-- Check for renamed books
book = renames[book] or book
-- Look up book in names table
for n, nn in pairs(names) do
if nn == book then
return n
end
end
-- Check for common errors
if safeFind(book, syntax["book"] .. " ") == 1 then
logAndThrowError('יש להשמיט את מילה "' .. syntax["book"] .. '" מתוך הפרמטר')
end
if suggestions[book] then
logAndThrowError("אין " .. syntax["book"] .. " " .. originalName ..
", האם הכוונה היא ל" .. suggestions[book] .. "?")
end
logAndThrowError("אין " .. syntax["book"] .. " " .. book)
end
-- Main function
function p.main(frame)
-- Skip processing in user conversation namespace
if mw.title.getCurrentTitle()["namespace"] == USER_NAMESPACE then
return
end
TEMPLATE_NAME = frame.args["type"]
-- Load configuration
local input = require("יחידה:ספרי קודש/" .. frame.args["type"])
local names, renames, data = input[1], input[2], input[3]
local syntax, numbered = input[4], input[5]
local checkparam, suggestions = input[6], input[7]
local morechecks, getnumbers = input[8], input[9]
-- Validate required parameters
if not frame.args["book"] or frame.args["book"] == "" then
logAndThrowError("חסר שם ה" .. syntax["book"])
end
if not frame.args["chapter"] or frame.args["chapter"] == "" then
logAndThrowError("חסר מספר " .. syntax["chapter"])
end
-- Clean and validate parameters
local function cleanParameter(param)
return param and string.gsub(param, "['\"]", "") or ""
end
local book = validateBook(frame.args["book"], names, renames, syntax, suggestions)
local chapter = validateHebrewNumber(cleanParameter(frame.args["chapter"]))
local bookData = data[book]
local par = cleanParameter(frame.args["par"])
local par1 = cleanParameter(frame.args["par1"])
-- Validate chapter and paragraph ranges
if safeFind(frame.args["chapter"], '-') > 0 then
logAndThrowError("יש לציין מספר " .. syntax["chapter"] .. " אחד בלבד, ניתן להפריד באמצעות |")
end
if safeFind(par .. par1, '-') > 0 then
logAndThrowError("יש לציין מספר ".. syntax["par"] .. " אחד בלבד בכל פרמטר, ניתן להפריד באמצעות |")
end
-- Convert parameters to numbers
local parNum = par == "" and 1 or (getnumbers and tonumber(par) or validateHebrewNumber(par))
local par1Num = par1 == "" and 2 or (getnumbers and tonumber(par1) or validateHebrewNumber(par1))
-- Validate chapter and paragraph numbers
if (type(bookData) == "table" and chapter > #bookData) or
(type(bookData) == "number" and chapter > bookData) then
logAndThrowError("אין " .. syntax["chapter"] .. " " .. frame.args["chapter"]
.. " ב" .. syntax["book"] .. " " .. frame.args["book"])
end
if --[[type(bookData) ~= "number" and]] parNum > bookData[chapter] and par ~= "" then
logAndThrowError("אין " .. syntax["par"] .. " " .. par .. " ב" .. syntax["chapter"] .. " " ..
frame.args["chapter"] .. " ב" .. syntax["book"] .. " " .. frame.args["book"])
end
-- Additional validation checks
if par1 ~= "" then
if --[[type(bookData) ~= "number" and]] par1Num > bookData[chapter] then
logAndThrowError("אין " .. syntax["par1"] .. " " .. par1 .. " ב" .. syntax["chapter"] .. " " ..
frame.args["chapter"] .. " ב" .. syntax["book"] .. " " .. frame.args["book"])
end
if par1Num == parNum then
logAndThrowError("שני הפרמטרים המציינים אותו מספר " .. syntax["par"])
end
if par1Num < parNum then
logAndThrowError("יש לשים את ה" .. syntax["pars"] .. " בסדר עולה")
end
if par == "" then
logAndThrowError("אין לציין " .. syntax["par"] .. " סיום ללא " .. syntax["par"] .. " התחלה")
end
end
-- Parent frame parameter validation
local parentFrame = frame:getParent()
if parentFrame then
if parentFrame.args[tostring(numbered + 1)] then
logAndThrowError("יש להעביר לכל היותר " .. numbered .. " פרמטרים")
end
for param, value in pairs(parentFrame.args) do
if not checkparam(param) then
logAndThrowError('נמצא פרמטר לא בשימוש "' .. param .. '="')
end
end
end
-- Additional custom checks
if morechecks then
morechecks({book = frame.args["book"], chapter = chapter, fpar = par})
end
end
return p