Модул:Klimatska tabela-ijek

Iz Vojne Enciklopedije
(разл) ← Старија измена | Тренутна верзија (разл) | Новија измена → (разл)
Пређи на навигацију Пређи на претрагу

Документацију овог модула можете да направите на страници Модул:Klimatska tabela-ijek/док

--
-- KLIMATSKA TABELA
--

w = {};
local args = {}
local w_table
wbc = require("Module:Klimatska_tabela/Boje");
wbd = require("Module:Klimatska_tabela/Dijagram");
math_mod = require('Module:Math');

local months = {"јан", "феб", "мар", "апр", "мај", "јун",
		"јул", "авг", "сеп", "окт", "нов", "дец"}

local CONSTANTS = {mean = 0, sum = 1}

-- 'months arguments'
local m_arg_table = {
	mean_temperature = { par = 'пт_', label = 'Просјечна температура (°C)' },
	max_temperature  = { par = 'вт_', label = 'Највиша просјечна температура (°C)' },
	min_temperature  = { par = 'нт_', label = 'Најнижа просјечна температура (°C)' },
	precipitation    = { par = 'п_', label = 'Падавине (mm)' },
	snowfall         = { par = 'сп_', label = 'Висина сњежног покривача (cm)' },
	humidity         = { par = 'вв_', label = 'Просјечна влажност ваздуха (%)' },
	sunshine_hours   = { par = 'сс_', label = 'Број сунчаних сати (h/дану)' }
}

-- other arguments
local arg_table = {
	title   = { par = 'наслов', label = '' },
	source  = { par = 'извор', label = 'Извор' },
	diagram = { par = 'дијаграм', label = ''}
}

local function renderHeader()
	local header = w_table:tag('tr')
		:css('background-color', '#eee')
		:css('text-align', 'center')
 	
	header:tag('td')
		:attr('scope', 'col')
		:css('width', '200px')
		:css('min-width', '140px')
	
	for i,v in ipairs(months) do
		header:tag('th')
			:attr('scope', 'col')
			:css('width', '40px')
			:wikitext(v:sub(1,1):upper() .. v:sub(2))
	end
		
	header:tag('td')
		:attr('scope', 'col')
	
	header:tag('th')
		:attr('scope', 'col')
		:css('width', '40px')
		:wikitext('год.')
end

local function addRow(rowArgs)
	local row = w_table:tag('tr')
		:css('text-align', 'center')
		
	local label = row:tag('td')
		:attr('scope', 'col')
	if rowArgs.label then
		label:wikitext(rowArgs.label)
		:css('text-align', 'left')
		:css('font-size', '85%')
	end
	
	local m_index = 0
	local total = 0
	for i,v in ipairs(months) do
		local temp = row:tag('td')
			:attr('scope', 'col')
		if rowArgs[v] then
			-- Lets the user use ',' instead of '.' i.e. 27,9 (27.9 works too).
			local to_dot = mw.ustring.gsub(rowArgs[v], ",", ".")
			local to_no = math_mod._cleanNumber(to_dot)
			if to_no ~= nil then
				m_index = m_index+1
				total = total + to_no
				temp:wikitext( (mw.ustring.gsub( (mw.ustring.gsub( rowArgs[v], "%-", "−") ), "%.", ",") ) )
				local color = rowArgs.color_func(to_no)
				temp:css('background-color', color.background)
				temp:css('color', color.color)
			else
				temp:wikitext("-")
			end
		else
			temp:wikitext("-")
		end
	end
	
	local total_sign = row:tag('th')
		:attr('scope', 'col')
		:css('padding', '0 5px')
	
	local m_value = math.floor((total/m_index) * 10 + 0.5) / 10
	local m_color = rowArgs.color_func(m_value)
	local total_col = row:tag('td')
		:attr('scope', 'col')
		:css('background-color', m_color.background)
		:css('color', m_color.color)

	if rowArgs.total_type == CONSTANTS.mean then
		total_sign:wikitext("Ø")
		total_col:wikitext((mw.ustring.gsub( (mw.ustring.gsub( m_value, "%-", "−") ), "%.", ",") ))
	elseif rowArgs.total_type == CONSTANTS.sum then
		total_sign:wikitext("Σ")
		total_col:wikitext((mw.ustring.gsub( (mw.ustring.gsub( total, "%-", "−") ), "%.", ",") ))
	end
end

local function renderRow(label, name, color_func, total_type)
	local temp_table = {}
	
	for i,val in pairs(months) do
		temp_table[val] = args[name .. val]
	end
	
	if tableIsEmpty(temp_table) then
		return
	end
	
	temp_table['label'] = label
	temp_table['color_func'] = color_func
	temp_table['total_type'] = total_type
	
	addRow(temp_table)
end

local function renderDiagram()
	local temp_table = {}
	local temp_p_table = {}
	local temp_mit_table = {}
	local temp_mat_table = {}
	
	for i,val in pairs(months) do
		temp_p_table[val] = args[m_arg_table.precipitation.par .. val]
		temp_mit_table[val] = args[m_arg_table.min_temperature.par .. val]
		temp_mat_table[val] = args[m_arg_table.max_temperature.par .. val]
	end
	
	if tableIsEmpty(temp_p_table) and 
		(tableIsEmpty(temp_mit_table) or tableIsEmpty(temp_mat_table)) then
		return
	end

	temp_table = {
		precipitation = temp_p_table,
		minTemperature = temp_mit_table,
		maxTemperature = temp_mat_table,
		state = args[arg_table.diagram.par]
	}
	
	w_table:tag('tr')
		:tag('td')
			:attr('colspan', '15')
			:wikitext(wbd.diagram(temp_table))
end

local function _weather_box()
	-- (table) root
	w_table = mw.html.create():tag('table')
		:attr('cellspacing', '1')
		:attr('cellpadding', '0')
		:css('margin', 'auto')
		:css('background', '#f9f9f9')
		:css('border', '1px solid #A9A9A9')
		:css('margin-bottom', '.5em')
		:css('margin-top', '.5em')
		:css('padding', '2px')
		:css('font-size', '95%')
	
	-- title
	if args[arg_table.title.par] then
		w_table:tag('tr')
			:tag('th')
				:attr('colspan', '15')
				:css('background-color', '#eee')
				:css('font-style', 'italic')
				:css('text-align', 'center')
				:wikitext(args[arg_table.title.par])	
	end
 
	renderHeader()
	renderRow(m_arg_table.mean_temperature.label, m_arg_table.mean_temperature.par,
		wbc._temperature_color, CONSTANTS.mean)
	renderRow(m_arg_table.max_temperature.label, m_arg_table.max_temperature.par,
		wbc._temperature_color, CONSTANTS.mean)
	renderRow(m_arg_table.min_temperature.label, m_arg_table.min_temperature.par,
		wbc._temperature_color, CONSTANTS.mean)
	renderRow(m_arg_table.precipitation.label, m_arg_table.precipitation.par,
		wbc._precipitation_color, CONSTANTS.sum)
	renderRow(m_arg_table.snowfall.label, m_arg_table.snowfall.par,
		wbc._snowfall, CONSTANTS.sum)
	renderRow(m_arg_table.humidity.label, m_arg_table.humidity.par,
		wbc._humidity, CONSTANTS.mean)
	renderRow(m_arg_table.sunshine_hours.label, m_arg_table.sunshine_hours.par,
		wbc._sunshine_hours, CONSTANTS.mean)
	
	-- TODO: if args[arg_table.diagram.par] == 'no' -> do not render?
	renderDiagram()
 
	-- source
	if args[arg_table.source.par] ~= nil then
		w_table:tag('tr')
			:tag('td')
			:attr('colspan', '15')
			:css('font-size', '85%')
			:wikitext(arg_table.source.label .. ': ' 
				.. args[arg_table.source.par]) 
	end

	return tostring(w_table)
end

local function preprocessSingleArg(argName)
    -- If the argument exists and isn't blank, add it to the argument table.
    -- Blank arguments are treated as nil to match the behaviour of ParserFunctions.
    if (origArgs[argName] and origArgs[argName] ~= '') then
		args[argName] = origArgs[argName]
    end
end

-- preProcessArgs: first argument the parameter,
-- the second a table containing string that will be appended
-- to the parameter e.g. _type = 'a_' and _table = {'1', '2'}
-- the function will process arguments 'a_1' and 'a_2'. 
local function preprocessArgs(_type, _table)

    if type(_type) ~= 'string' then
        error("Invalid type value detected", 2)
    end	

	if _table == nil then
		if origArgs[_type] then
			preprocessSingleArg(_type)
		end
	else
		for i,v in ipairs(_table) do
			local prefixArgName = _type .. v
			if origArgs[prefixArgName] then
				preprocessSingleArg(prefixArgName)
			end
		end
	end
end

function tableIsEmpty(t)
	if t == nil then
		return true
	end
    for _, _ in pairs(t) do
        return false
    end
    return true
end

function w.weather_box(frame)
	-- If called via #invoke, use the args passed into the invoking template.
    -- Otherwise, for testing purposes, assume args are being passed directly in.
    if frame == mw.getCurrentFrame() then
        origArgs = frame:getParent().args
    else
        origArgs = frame
    end

	for i,val in pairs(m_arg_table) do
		preprocessArgs(val.par, months)
	end
	
	for i,val in pairs(arg_table) do
		preprocessArgs(val.par, nil)
	end
 
	return _weather_box()
end

return w