Module:Alhatorah/sandbox

MyWikiBiz, Author Your Legacy — Saturday July 20, 2024
Jump to navigationJump to search

Documentation for this module may be created at Module:Alhatorah/sandbox/doc

-- This module implements Template:Alhatorah. Based on Template:Bibleverse
local p = {}

--possible book inputs, based on Chicago Manual
local book_aliases = {
	['Bereshit'] = {'genesis', 'gen', 'gn'},
	['Shemot'] = {'exodus', 'exod', 'ex'},
	['Vayikra'] = {'leviticus', 'lev', 'lv'},
	['Bemidbar'] = {'numbers', 'num', 'nm'},
	['Devarim'] = {'deuteronomy', 'deut', 'dt'},
	['Yehoshua'] = {'joshua', 'josh' , 'jo'},
	['Shofetim'] = {'judges', 'judg', 'jgs'},
	['Shemuel I'] = {'1_samuel', '1sam', '1sm', 'I_samuel'},
	['Shemuel II'] = {'2_samuel', '2sam', '2sm', 'II_samuel'},
	['Melakhim I'] = {'1_kings', '1kgs', 'I_kings'},
	['Melakhim II'] = {'2_kings', '2kgs', 'II_kings'},
	['Yeshayahu'] = {'isaiah', 'isa', 'is'},
	['Yirmeyahu'] = {'jeremiah', 'jer'},
	['Yechezkel'] = {'ezekiel', 'ezek', 'ez'},
	['Hoshea'] = {'hosea', 'hos'},
	['Yoel'] = {'joel', 'jl'},
	['Amos'] = {'amos', 'am'},
	['Ovadyah'] = {'obadiah', 'obad', 'ob'},
	['Yonah'] = {'jonah', 'jon'},
	['Mikhah'] = {'micah', 'mic', 'mi'},
	['Nachum'] = {'nahum', 'nah', 'na'},
	['Chavakkuk'] = {'habakkuk', 'hab', 'hb'},
	['Zephanyah'] = {'zephaniah', 'zeph', 'zep'},
	['Chaggai'] = {'haggai', 'hag', 'hg'},
	['Zekharyah'] = {'zechariah', 'zech', 'zec'},
	['Malakhi'] = {'malachi', 'mal'},
	['Tehillim'] = {'psalms', 'ps', 'pss', 'psalm'},
	['Mishlei'] = {'proverbs', 'prov', 'prv'},
	['Kohelet'] = {'ecclesiastes', 'eccles', 'eccl', 'qoheleth'},
	['Shir HaShirim'] = {'song_of_solomon', 'songofsol', 'songofsongs', 'song', 'sg', 'canticles', 'canticleofcanticles'},
	['Eikhah'] = {'lamentations', 'lam'},
	['Rut'] = {'ruth', 'ru'},
	['Esther'] = {'esther', 'est'},
	['Iyyov'] = {'job', 'jb'},
	['Daniel'] = {'daniel', 'dan', 'dn'},
	['Divrei HaYamim I'] = {'1_chronicles', '1chron', '1chr', 'I_chronicles'},
	['Divrei HaYamim II'] = {'2_chronicles', '2chron', '2chr', 'II_chronicles'},
	['Ezra'] = {'ezra', 'ezr'},
	['Nechemyah'] = {'nehemiah', 'neh'},
}

--these books only have one chapter, have to be handled differently
local no_chapters = {
	['obadiah'] = true,
}

--changes to the version name to be used in urls, only if necessary
local site_version_tbl = {
	mechon_mamre = {
		he = 'p/pt/pt',
		jps = 'e/et/et',
	},
}

local function trimArg(text)
	if type(text) == 'string' then
		text = text:match('(%S.-)%s*$')  --trimmed text or nil if empty
	end
	return text
end

local function valueExists(tbl, value)
	for _, v in pairs(tbl) do
		if value == v then
			return true
		end
	end
	return false
end

local function titlecase(arg)
	-- http://grammar.yourdictionary.com/capitalization/rules-for-capitalization-in-titles.html
	-- recommended by The U.S. Government Printing Office Style Manual:
	-- 'Capitalize all words in titles of publications and documents,
	-- except a, an, the, at, by, for, in, of, on, to, up, and, as, but, or, and nor.'
	local alwayslower = {
		['a'] = true, ['an'] = true, ['the'] = true,
		['and'] = true, ['but'] = true, ['or'] = true, ['for'] = true,
		['nor'] = true, ['on'] = true, ['in'] = true, ['at'] = true, ['to'] = true,
		['from'] = true, ['by'] = true, ['of'] = true, ['up'] = true,
	}
	local words = mw.text.split(mw.text.trim(arg or ''), '_')
	for i, s in ipairs(words) do
		s = string.lower(s)
		if i > 1 then
			if not alwayslower[s] then
				s = mw.getContentLanguage():ucfirst(s)
			end
		else
			s = mw.getContentLanguage():ucfirst(s)
		end
		words[i] = s
	end
	return table.concat(words, '_')
end

function p.main(frame)
	local targs = frame:getParent().args
	local args = {}
	for _, param in ipairs({1, 2, 3, 4, 5, 'nobook'}) do
		args[param] = trimArg(targs[param])
	end
	local default_version = 'nrsv'
	local input_book = ''
	local ref = ''
	local commentary = ''
	local text = ''
	local mainspace = mw.title.getCurrentTitle():inNamespaces(0)
	if args[1] == nil or args[2] == nil or tonumber(args[1]) ~= nil then
		-- first argument is a numeric prefix and second is book name
		input_book = trimArg((args[1] or '') .. ' ' .. (args[2] or '')) or ''
		ref = args[3] or ''
		commentary = args[4] or ''
		text = args[5] or trimArg((commentary .. ' to ' .. input_book .. ' ' .. ref))
	else
		-- first argument is the whole book name
		input_book = args[1] or ''
		ref = args[2] or ''
		commentary = args[3] or ''
		text = args[4] or (commentary .. ' to ' .. input_book .. ' ' .. ref)
	end
	if args.nobook == 'yes' then
		text = ref
	end
	text = text:gsub('-', '–')  --change hyphens to en dashes (3:2-5 → 3:2–5)

	local book = input_book:gsub('%p', ''):gsub(' ', '_')
	book = mw.ustring.lower(book)

	local book_found = false
	local standard = book:gsub('_', '')
	for full_book, aliases in pairs(book_aliases) do
		if standard == full_book:gsub('_', '') or valueExists(aliases, standard) then
			book = full_book
			book_found = true
			break
		end
	end

	local urlpat = 'https://mg.alhatorah.org/Dual/_commentary/_book/_schap._svers#m7e3n7'

	local split_ref = mw.text.split(ref, '[-–—]')       --split the ref into the part before and after the dash/hyphen
	local s_ref = mw.text.split(split_ref[1], '%p')     --any punctuation can be used to separate chapter from verse
	local e_ref = split_ref[2] or split_ref[1]
	e_ref = mw.text.split(e_ref, '%p')
	for i, v in ipairs(s_ref) do s_ref[i] = v:gsub('%D', '') end  --remove any non-numeric character (such as f)
	for i, v in ipairs(e_ref) do e_ref[i] = v:gsub('%D', '') end

	local e_chap, e_vers, s_chap, s_vers
	local chapter_only = not s_ref[2]
	if no_chapters[book] then
		chapter_only = false
		s_chap = 1
		s_vers = s_ref[2] or s_ref[1] or 1   --verse 3 can be specified as "3" or "1:3"
		e_chap = 1
		e_vers = e_ref[2] or e_ref[1] or 1
	else
		s_chap = s_ref[1] or 1
		s_vers = s_ref[2] or 1
		if e_ref[2] or not s_ref[2] then     --chapter-chapter or chapter(:verse)?-chapter:verse
			e_chap = e_ref[1] or s_chap
		else                                 --chapter:verse-verse
			e_chap = s_chap
		end
		e_vers = e_ref[2] or e_ref[1] or s_vers
	end
	
	book = titlecase(book)  --title case looks better at oremus where they display the input

	local v_range
	if chapter_only then
		if e_chap == s_chap then
			v_range = s_chap
		else
			v_range = s_chap .. '–' .. e_chap
		end
	else
		if e_chap == s_chap and e_vers == s_vers then
			v_range = s_chap ..':' .. s_vers
		elseif e_chap == s_chap then
			v_range = s_chap .. ':' .. s_vers .. '–' .. e_vers
		else
			v_range = s_chap .. ':' .. s_vers .. '–' .. e_chap .. ':' .. e_vers
		end
	end

	local url = urlpat:gsub('_%l+', {  --get the components into the url
					_book    = book,
					_schap   = s_chap,
					_svers   = s_vers,
					_echap   = e_chap,
					_evers   = e_vers,
					_vrange  = v_range,
					_commentary = commentary,
				})

	local fulllink
	fulllink = '[' .. url .. ' ' .. text .. ']'
	
	if mainspace then
		if not book_found then
			table.insert(errors, '<span style="color:red">Template:Bibleverse with invalid book</span>[[Category:Pages with Bible book errors]]')
		end
		if version_num then
			table.insert(errors, '[[Category:Pages with numeric Bible version references]]')
		end
	end
	
	return fulllink --.. table.concat(errors)
end

return p