Mô đun:la-headword
Giao diện
-- TODO: handle "-old" subtypes generally, appending "in Old Latin", where terms have additional OL inflections.
local export = {}
local pos_functions = {}
local m_str_utils = require("Module:string utilities")
local m_table = require("Module:table")
local legal_gender = {
["m"] = true,
["f"] = true,
["n"] = true,
["?"] = true,
["?!"] = true,
}
local declension_to_vietnamese = {
["1"] = "kiểu 1",
["2"] = "kiểu 2",
["3"] = "kiểu 3",
["4"] = "kiểu 4",
["5"] = "kiểu 5",
}
local gender_names = {
["m"] = "giống đực",
["f"] = "giống cái",
["n"] = "giống trung",
["?"] = "giống chưa xác định",
["?!"] = "giống chưa chứng thực",
}
local lang = require("Module:languages").getByCode("la")
local concat = table.concat
local deep_equals = m_table.deepEquals
local insert = table.insert
local insert_if_not = m_table.insertIfNot
local invert = m_table.invert
local pattern_escape = m_str_utils.pattern_escape
local remove = table.remove
local split = m_str_utils.split
local ulower = m_str_utils.lower
local umatch = mw.ustring.match
local NAMESPACE = mw.title.getCurrentTitle().namespace
local PAGENAME = mw.loadData("Module:headword/data").pagename
local function format(array, concatenater)
if #array == 0 then
return ""
else
local concatenated = concat(array, concatenater)
if concatenated == "" then
return ""
elseif concatenated:match("'$") then
concatenated = concatenated .. " "
end
return "; ''" .. concatenated .. "''"
end
end
local function glossary_link(anchor, text)
text = text or anchor
return "[[Phụ lục:Từ điển thuật ngữ#" .. anchor .. "|" .. text .. "]]"
end
local function make_link(page, display, face, accel)
return require("Module:links").full_link({term = page, alt = display, lang = lang, accel = accel}, face)
end
-- The main entry point.
-- This is the only function that can be invoked from a template.
function export.show(frame)
local iargs = require("Module:parameters").process(frame.args, {
[1] = {required = true},
["def"] = true,
["suff_type"] = true,
})
local args = frame:getParent().args
local poscat = iargs[1]
local def = iargs.def
local suff_type = iargs.suff_type
local postype = nil
if suff_type then
postype = poscat .. '-' .. suff_type
else
postype = poscat
end
local data = {lang = lang, categories = {}, heads = {}, genders = {}, inflections = {}}
local infl_classes = {}
local title = {}
local postscript = {}
if poscat == "Hậu tố" then
insert_if_not(data.categories, "Latin " .. suff_type .. "-forming suffixes")
end
if pos_functions[postype] then
local new_poscat = pos_functions[postype](def, args, data, infl_classes, title, postscript)
if new_poscat then
poscat = new_poscat
end
end
if NAMESPACE == 118 then -- Reconstruction:
data.pos_category = poscat .. " tái tạo"
data.nolink = true
else
data.pos_category = poscat
end
postscript = concat(postscript, ", ")
return
require("Module:headword").full_headword(data)
.. format(infl_classes, "/")
.. format(title, ", ")
.. (postscript ~= "" and " (" .. postscript .. ")" or "")
end
local function process_num_type(numtype, categories)
if numtype == "card" then
insert_if_not(categories, "Số đếm tiếng Latinh")
elseif numtype == "ord" then
insert_if_not(categories, "Số thứ tự tiếng Latinh")
elseif numtype == "dist" then
-- FIXME, should be named 'Latin distributive numbers'
insert_if_not(categories, "Số phân phối/Tiếng Latinh")
elseif numtype == "mul" then
-- FIXME, should be named 'Latin multiplicative numbers'
insert_if_not(categories, "Số nhân/Tiếng Latinh")
elseif numtype == "coll" then
-- FIXME, should be named 'Latin collective numbers'
insert_if_not(categories, "Số tập hợp/Tiếng Latinh")
elseif numtype then
error("Unrecognized numeral type '" .. numtype .. "'")
end
end
local function nouns(pos, def, args, data, infl_classes, title)
local is_num = pos == "numerals"
local is_pn = false
if pos == "Danh từ riêng" then
is_pn = true
pos = "Danh từ"
end
local decldata = require("Module:la-nominal").do_generate_noun_forms(args, pos, "headword", def, is_num)
local lemma = decldata.overriding_lemma
local lemma_num = decldata.num == "pl" and "pl" or "sg"
if not lemma or #lemma == 0 then
lemma = decldata.forms["linked_nom_" .. lemma_num]
if decldata.unattested["nom_" .. lemma_num] then
lemma[1] = '*' .. lemma[1]
end
end
data.heads = lemma
-- Since we always set data.heads to the lemma and specification of the lemma is mandatory in {{la-noun}}, there aren't
-- really any redundant heads.
data.no_redundant_head_cat = true
data.id = decldata.id
local genders = decldata.overriding_genders
if #genders == 0 then
if decldata.gender then
genders = {ulower(decldata.gender)}
elseif not is_num then
error("No gender explicitly specified in headword template using g=, and can't infer gender from lemma spec")
end
end
local categories = data.categories
if is_num then
process_num_type(decldata.num_type, categories)
end
if decldata.indecl then
insert(data.inflections, {label = glossary_link("không biến cách")})
insert_if_not(categories, decldata.pos .. " tiếng Latinh không có biến cách")
for _, g in ipairs(genders) do
local gender = g:match("^(.[\128-\191]*)%-[sp]$")
if not gender then
gender = g
end
if not legal_gender[gender] then
error("Gender “" .. gender .. "” is not a valid Latin gender.")
end
insert(data.genders, g)
insert_if_not(categories, decldata.pos .. " " .. gender_names[gender] .. " tiếng Latinh không có biến cách")
end
else
local is_irreg = false
local is_indecl = false
local is_decl = false
local has_multiple_decls = false
local has_multiple_variants = false
-- flatten declension specs
local decls = {}
for _, g in ipairs(genders) do
if not legal_gender[g] then
error("Gender “" .. g .. "” is not a valid Latin gender.")
elseif decldata.num == "pl" then
g = g .. "-p"
elseif decldata.num == "sg" then
g = g .. "-s"
end
insert(data.genders, g)
end
local function process_decl(decl_list, props)
local headword_decl = props.headword_decl
-- skip adjectival declensions
if headword_decl:match("+$") then
return
elseif props.decl == "irreg" then
is_irreg = true
headword_decl = headword_decl:match("^irreg/(.*)$") or headword_decl
local irreg_decls = split(headword_decl, ",")
if #irreg_decls > 1 then
has_multiple_decls = true
end
for _, d in ipairs(irreg_decls) do
if d == "indecl" or d == "0" then
is_indecl = true
else
is_decl = true
end
insert_if_not(decl_list, d)
end
else
if headword_decl == "indecl" or headword_decl == "0" then
is_indecl = true
else
is_decl = true
end
insert_if_not(decl_list, headword_decl)
end
end
for _, props in ipairs(decldata.propses) do
if props.headword_decl then
process_decl(decls, props)
else
local alternant_decls = {}
for _, alternant in ipairs(props) do
for _, single_props in ipairs(alternant) do
process_decl(alternant_decls, single_props)
end
end
if #alternant_decls > 1 then
has_multiple_decls = true
elseif #decls > 1 then
has_multiple_variants = true
end
for _, d in ipairs(alternant_decls) do
insert_if_not(decls, d)
end
end
end
if is_indecl and is_decl then
has_multiple_decls = true
end
if has_multiple_decls then
insert_if_not(categories, decldata.pos .. " tiếng Latinh có nhiều biến cách")
end
if has_multiple_variants then
insert_if_not(categories, decldata.pos .. " tiếng Latinh có nhiều biến thể của một biến cách")
end
if is_irreg then
insert(title, glossary_link("bất quy tắc"))
insert_if_not(categories, decldata.pos .. " bất quy tắc tiếng Latinh")
for _, g in ipairs(genders) do
insert_if_not(categories, decldata.pos .. " " .. gender_names[g] .. " bất quy tắc tiếng Latinh")
end
end
if is_indecl then
if is_decl then
insert(title, glossary_link("không biến cách"))
else
insert(data.inflections, {label = glossary_link("không biến cách")})
end
insert_if_not(categories, decldata.pos .. " tiếng Latinh không có biến cách")
for _, g in ipairs(genders) do
insert_if_not(categories, decldata.pos .. " " .. gender_names[g] .. " tiếng Latinh không có biến cách")
end
end
if #decls > 1 then
insert(title, "biến cách nhiều kiểu")
end
for _, decl in ipairs(decls) do
if not (decl == "0" or decl == "indecl" or decl == "sgpl" or decl == "irreg") then
local decl_class = declension_to_vietnamese[decl]
if not decl_class then
error("Internal error: declension '" .. decl .. "' not recognized")
end
insert(title, "[[Phụ lục:Biến cách " .. decl_class .. " tiếng Latinh|biến cách " .. decl_class .. "]]")
insert_if_not(categories, decldata.pos .. " tiếng Latinh có biến cách " .. decl_class)
for _, g in ipairs(genders) do
insert_if_not(categories, decldata.pos .. " " .. gender_names[g] .. " tiếng Latinh có biến cách " .. decl_class)
end
end
end
if NAMESPACE == 118 then -- Reconstruction:
-- For reconstructed nouns:
if data.genders[1] == 'n' and lemma_num == 'sg' then
-- singular neuter nouns give a plural
local pl = decldata.forms["nom_pl"]
if pl and pl ~= "" and #pl > 0 then
pl.label = "plural"
insert(data.inflections, pl)
end
else
-- all others give an oblique
local obl = decldata.forms["acc_" .. lemma_num]
if obl and obl ~= "" and #obl > 0 then
obl.label = "oblique"
insert(data.inflections, obl)
end
end
else
local gen = decldata.forms["gen_" .. lemma_num]
if (decldata.unattested["gen_" .. lemma_num]) then
gen[1] = '*' .. gen[1]
data.nolink = true
end
if gen and gen ~= "" and gen ~= "—" and #gen > 0 then
if is_decl then
-- Skip displaying the genitive for nouns that are only
-- indeclinable. But we do display it for nouns like Abrahām
-- and Ādām that can be either indeclinable or declined.
gen.label = "genitive"
insert(data.inflections, gen)
end
else
insert(data.inflections, {label = "không có gen."})
insert_if_not(categories, decldata.pos .. " tiếng Latinh không có dạng gen. số ít")
end
end
end
if #decldata.m > 0 then
decldata.m.label = "giống đực"
insert(data.inflections, decldata.m)
end
if #decldata.f > 0 then
decldata.f.label = "giống cái"
insert(data.inflections, decldata.f)
end
for _, cat in ipairs(decldata.categories) do
insert_if_not(categories, cat)
end
for _, cat in ipairs(decldata.cat) do
insert_if_not(categories, cat .. " tiếng Latinh")
end
return is_pn and decldata.pos == "Danh từ" and "Danh từ riêng" or decldata.pos
end
pos_functions["Danh từ"] = function(def, args, data, infl_classes, title)
return nouns("Danh từ", def, args, data, infl_classes, title)
end
pos_functions["Danh từ riêng"] = function(def, args, data, infl_classes, title)
return nouns("Danh từ riêng", def, args, data, infl_classes, title)
end
pos_functions["Hậu tố-noun"] = function(def, args, data, infl_classes, title)
return nouns("Hậu tố", def, args, data, infl_classes, title)
end
pos_functions["Số-noun"] = function(def, args, data, infl_classes, title)
return nouns("Số", def, args, data, infl_classes, title)
end
function export.verb_title(title, typeinfo, lemma_forms)
local conj = typeinfo.conj
local irreg_processing = typeinfo.irreg
local subtypes = typeinfo.subtypes
local first_lemma = ""
if #lemma_forms > 0 then
first_lemma = require("Module:links").remove_links(lemma_forms[1])
end
if conj == "1st" then
insert(title, "[[Phụ lục:Động từ tiếng Latinh chia kiểu 1|cách chia loại 1]]")
elseif conj == "2nd" then
insert(title, "[[Phụ lục:Động từ tiếng Latinh chia kiểu 2|cách chia loại 2]]")
elseif conj == "3rd" then
insert(title, "[[Phụ lục:Động từ tiếng Latinh chia kiểu 3|cách chia loại 3]]")
elseif conj == "3rd-io" then
insert(title, ("[[Phụ lục:Động từ tiếng Latinh chia kiểu 3|cách chia loại 3]] %s-variant"):format(make_link(nil, "iō", "term")))
elseif conj == "4th" then
insert(title, "[[Phụ lục:Động từ tiếng Latinh chia kiểu 4|cách chia loại 4]]")
elseif conj == "irreg" then -- sum
insert(title, "[[Phụ lục:Động từ bất quy tắc tiếng Latinh|cách chia bất quy tắc]]")
end
if subtypes.highlydef then -- āiō, inquam
insert(title, "rất [[khiếm khuyết]]")
end
if subtypes.suppl then -- sum, volō
insert(title, "[[bổ khuyết]]")
end
if subtypes["3only"] then -- decet
insert(title, "chỉ có [[third person|ngôi thứ ba]]")
elseif subtypes.impers then -- decet, advesperāscit (also nopass)
insert(title, "[[impersonal verb|không ngôi]]")
end
if subtypes.depon then -- dēmōlior, calvor (also noperf)
insert(title, "[[trung gian]]")
end
if subtypes.perfaspres then -- meminī, ōdī
insert(title, "không có thân [[hiện tại]]")
-- If semidepon is set, only the active forms are affected.
local voice = subtypes.semidepon and "[[chủ động]] " or ""
insert(title, ("%sDạng [[hoàn thành]] %snghĩa [[hiện tại]]"):format(voice, voice))
-- Clarify that deponency can only apply to the perfect.
if subtypes.semidepon then -- ōdī
insert(title, "động từ [[trung gian]] dạng [[hoàn thành]]")
end
if subtypes.optsemidepon then
insert(title, "động từ [[trung gian]] dạng [[hoàn thành]] (không cần thiết)")
end
else
if subtypes.semidepon then -- fīdō, gaudeō
insert(title, "[[semi-deponent#English|bán trung gian]]")
end
if subtypes.optsemidepon then -- audeō, placeō, soleō, pudeō
insert(title, "[[semi-deponent#English|bán trung gian]] (không cần thiết)")
end
end
if subtypes.imponly then -- cedo, apage
insert(title, "chỉ có lối [[mệnh lệnh]]")
end
if subtypes.nopass then -- coacēscō
insert(title, "không có dạng [[bị động]]")
end
local stems = {}
if subtypes.nopres then -- coepī; perfaspres already handles this above
insert(stems, "[[hiện tại]]")
end
if subtypes.noperf then
insert(stems, "[[hoàn thành]]")
end
if subtypes.nosup or subtypes.supfutractvonly then
insert(stems, "[[supine]]")
end
if #stems > 0 then
local extra = subtypes.supfutractvonly and " trừ [[phân từ]] [[tương lai]] [[chủ động]]]"
insert(title, ("không có thân từ %s%s"):format(m_table.serialCommaJoin(stems, {conj = "hoặc"}), #stems > 1 and "s" or "", extra or ""))
end
if subtypes.nofut then -- soleō
insert(title, "không có thì [[tương lai]]")
end
if subtypes.pass3only then -- praefundō
insert(title, "[[third person#English|third person]]-only in the [[passive voice#English|passive]]")
elseif subtypes.passimpers then -- abambulō
local msg = "[[impersonal verb#English|impersonal]] in the [[passive voice#English|passive]]"
if subtypes.passimpersold then -- possum
msg = msg .. " in [[Old Latin]]"
end
insert(title, msg)
end
if subtypes.noimp then -- volō
insert(title, "no [[imperative mood#English|imperative]]")
end
if irreg_processing and umatch(first_lemma, "d[īū]cō$") then -- dīcō
insert(title, "[[Appendix:Latin irregular verbs|irregular]] short [[imperative mood#English|imperative]]")
end
if subtypes.nofutractvptc and not subtypes.nosup then -- fīō
insert(title, "no [[future tense#English|future]] [[active voice#English|active]] [[participle#English|participle]]")
end
if not (subtypes.nopres or subtypes.perfaspres or subtypes.imponly) then
if subtypes.noinf then -- inquam
insert(title, "no [[infinitive#English|infinitive]]")
end
if subtypes.noger then -- libet
insert(title, "no [[gerund#English|gerund]]")
end
end
if subtypes.shorta then -- dō
insert(title, ("[[Appendix:Latin irregular verbs|irregular]] short %s in most forms"):format(make_link(nil, "ă", "term")))
end
if irreg_processing then
if first_lemma:match("edō$") then -- edō
insert(title, "[[Appendix:Latin irregular verbs|irregular]] alternative forms")
elseif first_lemma:match("fīō$") then -- fīō
insert(title, "[[Appendix:Latin irregular verbs|irregular]] long " .. make_link(nil, "ī", "term"))
end
end
end
pos_functions["Động từ"] = function(def, args, data, infl_classes, title)
local m_la_verb = require("Module:la-verb")
local def1, def2
if def then
def1, def2 = def:match("^(.-):(.*)$")
end
local conjdata, typeinfo = m_la_verb.make_data(args, true, def1, def2)
local lemma_forms = conjdata.overriding_lemma
if not lemma_forms or #lemma_forms == 0 then
lemma_forms = m_la_verb.get_lemma_forms(conjdata, true)
end
data.heads = lemma_forms
-- Since we always set data.heads to the lemma and specification of the lemma is mandatory in {{la-verb}}, there aren't
-- really any redundant heads.
data.no_redundant_head_cat = true
data.id = conjdata.id
local perf_only = false
local function insert_inflection(infl, label)
infl.label = label
insert(data.inflections, infl)
end
local inf = m_la_verb.get_valid_forms(conjdata.forms["pres_actv_inf"])
if #inf > 0 then
insert_inflection(inf, "nguyên mẫu ở thì hiện tại")
else
inf = m_la_verb.get_valid_forms(conjdata.forms["perf_actv_inf"])
if #inf > 0 then
perf_only = true
insert_inflection(inf, "nguyên mẫu ở thì hoàn thành")
end
end
if not perf_only then
local perf = m_la_verb.get_valid_forms(conjdata.forms["1s_perf_actv_indc"])
if #perf == 0 then
perf = m_la_verb.get_valid_forms(conjdata.forms["3s_perf_actv_indc"])
end
if #perf > 0 then
insert_inflection(perf, "chủ động ở thì hoàn thành")
end
end
local subtypes = typeinfo.subtypes
if not (subtypes.depon or subtypes.semidepon) then
local sup = m_la_verb.get_valid_forms(conjdata.forms["acc_sup"])
if #sup > 0 then
insert_inflection(sup, "danh động từ abl./acc.")
else
local fap = m_la_verb.get_valid_forms(conjdata.forms["futr_actv_ptc"])
if #fap > 0 then
insert_inflection(fap, "phân từ tương lai chủ động")
end
end
end
export.verb_title(title, typeinfo, lemma_forms)
end
pos_functions["Hậu tố-verb"] = pos_functions["Động từ"]
local function attested_form(decldata, index)
local form
if (decldata.unattested[index]) then
form = { { term = '*' .. decldata.forms[index][1], nolink = true } }
else
form = decldata.forms[index]
end
return form
end
local function adjectives(pos, def, args, data, infl_classes)
local is_num = pos == "Số"
local decldata = require("Module:la-nominal").do_generate_adj_forms(args, pos, "headword", def, is_num)
local lemma = decldata.overriding_lemma
local lemma_num = decldata.num == "pl" and "pl" or "sg"
if not lemma or #lemma == 0 then
lemma = decldata.forms["linked_nom_" .. lemma_num .. "_m"]
if decldata.unattested["nom_" .. lemma_num .. "_m"] then
lemma[1] = '*' .. lemma[1]
end
end
data.heads = lemma
-- Since we always set data.heads to the lemma and specification of the lemma is mandatory in {{la-noun}}, there aren't
-- really any redundant heads.
data.no_redundant_head_cat = true
data.id = decldata.id
local categories = data.categories
if is_num then
process_num_type(decldata.num_type, categories)
end
if decldata.num == "pl" then
insert_if_not(categories, decldata.pos .. " tiếng Latinh chỉ có số nhiều")
end
if decldata.indecl then
insert(data.inflections, {label = glossary_link("không biến cách")})
if decldata.pos == "Phân từ" then
if lemma[1]:match("[stxu]um$") then
insert_if_not(categories, "Phân từ hoàn thành tiếng Latinh")
end
end
else
local masc = decldata.forms["nom_" .. lemma_num .. "_m"]
local fem = attested_form(decldata, "nom_" .. lemma_num .. "_f")
local neut = attested_form(decldata, "nom_" .. lemma_num .. "_n")
local gen = attested_form(decldata, "gen_" .. lemma_num .. "_m")
if decldata.pos == "participles" then
if masc[1]:match("ūrus$") then
insert_if_not(categories, "Latin future active participles")
elseif masc[1]:match("ndus$") then
-- FIXME, should rename to "Latin gerundives")
insert_if_not(categories, "Latin future passive participles")
elseif masc[1]:match("[stxu]us$") then
insert_if_not(categories, "Latin perfect participles")
elseif masc[1]:match("ns$") then
insert_if_not(categories, "Latin present participles")
else
error("Unrecognized participle ending: " .. masc[1])
end
end
local function is_missing(form)
return not form or form == "" or form == "—" or #form == 0
end
-- We display the inflections in three different ways to mimic the
-- old way of doing things:
--
-- 1. If masc and fem are different, show masc, fem and neut.
-- 2. Otherwise, if masc and neut are different, show masc and neut.
-- 3. Otherwise, show masc nominative and masc genitive.
if not is_missing(fem) and not deep_equals(masc, fem) then
fem.label = "feminine"
insert(data.inflections, fem)
if not is_missing(neut) then
neut.label = "neuter"
insert(data.inflections, neut)
end
elseif not is_missing(neut) and not deep_equals(masc, neut) then
neut.label = "neuter"
insert(data.inflections, neut)
elseif not is_missing(gen) then
gen.label = "genitive"
insert(data.inflections, gen)
end
insert(infl_classes, decldata.title)
end
if #decldata.comp > 0 then
decldata.comp.label = "so sánh hơn"
insert(data.inflections, decldata.comp)
end
if #decldata.sup > 0 then
decldata.sup.label = "so sánh nhất"
insert(data.inflections, decldata.sup)
end
if #decldata.adv > 0 then
decldata.adv.label = "phó từ"
insert(data.inflections, decldata.adv)
end
for _, cat in ipairs(decldata.categories) do
insert_if_not(categories, cat)
end
for _, cat in ipairs(decldata.cat) do
insert_if_not(categories, cat .. " tiếng Latinh")
end
return decldata.pos
end
pos_functions["Tính từ"] = function(def, args, data, infl_classes, title)
return adjectives("Tính từ", def, args, data, infl_classes, title)
end
pos_functions["Tính từ so sánh hơn"] = function(def, args, data, infl_classes)
local list = {list = true}
args = require("Module:parameters").process(args, {
[1] = {alias_of = 'head'},
[2] = {alias_of = 'pos'},
["head"] = list,
["is_lemma"] = {type = "boolean"}, -- comparative-only adjective
-- The following two are intended for comparative-only adjectives.
["pos"] = list,
["sup"] = list,
["id"] = true,
})
data.no_redundant_head_cat = #args.head == 0
-- Set default manually so we can tell whether the user specified head=.
if #args.head == 0 then
args.head = {PAGENAME}
end
data.heads = args.head
data.id = args.id
if args.is_lemma then
insert(data.inflections, {label = "chỉ có so sánh hơn"})
insert_if_not(data.categories, "Tính từ tiếng Latinh chỉ có dạng so sánh hơn")
else
insert(data.inflections, {label = "so sánh hơn"})
end
insert(infl_classes, "[[Phụ lục:Biến cách kiểu 3 tiếng Latinh|biến cách kiểu 3]]")
local n = {label = "giống trung"}
for _, head in ipairs(args.head) do
local neuter = head:gsub("or$", "us")
insert(n, neuter)
end
insert(data.inflections, n)
if #args.pos > 0 then
args.pos.label = "khẳng định"
insert(data.inflections, args.pos)
end
if #args.sup > 0 then
args.sup.label = "so sánh nhất"
insert(data.inflections, args.sup)
end
if args.is_lemma then
-- If is_lemma, we're a comparative adjective without positive form,
-- so we're treated as a lemma. In that case, we return "adjectives" as
-- the part of speech, which will automatically categorize into
-- "Latin adjectives" and "Latin lemmas"; otherwise we don't return
-- anything, which defaults to the passed-in POS (usually
-- "comparative adjectives"), which will automatically categorize into
-- that POS (e.g. "Latin comparative adjectives") and into
-- "Latin non-lemma forms".
return "adjectives"
end
end
pos_functions["Tính từ so sánh nhất"] = function(def, args, data, infl_classes)
local list = {list = true}
args = require("Module:parameters").process(args, {
[1] = {alias_of = 'head'},
[2] = {alias_of = 'pos'},
["head"] = list,
["is_lemma"] = {type = "boolean"}, -- superlative-only adjective
-- The following two are intended for superlative-only adjectives.
["pos"] = list,
["comp"] = list,
["id"] = true,
})
data.no_redundant_head_cat = #args.head == 0
-- Set default manually so we can tell whether the user specified head=.
if #args.head == 0 then
args.head = {PAGENAME}
end
data.heads = args.head
data.id = args.id
if args.is_lemma then
insert(data.inflections, {label = "chỉ có so sánh nhất"})
insert_if_not(data.categories, "Tính từ tiếng Latinh chỉ có dạng so sánh nhất")
else
insert(data.inflections, {label = "so sánh nhất"})
end
insert(infl_classes, "[[Phụ lục:Biến cách kiểu 1 tiếng Latinh|biến cách kiểu 1]]")
insert(infl_classes, "[[Phụ lục:Biến cách kiểu 2 tiếng Latinh|kiểu 2]]")
local f, n = {label = "giống cái"}, {label = "giống trung"}
for _, head in ipairs(args.head) do
local stem = head:gsub("us$", "")
insert(f, stem .. "a")
insert(n, stem .. "um")
end
insert(data.inflections, f)
insert(data.inflections, n)
if #args.pos > 0 then
args.pos.label = "khẳng định"
insert(data.inflections, args.pos)
end
if #args.comp > 0 then
args.comp.label = "so sánh hơn"
insert(data.inflections, args.comp)
end
if args.is_lemma then
-- If is_lemma, we're a superlative adjective without positive form,
-- so we're treated as a lemma. In that case, we return "adjectives" as
-- the part of speech, which will automatically categorize into
-- "Latin adjectives" and "Latin lemmas"; otherwise we don't return
-- anything, which defaults to the passed-in POS (usually
-- "superlative adjectives"), which will automatically categorize into
-- that POS (e.g. "Latin superlative adjectives") and into
-- "Latin non-lemma forms".
return "adjectives"
end
end
pos_functions["Phân từ"] = function(def, args, data, infl_classes, title)
return adjectives("Phân từ", def, args, data, infl_classes, title)
end
pos_functions["Từ hạn định"] = function(def, args, data, infl_classes, title)
return adjectives("Từ hạn định", def, args, data, infl_classes, title)
end
pos_functions["Đại từ"] = function(def, args, data, infl_classes, title)
return adjectives("Đại từ", def, args, data, infl_classes, title)
end
pos_functions["Hậu tố-adjective"] = function(def, args, data, infl_classes, title)
return adjectives("Hậu tố", def, args, data, infl_classes, title)
end
pos_functions["Số-adjective"] = function(def, args, data, infl_classes, title)
return adjectives("Số", def, args, data, infl_classes, title)
end
pos_functions["Phó từ"] = function(def, args, data)
local list = {list = true}
args = require("Module:parameters").process(args, {
[1] = {alias_of = 'head'},
[2] = {alias_of = 'comp'},
[3] = {alias_of = 'sup'},
["head"] = {list = true, required = true},
["comp"] = list,
["sup"] = list,
["id"] = true,
})
data.heads = args.head
data.no_redundant_head_cat = true -- since head= is required
data.id = args.id
local comp, sup
local irreg = false
if args.comp[1] == "-" then
comp = "-"
elseif #args.comp > 0 then
args.comp.label = glossary_link("so sánh hơn")
comp = args.comp
irreg = true
end
if args.comp[1] == "-" or args.sup[1] == "-" then
sup = "-"
elseif #args.sup > 0 then
args.sup.label = glossary_link("so sánh nhất")
sup = args.sup
irreg = true
end
local categories = data.categories
if irreg then
insert_if_not(categories, "Phó từ bất quy tắc tiếng Latinh")
end
if not comp or not sup then
local default_comp = {label = glossary_link("so sánh hơn")}
local default_sup = {label = glossary_link("so sánh nhất")}
for _, head in ipairs(args.head) do
local stem = nil
for _, suff in ipairs({"iter", "nter", "ter", "er", "iē", "ē", "im", "ō"}) do
stem = head:match("(.*)" .. pattern_escape(suff) .. "$")
if stem ~= nil then
if suff == "nter" then
stem = stem .. "nt"
suff = "er"
end
insert(default_comp, stem .. "ius")
insert(default_sup, stem .. "issimē")
break
end
end
if not stem then
error("Unrecognized adverb type, recognized types are “-ē”, “-er”, “-ter”, “-iter”, “-im”, or “-ō” or specify irregular forms or “-” if incomparable.")
end
end
comp = comp or default_comp
sup = sup or default_sup
end
if comp == "-" then
insert(data.inflections, {label = "không [[Phụ lục:Từ điển thuật ngữ#so sánh hơn|so sánh được]]"})
insert_if_not(categories, "Phó từ tiếng Latinh không so sánh được")
else
insert(data.inflections, comp)
end
if sup == "-" then
if comp ~= "-" then
insert(data.inflections, {label = "không có [[Phụ lục:Từ điển thuật ngữ#so sánh nhất|so sánh nhất]]"})
end
else
insert(data.inflections, sup)
end
end
pos_functions["Hâu tố-adverb"] = pos_functions["Phó từ"]
local function adpositions(pos, def, args, data, infl_classes, title, postscript)
local cases = invert(require("Module:la-utilities").cases)
args = require("Module:parameters").process(args, {
[1] = {alias_of = 'head'},
[2] = {list = true, set = m_table.keysToList(cases)},
["head"] = {list = true, required = true},
["id"] = true,
})
-- Case names are supplied in numbered arguments, optionally preceded by
-- headwords.
cases = args[2]
for i = 1, #cases do
for j = i + 1, #cases do
if cases[i] == cases[j] then
error("Duplicate case")
end
end
local case = cases[i]
local appendix_link = glossary_link(case)
if i == 1 then
appendix_link = "+ " .. appendix_link
end
insert(postscript, appendix_link)
insert_if_not(data.categories, "Latin " .. case .. " " .. pos)
end
data.heads = args.head
data.no_redundant_head_cat = true -- since head= is required
data.id = args.id
end
pos_functions["Giới từ"] = function(...)
return adpositions("Giới từ", ...)
end
pos_functions["Hậu giới từ"] = function(...)
return adpositions("Hậu giới từ", ...)
end
pos_functions["Danh động từ"] = function(def, args, data)
args = require("Module:parameters").process(args, {
[1] = {required = true, default = "labōrandum"}, -- headword
[2] = true, -- gerundive
})
data.heads = {args[1]}
data.no_redundant_head_cat = true -- since 1= is required and goes into data.heads
insert(data.inflections, {label = "[[Phụ lục:Từ điển thuật ngữ#accusative|acc.]]"})
local stem = args[1]:match("^(.*)um$")
if not stem then
error("Unrecognized gerund ending: " .. stem)
end
if args[2] == "-" then
insert(data.inflections, {label = "không có [[Phụ lục:Từ điển thuật ngữ#gerundive|gerundive]]"})
else
insert(data.inflections, {[1] = args[2] or stem .. "us", label = "[[Phụ lục:Từ điển thuật ngữ#gerundive|gerundive]]"})
end
end
local function non_lemma_forms(def, args, data)
args = require("Module:parameters").process(args, {
[1] = {required = true, default = def}, -- headword or cases
["head"] = {list = true, require_index = true},
["g"] = {list = true},
["id"] = true,
})
local heads = {args[1]}
for _, head in ipairs(args.head) do
insert(heads, head)
end
data.heads = heads
data.no_redundant_head_cat = true -- since 1= is required and goes into data.heads
data.genders = args.g
data.id = args.id
end
pos_functions["Biến thể hình thái danh từ"] = non_lemma_forms
pos_functions["Biến thể hình thái danh từ riêng"] = non_lemma_forms
pos_functions["Biến thể hình thái đại từ"] = non_lemma_forms
pos_functions["Biến thể hình thái động từ"] = non_lemma_forms
pos_functions["Biến thể hình thái danh động từ"] = non_lemma_forms
pos_functions["Biến thể hình thái tính từ"] = non_lemma_forms
pos_functions["Biến thể hình thái phân từ"] = non_lemma_forms
pos_functions["Biến thể hình thái từ hạn định"] = non_lemma_forms
pos_functions["Biến thể hình thái số từ"] = non_lemma_forms
pos_functions["Biến thể hình thái hậu tố"] = non_lemma_forms
return export