יחידה:שם המספר

מתוך ויקימקדש

ניתן ליצור תיעוד על היחידה הזאת בדף יחידה:שם המספר/תיעוד

--------------------------------------------------------------------------------------------------------------
-- 
--------------------------------------------------------------------------------------------------------------
-- For reference see:
-- [1]	https://hebrew-academy.org.il/topic/hahlatot/grammardecisions/terminology-ordinance/4-3-השימוש-בשם-המספר/
-- [2]	https://hebrew-academy.org.il/wp-content/uploads/meeting20.pdf#page=19
-- [3]	https://hebrew-academy.org.il/wp-content/uploads/Intro-zihronot-5.pdf#page=16
-- [4]	https://hebrew-academy.org.il/wp-content/uploads/meeting92.pdf#page=6
-- [5]	https://hebrew-academy.org.il/wp-content/uploads/meeting164-165.pdf#page=14
-- [6]	https://hebrew-academy.org.il/wp-content/uploads/meeting216.pdf#page=15
-- [7]	https://hebrew-academy.org.il/wp-content/uploads/meeting240.pdf#page=7
-- [8]	https://hebrew-academy.org.il/wp-content/uploads/meeting309.pdf#page=8
-- [9]	https://hebrew-academy.org.il/wp-content/uploads/meeting314.pdf#page=2
-- [10]	https://hebrew-academy.org.il/wp-content/uploads/meeting-329.pdf#page=9
--------------------------------------------------------------------------------------------------------------

local m_cardinal = {
	[0] = 'אפס',
	[1] = 'אחד',
	[2] = 'שניים',
	[3] = 'שלושה',
	[4] = 'ארבעה',
	[5] = 'חמישה',
	[6] = 'שישה',
	[7] = 'שבעה',
	[8] = 'שמונה',
	[9] = 'תשעה',
	[10] = 'עשרה',
	[11] = 'עשר'
}

local f_cardinal = {
	[0] = 'אפס',
	[1] = 'אחת',
	[2] = 'שתיים',
	[3] = 'שלוש',
	[4] = 'ארבע',
	[5] = 'חמש',
	[6] = 'שש',
	[7] = 'שבע',
	[8] = 'שמונה',
	[9] = 'תשע',
	[10] = 'עשר',
	[11] = 'עשרה'
}

local m_ordinal = {
	[0] = 'האפס',
	[1] = 'הראשון',
	[2] = 'השני',
	[3] = 'השלישי',
	[4] = 'הרביעי',
	[5] = 'החמישי',
	[6] = 'השישי',
	[7] = 'השביעי',
	[8] = 'השמיני',
	[9] = 'התשיעי',
	[10] = 'העשירי',
	[11] = 'העשירית'
}

local f_ordinal = {
	[0] = 'האפס',
	[1] = 'הראשונה',
	[2] = 'השנייה',
	[3] = 'השלישית',
	[4] = 'הרביעית',
	[5] = 'החמישית',
	[6] = 'השישית',
	[7] = 'השביעית',
	[8] = 'השמינית',
	[9] = 'התשיעית',
	[10] = 'העשירית',
	[11] = 'העשירי'
}

local m_construct = {
	[1] = 'אחד',
	[2] = 'שני',
	[3] = 'שלושת',
	[4] = 'ארבעת',
	[5] = 'חמשת',
	[6] = 'ששת',
	[7] = 'שבעת',
	[8] = 'שמונת',
	[9] = 'תשעת',
	[10] = 'עשרת',
	[11] = 'עשר'
}

local f_construct = {
	[1] = 'אחת',
	[2] = 'שתי',
	[3] = 'שלוש',
	[4] = 'ארבע',
	[5] = 'חמש',
	[6] = 'שש',
	[7] = 'שבע',
	[8] = 'שמונה',
	[9] = 'תשע',
	[10] = 'עשר',
	[11] = 'עשרה'
}

local tens = {
	[1] = 'עשרה',
	[2] = 'עשרים',
	[3] = 'שלושים',
	[4] = 'ארבעים',
	[5] = 'חמישים',
	[6] = 'שישים',
	[7] = 'שבעים',
	[8] = 'שמונים',
	[9] = 'תשעים'
}

local specials = {
	[11] = 'עשתי עשר',
	[12] = 'תריסר',
	[200] = 'מאתיים',
	[2000] = 'אלפיים',
	[10000] = 'רבבה'
}

local others = {
	[1] = 'פרט',
	[2] = 'זוג',
	[3] = 'שלישיה',
	[4] = 'רביעיה',
	[5] = 'חמישיה',
	[6] = 'שישיה',
	[7] = 'שביעיה',
	[8] = 'שמיניה',
	[9] = 'תשיעיה',
	[10] = 'עשיריה'
}

local fractions = {
	[1] = 'יחידה',
	[2] = 'חצי',
	[3] = 'שליש',
	[4] = 'רבע',
	[5] = 'חמישית',
	[6] = 'שישית',
	[7] = 'שביעית',
	[8] = 'שמינית',
	[9] = 'תשיעית',
	[10] = 'עשירית',
	[100] = 'מאית',
	[1000] = 'אלפית'
}

local groups = {
	[1] = 'אלף',
	[2] = 'מיליון',
	[3] = 'מיליארד',
	[4] = 'טריליון',
	[5] = 'קוודריליון',
	[6] = 'קווינטיליון'
}

local groups_plurals = {
	[1] = 'אחדות',
	[2] = 'עשרות',
	[3] = 'מאות',
	[4] = 'אלפים',
	[5] = 'עשרות אלפים',
	[6] = 'מאות אלפים',
	[7] = 'מיליונים',
	[8] = 'עשרות מיליונים',
	[9] = 'מאות מיליונים',
	[10] = 'מיליארדים',
	[11] = 'עשרות מיליארדים',
	[12] = 'מאות מיליארדים',
	[13] = 'טריליונים',
	[14] = 'עשרות טריליונים',
	[15] = 'מאות טריליונים',
	[16] = 'קוודריליונים',
	[17] = 'עשרות קוודריליונים',
	[18] = 'מאות קוודריליונים',
	[19] = 'קווינטיליונים',
	[20] = 'עשרות קווינטיליונים',
	[21] = 'מאות קווינטיליונים'
}

function set(...)
   local t = {}
   for _,k in ipairs({...}) do t[k] = true end
   return t
end

function tableConcat(primary, secondary)
    for i=1,#secondary do
        primary[#primary+1] = secondary[i]
    end
    return primary
end

function stringify(t)
	local result = ''
	if #t > 1 then
		for _,name in pairs(t) do
			if result ~= '' then result=result..' ' end
			if next(t,_) == nil then
				result = result..'ו'..name
			else
				result = result..name
			end
		end
	else
		result = t[1]
	end
	
	return result
end

function triadicGroup(position, digit3, digit2, digit1, ones)
	local res = {}

	if math.fmod(position, 3) == 2 and digit3 ~= 0 then
		if digit3 == 1 then
			table.insert(res, 'מאה')
		elseif digit3 == 2 then
			table.insert(res, 'מאתיים')
		else
			table.insert(res, f_cardinal[digit3] .. ' ' .. 'מאות')
		end
	end
	if math.fmod(position, 3) >= 1 and digit2 ~= 0 then
		if digit2 ~= 1 or digit1 == 0 then
			table.insert(res, tens[digit2])
		end
	end
	if math.fmod(position, 3) >= 0 and digit1 ~= 0 then
		if digit2 == 1 then
			table.insert(res, ones[digit1]..'־'..ones[11])
		elseif digit1 ~= 1 or math.floor(position / 3) == 0 then
			if not (digit1 == 2 and math.floor(position / 3) == 1) then
				table.insert(res, ones[digit1])
			end
		end
	end
	
	if res[1] and math.floor(position / 3) == 0 then
		return res
	elseif digit1 == 2 and math.floor(position / 3) == 1 then
		table.insert(res, 'אלפיים')
		return res
	else
		table.insert(res, groups[math.floor(position / 3)])
		return res
	end
end

function _numeral_to_hebrew(mispar, gender, feature, termSingular, termPlural)
	local reversed = string.reverse(mispar)
	local grouped, parts, ones = {}, {}, {}

	if set('m', "masculine", 'ז', "זכר")[gender] then
		if set("cardinal", "מונה")[feature] then
			ones = m_cardinal
		elseif set("ordinal", "סודר", "סידורי")[feature] then
			ones = m_ordinal
		elseif set("construct", "נסמך")[feature] then
			ones = m_construct
		else
			ones = m_cardinal
		end
	elseif set('f', "feminine", 'נ', "נקבה")[gender] then
		if set("cardinal", "מונה")[feature] then
			ones = f_cardinal
		elseif set("ordinal", "סודר", "סידורי")[feature] then
			ones = f_ordinal
		elseif set("construct", "נסמך")[feature] then
			ones = f_construct
		else
			ones = f_cardinal
		end
	else
		if set("cardinal", "מונה")[feature] then
			ones = f_cardinal
		elseif set("ordinal", "סודר", "סידורי")[feature] then
			ones = f_ordinal
		elseif set("construct", "נסמך")[feature] then
			ones = f_construct
		else
			ones = f_cardinal
		end
	end
	
	if tonumber(mispar) == 0 then
		return ones[0]
	end
	
	while reversed ~= '' do
		if math.fmod(#reversed, 3) ~= 0 then
			if math.fmod(#reversed, 3) == 2 then
				grouped = triadicGroup(	#reversed-1,
										0,
										tonumber(string.sub(reversed, #reversed, #reversed)) or 0,
										tonumber(string.sub(reversed, #reversed-1, #reversed-1)) or 0,
										ones
										)
			elseif math.fmod(#reversed, 3) == 1 then
				grouped = triadicGroup(	#reversed-1,
										0,
										0,
										tonumber(string.sub(reversed, #reversed, #reversed)) or 0,
										ones
										)
			end
			reversed = string.sub(reversed, 1, #reversed-math.fmod(#reversed, 3))
		else
			grouped = triadicGroup(	#reversed-1,
									tonumber(string.sub(reversed, #reversed, #reversed)) or 0,
									tonumber(string.sub(reversed, #reversed-1, #reversed-1)) or 0,
									tonumber(string.sub(reversed, #reversed-2, #reversed-2)) or 0,
									ones
									)
			reversed = string.sub(reversed, 1, #reversed-3)
		end
		tableConcat(parts, grouped)
		if math.floor(#reversed / 3) == 0 and math.fmod(#reversed, 3) == 0 then reversed = '' end
	end
	
	if termSingular ~= '' and termPlural ~= '' then
		if tonumber(mispar) == 1 then
			return termSingular..' '..stringify(parts)
		else
			return stringify(parts)..' '..termPlural
		end
	end
	return stringify(parts)
end

local p = {
	numeral_to_hebrew = numeral_to_hebrew,
}

function p.numeral_to_hebrew(frame)
	local args = require('Module:Arguments').getArgs(frame)
	local mispar = args[1]
	local gender, feature, termSingular, termPlural
	local translatedArgs = {};
	for k,v in pairs(args) do
		if mw.ustring.match(k, '[א-ת]') ~=nil then
			local enKey = mw.ustring.gsub(k, 'מין', 'gender')
			enKey = mw.ustring.gsub(enKey, 'מגדר', 'gender')
			enKey = mw.ustring.gsub(enKey, 'תכונית', 'feature')
			enKey = mw.ustring.gsub(enKey, 'תכונה', 'feature')
			enKey = mw.ustring.gsub(enKey, 'סוג', 'feature')
			if k == 'יחידה' or k == 'רבות' then
				gender = "feminine"
			elseif k == 'יחיד' or k == 'רבים' then
				gender = "masculine"
			end
			enKey = mw.ustring.gsub(enKey, 'יחידה', 'singular')
			enKey = mw.ustring.gsub(enKey, 'יחיד', 'singular')
			enKey = mw.ustring.gsub(enKey, 'רבות', 'plural')
			enKey = mw.ustring.gsub(enKey, 'רבים', 'plural')

			translatedArgs[enKey] = v
		else
			translatedArgs[k] = v
		end
	end
	
	gender = gender or translatedArgs['gender']
	feature = translatedArgs['feature']
	termSingular = translatedArgs['singular']
	termPlural = translatedArgs['plural']
	
	if termSingular and termPlural then
		feature = 'construct'
	end
	
	return _numeral_to_hebrew(
		mispar,
		gender or '',
		feature or '',
		termSingular or '',
		termPlural or ''
	) or ''
end

return {
	['המר'] = p.numeral_to_hebrew,
	convert = p.numeral_to_hebrew
}