Module:User:Dragonoid76/sa-verb

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_verb_data = require("Module:User:Dragonoid76/sa-verb/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 gsub = mw.ustring.gsub local match = mw.ustring.match local split = mw.text.split

local sa_utils = require("Module:sa-utilities")

local names = { ["pres"] = "Present", ["impf"] = "Imperfect", ["fut"] = "Future", ["cond"] = "Conditional", ["aor"] = "Aorist", ["bene"] = "Benedictive/Precative", ["perf"] = "Perfect", ["indic"] = "Indicative", ["imper"] = "Imperative", ["optat"] = "Optative/Potential", ["part"] = "Participles", ["simple"] = "Simple Indicative", ["periph"] = "Periphrastic Indicative", ["inf"] = "Infinitive", ["gerund"] = "Gerund", ["gerundive_mn"] = "Masculine/Neuter Gerundive", ["gerundive_f"] = "Feminine Gerundive", ["part_mn"] = "Masculine/Neuter Past Passive Participle", ["part_f"] = "Feminine Past Passive Participle", ["part_av_mn"] = "Masculine/Neuter Past Active Participle", ["part_av_f"] = "Feminine Past Active Participle", ["nonf"] = "Nonfinite Forms" }

local tenses = { ["pres"] = { ["moods"] = { "indic", "imper", "optat", "part" }, ["voices"] = { "av", "mv" } },	["impf"] = { ["moods"] = { "indic" }, ["voices"] = { "av", "mv" } },	["fut"] = { ["moods"] = { "simple", "periph", "part" }, ["voices"] = { "av", "mv" } },	["cond"] = { ["moods"] = { "indic" }, ["voices"] = { "av", "mv" } },	["aor"] = { ["moods"] = { "indic" }, ["voices"] = { "av", "mv" } },	["bene"] = { ["moods"] = { "optat" }, ["voices"] = { "av", "mv" } },	["perf"] = { ["moods"] = { "indic", "part" }, ["voices"] = { "av", "mv" } },	["nonf"] = { ["moods"] = { "inf", "gerund", "gerundive_mn", "gerundive_f", "part_mn", "part_f", "part_av_mn", "part_av_f" } } }

local numbers = {"1_s", "2_s", "3_s", "1_d", "2_d", "3_d", "1_p", "2_p", "3_p"}

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, title_models, sc_cache) local width = 70 local title = names[args.tense] .. ": " .. title_models

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="' .. args.colspan .. '" | ' .. title .. "\n"    ) table.insert(header, '|- class="vsHide"\n') table.insert(header, '! style="background:#eff7ff" rowspan="2" |\n')

table.insert(header, '! colspan="3" style="background:#eff7ff" | Active\n') table.insert(header, '! colspan="3" style="background:#eff7ff" | Mediopassive\n')

table.insert(header, '|- class="vsHide"\n') local size = 2 for i = 1, size, 1 do       table.insert(header, '! style="background:#eff7ff" | Singular\n') table.insert(header, '! style="background:#eff7ff" | Dual\n') table.insert(header, '! style="background:#eff7ff" | Plural\n') end

return table.concat(header) end

local function make_cell(args, data, tag, arg_tag, sc_cache, col_span, voice) local forms, links, trs = {}, {}, {} if (not match(args.n, "a") and voice == "av") or (not match(args.n, "m") and voice == "mv") or (not match(args.n, "p") and voice == "pv") then forms = {"-"} elseif args[arg_tag] then forms = mw.text.split(args[arg_tag], "%s*[,]%s*") else forms = data.forms[tag] end

if not forms then return "| -\n" end for i, form in ipairs(forms) do   	form = sc_cache.tr(form) form = gsub(form, 'V', 'f') form = gsub(form, "Z", "x") local form_note_tag = get_form_note_tags(forms["note" .. i] or {}, data) table.insert(           links,            m_links.full_link({term = sc_cache.reverse_tr(form), tr = "-", lang = lang, sc = sc_cache.sc}) ..                form_note_tag        ) table.insert(trs, SLP_to_IAST.tr(form) .. form_note_tag) end

return table.concat { "| ",       "colspan = ", col_span, " | ",       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="' .. args.colspan .. '" |' }   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_nonf_table(args, data, output, sc_cache) local moods = tenses[args.tense].moods if data.forms["part_mn"] ~= "-" and data.forms["part_mn"] ~= nil then data.forms["part_av_mn"] = { data.forms["part_mn"][1] .. "vat" } -- these two formed directly from the given forms always data.forms["part_av_f"] = { data.forms["part_mn"][1] .. "vatī" } else data.forms["part_av_mn"] = { "-" } data.forms["part_av_f"] = { "-" } end local title_models = "" local arg_before = false local tag = moods[1] local arg_tag = moods[1] local forms if args[arg_tag] then forms = mw.text.split(args[arg_tag], "%s*[,]%s*") else forms = data.forms[tag] end for i, title_lem in ipairs(forms) do       	title_lem = sc_cache.tr(title_lem) title_lem = gsub(title_lem, 'V', 'f') title_lem = gsub(title_lem, "Z", "x") if i > 1 then title_models = title_models .. " or " end title_models = title_models .. m_links.full_link(                   {                        term = nil,                        alt = sc_cache.reverse_tr(title_lem),                        tr = SLP_to_IAST.tr(title_lem),                        lang = lang,                        sc = sc_cache.sc                    }                ) end local title = names[args.tense] .. ": " .. title_models table.insert(output, 'Forms of Sanskrit verbs are numerous and complicated. The following conjugation shows only a subset of all forms and should be treated as a guide. \n') table.insert(           output,            '{| class="inflection-table vsSwitcher" data-toggle-category="inflection" style="background:#F9F9F9; text-align:center; border: 1px solid #CCC; width: 40em"\n'        ) table.insert(output, '|- style="background: #d9ebff;"\n') table.insert(output, '! class="vsToggleElement" style="text-align: left;" colspan="4" | ' .. title .. "\n") table.insert(output, '|- class="vsHide"\n') table.insert(output, '! style="background:#eff7ff" |\n')

table.insert(output, '! colspan="2" style="background:#eff7ff" | Undeclinable\n') table.insert(output, '|- class="vsHide"\n') for _, mood in ipairs(moods) do           if mood == "gerundive_mn" then table.insert(output, '! style="background:#eff7ff" |\n') table.insert(output, '! colspan="2" style="background:#eff7ff" | Participles\n') table.insert(output, '|- class="vsHide"\n') end table.insert(output, '! style="background-color:#eff7ff;" | ' .. names[mood] .. "\n") local tag = mood local arg_tag = mood table.insert(output, make_cell(args, data, tag, arg_tag, sc_cache, 1)) table.insert(output, '|- class="vsHide"\n') 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 output end

local function make_voice(title_models, args, data, sc_cache, voice) local moods = tenses[args.tense].moods local tag = moods[1] .. "_" .. voice .. "_3_s" local arg_tag = moods[1] .. "_" .. voice .. "_3_s" local forms if args[arg_tag] then forms = mw.text.split(args[arg_tag], "%s*[,]%s*") else forms = data.forms[tag] end if #title_models > 0 then table.insert(title_models, ", ") end for i, title_lem in ipairs(forms or {"-"}) do   	title_lem = sc_cache.tr(title_lem) if i > 1 then table.insert(title_models, " or ") end title_lem = gsub(title_lem, 'V', 'f') title_lem = gsub(title_lem, "Z", "x") table.insert(title_models,            m_links.full_link( {                   term = nil, alt = sc_cache.reverse_tr(title_lem), tr = SLP_to_IAST.tr(title_lem), lang = lang, sc = sc_cache.sc               } )       )    end end

local function make_table_verb(args, data, output, sc_cache) local moods = tenses[args.tense].moods

if args.tense == "nonf" then table.insert(data.categories, "Sanskrit verbs with nonfinite forms") return make_nonf_table(args, data, output, sc_cache) end

-- local voices = tenses[args.tense].voices local voices = tenses[args.tense].voices local numbers = {"s", "d", "p"} local people = {{"3", "Third"}, {"2", "Second"}, {"1", "First"}}

local title_models = {} if match(args.n, "a") then make_voice(title_models, args, data, sc_cache, "av") end if match(args.n, "m") then make_voice(title_models, args, data, sc_cache, "mv") end if match(args.n, "p") then make_voice(title_models, args, data, sc_cache, "pv") end

table.insert(output, make_header(args, data, table.concat(title_models, ""), sc_cache)) table.insert(output, '|- class="vsHide"\n')

for _, mood in ipairs(moods) do       table.insert(output, '! style="background:#eff7ff" colspan="' .. args.colspan .. '" | ' .. names[mood] .. "\n") table.insert(output, '|- class="vsHide"\n') if mood == "part" then table.insert(output, '| style="background-color:#eff7ff; font-style:italic;" | \n') for _, voice in ipairs(voices) do               local tag = mood .. "_" .. voice local arg_tag = mood .. "_" .. voice table.insert(output, make_cell(args, data, tag, arg_tag, sc_cache, 3, voice)) end else for i, person_pair in ipairs(people) do               local person, person_name = person_pair[1], person_pair[2] table.insert(output, '| style="background-color:#eff7ff; font-style:italic;" | ' .. person_name .. "\n") for _, voice in ipairs(voices) do                   for _, number in ipairs(numbers) do                        local tag = mood .. "_" .. voice .. "_" .. person .. "_" .. number local arg_tag = mood .. "_" .. voice .. "_" .. person .. "_" .. number table.insert(output, make_cell(args, data, tag, arg_tag, sc_cache, 1, voice)) end end table.insert(output, '|- class="vsHide"\n') end 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 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.") -- Suppress; this fixes issues where docs pages get errors return get_sc_details({sc = "Deva"}) 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

--[=[Splits a string by commas and displays ]=] function export.split(frame) local args = frame.args args.lemma = args[1] local sc_cache = get_sc_details(args) if not sc_cache then return "Module failed on page " end local output = {} local splitted = mw.text.split(frame.args[1], ",") for i, form in ipairs(splitted) do		if i > 1 then table.insert(output, " ") end table.insert(           output,            m_links.full_link({term = form, lang = lang, sc = sc_cache.sc})        ) end return table.concat(output) end

function export.show(frame) local params = { lemma = {default = PAGENAME}, n = {default = "amp"}, sc = {}, [1] = {required = true}, [2] = {alias_of = "lemma"}, [3] = {},       [4] = {},        auto_sandhi = {default = true, type = "boolean"}, set = {default = false, type = "boolean" }, -- set vs anit roots note = {list = true, type = "boolean"}, o = {default = false, type = "boolean"}, mono = {default = false, type = "boolean"} }   for tense, tense_l in pairs(tenses) do    	if tense == "nonf" then for _, mood in pairs(tense_l["moods"]) do   			params[mood] = {} end else for _, mood in pairs(tense_l["moods"]) do   			for _, voice in pairs(tense_l["voices"]) do    				if mood == "part" then params[mood .. "_" .. voice] = {} else for _, number in pairs(numbers) do params[mood .. "_" .. voice .. "_" .. number] = {} end end end end end end local data = { forms = {}, categories = {}, decl_type = nil, form_notes = {}, form_notes_out = {}, general_notes = {} }   local args = m_para.process(frame:getParent.args, params)

local sc_cache = get_sc_details(args) if not sc_cache then return "Module failed on page " end args.lemma = sc_cache.tr(args.lemma) if args[3] ~= nil then args[3] = sc_cache.tr(args[3]) end if args[4] ~= nil then args[4] = sc_cache.tr(args[4]) end

local output = {} args.tense = args[1] -- conjugate(args, data) args.colspan = 7 args.n = gsub(args.n, "p", "") args.strong_lemma = args.lemma -- split(args.lemma, ",") args.weak_lemma = args[3] -- and split(args[3], ",") args.passive_lemma = args[4] -- and split(args[4], ",") if not args.o then sa_verb_data[args.tense](args, data) end make_table_verb(args, data, output, sc_cache) return table.concat(output) end

return export