Module:sla-noun

local m_utilities = require("Module:utilities") local com = require("Module:sla-common")

local export = {}

local lang = require("Module:languages").getByCode("sla-pro")

local rfind = mw.ustring.find local rsubn = mw.ustring.gsub local rmatch = mw.ustring.match local rsplit = mw.text.split local ulower = mw.ustring.lower local uupper = mw.ustring.upper local usub = mw.ustring.sub local ulen = mw.ustring.len local ugmatch = mw.ustring.gmatch

function export.show(frame) local SUBPAGENAME = mw.title.getCurrentTitle.subpageText local params = { [1] = {alias_of = 'recons'}, recons = {default = SUBPAGENAME}, n = {default = "sdp"}, ap = {}, g = {}, stem = {}, }	local args = require("Module:parameters").process(frame:getParent.args, params) local gender = args["g"] local ap = args["ap"] local nom_sg = com.canon_decompose(args["recons"]) local unom_sg = (lang:makeEntryName(nom_sg)) local stem, desinence = com.auto_accent_and_check_accents(nom_sg, ap) local ustem, _ = com.split_stem_desinence(unom_sg) local num = {} if not args.n or not rfind(args.n, "^s?d?p?$") then error("Illegal number “" .. args.n .. "”. Possible values are “s”, “d”, “p”, “sd”, “dp”, “sp”, or “sdp”.") else num = rsplit(args.n, "") end

if (nom_sg == "" or desinence == "") then error("Error: SUBPAGENAME=" .. SUBPAGENAME .. "Must only be used in the Reconstruction namespace with " .. lang:getCanonicalName .. " reconstructions") end local stem_type = get_stem(args["stem"], desinence, gender, unom_sg) if stem_type == "soft a-stem" and desinence=="i" then -- ī-stem +j/+ьj (Module:sla-noun/data declensions["soft a-stem"] doesn't let check data.args["stem"], for some reason #data.args==0) stem = ( args["stem"] and args["stem"]=="ī/ьj" and ustem.."ьj" or com.iotate(ustem) ) end if ap and ap ~= "a" and ap ~= "b" and ap ~= "c" then error("Accent paradigm “" .. ap .. "” must be either “a”, “b”, or “c”") end local forms, title, extracats local categories = {} local data = { args = args, gender = gender, desinence = desinence, ap = ap, nom_sg = nom_sg, unom_sg = unom_sg,	-- only used for *mati/*dъťi? stem = stem, ustem = ustem, footnotes = {}, footnote_to_sym = {}, next_notesym = "*" }	local declensions = require("Module:sla-noun/data") if declensions[stem_type] then forms, title, extracats = declensions[stem_type](data) else error("Internal error -- unrecognized internal stem type '" .. stem_type .. "'") end

if extracats then for _, cat in ipairs(extracats) do table.insert(categories, lang:getCanonicalName .. " " .. cat) end end table.insert(categories, 1, lang:getCanonicalName .. " " .. title .. " nouns") if ap then title = title .. ", accent paradigm " .. ap table.insert(categories, lang:getCanonicalName .. " nominals with accent paradigm " .. ap) end if #num == 1 then if num[1] == 's' then title = title .. ', uncountable' table.insert(categories, lang:getCanonicalName .. " singularia tantum") elseif num[1] == 'p' then title = title .. ', plural only' table.insert(categories, lang:getCanonicalName .. " pluralia tantum") end end return make_table(forms, num, title, data.footnotes) .. m_utilities.format_categories(categories, lang) end

function get_stem(st, desinence, gender, unom_sg) if st then -- explicitly specified stem if st == "o" then if "ъ" == desinence then return "hard masculine o-stem" elseif "ь" == desinence then return "soft masculine o-stem" elseif "o" == desinence then return "hard neuter o-stem" elseif "e" == desinence then return "soft neuter o-stem" else error("Unrecognized ending for o-stem") end elseif st == "a" then if "a" ~= desinence then error("Unrecognized ending for a-stem") end if rfind(unom_sg, "[cčďjľňřšťž]a$") or rfind(unom_sg, "dza$") then return "soft a-stem" else return "hard a-stem" end elseif st == "i" then if "ь" ~= desinence then error("Unrecognized ending for i-stem") end if gender == "m" then return "masculine i-stem" elseif gender == "f" then return "feminine i-stem" else error("Gender for i-stems must be specified through g= parameter, as \"m\" or \"f\"") end elseif st == "ī" or st=="ī/ьj" or st=="ī/j" then if "i" ~= desinence then error("Unrecognized ending for ī-stem") end return "soft a-stem" -- FIXME, remove this hack --consonant stems have several names in the literature, we handle all so that editors don't have to remember which one Wiktionary prefers elseif st == "n" then return "n-stem" elseif st == "nt" or st == "t" then return "nt-stem" elseif st == "r" then return "r-stem" elseif st == "s" then return "s-stem" elseif st == "u" then return "u-stem" elseif st == "v" or st == "ū" or st == "ъv" then return "v-stem" else error("Unrecognized stem class " .. st) end -- Autodetect common stem types on the basis of desinence, preceding -- consonant, and passed arguments (g=). -- hard masculine o-stems always and in -ъ, and we skip u-stems (which have stem= parameter provided) elseif "ъ" == desinence then return "hard masculine o-stem" -- soft masculine o-stems end in ь and are preceded by a soft, palatal consonant, except for such i-stems which will -- always have g= parameter specified elseif "ь" == desinence and not gender and (rfind(unom_sg, "[cčďjľňřšťž]ь$") or rfind(unom_sg, "dzь$")) then return "soft masculine o-stem" -- hard neuter o-stems always end in -o, and we skip s-stems in -o (which have stem= parameter provided) elseif "o" == desinence then return "hard neuter o-stem" -- soft neuter o-stems always end in -e and are preceded by a soft, platal consonant, and we skip s-stems in -e -- (which have stem= parameter provided) elseif "e" == desinence and rfind(unom_sg, "[cčďjľňřšťž]e$") then return "soft neuter o-stem" -- soft a-stems are feminines and masculines (OCS junoša) that and in -a and are preceded by a soft, palatal consonant, or	-- in -i (except for words *mati and *dъťi which are handled as r-stems) elseif ( "a" == desinence and ( rfind(unom_sg, "[cčďjľňřšťž]a$") or rfind(unom_sg, "dza$") )  ) or ( ("i" == desinence) and (unom_sg ~= "mati") and (unom_sg ~= "dъťi") ) then return "soft a-stem" -- hard a-stems are the ones that are not soft a-stems elseif "a" == desinence then return "hard a-stem" -- i-stems ending in -ь preceded by a hard, non-palatal consonant. Gender is mandatory to distinguish between masculine and -- feminine inflection. We skip n-stems (having stem= parameter specified), which are handled below. elseif "ь" == desinence then if gender == "m" then return "masculine i-stem" elseif gender == "f" then return "feminine i-stem" else error("Gender for i-stems must be specified through g= parameter, as “m” or “f”") end -- in case of r-stems, there are only two nouns, so the stem= parameter might as well be superfluous elseif (unom_sg == "mati") or (unom_sg == "dъťi") then return "r-stem" else error("Unable to autodetect stem type; must specify stem=, per WT:ASLA") end end

local number_map = { s = "singular", d = "dual", p = "plural", }

local case_map = { nom = "nominative", acc = "accusative", gen = "genitive", loc = "locative", dat = "dative", ins = "instrumental", voc = "vocative", }

function make_header(forms, num, title) local lemma = forms.nom[num[1]] if type(lemma) ~= "table" then -- lemma remains elseif lemma.notesym then lemma = lemma[1] else local lemmavals = {} for _, item in ipairs(lemma) do			if type(item) == "table" then table.insert(lemmavals, com.link_form(item[1])) else table.insert(lemmavals, com.link_form(item)) end end lemma = table.concat(lemmavals, ", ") end local header = { '', ' Declension of ' .. lemma .. (title and " (" .. title .. ")" or "") .. ' ',		' ',		'{| class="inflection-table" style="width: 100%; background: #F9F9F9; text-align: center"', '|-',		'| style="width:15%; background: #d9ebff" |', }	for _, n in ipairs(num) do table.insert(header, '! style="width: ' .. math.floor(100 / (1 + #num)) .. '%; background: #d9ebff;" | ' .. number_map[n]) end return table.concat(header, "\n") end

function make_row(forms, num, case) local row = { "|-",		"| style=\"background-color: #eff7ff;\" | " .. case_map[case] .. ""	}	for _, n in ipairs(num) do table.insert(row, "| " .. com.link_form(forms[case][n])) end return table.concat(row, "\n") end

function make_footer(footnotes) local footnote_text = (#footnotes > 0) and [===[ ]===] .. table.concat(footnotes, " ") .. [===[ ]===] or ""

return "|}\n" .. footnote_text .. " " end

-- Make the table function make_table(forms, num, title, footnotes) return table.concat(		{			make_header(forms, num, title),			make_row(forms, num, "nom"),			make_row(forms, num, "gen"),			make_row(forms, num, "dat"),			make_row(forms, num, "acc"),			make_row(forms, num, "ins"),			make_row(forms, num, "loc"),			make_row(forms, num, "voc"),			make_footer(footnotes),		},		"\n"	) end

return export