Module:txb-nominal



local export = {}

--[=[

Authors: [[User:kc_kennylau]], [[User:Vampyricon]].
Inspired by [[Module:la-nominal]] by Ben Wing <benwing2>.

]=]

local lang = require("Module:languages").getByCode("txb")
local m_links = require("Module:links")

-- Internal substitutions
local encode = {
	["ā"] = "x",
	["ä"] = "z",
	["Ā"] = "X",
	["Ä"] = "Z",
}
local decode = {
	x = "ā",
	z = "ä",
	X = "Ā",
	Z = "Ä",
}
local function encodefunc(c)
	return encode[c]
end
local function decodefunc(c)
	return decode[c]
end

-- stressed variants of vowels
local stressed = {
	a = "x",
	z = "a",
}
local unstressed = {
	x = "a",
	a = "z",
}

local function palatalise(stem)
	stem = stem:gsub("[tks]$",{t="c",k="c",s="ś"})
	return stem
end

-- e.g. stress the N-th syllable of stem
function export.stressvar(stem,N)
	local count = 0
	stem = stem:gsub("[aeiouxz]+",function(vowel)
		count = count + 1
		if count == N then
			return stressed[vowel] or vowel
		end
		if count == N-1 then
			return unstressed[vowel] or vowel --need to delete ä and u|_w (and i|_y?)
		end
		return vowel
	end)
	return stem
end

local function unstress(stem)
	--stemcode = string.gsub(stemcode,"^(.+)uw(.+)$","^(.+)w(.+)$")
	--stemcode = string.gsub(stemcode,"^(.+)iy(.+)$","^(.+)y(.+)$")
	local a,b,c = stem:match("^(.+)([ax])(.+)$")
	return a and a..({a="z",x="a"})[b]..c or stem
end
local function stress(stem)
	local a,b,c = stem:match("^(.+)([az])(.+)$")
	return a and a..({a="x",z="a"})[b]..c or stem
end

local patterns = {}

-- Class I.1; plurals in -(C)a
-- pikul: "pikul/pikwala<I.1>"
patterns["I.1"] = function(stem)
	local sg_stem, pl_stem = stem:match("^(.+)/(.+)$")
	if sg_stem:sub(-1) == "o" then
		sg_stem = sg_stem:sub(1,-2)
		local u_sg_stem = unstress(sg_stem)
		local u_pl_stem = unstress(pl_stem:sub(1,-2))
		return {
			["nom-sg"] = sg_stem.."o",
			["gen-sg"] = u_sg_stem.."āntse",
			["acc-sg"] = sg_stem.."a",
			["nom-pl"] = pl_stem,
			["gen-pl"] = u_pl_stem.."āṃts",
			["acc-pl"] = pl_stem,
		}
	else
		local s_sg_stem = export.stressvar(sg_stem,2)
		return {
			["nom-sg"] = sg_stem,
			["gen-sg"] = s_sg_stem.."ntse",
			["acc-sg"] = sg_stem,
			["nom-pl"] = pl_stem,
			["gen-pl"] = pl_stem.."ṃts",
			["acc-pl"] = pl_stem,
		}
	end
end

-- Class I.2; plurals in -wa
-- ost: "ost<I.2>"
patterns["I.2"] = function(stem) --still need to add stress and the exception of "wood"
	return {
		["nom-sg"] = stem,
		["gen-sg"] = stem.."antse",
		["acc-sg"] = stem,
		["nom-pl"] = {stem.."wa", stem.."uwa"},
		["gen-pl"] = stem.."waṃts",
		["acc-pl"] = {stem.."wa", stem.."uwa"},
	}
end

-- pācer: "pāt<IV>"
patterns["IV"] = function(stem)
	local p_stem = palatalise(stem)
	local up_stem = unstress(p_stem)
	return {
		["nom-sg"] = p_stem.."er",
		["gen-sg"] = stem.."ri",
		["acc-sg"] = stem.."är",
		["nom-pl"] = {up_stem.."era", stem.."ärñ"},
		["gen-pl"] = {stem.."ärnts", stem.."ärntso"},
		["acc-pl"] = {up_stem.."era", stem.."ärñ"},
	}
end

local function make_links(forms)
	for key,val in pairs(forms) do
		if type(val) == "string" then
			val = {val}
		end
		for i,form in ipairs(val) do
			form = form:gsub("[xzXZ]",decode)
			val[i] = m_links.full_link({lang=lang, term=form})
		end
		forms[key] = table.concat(val," / ")
	end
	return true
end

local function make_table(forms)
	local stylesheet = require("Module:TemplateStyles")("Template:txb-nominal/style.css")
	return stylesheet .. '\n' .. ([=[
{| class="wikitable inflection-table inflection-table-txb"
|-
! class="corner-header" | Case
! class="number-header" | Singular
! class="number-header" | Plural
|-
! class="case-header" | [[nominative case|Nominative]]
| class="form-cell" | {{{nom-sg}}}
| class="form-cell" | {{{nom-pl}}}
|-
! class="case-header" | [[genitive case|Genitive]]
| class="form-cell" | {{{gen-sg}}}
| class="form-cell" | {{{gen-pl}}}
|-
! class="case-header" | [[accusative case|Accusative]]
| class="form-cell" | {{{acc-sg}}}
| class="form-cell" | {{{acc-pl}}}
|}]=]):gsub("{{{([^{}]+)}}}", forms)
end

function export.show(frame)
	local stem_typ = frame:getParent().args[1]
	stem_typ = stem_typ:gsub("[\192-\223][\128-\191]",encode)
	local stem,typ = stem_typ:match("^(.+)<(.+)>$")
	local forms = patterns[typ](stem)
	make_links(forms)
	return make_table(forms)
end

return export