Module:sa-decl

local export = {}

local m_para = require("Module:parameters") local m_links = require("Module:links") local m_utils = require("Module:utilities") local lang = require("Module:languages").getByCode("sa") local m_script_utils = require("Module:script utilities") local sa_decl_data = require("Module:sa-decl/data") local SLP_to_IAST = require("Module:sa-utilities/translit/SLP1-to-IAST") local sa_utils_translit = require("Module:sa-utilities/translit") local PAGENAME = mw.title.getCurrentTitle.text

local sub = mw.ustring.sub local gsub = mw.ustring.gsub local match = mw.ustring.match local len = mw.ustring.len

local accent = '[/\\]'

local genders = { m = 'Masculine', f = 'Feminine', n = 'Neuter', } local cases = { {'nom', 'Nominative'}, {'voc', 'Vocative'}, {'acc', 'Accusative'}, {'ins', 'Instrumental'}, {'dat', 'Dative'}, {'abl', 'Ablative'}, {'gen', 'Genitive'}, {'loc', 'Locative'}, }

local super_nums = { [1] = '¹', [2] = '²', [3] = '³', [4] = '⁴', [5] = '⁵',	[6] = '⁶', [7] = '⁷', [8] = '⁸', [9] = '⁹', [0] = '⁰', }

local function to_super(num) local annotation = gsub(num, ".", super_nums) return annotation end

local function get_form_note_tags(form_notes, data) local output = {} if type(form_notes) ~= 'table' then form_notes = { form_notes } end for _, form_note in ipairs(form_notes) do		if type(data.form_notes[form_note]) ~= "number" then table.insert(data.form_notes_out, form_note) data.form_notes[form_note] = #data.form_notes_out end table.insert(output, to_super(data.form_notes[form_note])) end return table.concat(output) end

local function make_header(args, data, sc_cache) local width = '40' local title = genders[args.g] .. ' ' .. ' ' .. data.decl_type .. ' declension of ' .. m_links.full_link({term = nil, alt = sc_cache.reverse_tr(args.lemma), tr = SLP_to_IAST.tr(args.lemma), lang = lang, sc = sc_cache.sc}) local header = {'{| class="inflection-table vsSwitcher" data-toggle-category="inflection" style="background:#F9F9F9; text-align:center; border: 1px solid #CCC; width: ' .. width .. 'em"\n'} table.insert(header, '|- style="background: #d9ebff;"\n') table.insert(header, '! class="vsToggleElement" style="text-align: left;" colspan="4" | ' .. title .. '\n') table.insert(header, '|- class="vsHide"\n') table.insert(header, '! style="background:#eff7ff" |\n') if args.n == 'sdp' then table.insert(header, '! style="background:#eff7ff" | Singular\n') table.insert(header, '! style="background:#eff7ff" | Dual\n') table.insert(header, '! style="background:#eff7ff" | Plural\n') elseif args.n == 's' then table.insert(header, '! style="background:#eff7ff" | Singular\n') elseif args.n == 'd' then table.insert(header, '! style="background:#eff7ff" | Dual\n') elseif args.n == 'p' then table.insert(header, '! style="background:#eff7ff" | Plural\n') end return table.concat(header) end

local function make_cell(args, data, code, num, sc_cache) local tag = code .. '_' .. num local forms, links, trs = {}, {}, {} if args[tag] then forms = mw.text.split(sc_cache.tr(args[tag]), '%s*[,]%s*') else forms = data.forms[tag] end

if not forms then error("Internal error: No forms for slot '" .. tag .. "'") end for i, form in ipairs(forms) do		if form == "" then -- in case of form reduced to zero by 'novedic' parameter -- do nothing else local form_note_tag = get_form_note_tags(forms['note' .. i] or {}, data) -- a superscript number at the end of manually added forms should not be part of the (linked) form if match(form, "[¹²³⁴⁵⁶⁷⁸⁹]$") then extra_note_tag = gsub(form, "^.+(.)$", "%1") form = gsub(form, ".$", "") else extra_note_tag = "" end if form == "-" then table.insert(links, m_links.full_link({term = nil, alt = '-', tr = '-', lang = lang, sc = sc_cache.sc})) table.insert(trs, '-') else table.insert(links, m_links.full_link({ term = sc_cache.reverse_tr(form), tr = '-', lang = lang, sc = sc_cache.sc }) .. 					form_note_tag .. extra_note_tag) table.insert(trs, SLP_to_IAST.tr(form) .. form_note_tag .. extra_note_tag) end end end return table.concat { '| ',		table.concat(links, ' / '), ' ',		m_script_utils.tag_translit(table.concat(trs, ' / '), lang, "default", 'style="color: #888;"'), '\n' } end

local function format_notes(args, data) local output = { '|- class="vsHide"', '| style="background-color:#eff7ff; font-style:italic;border-top:double #888;" | Notes', '| style="text-align:left;border-top:double #888;" colspan=' .. len(args.n) .. ' |'	}	if #data.form_notes_out > 0 or #data.general_notes > 0 or #args.note > 0 then for i, form_note in ipairs(data.form_notes_out) do table.insert(output, '* ' .. to_super(i) .. form_note) end for _, general_note in ipairs(data.general_notes) do table.insert(output, '* ' .. general_note) end for _, note in ipairs(args.note) do table.insert(output, '* ' .. note) end return table.concat(output, '\n') .. '\n' else return '' end end

local function make_table_noun(args, data, sc_cache) local output = {make_header(args, data, sc_cache)} for _, case in ipairs(cases) do		local code, name = case[1], case[2] table.insert(output, '|- class="vsHide"\n') table.insert(output, '! style="background-color:#eff7ff; font-style:italic;" | ' .. name ..'\n') if args.n == 'sdp' then table.insert(output, make_cell(args, data, code, 's', sc_cache)) table.insert(output, make_cell(args, data, code, 'd', sc_cache)) table.insert(output, make_cell(args, data, code, 'p', sc_cache)) elseif args.n == 's' then table.insert(output, make_cell(args, data, code, 's', sc_cache)) elseif args.n == 'd' then table.insert(output, make_cell(args, data, code, 'd', sc_cache)) elseif args.n == 'p' then table.insert(output, make_cell(args, data, code, 'p', sc_cache)) end end table.insert(output, format_notes(args, data)) table.insert(output, '|}') if not args.nocat and #data.categories > 0 then table.insert(output, m_utils.format_categories(data.categories, lang)) end return table.concat(output) end

local function get_sc_details(args) local sc, scCode if args.sc then sc = require("Module:scripts").getByCode(args.sc) scCode = args.sc	else sc = lang:findBestScript(args.lemma) scCode = sc:getCode if scCode == 'None' then sc = lang:findBestScript(PAGENAME) scCode = sc:getCode if scCode == 'None' then error('Script code was not specified or detected.') end end end local tr, reverse_tr = sa_utils_translit.retrieve_tr_modules(scCode) return { tr = tr, reverse_tr = reverse_tr, sc = sc, scCode = scCode} end

function export.show(frame) local params = { lemma = {default = PAGENAME}, decl = {default = nil}, n = {default = 'sdp'}, sc = {}, [1] = {alias_of = 'lemma'}, nom_s = {}, nom_d = {}, nom_p = {}, acc_s = {}, acc_d = {}, acc_p = {}, ins_s = {}, ins_d = {}, ins_p = {}, dat_s = {}, dat_d = {}, dat_p = {}, abl_s = {}, abl_d = {}, abl_p = {}, gen_s = {}, gen_d = {}, gen_p = {}, loc_s = {}, loc_d = {}, loc_p = {}, voc_s = {}, voc_d = {}, voc_p = {}, note = { list = true }, root = { type = 'boolean' }, compound = { type = 'boolean' }, novedic = {default = false, type = "boolean" }, -- disable extra Vedic forms r_stem_a = {}, ambig_final = {},   -- for stems on -j, -ś or -h diaspirate = { type = 'boolean' }, -- for diaspirate roots like 'duh' participle = { type = 'boolean' }, contract = { type = 'boolean' }, nocat = {}, }	local data = { forms = {}, categories = {}, decl_type = nil, form_notes = {}, form_notes_out = {}, general_notes = {}, }	local args = m_para.process(frame:getParent.args, params) args.g = frame.args[1] local sc_cache = get_sc_details(args) args.lemma = sc_cache.tr(args.lemma) args.has_accent = match(args.lemma, accent)

if args.decl == nil then for decl, decl_data in pairs(sa_decl_data) do			if decl_data.detect(args) then sa_decl_data[decl](args, data) break end end end if data.decl_type == nil then error("No declension class could be detected. Please check the lemma form or specify the declension.") end

return make_table_noun(args, data, sc_cache) end

return export