Jump to content

Module:odt-decl-noun

From Wiktionary, the free dictionary


local export = {}

local m_links = require("Module:links")
local m_utils = require("Module:utilities")

local lang = require("Module:languages").getByCode("odt")

local decl_data = {}

local function devoice(stem)
	stem = mw.ustring.gsub(stem, "ng$", "nc")
	stem = mw.ustring.gsub(stem, "d$", "t")
	stem = mw.ustring.gsub(stem, "b$", "p")
	stem = mw.ustring.gsub(stem, "v$", "f")
	stem = mw.ustring.gsub(stem, "z$", "s")
	return stem
end

local function umlaut(stem)
	subStr = string.sub(stem, -4, -1)
	if string.find(subStr, "ie") then
    	stem = stem.gsub(stem, "ie", "iu")
    end
    if string.find(subStr, "e") and not string.find(subStr, "ei") then
    	stem = stem.gsub(stem, "e", "i")
    end
    if string.find(subStr, "a") then
    	stem = stem.gsub(stem, "a", "e")
    end
    if string.find(subStr, "o") and not string.find(stem, "ou") then
    	stem = stem.gsub(stem, "o", "u")
    end
    stem = mw.ustring.gsub(stem, "ce", "ke")
    stem = mw.ustring.gsub(stem, "ci", "ki")
    return stem
end

local function C_to_K(stem)
    stem = mw.ustring.gsub(stem, "cc$", "ck")
    stem = mw.ustring.gsub(stem, "c$", "k")
    stem = mw.ustring.gsub(stem, "z$", "c")
    return stem
end

local function K_to_C(stem)
    stem = mw.ustring.gsub(stem, "ck$", "cc")
    stem = mw.ustring.gsub(stem, "k$", "c")
    return stem
end

local function degeminate(stem)
	stem = mw.ustring.gsub(stem, "([bcdfghjklmnprstvwzþ])%1$", "%1")
	stem = mw.ustring.gsub(stem, "ck$", "k")
	return stem
end

local function categorize(gender)
	if gender == 'm' then
		cat_gender='masculine'
	elseif gender == 'f' then
		cat_gender='feminine'
	elseif gender == 'n' then
		cat_gender='neuter'
	else
		cat_gender='masculine'
--		error("Unrecognized gender '" .. gender .. "'. Only masculine ('m'), feminine ('f') or neuter ('n')")
	end

	return cat_gender
end


decl_data["a"] = {
	params = {
		[1] = {},
		["g"] = {},
		["nopl"] = {},
		["gender"] = {alias_of = "g"},
	},
}
setmetatable(decl_data["a"], {__call = function(self, args, data)
	cat_type = "a-stem noun"
	cat_gender = categorize(args.g)
	
	data.decl_type = "" ..cat_gender.. " " ..cat_type.. ""
	table.insert(data.categories, "Old Dutch " .. cat_gender .. " " .. cat_type .. "s")

	stem_C = K_to_C(args[1])
	stem_K = C_to_K(args[1])
	devoiced_stem = devoice(degeminate(stem_C))
	
	data.forms["nom_sg"] = {devoiced_stem}
	data.forms["acc_sg"] = {devoiced_stem}
	data.forms["gen_sg"] = {stem_K .. "es"}
	data.forms["dat_sg"] = {stem_K .. "e"}

	data.forms["nom_pl"] = {stem_C .. "a"}
	data.forms["acc_pl"] = {stem_C .. "a"}
	data.forms["gen_pl"] = {stem_C .. "o"}
	data.forms["dat_pl"] = {stem_C .. "on"}
	
	if args.g == 'n' then
				data.forms["nom_pl"] = {devoiced_stem}
				data.forms["acc_pl"] = {devoiced_stem}
	end
end
})


decl_data["o"] = {
	params = {
		[1] = {},
		["nopl"] = {},
		},
}
setmetatable(decl_data["o"], {__call = function(self, args, data)
	args.g='f'
	cat_type = "ō/ōn-stem noun"
	cat_gender = categorize(args.g)
	
	data.decl_type = "" ..cat_gender.. " " ..cat_type.. ""
	table.insert(data.categories, "Old Dutch " .. cat_type .. "s")
	
	data.forms["nom_sg"] = {args[1] .. "a"}
	data.forms["acc_sg"] = {args[1] .. "a", args[1] .. "on"}
	data.forms["gen_sg"] = {args[1] .. "on"}
	data.forms["dat_sg"] = {args[1] .. "on"}

	data.forms["nom_pl"] = {args[1] .. "a", args[1] .. "on"}
	data.forms["acc_pl"] = {args[1] .. "a", args[1] .. "on"}
	data.forms["gen_pl"] = {args[1] .. "ono"}
	data.forms["dat_pl"] = {args[1] .. "on"}
end
})

decl_data["ja"] = {
	params = {
		[1] = {},
		["g"] = {},
		["nopl"] = {},
		["gender"] = {alias_of = "g"},
		},
}
setmetatable(decl_data["ja"], {__call = function(self, args, data)
	cat_type = "ja-stem noun"
	cat_gender = categorize(args.g)
	
	data.decl_type = "" ..cat_gender.. " " ..cat_type.. ""
	table.insert(data.categories, "Old Dutch " .. cat_gender .. " " .. cat_type .. "s")

	stem_C = K_to_C(args[1])
	stem_K = C_to_K(args[1])

	data.forms["nom_sg"] = {stem_K .. "i"}
	data.forms["acc_sg"] = {stem_K .. "i"}
	data.forms["gen_sg"] = {stem_K .. "is"}
	data.forms["dat_sg"] = {stem_K .. "i"}

	data.forms["nom_pl"] = {stem_C .. "a"}
	data.forms["acc_pl"] = {stem_C .. "a"}
	data.forms["gen_pl"] = {stem_C .. "o"}
	data.forms["dat_pl"] = {stem_C .. "on"}
	
	if args.g == 'n' then
		data.forms["nom_pl"] = {stem_K .. "i"}
		data.forms["acc_pl"] = {stem_K .. "i"}
	end
end
})

decl_data["wa"] = {
	params = {
		[1] = {},
		["g"] = {},
		["nopl"] = {},
		["gender"] = {alias_of = "g"},
		},
}
setmetatable(decl_data["wa"], {__call = function(self, args, data)
	cat_type = "wa-stem noun"
	cat_gender = categorize(args.g)
	
	data.decl_type = "" ..cat_gender.. " " ..cat_type.. ""
	table.insert(data.categories, "Old Dutch " .. cat_gender .. " " .. cat_type .. "s")
	
	data.forms["nom_sg"] = {args[1] .. "o"}
	data.forms["acc_sg"] = {args[1] .. "o"}
	data.forms["gen_sg"] = {args[1] .. "wes"}
	data.forms["dat_sg"] = {args[1] .. "we"}

	data.forms["nom_pl"] = {args[1] .. "wa"}
	data.forms["acc_pl"] = {args[1] .. "wa"}
	data.forms["gen_pl"] = {args[1] .. "wo"}
	data.forms["dat_pl"] = {args[1] .. "won"}
	
	if args.g == 'n' then
			data.forms["nom_pl"] = {args[1] .. "o"}
			data.forms["acc_pl"] = {args[1] .. "o"}
	end
end
})

decl_data["wo"] = {
	params = {
		[1] = {},
		["nopl"] = {},
		},
}
setmetatable(decl_data["wo"], {__call = function(self, args, data)
	args.g='f'
	cat_type = "wō-stem noun"
	cat_gender = categorize(args.g)
	
	data.decl_type = "" ..cat_gender.. " " ..cat_type.. ""
	table.insert(data.categories, "Old Dutch " .. cat_type .. "s")
	
	data.forms["nom_sg"] = {args[1] .. "wa"}
	data.forms["acc_sg"] = {args[1] .. "wa", args[1] .. "won"}
	data.forms["gen_sg"] = {args[1] .. "won"}
	data.forms["dat_sg"] = {args[1] .. "won"}

	data.forms["nom_pl"] = {args[1] .. "wa", args[1] .. "won"}
	data.forms["acc_pl"] = {args[1] .. "wa", args[1] .. "won"}
	data.forms["gen_pl"] = {args[1] .. "wono"}
	data.forms["dat_pl"] = {args[1] .. "won"}
end
})

decl_data["i"] = {
	params = {
		[1] = {},
		["g"] = {},
		["nopl"] = {},
		["nomut"] = {},
		["w"] = {},
		["gender"] = {alias_of = "g"},
		["weight"] = {alias_of = "w"},
		},
}
setmetatable(decl_data["i"], {__call = function(self, args, data)
	cat_type = "i-stem noun"
	cat_gender = categorize(args.g)

	data.decl_type = "" ..cat_gender.. " " ..cat_type.. ""
	table.insert(data.categories, "Old Dutch " .. cat_gender .. " " .. cat_type .. "s")

	stem_C = K_to_C(args[1])
	stem_K = C_to_K(args[1])
	umlauted_stem_C = umlaut(stem_C)
	umlauted_stem_K = umlaut(stem_K)
	devoiced_stem = degeminate(devoice(stem_C))

	if args.w == 'l' or args.nomut == '1' then
		umlauted_stem_C = stem_C
		umlauted_stem_K = stem_K
	end

	data.forms["nom_sg"] = {devoiced_stem}
	data.forms["acc_sg"] = {devoiced_stem}
	data.forms["gen_sg"] = {umlauted_stem_K .. "is"}
	data.forms["dat_sg"] = {umlauted_stem_K .. "i"}
	
	data.forms["nom_pl"] = {umlauted_stem_K .. "i"}
	data.forms["acc_pl"] = {umlauted_stem_K .. "i"}
	data.forms["gen_pl"] = {umlauted_stem_C .. "o"}
	data.forms["dat_pl"] = {umlauted_stem_K .. "in", umlauted_stem_C .. "on"}
	
	if args.w == 'l' then
		data.forms["nom_sg"] = {umlauted_stem_K .. "i"}
		data.forms["acc_sg"] = {umlauted_stem_K .. "i"}
	end

	if args.g == 'f' then
		data.forms["gen_sg"] = {umlauted_stem_K .. "i"}
	end
end
})

decl_data["u"] = {
	params = {
		[1] = {},
		["g"] = {},
		["nopl"] = {},
		["nomut"] = {},
		["w"] = {},
		["gender"] = {alias_of = "g"},
		["weight"] = {alias_of = "w"},
		},
}
setmetatable(decl_data["u"], {__call = function(self, args, data)
	cat_type = "u-stem noun"
	cat_gender = categorize(args.g)

	data.decl_type = "" ..cat_gender.. " " ..cat_type.. ""
	table.insert(data.categories, "Old Dutch " .. cat_gender .. " " .. cat_type .. "s")

	stem_C = K_to_C(args[1])
	stem_K = C_to_K(args[1])
	umlauted_stem_C = umlaut(stem_C)
	umlauted_stem_K = umlaut(stem_K)
	devoiced_stem = degeminate(devoice(stem_C))

	if args.w == 'l' or args.nomut == '1' then
		umlauted_stem_C = stem_C
		umlauted_stem_K = stem_K
	end

	data.forms["nom_sg"] = {devoiced_stem}
	data.forms["acc_sg"] = {devoiced_stem}
	data.forms["gen_sg"] = {umlauted_stem_K .. "is"}
	data.forms["dat_sg"] = {umlauted_stem_K .. "i"}
	
	data.forms["nom_pl"] = {umlauted_stem_K .. "i"}
	data.forms["acc_pl"] = {umlauted_stem_K .. "i"}
	data.forms["gen_pl"] = {stem_C .. "o"}
	data.forms["dat_pl"] = {stem_C .. "on"}
	
	if args.w == 'l' then
		data.forms["nom_sg"] = {stem_C .. "o"}
		data.forms["acc_sg"] = {stem_C .. "o"}
	end

	if args.g == 'f' then
		data.forms["gen_sg"] = {umlauted_stem_K .. "i"}
	end
end
})

decl_data["an"] = {
	params = {
		[1] = {},
		["g"] = {},
		["nopl"] = {},
		["gender"] = {alias_of = "g"},
		},
}
setmetatable(decl_data["an"], {__call = function(self, args, data)
	cat_type = "an-stem noun"
	cat_gender = categorize(args.g)
	
	data.decl_type = "" ..cat_gender.. " " ..cat_type.. ""
	table.insert(data.categories, "Old Dutch " .. cat_gender .. " " .. cat_type .. "s")

	stem_C = K_to_C(args[1])
	stem_K = C_to_K(args[1])
	
	data.forms["nom_sg"] = {stem_C .. "o"}
	data.forms["acc_sg"] = {stem_C .. "on"}
	data.forms["gen_sg"] = {stem_K .. "in"}
	data.forms["dat_sg"] = {stem_K .. "in"}
	
	data.forms["nom_pl"] = {stem_C .. "on"}
	data.forms["acc_pl"] = {stem_C .. "on"}
	data.forms["gen_pl"] = {stem_C .. "ono"}
	data.forms["dat_pl"] = {stem_C .. "on"}
	
	if args.g == 'n' then
		data.forms["nom_sg"] = {stem_C .. "a"}
		data.forms["acc_sg"] = {stem_C .. "a"}
		data.forms["nom_pl"] = {stem_C .. "on", stem_C .. "a"}
		data.forms["acc_pl"] = {stem_C .. "on", stem_C .. "a"}
	end
end
})

decl_data["in"] = {
	params = {
		[1] = {},
		},
}
setmetatable(decl_data["in"], {__call = function(self, args, data)
	args.g='f'
	args.nopl='1'
	cat_type = "īn-stem noun"
	cat_gender = categorize(args.g)
	
	data.decl_type = "" ..cat_gender.. " " ..cat_type.. ""
	table.insert(data.categories, "Old Dutch " .. cat_type .. "s")

	data.forms["nom_sg"] = {args[1] .. "i"}
	data.forms["acc_sg"] = {args[1] .. "i"}
	data.forms["gen_sg"] = {args[1] .. "i"}
	data.forms["dat_sg"] = {args[1] .. "i"}
end
})

decl_data["cons"] = {
	params = {
		[1] = {},
		["nopl"] = {},
		},
}
setmetatable(decl_data["cons"], {__call = function(self, args, data)
	data.decl_type = "consonant stem"

	stem_C = K_to_C(args[1])
	stem_K = C_to_K(args[1])
	devoiced_stem = devoice(degeminate(stem_C))
	
	data.forms["nom_sg"] = {devoiced_stem}
	data.forms["acc_sg"] = {devoiced_stem}
	data.forms["gen_sg"] = {stem_K .. "es"}
	data.forms["dat_sg"] = {stem_K .. "e"}

	data.forms["nom_pl"] = {devoiced_stem}
	data.forms["acc_pl"] = {devoiced_stem}
	data.forms["gen_pl"] = {stem_C .. "o"}
	data.forms["dat_pl"] = {stem_C .. "on"}

	table.insert(data.categories, "Old Dutch consonant stem nouns")
end
})


decl_data["r"] = {
	params = {
		[1] = {},
		},
}
setmetatable(decl_data["r"], {__call = function(self, args, data)
	data.decl_type = "r-stem"
	
	data.forms["nom_sg"] = {args[1]}
	data.forms["acc_sg"] = {args[1]}
	data.forms["gen_sg"] = {args[1]}
	data.forms["dat_sg"] = {args[1]}

	data.forms["nom_pl"] = {args[1]}
	data.forms["acc_pl"] = {args[1]}
	data.forms["gen_pl"] = {args[1] .. "o"}
	data.forms["dat_pl"] = {args[1] .. "on"}

	table.insert(data.categories, "Old Dutch r-stem nouns")
end
})

decl_data["z"] = {
	params = {
		[1] = {},
		},
}
setmetatable(decl_data["z"], {__call = function(self, args, data)
	data.decl_type = "z-stem"
	
	stem_C = K_to_C(args[1])
	stem_K = C_to_K(args[1])
	devoiced_stem = devoice(degeminate(stem_C))
	
	data.forms["nom_sg"] = {devoiced_stem}
	data.forms["acc_sg"] = {devoiced_stem}
	data.forms["gen_sg"] = {stem_K .. "es"}
	data.forms["dat_sg"] = {stem_K .. "e"}

	data.forms["nom_pl"] = {stem_K .. "ir"}
	data.forms["acc_pl"] = {stem_K .. "ir"}
	data.forms["gen_pl"] = {stem_K .. "iro"}
	data.forms["dat_pl"] = {stem_K .. "iron"}

	table.insert(data.categories, "Old Dutch z-stem nouns")
end
})


decl_data["manual"] = {
	params = {
		[1] = {},
		[2] = {},
		[3] = {},
		[4] = {},
		[5] = {},
		[6] = {},
		[7] = {},
		[8] = {},
		["type"] = {},
		["nopl"] = {},
		},
}
setmetatable(decl_data["manual"], {__call = function(self, args, data)
	data.decl_type = "" .. args.type .. ""
	
	data.forms["nom_sg"] = {args[1]}
	data.forms["acc_sg"] = {args[2]}
	data.forms["gen_sg"] = {args[3]}
	data.forms["dat_sg"] = {args[4]}

	data.forms["nom_pl"] = {args[5]}
	data.forms["acc_pl"] = {args[6]}
	data.forms["gen_pl"] = {args[7]}
	data.forms["dat_pl"] = {args[8]}
end
})


-- The main entry point for automatic declension.
function export.show(frame)

	local parent_args = frame:getParent().args
	local decl_type = (frame.args["decl"] or parent_args["decl"]) or "a"

	if not decl_data[decl_type] then
		error("Unknown declension '" .. decl_type .. "'")
	end
	
	local data = {forms = {}, categories = {}}
	
	data.head = parent_args["head"] or nil

	local args = require("Module:parameters").process(parent_args, decl_data[decl_type].params, true)
	
	-- Override for templates
	if not args[1] then
		setmetatable(args, {__index = function(self, key)
			return "{{{" .. key .. "}}}"
		end
		})
	end
	
	-- Generate the forms
	if parent_args.irr then
		table.insert(data.categories, "Old Dutch irregular nouns")
		if decl_data.irregular[parent_args.irr] then
			decl_data.irregular[parent_args.irr](data)
		else
			decl_data[decl_type](args, data)
		end
	else
		decl_data[decl_type](args, data)
	end

	-- Make the table
	if args.nopl=='1' then
		return make_table_nopl(data)
	else
		return make_table(data)
	end
end

-- The main entry point for manual declension.
function export.show_manual(frame)
	local parent_args = frame:getParent().args
	local params = {
		[1] = {},
		[2] = {},
		[3] = {},
		[4] = {},
		[5] = {},
		[6] = {},
		[7] = {},
		[8] = {},
		["head"] = {}, -- currently ignored
	}

	local data = {forms = {}, categories = {}}
	local args = require("Module:parameters").process(parent_args, params)
	
	local function split(arg)
		return arg and mw.text.split(arg, "%s*,%s*") or nil
	end
	data.forms.nom_sg = split(args[1])
	data.forms.nom_pl = split(args[2])
	data.forms.acc_sg = split(args[3])
	data.forms.acc_pl = split(args[4])
	data.forms.gen_sg = split(args[5])
	data.forms.gen_pl = split(args[6])
	data.forms.dat_sg = split(args[7])
	data.forms.dat_pl = split(args[8])
	data.decl_type = "irregular"

	-- Make the table
	if args.nopl=='1' then
		return make_table_nopl(data)
	else
		return make_table(data)
	end
end

function make_table(data)
	local function show_form(form)
		if not form then
			return "—"
		end
		
		local ret = {}
		
		for key, subform in ipairs(form) do
			if mw.title.getCurrentTitle().nsText == "Reconstruction" and subform ~= "—" then
				subform = "*" .. subform
			end
			table.insert(ret, m_links.full_link({lang = lang, term = subform}))
		end
			
		return table.concat(ret, ", ")
	end
	
	local function repl(param)
		if param == "decl_type" then
			return data.decl_type
		else
			return show_form(data.forms[param])
		end
	end

local wikicode = [=[
<div class="NavFrame" style="width: 42em">
<div class="NavHead" style="">Declension of {{{nom_sg}}} ({{{decl_type}}})</div>
<div class="NavContent">
{| style="background:#f1f5eb; text-align:center; width:100%" cellpadding="0" cellspacing="1" class="inflection-table"
|-
! style="width: 20%; background:#d5dbd8" colspan="1" |  '''case'''
! style="width: 40%; background:#e5eede" colspan="1" | singular
! style="width: 40%; background:#e5eede" colspan="1" | plural
|-
! style="background:#ebf0ed" | nominative
| style="background-color:#fdfffc;" | {{{nom_sg}}}
| style="background-color:#fdfffc;" | {{{nom_pl}}}
|-
! style="background:#ebf0ed" | accusative
| style="background-color:#fdfffc;" | {{{acc_sg}}}
| style="background-color:#fdfffc;" | {{{acc_pl}}}
|-
!style="background:#ebf0ed" | genitive
| style="background-color:#fdfffc;" | {{{gen_sg}}}
| style="background-color:#fdfffc;" | {{{gen_pl}}}
|-
! style="background:#ebf0ed" | dative
| style="background-color:#fdfffc;" | {{{dat_sg}}}
| style="background-color:#fdfffc;" | {{{dat_pl}}}
|}</div></div>]=]

	return (mw.ustring.gsub(wikicode, "{{{([a-z0-9_]+)}}}", repl)) .. m_utils.format_categories(data.categories, lang)
end

function make_table_nopl(data)
	local function show_form(form)
		if not form then
			return "—"
		end
		
		local ret = {}
		
		for key, subform in ipairs(form) do
			if mw.title.getCurrentTitle().nsText == "Reconstruction" and subform ~= "—" then
				subform = "*" .. subform
			end
			table.insert(ret, m_links.full_link({lang = lang, term = subform}))
		end
			
		return table.concat(ret, ", ")
	end
	
	local function repl(param)
		if param == "decl_type" then
			return data.decl_type
		else
			return show_form(data.forms[param])
		end
	end

local wikicode = [=[
<div class="NavFrame" style="width: 38em">
<div class="NavHead" style="">Declension of {{{nom_sg}}} ({{{decl_type}}} - no plural)</div>
<div class="NavContent">
{| style="background:#f1f5eb; text-align:center; width:100%" cellpadding="0" cellspacing="1" class="inflection-table"
|-
! style="width: 30%; background:#d5dbd8" colspan="1" |  '''case'''
! style="width: 70%; background:#e5eede" colspan="1" | singular
|-
! style="background:#ebf0ed" | nominative
| style="background-color:#fdfffc;" | {{{nom_sg}}}
|-
! style="background:#ebf0ed" | accusative
| style="background-color:#fdfffc;" | {{{acc_sg}}}
|-
!style="background:#ebf0ed" | genitive
| style="background-color:#fdfffc;" | {{{gen_sg}}}
|-
! style="background:#ebf0ed" | dative
| style="background-color:#fdfffc;" | {{{dat_sg}}}
|}</div></div>]=]

	return (mw.ustring.gsub(wikicode, "{{{([a-z0-9_]+)}}}", repl)) .. m_utils.format_categories(data.categories, lang)
end

return export