Module:snon-headword: Difference between revisions

From Linguifex
Jump to navigation Jump to search
Created page with "local export = {} local pos_functions = {} local m_links = require("Module:links") local m_table = require("Module:table") local m_en_util = require("Module:en-utilities") local lang = require("Module:languages").getByCode("snon") local langname = lang:getCanonicalName() local PAGENAME = mw.loadData("Module:headword/data").pagename local suffix_categories = { ["adjectives"] = true, ["adverbs"] = true, ["nouns"] = true, ["verbs"] = true, } local function glossary..."
 
No edit summary
 
(13 intermediate revisions by the same user not shown)
Line 5: Line 5:
local m_table = require("Module:table")
local m_table = require("Module:table")
local m_en_util = require("Module:en-utilities")
local m_en_util = require("Module:en-utilities")
local m_hw_util = require("Module:headword utilities")


local lang = require("Module:languages").getByCode("snon")
local lang = require("Module:languages").getByCode("snon")
local langname = lang:getCanonicalName()
local langname = lang:getCanonicalName()


local PAGENAME = mw.loadData("Module:headword/data").pagename
local pagename = mw.loadData("Module:headword/data").pagename


local suffix_categories = {
local suffix_categories = {
Line 17: Line 18:
["verbs"] = true,
["verbs"] = true,
}
}
local function glossary_link(...)
return require("Module:headword utilities").glossary_link(...)
end


local function do_inflection(data, forms, label, accel)
local function do_inflection(data, forms, label, accel)
Line 35: Line 32:
-- This is the only function that can be invoked from a template.
-- This is the only function that can be invoked from a template.
function export.show(frame)
function export.show(frame)
 
local poscat = frame.args[1] or error("Part of speech has not been specified. Please pass parameter 1 to the module invocation.")
local poscat = frame.args[1]
local parargs = frame:getParent().args
or error("Plural part of speech e.g. 'nouns' has not been specified. Please pass parameter 1 to the module invocation.")


local params = {
local params = {
["head"] = {list = true, disallow_holes = true},
["head"] = {list = true, disallow_holes = true},
["nomut"] = {type = "boolean"},
}
}


Line 69: Line 66:
pos_functions[poscat].func(args, data)
pos_functions[poscat].func(args, data)
end
end
 
if params.nomut then
table.insert(data.inflections, {label = "not mutable"})
table.insert(data.categories, langname .. " non-mutable terms")
end
return require("Module:headword").full_headword(data)
return require("Module:headword").full_headword(data)
end
end


local allowed_genders = {
-----------------------------------------------------------------------------------------
["m"] = true,
--                                          Nouns                                      --
["f"] = true,
-----------------------------------------------------------------------------------------
["mf"] = true,
 
["mfbysense"] = true,
local allowed_genders = m_table.listToSet(
["p"] = true,
    {"m", "f", "mf", "mfbysense", "mfequiv", "gneut", "n", "m-p", "f-p", "mf-p", "mfbysense-p", "mfequiv-p", "gneut-p", "n-p", "?", "?-p"}
["m-p"] = true,
)
["f-p"] = true,
["mf-p"] = true,
["mfbysense-p"] = true,
}


local function noun_params(args)
local function validate_genders(genders)
local params = {
for _, g in ipairs(genders) do
[1] = {alias_of = "g", list = false},
if type(g) == "table" then
["g"] = {list = true}, --gender(s)
g = g.spec
["f"] = {list = true}, --feminine form(s)
end
["m"] = {list = true}, --masculine form(s)
if not allowed_genders[g] then
["nomut"] = {type = "boolean"},
error("Unrecognized gender: " .. g)
}
end
if args[1] and args[1]:find("p$") then
params[2] = {alias_of = "sg", list = false}
params["sg"] = {list = true}
params["msg"] = {list = true}
params["fsg"] = {list = true}
else
params[2] = {alias_of = "pl", list = false}
params["pl"] = {list = true}
end
end
return params
end
end


local function do_nouns(pos, args, data)
local function do_noun(args, data, is_proper)
local genders = {}
local is_plurale_tantum = false
for _, g in ipairs(args.g) do
local category_pos = m_en_util.singularize(data.pos_category)
if not allowed_genders[g] then
 
error("Unrecognized gender: " .. g)
validate_genders(args[1])
data.genders = args[1]
-- Check for specific genders and pluralia tantum.
for _, g in ipairs(args[1]) do
if type(g) == "table" then
g = g.spec
end
if g:find("-p$") then
is_plurale_tantum = true
end
end
table.insert(genders, g)
end
end


local plpos = m_en_util.pluralize(pos)
local lemma = data.pagename


-- Check for special plural signals
local plurals = {}
local mode = nil


if args.pl then
local function insert_noun_inflection(terms, label, accel)
-- not a plurale tantum
m_hw_util.insert_inflection {
if args.pl[1] == "?" or args.pl[1] == "!" or args.pl[1] == "-" or args.pl[1] == "~" or args.pl[1] == "#" then
headdata = data,
mode = args.pl[1]
terms = terms,
table.remove(args.pl, 1) -- Remove the mode parameter
label = label,
accel = accel and {form = accel} or nil,
}
end
local function make_plural(term)
return {{term = term .. "ar"}}
end
if is_plurale_tantum then
if args[2][1] then
error("Can't specify plurals of plurale tantum " .. category_pos)
end
end
else
plurals = m_hw_util.parse_term_list_with_modifiers {
paramname = {2, "pl"},
forms = args[2],
splitchar = ",",
}
-- Check for special plural signals
local mode = nil


local countable, uncountable
local pl1 = plurals[1]
if pl1 and #pl1.term == 1 then
mode = pl1.term
if mode == "?" or mode == "!" or mode == "-" or mode == "~" then
pl1.term = nil
if next(pl1) then
error(("Can't specify inline modifiers with plural code '%s'"):format(mode))
end
table.remove(plurals, 1)  -- Remove the mode parameter
elseif mode ~= "+" and mode ~= "#" then
error(("Unexpected plural code '%s'"):format(mode))
end
end
if args.mut then
local mutation = {
["r"] = "radical", ["l"] = "lenite", ["e"] = "eclipse"
}
table.insert(data.inflections, {label = mutation[args.mut]})
end
if is_plurale_tantum then
-- both singular and plural
table.insert(data.inflections, {label = "sometimes " .. m_hw_util.glossary_link("plural only") .. ", in variation"})
end
if mode == "?" then
if mode == "?" then
-- Plural is unknown
-- Plural is unknown
table.insert(data.categories, langname .. " " .. plpos .. " with unknown or uncertain plurals")
table.insert(data.categories, langname .. " " .. data.pos_category .. " with unknown or uncertain plurals")
elseif mode == "!" then
elseif mode == "!" then
-- Plural is not attested
-- Plural is not attested
table.insert(data.inflections, {label = "plural not attested"})
table.insert(data.inflections, {label = "plural not attested"})
table.insert(data.categories, langname .. " " .. plpos .. " with unattested plurals")
table.insert(data.categories, langname .. " " .. data.pos_category .. " with unattested plurals")
return
if plurals[1] then
error("Can't specify any plurals along with unattested plural code '!'")
end
elseif mode == "-" then
elseif mode == "-" then
-- Uncountable noun; may occasionally have a plural
-- Uncountable noun; may occasionally have a plural
uncountable = true
insert(data.categories, langname .. " uncountable " .. data.pos_category)
 
-- If plural forms were given explicitly, then show "usually"
-- If plural forms were given explicitly, then show "usually"
if #args.pl > 0 then
if plurals[1] then
table.insert(data.inflections, {label = "usually " .. glossary_link("uncountable")})
table.insert(data.inflections, {label = "usually " .. m_hw_util.glossary_link("uncountable")})
countable = true
table.insert(data.categories, langname .. " countable " .. data.pos_category)
else
else
table.insert(data.inflections, {label = glossary_link("uncountable")})
table.insert(data.inflections, {label = m_hw_util.glossary_link("uncountable")})
end
else
-- Countable or mixed countable/uncountable
if not plurals[1] and not is_proper then
plurals[1] = {term = "+"}
end
end
elseif mode == "~" then
if mode == "~" then
-- Mixed countable/uncountable noun, always has a plural
-- Mixed countable/uncountable noun, always has a plural
table.insert(data.inflections, {label = glossary_link("countable") .. " and " .. glossary_link("uncountable")})
table.insert(data.inflections, {label = m_hw_util.glossary_link("countable") .. " and " .. m_hw_util.glossary_link("uncountable")})
uncountable = true
table.insert(data.categories, langname .. " uncountable " .. data.pos_category)
countable = true
table.insert(data.categories, langname .. " countable " .. data.pos_category)
elseif mode == "#" or pos == "noun" then
elseif plurals[1] then
-- Countable nouns; the default for regular nouns but not proper nouns
-- Countable nouns
if mode == "#" then
table.insert(data.categories, langname .. " countable " .. data.pos_category)
table.insert(data.inflections, {label = glossary_link("countable")})
else
-- Uncountable nouns
table.insert(data.categories, langname .. " uncountable " .. data.pos_category)
end
end
countable = true
end
end


if countable then
local new_plurals = {}
table.insert(data.categories, langname .. " countable " .. plpos)
for _, pl in ipairs(plurals) do
if pl.term == "+" then
for _, generated_pl in ipairs(make_plural(lemma)) do
table.insert(new_plurals, generated_pl)
end
else
table.insert(new_plurals, pl)
end
end
end
if uncountable and pos == "noun" then
plurals = new_plurals
table.insert(data.categories, langname .. " uncountable " .. plpos)
end
 
if #args.pl > 0 then
local plurals = {}


for _, pl in ipairs(args.pl) do
insert_noun_inflection(plurals, "plural", "p")
m_table.insertIfNot(plurals, pl)
end


do_inflection(data, plurals, "plural", {form = "p"})
if plurals[2] then
end
table.insert(data.categories, langname .. " " .. data.pos_category .. " with multiple plurals")
else
-- plurale tantum or "plural-basic" lemma (cases where the plural is the basic lemma and the
-- singular is derived from it)
local function has_singular(sgargs)
return #sgargs > 0 and sgargs[1] ~= "-"
end
local new_g = {}
for _, g in ipairs(genders) do
if g ~= "p" then
g = g:gsub("%-p$", "")
table.insert(new_g, g)
end
end
genders = nil
if has_singular(args.sg) or has_singular(args.msg) or has_singular(args.fsg) then
table.insert(data.inflections, {label = glossary_link("plural")})
table.insert(data.categories, langname .. " plural-basic " .. plpos)
end
local function do_singular(sgargs, label, accel, genders)
if sgargs then
if sgargs[1] == "-" then
table.insert(data.inflections, {label = "no " .. label})
else
if genders then
for i, sgarg in ipairs(sgargs) do
sgargs[i] = {term = sgarg, genders = genders}
end
end
do_inflection(data, sgargs, label, accel)
end
end
end
end
do_singular(args.sg, glossary_link("singular"), {form = "singular"}, new_g)
do_singular(args.msg, "masculine " .. glossary_link("singular"), nil, {"m"})
do_singular(args.fsg, "feminine " .. glossary_link("singular"), nil, {"f"})
end
end
do_inflection(data, args.f, "feminine")
end
do_inflection(data, args.m, "masculine")
 
do_inflection(data, args.dim, glossary_link("diminutive"))
local function get_noun_params(is_proper)
data.genders = genders
return {
[1] = {list = "g", disallow_holes = true, required = not is_proper, default = "?", type = "genders", flatten = true},
[2] = {list = "pl", disallow_holes = true},
["mut"] = {set = {"r", "l", "e"}}
}
end
end


pos_functions["nouns"] = {
pos_functions["nouns"] = {
params = noun_params,
params = get_noun_params(),
func = function(args, data)
func = do_noun,
return do_nouns("noun", args, data)
end,
}
}


pos_functions["proper nouns"] = {
pos_functions["proper nouns"] = {
params = noun_params,
params = get_noun_params("is proper"),
func = function(args, data)
func = function(args, data)
return do_nouns("proper noun", args, data)
do_noun(args, data, "is proper noun")
end,
end,
}
}
local function pos_with_gender()
return {
params = {
["g"] = {list = true},
["mut"] = {type = "boolean"},
},
func = function(args, data)
data.genders = args["g"]
end,
}
end
pos_functions.numerals = pos_with_gender()
pos_functions["adjective forms"] = pos_with_gender()
pos_functions["determiner forms"] = pos_with_gender()
pos_functions["noun forms"] = pos_with_gender()
pos_functions["noun plural forms"] = pos_with_gender()
pos_functions["numeral forms"] = pos_with_gender()
pos_functions["pronoun forms"] = pos_with_gender()
pos_functions["singulatives"] = pos_with_gender()
pos_functions["verb forms"] = pos_with_gender()


return export
return export

Latest revision as of 20:31, 6 May 2026

export.show

function export.show(frame)

This function lacks documentation. Please add a description of its usages, inputs and outputs, or its difference from similar functions, or make it local to remove it from the function list.


local export = {}
local pos_functions = {}

local m_links = require("Module:links")
local m_table = require("Module:table")
local m_en_util = require("Module:en-utilities")
local m_hw_util = require("Module:headword utilities")

local lang = require("Module:languages").getByCode("snon")
local langname = lang:getCanonicalName()

local pagename = mw.loadData("Module:headword/data").pagename

local suffix_categories = {
	["adjectives"] = true,
	["adverbs"] = true,
	["nouns"] = true,
	["verbs"] = true,
}

local function do_inflection(data, forms, label, accel)
	if forms and #forms > 0 then
		forms.label = label
		if accel then
			forms.accel = accel
		end
		table.insert(data.inflections, forms)
	end
end

-- The main entry point.
-- This is the only function that can be invoked from a template.
function export.show(frame)
	local poscat = frame.args[1] or error("Part of speech has not been specified. Please pass parameter 1 to the module invocation.")
	local parargs = frame:getParent().args

	local params = {
		["head"] = {list = true, disallow_holes = true},
		["nomut"] = {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(parargs, params)

	local heads = args.head
	if #heads == 0 then
		heads = {pagename}
	end

	local data = {
		lang = lang,
		pos_category = poscat,
		categories = {},
		heads = heads,
		genders = {},
		inflections = {},
		pagename = pagename,
	}

	if pos_functions[poscat] then
		pos_functions[poscat].func(args, data)
	end

	return require("Module:headword").full_headword(data)
end

-----------------------------------------------------------------------------------------
--                                          Nouns                                      --
-----------------------------------------------------------------------------------------

local allowed_genders = m_table.listToSet(
    {"m", "f", "mf", "mfbysense", "mfequiv", "gneut", "n", "m-p", "f-p", "mf-p", "mfbysense-p", "mfequiv-p", "gneut-p", "n-p", "?", "?-p"}
)

local function validate_genders(genders)
	for _, g in ipairs(genders) do
		if type(g) == "table" then
			g = g.spec
		end
		if not allowed_genders[g] then
			error("Unrecognized gender: " .. g)
		end
	end
end

local function do_noun(args, data, is_proper)
	local is_plurale_tantum = false
	local category_pos = m_en_util.singularize(data.pos_category)

	validate_genders(args[1])
	data.genders = args[1]
	-- Check for specific genders and pluralia tantum.
	for _, g in ipairs(args[1]) do
		if type(g) == "table" then
			g = g.spec
		end
		if g:find("-p$") then
			is_plurale_tantum = true
		end
	end

	local lemma = data.pagename

	local plurals = {}

	local function insert_noun_inflection(terms, label, accel)
		m_hw_util.insert_inflection {
			headdata = data,
			terms = terms,
			label = label,
			accel = accel and {form = accel} or nil,
		}
	end
	
	local function make_plural(term)
		return {{term = term .. "ar"}}
	end
	
	if is_plurale_tantum then
		if args[2][1] then
			error("Can't specify plurals of plurale tantum " .. category_pos)
		end
	else
		plurals = m_hw_util.parse_term_list_with_modifiers {
			paramname = {2, "pl"},
			forms = args[2],
			splitchar = ",",
		}
		-- Check for special plural signals
		local mode = nil

		local pl1 = plurals[1]
		if pl1 and #pl1.term == 1 then
			mode = pl1.term
			if mode == "?" or mode == "!" or mode == "-" or mode == "~" then
				pl1.term = nil
				if next(pl1) then
					error(("Can't specify inline modifiers with plural code '%s'"):format(mode))
				end
				table.remove(plurals, 1)  -- Remove the mode parameter
			elseif mode ~= "+" and mode ~= "#" then
				error(("Unexpected plural code '%s'"):format(mode))
			end
		end
		
		if args.mut then
			local mutation = {
				["r"] = "radical", ["l"] = "lenite", ["e"] = "eclipse"
			}
			
			table.insert(data.inflections, {label = mutation[args.mut]})
		end
		
		if is_plurale_tantum then
			-- both singular and plural
			table.insert(data.inflections, {label = "sometimes " .. m_hw_util.glossary_link("plural only") .. ", in variation"})
		end
		if mode == "?" then
			-- Plural is unknown
			table.insert(data.categories, langname .. " " .. data.pos_category .. " with unknown or uncertain plurals")
		elseif mode == "!" then
			-- Plural is not attested
			table.insert(data.inflections, {label = "plural not attested"})
			table.insert(data.categories, langname .. " " .. data.pos_category .. " with unattested plurals")
			if plurals[1] then
				error("Can't specify any plurals along with unattested plural code '!'")
			end
		elseif mode == "-" then
			-- Uncountable noun; may occasionally have a plural
			insert(data.categories, langname .. " uncountable " .. data.pos_category)

			-- If plural forms were given explicitly, then show "usually"
			if plurals[1] then
				table.insert(data.inflections, {label = "usually " .. m_hw_util.glossary_link("uncountable")})
				table.insert(data.categories, langname .. " countable " .. data.pos_category)
			else
				table.insert(data.inflections, {label = m_hw_util.glossary_link("uncountable")})
			end
		else
			-- Countable or mixed countable/uncountable
			if not plurals[1] and not is_proper then
				plurals[1] = {term = "+"}
			end
			if mode == "~" then
				-- Mixed countable/uncountable noun, always has a plural
				table.insert(data.inflections, {label = m_hw_util.glossary_link("countable") .. " and " .. m_hw_util.glossary_link("uncountable")})
				table.insert(data.categories, langname .. " uncountable " .. data.pos_category)
				table.insert(data.categories, langname .. " countable " .. data.pos_category)
			elseif plurals[1] then
				-- Countable nouns
				table.insert(data.categories, langname .. " countable " .. data.pos_category)
			else
				-- Uncountable nouns
				table.insert(data.categories, langname .. " uncountable " .. data.pos_category)
			end
		end

		local new_plurals = {}
		for _, pl in ipairs(plurals) do
			if pl.term == "+" then
				for _, generated_pl in ipairs(make_plural(lemma)) do
					table.insert(new_plurals, generated_pl)
				end
			else
				table.insert(new_plurals, pl)
			end
		end
		plurals = new_plurals

		insert_noun_inflection(plurals, "plural", "p")

		if plurals[2] then
			table.insert(data.categories, langname .. " " .. data.pos_category .. " with multiple plurals")
		end
	end
end

local function get_noun_params(is_proper)
	return {
		[1] = {list = "g", disallow_holes = true, required = not is_proper, default = "?", type = "genders", flatten = true},
		[2] = {list = "pl", disallow_holes = true},
		["mut"] = {set = {"r", "l", "e"}}
	}
end

pos_functions["nouns"] = {
	params = get_noun_params(),
	func = do_noun,
}

pos_functions["proper nouns"] = {
	params = get_noun_params("is proper"),
	func = function(args, data)
		do_noun(args, data, "is proper noun")
	end,
}

return export