Module:GHG

From Wikisource
Jump to navigation Jump to search
Documentation icon Module documentation[view] [edit] [history] [purge]

This module is a work in progress to reimplement Gesenius' Hebrew Grammar templates in Lua. This will allow adding new functionality, such as linking to any verse in the Hebrew Bible in the Hebrew Wikisource, and it will allow easier porting of this functionality to editions of Wikisource in other languages.

The plan for now is to keep using the templates and to implement the internal functions, such as {{GHGpage-calc}} and {{GHGbible-ref/linker}} in Lua. At this stage the module will be used in the templates and not directly in pages. At a later stage the templates may be completely deprecated.

local p = {}

-- Begin things that need localization
SCANNED_FILE_NAME = "Gesenius' Hebrew Grammar (1910 Kautzsch-Cowley edition).djvu"

-- See also:
-- * romanPages in p._page
-- * "Invalid book name"

-- End things that need localization

function p._pageCalc(number)
	romanPages = {
		i = 5,
		ii = 6,
		iii = 7,
		iv = 8,
		v = 9,
		vi = 10,
		vii = 11,
		viii = 12,
		ix = 13,
		x = 14,
		xi = 15,
		xii = 16,
		xiii = 17,
		xiv = 18,
		xv = 19,
		xvi = 20,
		xviii = 22,
		xix = 23
	}

	if (romanPages[number]) then
		return romanPages[number]
	end

	return(number + 24)
end

function p._page(number)
	internalNumber = p._pageCalc(number)

	return "[[Page:" .. SCANNED_FILE_NAME .. "/" .. internalNumber .. "|" .. number .. "]]"
end

function p.page(frame)
	return p._page(frame.args[1])
end

function p.pages(frame)
	section = frame.args["section"]

	layout = frame:expandTemplate{
		title = "Default layout",
		args = { "Layout 2" }
	}
	pagesTag = frame:extensionTag{
		name = "pages",
		content = "",
		args = {
			index = SCANNED_FILE_NAME,
			from = p._pageCalc(frame.args["from"]),
			to = p._pageCalc(frame.args["to"]),
			fromsection = section,
			tosection = section
		}
	}

	return layout .. pagesTag
end

-- Converts a number to a Hebrew ("Gematria") number.
-- This doesn't cover all the Hebrew numbers, but only what is needed for
-- Bible chapters and verses.
function toHebrewNumber(numberStr)
	hebrewNumber = ""

	numberNum = tonumber(numberStr, 10)

	if (numberNum >= 100) then
		hebrewNumber = hebrewNumber .. "ק"
	end

	modulo100 = numberNum % 100
	if (modulo100 == 15) then
		return hebrewNumber .. "טו"
	end

	if (modulo100 == 16) then
		return hebrewNumber .. "טז"
	end

	onesNumber = numberNum % 10
	tensNumber = math.floor(modulo100 / 10)

	tensLetter = {
		"י",
		"כ",
		"ל",
		"מ",
		"נ",
		"ס",
		"ע",
		"פ",
		"צ"
	}

	if (tensNumber ~= 0) then
		hebrewNumber = hebrewNumber .. tensLetter[tensNumber]
	end

	onesLetter = {
		"א",
		"ב",
		"ג",
		"ד",
		"ה",
		"ו",
		"ז",
		"ח",
		"ט"
	}

	if (onesNumber ~= 0) then
		hebrewNumber = hebrewNumber .. onesLetter[onesNumber]
	end

	return hebrewNumber
end

-- Converts a number to a Greek numeral.
-- This doesn't cover all the Greek numbers, but only what is needed for
-- Bible chapters and verses.
function toGreekNumber(numberStr)
	numberNum = tonumber(numberStr, 10)
	greekNumber = ""

	onesLetter = { "Α", "Β", "Γ", "Δ", "Ε", "ΣΤ", "Ζ", "Η", "Θ" }
	tensLetter = { "Ι", "Κ", "Λ", "Μ", "Ν", "Ξ",  "Ο", "Π", "ϟ" }

	if (numberNum >= 10) then
		tensNumber = math.floor(numberNum / 10)
		greekNumber = greekNumber .. tensLetter[tensNumber]
	end

	onesNumber = numberNum % 10

	if (onesNumber > 0) then
		greekNumber = greekNumber .. onesLetter[onesNumber]
	end

	greekNumber = greekNumber .. "'"

	return greekNumber
end

function verseLink(targetLanguage, linkTargetTitle, chapter, verseStr)
	verseNum = string.match(verseStr, "[0-9]+")

	verseLinkWikitext = "[[:" .. targetLanguage .. ":" .. linkTargetTitle
	if (targetLanguage == "he") then
		verseLinkWikitext = verseLinkWikitext .. " " .. toHebrewNumber(chapter) ..
			" " .. toHebrewNumber(verseNum) .. "|" .. verseStr

		if (string.match(verseStr, "f$")) then
			verseLinkWikitext = verseLinkWikitext .. "."
		end
		verseLinkWikitext = verseLinkWikitext .. "]]"
	else
		-- Greek Wikisource doesn't support verses at the moment
	end

	return verseLinkWikitext
end

function verseLinks(targetLanguage, linkTargetTitle, chapter, versesStr)
	-- Greek Wikisource and Hebrew Sirac don't support verses at the moment
	if (targetLanguage == "el" or linkTargetTitle == "בן סירא") then
		return versesStr
	end

	formattedLinks = {}

	verseStrs = mw.text.split( versesStr, "%." )

	for i, verse in ipairs(verseStrs) do
		if (verse ~= "") then
			formattedLinks[i] = verseLink(
				targetLanguage,
				linkTargetTitle,
				chapter,
				verse
			)
		end
	end

	wholeVersesString = table.concat(formattedLinks, ".")

	-- Remove repeated periods (can appear after f./ff.)
	wholeVersesString = mw.ustring.gsub( wholeVersesString, "%.%]%]%.", "]].", n )

	-- Remove spaces in the beginning of links
	wholeVersesString = mw.ustring.gsub( wholeVersesString, "%| ", "|", n )
	wholeVersesString = mw.ustring.gsub( wholeVersesString, "f%]%]%.%[%[", "f]]. [[", n )

	return wholeVersesString
end

function bibleRefContent(book, chapter, verse, hideBook, fullSizeVerse, actualBook, frame)
	linkTargetBook = {
		["Gn"] = "בראשית",
		["Gen"] = "בראשית",
		["Gn."] = "בראשית",
		["Ex"] = "שמות",
		["Lv"] = "ויקרא",
		["Lev"] = "ויקרא",
		["Lv."] = "ויקרא",
		["Nu"] = "במדבר",
		["Dt"] = "דברים",
		["Dt."] = "דברים",
		["Jos"] = "יהושע",
		["Ju"] = "שופטים",
		["Jud"] = "שופטים",
		["Ju."] = "שופטים",
		["1 S"] = "שמואל א",
		["2 S"] = "שמואל ב",
		["1 K"] = "מלכים א",
		["2 K"] = "מלכים ב",
		["Is"] = "ישעיהו",
		["Is."] = "ישעיהו",
		["Jer"] = "ירמיהו",
		["Je"] = "ירמיהו",
		["Jer."] = "ירמיהו",
		["Ez"] = "יחזקאל",
		["Ez."] = "יחזקאל",
		["Eze"] = "יחזקאל",
		["Hos"] = "הושע",
		["Ho"] = "הושע",
		["Jo"] = "יואל",
		["Joel"] = "יואל",
		["Am"] = "עמוס",
		["Amos"] = "עמוס",
		["Ob"] = "עובדיה",
		["Jon"] = "יונה",
		["Jn"] = "יונה",
		["Mi"] = "מיכה",
		["Mic"] = "מיכה",
		["Na"] = "נחום",
		["Nah"] = "נחום",
		["Hb"] = "חבקוק",
		["Hab"] = "חבקוק",
		["Zp"] = "צפניה",
		["Hag"] = "חגי",
		["Zc"] = "זכריה",
		["Mal"] = "מלאכי",
		["Mal."] = "מלאכי",
		["Ps"] = "תהלים",
		["PsPs"] = "תהלים",
		["Pr"] = "משלי",
		["Jb"] = "איוב",
		["Job"] = "איוב",
		["Ct"] = "שיר השירים",
		["Cant"] = "שיר השירים",
		["Ru"] = "רות",
		["La"] = "איכה",
		["Lam"] = "איכה",
		["Ec"] = "קהלת",
		["Est"] = "אסתר",
		["Dn"] = "דניאל",
		["Ezr"] = "עזרא",
		["Neh"] = "נחמיה",
		["Ne"] = "נחמיה",
		["1 Ch"] = "דברי הימים א",
		["1 Chr"] = "דברי הימים א",
		["2 Ch"] = "דברי הימים ב",
		["2 Chr"] = "דברי הימים ב",
		["3 Ezr"] = "Έσδρας_Α",
		["1 Macc."] = "Μακκαβαίων_Α'",
		-- The only reference that uses Ecclus is relevant for the Hebrew text
		["Ecclus"] = "בן סירא",
		["Sirac"] = "Σοφία_Σειράχ",
		["St. Mark"] = "Κατά Μάρκον",
		["John"] = "Κατά Ιωάννην",
		["Acts"] = "Πράξεις των Αποστόλων",
		["Rv"] = "Αποκάλυψις Ιωάννου"
	}

	if (
		(not linkTargetBook[book]) or
		(actualBook ~= "" and not linkTargetBook[actualBook])
	) then
		return "'''''[[Template:GHGbible-ref/invalid book|Invalid book name]]'''''"
	end

	greekBook = {
		["3 Ezr"] = true,
		["1 Macc."] = true,
		["Sirac"] = true,
		["Mark"] = true,
		["St. Mark"] = true,
		["John"] = true,
		["Acts"] = true,
		["Rv"] = true
	}

	-- At least one abbreviation is known to be ambiguous in the 1910 edition:
	-- Jn may mean both Jonah and John (New Testament).
	-- There may be others.
	if (actualBook == "") then
		linkTargetTitle = linkTargetBook[book]
	else
		linkTargetTitle = linkTargetBook[actualBook]
	end

	if (greekBook[book] or greekBook[actualBook]) then
		targetLanguage = "el"
	else
		targetLanguage = "he"
	end

	linkBeginning = "[[:" .. targetLanguage .. ":"
	linkEnding = "]]"

	bibleRef = ""

	if (hideBook ~= "completely") then
		if (hideBook == "") then
			if (book == "Ps") then
				displayBook = "ψ"
			elseif (book == "PsPs") then
				displayBook = "ψψ"
			else
				displayBook = book
			end
	
			bibleRef = bibleRef .. displayBook .. " "
		end
	
		-- Obadiah has only one chapter, so the chapter number is not needed
		-- and only the verse number is shown.
		-- All the existing references to Obadiah have a verse.
		if (book == "Ob") then
			bibleRef = bibleRef .. linkBeginning .. linkTargetTitle .. " א " ..
				toHebrewNumber(verse) .. "|" .. verse .. linkEnding
		end
	
		bibleRef = bibleRef .. linkBeginning .. linkTargetTitle
	
		if (targetLanguage == "he") then
			bibleRef = bibleRef .. " " .. toHebrewNumber(chapter)
		else
			-- This works only with some Greek books for now.
			-- See el:Συζήτηση:Η_Αγία_Γραφή#Numbering_of_chapters
			bibleRef = bibleRef .. "#Κεφάλαιον " .. toGreekNumber(chapter)
		end
	
		bibleRef = bibleRef .. "|"
		
		if (string.match(hideBook, "^v")) then
			bibleRef = bibleRef .. hideBook .. "."
		else
			bibleRef = bibleRef .. chapter
		end
	
		bibleRef = bibleRef .. linkEnding
	end

	if (verse ~= "") then
		verseLinksContent = verseLinks(
			targetLanguage,
			linkTargetTitle,
			chapter,
			verse
		)

		if (fullSizeVerse == "") then
			verseLinksContent = "<sup>" .. verseLinksContent .. "</sup>"
		end

		bibleRef = bibleRef .. verseLinksContent
	end

	return bibleRef
end

function p._bibleRef(book, chapter, verse, hideBook, fullSizeVerse, actualBook, frame)
	content = bibleRefContent(
		book,
		chapter,
		verse,
		hideBook,
		fullSizeVerse,
		actualBook,
		frame
	)

	formattedContent = frame:expandTemplate{
		title = "nowrap",
		args = { content }
	}

	return formattedContent
end

function p.bibleRef(frame)
	book = frame.args["book"]
	chapter = frame.args["chapter"]
	verse = frame.args["verse"]
	hideBook = frame.args["hidebook"]
	fullSizeVerse = frame.args["fullsizeverse"]
	actualBook = frame.args["actualbook"]

	return p._bibleRef(book, chapter, verse, hideBook, fullSizeVerse, actualBook, frame)
end

function p._heb(text, translate, pron, en, indexitem, frame)
	tag = "span" -- Will probably also support <div> in the future
	hebElement = mw.html.create( tag )
	hebElement
		:wikitext( text )
		:attr( "lang", "hbo" )
		:attr( "dir", "rtl" )
		:addClass( "he_GHG" )
		-- Calling HTML class "he_GHG" to render Hebrew text,
		-- which is available at Template:GHGheb/styles.css.

	if (indexitem) then
		hebElement:addClass( "indexitem" )
	end

	hebText = tostring( hebElement )

	if (pron ~= "") then
		hebText = hebText .. " " .. p._pron(pron, frame)
	end
	
	if (translate ~= "") then
		hebText = hebText .. " " .. p._translate(translate, en, "", frame)
	end

	return hebText
end

function p.heb(frame)
	text = frame.args["text"]
	translate = frame.args["translate"]
	pron = frame.args["pron"]
	en = frame.args["en"]
	indexitem = ( frame.args["indexitem"] == "1" )

	return p._heb(text, translate, pron, en, indexitem, frame)
end

function p._pron(text, frame)
	return frame:expandTemplate{
		title = "nowrap",
		args = { "''" .. text .. "''" }
	}
end

function p.pron(frame)
	text = frame.args[1]

	return p._pron(text, frame)
end

function p._translate(text, en, lang, frame)
	translation = "''" .. text .. "''"
	
	if (en ~= "") then
		if ( lang == "" ) then
			lang = "la"
		end
		
		translatedElement = mw.html.create( "span" )
		translatedElement
			:wikitext( translation )
			:attr( "lang", lang )
			:attr( "title", en )
			:css( "border-bottom", "1px dotted" )
			
		translation = tostring(translatedElement)
	end

	return translation
end

function p.translate(frame)
	text = frame.args[1]
	en = frame.args["en"]
	lang = frame.args["lang"]

	return p._translate(text, en, lang, frame)
end

return p