local export = {}
local pos_functions = {}
local en_utilities_module = "Module:en-utilities"
local table_module = "Module:table"
local m_table -- defined when needed
local dump = mw.dumpObject
local insert = table.insert
local remove = table.remove
local lang = require("Module:languages").getByCode("bg")
local langname = lang:getCanonicalName()
local alias_of_comp_not_list = {alias_of = "comp", list = false}
local alias_of_sup_not_list = {alias_of = "sup", list = false}
local boolean = {type = "boolean"}
local list = {list = true}
local genders = {"m", "m-p", "f", "f-p", "n", "n-p", "p", "mf", "mf-p", "mfbysense", "mfbysense-p"}
local genders_param = {list = true, set = genders}
local function track(page)
require("Module:debug/track")("bg-headword/" .. page)
return true
end
local function glossary_link(anchor, text)
return "]"
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 or error("Part of speech has not been specified. Please pass parameter 1 to the module invocation.")
local params = {
= {list = true, disallow_holes = true},
= {alias_of = "head", list = false},
= {list = true, allow_holes = true},
= true,
= boolean,
= boolean,
= boolean,
= true, -- for testing
}
if pos_functions then
for key, val in pairs(pos_functions.params) do
params = val
end
end
local args = require("Module:parameters").process(frame:getParent().args, 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.nolinkhead then
local heads_n = #heads
if heads_n == 0 then
heads = pagename
elseif heads_n == 1 and heads == pagename then
track("redundant-head")
end
end
local is_suffix = pagename:find("^%-") and poscat ~= "suffix forms"
local orig_poscat = poscat
poscat = pos_functions.overriding_poscat or poscat
local data = {
lang = lang,
-- FIXME: Is the following necessary?
pos_category = (mw.title.getCurrentTitle().nsText == "Reconstruction" and "reconstructed " or "") ..
(is_suffix and "suffixes" or poscat),
orig_poscat = orig_poscat,
is_suffix = is_suffix,
categories = {},
heads = heads,
user_specified_heads = user_specified_heads,
no_redundant_head_cat = #user_specified_heads == 0,
inflections = {},
pagename = pagename,
id = args.id,
}
if is_suffix then
local singular_poscat = require(en_utilities_module).singularize(poscat)
insert(data.categories, langname .. " " .. singular_poscat .. "-forming suffixes")
insert(data.inflections, {label = singular_poscat .. "-forming suffix"})
end
if pos_functions then
pos_functions.func(args, data, is_suffix)
end
if args.json then
return require("Module:JSON").toJSON(data)
end
return require("Module:headword").full_headword(data)
end
-- Returns the lemma we should use in acceleration tags, which contains
-- the stress mark for polysyllabic words.
local function get_accel_lemma(data)
local accel_lemma
if #data.heads > 0 then
accel_lemma = data.heads
else
accel_lemma = data.pagename
end
return accel_lemma
end
local function insert_infl(data, forms, label, accel)
if forms and #forms > 0 then
forms.label = label
if accel then
accel.lemma = get_accel_lemma(data)
forms.accel = accel
end
insert(data.inflections, forms)
end
end
local function handle_infl(args, data, argpref, label, accel)
insert_infl(data, args, label, accel)
end
pos_functions = {
params = {
= {set = {"pf", "impf", "both", "biasp", "?"}, default = "?"},
= list,
= list,
= boolean,
},
func = function(args, data)
m_table = m_table or require(table_module)
local aspect = args
if aspect == "both" then
aspect = "biasp"
end
data.genders = {aspect}
handle_infl(args, data, "pf", "perfective")
handle_infl(args, data, "impf", "imperfective")
if args.impers then
insert(data.inflections, {label = "impersonal"})
data.gloss = "third-singular present indicative"
else
data.gloss = "first-singular present indicative"
end
end
}
local valid_genders
local function get_valid_genders()
m_table = m_table or require(table_module)
valid_genders, get_valid_genders = valid_genders or m_table.listToSet{"m", "m-p", "f", "f-p", "n", "n-p", "p", "mf", "mf-p", "mfbysense", "mfbysense-p"}, nil
return valid_genders
end
local nouns = {
params = {
= {alias_of = "g", list = false},
= genders_param,
= list,
= list,
= list,
= list,
= list,
= list,
= list,
= list,
= boolean,
},
func = function(args, data)
data.genders = args.g
if args.indecl then
insert(data.inflections, {label = glossary_link("indeclinable")})
end
handle_infl(args, data, "m", "masculine")
handle_infl(args, data, "f", "feminine", {form = "f"})
handle_infl(args, data, "adj", "relational adjective", {form = "relational adjective"})
handle_infl(args, data, "dim", "diminutive", {form = "diminutive"})
handle_infl(args, data, "aug", "augmentative", {form = "augmentative"})
handle_infl(args, data, "pej", "pejorative")
handle_infl(args, data, "dem", "demonym")
handle_infl(args, data, "fdem", "female demonym")
end,
}
pos_functions = nouns
pos_functions = nouns
-- Handle comparatives and superlatives for adjectives and adverbs, including user-specified comparatives and
-- superlatives and default-requested comparatives/superlatives using '+'. Code is the same for adjectives and adverbs.
local function handle_adj_adv_comp(args, data)
local plpos = data.pos_category:gsub("^reconstructed ", "")
if args.comp == "-" then
remove(args.comp, 1)
if #args.comp > 0 then
insert(data.inflections, {label = "sometimes " .. glossary_link("comparable")})
insert(data.categories, langname .. " comparable " .. plpos)
insert(data.categories, langname .. " uncomparable " .. plpos)
else
insert(data.inflections, {label = "not " .. glossary_link("comparable")})
insert(data.categories, langname .. " uncomparable " .. plpos)
end
elseif #args.comp > 0 then
insert(data.categories, langname .. " comparable " .. plpos)
end
-- If comp=+, use default comparative 'по́-...', and set a default superlative if unspecified.
local saw_comp_plus = false
local comps = {}
for _, compval in ipairs(args.comp) do
if compval == "+" then
saw_comp_plus = true
for _, head in ipairs(data.heads) do
insert(comps, "по́-" .. head)
end
else
insert(comps, compval)
end
end
if saw_comp_plus and #args.sup == 0 then
args.sup = {"+"}
end
insert_infl(data, comps, "comparative", {form = "comparative"})
local sups = {}
if args.sup == "-" then
insert(data.inflections, {label = "no superlative"})
else
-- If sup=+ (possibly from comp=+), use default superlative 'на́й-...'.
for _, supval in ipairs(args.sup) do
if supval == "+" then
for _, head in ipairs(data.heads) do
insert(sups, "на́й-" .. head)
end
else
insert(sups, supval)
end
end
end
insert_infl(data, sups, "superlative", {form = "superlative"})
end
pos_functions = {
params = {
= alias_of_comp_not_list,
= list,
= alias_of_sup_not_list,
= list,
},
func = function(args, data)
handle_adj_adv_comp(args, data)
end,
}
local function make_adjective_pos_function(pos)
local params = {
= boolean,
= list,
}
if pos == "adjectives" then
params = alias_of_comp_not_list
params = list
params = alias_of_sup_not_list
params = list
params = list
params = list
end
return {
params = params,
overriding_poscat = pos == "numerals" and "numerals" or nil,
func = function(args, data)
if args.indecl then
insert(data.inflections, {label = glossary_link("indeclinable")})
end
handle_adj_adv_comp(args, data)
handle_infl(args, data, "dim", "diminutive")
handle_infl(args, data, "adv", "adverb")
handle_infl(args, data, "absn", "abstract noun", {form = "abstract noun", pos = "noun"})
end,
}
end
pos_functions = make_adjective_pos_function("adjectives")
pos_functions = make_adjective_pos_function("determiners")
pos_functions = make_adjective_pos_function("pronouns")
pos_functions = make_adjective_pos_function("numerals")
local participle_types = {
= "adverbial",
= "past active aorist",
= "past active imperfect",
= "present active",
= "past passive",
= "past passive",
= "present passive",
}
pos_functions = {
params = {
= {required = true, list = true, default = "aor"},
},
func = function(args, data)
insert(data.categories, "Bulgarian verb forms")
for _, part in ipairs(args) do
local part_type = participle_types
if not part_type then
m_table = m_table or require(table_module)
error("Unrecognized participle type " .. dump(part) .. "; should be " .. m_table.serialCommaJoin(m_table.keysToList(participle_types), {conj = "or", dump = true, dontTag = true}))
end
insert(data.categories, "Bulgarian " .. part_type .. " participles")
end
end
}
pos_functions = {
params = {
= genders_param,
},
func = function(args, data)
data.genders = args.g
insert(data.categories, "Bulgarian verb forms")
end
}
pos_functions = {
params = {
-- Verbal nouns in Bulgarian are overwhelmingly formed with the suffixes
-- "-не" or "-ние", which both have neuter gender.
= {list = true, set = genders, default = "n"},
},
overriding_poscat = "nouns",
func = function(args, data)
data.genders = args.g
end
}
pos_functions = {
params = {
= genders_param,
},
overriding_poscat = "noun forms",
func = function(args, data)
data.genders = args.g
end
}
return export