Modul:number list/data/tl

Daripada Wiktionary

Pendokumenan untuk modul ini boleh diciptakan di Modul:number list/data/tl/doc

local export = {numbers = {}}

export.additional_number_types = {
	{key = "spanish_cardinal", after = "cardinal"},
	{key = "spanish_ordinal", after = "ordinal"},
	{key = "restrictive", after = "collective"}
}

local lang_tl = "tl"
local lang_es = "es"

local numbers = export.numbers

--- Table operations for simpler use

local function table_merge(t1,t2)
	local merged = {}
    for key, value in pairs(t1) do
        merged[key] = value
    end
    for key, value in pairs(t2) do
    	merged[key] = value
    end
    return merged
end

local function table_append(t1,t2)
	local appended = {}
    for key, value in pairs(t1) do
        table.insert(appended, value)
    end
    for key, value in pairs(t2) do
    	table.insert(appended, value)
    end
    return appended
end

-- canonicalize multiple spaces and remove leading and trailing spaces
local function canon_spaces(text)
	text = text:gsub("%s+", " ")
	text = text:gsub("^ ", "")
	text = text:gsub(" $", "")
	return text
end

-- List down preset names

local number_names = {
	ones = {
		[lang_tl] = {"isa", "dalawa", "tatlo", "apat", "lima", "anim", "pito", "walo", "siyam"},
		[lang_es] = {"uno", "dos", "tres", "kuwatro", "singko", "seis", "siyete", "otso", "nuwebe"}
	},
	tens = {
		[lang_es] = {"diyes", "beynte", "treynta", "kuwarenta", "singkuwenta", "sesenta", "setenta", "otsenta", "nobenta"}
	},
	nteens = {
		[lang_es] = {"onse", "dose", "trese", "katorse", "kinse"}
	},
	hundreds = {
		[lang_tl] = {"sandaan", "dalawandaan", "tatlundaan", "apatnaraan", "limandaan", "animnaraan", "pitundaan", "walongdaan", "siyamnaraan"},
		[lang_es] = {"siyento", "dosyentos", "tresyentos", "kuwatrosiyentos", "kinyentos", "seissiyentos", "setesiyentos", "otsosiyentos", "nobesiyentos"} 
	},
	power_10 = {
		[lang_tl] = {"", "pu", "daan", "libo", "laksa", "yuta", "angaw", "kati", "bahala", "libong-angaw", "", "", "angaw-na-angaw"},
		[lang_es] = {"mil", "milyon", "bilyon", "trilyon"}
	},
	ordinals = {
		[lang_es] = {
			{"primero", "primera"},  
			{"segundo", "segunda"}, 
			{"tersero", "tersera"},
			"kuwarta",
			{"kinto", "kinta"},
			nil,
			nil,
			{"oktabo", "oktaba"},
			nil
		}
	}
}

local number_data_preset = {
	[1] = {
		ordinal = {"una", "pang-una", "ikaisa" },
		adverbial = "minsan",
		fractional = "buo"
	},
	[2] = {
		ordinal = {"ikalawa", "pangalawa"},
		adverbial = {{"makalawa"}, "?"},
		fractional = {"kalahati"},
		multiplier = {"doble", "?"}
	},
	[3] = {
		ordinal = {"ikatlo", "ikatatlo", "pangatlo"},
		adverbial = {{"makatlo", "makaitlo"}, "?"},
		fractional = {"katlo", "sangkatlo", "saikatlo"},
		multiplier = {{"triple"}, "?"}
	},
	[4] = {
		adverbial =  {"?", {"makaipat"}},
		fractional = {"kapat", "sangkapat", "saikapat"}
	},
	[6] = {
		fractional = {{"kanim", "sangkanim", "saikanim"}, "?"}
	},
	[10] = {
		ordinal = {{"ikapu"}, "?"},
		fractional = {{"kapu", "ikapu", "saikapu"}, "?"},
		collective = {"pu", "desena"}
	},
	[12] = {
		collective = "dosena"
	},
	[100] = {
		distributive = {"manaan", "mandaan", "tigsandaan", "sanda-sandaan", "sandaanan"},
		fractional = {"ikaraan", "ikasandaan", "saikaraan", "saikasandaan"},
		collective = "daan"
	},
	[10^3] = {
		adverbial = {{"makalibo", "makalilibo"}, "?"},
		ordinal = {{"ikalibo", "panlibo"}, "?"},
		distributive = {{"libo-libo", "panlibo"}, "?"},
		collective = "libo"
	},
	[10^4] = {
		cardinal = {'?', {"sanlaksa"}},
		ordinal = {'?', {"ikalaksa", "ikasanlaksa", "pansanlaksa"}},
		collective = "laksa"
	},
	[10^5] = {
		cardinal = {'?', {"sangyuta"}},
		ordinal = {'?', {"ikayuta", "pangyuta", "ikasangyuta"}},
		collective = {'daang libo', "yuta"}
	},
	[10^6] = {
		cardinal = {'?', {"sang-angaw-angaw", "sampung yuta", "sanlibong-libo"}},
		ordinal = {'?', {"ikaangaw", "<br>pang-angaw", "ikasang-angaw-angaw", "ikasampung yuta"}},
		collective = "angaw"
	},
	[10^7] = {
		cardinal = {'?', {"sangkati"}},
		ordinal = {'?', {"<br>ikakati", "pangkati", "ikasangkati"}},
		collective = "kati"
	},
	[10^8] = {
		cardinal = {'?', {"sambahala"}},
		ordinal = {'?', {"ikabahala", "pangbahala", "ikasambahala"}},
		collective = "bahala"
	},
	[10^9] = {
		cardinal = {'?', {"sanggatos"}},
		ordinal = {'?', {"ikagatos", "panggatos", "ikasanggatos"}},
		collective = "gatos"
	}
}

local affixes = {
	["ordinal"] = {"ika", "pang-"},
	["adverbial"] = {"maka"},
	["grouping"] = {"-an"},
	["distributive"] = {"tig-"},
	["tens"] = {"labing-"},
	["es_tens"] = {"disi"},
	["fractional"] = {"ka", "sangka", "ika", "saika"}
}

local function append_affix(affixes, root, nasal, br)
	affixed_list = {}
	new_root = tostring(root)
	nasal = nasal or "none"

	if type(root) == "number" then
		new_root = '-' .. new_root	
	end
	
	if type(affixes) ~= "table" then
		affixes = { affixes }
	end
	
	for idx, affix in pairs(affixes) do
		if affix:match("^-") then
			-- If affix is a suffix, do the following:
			new_root = new_root:gsub("o$", "u")
			if new_root:match("[aeiou]$") and not new_root:match("pu$") then
				new_root = new_root .. "h"
			end
			table.insert(affixed_list, new_root .. affix:sub(2))
		else
			if affix:match("-$") and not new_root:match("^[aeiou]") then
				-- If affix is a prefix and root is starting with a consonant
				affix = affix:sub(1, -2)
				if nasal ~= "none" then
					affix = affix:gsub("ng$", (new_root:match("^[bp]") and "m") or (new_root:match("^[dlst]") and "n") or "ng")
					if nasal == "total" then
						new_root = new_root:sub(2)
					end
				end
			end
			table.insert(affixed_list, (br and #affixed_list > 0 and "<br>" or '') .. affix .. new_root)
		end
	end
	
	if #affixed_list == 1 then
		affixed_list = affixed_list[1]
	end
	
	return affixed_list
end

local function syllable_rdp(word, rdp_type)
	local words =  mw.text.split(word, " ") -- Multiple word, just apply repetition on the first word
	syll_temp = words[1]
	syll_result = ""
	
	if type(rdp_type) == "number" then
		--Find reduplication
		syll_temp = syll_temp:gsub("([aeiou])", "%1.")
		syll_temp = mw.text.split(syll_temp, "%.")
		
		if not syll_temp[#syll_temp]:match("[aeiou]") then
			syll_temp[#syll_temp-1] = syll_temp[#syll_temp-1] .. syll_temp[#syll_temp]
			table.remove(syll_temp, #syll_temp)
		end
		
		if rdp_type == #syll_temp then
			syll_result = words[1] .. "-"
		elseif rdp_type == 1 then
			syll_result = syll_temp[1]:sub(1,1) .. 	(syll_temp[1]:len() > 1 and  syll_temp[1]:sub(-1,-1) or '') -- Fix clusters
		else
			for i = 1, rdp_type do
				syll_result = syll_result .. syll_temp[i] or ""	
			end
			syll_result = syll_result .. "-"
		end
	elseif rdp_type == "full" then
		syll_result = words[1] .. "-"
	end
	
	words[1] = syll_result .. words[1]
	return table.concat(words, " ")
end

local function enclitic(word, append, space)
	result = ""
	encl = "ng"
	space = space or " "
	if not word:match("[aeioun]$") then
		result = word .. space .. "na" .. space .. append
	else
		if word:match("n$") then
			encl = "g"
		end
		
		word = word .. encl
		if space == "" then
			local root_replace = (append:match("^[bp]") and "m") or (append:match("^[dlst]") and "n") or "ng"
			word = word:gsub("ong$", "u" .. root_replace)
			word = word:gsub("ng$", root_replace)
		end
		
		result = word .. space .. append
	end
	return result
end

local function make_number(number)
	local num_table = {} 
	if number == 0 then
		num_table =  {
			cardinal = "wala",
			spanish_cardinal = "sero"
		}
	else
		local comma_separated = tostring(number)
		comma_separated = comma_separated:gsub("(%d)(%d%d%d)$", "%1,%2")
		while comma_separated:match("(%d)(%d%d%d)(,)") do
			comma_separated = comma_separated:gsub("(%d)(%d%d%d)(,)", "%1,%2%3")
		end	
		
		local place_values = mw.text.split(comma_separated, ",")
		
		local hundred = 0
		local tens = 0
		local ones = 0
		
		local tl_name = {}
		local es_name = {}
		
		for idx1, temp_places in pairs(place_values) do
			places = tonumber(temp_places)
			
			local thousands_name = {}
			local thousands_name_es = {}
			
			hundreds = places - (places % 100)
			tens_ones = (places % 100)
			tens = (places % 100) - (places % 10)
			ones = (places % 10)
			
			if places ~= 0 then
				values_names = {
					['hundreds'] = {},
					['tens'] = {},
					['ones'] = {}
				}
				
				if hundreds > 0 then
					values_names['hundreds'] = {
						cardinal =  number_names.hundreds[lang_tl][hundreds/100],
						spanish_cardinal =  number_names.hundreds[lang_es][hundreds/100]
					}
				end
				
				if tens_ones > 10 and tens_ones < 20 then
					values_names['ones'] = {
						cardinal = append_affix(affixes["tens"], number_names.ones[lang_tl][ones], "partial"),
						spanish_cardinal = number_names.nteens[lang_es][ones] or affixes["es_tens"][1] .. number_names.ones[lang_es][ones]
					}
				else
					if tens > 0 then
						if tens == 10 then
							num_param = append_affix("sang-", number_names.power_10[lang_tl][2], "partial")
						else
							num_param = enclitic(number_names.ones[lang_tl][tens/10], number_names.power_10[lang_tl][2], "")
						end
						
						values_names['tens'] = {
							cardinal = num_param,
							spanish_cardinal = number_names.tens[lang_es][tens/10],
						}
					end
					if ones > 0 then
						values_names['ones'] = 	{
							cardinal = number_names.ones[lang_tl][ones],
							spanish_cardinal = number_names.ones[lang_es][ones],
							spanish_ordinal = number_names.ordinals[lang_es][ones],
						}
					end
				end
				
				-- Build final name
				for idx2, key in pairs({'hundreds', 'tens', 'ones'}) do
					if values_names[key].cardinal ~= nil then
						table.insert(thousands_name, values_names[key].cardinal)
					end
					if values_names[key].spanish_cardinal ~= nil then
						table.insert(thousands_name_es, values_names[key].spanish_cardinal)
						if key == "tens" and tens >= 30 and ones > 0 then
							table.insert(thousands_name_es, "y")
						end
					end
				end
				
				table.insert(tl_name, table.concat(thousands_name, " at "))
				table.insert(es_name, table.concat(thousands_name_es, " "))
				
				if (idx1 < #place_values) and (#place_values > 1) then
					local place_distance = #place_values-idx1

					if tl_name[#tl_name] == "isa" then
						tl_name[#tl_name] =  append_affix("sang-", number_names.power_10[lang_tl][(3*place_distance)+1], "partial")
					else
						tl_name[#tl_name] = enclitic(tl_name[#tl_name], number_names.power_10[lang_tl][(3*place_distance)+1])
					end
					
					if es_name[#es_name] == "uno" then
						es_name[#es_name] = number_names.power_10[lang_es][place_distance]
					else
						table.insert(es_name, number_names.power_10[lang_es][place_distance])
						if place_distance > 1 then
							es_name[#es_name] = es_name[#es_name] .. "es"
						end
					end
				end
			end
			
			num_table = {
				cardinal = canon_spaces(table.concat(tl_name, " at ")),
				spanish_cardinal = canon_spaces(table.concat(es_name, " ")),
				spanish_ordinal = number < 10 and number_names.ordinals[lang_es][ones] or nil
			}
		end
	end
	num_table.cardinal =  num_table.cardinal:gsub("([aeiou]) (at)", "%1't")
	return num_table
end

-- Start list process

local number = 0

while (true) do
	local data = make_number(number)
	if number ~= 0 then
		local cardinal_num = data.cardinal
		data = table_merge(data, {
			ordinal = append_affix(affixes["ordinal"], cardinal_num, "partial", number == 9999),
			ordinal_abbr = append_affix(affixes["ordinal"], number, "partial"),
		})
		
		local limitation = require("Module:table").contains({
			number <= 21, 
			number % 10 == 0 and number <= 100,
			number == 99,
			number % 500 == 0 and number <= 1000
		}, true)
		if limitation then
			-- Limit the following data only to certain numbers for a cleaner table
			data = table_merge(data, {
				adverbial = append_affix(affixes["adverbial"], cardinal_num),
				multiplier =  ("[[" .. cardinal_num .. "|" .. canon_spaces(enclitic(cardinal_num, "")) .. "]] [[ibayo]]"),
				distributive = {
					append_affix(affixes["distributive"], cardinal_num),
					append_affix(affixes["grouping"], cardinal_num),
					syllable_rdp(cardinal_num, 2), 
				},
				restrictive = syllable_rdp(cardinal_num, 1),
				fractional = append_affix(affixes["fractional"], cardinal_num)
			})
			data.multiplier = data.multiplier:gsub(" na]]", "]] [[na]]")
		end
		
		if (number <= 20) or 
			(tostring(number):gsub("0", ""):len() == 1 and
			(number <= 10^6 and (number % 1000 and tostring(number):gsub("0", "") == "1") or math.log10(number) % 3 == 0)
		) then
			data.wplink = number .. " (bilang)"
		end
	
		local preset = number_data_preset[number]
		if preset then
			for num_type, num_vals in pairs(preset) do
				if type(preset[num_type]) == "table" then
					local new_preset_list = {}
					for index, value in pairs(preset[num_type]) do
						local insert_value = value
						if insert_value == "?" and data[num_type] then
							if type(data[num_type]) == "string" then
								data[num_type] = {data[num_type]}	
							end
							insert_value = data[num_type]
						end
						if type(insert_value) == "string" then
							insert_value = {insert_value}	
						end
						if number == 10 and num_type == "fractional" then
							insert_value[1] = "<br>" .. insert_value[1]
						end
						new_preset_list = table_append(new_preset_list, insert_value)
					end
					preset[num_type] = new_preset_list
				end
			end
			data = table_merge(data, preset)
		end
	end
	
	-- Set data to export
	numbers[number] = data
	
	if number < 100 or number == 9999 then
		number = number + 1
	elseif number <= 1100 then
		if number == 1100 then
			number = 2000
		else
			number = number + 100
		end
	elseif number < 10^4 then
		number = number + 1000
		if number == 10^4 then
			number = 9999
		end
	elseif number < 10^9 then
		number = number * 10
	elseif number < 10^12 then
		number = number * 10^3
	else
		break
	end
end

return export