Modul:grc-decl/decl
Penampilan
- Modul ini kekurangan sublaman pendokumenan. Sila mencipta laman pendokumenan berkaitan.
- Pautan berguna: laman akar • sublaman • pautan • transklusi • kes ujian • kotak pasir
local module_path = 'Module:grc-decl/decl'
local m_decl_static_data = mw.loadData(module_path .. '/staticdata')
local m_paradigms = mw.loadData(module_path .. '/staticdata/paradigms')
local m_dialect_groups = mw.loadData(module_path .. '/staticdata/dialects')
local m_decl_data = require(module_path .. '/data')
local m_dialects = mw.loadData('Module:grc:Dialects')
local m_accent = require('Module:grc-accent')
local export = {
inflections = m_decl_data.inflections,
adjinflections = m_decl_data.adjinflections,
adjinflections_con = m_decl_data.adjinflections_con,
}
local function quote(text)
return "“" .. text .. "”"
end
local function add_forms(args)
if args.decl_type:match('irreg') then
for k, v in pairs(args.ctable) do
if k:match('[NGDAV][SDP]') then
args.ctable[k] = args[k] or args.stem[v]
end
end
else
--add stem to forms
local join_suffix = function(stem_num)
return args.stem[tonumber(stem_num)]
end
for k, v in pairs(args.ctable) do
if k:match('[NGDAV][SDP]') then -- only format case-number forms
args.ctable[k] = mw.ustring.gsub(v, '%d', join_suffix)
if args.dial == 'les' then
args.ctable[k] = m_accent.antepenult(args.ctable[k])
end
end
end
end
end
--[=[
Gets stem-ending combinations from [[Module:grc-decl/data]]
and [[Module:grc-decl/staticdata]]. Called a single time to get forms
of a noun, and two or three times by make_decl_adj for each of the genders
of an adjective.
]=]
function export.make_decl(args, decl, root)
if not export.inflections[decl] then
error('unrecognized inflection type ' .. decl)
end
-- mw.log(root, decl)
args.stem = { m_accent.ult(root), m_accent.penult(root), root }
if not mw.ustring.match(decl, '^3rd.+p[ra]x') and not mw.ustring.match(decl, 'prx') then
args.stem[2] = m_accent.circ(root)
end
export.inflections[decl](args)
args.gender[1] = args.gender[1] or args.ctable['g']
args.declheader = args.declheader or args.ctable['decl']
add_forms(args)
end
-- Constructs an adverb, comparative, and superlative.
function export.make_acs(args)
if export.adjinflections_con[args.decl_type] and not args.form:match('open') then
if args.decl_type:match('3rd%-εσ%-adj') then
args.atable.comp = args.root .. 'έστερος'
else
args.atable.comp = args.root .. 'εώτερος' -- I assume—though I can't find examples
end
args.atable.super = mw.ustring.sub(args.atable.comp, 1, -5) .. 'ᾰτος'
elseif args.decl_type == '1&2-alp-prx' and mw.ustring.sub(args.root, -3) == 'τερ' then
args.atable.comp = '(' .. args.atable['MNS'] .. ')'
args.atable.super = mw.ustring.gsub(args.atable.comp, 'τερος$', 'τᾰτος')
args.atable.adv = args.atable['NNS']
args.comp = nil
elseif args.decl_type == '1&2-alp-prx' and mw.ustring.sub(args.root, -3) == 'τᾰτ' then
args.atable.super = '(' .. args.atable['MNS'] .. ')'
args.atable.comp = mw.ustring.gsub(args.atable.super, 'τᾰτος$', 'τερος')
args.atable.adv = args.atable['NNP']
args.super = nil
elseif args.decl_type:match('ups') then
args.atable.comp = args.root .. 'ῠ́τερος'
elseif args.decl_type == '1&3-οτ' then
args.atable.comp = nil
args.atable.super = nil
elseif args.decl_type == '1&3-ᾰν-pax' then
args.atable.comp = args.root .. 'ᾰ́ντερος'
elseif args.decl_type == '1&3-εν-pax' then
args.atable.comp = args.root .. 'έντερος'
elseif args.decl_type == '1&3-εντ-pax' then
args.atable.comp = args.root .. 'έστερος' -- hopefully this is general?
elseif mw.ustring.match(args.decl_type, 'ντ') then
args.atable.comp = nil --participles
args.atable.super = nil
elseif args.decl_type:match('cons') then
if mw.ustring.match(args.root, 'ον$') then
args.atable.comp = args.root .. 'έστερος'
elseif mw.ustring.match(args.root, 'εσ$') then
args.atable.comp = mw.ustring.sub(args.root, 1, -3) .. 'έστερος'
else
args.atable.comp = nil --not really regular afaict
args.atable.super = nil
end
elseif ((m_accent.circ(args.root) == m_accent.ult(args.root)) or args.decl_type:match('att')) and not args.hp then
args.atable.comp = args.root .. 'ώτερος'
else
args.atable.comp = args.root .. 'ότερος'
end
args.atable.adv = args.adv or args.atable.adv or mw.ustring.gsub(mw.ustring.gsub(args.atable.MGP, 'ν$', 'ς'), 'ν<', 'ς<')
args.atable.comp = args.comp or args.atable.comp
args.atable.super = args.super or args.atable.super or (args.atable.comp and mw.ustring.gsub(args.atable.comp, 'ερος$', 'ᾰτος'))
end
--[=[
Interprets the table for the adjective's inflection type
in [[Module:grc-decl/decl/staticdata]].
]=]
function export.make_decl_adj(args, ct)
--[[
Two possibilities, with the indices of the table of endings
and the stem augmentation that they use:
- masculine–feminine (1, a1), neuter (2, a2)
- masculine (1, a1), feminine (2, a2), neuter (3, a1)
]]
-- Masculine or masculine and feminine forms.
export.make_decl(args, ct[1], args.root .. (ct.a1 or ''))
for k, v in pairs(args.ctable) do
args.atable['M' .. k] = v
end
-- Feminine or neuter forms.
if ct[2] then
export.make_decl(args, ct[2], args.fstem or (args.root .. (ct.a2 or '')))
for k, v in pairs(args.ctable) do
args.atable['F' .. k] = v
end
end
export.make_decl(args, ct[3], args.root .. (ct.a1 or ''))
for k, v in pairs(args.ctable) do
args.atable['N' .. k] = v
end
args.ctable = nil
export.make_acs(args)
args.adeclheader = ct.adeclheader or 'Declension'
end
function export.get_decl(args)
if args[1] == 'indecl' then
if not args[2] then error("Specify the indeclinable form in the 2nd parameter.") end
args.decl_type, args.root = 'indecl', ''
return
elseif args[1] == 'irreg' then
if args.gender[1] == "N" then
args.decl_type, args.root = 'irregN', ''
else
args.decl_type, args.root = 'irreg', ''
end
return
end
if not args[1] or not args[2] then error("Use the 1st and 2nd parameters for the nominative and genitive singular.") end
args[1] = mw.ustring.toNFD(args[1])
args[2] = mw.ustring.toNFD(args[2])
local nomstrip = m_accent.strip_tone(args[1])
local genstrip = m_accent.strip_tone(args[2])
if not mw.ustring.match(args[1], 'ῠς?$') then
genstrip = mw.ustring.gsub(genstrip, 'εος$', 'ους')
genstrip = mw.ustring.gsub(genstrip, 'α[̆]ος$', 'ως')
end
local nom_match, decl_type, root, nom, gen
for i = 5, 1, -1 do
local NS = mw.ustring.sub(nomstrip, -i)
local decl = m_decl_static_data.infl_info[NS]
if type(decl) == "string" then
decl = m_decl_static_data.infl_info[decl]
end
if decl then
nom_match = decl
root = mw.ustring.sub(nomstrip, 1, -(1 + mw.ustring.len(NS)))
nom = NS
for i = 6, 1, -1 do
local GS = mw.ustring.sub(genstrip, -i)
local name = decl[GS]
if name then
decl_type = name
gen = GS
break
end
end
if decl_type then
-- mw.log(nomstrip, nom, genstrip, gen, decl_type)
break
end
end
end
if decl_type and root then
-- This could be simplified by writing a new function in [[Module:grc-accent]].
mw.log("actual form: " .. args[1], "ult: " .. m_accent.ult(nomstrip), "circ: " .. m_accent.circ(nomstrip), "pencirc: " .. m_accent.pencirc(nomstrip), "antepenult: " .. m_accent.antepenult(nomstrip), "penult: " .. m_accent.penult(nomstrip))
local suffix = '-prx'
if m_accent.ult(nomstrip) == args[1] then
suffix = ''
elseif m_accent.circ(nomstrip) == args[1] then
suffix = '-con'
elseif m_accent.pencirc(nomstrip) == args[1] and export.inflections[decl_type .. '-pax'] then
suffix = '-pax'
elseif m_accent.antepenult(nomstrip) == args[1] then
suffix = '-prx'
elseif m_accent.penult(nomstrip) == args[1] then -- we have a word someone didn't put a breve on
suffix = '-pax'
end
decl_type = decl_type .. suffix
args.decl_type, args.root = decl_type, root
return
elseif mw.ustring.match(genstrip, 'ος$') then
local suffix = '-prx'
if m_accent.circ(nomstrip) == args[1] or m_accent.ult(nomstrip) == args[1] then
suffix = ''
elseif m_accent.pencirc(nomstrip) == args[1] then
suffix = '-pax'
end
local root = mw.ustring.sub(genstrip, 1, -3)
if args.gender[1] == "N" or (mw.ustring.match(root, 'α[̆̄]τ$') and not (args.gender[1] == "M" and args.gender[2] == "F")) then
args.decl_type, args.root = '3rd-N-cons' .. suffix, root
else
args.decl_type, args.root = '3rd-cons' .. suffix, root
end
return
end
if nom_match then
local gens = {}
for gen, name in pairs(nom_match) do
table.insert(gens, quote("-" .. gen))
end
local agreement = { "A declension was", " ", " does" }
if #gens > 1 then
agreement = { "Declensions were", "s ", " do" }
end
gens = table.concat(gens, ", ")
error(agreement[1] .. " found that matched the ending of the nominative form " .. quote(args[1]) ..
", but the genitive ending" .. agreement[2] .. gens ..
agreement[3] .. " not match the genitive form " .. quote(args[2]) .. ".")
else
for nom, gens in pairs(m_decl_static_data.ambig_forms) do
for gen, _ in pairs(gens) do
if mw.ustring.match(args[1], nom .. "$") and mw.ustring.match(args[2], gen .. "$") then
error("No declension found for nominative " .. quote(args[1]) .. " and genitive " .. quote(args[2]) ..
". There are two declensions with nominative " .. quote("-" .. nom) ..
" and genitive " .. quote("-" .. gen) ..
". To indicate which one you mean, mark the vowel length of the endings with a macron or breve.")
end
end
end
error("Can’t find a declension type for nominative " .. quote(args[1]) .. " and genitive " .. quote(args[2]) .. ".")
end
end
function export.get_decl_adj(args)
if args[1] == 'irreg' then
args.decl_type, args.root = 'irreg', ''
return
end
if not args[1] then error("Use the 1st and 2nd parameters for the masculine and feminine/neuter nominative singular or 3rd declension stem.") end
args[1] = mw.ustring.toNFD(args[1])
if args[2] then
args[2] = mw.ustring.toNFD(args[2])
end
local mstrip = m_accent.strip_tone(args[1])
local fstrip
if args[2] then
fstrip = m_accent.strip_tone(args[2])
end
if not args[2] then
local suffix = '-prx'
if args[1] == m_accent.ult(mstrip) then
suffix = ''
elseif args[1] == m_accent.pencirc(mstrip) then
suffix = '-pax'
end
args.decl_type, args.root = '3rd-cons' .. suffix, mstrip
if not export.adjinflections[args.decl_type] then
error('Unrecognized inflection type ' .. args.decl_type)
end
return
end
-- See if last three or two characters of masc have an entry.
local masc, decl
for i = 3, 2, -1 do
local ending = mw.ustring.sub(mstrip, -i)
local data = m_decl_static_data.infl_info_adj[ending]
if data then
masc = ending
decl = data
break
end
end
-- Allows redirecting, so that macrons or breves can be omitted for instance.
if type(decl) == "string" then
decl = m_decl_static_data.infl_info_adj[decl]
end
if decl then
-- Look for a feminine ending that matches the end of the feminine form.
local fem, name
for feminine, decl_name in pairs(decl) do
if mw.ustring.match(fstrip, feminine .. '$') then
fem = feminine
name = mw.ustring.gsub(decl_name, "%d$", "")
break
end
end
if fem then
if name == '1&2-alp-con' and mw.ustring.match(fstrip, 'ουσα$') then
name = '1&3-ουντ'
end
local suffix = '-prx'
if args[1] == m_accent.ult(mstrip) then
suffix = ''
elseif args[1] == m_accent.circ(mstrip) then
suffix = '-con'
elseif args[1] == m_accent.pencirc(mstrip) and name ~= '3rd-εσ-adj' then
suffix = '-pax'
elseif name == '3rd-εσ-adj' and args[2] == m_accent.pencirc(fstrip) then
suffix = '-prp'
end
args.decl_type, args.root = name .. suffix, mw.ustring.sub(mstrip, 1, -1 - mw.ustring.len(masc))
if not export.adjinflections[args.decl_type] then
error('Unrecognized inflection type ' .. args.decl_type)
end
return
else
local fems = {}
local is_neuter = false
for fem, name in pairs(decl) do
if fem == "ον" then
is_neuter = true
end
table.insert(fems, quote("-" .. fem))
end
fems = table.concat(fems, ", ")
local agreement = { "A declension was", " ", " does" }
if #fems > 1 then
agreement = { "Declensions were", "s ", " do" }
end
error(agreement[1] .. " found that matched the ending of the masculine " .. quote(args[1]) ..
", but the corresponding feminine" .. (is_neuter and " and neuter" or "") .. " ending" .. agreement[2] .. fems ..
agreement[3] .. " not match the feminine " .. quote(args[2]) .. ".")
end
end
error("Can’t find a declension type for masculine " .. quote(args[1]) .. " and feminine " .. quote(args[2]) .. ".")
end
--[[
Returns a table containing the inflected forms of the article,
to be placed before each inflected noun form.
]]
function export.infl_art(args)
if args.dial == 'epi' or args.adjective or args.form:match('X') then
return {}
end
local art = {}
local arttable
if args.gender[1] then
arttable = m_paradigms.art_att[args.gender[1]]
else
error('Gender not specified.')
end
for code, suffix in pairs(arttable) do
if (args.gender[1] == "M" and args.gender[2] == "F") and m_paradigms.art_att.M[code] ~= m_paradigms.art_att.F[code] then
art[code] = m_paradigms.art_att.M[code] .. ', ' .. m_paradigms.art_att.F[code]
else
art[code] = suffix
end
end
if args.gender[1] == 'F' then
if m_dialect_groups['nonIA'][args.dial] then
art['NS'] = 'ᾱ̔' -- 104.1-4
art['GS'] = 'τᾶς'
art['DS'] = 'τᾷ'
art['AS'] = 'τᾱ̀ν'
end
if args.dial == 'the' or args.dial == 'les' then
art['DS'] = 'τᾶ' -- 39
elseif args.dial == 'boi' or args.dial == 'ara' or args.dial == 'ele' then
art['DS'] = 'ται' -- 104.3
end
if m_dialect_groups['nonIA'][args.dial] then
art['GP'] = 'τᾶν' -- 104.6
end
if args.dial == 'ato' then
art['DP'] = 'τῆσῐ(ν)' -- 104.7
elseif args.dial == 'ion' then
art['DP'] = 'τῇσῐ(ν)' -- 104.7
end
if m_dialect_groups['buck78'][args.dial] then
art['AP'] = 'τᾰ̀ς' -- 104.8
elseif args.dial == 'kre' or args.dial == 'arg' then
art['AP'] = 'τὰνς'
elseif args.dial == 'les' then
art['AP'] = 'ταῖς'
elseif args.dial == 'ele' then
art['AP'] = 'ταὶρ'
end
if args.dial == 'kre' or args.dial == 'les' or args.dial == 'kyp' then
art['NS'] = 'ᾱ̓' -- 57
art['NP'] = 'αἰ'
elseif args.dial == 'ele' then
art['NS'] = 'ᾱ̓'
art['NP'] = 'ταὶ'
elseif args.dial == 'boi' then
art['NP'] = 'τὴ' -- 104.5
elseif m_dialect_groups['west'][args.dial] then --boeotian is covered above
art['NP'] = 'ταὶ'
end
elseif args.gender[1] == 'M' or args.gender[1] == 'N' then
if args.dial == 'the' then
art['GS'] = 'τοῖ' -- 106.1
art['DS'] = 'τοῦ' -- 23
art['ND'] = 'τοὺ'
art['GP'] = 'τοῦν'
end
if args.dial == 'les' then
art['DS'] = 'τῶ' -- 106.2
elseif args.dial == 'boi' or args.dial == 'ara' or args.dial == 'ele' or args.dial == 'eub' then
art['DS'] = 'τοι' -- 106.2
end
if args.dial == 'ato' or args.dial == 'ion' then
art['DP'] = 'τοῖσῐ(ν)' -- 106.4
end
if args.gender[1] == 'M' then
if m_dialect_groups['buck78'][args.dial] then
art['AP'] = 'τὸς' -- 106.5
elseif args.dial == 'kre' or args.dial == 'arg' then
art['AP'] = 'τὸνς'
elseif args.dial == 'les' then
art['AP'] = 'τοῖς'
elseif args.dial == 'ele' then
art['AP'] = 'τοὶρ'
elseif m_dialect_groups['severe'][args.dial] or args.dial == 'boi' then
art['AP'] = 'τὼς'
end
if args.dial == 'kre' or args.dial == 'les' or args.dial == 'kyp' then
art['NS'] = 'ὀ' -- 57
art['NP'] = 'οἰ'
elseif args.dial == 'ele' then
art['NS'] = 'ὀ'
art['NP'] = 'τοὶ'
elseif m_dialect_groups['west'][args.dial] or args.dial == 'boi' then
art['NP'] = 'τοὶ'
end
end
if args.dial == 'ele' then
art['GD'] = 'τοίοις'
-- elseif args.dial == 'ara' then
-- art['GD'] = 'τοιυν'
end
end
return art
end
local lang = require("Module:languages").getByCode("grc")
local function tag(text)
return require("Module:script utilities").tag_text("-" .. text, lang)
end
local function print_detection_table(detection_table, labels, noun)
local out = {}
for key1, value1 in pairs(detection_table) do
table.insert(out, "\n* " .. labels[1] .. " " .. tag(key1))
if type(value1) == "string" then
table.insert(out, " → " .. tag(value1))
elseif type(value1) == "table" then
for key2, value2 in pairs(value1) do
mw.log(mw.ustring.len(key1), mw.ustring.len(key2))
table.insert(out, "\n** " .. (noun and labels[2] or key2 == "ον" and "neuter" or "feminine") .. " " .. tag(key2) .. ": " .. value2)
if noun then
table.insert(out, " (" .. (m_decl_static_data.conversion[value2] or "?") .. ")")
end
end
end
end
return out
end
function export.show_noun_categories(frame)
local out = print_detection_table(m_decl_static_data.infl_info, { "nominative", "genitive" }, true)
return table.concat(out)
end
function export.show_adj_categories(frame)
local out = print_detection_table(m_decl_static_data.infl_info_adj, { "masculine", "feminine or neuter" })
return table.concat(out)
end
return export