Module:User:Benwing2/sa-decl
- This module sandbox lacks a documentation subpage. You may create it.
- Useful links: root page • root page’s subpages • links • transclusions • testcases • user page • user talk page • userspace
This is a private module sandbox of Benwing2, for their own experimentation. Items in this module may be added and removed at Benwing2's discretion; do not rely on this module's stability.
local export = {}
local m_para = require("Module:parameters")
local m_links = require("Module:links")
local m_scripts = require("Module:scripts")
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:User:Benwing2/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
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 {
'| ',
table.concat(links, ' / '),
'<br/>',
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 #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 = m_scripts.getByCode(args.sc)
scCode = args.sc
else
sc = m_scripts.findBestScript(args.lemma, lang)
scCode = sc:getCode()
if scCode == 'None' then
sc = m_scripts.findBestScript(PAGENAME, lang)
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' },
r_stem_a = {},
contract = { type = 'boolean' },
}
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