local export = {}
local pos_functions = {}
local function track(page)
require("Module:debug").track("hsb-dsb-headword/" .. page)
return true
end
local function glossary_link(entry, text)
text = text or entry
return "[[Appendix:Glossary#" .. entry .. "|" .. text .. "]]"
end
-- The main entry point.
-- This is the only function that can be invoked from a template.
function export.show(frame)
local iparams = {
[1] = {required = true},
["lang"] = {required = true},
}
local iargs = require("Module:parameters").process(frame.args, iparams)
local poscat = iargs[1]
langcode = iargs.lang
if langcode ~= "hsb" and langcode ~= "dsb" then
error("This module currently only works for lang=hsb and lang=dsb")
end
local lang = require("Module:languages").getByCode(langcode)
local langname = lang:getCanonicalName()
local params = {
["head"] = {list = true},
["nolink"] = {type = "boolean"},
["nolinkhead"] = {type = "boolean", alias_of = "nolink"},
["suffix"] = {type = "boolean"},
["nosuffix"] = {type = "boolean"},
["json"] = {type = "boolean"},
["pagename"] = {}, -- for testing
}
if pos_functions[poscat] then
for key, val in pairs(pos_functions[poscat].params) do
params[key] = val
end
end
local parargs = frame:getParent().args
local args = require("Module:parameters").process(parargs, params)
local pagename = args.pagename or mw.loadData("Module:headword/data").pagename
local user_specified_heads = args.head
local heads = user_specified_heads
if args.nolink then
if #heads == 0 then
heads = {pagename}
end
end
local data = {
lang = lang,
langname = langname,
pos_category = poscat,
categories = {},
heads = heads,
user_specified_heads = user_specified_heads,
no_redundant_head_cat = #user_specified_heads == 0,
genders = {},
inflections = {},
categories = {},
pagename = pagename,
id = args.id,
force_cat_output = force_cat,
}
data.is_suffix = false
if args.suffix or (
not args.nosuffix and pagename:find("^%-") and poscat ~= "suffixes" and poscat ~= "suffix forms"
) then
data.is_suffix = true
data.pos_category = "suffixes"
local singular_poscat = require("Module:string utilities").singularize(poscat)
table.insert(data.categories, langname .. " " .. singular_poscat .. "-forming suffixes")
table.insert(data.inflections, {label = singular_poscat .. "-forming suffix"})
end
if pos_functions[poscat] then
pos_functions[poscat].func(args, data)
end
if args.json then
return require("Module:JSON").toJSON(data)
end
return require("Module:headword").full_headword(data)
end
local function get_noun_pos(is_proper)
local noun_inflection_specs = {
{"gen", "genitive singular"},
{"du", "nominative dual"},
{"pl", "nominative plural"},
{"genpl", "genitive plural"},
{"f", "feminine"},
{"m", "masculine"},
{"dim", "diminutive"},
{"pej", "pejorative"},
{"aug", "augmentative"},
{"adj", "related adjective"},
{"dem", "demonym"},
{"fdem", "female demonym"},
}
local params = {
["indecl"] = {type = "boolean"},
[1] = {list = "g"},
}
for _, spec in ipairs(noun_inflection_specs) do
local param, desc = unpack(spec)
params[param] = {list = true, disallow_holes = true}
params[param .. "\1q"] = {list = true, allow_holes = true}
end
return {
params = params,
func = function(args, data)
-- Compute allowed genders, and map incomplete genders to specs with a "?" in them.
local masc_genders = {"m", "mf", "mfbysense"}
local non_masc_genders = {false, "f", "n"}
local hsb_masc_animacies = {false, "in", "anml", "pr"}
local dsb_masc_animacies = {false, "in", "an"}
local numbers = {false, "d", "p"}
local allowed_genders = {}
local function insert_genders(genders, animacies, numbers, is_masc)
for _, g in ipairs(genders) do
for _, an in ipairs(animacies) do
for _, num in ipairs(numbers) do
local source_gender_parts = {}
local dest_gender_parts = {}
local function ins_part(part, partname)
if part then
table.insert(source_gender_parts, part)
table.insert(dest_gender_parts, part)
elseif partname == "g" and num == false or partname == "an" and is_masc then
-- allow incomplete gender duale tantum and plurale tantum nouns; also allow
-- incomplete animacy for fem/neut; otherwise insert a ? to indicate incomplete
-- gender spec
table.insert(dest_gender_parts, "?")
end
end
ins_part(g, "g")
ins_part(an, "an")
ins_part(num, "num")
if #source_gender_parts == 0 then
allowed_genders["?"] = "?"
else
allowed_genders[table.concat(source_gender_parts, "-")] =
table.concat(dest_gender_parts, "-")
end
end
end
end
end
if data.lang:getCode() == "hsb" then
insert_genders(masc_genders, hsb_masc_animacies, numbers, true)
else
insert_genders(masc_genders, dsb_masc_animacies, numbers, true)
end
insert_genders(non_masc_genders, {false}, numbers, false)
-- allow inanimate dual/plural; no gender distinction here
allowed_genders["in-d"] = "in-d"
allowed_genders["in-p"] = "in-p"
-- Gather genders
data.genders = args[1]
-- Validate and canonicalize genders
for i, g in ipairs(data.genders) do
if not allowed_genders[g] then
error("Unrecognized " .. data.langname .. " gender: " .. g)
else
data.genders[i] = allowed_genders[g]
end
end
local function process_inflection(label, infls, qs, frob)
infls.label = label
for i, infl in ipairs(infls) do
if frob then
infl = frob(infl)
end
if qs[i] then
infls[i] = {term = infl, q = {qs[i]}}
end
end
if #infls > 0 then
table.insert(data.inflections, infls)
end
end
if args.indecl then
table.insert(data.inflections, {label = glossary_link("indeclinable")})
end
-- Process all inflections.
for _, spec in ipairs(noun_inflection_specs) do
local param, desc = unpack(spec)
process_inflection(desc, args[param], args[param .. "q"])
end
end
}
end
pos_functions["nouns"] = get_noun_pos(false)
pos_functions["proper nouns"] = get_noun_pos(true)
return export