local export = {}
local m_table = require( "Module:table" )
local m_links = require( "Module:links" )
local m_string_utilities = require( "Module:string utilities" )
local lang = require( "Module:languages" ).getByCode( "mn" )
local com = require( "Module:mn-common" )
local iut = require( "Module:inflection utilities" )
local put = require("Module:parse utilities")
local m_para = require( "Module:parameters" )
local char = mw.ustring.char
local find = mw.ustring.find
local format = mw.ustring.format
local len = require( "Module:string" ).ulen
local match = mw.ustring.match
local gmatch = mw.ustring.gmatch
local sub = mw.ustring.sub
local gsub = mw.ustring.gsub
local lower = mw.ustring.lower
local split = mw.text.split
local reverse = require( "Module:string" ).reverse
local upper = mw.ustring.upper
table.append = require( "Module:table" ).append
local FVS = ""
local n = char( 0xFFF0 )
local g = char( 0xFFF1 )
local bor = char( 0xFFF2 )
local Russian = char( 0xFFF3 )
local proper = char( 0xFFF4 )
local output_verb_slots = {
imp = "imp",
prec = "prec",
prescr = "prescr",
bened = "bened",
voln = "voln",
perm = "perm",
des = "des",
dub = "dub",
opt = "opt",
conc = "conc",
potn = "potn",
presump = "presump",
dur_ind = "dur|ind",
conf_ind = "conf|ind",
term_ind = "term|ind",
res_ind = "res|ind",
futv_ptcp = "futv|ptcp",
habv_ptcp = "habv|ptcp",
impfv_ptcp = "impfv|ptcp",
pfv_ptcp = "pfv|ptcp",
ag_ptcp = "ag|ptcp",
impfv_conv = "impfv|conv",
pfv_conv = "pfv|conv",
mod_conv_1 = "mod|conv",
mod_conv_2 = "mod|conv",
neg_mod_conv = "neg|mod|conv",
mom_conv = "mom|conv",
ser_conv = "ser|conv",
abtemp_conv = "abtemp|conv",
purp_conv_1 = "purp|conv",
purp_conv_2 = "purp|conv",
incid_conv = "incid|conv",
precond_conv = "precond|conv",
cond_conv_1 = "cond|conv",
cond_conv_2 = "cond|conv",
conc_conv = "conc|conv",
term_conv = "term|conv",
imm_conv = "imm|conv",
concom_conv_1 = "concom|conv",
concom_conv_2 = "concom|conv",
succ_conv = "succ|conv",
contemp_conv = "contemp|conv",
intent,
nec
}
local output_verb_slots_with_linked = m_table.shallowcopy( output_verb_slots )
output_verb_slots_with_linked = "nom|s"
output_verb_slots_with_linked = "nom|p"
local input_params_to_slots_both = {
= "attr",
= "nom_sg",
= "gen_sg",
= "acc_sg",
= "dat_loc_sg",
= "gen_dat_sg",
= "abl_sg",
= "dat_abl_sg",
= "ins_sg",
= "com_sg",
= "priv_sg",
= "dirc_sg",
= "nom_pl",
= "gen_pl",
= "acc_pl",
= "dat_loc_pl",
= "gen_dat_pl",
= "abl_pl",
= "dat_abl_pl",
= "ins_pl",
= "com_pl",
= "priv_pl",
= "dirc_pl",
= "spos_indgen_sg",
= "cpos_indgen_sg",
= "spos_indgen_pl",
= "cpos_indgen_pl",
= "spos_indloc_sg",
= "cpos_indloc_sg",
= "spos_indloc_pl",
= "cpos_indloc_pl",
= "nom_sg_refl",
= "gen_sg_refl",
= "acc_sg_refl",
= "dat_loc_sg_refl",
= "gen_dat_sg_refl",
= "abl_sg_refl",
= "dat_abl_sg_refl",
= "ins_sg_refl",
= "com_sg_refl",
= "priv_sg_refl",
= "dirc_sg_refl",
= "nom_pl_refl",
= "gen_pl_refl",
= "acc_pl_refl",
= "dat_loc_pl_refl",
= "gen_dat_pl_refl",
= "abl_pl_refl",
= "dat_abl_pl_refl",
= "ins_pl_refl",
= "com_pl_refl",
= "priv_pl_refl",
= "dirc_pl_refl",
}
local input_params_to_slots_sg = {
= "attr",
= "nom_sg",
= "gen_sg",
= "acc_sg",
= "dat_loc_sg",
= "gen_dat_sg",
= "abl_sg",
= "dat_abl_sg",
= "ins_sg",
= "com_sg",
= "priv_sg",
= "dirc_sg",
= "spos_indgen_sg",
= "cpos_indgen_sg",
= "spos_indloc_sg",
= "cpos_indloc_sg",
= "nom_sg_refl",
= "gen_sg_refl",
= "acc_sg_refl",
= "dat_loc_sg_refl",
= "gen_dat_sg_refl",
= "abl_sg_refl",
= "dat_abl_sg_refl",
= "ins_sg_refl",
= "com_sg_refl",
= "priv_sg_refl",
= "dirc_sg_refl",
}
local input_params_to_slots_pl = {
= "attr",
= "nom_pl",
= "gen_pl",
= "acc_pl",
= "dat_loc_pl",
= "gen_dat_pl",
= "abl_pl",
= "dat_abl_pl",
= "ins_pl",
= "com_pl",
= "priv_pl",
= "dirc_pl",
= "spos_indgen_pl",
= "cpos_indgen_pl",
= "spos_indloc_pl",
= "cpos_indloc_pl",
= "nom_pl_refl",
= "gen_pl_refl",
= "acc_pl_refl",
= "dat_loc_pl_refl",
= "gen_dat_pl_refl",
= "abl_pl_refl",
= "dat_abl_pl_refl",
= "ins_pl_refl",
= "com_pl_refl",
= "priv_pl_refl",
= "dirc_pl_refl",
}
local input_params_to_slots_poss = {
= "nom",
= "gen",
= "acc",
= "dat_loc",
= "abl",
= "ins",
= "com",
= "priv",
= "dirc",
= "nom_refl",
= "gen_refl",
= "acc_refl",
= "dat_loc_refl",
= "abl_refl",
= "ins_refl",
= "com_refl",
= "priv_refl",
= "dirc_refl",
}
local cases = {
attr = true,
nom = true,
gen = true,
dat_loc = true,
gen_dat = true,
acc = true,
abl = true,
dat_abl = true,
ins = true,
com = true,
priv = true,
dirc = true,
}
local accented_cases = {
= "attr",
= "nom",
= "gen",
= "dat_loc",
= "gen_dat",
= "acc",
= "abl",
= "dat_abl",
= "ins",
= "com",
= "priv",
= "dirc",
}
local function skip_slot( number, slot )
return number == "sg" and find( slot, "_p$" ) or
number == "pl" and find( slot, "_s$" )
end
local function add( data, slot, stem_and_ending, footnotes )
local stem
local ending
if not stem_and_ending then
return
end
if skip_slot( data.number, slot ) then
return
end
if type( stem_and_ending ) == "string" then
stem = stem_and_ending
ending = ""
else
stem = stem_and_ending
ending = stem_and_ending
end
iut.add_forms( data.forms, slot, stem, ending, com.combine_stem_ending, lang )
end
local function process_slot_overrides( data, do_slot )
for slot, overrides in pairs( data.overrides ) do
if skip_slot( data.number, slot ) then
error( "Override specified for invalid slot '" .. slot .. "' due to '" .. data.number .. "' number restriction" )
end
if do_slot( slot ) then
data.forms = nil
local slot_is_plural = find( slot, "_p$" )
for _, override in ipairs( overrides ) do
for _, value in ipairs( override.values ) do
local form = value.form
local combined_notes = iut.combine_footnotes( data.footnotes, value.footnotes )
end
end
end
end
end
local function preprocess_inflection( infl )
local params = {}
if match( infl, Russian ) then params.bor = "Russian"
elseif match( infl, bor ) then params.bor = true end
if match( infl, proper ) then params.proper = true end
infl = gsub( infl, "", "" )
return infl, params
end
local function vowelharmony( infl, data )
return com.vowelharmony( infl, data )
end
local function syllables( infl )
return #com.syllables( infl )
end
local function propernoun( infl )
if sub( infl, 1, 1 ) ~= lower( sub( infl, 1, 1 ) ) then
return true
else
return false
end
end
local function voweldeletion( infl, data )
return com.voweldeletion( infl, data )
end
local function hidden_n( infl, params, vh )
infl = gsub( infl, n, "" )
local vh = vh or vowelharmony( infl, params )
local reduced = gsub( voweldeletion( infl, params ), FVS .. "$", "" )
local infl_nostress = lang:makeEntryName( infl )
local reduced_nostress = lang:makeEntryName( reduced )
local matches = {
{ { match( reduced_nostress, "$" ) },
"н"
},
{ { match( infl_nostress, "$" ) },
"ин"
},
{ {
match( infl_nostress, "$" ),
match( reduced_nostress, "$" ),
},
vh.Cyrl.a .. "н"
},
{ { match( infl_nostress, "" .. FVS .. "?$" ) },
"ᠨ"
},
{ { match( infl_nostress, "" .. FVS .. "?$" ) },
vh.Mong.u .. "ᠨ"
}
}
for s,t in ipairs( matches ) do
for _,m in pairs( t ) do
if m then return reduced .. t, {} end
end
end
end
local function hidden_g( infl )
infl = gsub( infl, g, "" )
return infl .. "г"
end
local function attributive( infl, vh )
if match( infl, n ) then
local infl, params = preprocess_inflection( infl )
return { hidden_n( infl, params, vh ), "" }
else
return { infl, "" }
end
end
local function plural( infl, vh )
local infl, params = preprocess_inflection( infl )
if match( infl, n ) then infl, params = hidden_n( infl, params, vh )
elseif match( infl, g ) then infl = hidden_g( infl ) end
local vh = vh or vowelharmony( infl, params )
local reduced = voweldeletion( infl, params )
local infl_nostress = lang:makeEntryName( infl )
local reduced_nostress = lang:makeEntryName( reduced )
local matches = {
{ {
match( infl_nostress, "ч.н$" ),
match( infl_nostress, "ён$" )
},
"д"
},
{ { match( infl_nostress, "$" ) },
"н" .. vh.Cyrl.uu .. "д"
},
{ {
match( infl_nostress, "$" ),
match( reduced_nostress, "$" ), -- C, and also loanwords with a word-final long vowel written as a single vowel
match( infl_nostress, "$" ) and params.bor
},
"г" .. vh.Cyrl.uu .. "д"
},
{ { match( infl_nostress, "$" ) },
"и" .. vh.Cyrl.u .. "д"
},
{ { match( infl_nostress, "$" ) },
vh.Cyrl.u .. "д"
},
{ { match( infl_nostress, "?$" ) },
vh.Cyrl.uu .. "д"
},
{ { match( infl_nostress, "" .. FVS .. "?$" ) },
com.NNBSP .. "ᠨ" .. vh.Mong.u .. "ᠭ" .. vh.Mong.u .. "ᠳ"
},
{ { match( infl_nostress, "" .. FVS .. "?$" ) },
com.NNBSP .. vh.Mong.u .. "ᠳ"
}
}
for s,t in ipairs( matches ) do
for _,m in pairs( t ) do
if match( infl_nostress, "^хүн$" ) then
return { "хүмүүс", "" }
elseif t == "д" then
return { sub( infl, 1, len( infl ) - 1 ), t }
else
return { reduced, t }
end
end
end
end
local function genitive( infl, vh )
local infl, params = preprocess_inflection( infl )
if match( infl, n ) then infl, params = hidden_n( infl, params, vh )
elseif match( infl, g ) then infl = hidden_g( infl ) end
local vh = vh or vowelharmony( infl, params )
local reduced = voweldeletion( infl, params )
local infl_nostress = lang:makeEntryName( infl )
local reduced_nostress = lang:makeEntryName( reduced )
local matches = {
{ { match( infl_nostress, "н$" ) },
vh.Cyrl.ii
},
{ {
match( infl_nostress, "$" ),
match( reduced_nostress, "и$" )
},
"н"
},
{ {
match( infl_nostress, "$" ),
match( reduced_nostress, "$" ), -- C, and also loanwords with a word-final long vowel written as a single vowel
match( infl_nostress, "$" ) and params.bor
},
"гийн"
},
{ { match( infl_nostress, "$" ) },
"ийн"
},
{ {
match( infl_nostress, "$" ),
match( infl_nostress, "$" ),
match( infl_nostress, "$" ) -- not C
},
vh.Cyrl.ii .. "н"
},
{ { match( infl_nostress, "" .. FVS .. "?$" ) },
com.NNBSP .. "ᠶᠢᠨ"
},
{ { match( infl_nostress, "ᠨ" .. FVS .. "?$" ) },
com.NNBSP .. vh.Mong.u
},
{ { match( infl_nostress, "" .. FVS .. "?$" ) },
com.NNBSP .. vh.Mong.u .. "ᠨ"
}
}
for s,t in ipairs( matches ) do
for _,m in pairs( t ) do
if m then return { reduced, t } end
end
end
end
local function accusative( infl, vh )
local infl, params = preprocess_inflection( infl )
if match( infl, n ) then infl = gsub( infl, n, "" )
elseif match( infl, g ) then return { infl, "г" } end
local vh = vh or vowelharmony( infl, params )
local reduced = voweldeletion( infl, params )
local infl_nostress = lang:makeEntryName( infl )
local reduced_nostress = lang:makeEntryName( reduced )
local matches = {
{ {
match( infl_nostress, "$" ),
match( infl_nostress, "$" ),
match( reduced_nostress, "$" ), -- C, and also loanwords with a word-final long vowel written as a single vowel
match( reduced_nostress, "и$" ),
match( infl_nostress, "$" ) and params.bor
},
"г"
},
{ { match( infl_nostress, "$" ) },
"ийг"
},
{ {
match( infl_nostress, "$" ),
match( infl_nostress, "$" ),
match( infl_nostress, "$" ) -- not C
},
vh.Cyrl.ii .. "г"
},
{ { match( infl_nostress, "" .. FVS .. "?$" ) },
com.NNBSP .. "ᠶᠢ"
},
{ { match( infl_nostress, "" .. FVS .. "?$" ) },
com.NNBSP .. "ᠢ"
}
}
for s,t in ipairs( matches ) do
for _,m in pairs( t ) do
if m then return { reduced, t } end
end
end
end
local function dative_locative( infl, vh )
local infl, params = preprocess_inflection( infl )
if match( infl, n ) then infl, params = hidden_n( infl, params, vh )
elseif match( infl, g ) then infl = gsub( infl, g, "" ) end
local vh = vh or vowelharmony( infl, params )
local syllables = syllables( infl )
local reduced = voweldeletion( infl, params )
local infl_nostress = lang:makeEntryName( infl )
local reduced_nostress = lang:makeEntryName( reduced )
local vowel = ""
local consonant = ""
local matches = {
{ {
match( infl_nostress, "$" ) or match( infl_nostress, "п$" ),
( match( infl_nostress, "в$" ) or match( infl_nostress, "б$" ) ) and ( syllables ~= 1 or match( infl_nostress, "^" .. consonant .. consonant ) ),
match( infl_nostress, vowel .. vowel .. "$" ) or match( infl_nostress, consonant .. "р$" ),
( match( infl_nostress, "р$" ) or match( infl_nostress, vowel .. "с$" ) ) and ( syllables ~= 1 or params.proper ),
match( infl_nostress, vowel .. "ь?с$" ),
match( infl_nostress, "ьс$" ),
match( infl_nostress, "ис$" ),
},
"т"
},
{ {
match( infl_nostress, vowel .. "$" ),
match( infl_nostress, "б$" ),
match( infl_nostress, "$" ),
match( infl_nostress, "ь$" ),
},
"д"
},
{ {
match( infl_nostress, "ь?$" ),
match( infl_nostress, "ь$" )
},
"ид"
},
{ { match( infl_nostress, "" .. FVS .. "?$" ) },
com.NNBSP .. "ᠲ" .. vh.Mong.u
},
{ { match( infl_nostress, "" .. FVS .. "?$" ) },
com.NNBSP .. "ᠳ" .. vh.Mong.u
},
{ { match( infl_nostress, ".$" ) },
vh.Cyrl.a .. "д"
}
}
for s,t in ipairs( matches ) do
for _,m in pairs( t ) do
if m then
if match( infl_nostress, "ь$" ) then
return { sub( infl, 1, len( infl ) - 1 ), t }
elseif match( infl_nostress, "$" ) then
return { reduced, t }
else
return { infl, t }
end
end
end
end
end
local function aa( infl, params )
local vh = vh or vowelharmony( infl, params )
local reduced = voweldeletion( infl, params )
local infl_nostress = lang:makeEntryName( infl )
local reduced_nostress = lang:makeEntryName( reduced )
local matches = {
{ {
match( infl_nostress, "$" ),
match( infl_nostress, "$" ),
match( reduced_nostress, "$" ), -- C, and also loanwords with a word-final long vowel written as a single vowel
match( reduced_nostress, "и$" ),
match( infl_nostress, "$" ) and params.bor
},
"г" .. vh.Cyrl.aa
},
{ { match( infl_nostress, "$" ) },
vh.Cyrl.a
},
{ { match( infl_nostress, "$" ) },
"и" .. vh.Cyrl.a
},
{ {
match( infl_nostress, "$" ),
match( infl_nostress, "$" ) -- not C
},
vh.Cyrl.aa
}
}
for s,t in ipairs( matches ) do
for _,m in pairs( t ) do
if m then return reduced, t end
end
end
end
local function ablative( infl, vh )
local infl, params = preprocess_inflection( infl )
if match( infl, n ) then infl, params = hidden_n( infl, params, vh )
elseif match( infl, g ) then infl = hidden_g( infl ) end
local vh = vh or vowelharmony( infl, params )
if match( infl, com.NNBSP .. "" .. vh.Mong.u .. "$" ) then
return { sub( infl, 1, len( infl ) - 1 ), vh.Mong.a .. "ᠴ" .. vh.Mong.a }
elseif match( infl, "" .. FVS .. "?$" ) then
return { infl, com.NNBSP .. vh.Mong.a .. "ᠴ" .. vh.Mong.a }
else
local stem, ending = aa( infl, params )
return { stem, ending .. "с" }
end
end
local function instrumental( infl, vh )
local infl, params = preprocess_inflection( infl )
if match( infl, n ) then infl = gsub( infl, n, "" )
elseif match( infl, g ) then infl = hidden_g( infl ) end
if match( infl, "" .. FVS .. "?$" ) then
local matches = {
{ { match( infl, "" .. FVS .. "?$" ) },
com.NNBSP .. "ᠪ" .. vh.Mong.a .. "ᠷ"
},
{ { match( infl, "" .. FVS .. "?$" ) },
com.NNBSP .. "ᠢᠶ" .. vh.Mong.a .. "ᠷ"
}
}
for s,t in ipairs( matches ) do
for _,m in pairs( t ) do
if m then return { infl, t } end
end
end
else
local stem, ending = aa( infl, params )
return { stem, ending .. "р" }
end
end
local function reflexive( infl, vh )
local infl, params = preprocess_inflection( infl )
if match( infl, n ) then infl = gsub( infl, n, "" )
elseif match( infl, g ) then infl = hidden_g( infl ) end
if match( infl, "" .. FVS .. "?$" ) then
local matches = {
{ { match( infl, com.NNBSP .. "ᠶ?ᠢ$" ) },
"ᠶ" .. vh.Mong.u .. "ᠭ" .. vh.Mong.a .. "ᠨ"
},
{ { match( infl, com.NNBSP .. "" .. vh.Mong.u .. "$" ) },
vh.Mong.a .. "ᠭ" .. vh.Mong.a .. "ᠨ"
},
{ { match( infl, com.NNBSP .. vh.Mong.a .. "ᠴ" .. vh.Mong.a .. "$" ) },
"ᠭ" .. vh.Mong.a .. "ᠨ"
},
{ { match( infl, com.NNBSP .. "ᠲ" .. vh.Mong.a .. "ᠢ$" ) },
"ᠶᠢᠭ" .. vh.Mong.a .. "ᠨ"
},
{ { match( infl, "" .. FVS .. "?$" ) },
com.NNBSP .. "ᠪ" .. vh.Mong.a .. "ᠨ"
},
{ { match( infl, "" .. FVS .. "?$" ) },
com.NNBSP .. "ᠢᠶ" .. vh.Mong.a .. "ᠨ"
}
}
for s,t in ipairs( matches ) do
for _,m in pairs( t ) do
if m then
if match( infl, com.NNBSP .. "ᠶᠢ$" ) then
return { sub( infl, 1, len( infl ) - 2 ), t }
elseif match( infl, com.NNBSP .. "ᠢ$" ) or match( infl, com.NNBSP .. "" .. vh.Mong.u .. "$" ) or match( infl, com.NNBSP .. "ᠲ" .. vh.Mong.a .. "ᠢ$" ) then
return { sub( infl, 1, len( infl ) - 1 ), t }
else
return { infl, t }
end
end
end
end
else
local stem, ending = aa( infl, params )
return { stem, ending .. n }
end
end
local function comitative( infl, vh )
local infl, params = preprocess_inflection( infl )
if match( infl, n ) then infl = gsub( infl, n, "" )
elseif match( infl, g ) then infl = gsub( infl, g, "" ) end
local vh = vh or vowelharmony( infl, params )
if match( infl, "ь$" ) then
return { sub( infl, 1, len( infl ) - 1 ), "ит" .. vh.Cyrl.ai, }
elseif match( infl, "" .. FVS .. "?$" ) then
return { infl, com.NNBSP .. "ᠲ" .. vh.Mong.a .. "ᠢ" }
else
return { infl, "т" .. vh.Cyrl.ai }
end
end
local function privative( infl )
local infl = preprocess_inflection( infl )
if match( infl, n ) then infl = gsub( infl, n, "" )
elseif match( infl, g ) then infl = gsub( infl, g, "" ) end
if match( infl, "" .. FVS .. "?$" ) then
return { infl, com.NNBSP .. "ᠦᠭᠡᠢ" }
else
return { infl, "гүй" }
end
end
local function directive( infl, vh )
local infl, params = preprocess_inflection( infl )
if match( infl, n ) then infl = gsub( infl, n, "" )
elseif match( infl, g ) then infl = gsub( infl, g, "" ) end
local vh = vh or vowelharmony( infl, params )
if match( infl, "рь?$" ) then
return { infl, " [[л" .. vh.Cyrl.uu }
elseif match( infl, "" .. FVS .. "?$" ) then
return { infl, com.NNBSP .. "ᠤᠷᠤᠭᠤ" }
else
return { infl, " [[р" .. vh.Cyrl.uu }
end
end
local function equative( infl )
end
local function singular_independent_genitive( infl )
local infl = preprocess_inflection( infl )
if match( infl, n ) then infl = gsub( infl, n, "" )
elseif match( infl, g ) then infl = gsub( infl, g, "" ) end
if match( infl, "" .. FVS .. "?$" ) then
return { infl, com.NNBSP .. "ᠬᠢ" }
else
return { infl, "х" }
end
end
local function collective_independent_genitive( infl, vh )
local infl, params = preprocess_inflection( infl )
if match( infl, n ) then infl = gsub( infl, n, "" )
elseif match( infl, g ) then infl = gsub( infl, g, "" ) end
local vh = vh or vowelharmony( infl, params )
if match( infl, "" .. FVS .. "?$" ) then
return { infl, com.NNBSP .. "ᠬᠢᠨ" }
else
return { infl, "х" .. vh.Cyrl.a .. "н" }
end
end
local function handle_derived_slots_and_overrides( data )
if data.decl == "n" then data.lemma = data.lemma .. n end
if data.decl == "g" then data.lemma = data.lemma .. g end
if data.bor == "Russian" then
data.lemma = data.lemma .. Russian
elseif data.bor then
data.lemma = data.lemma .. bor
end
if data.proper then data.lemma = data.lemma .. proper end
if data.number ~= "spos" and data.number ~= "cpos" then
add( data, "attr", attributive( data.lemma ) )
add( data, "nom_sg", data.lemma )
add( data, "gen_sg", genitive( data.lemma ) )
add( data, "acc_sg", accusative( data.lemma ) )
add( data, "dat_loc_sg", dative_locative( data.lemma ) )
add( data, "abl_sg", ablative( data.lemma ) )
add( data, "ins_sg", instrumental( data.lemma ) )
add( data, "com_sg", comitative( data.lemma ) )
add( data, "priv_sg", privative( data.lemma ) )
add( data, "dirc_sg", directive( data.lemma ) )
add( data, "nom_pl", plural( data.lemma ) )
add( data, "gen_pl", genitive( data.forms.form ) )
add( data, "acc_pl", accusative( data.forms.form ) )
add( data, "dat_loc_pl", dative_locative( data.forms.form ) )
add( data, "abl_pl", ablative( data.forms.form ) )
add( data, "ins_pl", instrumental( data.forms.form ) )
add( data, "com_pl", comitative( data.forms.form ) )
add( data, "priv_pl", privative( data.forms.form ) )
add( data, "dirc_pl", directive( data.forms.form ) )
add( data, "spos_indgen_sg", singular_independent_genitive( data.forms.form ) )
add( data, "cpos_indgen_sg", collective_independent_genitive( data.forms.form ) )
add( data, "spos_indgen_pl", singular_independent_genitive( data.forms.form ) )
add( data, "cpos_indgen_pl", collective_independent_genitive( data.forms.form ) )
--"spos_indloc_sg",
--"cpos_indloc_sg",
--"spos_indloc_pl",
--"cpos_indloc_pl",
add( data, "nom_sg_refl", reflexive( data.forms.form ) )
add( data, "gen_sg_refl", reflexive( data.forms.form ) )
add( data, "acc_sg_refl", reflexive( data.forms.form ) )
add( data, "dat_loc_sg_refl", reflexive( data.forms.form ) )
add( data, "abl_sg_refl", reflexive( data.forms.form ) )
add( data, "ins_sg_refl", reflexive( data.forms.form ) )
add( data, "com_sg_refl", reflexive( data.forms.form ) )
add( data, "priv_sg_refl", reflexive( data.forms.form ) )
add( data, "dirc_sg_refl", reflexive( data.forms.form ) )
add( data, "nom_pl_refl", reflexive( data.forms.form ) )
add( data, "gen_pl_refl", reflexive( data.forms.form ) )
add( data, "acc_pl_refl", reflexive( data.forms.form ) )
add( data, "dat_loc_pl_refl", reflexive( data.forms.form ) )
add( data, "abl_pl_refl", reflexive( data.forms.form ) )
add( data, "ins_pl_refl", reflexive( data.forms.form ) )
add( data, "com_pl_refl", reflexive( data.forms.form ) )
add( data, "priv_pl_refl", reflexive( data.forms.form ) )
add( data, "dirc_pl_refl", reflexive( data.forms.form ) )
if data.gen_dat then
add( data, "gen_dat_sg", dative_locative( data.forms.form ) )
add( data, "gen_dat_pl", dative_locative( data.forms.form ) )
add( data, "gen_dat_sg_refl", reflexive( data.forms.form ) )
add( data, "gen_dat_pl_refl", reflexive( data.forms.form ) )
end
if data.dat_abl then
add( data, "dat_abl_sg", ablative( data.forms.form ) )
add( data, "dat_abl_sg_refl", reflexive( data.forms.form ) )
end
else
add( data, "nom", data.lemma )
if data.number == "cpos" then
add( data, "gen", genitive( data.lemma ) )
end
add( data, "acc", accusative( data.lemma ) )
add( data, "dat_loc", dative_locative( data.lemma ) )
add( data, "abl", ablative( data.lemma ) )
add( data, "ins", instrumental( data.lemma ) )
add( data, "com", comitative( data.lemma ) )
add( data, "priv", privative( data.lemma ) )
add( data, "dirc", directive( data.lemma ) )
add( data, "nom_refl", reflexive( data.forms.form ) )
if data.number == "cpos" then
add( data, "gen_refl", reflexive( data.forms.form ) )
end
add( data, "acc_refl", reflexive( data.forms.form ) )
add( data, "dat_loc_refl", reflexive( data.forms.form ) )
add( data, "abl_refl", reflexive( data.forms.form ) )
add( data, "ins_refl", reflexive( data.forms.form ) )
add( data, "com_refl", reflexive( data.forms.form ) )
add( data, "priv_refl", reflexive( data.forms.form ) )
add( data, "dirc_refl", reflexive( data.forms.form ) )
end
for _,form in pairs( data.forms ) do
for _,variant in ipairs( form ) do
variant.form = gsub( variant.form, "", "" )
if match( gsub( variant.form, data.orig_lemma, "" ), " " ) then variant.form = variant.form .. "]]" end
end
end
-- Compute linked versions of potential lemma slots, for use in {{mn-noun}}.
-- We substitute the original lemma (before removing links) for forms that
-- are the same as the lemma, if the original lemma has links.
for _, slot in ipairs( { "nom_sg", "nom_pl" } ) do
iut.insert_forms( data.forms, slot .. "_linked", iut.map_forms( data.forms, function( form )
if form == data.orig_lemma_no_links and find( data.orig_lemma, "%[%[" ) then
return data.orig_lemma
else
return form
end
end ) )
end
end
local function fetch_footnotes( separated_group )
local footnotes
for j = 2, #separated_group - 1, 2 do
if separated_group ~= "" then
error( "Extraneous text after bracketed footnotes: '" .. table.concat( separated_group ) .. "'" )
end
if not footnotes then
footnotes = {}
end
table.insert( footnotes, separated_group )
end
return footnotes
end
local function parse_override( segments, case )
local retval = { values = {} }
local part = segments
if cases then
-- ok
elseif accented_cases then
case = accented_cases
retval.stemstressed = true
else
error("Internal error: unrecognized case in override: '" .. table.concat(segments) .. "'")
end
local rest = sub( part, len(case)+1, len(case)+3 )
local slot
if find( rest, "^pl" ) then
rest = gsub( rest, "^pl", "" )
slot = case .. "_pl"
else
slot = case .. "_sl"
end
if find( rest, "^:" ) then
retval.full = true
rest = gsub( rest, "^:", "" )
end
segments = rest
local colon_separated_groups = put.split_alternating_runs( segments, ":" )
for i, colon_separated_group in ipairs( colon_separated_groups ) do
local value = {}
local form = colon_separated_group
if form == "" then
error( "Use - to indicate an empty ending for slot '" .. slot .. "': '" .. table.concat( segments .. "'" ) )
elseif form == "-" then
value.form = ""
else
value.form = form
end
value.footnotes = fetch_footnotes( colon_separated_group )
table.insert( retval.values, value )
end
return slot, retval
end
local function parse_indicator_spec( angle_bracket_spec )
local inside = match( angle_bracket_spec, "^<(.*)>$" )
local data = { overrides = {}, forms = {} }
if inside ~= "" then
local segments = put.parse_balanced_segment_run( inside, "" )
local dot_separated_groups = put.split_alternating_runs( segments, "%." )
for i, dot_separated_group in ipairs( dot_separated_groups ) do
local part = dot_separated_group
local case_prefix
for case,_ in pairs( cases ) do
if match( part, "^" .. case .. "" ) then
case_prefix = match( part, "^" .. case )
local slot, override = parse_override( dot_separated_group, case_prefix )
if data.overrides then
table.insert( data.overrides, override )
else
data.overrides = { override }
end
end
end
if case_prefix ~= nil then
elseif part == "" then
if #dot_separated_group == 1 then
error( "Blank indicator: '" .. inside .. "'" )
end
data.footnotes = fetch_footnotes( dot_separated_group )
elseif part == "r" or part == "n" or part == "g" then
if data.decl then
error( "Can't specify declension twice: '" .. inside .. "'" )
end
data.decl = part
elseif part == "sg" or part == "pl" or part == "spos" or part == "cpos" then
if data.number then
error( "Can't specify number twice: '" .. inside .. "'" )
end
data.number = part
elseif part == "gen_dat" then
if data.gen_dat then
error( "Can't specify genitive-dative twice: '" .. inside .. "'" )
end
data.gen_dat = true
elseif part == "dat_abl" then
if data.dat_abl then
error( "Can't specify dative-ablative twice: '" .. inside .. "'" )
end
data.dat_abl = true
elseif part == "а" or part == "о" or part == "ө" or part == "э" then
if data.vh_override then
error( "Can't specify vowel harmony twice: '" .. inside .. "'" )
end
data.vh_override = part
elseif part == "bor" or part == "Russian" then
if data.bor then
error( "Can't specify borrowing twice: '" .. inside .. "'" )
end
data.bor = part
elseif part == "proper" then
if data.proper then
error( "Can't specify proper noun twice: '" .. inside .. "'" )
end
data.proper = true
else
error( "Unrecognized indicator '" .. part .. "': '" .. inside .. "'" )
end
end
else
error( "Blank indicator: '" .. inside .. "'" )
end
return data
end
local function set_defaults_and_check_bad_indicators( data )
-- Set default values.
if not data.adj then
if data.proper then
data.number = data.number or "sg"
else
data.number = data.number or "both"
end
end
end
local function check_indicators_match_lemma( data )
-- Check for indicators that don't make sense given the context.
if data.decl == "n" and match( data.lemma, "н$" ) then
error( "Hidden-n declension cannot be specified with a lemma ending in н" )
end
if data.decl == "g" and not match( data.lemma, "н$" ) then
error( "Hidden-g declension can only be specified with a lemma ending in н" )
end
end
local function detect_indicator_spec( data )
if propernoun( data.lemma ) then data.proper = true end
set_defaults_and_check_bad_indicators( data )
check_indicators_match_lemma( data )
end
local function detect_all_indicator_specs( alternant_multiword_spec )
local is_multiword = #alternant_multiword_spec.alternant_or_word_specs > 1
iut.map_word_specs( alternant_multiword_spec, function( data )
detect_indicator_spec( data )
data.multiword = is_multiword
end )
end
local propagate_multiword_properties
local function propagate_alternant_properties( alternant_spec, property, mixed_value, nouns_only )
local seen_property
for _, multiword_spec in ipairs( alternant_spec.alternants ) do
propagate_multiword_properties( multiword_spec, property, mixed_value, nouns_only )
if seen_property == nil then
seen_property = multiword_spec
elseif multiword_spec and seen_property ~= multiword_spec then
seen_property = mixed_value
end
end
alternant_spec = seen_property
end
propagate_multiword_properties = function( multiword_spec, property, mixed_value, nouns_only )
local seen_property = nil
local last_seen_nounal_pos = 0
local word_specs = multiword_spec.alternant_or_word_specs or multiword_spec.word_specs
for i = 1, #word_specs do
local is_nounal
if word_specs.alternants then
propagate_alternant_properties( word_specs, property, mixed_value )
is_nounal = not not word_specs
elseif nouns_only then
is_nounal = not word_specs.adj
else
is_nounal = not not word_specs
end
if is_nounal then
if not word_specs then
error( "Internal error: noun-type word spec without " .. property .. " set" )
end
for j = last_seen_nounal_pos + 1, i - 1 do
word_specs = word_specs or word_specs
end
last_seen_nounal_pos = i
if seen_property == nil then
seen_property = word_specs
elseif seen_property ~= word_specs then
seen_property = mixed_value
end
end
end
if last_seen_nounal_pos > 0 then
for i = last_seen_nounal_pos + 1, #word_specs do
word_specs = word_specs or word_specs
end
end
multiword_spec = seen_property
end
local function propagate_properties_downward( alternant_multiword_spec, property, default_propval )
local propval1 = alternant_multiword_spec or default_propval
for _, alternant_or_word_spec in ipairs( alternant_multiword_spec.alternant_or_word_specs ) do
local propval2 = alternant_or_word_spec or propval1
if alternant_or_word_spec.alternants then
for _, multiword_spec in ipairs( alternant_or_word_spec.alternants ) do
local propval3 = multiword_spec or propval2
for _, word_spec in ipairs( multiword_spec.word_specs ) do
local propval4 = word_spec or propval3
if propval4 == "mixed" then
error( "Attempt to assign mixed " .. property .. " to word" )
end
word_spec = propval4
end
end
else
if propval2 == "mixed" then
error( "Attempt to assign mixed " .. property .. " to word" )
end
alternant_or_word_spec = propval2
end
end
end
local function propagate_properties( alternant_multiword_spec, property, default_propval, mixed_value )
propagate_multiword_properties( alternant_multiword_spec, property, mixed_value, "nouns only" )
propagate_multiword_properties( alternant_multiword_spec, property, mixed_value, false )
propagate_properties_downward( alternant_multiword_spec, property, default_propval )
end
local function normalize_all_lemmas( alternant_multiword_spec )
iut.map_word_specs( alternant_multiword_spec, function( data )
data.orig_lemma = data.lemma
data.orig_lemma_no_links = m_links.remove_links( data.lemma )
data.lemma = data.orig_lemma_no_links
end )
end
local function compute_categories_and_annotation( alternant_multiword_spec )
local cats = {}
local function insert( cattype )
m_table.insertIfNot( cats, "Mongolian " .. cattype )
end
if alternant_multiword_spec.pos == "noun" then
if alternant_multiword_spec.number == "sg" then
insert( "uncountable nouns" )
elseif alternant_multiword_spec.number == "pl" then
insert( "pluralia tantum" )
end
end
local annotation
if alternant_multiword_spec.manual then
alternant_multiword_spec.annotation =
alternant_multiword_spec.number == "sg" and "sg-only" or
alternant_multiword_spec.number == "pl" and "pl-only" or
alternant_multiword_spec.number == "spos" and "sg poss" or
alternant_multiword_spec.number == "cpos" and "col poss" or
""
else
local annparts = {}
local bor = nil
local decl = {}
local irregs = {}
local stems = {}
local reducible = nil
local vh = {}
local function do_word_spec( data )
m_table.insertIfNot( vh, vowelharmony( data.lemma, data ).Cyrl.a )
insert( vowelharmony( data.lemma, data ).Cyrl.a .. "-harmonic nouns" )
if data.decl == "r" then
m_table.insertIfNot( decl, "regular" )
insert( "regular declension nouns" )
elseif data.decl == "n" then
m_table.insertIfNot( decl, "hidden-n" )
insert( "hidden-n declension nouns" )
elseif data.decl == "g" then
m_table.insertIfNot( decl, "hidden-g" )
insert( "hidden-g declension nouns" )
end
if data.bor then bor = true end
if voweldeletion( data.lemma, data ) ~= data.lemma then reducible = true end
end
local key_entry = alternant_multiword_spec.first_noun or 1
if #alternant_multiword_spec.alternant_or_word_specs >= key_entry then
local alternant_or_word_spec = alternant_multiword_spec.alternant_or_word_specs
if alternant_or_word_spec.alternants then
for _, multiword_spec in ipairs( alternant_or_word_spec.alternants ) do
key_entry = multiword_spec.first_noun or 1
if #multiword_spec.word_specs >= key_entry then
do_word_spec( multiword_spec.word_specs )
end
end
else
do_word_spec( alternant_or_word_spec )
end
end
if alternant_multiword_spec.pos == "proper noun" then
table.insert( annparts, "proper" )
elseif alternant_multiword_spec.number == "sg" then
table.insert( annparts, "sg-only" )
elseif alternant_multiword_spec.number == "pl" then
table.insert( annparts, "pl-only" )
elseif alternant_multiword_spec.number == "spos" then
table.insert( annparts, "sg poss" )
elseif alternant_multiword_spec.number == "cpos" then
table.insert( annparts, "col poss" )
end
if #vh > 0 then
table.insert( annparts, table.concat( vh, "/" ) .. "-harmonic" )
end
if #decl > 0 then
table.insert( annparts, table.concat( decl, "/" ) )
end
if bor then
table.insert( annparts, "borr" )
end
if reducible then
table.insert( annparts, "reduc" )
end
if #irregs > 0 then
table.insert( annparts, table.concat( irregs, " // " ) )
end
alternant_multiword_spec.annotation = table.concat( annparts, " " )
if #stems > 1 then
insert( "nouns with multiple stems" )
end
end
alternant_multiword_spec.categories = cats
end
local function combine_stem_ending( stem, ending )
return stem .. ending
end
local function show_forms( alternant_multiword_spec )
local lemmas = {}
if alternant_multiword_spec.forms.nom_sg then
for _, nom_sg in ipairs( alternant_multiword_spec.forms.nom_sg ) do
table.insert( lemmas, nom_sg.form )
end
elseif alternant_multiword_spec.forms.nom_pl then
for _, nom_pl in ipairs( alternant_multiword_spec.forms.nom_pl ) do
table.insert( lemmas, nom_pl.form )
end
end
local props = {
lemmas = lemmas,
slot_table = output_verb_slots_with_linked,
lang = lang,
canonicalize = function( form ) return form end,
include_translit = true,
footnotes = alternant_multiword_spec.footnotes,
allow_footnote_symbols = not not alternant_multiword_spec.footnotes,
}
iut.show_forms( alternant_multiword_spec.forms, props )
end
local function make_table( alternant_multiword_spec )
local forms = alternant_multiword_spec.forms
local function header( min_width )
min_width = min_width or "70"
return gsub( [===[
<div class="NavFrame" style="display:inline-block;min-width:MINWIDTHem">
<div class="NavHead" style="background:#eff7ff">{title}{annotation} </div>
<div class="NavContent">
{\op}| style="background:#f9f9f9;text-align:center;min-width:MINWIDTHem;width:100%" class="inflection-table"
|-
]===], "MINWIDTH", min_width )
end
local function reflexive( min_width, color )
min_width = min_width or "70"
color = color or "d9ebff"
return gsub( gsub( [===[|-
|{\cl}
<div class="NavFrame" min-width:MINWIDTHem">
<div class="NavHead" style="background:#COLOR">Reflexive possessive forms </div>
<div class="NavContent">
{\op}| style="background:#f9f9f9;text-align:center;min-width:MINWIDTHem;width:100%" class="inflection-table"
|-
]===], "MINWIDTH", min_width ), "COLOR", color )
end
local function add_case( case, name, sg, pl, refl )
if forms ~= "—" or forms ~= "—" then
local output = gsub( [===[|-
! style="background:#eff7ff" | NAME
]===], "NAME", name )
if sg then
if refl then
output = output .. gsub( [===[
| {CASE_sg_refl}
]===], "CASE", case )
else
output = output .. gsub( [===[
| {CASE_sg}
]===], "CASE", case )
end
end
if pl then
if refl then
output = output .. gsub( [===[
| {CASE_pl_refl}
]===], "CASE", case )
else
output = output .. gsub( [===[
| {CASE_pl}
]===], "CASE", case )
end
end
return output
else
return ""
end
end
local function template_footer()
return [===[|-
|{\cl}{notes_clause}</div></div>]===]
end
local table_spec_both = header( "45" ) .. [===[
! style="background:#d9ebff" | attributive
| colspan=2 | {attr}
|-
! style="background:#d9ebff;width:10em" |
! style="background:#d9ebff;width:17.5em" | singular / indefinite
! style="background:#d9ebff;width:17.5em" | definite plural
|-
! style="background:#eff7ff" | nominative
| {nom_sg}
| {nom_pl}
|-
! style="background:#eff7ff" | genitive
| {gen_sg}
| {gen_pl}
|-
! style="background:#eff7ff" | accusative
| {acc_sg}
| {acc_pl}
|-
! style="background:#eff7ff" | dative-locative
| {dat_loc_sg}
| {dat_loc_pl}
]===] .. add_case( "gen_dat", "genitive-dative", true, true ) .. [===[
|-
! style="background:#eff7ff" | ablative
| {abl_sg}
| {abl_pl}
]===] .. add_case( "dat_abl", "dative-ablative", true, true ) .. [===[
|-
! style="background:#eff7ff" | instrumental
| {ins_sg}
| {ins_pl}
|-
! style="background:#eff7ff" | comitative
| {com_sg}
| {com_pl}
|-
! style="background:#eff7ff" | privative
| {priv_sg}
| {priv_pl}
|-
! style="background:#eff7ff" | directive
| {dirc_sg}
| {dirc_pl}
]===] .. reflexive( "45" ) .. [===[
! style="background:#d9ebff;width:10em" |
! style="background:#d9ebff;width:17.5em" | singular / indefinite
! style="background:#d9ebff;width:17.5em" | definite plural
|-
! style="background:#eff7ff" | nominative
| {nom_sg_refl}
| {nom_pl_refl}
|-
! style="background:#eff7ff" | genitive
| {gen_sg_refl}
| {gen_pl_refl}
|-
! style="background:#eff7ff" | accusative
| {acc_sg_refl}
| {acc_pl_refl}
|-
! style="background:#eff7ff" | dative-locative
| {dat_loc_sg_refl}
| {dat_loc_pl_refl}
]===] .. add_case( "gen_dat", "genitive-dative", true, true, true ) .. [===[
|-
! style="background:#eff7ff" | ablative
| {abl_sg_refl}
| {abl_pl_refl}
]===] .. add_case( "dat_abl", "dative-ablative", true, true, true ) .. [===[
|-
! style="background:#eff7ff" | instrumental
| {ins_sg_refl}
| {ins_pl_refl}
|-
! style="background:#eff7ff" | comitative
| {com_sg_refl}
| {com_pl_refl}
|-
! style="background:#eff7ff" | privative
| {priv_sg_refl}
| {priv_pl_refl}
|-
! style="background:#eff7ff" | directive
| {dirc_sg_refl}
| {dirc_pl_refl}
|{\cl}</div></div>
{\op}| style="background:#f9f9f9;text-align:center;min-width:45em;width:100%" class="inflection-table"
|-
! style="background:#d9ebff;width:10em" | independent<br>genitive
! style="background:#d9ebff;width:17.5em" | singular / indefinite
! style="background:#d9ebff;width:17.5em" | definite plural
|-
! style="background:#eff7ff" | singular<br>possession
| {spos_indgen_sg}
| {spos_indgen_pl}
|-
! style="background:#eff7ff" | collective<br>possession
| {cpos_indgen_sg}
| {cpos_indgen_pl}
]===] .. template_footer()
local function table_spec_one( num, number )
return gsub( gsub( header( "30" ) .. [===[
! style="background:#d9ebff" | attributive
| {attr}
|-
! style="background:#d9ebff;width:10em" |
! style="background:#d9ebff;width:20em" | NUMBER
|-
! style="background:#eff7ff" | nominative
| {nom_NUM}
|-
! style="background:#eff7ff" | genitive
| {gen_NUM}
|-
! style="background:#eff7ff" | accusative
| {acc_NUM}
|-
! style="background:#eff7ff" | dative-locative
| {dat_loc_NUM}
]===] .. add_case( "gen_dat", "genitive-dative", true ) .. [===[
|-
! style="background:#eff7ff" | ablative
| {abl_NUM}
]===] .. add_case( "dat_abl", "dative-ablative", true ) .. [===[
|-
! style="background:#eff7ff" | instrumental
| {ins_NUM}
|-
! style="background:#eff7ff" | comitative
| {com_NUM}
|-
! style="background:#eff7ff" | privative
| {priv_NUM}
|-
! style="background:#eff7ff" | directive
| {dirc_NUM}
]===] .. reflexive( "30" ) .. [===[
! style="background:#d9ebff;width:10em" |
! style="background:#d9ebff;width:20em" | NUMBER
|-
! style="background:#eff7ff" | nominative
| {nom_NUM_refl}
|-
! style="background:#eff7ff" | genitive
| {gen_NUM_refl}
|-
! style="background:#eff7ff" | accusative
| {acc_NUM_refl}
|-
! style="background:#eff7ff" | dative-locative
| {dat_loc_NUM_refl}
]===] .. add_case( "gen_dat", "genitive-dative", true, nil, true ) .. [===[
|-
! style="background:#eff7ff" | ablative
| {abl_NUM_refl}
]===] .. add_case( "dat_abl", "dative-ablative", true, nil, true ) .. [===[
|-
! style="background:#eff7ff" | instrumental
| {ins_NUM_refl}
|-
! style="background:#eff7ff" | comitative
| {com_NUM_refl}
|-
! style="background:#eff7ff" | privative
| {priv_NUM_refl}
|-
! style="background:#eff7ff" | directive
| {dirc_NUM_refl}
|{\cl}</div></div>
{\op}| style="background:#f9f9f9;text-align:center;min-width:30em;width:100%" class="inflection-table"
|-
! style="background:#d9ebff;width:10em" | independent<br>genitive
! style="background:#d9ebff;width:20em" | NUMBER
|-
! style="background:#eff7ff" | singular<br>possession
| {spos_indgen_NUM}
|-
! style="background:#eff7ff" | collective<br>possession
| {cpos_indgen_NUM}
]===] .. template_footer(), "NUMBER", number ), "NUM", num )
end
local function table_spec_poss()
return header( "30" ) .. [===[
! style="background:#eff7ff;width:10em" | nominative
| style="width:20em" | {nom}
|-
! style="background:#eff7ff" | genitive
| {gen}
|-
! style="background:#eff7ff" | accusative
| {acc}
|-
! style="background:#eff7ff" | dative-locative
| {dat_loc}
|-
! style="background:#eff7ff" | ablative
| {abl}
|-
! style="background:#eff7ff" | instrumental
| {ins}
|-
! style="background:#eff7ff" | comitative
| {com}
|-
! style="background:#eff7ff" | privative
| {priv}
|-
! style="background:#eff7ff" | directive
| {dirc}
]===] .. reflexive( "30" ) .. [===[
! style="background:#eff7ff;width:10em" | nominative
| style="width:20em" | {nom_refl}
|-
! style="background:#eff7ff" | genitive
| {gen_refl}
|-
! style="background:#eff7ff" | accusative
| {acc_refl}
|-
! style="background:#eff7ff" | dative-locative
| {dat_loc_refl}
|-
! style="background:#eff7ff" | ablative
| {abl_refl}
|-
! style="background:#eff7ff" | instrumental
| {ins_refl}
|-
! style="background:#eff7ff" | comitative
| {com_refl}
|-
! style="background:#eff7ff" | privative
| {priv_refl}
|-
! style="background:#eff7ff" | directive
| {dirc_refl}
]===] .. template_footer()
end
local notes_template = [===[
<div style="width:100%;text-align:left;background:#d9ebff">
<div style="display:inline-block;text-align:left;padding-left:1em;padding-right:1em">
{footnote}
</div></div>
]===]
if alternant_multiword_spec.title then
forms.title = alternant_multiword_spec.title
else
forms.title = "Declension of <i lang=\"mn\" class=\"Cyrl\">" .. forms.lemma .. "</i>"
end
local annotation = alternant_multiword_spec.annotation or ""
if annotation == "" then
forms.annotation = ""
else
forms.annotation = " (<span style=\"font-weight:normal;font-size:small\">" .. annotation .. "</span>)"
end
local table_spec =
alternant_multiword_spec.number == "sg" and table_spec_one( "sg", "singular / indefinite" ) or
alternant_multiword_spec.number == "pl" and table_spec_one( "pl", "definite plural" ) or
alternant_multiword_spec.number == "spos" and table_spec_poss() or
alternant_multiword_spec.number == "cpos" and table_spec_poss() or
table_spec_both
forms.notes_clause = forms.footnote ~= "" and
m_string_utilities.format( notes_template, forms ) or ""
return m_string_utilities.format( table_spec, forms )
end
function export.do_generate_forms( parent_args, pos, from_headword, def )
local params = {
= { required = true, default = "хаан<r>" },
footnote = { list = true },
title = {},
pos = { default = "noun" }
}
local args = m_para.process( parent_args, params )
if not match( args, "<.*>" ) then error( "Please specify declension" ) end
local parse_props = {
parse_indicator_spec = parse_indicator_spec
}
local alternant_multiword_spec = iut.parse_inflected_text( args, parse_props )
alternant_multiword_spec.title = args.title
alternant_multiword_spec.pos = pos or args.pos
alternant_multiword_spec.footnotes = args.footnote
alternant_multiword_spec.args = args
normalize_all_lemmas( alternant_multiword_spec )
detect_all_indicator_specs( alternant_multiword_spec )
propagate_properties( alternant_multiword_spec, "number", "both", "both" )
local inflect_props = {
skip_slot = function( slot )
return skip_slot( alternant_multiword_spec.number, slot )
end,
slot_table = output_verb_slots_with_linked,
get_variants = get_variants,
inflect_word_spec = handle_derived_slots_and_overrides,
lang = lang
}
iut.inflect_multiword_or_alternant_multiword_spec( alternant_multiword_spec, inflect_props )
compute_categories_and_annotation( alternant_multiword_spec )
return alternant_multiword_spec
end
function export.show( frame )
local parent_args = frame:getParent().args or frame.args
local pos = propernoun( parent_args or "хаан" ) and "proper noun" or "noun"
local alternant_multiword_spec = export.do_generate_forms( parent_args, pos )
show_forms( alternant_multiword_spec )
return make_table( alternant_multiword_spec ) .. require( "Module:utilities" ).format_categories( alternant_multiword_spec.categories, lang )
end
return export