Module:io-headword

From Wiktionary, the free dictionary
Jump to navigation Jump to search
This module needs documentation.
Please document this module by describing its purpose and usage on the documentation page.

local export = {}
local pos_functions = {}

local PAGENAME = mw.title.getCurrentTitle().text 
local lang = require("Module:languages").getByCode("io")
local except = require("Module:io-headword/exceptions")
local participle_pattern = "[aio]n?t[aeo]?$"

local function monosyllabic(word)
	local _, n = mw.ustring.gsub(word, "[AEIOUaeiou]", "")
	return n == 1
end

local function check(data, tracking_categories)
	local catname = "Ido nouns with red links in their headword lines"
	
	for _,entry in ipairs(data.check) do
		local t = mw.title.new(entry)
		if t and not t.exists then
			table.insert(tracking_categories, catname)
		end
	end
end

local function getPOS(word)
	-- delete anything after "de"
	word = mw.ustring.gsub(word, " de .+$", "")
	
	-- deal with letters
	if mw.ustring.match(word,"^[aeiou]$") or mw.ustring.match(word,"^[bcdefghijklmnoprstuvwxyz]o$") then
		return "nouns"
	end
	
	-- deal with some exceptions
	if except[word] then
		return except[word]
	end
	
	-- Words with only one vowel are always irregular
	if monosyllabic(word) then
		return nil
	elseif word:find(participle_pattern) then -- detect this firstly
		return "participles"
	elseif word:find("a$") then
		return "adjectives"
	elseif word:find("e$") then
		return "adverbs"
	elseif word:find("u$") then
		return "pronouns"
	elseif word:find("o$") then
		if mw.ustring.find(word, "^%u") then
			return "proper nouns"
		else
			return "nouns"
		end
	elseif word:find("i$") then
		if mw.ustring.find(word, "^%u") then
			return "proper noun forms"
		else
			return "noun forms"
		end
	elseif word:find("ar$") then
		return "verbs"
	elseif word:find("[iaou]s$") or word:find("ez$") then
		return "verb forms"
	else
		return nil
	end
end

-- The main entry point
function export.show(frame)
	local tracking_categories = {}
	
	local poscat = frame:getParent().args["pos"] or frame.args["poscat"] or getPOS(PAGENAME)
	
	if not poscat then
		if mw.title.getCurrentTitle().nsText == "Template" then
			poscat = "nouns"
		else
			error("Part of speech of \"" .. PAGENAME .. "\" cannot be automatically determined.")
		end
	end
	
	local params = {
		["head"] = {list = true},
		["pos"] = {},
		["suff"] = {type = "boolean"},
	}
	
	if pos_functions[poscat] then
		for key, val in pairs(pos_functions[poscat].params) do
			params[key] = val
		end
	end
	
	local args = require("Module:parameters").process(frame:getParent().args, params)
	local data = {lang = lang, pos_category = poscat, categories = {}, heads = args["head"], genders = {}, inflections = {}, check = {}}
	
	if pos_functions[poscat] then
		pos_functions[poscat].func(args, data)
	end
	
	check(data, tracking_categories)
	
	return require("Module:headword").full_headword(data) .. require("Module:utilities").format_categories(tracking_categories, lang)
end

pos_functions["determiners"] = {
	params = {
	},
	func = function(args, data)
		table.insert(data.inflections, {label = "plural", accel = {form = "p"}, PAGENAME .. "i"})
		table.insert(data.check, PAGENAME .. "i")
	end
}

pos_functions["nouns"] = {
	params = {
		[1] = {list = true, allow_holes = true},
	},
	func = function(args, data)
		local stem = PAGENAME:sub(1, -2)
		-- Get the parameters
		local inflected_words_specified = false
		local inflected_words = {}
		
		for i = 1, args[1].maxindex do
			local word = args[1][i]
			
			if word == "+" or word == "-" then
				word = nil
			end
			
			if word then
				inflected_words[word] = true
				inflected_words_specified = true
			end
		end
		
		local pl = {}

		-- Split multi-word terms
		for word in mw.text.gsplit(PAGENAME, " ", true) do
			local pos = getPOS(word)
			
			-- Inflect each word separately
			if (not inflected_words_specified or inflected_words[word]) and (pos == "adjectives" or pos == "nouns" or pos == "proper nouns") then
				local is_letter = ""
				if mw.ustring.match(word,"^[aeiou]$") or mw.ustring.match(word,"^[bcdefghijklmnoprstuvwxyz]o$")then
					is_letter = "-o"
				end
				table.insert(pl, stem .. "i")
			else
				table.insert(pl, word)
			end
		end
		
		-- Merge back together
		pl = table.concat(pl, " ")

		local pl2
		
		if args[1][1] == "-" then
			table.insert(data.inflections, {label = "[[Appendix:Glossary#uncountable|uncountable]]"})
			table.insert(data.categories, lang:getCanonicalName() .. " uncountable nouns")
		else
			table.insert(data.inflections, {label = "plural", accel = {form = "p"}, pl, pl2})
			table.insert(data.check, pl)
		end
	end
}

pos_functions["proper nouns"] = {
	params = {
		[1] = {list = true, allow_holes = true},
	},
	func = function(args, data)
		-- Get the parameters
		local inflected_words_specified = false
		local inflected_words = {}
		
		for i = 1, args[1].maxindex do
			local word = args[1][i]
			
			if word == "+" or word == "-" then
				word = nil
			end
			
			if word then
				inflected_words[word] = true
				inflected_words_specified = true
			end
		end
		
		local pl = {}

		local de = false
		
		-- Split multi-word terms
		for word in mw.text.gsplit(PAGENAME, " ", true) do
			local pos = getPOS(word)
			
			if word == "de" then de = true end
			
			-- Inflect each word separately
			if (not inflected_words_specified or inflected_words[word]) and (pos == "adjectives" or pos == "nouns" or pos == "proper nouns" or mw.ustring.match(word,'[aio]$') and not monosyllabic(word)) and not de then
				table.insert(pl, word .. "i")
			else
				table.insert(pl, word)
			end
		end
		
		-- Merge back together
		pl = table.concat(pl, " ")

		if args[1][1] == "+" then
			table.insert(data.inflections, {label = "plural", accel = {form = "p"}, pl})
			table.insert(data.check, pl)
		else
		end
	end
}

pos_functions["verbs"] = {
	params = {
	},
	func = function(args, data)
		local stem = PAGENAME:sub(1, -3)
		
		table.insert(data.inflections, {label = "present", stem .. "as"})
		table.insert(data.inflections, {label = "past", stem .. "is"})
		table.insert(data.inflections, {label = "future", stem .. "os"})
		table.insert(data.inflections, {label = "conditional", stem .. "us"})
		table.insert(data.inflections, {label = "imperative", stem .. "ez"})
	end
}

pos_functions["noun forms"] = {
	params = {
		[1] = {},
	},
	func = function(args, data)
		if args[1] == "p" or args[1] == "p+" then
			table.insert(data.genders, "p")
			data.categories = {"Ido nouns", "Ido pluralia tantum"}
			if args[1] == "p+" then
				local singular = mw.ustring.gsub(PAGENAME, "i$", "")
				table.insert(data.inflections, {label = "singular", singular})
				table.insert(data.check, singular)
			end
		end
	end
}

pos_functions["pluralia tantum"] = {
	params = {
		[1] = {},
	},
	func = function(args, data)
		table.insert(data.categories, 1, "Ido nouns")
		if args[1] == "+" then
			local singular = mw.ustring.gsub(PAGENAME, "i$", "")
			table.insert(data.inflections, {label = "singular", singular})
			table.insert(data.check, singular)
		end
	end
}

pos_functions["participles"] = {
	params = {
		[1] = {}, [2] = {}, --these will be phased out
	},
	func = function(args, data)
		local ending = mw.ustring.match(PAGENAME, participle_pattern)
		if ending then
			local vowel, consonant = ending:match("([aeio])$")
			if consonant == "" then
				if vowel == "a" or vowel == "o" then
					table.insert(data.inflections, {label = "plural", PAGENAME .. "j"})
					table.insert(data.check, PAGENAME .. "i")
				elseif vowel == "e" then
					data.categories = {"Ido adverbial participles"}
				end
			elseif vowel == "e" then
				error("-e" .. consonant .. " is not a valid participle ending!")
			end
			if vowel == "a" then
				data.categories = {"Ido adjectival participles"}
			elseif vowel == "o" then
				data.categories = {"Ido nominal participles"}
			end
		else
			error("This term is not a participle!")
		end
	end
}

return export