Jump to content

Module:sem-arb-utilities

From Wiktionary, the free dictionary


local export = {}

local m_str_utils = require("Module:string utilities")

local m_utilities = require("Module:utilities")
local m_links = require("Module:links")
local m_headword = require("Module:headword")

local rsplit = m_str_utils.split
local rsubn = m_str_utils.gsub

local separator_langs = { ["mt"] = true, ["acy"] = true }
local color_langs = { ["mt"] = "red", ["ary"] = "red" }
local template_preview_per_langcode = { ["mt"] = "k-t-b", ["acy"] = "k-t-p" }
local lang
local sc

local function link(term, alt, id)
	if term == "" or term == "—" then
		return term
	else
		return m_links.full_link({
			term = term,
			alt = alt,
			lang = lang,
			id = id,
		})
	end
end

local radicals = {
	["Arab"] = {
		["ء"] = true,
		["ب"] = true,
		["ت"] = true,
		["ث"] = true,
		["ج"] = true,
		["ح"] = true,
		["خ"] = true,
		["د"] = true,
		["ذ"] = true,
		["ر"] = true,
		["ز"] = true,
		["س"] = true,
		["ش"] = true,
		["ص"] = true,
		["ض"] = true,
		["ط"] = true,
		["ظ"] = true,
		["ع"] = true,
		["غ"] = true,
		["ف"] = true,
		["ق"] = true,
		["ك"] = true,
		["ل"] = true,
		["م"] = true,
		["ن"] = true,
		["ه"] = true,
		["و"] = true,
		["ي"] = true,
		["گ"] = true,
		["چ"] = true,
		["پ"] = true,
	},
	["Latn"] = {
		["'"] = true,
		["b"] = true,
		["c"] = true,
		["ċ"] = true,
		["d"] = true,
		["δ"] = true,
		["f"] = true,
		["ġ"] = true,
		["g"] = true,
		["għ"] = true,
		["h"] = true,
		["ħ"] = true,
		["j"] = true,
		["k"] = true,
		["l"] = true,
		["m"] = true,
		["n"] = true,
		["p"] = true,
		["q"] = true,
		["r"] = true,
		["s"] = true,
		["ş"] = true,
		["t"] = true,
		["v"] = true,
		["w"] = true,
		["x"] = true,
		["y"] = true,
		["ż"] = true,
		["z"] = true,
		["θ"] = true,
	}
}

local function validateRoot(rootTable, joined_root)
	if type(rootTable) ~= "table" then
		error("rootTable is not a table", 2)
	end

	local len = #rootTable

	if len < 3 then
		error("Root must have at least three radicals.")
	end
	
	if sc == nil then
		 sc = lang:findBestScript(joined_root):getCode()
	end

	for i, radical in ipairs(rootTable) do
		if not radicals[sc][radical] then
			error("Unrecognized radical " .. radical .. " in " .. joined_root)
		end
	end
end

function export.root(frame)
	local output = {}
	local categories = {}
	local title = mw.title.getCurrentTitle()
	local namespace = title.nsText
	local fulltitle = title.fullText

	if frame.args["lang"] then
		lang = require("Module:languages").getByCode(frame.args["lang"])
	else
		error("Please provide a language code.")
	end

	local subpage = "Appendix:" .. lang:getCanonicalName() .. " roots/"
	local fulltitle = rsubn(fulltitle, rsubn(subpage, "([^%w])", "%%%1"), "")

	local params = {
		[1] = { list = true },
		["nocat"] = { type = "boolean" },
		["plain"] = { type = "boolean" },
		["notext"] = { type = "boolean" },
		["sense"] = {}
	}

	local args = require("Module:parameters").process(frame:getParent().args, params)
	local rootLetters = {}
	local roots = args[1]

	local plain = args["plain"]
	if frame.args["plain"] then
		plain = true
	end

	local langCode = lang:getCode()

	local separator = " "
	if separator_langs[langCode] then
		separator = "-"
	else
		separator = " "
	end

	local roots_len = #roots

	if #roots == 0 and namespace == "Template" then
		if template_preview_per_langcode[langCode] ~= nil then
			table.insert(rootLetters, rsplit(template_preview_per_langcode[langCode], separator))
		else
			table.insert(rootLetters, rsplit("ك ت ب", separator))
		end
	elseif #roots ~= 0 then
		for _, root in ipairs(roots) do
			table.insert(rootLetters, rsplit(root, separator))
		end
	else
		table.insert(rootLetters, rsplit(fulltitle, separator))
	end

	local joined_roots = {}
	for i, rootLetter in ipairs(rootLetters) do
		table.insert(joined_roots, table.concat(rootLetter, separator))
		validateRoot(rootLetter, joined_roots[i])
	end

	local sense = args["sense"]
	local sense_formatted = ""
	if sense ~= nil then
		sense_formatted = " (" .. sense .. ") "
	end

	if fulltitle == joined_roots[1] then
		if namespace == "" then
			error("The root page should be in the Appendix namespace. Please move it to : [[" ..
				subpage .. joined_roots[1] .. "]]")
		end

		if roots_len > 1 then
			error("There should be only one root.")
		end

		table.insert(output,
			m_headword.full_headword({ lang = lang, pos_category = "roots", categories = {}, heads = { fulltitle }, nomultiwordcat = true, noposcat = true }))

		if args["nocat"] then
			return table.concat(output)
		else
			return table.concat(output) .. table.concat(categories)
		end
	else
		local link_texts = {}
		local term_counts = {}

		for i, joined_root in ipairs(joined_roots) do
			local link_text = subpage .. joined_root
			table.insert(link_texts, link(link_text, joined_root .. sense_formatted, sense))
			table.insert(
				categories,
				m_utilities.format_categories(
					{ lang:getCanonicalName() .. " terms belonging to the root " .. joined_root .. sense_formatted },
					lang)
			)
			table.insert(term_counts,
				mw.site.stats.pagesInCategory(
					lang:getCanonicalName() .. " terms belonging to the root " .. joined_root .. sense_formatted, "pages")
			)
		end

		if args["nocat"] or plain then
			if args["nocat"] then
				return table.concat(link_texts, ", ")
			else
				return table.concat(link_texts, ", ") .. table.concat(categories)
			end
		else
			local link_text_output = ""
			for i, link_text in ipairs(link_texts) do
				link_text_output = link_text_output ..
					"\n|-\n| " .. link_text ..
					"\n|-\n| [[:Category:" ..
					lang:getCanonicalName() ..
					" terms belonging to the root " ..
					joined_roots[i] ..
					sense_formatted .. "|" .. term_counts[i] .. " term" .. (term_counts[i] == 1 and "" or "s") .. "]]\n"
			end
			
			local color = "grey"
			
			if color_langs[langCode] ~= nil then
				color = color_langs[langCode]
			end

			local wikicode = mw.getCurrentFrame():expandTemplate {
				title = 'inflection-table-top',
				args = {
					title = "-",
					palette = color,
					class = "floatright tr-alongside"
				}
			}

			wikicode = wikicode .. [=[
! [[w:Semitic root|Root]=] .. (#term_counts == 1 and "" or "s") .. [=[]]]=]

			wikicode = wikicode .. link_text_output

			wikicode = wikicode .. mw.getCurrentFrame():expandTemplate {
				title = 'inflection-table-bottom',
			}
			return wikicode .. table.concat(categories)
		end
	end
end

return export