Module:siwa-noun

From Linguifex
Revision as of 18:48, 19 July 2021 by Sware (talk | contribs)
Jump to navigation Jump to search



local export = {}

local m_u = require('Module:utilities')
local m_data = require('Module:siwa-noun/data')
local m_com = require('Module:siwa-noun/common')

local sub = mw.ustring.sub
local find = mw.ustring.find
local match = mw.ustring.match
local gmatch = mw.ustring.gmatch
local gsub = mw.ustring.gsub
local u = mw.ustring.char
local split = mw.text.split
local gsplit = mw.text.gsplit

local PAGENAME = mw.title.getCurrentTitle().text
--[[local vowels = "[aeiouyůõảẻỉỏủỷę̊]"
local consonants = "[mpbvntdsṡʦʨʥŋɲcɟħðrṁṅḥkgġhłƛɬḍ]"

local function dedigraphize(word)
	for digraph, repl in pairs(m_com.digraphs_to_single) do
		word = gsub(word, digraph, repl)
	end
	return word
end	

function syll_count(word)
	local pattern = "(" .. consonants .. "?" .. vowels .. "+ː?" .. consonants .. "*)"
	local syllable, n = gsub(word, pattern, "%1")
	syllable = match(syllable, pattern)
	
	return syllable, n
end

local function stressed_components(word)
	local pattern = consonants .. "?(" .. vowels .. "+ː?)(" .. consonants .. "*)"
	local pattern2 = consonants .. "?" .. vowels .. "+ː?" .. consonants .. "*(.)"
	local v, c = match(word, pattern)
	if c == "d" or c == "ġ" or c == "r" or c == "ɲ" or c == "ħ" then
		c = c .. match(word, pattern2)
	end
	return v, c
end	

local function detect_quality(word)
	local stressed, n = syll_count(word)
	if match(stressed, vowels .. vowels .. vowels .. "?") or match(stressed, "ː") or n>=3 then
		return "w" -- weak nouns
	elseif (match(stressed, vowels .. vowels .. vowels .. "?") or match(stressed, "ː")) and n<3 then
		return "l" -- long nouns 
	else return "s" -- strong nouns
	end 
end

local function detect_decl(word, gender, quality)
	local stressed = syll_count(word)
	local tonic_vowel = stressed_components(word)
	for vowel, d in pairs(stressed_vowels) do
		tonic_vowel = gsub(tonic_vowel, vowel, d)	
	end	
	if gender and quality then
		if find(word, vowels .. "$") then
			local decl = gender .. "-" .. tonic_vowel .. "-" .. quality
			return decl
		else
			return gender .. "-" .. sub(word, -1) .. "-" .. tonic_vowel
		end	
	end	
end

local function lenition(word)
	local lenited = ""
	local _, c = stressed_components(word)
	for regex, repl in pairs(m_data.lenition_patterns) do
		lenited = gsub(c, regex, repl, 1)
	end
	local i, j = find(word, c)
	return sub(word, 1, i-1) .. lenited .. sub(word, j+1)
end

]]

local function detect_decl(word, sv) -- stressed vowel
	return m_com.stressed_vowels[sv]
end

-- The main entry point.
function export.show(frame)
	local parent_args = frame:getParent().args
	
	local numbers = nil
	local decl = {}
	local word = NAMESPACE == "Template" and "sivi" or parent_args.word or PAGENAME
	local args = {}

	if not m_data[word] then
		if frame.args.decl then
			decl_type = frame.args.decl
		else
			if parent_args.n and parent_args.c and parent_args[1] then
				decl_type = parent_args.n .. "-" .. parent_args.c
				numbers = {parent_args[1]}
			else
				decl_type, numbers = detect_decl(word, parent_args[2] or "oa")
			end
		end
		
		if not decl_type then
			error("Unknown declension '" .. decl_type .. "'")
		end
		
		args = require("Module:parameters").process(parent_args, m_data[decl_type].params, true)
	
		if numbers then
			for i, number in ipairs(numbers) do
				args[i] = number
			end
		end
	end

	local data = {forms = {}, categories = {}}
	
	data.head = parent_args["head"] or nil
	data.proper = parent_args["proper"] and true or false
	data.nocat = parent_args["nocat"] and true or false
	data.sv = parent_args[1] or "oa" or error("Parameter 1 must be the word's stressed vowel")
	
	-- Generate the forms
	if m_data[word] then
		m_data[word](parent_args, data)
	else
		m_data[decl_type](args, data)
	end

	-- Make the table
	return make_table(data)
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
			table.insert(ret, subform)
		end
			
		return table.concat(ret, ", ")
	end
	
	local function link(term)
		local links = {}
		for alt in gmatch(term, "([^%s,]+)") do
			alt = "[[Contionary:" .. alt .. "|" .. alt .. "]]"
			table.insert(links, alt)
		end
		return table.concat(links, ", ")
	end	
	
	local function repl(param)
		if param == "decl_type" then
			return data.decl_type
		elseif param == "title" then
			return data.forms.nom_sg[1]
		elseif param == "pagename" and NAMESPACE == "Template" then
			return "sivi"
		elseif param == "pagename" then
			return PAGENAME
		else
			return show_form(data.forms[param])
		end
	end

	function export.make_cases(data, animacy)
		local cases = {"Unmarked<br />''agentive/dative''", "Marked<br />''patientive/genitive''", "Locative"}
		local loccases = {"inessive", "illative", "elative", "adessive", "allative", "ablative"}
		local all = {}
		local numbers = {"singular", "plural"}
		local ret = {}
		
		for _, case in ipairs(cases) do
			local case_short = mw.ustring.lower(case, 1, 1)
			table.insert(ret, '|- \n! ' .. (case_short == "l" and 'colspan="6"' or 'rowspan="2"') .. ' | ' .. case .. '\n')
			table.insert(all, case_short)
		end
		for _, loccase in ipairs(loccases) do
			local loccase_short = sub(loccase, 1, 1)
			table.insert(ret, "! " .. loccase .. "\n")
			table.insert(all, loccase_short)
		end
		for _, single in ipairs(all) do
			table.insert(ret, "| " .. link(show_form(data.forms[single])) .. "\n")
		end
		
		return table.concat(ret)
	end

	local wikicode = [=[
	
<div class="mw-collapsible" style="border-collapse: collapse; margin: 0px 0px -1px 0px; padding: 2px; border: 1px solid #aaaaaa; text-align: center; font-size: 95%; overflow: auto; width: 70%;">
<div style="min-height: 1.6em; font-weight:bold; font-size: 100%; text-align: left; background-color:#efefef; padding-left: 10px; background-image: -webkit-gradient(linear, left top, left bottom, from(#EFEFEF), to(#DFDFDF), color-stop(0.6, #E3E3E3)); background-image: -moz-linear-gradient(top, #EFEFEF, #E3E3E3 60%, #DFDFDF);  background-image: -o-linear-gradient(top, #EFEFEF, #E3E3E3 60%, #DFDFDF);">{{{pagename}}} — {{{gender}}} noun, {{{decl_type}}}
</div>
<div class="mw-collapsible-content" style="font-size: 100%;">
{| class="greentable" border="1px #aaaaaa solid" margin="1em 1em 1em 0" style="background: #f9f9f9; border-collapse: collapse;" width="100%"
|-
]=] .. export.make_cases(data) .. [=[
|}]=]


	return gsub(wikicode, "{{{([a-z0-9_]+)}}}", repl) .. (not data.nocat and m_u.format_categories(data.categories, lang) or "")
end

return export