Jump to content

မေႃႇၵျူး:sem-arb-headword/new

လုၵ်ႉတီႈ ဝိၵ်ႇသျိၼ်ႇၼရီႇ မႃး

Documentation for this module may be created at မေႃႇၵျူး:sem-arb-headword/new/doc

local export = {}
local pos_functions = {}

local force_cat = false -- for testing; if true, categories appear in non-mainspace pages

local langcode = "ar"
local lang = require("Module:languages").getByCode(langcode, true)
local langname = lang:getCanonicalName()

local require_when_needed = require("Module:utilities/require when needed")
local m_table = require("Module:table")
local headword_module = "Module:headword"
local headword_data_module = "Module:headword/data"
local headword_utilities_module = "Module:headword utilities"
local m_headword_utilities = require_when_needed(headword_utilities_module)

local list_param = { list = true, disallow_holes = true }

local function append_cat(data, pos)
	table.insert(data.categories, langname .. " " .. pos)
end

-- Table of all valid genders, mapping user-specified gender specs to canonicalized versions.
local valid_genders = {
	["m"] = true,
	["f"] = true,
	["m-p"] = true,
	["f-p"] = true,
	["p"] = true,
	["d"] = true,
	["m-d"] = true,
	["f-d"] = true,
	["mfbysense"] = true,
	["mf"] = true,
}

-- Table of all valid aspects.
local valid_aspects = m_table.listToSet {
	"impf", "pf", "both", "biasp", "?",
}

local function ine(val)
	if val == "" then return nil else return val end
end

local function track(track_id, pos)
	local tracking_pages = {}
	table.insert(tracking_pages, "sem-arb-headword/" .. track_id)
	if pos then
		table.insert(tracking_pages, "sl-headword/" .. track_id .. "/" .. pos)
	end
	require("Module:debug/track")(tracking_pages)
	return true
end

-- Parse and insert an inflection not requiring additional processing into `data.inflections`. The raw arguments come
-- from `args[field]`, which is parsed for inline modifiers. `label` is the label that the inflections are given;
-- sections enclosed in <<...>> are linked to the glossary. `accel` is the accelerator form, or nil.
local function parse_and_insert_inflection(pos, data, args, field, label, accel)
	m_headword_utilities.parse_and_insert_inflection {
		headdata = data,
		forms = args[field],
		paramname = field,
		label = label,
		accel = accel and { form = accel } or nil,
	}
end

-- The main entry point.
-- This is the only function that can be invoked from a template.
function export.show(frame)
	local iparams = {
		[1] = {},
		["lang"] = { required = true }
	}
	local iargs = require("Module:parameters").process(frame.args, iparams)
	local parargs = frame:getParent().args
	local poscat = iargs[1]

	if frame.args["lang"] then
		langcode = frame.args["lang"]
	else
		error("Please specify a language code.")
	end

	local headarg
	if poscat then
		headarg = 1
	else
		headarg = 2
		poscat = ine(parargs[1]) or
			mw.title.getCurrentTitle().fullText == "Template:" .. langcode .. "-head" and "interjection" or
			error("Part of speech must be specified in 1=")
		poscat = require(headword_module).canonicalize_pos(poscat)
	end

	local params = {
		[headarg] = { list = "head", required = false, disallow_holes = true },
		["tr"] = { list = true, allow_holes = true },
		["id"] = true,
		["sort"] = true,
		-- no nolinkhead= because head in 1= is always specified
		["json"] = { type = "boolean" },
		["pagename"] = true, -- for testing
	}

	if headarg == 2 then
		params[1] = { required = true } -- required but ignored as already processed above
	end

	if pos_functions[poscat] then
		local posparams = pos_functions[poscat].params
		if type(posparams) == "function" then
			posparams = posparams(lang)
		end
		for key, val in pairs(posparams) do
			params[key] = val
		end
	end

	local args = require("Module:parameters").process(parargs, params)

	local pagename = args.pagename or mw.loadData(headword_data_module).pagename

	local data = {
		lang = lang,
		pos_category = poscat,
		categories = {},
		heads = {},
		genders = {},
		inflections = { enable_auto_translit = true },
		pagename = pagename,
		id = args.id,
		sort_key = args.sort,
		force_cat_output = force_cat,
	}
	
	local heads = args[headarg]

	for i = 1, #heads do
		table.insert(data.heads, {
			term = head,
			tr = args.tr[i],
		})
	end

	if pos_functions[poscat] then
		pos_functions[poscat].func(args, data)
	end

	if args.json then
		return require("Module:JSON").toJSON(data)
	end

	return require(headword_module).full_headword(data)
end

local function get_noun_params(is_proper)
	return function(lang)
		params = {
			[2] = { alias_of = "g" },
			["g"] = { type = "genders", required = true, template_default = "?" },
			["cons"] = list_param,
			["d"] = list_param,
			["pl"] = list_param,
			["pauc"] = list_param,
			["dim"] = list_param,
			["m"] = list_param,
			["f"] = list_param,
		}
		return params
	end
end

local function do_nouns(is_proper, args, data)
	for _, g in ipairs(args.g) do
		local canon_g = valid_genders[g.spec]
		if canon_g then
			track("gender-" .. g.spec)
			if canon_g ~= true then
				g.spec = canon_g
			end
		else
			error("Unrecognized gender: '" .. g.spec .. "'")
		end
	end
	data.genders = args.g
	if #data.genders == 0 then
		table.insert(data.genders, "?")
	end

	-- Parse and insert an inflection not requiring additional processing into `data.inflections`. The raw arguments
	-- come from `args[field]`, which is parsed for inline modifiers. `label` is the label that the inflections are
	-- given; <<..>> ini the label is linked to the glossary). `accel` is the accelerator form, or nil. `frob` is a
	-- function to apply to the values before storing.
	local function handle_infl(field, label, frob)
		parse_and_insert_inflection("noun", data, args, field, label)
	end

	handle_infl("cons", "<<construct state>>")
	handle_infl("d", "<<dual>>")
	handle_infl("pl", "<<plural>>")
	handle_infl("pauc", "<<paucal>>")
	handle_infl("m", "male equivalent")
	handle_infl("f", "female equivalent")
	handle_infl("dim", "<<diminutive>>")
end

pos_functions["nouns"] = {
	params = get_noun_params(false),
	func = function(args, data)
		return do_nouns(false, args, data)
	end,
}

pos_functions["proper nouns"] = {
	params = get_noun_params("proper noun"),
	func = function(args, data)
		return do_nouns("proper noun", args, data)
	end,
}

local verb_forms = {
	["I"] = true,
	["II"] = true,
	["III"] = true,
	["IV"] = true,
	["V"] = true,
	["VI"] = true,
	["VII"] = true,
	["VIII"] = true,
	["IX"] = true,
	["X"] = true,
	["XI"] = true,
	["Iq"] = true,
	["IIq"] = true
}

local lang_exception = { ["ajp"] = true, ["acy"] = true }

local function get_verb_params()
	return function(lang)
		local params
		if lang_exception[lang:getCode()] then
			params = {
				[2] = { alias_of = "form" },
				["form"] = { required = true },
				["pres"] = list_param,
				["subj"] = list_param,
				["vn"] = list_param,
				["ap"] = list_param,
				["pp"] = list_param,
			}
		else
			params = {
				[2] = { alias_of = "form" },
				["form"] = { required = true },
				["np"] = list_param,
				["vn"] = list_param,
				["ap"] = list_param,
				["pp"] = list_param,
			}
		end
		return params
	end
end

pos_functions["verbs"] = {
	params = get_verb_params(),
	func = function(args, data)
		if args[2] then
			if verb_forms[args[2]] then
				data.gloss = '<abbr title="Form ' ..
					args[2] .. '">[[Appendix:Arabic verbs#Form ' .. args[1] .. '|' .. args[1] .. ']]</abbr>'
				append_cat(data, "form-" .. args[2] .. " verbs")
			else
				error("Invalid verb form. Please provide a valid one.")
			end
		end

		if lang_exception[lang:getCode()] then
			parse_and_insert_inflection("verb", data, args, "pres", "present")
			parse_and_insert_inflection("verb", data, args, "subj", "subjunctive")
		else
			parse_and_insert_inflection("verb", data, args, "np", "non-past")
		end
		parse_and_insert_inflection("verb", data, args, "vn", "verbal noun")
		parse_and_insert_inflection("verb", data, args, "ap", "active participle")
		parse_and_insert_inflection("verb", data, args, "pp", "passive participle")
	end,
}

return export