Module:Chak-utilities

From The Languages of David J. Peterson
Revision as of 20:12, 19 October 2023 by Vaxjedi (talk | contribs)
Jump to navigation Jump to search

Utilities for Chakobsa scripts. Implements {{chak-from-root}}.

Exposed functions

l(term, face, alt)
Creates a link to a Chakobsa lexeme - similar to {{l|chak|term}}
is_geminate(char)
returns true if the supplied 'character' is geminate
compress_consonants(str)
Returns a 'compressed' version of the string where consonant digraphs are reduced to a single character and trigraph geminates are reduced to a geminate of a single character. Mostly for use with other functions for parsing.
expand_consonants(str)
Returns an 'expanded' version of the string where reductions from compress_consonants are replaced with the original romanizations.
parse_consonants(str)
Returns a string where the consonants have been split out, delimited by hyphens. Understands geminate consonants and considers them a 'single' consonant.
parse_root(root_str,expandFinal)
Returns a table of parts of the root string is grouped by consonant and vowels. Example: "kkaalatg" > "kk","aa","l","a","tg". If expandFinal is true, returns the final part parsed out through parse_consonants The above example would be "kkaalatg" > "kk","aa","l","a","t-g". Used for inflection functions.

export = {}

local m_links = require("Module:links")
local m_utilities = require("Module:utilities")
local m_headword = require("Module:headword")

local lang = require("Module:Languages").getByCode("chak")

local zwnj = "\u200C"

	
local function link(term, face, alt)
	return m_links.full_link( { term = term, lang = lang, alt = alt }, face )
end

function export.is_geminate(char)
	return char ~= nil and #char > 1 and #char < 4 and string.sub(char,1,1) == string.sub(char,2,2)
end

function export.extract_root(root_str)
	
	vowels = "aeiou"
	
	roots = {
		onset = '',
		vowel = '',
		coda = '',
	}
	
	if root_str then

		root_str = mw.ustring.gsub(root_str,zwnj,'-')
		root_str = string.gsub(root_str,'%s','-')
		parts = mw.text.split(root_str,'-')
	
		if #parts == 3 then
			roots['onset'] = parts[1]
			roots['vowel'] = parts[2]
			roots['coda'] = parts[3]
		elseif #parts == 2 then
			if string.find(parts[1],"^[aeiou]") then
				roots['onset'] = ''
				roots['vowel'] = parts[1]
				roots['coda'] = parts[2]
			elseif string.find(parts[2],"^[aeiou]") then
				roots['onset'] = parts[1]
				roots['vowel'] = parts[2]
				roots['coda'] = ''
			else
				roots['onset'] = parts[1]
				roots['vowel'] = ''
				roots['coda'] = parts[2]
			end
		elseif #parts == 1 and parts[1] ~= '' then
			local temp = root_str
			s,e = string.find(temp,"["..vowels.."]+")
			if s then 
				roots['vowel'] = string.sub(temp,s,e)
			end
			s,e = string.find(temp,"^[^"..vowels.."]+")
			if s then
				roots['onset'] = string.sub(temp,s,e)
				temp = string.gsub(temp,roots['onset'],'',1)
			end
			s,e = string.find(temp,"[^"..vowels.."]+")
			if s then
				roots['coda'] = string.sub(temp,s,e)	
			end
		else 
			return nil
		end
	else
		return nil
	end	
	
	return roots
end

function export.verbose_root(roots)
	r = { roots["onset"], roots["vowel"], roots["coda"] }
	
	return mw.text.listToText(r,'-','-')
end

function export.geminate_char(char)
	char = char or '' 
	if #char == 1 or (#char == 2 and string.sub(char,2) == 'h') then
		return string.sub(char,1,1)..char
	else
		return char
	end
end

function export.degeminate_char(char)
	char = char or ''
	
	if (#char == 2 or #char == 3) and string.sub(char,1,1) == string.sub(char,2,2)  then
		return string.sub(char,2)
	else
		return char
	end
end

function export.assimilate(str)

	devoiced = "[ktfs]"
	voiced = "[gdvz]"
	devoicing = {
		["g"] = "k",
		["d"] = "t",
		["v"] = "f",
		["z"] = "s",
	}
	h_devoicing = {
		["g"] = "k",
		["d"] = "t",
		["v"] = "f",
		["z"] = "z",
	}

	output = str

	if str and str ~= '' then
			--VvC assimilition
			output = string.gsub(output,"([au])v([^iua])","%1~v%2"):gsub("(.)~v",{["a"] = "au", ["u"] = "uu"})
			--General Devoicing
			output = string.gsub(output,"("..devoiced..")("..voiced..")","%1~%2"):gsub("~(.)",devoicing)
			output = string.gsub(output,"("..voiced..")("..devoiced..")","~%1%2"):gsub("~(.)",devoicing)
			--H devoicing
			output = string.gsub(output,"h("..voiced..")","%1~%2"):gsub("~(.)",h_devoicing)
			output = string.gsub(output,"("..voiced..")(h)","~%1%2"):gsub("~(.)",h_devoicing)	
			output = string.gsub(output,"("..voiced..")(h)","~%1%2"):gsub("~(.)",h_devoicing)
			
	end
	
	return output
end

function export.chak_from_root(frame)
	local output = {}
	local categories = {}
	
	local title = mw.title.getCurrentTitle()
	local namespace = title.nsText
	
	local params = {
		[1] = { alias_of = "root"},
		[2] = { alias_of = "mod"},
		["root"] = {required = true},
		["mod"] = {},		
		["nocat"] = { type = "boolean", default = false },
		["plain"] = { type = "boolean", default = false },
		["alt"] = {},
		["face"] = { default = "term" },
		["notext"] = { type = "boolean", default = false },
		["nolink"] = { type = "boolean", default = false },
	}
	
	local args = require("Module:parameters").process(frame:getParent().args, params)
	
	if not args["root"] and namespace == "Template" then
		args["root"] = "tes"
		args["mod"] = "t"
	end
	
	--local verbose_root = export.verbose_root(export.extract_root(args["root"]))
	local verbose_root = mw.ustring.gsub(args["root"],"%x{200C}","-")
	
	local link_text = link(args["root"], args["face"], verbose_root:gsub('-','') )
	mw.getCurrentFrame():callParserFunction( '#vardefine', { 'chak-root', verbose_root } )
	if args["mod"] then
		link_text = link_text.." + -"..link(args["mod"], args["face"], args["mod"])
		table.insert(categories, m_utilities.format_categories( { "Chakobsa terms with the modifier -" .. args["mod"] }, lang) )
		mw.getCurrentFrame():callParserFunction( '#vardefine', { 'chak-mod', args["mod"] } )
	end
		
	table.insert(output, link_text)
	table.insert(categories, m_utilities.format_categories( { "Chakobsa terms belonging to the root " .. args["root"] }, lang) )
	
	
	if args["plain"] then
		return args["root"].." + -"..args["mod"]
	elseif args["nocat"] then
		return table.concat(output)
	elseif args["notext"] then
		return table.concat(categories)
	else
		return table.concat(output) .. table.concat(categories)
	end
	
	return output
end

return export