Module:sw-derivations

For use in {{sw-derivations}}.


local m_links = require("Module:links")
local lang = require("Module:languages").getByCode("sw")
local match = mw.ustring.match
local gsub = mw.ustring.gsub

PAGENAME = mw.title.getCurrentTitle().text or ''

local export = {}

local classes = {
	"appl", "aug", "caus", "conv", "pass", "recip", "redup", "stat", "statc"
}

local classes_names = {
	appl = "Applicative",
	aug = "Augmentative",
	caus = "Causative",
	conv = "Conversive",
	pass = "Passive",
	recip = "Reciprocal",
	redup = "Reduplicative",
	stat = "Stative",
	statc = "Static"
}

local function join_E_suffix(stem, suffix)
	if match(stem, "[aiu][^aeiou]*$") then
		return stem .. gsub(suffix, "E", "i")
	elseif match(stem, "[oe][^aeiou]*$") then
		return stem .. gsub(suffix, "E", "e")
	else -- Default to an 'e'. Perhaps throw an error instead?
		return stem .. gsub(suffix, "E", "e")
	end
end

local auto_deriv = {}

auto_deriv.appl = function(lemma)
	if match(lemma, "au$") then
		return lemma .. "lia"
	elseif match(lemma, "u$") then
		return gsub(lemma, "u$", "ia")
	elseif match(lemma, "[ei]$") then
		return lemma .. "a"
	elseif match(lemma, "[aeiou]a$") then
		return join_E_suffix(gsub(lemma, "a$", ""), "lEa")
	elseif match(lemma, "a$") then
		return join_E_suffix(gsub(lemma, "a$", ""), "Ea")
	end
	return lemma
end
auto_deriv.aug = function(lemma)
	if match(lemma, "o.$") then
		return gsub(lemma, ".$", "oa")
	else
		return gsub(lemma, ".$", "ua")
	end
end
auto_deriv.caus = function(lemma)
	if match(lemma, "au$") then
		return lemma .. "lisha"
	elseif match(lemma, "[eiu]$") then
		return join_E_suffix(gsub(lemma, "[eiu]$", ""), "Esha")
	elseif match(lemma, "[aeiou]a$") then
		return gsub(lemma, "a$", "za")
	elseif match(lemma, "a$") then
		return join_E_suffix(gsub(lemma, "a$", ""), "Esha")
	end
	return lemma
end
auto_deriv.conv = function(lemma)
	if match(lemma, "o.$") then
		return gsub(lemma, ".$", "oa")
	else
		return gsub(lemma, ".$", "ua")
	end
end
auto_deriv.pass = function(lemma)
	local mono = {cha = "chewa", la = "liwa", nywa = "nywewa", pa = "pewa"}
	if mono[lemma] then
		return mono[lemma]
	elseif match(lemma, "au$") then
		return lemma .. "liwa"
	elseif match(lemma, "[iu]$") then
		return gsub(lemma, "[iu]$", "iwa")
	elseif match(lemma, "e$") then
		return lemma .. "wa"
	elseif match(lemma, "[aeiou]a$") then
		return join_E_suffix(gsub(lemma, "a$", ""), "lEwa")
	elseif match(lemma, "a$") then
		return gsub(lemma, "a$", "wa")
	end
	return lemma
end
auto_deriv.recip = function(lemma)
	if match(lemma, "[eiu]$") then
		return auto_deriv.appl(lemma) .. "na"
	else
		return lemma .. "na"
	end
end
auto_deriv.redup = function(lemma) return lemma .. lemma end
auto_deriv.stat = function(lemma)
	local mono = {ja = "jika", la = "lika", nywa = "nyweka"}
	if mono[lemma] then
		return mono[lemma]
	elseif match(lemma, "au$") then
		return lemma .. "lika"
	elseif match(lemma, "[iu]$") then
		return gsub(lemma, "[iu]$", "ika")
	elseif match(lemma, "e$") then
		return lemma .. "ka"
	elseif match(lemma, "[aeiou]a$") then
		return join_E_suffix(gsub(lemma, "a$", ""), "lEka")
	elseif match(lemma, "a$") then
		return join_E_suffix(gsub(lemma, "a$", ""), "Eka")
	end
	return lemma
end
auto_deriv.statc = function(lemma) return lemma .. "ma" end

local function pop_contains(arr, val)
	for i, v in pairs(arr) do
		if val == v then
			table.remove(arr, i)
			return true
		end
	end
	return false
end

local function get_remaining(arr)
	local out = {}
	for _, v in ipairs(arr) do table.insert(out, v) end
	return out
end

local function make_verb_row(lemma, code, autogen, forms, gloss)
	if autogen and auto_deriv[code] then
		local autoval = auto_deriv[code](lemma)
		table.insert(forms, 1, autoval)
	end

	local row = {}

	for i, term in pairs(forms) do
		if code == 'pass' or code == 'appl' or code == 'caus' or code == 'recip' or
			code == 'stat' then
			table.insert(row, m_links.full_link({
					lang = lang,
					term = term,
					alt = '-' .. term,
					gloss = gloss[i],
					accel = {form = "root:" .. code}
				}))
		else
			table.insert(row, m_links.full_link({
					lang = lang,
					term = term,
					alt = '-' .. term,
					gloss = gloss[i]
				}))
		end
	end
	return table.concat {
		"** ''", classes_names[code], "'': ", table.concat(row, ", ")
	}
end

local function make_other_verb_row(forms, gloss)
	local row = {}

	for i, term in pairs(forms) do
		table.insert(row, m_links.full_link({
				lang = lang,
				term = term,
				alt = '-' .. term,
				gloss = gloss[i]
			}))
	end
	table.sort(row)
	return table.concat {"** ''Other formations'': ", table.concat(row, ", ")}
end

local function make_noun_row(term, gloss)
	return table.concat {
		"** ", m_links.full_link({lang = lang, term = term, gloss = gloss})
	}
end

local function make_output(args)
	local output = {}
	local autogen = nil
	local verb_output = {}
	for _, code in ipairs(classes) do
		autogen = pop_contains(args[1], code)
		if autogen or #args[code] > 0 then
			table.insert(verb_output, make_verb_row(args.lemma, code, autogen, args[code], args[code .. "-g"]))
		end
	end
	if #args.vrb > 0 then
		table.insert(verb_output, make_other_verb_row(args.vrb, args["vrb-g"]))
	end

	if #args[1] > 0 then
		error('Unrecognized Swahili derivation type(s) "' .. table.concat(get_remaining(args[1]), '", "') .. '".')
	end

	if #verb_output > 0 then
		table.insert(verb_output, 1, "* '''[[Appendix:Swahili verbal derivation|Verbal derivations]]''':")
		table.insert(output, table.concat(verb_output, "\n"))
	end

	local noun_output = {}
	for i, noun in pairs(args.nom) do
		table.insert(noun_output, make_noun_row(noun, args["nom-g"][i]))
	end

	if #noun_output > 0 then
		table.sort(noun_output)
		table.insert(noun_output, 1, "* '''[[Appendix:Swahili verbal derivation#Nouns|Nominal derivations]]''':")
		table.insert(output, table.concat(noun_output, "\n"))
	end

	local other_output = {}
	for i, other in pairs(args.other) do
		table.insert(other_output, make_noun_row(other, args["other-g"][i]))
	end

	if #other_output > 0 then
		table.sort(other_output)
		table.insert(other_output, 1, "* '''[[Appendix:Swahili verbal derivation|Other derivations]]''':")
		table.insert(output, table.concat(other_output, "\n"))
	end

	return table.concat(output, "\n\n")
end

function export.show(frame)
	local params = {
		-- verbal derivatives
		[1] = {list = true},
		["appl"] = {list = true},
		["appl-g"] = {list = true, allow_holes = true},
		["aug"] = {list = true},
		["aug-g"] = {list = true, allow_holes = true},
		["caus"] = {list = true},
		["caus-g"] = {list = true, allow_holes = true},
		["conv"] = {list = true},
		["conv-g"] = {list = true, allow_holes = true},
		["pass"] = {list = true},
		["pass-g"] = {list = true, allow_holes = true},
		["recip"] = {list = true},
		["recip-g"] = {list = true, allow_holes = true},
		["redup"] = {list = true},
		["redup-g"] = {list = true, allow_holes = true},
		["stat"] = {list = true},
		["stat-g"] = {list = true, allow_holes = true},
		["statc"] = {list = true},
		["statc-g"] = {list = true, allow_holes = true},
		-- other verbal formations
		["vrb"] = {list = true},
		["vrb-g"] = {list = true, allow_holes = true},
		-- nominal derivatives
		["nom"] = {list = true},
		["nom-g"] = {list = true, allow_holes = true},
		-- other non-verbal derivatives
		["other"] = {list = true},
		["other-g"] = {list = true, allow_holes = true},
		-- other
		["lemma"] = {default = PAGENAME}
	}

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

	return make_output(args)
end

return export