Module:odt-decl-noun
Appearance
- This module lacks a documentation subpage. Please create it.
- Useful links: subpage list • links • transclusions • testcases • sandbox
local export = {}
local m_links = require("Module:links")
local m_utils = require("Module:utilities")
local lang = require("Module:languages").getByCode("odt")
local decl_data = {}
local function devoice(stem)
stem = mw.ustring.gsub(stem, "ng$", "nc")
stem = mw.ustring.gsub(stem, "d$", "t")
stem = mw.ustring.gsub(stem, "b$", "p")
stem = mw.ustring.gsub(stem, "v$", "f")
stem = mw.ustring.gsub(stem, "z$", "s")
return stem
end
local function umlaut(stem)
subStr = string.sub(stem, -4, -1)
if string.find(subStr, "ie") then
stem = stem.gsub(stem, "ie", "iu")
end
if string.find(subStr, "e") and not string.find(subStr, "ei") then
stem = stem.gsub(stem, "e", "i")
end
if string.find(subStr, "a") then
stem = stem.gsub(stem, "a", "e")
end
if string.find(subStr, "o") and not string.find(stem, "ou") then
stem = stem.gsub(stem, "o", "u")
end
stem = mw.ustring.gsub(stem, "ce", "ke")
stem = mw.ustring.gsub(stem, "ci", "ki")
return stem
end
local function C_to_K(stem)
stem = mw.ustring.gsub(stem, "cc$", "ck")
stem = mw.ustring.gsub(stem, "c$", "k")
stem = mw.ustring.gsub(stem, "z$", "c")
return stem
end
local function K_to_C(stem)
stem = mw.ustring.gsub(stem, "ck$", "cc")
stem = mw.ustring.gsub(stem, "k$", "c")
return stem
end
local function degeminate(stem)
stem = mw.ustring.gsub(stem, "([bcdfghjklmnprstvwzþ])%1$", "%1")
stem = mw.ustring.gsub(stem, "ck$", "k")
return stem
end
local function categorize(gender)
if gender == 'm' then
cat_gender='masculine'
elseif gender == 'f' then
cat_gender='feminine'
elseif gender == 'n' then
cat_gender='neuter'
else
cat_gender='masculine'
-- error("Unrecognized gender '" .. gender .. "'. Only masculine ('m'), feminine ('f') or neuter ('n')")
end
return cat_gender
end
decl_data["a"] = {
params = {
[1] = {},
["g"] = {},
["nopl"] = {},
["gender"] = {alias_of = "g"},
},
}
setmetatable(decl_data["a"], {__call = function(self, args, data)
cat_type = "a-stem noun"
cat_gender = categorize(args.g)
data.decl_type = "" ..cat_gender.. " " ..cat_type.. ""
table.insert(data.categories, "Old Dutch " .. cat_gender .. " " .. cat_type .. "s")
stem_C = K_to_C(args[1])
stem_K = C_to_K(args[1])
devoiced_stem = devoice(degeminate(stem_C))
data.forms["nom_sg"] = {devoiced_stem}
data.forms["acc_sg"] = {devoiced_stem}
data.forms["gen_sg"] = {stem_K .. "es"}
data.forms["dat_sg"] = {stem_K .. "e"}
data.forms["nom_pl"] = {stem_C .. "a"}
data.forms["acc_pl"] = {stem_C .. "a"}
data.forms["gen_pl"] = {stem_C .. "o"}
data.forms["dat_pl"] = {stem_C .. "on"}
if args.g == 'n' then
data.forms["nom_pl"] = {devoiced_stem}
data.forms["acc_pl"] = {devoiced_stem}
end
end
})
decl_data["o"] = {
params = {
[1] = {},
["nopl"] = {},
},
}
setmetatable(decl_data["o"], {__call = function(self, args, data)
args.g='f'
cat_type = "ō/ōn-stem noun"
cat_gender = categorize(args.g)
data.decl_type = "" ..cat_gender.. " " ..cat_type.. ""
table.insert(data.categories, "Old Dutch " .. cat_type .. "s")
data.forms["nom_sg"] = {args[1] .. "a"}
data.forms["acc_sg"] = {args[1] .. "a", args[1] .. "on"}
data.forms["gen_sg"] = {args[1] .. "on"}
data.forms["dat_sg"] = {args[1] .. "on"}
data.forms["nom_pl"] = {args[1] .. "a", args[1] .. "on"}
data.forms["acc_pl"] = {args[1] .. "a", args[1] .. "on"}
data.forms["gen_pl"] = {args[1] .. "ono"}
data.forms["dat_pl"] = {args[1] .. "on"}
end
})
decl_data["ja"] = {
params = {
[1] = {},
["g"] = {},
["nopl"] = {},
["gender"] = {alias_of = "g"},
},
}
setmetatable(decl_data["ja"], {__call = function(self, args, data)
cat_type = "ja-stem noun"
cat_gender = categorize(args.g)
data.decl_type = "" ..cat_gender.. " " ..cat_type.. ""
table.insert(data.categories, "Old Dutch " .. cat_gender .. " " .. cat_type .. "s")
stem_C = K_to_C(args[1])
stem_K = C_to_K(args[1])
data.forms["nom_sg"] = {stem_K .. "i"}
data.forms["acc_sg"] = {stem_K .. "i"}
data.forms["gen_sg"] = {stem_K .. "is"}
data.forms["dat_sg"] = {stem_K .. "i"}
data.forms["nom_pl"] = {stem_C .. "a"}
data.forms["acc_pl"] = {stem_C .. "a"}
data.forms["gen_pl"] = {stem_C .. "o"}
data.forms["dat_pl"] = {stem_C .. "on"}
if args.g == 'n' then
data.forms["nom_pl"] = {stem_K .. "i"}
data.forms["acc_pl"] = {stem_K .. "i"}
end
end
})
decl_data["wa"] = {
params = {
[1] = {},
["g"] = {},
["nopl"] = {},
["gender"] = {alias_of = "g"},
},
}
setmetatable(decl_data["wa"], {__call = function(self, args, data)
cat_type = "wa-stem noun"
cat_gender = categorize(args.g)
data.decl_type = "" ..cat_gender.. " " ..cat_type.. ""
table.insert(data.categories, "Old Dutch " .. cat_gender .. " " .. cat_type .. "s")
data.forms["nom_sg"] = {args[1] .. "o"}
data.forms["acc_sg"] = {args[1] .. "o"}
data.forms["gen_sg"] = {args[1] .. "wes"}
data.forms["dat_sg"] = {args[1] .. "we"}
data.forms["nom_pl"] = {args[1] .. "wa"}
data.forms["acc_pl"] = {args[1] .. "wa"}
data.forms["gen_pl"] = {args[1] .. "wo"}
data.forms["dat_pl"] = {args[1] .. "won"}
if args.g == 'n' then
data.forms["nom_pl"] = {args[1] .. "o"}
data.forms["acc_pl"] = {args[1] .. "o"}
end
end
})
decl_data["wo"] = {
params = {
[1] = {},
["nopl"] = {},
},
}
setmetatable(decl_data["wo"], {__call = function(self, args, data)
args.g='f'
cat_type = "wō-stem noun"
cat_gender = categorize(args.g)
data.decl_type = "" ..cat_gender.. " " ..cat_type.. ""
table.insert(data.categories, "Old Dutch " .. cat_type .. "s")
data.forms["nom_sg"] = {args[1] .. "wa"}
data.forms["acc_sg"] = {args[1] .. "wa", args[1] .. "won"}
data.forms["gen_sg"] = {args[1] .. "won"}
data.forms["dat_sg"] = {args[1] .. "won"}
data.forms["nom_pl"] = {args[1] .. "wa", args[1] .. "won"}
data.forms["acc_pl"] = {args[1] .. "wa", args[1] .. "won"}
data.forms["gen_pl"] = {args[1] .. "wono"}
data.forms["dat_pl"] = {args[1] .. "won"}
end
})
decl_data["i"] = {
params = {
[1] = {},
["g"] = {},
["nopl"] = {},
["nomut"] = {},
["w"] = {},
["gender"] = {alias_of = "g"},
["weight"] = {alias_of = "w"},
},
}
setmetatable(decl_data["i"], {__call = function(self, args, data)
cat_type = "i-stem noun"
cat_gender = categorize(args.g)
data.decl_type = "" ..cat_gender.. " " ..cat_type.. ""
table.insert(data.categories, "Old Dutch " .. cat_gender .. " " .. cat_type .. "s")
stem_C = K_to_C(args[1])
stem_K = C_to_K(args[1])
umlauted_stem_C = umlaut(stem_C)
umlauted_stem_K = umlaut(stem_K)
devoiced_stem = degeminate(devoice(stem_C))
if args.w == 'l' or args.nomut == '1' then
umlauted_stem_C = stem_C
umlauted_stem_K = stem_K
end
data.forms["nom_sg"] = {devoiced_stem}
data.forms["acc_sg"] = {devoiced_stem}
data.forms["gen_sg"] = {umlauted_stem_K .. "is"}
data.forms["dat_sg"] = {umlauted_stem_K .. "i"}
data.forms["nom_pl"] = {umlauted_stem_K .. "i"}
data.forms["acc_pl"] = {umlauted_stem_K .. "i"}
data.forms["gen_pl"] = {umlauted_stem_C .. "o"}
data.forms["dat_pl"] = {umlauted_stem_K .. "in", umlauted_stem_C .. "on"}
if args.w == 'l' then
data.forms["nom_sg"] = {umlauted_stem_K .. "i"}
data.forms["acc_sg"] = {umlauted_stem_K .. "i"}
end
if args.g == 'f' then
data.forms["gen_sg"] = {umlauted_stem_K .. "i"}
end
end
})
decl_data["u"] = {
params = {
[1] = {},
["g"] = {},
["nopl"] = {},
["nomut"] = {},
["w"] = {},
["gender"] = {alias_of = "g"},
["weight"] = {alias_of = "w"},
},
}
setmetatable(decl_data["u"], {__call = function(self, args, data)
cat_type = "u-stem noun"
cat_gender = categorize(args.g)
data.decl_type = "" ..cat_gender.. " " ..cat_type.. ""
table.insert(data.categories, "Old Dutch " .. cat_gender .. " " .. cat_type .. "s")
stem_C = K_to_C(args[1])
stem_K = C_to_K(args[1])
umlauted_stem_C = umlaut(stem_C)
umlauted_stem_K = umlaut(stem_K)
devoiced_stem = degeminate(devoice(stem_C))
if args.w == 'l' or args.nomut == '1' then
umlauted_stem_C = stem_C
umlauted_stem_K = stem_K
end
data.forms["nom_sg"] = {devoiced_stem}
data.forms["acc_sg"] = {devoiced_stem}
data.forms["gen_sg"] = {umlauted_stem_K .. "is"}
data.forms["dat_sg"] = {umlauted_stem_K .. "i"}
data.forms["nom_pl"] = {umlauted_stem_K .. "i"}
data.forms["acc_pl"] = {umlauted_stem_K .. "i"}
data.forms["gen_pl"] = {stem_C .. "o"}
data.forms["dat_pl"] = {stem_C .. "on"}
if args.w == 'l' then
data.forms["nom_sg"] = {stem_C .. "o"}
data.forms["acc_sg"] = {stem_C .. "o"}
end
if args.g == 'f' then
data.forms["gen_sg"] = {umlauted_stem_K .. "i"}
end
end
})
decl_data["an"] = {
params = {
[1] = {},
["g"] = {},
["nopl"] = {},
["gender"] = {alias_of = "g"},
},
}
setmetatable(decl_data["an"], {__call = function(self, args, data)
cat_type = "an-stem noun"
cat_gender = categorize(args.g)
data.decl_type = "" ..cat_gender.. " " ..cat_type.. ""
table.insert(data.categories, "Old Dutch " .. cat_gender .. " " .. cat_type .. "s")
stem_C = K_to_C(args[1])
stem_K = C_to_K(args[1])
data.forms["nom_sg"] = {stem_C .. "o"}
data.forms["acc_sg"] = {stem_C .. "on"}
data.forms["gen_sg"] = {stem_K .. "in"}
data.forms["dat_sg"] = {stem_K .. "in"}
data.forms["nom_pl"] = {stem_C .. "on"}
data.forms["acc_pl"] = {stem_C .. "on"}
data.forms["gen_pl"] = {stem_C .. "ono"}
data.forms["dat_pl"] = {stem_C .. "on"}
if args.g == 'n' then
data.forms["nom_sg"] = {stem_C .. "a"}
data.forms["acc_sg"] = {stem_C .. "a"}
data.forms["nom_pl"] = {stem_C .. "on", stem_C .. "a"}
data.forms["acc_pl"] = {stem_C .. "on", stem_C .. "a"}
end
end
})
decl_data["in"] = {
params = {
[1] = {},
},
}
setmetatable(decl_data["in"], {__call = function(self, args, data)
args.g='f'
args.nopl='1'
cat_type = "īn-stem noun"
cat_gender = categorize(args.g)
data.decl_type = "" ..cat_gender.. " " ..cat_type.. ""
table.insert(data.categories, "Old Dutch " .. cat_type .. "s")
data.forms["nom_sg"] = {args[1] .. "i"}
data.forms["acc_sg"] = {args[1] .. "i"}
data.forms["gen_sg"] = {args[1] .. "i"}
data.forms["dat_sg"] = {args[1] .. "i"}
end
})
decl_data["cons"] = {
params = {
[1] = {},
["nopl"] = {},
},
}
setmetatable(decl_data["cons"], {__call = function(self, args, data)
data.decl_type = "consonant stem"
stem_C = K_to_C(args[1])
stem_K = C_to_K(args[1])
devoiced_stem = devoice(degeminate(stem_C))
data.forms["nom_sg"] = {devoiced_stem}
data.forms["acc_sg"] = {devoiced_stem}
data.forms["gen_sg"] = {stem_K .. "es"}
data.forms["dat_sg"] = {stem_K .. "e"}
data.forms["nom_pl"] = {devoiced_stem}
data.forms["acc_pl"] = {devoiced_stem}
data.forms["gen_pl"] = {stem_C .. "o"}
data.forms["dat_pl"] = {stem_C .. "on"}
table.insert(data.categories, "Old Dutch consonant stem nouns")
end
})
decl_data["r"] = {
params = {
[1] = {},
},
}
setmetatable(decl_data["r"], {__call = function(self, args, data)
data.decl_type = "r-stem"
data.forms["nom_sg"] = {args[1]}
data.forms["acc_sg"] = {args[1]}
data.forms["gen_sg"] = {args[1]}
data.forms["dat_sg"] = {args[1]}
data.forms["nom_pl"] = {args[1]}
data.forms["acc_pl"] = {args[1]}
data.forms["gen_pl"] = {args[1] .. "o"}
data.forms["dat_pl"] = {args[1] .. "on"}
table.insert(data.categories, "Old Dutch r-stem nouns")
end
})
decl_data["z"] = {
params = {
[1] = {},
},
}
setmetatable(decl_data["z"], {__call = function(self, args, data)
data.decl_type = "z-stem"
stem_C = K_to_C(args[1])
stem_K = C_to_K(args[1])
devoiced_stem = devoice(degeminate(stem_C))
data.forms["nom_sg"] = {devoiced_stem}
data.forms["acc_sg"] = {devoiced_stem}
data.forms["gen_sg"] = {stem_K .. "es"}
data.forms["dat_sg"] = {stem_K .. "e"}
data.forms["nom_pl"] = {stem_K .. "ir"}
data.forms["acc_pl"] = {stem_K .. "ir"}
data.forms["gen_pl"] = {stem_K .. "iro"}
data.forms["dat_pl"] = {stem_K .. "iron"}
table.insert(data.categories, "Old Dutch z-stem nouns")
end
})
decl_data["manual"] = {
params = {
[1] = {},
[2] = {},
[3] = {},
[4] = {},
[5] = {},
[6] = {},
[7] = {},
[8] = {},
["type"] = {},
["nopl"] = {},
},
}
setmetatable(decl_data["manual"], {__call = function(self, args, data)
data.decl_type = "" .. args.type .. ""
data.forms["nom_sg"] = {args[1]}
data.forms["acc_sg"] = {args[2]}
data.forms["gen_sg"] = {args[3]}
data.forms["dat_sg"] = {args[4]}
data.forms["nom_pl"] = {args[5]}
data.forms["acc_pl"] = {args[6]}
data.forms["gen_pl"] = {args[7]}
data.forms["dat_pl"] = {args[8]}
end
})
-- The main entry point for automatic declension.
function export.show(frame)
local parent_args = frame:getParent().args
local decl_type = (frame.args["decl"] or parent_args["decl"]) or "a"
if not decl_data[decl_type] then
error("Unknown declension '" .. decl_type .. "'")
end
local data = {forms = {}, categories = {}}
data.head = parent_args["head"] or nil
local args = require("Module:parameters").process(parent_args, decl_data[decl_type].params, true)
-- Override for templates
if not args[1] then
setmetatable(args, {__index = function(self, key)
return "{{{" .. key .. "}}}"
end
})
end
-- Generate the forms
if parent_args.irr then
table.insert(data.categories, "Old Dutch irregular nouns")
if decl_data.irregular[parent_args.irr] then
decl_data.irregular[parent_args.irr](data)
else
decl_data[decl_type](args, data)
end
else
decl_data[decl_type](args, data)
end
-- Make the table
if args.nopl=='1' then
return make_table_nopl(data)
else
return make_table(data)
end
end
-- The main entry point for manual declension.
function export.show_manual(frame)
local parent_args = frame:getParent().args
local params = {
[1] = {},
[2] = {},
[3] = {},
[4] = {},
[5] = {},
[6] = {},
[7] = {},
[8] = {},
["head"] = {}, -- currently ignored
}
local data = {forms = {}, categories = {}}
local args = require("Module:parameters").process(parent_args, params)
local function split(arg)
return arg and mw.text.split(arg, "%s*,%s*") or nil
end
data.forms.nom_sg = split(args[1])
data.forms.nom_pl = split(args[2])
data.forms.acc_sg = split(args[3])
data.forms.acc_pl = split(args[4])
data.forms.gen_sg = split(args[5])
data.forms.gen_pl = split(args[6])
data.forms.dat_sg = split(args[7])
data.forms.dat_pl = split(args[8])
data.decl_type = "irregular"
-- Make the table
if args.nopl=='1' then
return make_table_nopl(data)
else
return make_table(data)
end
end
function make_table(data)
local function show_form(form)
if not form then
return "—"
end
local ret = {}
for key, subform in ipairs(form) do
if mw.title.getCurrentTitle().nsText == "Reconstruction" and subform ~= "—" then
subform = "*" .. subform
end
table.insert(ret, m_links.full_link({lang = lang, term = subform}))
end
return table.concat(ret, ", ")
end
local function repl(param)
if param == "decl_type" then
return data.decl_type
else
return show_form(data.forms[param])
end
end
local wikicode = [=[
<div class="NavFrame" style="width: 42em">
<div class="NavHead" style="">Declension of {{{nom_sg}}} ({{{decl_type}}})</div>
<div class="NavContent">
{| style="background:#f1f5eb; text-align:center; width:100%" cellpadding="0" cellspacing="1" class="inflection-table"
|-
! style="width: 20%; background:#d5dbd8" colspan="1" | '''case'''
! style="width: 40%; background:#e5eede" colspan="1" | singular
! style="width: 40%; background:#e5eede" colspan="1" | plural
|-
! style="background:#ebf0ed" | nominative
| style="background-color:#fdfffc;" | {{{nom_sg}}}
| style="background-color:#fdfffc;" | {{{nom_pl}}}
|-
! style="background:#ebf0ed" | accusative
| style="background-color:#fdfffc;" | {{{acc_sg}}}
| style="background-color:#fdfffc;" | {{{acc_pl}}}
|-
!style="background:#ebf0ed" | genitive
| style="background-color:#fdfffc;" | {{{gen_sg}}}
| style="background-color:#fdfffc;" | {{{gen_pl}}}
|-
! style="background:#ebf0ed" | dative
| style="background-color:#fdfffc;" | {{{dat_sg}}}
| style="background-color:#fdfffc;" | {{{dat_pl}}}
|}</div></div>]=]
return (mw.ustring.gsub(wikicode, "{{{([a-z0-9_]+)}}}", repl)) .. m_utils.format_categories(data.categories, lang)
end
function make_table_nopl(data)
local function show_form(form)
if not form then
return "—"
end
local ret = {}
for key, subform in ipairs(form) do
if mw.title.getCurrentTitle().nsText == "Reconstruction" and subform ~= "—" then
subform = "*" .. subform
end
table.insert(ret, m_links.full_link({lang = lang, term = subform}))
end
return table.concat(ret, ", ")
end
local function repl(param)
if param == "decl_type" then
return data.decl_type
else
return show_form(data.forms[param])
end
end
local wikicode = [=[
<div class="NavFrame" style="width: 38em">
<div class="NavHead" style="">Declension of {{{nom_sg}}} ({{{decl_type}}} - no plural)</div>
<div class="NavContent">
{| style="background:#f1f5eb; text-align:center; width:100%" cellpadding="0" cellspacing="1" class="inflection-table"
|-
! style="width: 30%; background:#d5dbd8" colspan="1" | '''case'''
! style="width: 70%; background:#e5eede" colspan="1" | singular
|-
! style="background:#ebf0ed" | nominative
| style="background-color:#fdfffc;" | {{{nom_sg}}}
|-
! style="background:#ebf0ed" | accusative
| style="background-color:#fdfffc;" | {{{acc_sg}}}
|-
!style="background:#ebf0ed" | genitive
| style="background-color:#fdfffc;" | {{{gen_sg}}}
|-
! style="background:#ebf0ed" | dative
| style="background-color:#fdfffc;" | {{{dat_sg}}}
|}</div></div>]=]
return (mw.ustring.gsub(wikicode, "{{{([a-z0-9_]+)}}}", repl)) .. m_utils.format_categories(data.categories, lang)
end
return export