This is a private module sandbox of Chernorizets, for his own experimentation. Items in this module may be added and removed at Chernorizets's discretion; do not rely on this module's stability.
local export = {}
local pos_functions = {}
local headword_utilities_module = require("Module:headword utilities")
local lang = require("Module:languages").getByCode("bg")
local langname = lang:getCanonicalName()
local function track(page)
require("Module:debug/track")("bg-headword/" .. page)
return true
end
local function glossary_link(anchor, text)
text = text or anchor
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 = true, allow_holes = true},
= {},
= {type = "boolean"},
= {type = "boolean"},
= {type = "boolean"},
= {}, -- 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.title.getCurrentTitle().subpageText
local user_specified_heads = args.head
local heads = user_specified_heads
if args.nolinkhead then
if #heads == 0 then
heads = {pagename}
else
for i, head in ipairs(heads) do
if head == auto_linked_head then
track("redundant-head")
end
if not head or head == "+" then
heads = auto_linked_head
end
end
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,
force_cat_output = force_cat,
}
if is_suffix then
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 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)
accel_lemma = nil
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
table.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 = {
= {},
= {list = true},
= {list = true},
= {type = "boolean"},
},
func = function(args, data)
if args == "pf" then
data.genders = {"pf"}
elseif args == "impf" then
data.genders = {"impf"}
elseif args == "both" or args == "biasp" then
data.genders = {"biasp"}
elseif args then
error("Unrecognized aspect '" .. args .. "'")
end
handle_infl(args, data, "pf", "perfective")
handle_infl(args, data, "impf", "imperfective")
if args.impers then
table.insert(data.inflections, {label = "impersonal"})
data.gloss = "third-singular present indicative"
else
data.gloss = "first-singular present indicative"
end
end
}
local function verify_genders(genders)
for _, g in ipairs(genders) do
if g == "m" or g == "m-p" or g == "f" or g == "f-p" or g == "n" or g == "n-p" or g == "p" or
g == "mf" or g == "mf-p" or g == "mfbysense" or g == "mfbysense-p" then
-- OK
else
error("Unrecognized gender: '" .. g .. "'")
end
end
end
local nouns = {
params = {
= {alias_of = "g"},
= {list = true},
= {list = true},
= {list = true},
= {list = true},
= {list = true},
= {list = true},
= {list = true},
= {type = "boolean"},
},
func = function(args, data)
verify_genders(args.g)
data.genders = args.g
if args.indecl then
table.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")
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 lemma = data.pagename
local plpos = data.pos_category:gsub("^reconstructed ", "")
if args.comp == "-" then
table.remove(args.comp, 1)
if #args.comp > 0 then
table.insert(data.inflections, {label = "sometimes " .. glossary_link("comparable")})
table.insert(data.categories, langname .. " comparable " .. plpos)
table.insert(data.categories, langname .. " uncomparable " .. plpos)
else
table.insert(data.inflections, {label = "not " .. glossary_link("comparable")})
table.insert(data.categories, langname .. " uncomparable " .. plpos)
end
elseif #args.comp > 0 then
table.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 i, compval in ipairs(args.comp) do
if compval == "+" then
saw_comp_plus = true
for _, head in ipairs(data.heads) do
table.insert(comps, "по́-" .. head)
end
else
table.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
table.insert(data.inflections, {label = "no superlative"})
else
-- If sup=+ (possibly from comp=+), use default superlative 'на́й-...'.
for i, supval in ipairs(args.sup) do
if supval == "+" then
for _, head in ipairs(data.heads) do
table.insert(sups, "на́й-" .. head)
end
else
table.insert(sups, supval)
end
end
end
insert_infl(data, sups, "superlative", {form = "superlative"})
end
pos_functions = {
params = {
= {alias_of = "comp"},
= {list = true},
= {alias_of = "sup"},
= {list = true},
},
func = function(args, data)
handle_adj_adv_comp(args, data)
end,
}
local function make_adjective_pos_function(pos)
local params = {
= {type = "boolean"},
= {list = true},
}
if pos == "adjectives" then
params = {alias_of = "comp"}
params = {list = true}
params = {alias_of = "sup"}
params = {list = true}
params = {list = true}
params = {list = true}
end
return {
params = params,
overriding_poscat = pos == "numerals" and "numerals" or nil,
func = function(args, data)
if args.indecl then
table.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")
pos_functions = {
params = {
= {required = true, list = true, default = "aor"},
},
func = function(args, data)
table.insert(data.categories, "Bulgarian verb forms")
for _, part in ipairs(args) do
if part == "adv" then
table.insert(data.categories, "Bulgarian adverbial participles")
elseif part == "aor" then
table.insert(data.categories, "Bulgarian past active aorist participles")
elseif part == "impf" then
table.insert(data.categories, "Bulgarian past active imperfect participles")
elseif part == "pres" then
table.insert(data.categories, "Bulgarian present active participles")
elseif part == "pass" or part == "ppp" then
table.insert(data.categories, "Bulgarian past passive participles")
elseif part == "prespass" then
table.insert(data.categories, "Bulgarian present passive participles")
else
error("Unrecognized participle type '" .. part .. "': Should be adv, aor, impf, pres, pass or prespass")
end
end
end
}
pos_functions = {
params = {
= {list = true},
},
func = function(args, data)
verify_genders(args.g)
data.genders = args.g
table.insert(data.categories, "Bulgarian verb forms")
end
}
pos_functions = {
overriding_poscat = "nouns",
params = {
-- Verbal nouns in Bulgarian are overwhelmingly formed with the suffixes
-- "-не" or "-ние", which both have neuter gender.
= {list = true, default = "n"},
},
func = function(args, data)
verify_genders(args.g)
data.genders = args.g
end
}
pos_functions = {
params = {
= {list = true},
},
overriding_poscat = "noun forms",
func = function(args, data)
verify_genders(args.g)
data.genders = args.g
end
}
return export