Module:de-headword

Definition from Wiktionary, the free dictionary
Jump to navigation Jump to search
Text-x-generic with pencil.svg This module needs documentation.
Please document this module by describing its purpose and usage on the documentation page.

local export = {}
local pos_functions = {}

local legal_gender = {
	["m"] = true,
	["m-s"] = true,
	["m-p"] = true,
	["f"] = true,
	["f-s"] = true,
	["f-p"] = true,
	["n"] = true,
	["n-s"] = true,
	["n-p"] = true,
	["?"] = true,
	["?-s"] = true,
	["?-p"] = true,
	["p"] = true,
}

local gender_names = {
	["m"] = "masculine",
	["m-s"] = "masculine",
	["m-p"] = "masculine",
	["f"] = "feminine",
	["f-s"] = "feminine",
	["f-p"] = "feminine",
	["n"] = "neuter",
	["n-s"] = "neuter",
	["n-p"] = "neuter",
	["?"] = "unknown gender",
	["?-s"] = "unknown gender",
	["?-p"] = "unknown gender",
	["p"] = "plural",
}

local legal_verb_classes = {
	['1'] = true,
	['2'] = true,
	['3'] = true,
	['4'] = true,
	['5'] = true,
	['6'] = true,
	['7'] = true,
}

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

-- The main entry point.
-- This is the only function that can be invoked from a template.
function export.show(frame)
	local args = frame:getParent().args
	PAGENAME = mw.title.getCurrentTitle().text
	
	local head = args["head"]; if head == "" then head = nil end
	
	local poscat = frame.args[1] or error("Part of speech has not been specified. Please pass parameter 1 to the module invocation.")
	local class = frame.args[2]; if class == "" then class = nil end
	
	local data = {lang = lang, pos_category = poscat, categories = {}, heads = {head}, genders = {}, inflections = {}}
	
	if pos_functions[poscat] then
		pos_functions[poscat](class, args, data)
	end
	
	return
		require("Module:headword").full_headword(data)
end

pos_functions.adjectives = function(class, args, data)
	params = {
		[1] = {list = "comp"},
		[2] = {list = "sup"},
		["head"] = {},
	}
	local args = require("Module:parameters").process(args, params)
	data.heads = {args["head"]}
	
	if args[1][1] == '-' then
		table.insert(data.inflections, {label = 'not comparable'})
		table.insert(data.categories, 'German uncomparable adjectives')
		return
	end
	
	if #args[1] > 0 then
		for i, form in ipairs(args[1]) do
			args[1][i] = {term = (form == 'er' and PAGENAME .. 'er' or form),
				accel = 'comparative-form-of'}
		end
	else
		args[1] = {request = true}
		table.insert(data.categories, 'de-adj lacking comparative')
	end
	args[1].label = "[[Appendix:Glossary#comparative|comparative]]"
	table.insert(data.inflections, args[1])
	
	if #args[2] > 0 then
		for i, form in ipairs(args[2]) do
			args[2][i] = {
				term = 'am [[' ..  (form == 'sten' and PAGENAME .. 'sten' or form) .. ']]',
				accel = 'superlative-form-of'}
		end
	else
		args[2] = {request = true}
		table.insert(data.categories, 'de-adj lacking superlative')
	end
	args[2].label = "[[Appendix:Glossary#superlative|superlative]]"
	table.insert(data.inflections, args[2])
end

pos_functions.nouns = function(class, args, data)
	params = {
		[1] = {list = 'g', default = '?'},
		[2] = {list = 'gen',
			default = (
				args[1] == 'm' or
				args[1] == 'm-s' or
				args[1] == 'n' or
				args[1] == 'n-s'
				) and PAGENAME .. 's' or PAGENAME},
		[3] = {list = 'pl'},
		[4] = {list = 'dim'},
		["head"] = {},
		["m"] = {list = true},
		["f"] = {list = true},
	}
	
	if data.pos_category == 'nouns' then
		params[3].default = PAGENAME .. 'en'
	end
	
	local args = require("Module:parameters").process(args, params)
	data.heads = {args["head"]}
	
	for _, g in ipairs(args[1]) do
		if legal_gender[g] then
			table.insert(data.genders, g)
			table.insert(data.categories, "German " .. gender_names[g] .. " nouns")
		else
			error("Gender “" .. g .. "” is not an valid German gender.")
		end
	end
	
	for i, form in ipairs(args[2]) do
		args[2][i] = {term = form, accel = 'genitive-form-of'}
	end
	args[2].label = "genitive"
	table.insert(data.inflections, args[2])
	
	if args[3][1] == '-' then
		table.insert(data.inflections, {label = 'no plural'})
		table.insert(data.categories, 'German uncountable nouns')
	elseif #args[3] > 0 then
		for i, form in ipairs(args[3]) do
			args[3][i] = {term = form, accel = 'plural-form-of'}
		end
		args[3].label = "plural"
		table.insert(data.inflections, args[3])
	end
	
	if #args[4] > 0 then
		for i, form in ipairs(args[4]) do
			args[4][i] = {
				term = form,
				genders = {'n'},
				accel = 'diminutive-form-of gender-n'
				}
		end
		args[4].label = "diminutive"
		table.insert(data.inflections, args[4])
	end
	
	if #args.f > 0 then
		args.f.label = "feminine"
		table.insert(data.inflections, args.f)
	end
	
	if #args.m > 0 then
		args.m.label = "masculine"
		table.insert(data.inflections, args.m)
	end
end

pos_functions["proper nouns"] = pos_functions.nouns

function export.detect_type(pr,pa,pp,ps)
	local args = {
		type = "",
		class = "",
	}
	local prefix = ""
	if mw.ustring.match(pr," ") then
		pr, prefix = mw.ustring.match(pr, "([^ ]+) (.+)")
		prefix = mw.ustring.gsub(prefix, " ", "")
	end
	pr = mw.ustring.gsub(pr, "e?t$", "")
	pa = mw.ustring.gsub(pa, " .+", "")
	ps = mw.ustring.gsub(ps, " .+", "")
	pp = mw.ustring.gsub(pp, " ", "")
	pp = mw.ustring.gsub(pp, prefix, "")
	pr = mw.ustring.gsub(pr, "ß", "ss")
	pa = mw.ustring.gsub(pa, "ß", "ss")
	pp = mw.ustring.gsub(pp, "ß", "ss")
	ps = mw.ustring.gsub(ps, "ß", "ss")
	local e = mw.ustring.match(pr, "[dt]$") and "e" or ""
	if pr .. e .. "te" == pa then
		args.type = 'weak'
	else
		local before, stem_vowel, long = mw.ustring.match(pr, "^(.-)([aeiouäöü]+)([^aeiouäöü]*)$")
		long = long or ""
		local short = long
		if mw.ustring.len(long) == 1 then
			short = long .. long
		elseif mw.ustring.match(long,"^h.$") then
			short = mw.ustring.gsub(long,"h(.)","%1%1")
		elseif mw.ustring.match(long,"^(.)%1") then
			long = mw.ustring.sub(long,1,1)
			short = long .. long
		end
		mw.log(pr,pa,pp,ps,before,stem_vowel,short,long)
		local function check(class, past, participle)
			participle = participle or past
			if pa == (before .. past .. long) then
				if pp == (before .. participle .. long .. "en") or pp == ("ge" .. before .. participle .. long .. "en") then
				args.type = "strong"
					args.class = type(class) == "string" and class or class()
					return true
				end
			elseif pa == (before .. past .. short) then
				if pp == (before .. participle .. short .. "en") or pp == ("ge" .. before .. participle .. short .. "en") then
					args.type = "strong"
					args.class = type(class) == "string" and class or class()
					return true
				end
			end
			return false
		end
		
		local function check_stem(class, stem)
			if mw.ustring.match(pr, stem .. "$") then
			args.type = "strong"
				args.class = class
				return true
			end
			return false
		end
		
		local done = false
		if stem_vowel == "ä" then
			done = check("3", "o", "o") or check("6", "u", "a") or check("7", "ie", "a")
		elseif stem_vowel == "au" then
			done = check("2", "o")
		elseif stem_vowel == "äu" then
			done = check("2", "o") or check("7", "ie", "au")
		elseif stem_vowel == "ei" then
			done = check("1", "ie") or check("1", "i") or check("7", "ie", "ei")
		elseif stem_vowel == "i" then
			local function distinguish()
				if ps then
					if ps == (before .. "ä" .. long .. "e") then
						return "4"
					else
						return "3"
					end
				else
					error("Please specify the past subjunctive by passing parameter 4")
				end
			end
			done = check("3", "a", "u") or check("3", "i", "o") or check("5", "a", "e")
			done = done or check("7", "ie", "e") or check(distinguish, "a", "o")
		elseif stem_vowel == "ie" then
			done = check("2", "o") or check("5", "a", "e") or check("7", "ie", "e")
		elseif stem_vowel == "ö" then
			done = check("7", "ie", "o")
		elseif stem_vowel == "ü" then
			done = check("2", "o") or check("7", "ie", "u")
		end
		if not done then
			done = check_stem("2", "zieh")
				or check_stem("3", "erlisch")
				or check_stem("3", "fich")
				or check_stem("3", "schall")
				or check_stem("4", "komm")
				or check_stem("4", "nimm")
				or check_stem("5", "iss")
				or check_stem("6", "heb")
				or check_stem("6", "schwör")
				or check_stem("7", "geh")
				or check_stem("7", "hau")
			args.type = "irregular"
		end
	end
	return args.type, args.class
end

pos_functions.verbs = function(class, args, data)
	params = {
		[1] = {list = 'present ='},
		[2] = {list = 'past ='},
		[3] = {list = 'past participle ='},
		["head"] = {},
		["type"] = {default = class},
		["auxiliary"] = {default = 'haben'},
	}
	
	if class ~= 'weak' or args.type ~= 'weak' then
		params[4] = {list = 'past subjunctive'}
	end
	if class == 'strong' or args.type == 'strong' then
		params.class = {default = nil}
	end
	local args = require("Module:parameters").process(args, params)
	data.heads = {args["head"]}
	
	if not args.type then
		args.type, args.class = detect_type(args[1][1],args[2][1],args[3][1],args[4][1])
	end
	
	if args.type == 'strong' then
		if not args.class then
			table.insert(data.inflections, {label = '[[Appendix:Glossary#strong verb|strong]]'})
			table.insert(data.categories, 'German strong verbs without classes')
		elseif legal_verb_classes[args.class] then
			table.insert(data.inflections, {label = 'class ' .. args.class .. ' [[Appendix:Glossary#strong verb|strong]]'})
			table.insert(data.categories, 'German class ' .. args.class .. ' strong verbs')
		else
			error("Strong verb class “" .. args.class .. "” is not an valid German class (1-7).")
		end
		table.insert(data.categories, 'German strong verbs')
	elseif args.type == 'weak' then
		table.insert(data.inflections, {label = '[[Appendix:Glossary#weak verb|weak]]'})
		table.insert(data.categories, 'German weak verbs')
	elseif args.type == 'irregular' then
		table.insert(data.inflections, {label = '[[Appendix:Glossary#irregular|irregular]]'})
		table.insert(data.categories, 'German irregular verbs')
	elseif not args.type then
		table.insert(data.categories, 'German verbs without conjugation types')
	else
		error("Verb type “" .. args.type .. "” is not an valid German type (“strong” or “weak”).")
	end
	
	if #args[1] == 0 then
		args[1] = {request = true}
	end
	args[1].label = 'third-person singular simple present'
	table.insert(data.inflections, args[1])
	
	if #args[2] == 0 then
		args[2] = {request = true}
	end
	args[2].label = 'past tense'
	table.insert(data.inflections, args[2])
	
	if #args[3] == 0 then
		args[3] = {request = true}
	end
	args[3].label = 'past participle'
	table.insert(data.inflections, args[3])
	
	if #args["past subjunctive"] > 0 then
		args["past subjunctive"].label = "past subjunctive"
		table.insert(data.inflections, args["past subjunctive"])
	end
	
	if args.auxiliary == 'haben' then
		args.auxiliary = {'haben'}
		table.insert(data.categories, 'German verbs using haben as auxiliary')
	elseif args.auxiliary == 'sein' then
		args.auxiliary = {'sein'}
		table.insert(data.categories, 'German verbs using sein as auxiliary')
	elseif args.auxiliary == 'both' then
		args.auxiliary = {'haben', 'sein'}
		table.insert(data.categories, 'German verbs using haben and sein as auxiliary')
	else
		error("Verb auxiliary “" .. args.auxiliary .. "” is not an valid German auxiliary (“haben”, “sein”, or “both”).")
	end
	args.auxiliary.label = "auxiliary"
	table.insert(data.inflections, args.auxiliary)
end

return export