Documentation for this module may be created at Module:fr-headword/doc

local export = {}
local pos_functions = {}

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

-- The main entry point.
-- This is the only function that can be invoked from a template.
function export.show(frame)
	PAGENAME = mw.title.getCurrentTitle().text
	
	local poscat = frame.args[1] or error("Part of speech has not been specified. Please pass parameter 1 to the module invocation.")
	
	local params = {
		["head"] = {list = true, default = ""},
		["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 = {heads = args["head"], genders = {}, inflections = {}, categories = {}}
	
	if args["suff"] then
		table.insert(data.categories, lang:getCanonicalName() .. " suffixes")
		
		if poscat == "adjectives" then
			table.insert(data.categories, lang:getCanonicalName() .. " adjective-forming suffixes")
		elseif poscat == "adverbs" then
			table.insert(data.categories, lang:getCanonicalName() .. " adverb-forming suffixes")
		elseif poscat == "nouns" then
			table.insert(data.categories, lang:getCanonicalName() .. " noun-forming suffixes")
		elseif poscat == "verbs" then
			table.insert(data.categories, lang:getCanonicalName() .. " verb-forming suffixes")
		else
			error("No category exists for suffixes forming " .. poscat .. ".")
		end
	else
		table.insert(data.categories, lang:getCanonicalName() .. " " .. poscat)
	end
	
	if pos_functions[poscat] then
		pos_functions[poscat].func(args, data)
	end
	
	return require("Module:headword").full_headword(lang, nil, data.heads, nil, data.genders, data.inflections, data.categories, nil)
end

pos_functions["nouns"] = {
	params = {
		[1] = {},
		["g2"] = {},
		[2] = {list = true},
		["f"] = {list = true},
		["m"] = {list = true},
		},
	func = function(args, data)
		-- Gather genders
		local gender = args[1]
		local gender2 = args["g2"]
		
		if gender == "mf" then
			table.insert(data.genders, "m")
			table.insert(data.genders, "f")
		else
			table.insert(data.genders, gender)
			table.insert(data.genders, gender2)
		end
		
		-- Gather all the plural parameters from the numbered parameters.
		local plurals = args[2]
		plurals.label = "ពហុវចនៈ"
		plurals.accel = "plural-form-of"
		plurals.request = true
		
		-- Gather all the feminine parameters
		local feminines = args["f"]
		feminines.label = "feminine"
		
		-- Gather all the masculine parameters
		local masculines = args["m"]
		masculines.label = "masculine"
		
		-- Add categories for genders
		if #data.genders == 0 then
			table.insert(data.genders, "?")
		end
		
		local mode = nil
		
		for _, g in ipairs(data.genders) do
			if g == "m-p" or g == "f-p" then
				mode = "p"
			end
			
			if g == "m" then
				table.insert(data.categories, "French masculine nouns")
			elseif g == "f" then
				table.insert(data.categories, "French feminine nouns")
			end
		end
		
		-- Decide how to show the plurals
		mode = mode or plurals[1]
		
		-- Plural is not attested
		if mode == "!" then
			table.insert(data.inflections, {label = "plural not attested"})
			table.insert(data.categories, "French nouns with unattested plurals")
		-- Plural-only noun, doesn't have a plural
		elseif mode == "p" then
			table.insert(data.inflections, {label = "plural only"})
			table.insert(data.categories, "French pluralia tantum")
		else
			-- Plural is unknown
			if mode == "?" then
				table.remove(plurals, 1)  -- Remove the mode parameter
			-- Uncountable noun; may occasionally have a plural
			elseif mode == "-" then
				table.remove(plurals, 1)  -- Remove the mode parameter
				table.insert(data.categories, "French uncountable nouns")
				
				-- If plural forms were given explicitly, then show "countable" as well
				if #plurals > 0 then
					table.insert(data.inflections, {label = "countable or [[Appendix:Glossary#uncountable|uncountable]]"})
					table.insert(data.categories, "French countable nouns")
				else
					table.insert(data.inflections, {label = "[[Appendix:Glossary#uncountable|uncountable]]"})
				end
			-- The default, always has a plural
			else
				table.insert(data.categories, "French countable nouns")
				
				-- If no plural was given, add a default one now
				if #plurals == 0 then
					if mw.ustring.find(PAGENAME,'s$') then
						table.insert(plurals, PAGENAME)
					elseif mw.ustring.find(PAGENAME,'[ae]u$') then
						table.insert(plurals, "x")
					elseif mw.ustring.find(PAGENAME,'al$') then
						table.insert(plurals, mw.ustring.sub(PAGENAME, 1, -3) .. 'aux')
					else
						table.insert(plurals, "s")
					end
				end
			end
			
			-- Process the plural forms
			for i, pl in ipairs(plurals) do
				if pl == "s" then
					plurals[i] = PAGENAME .. "s"
				elseif pl == "x" then
					plurals[i] = PAGENAME .. "x"
				end
				
				if not mw.title.new(pl).exists then
					table.insert(data.categories, "French nouns with missing plurals")
				end	
			end
	
			-- Add the plural forms
			if mode ~= "-" or #plurals > 0 then
				table.insert(data.inflections, plurals)
			end
		end
		
		-- Add the feminine forms
		if #feminines > 0 then
			table.insert(data.inflections, feminines)
			
			for _, f in ipairs(feminines) do
				if not mw.title.new(f).exists then
					table.insert(data.categories, "French nouns with missing forms")
				end
			end
		end
		
		-- Add the masculine forms
		if #masculines > 0 then
			table.insert(data.inflections, masculines)
			
			for _, m in ipairs(masculines) do
				if not mw.title.new(m).exists then
					table.insert(data.categories, "French adjectives with missing forms")
				end
			end
		end
	end
}

return export