Jump to content

Module:Sandbox/Erutuon/Temperature arrays/mw.html

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Erutuon (talk | contribs) at 22:12, 26 September 2016 (version of Module:Sandbox/Erutuon/Temperature arrays that uses MediaWiki HTML library; not sure if it is faster or slower). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
(diff) ← Previous revision | Latest revision (diff) | Newer revision → (diff)

degree = "°"
weather = require("Module:Weather/sandbox")

message = ""

function add_message(new_message)
	if message == "" then
		message = "Notices: " .. new_message
	else
		message = message .. " " .. new_message
	end
end

function get_format (frame)
	local input_format_parameter = frame.args.input_format
	
	if input_format_parameter == nil then
		input_unit = frame.args.input_unit
		length = tonumber(frame.args.length)
	else
		length = string.match(input_format_parameter, '(%d+)') -- find digits in the input_format parameter
		length = tonumber(length)
		
		input_unit = string.match(input_format_parameter, '([CF])') -- C or F
	end
	
	if input_unit == "C" then
		output_unit = "F"
	elseif input_unit == "F" then
		output_unit = "C"
	else
		error ("Input unit is not recognized. Please choose F for Fahrenheit or C for Celsius", 0)
	end
	
	output_format = tostring(frame.args.output_format)
	display_unit = frame.args.display_unit
	
	if length == nil then
		error ("get_format has not found a length value in the length or input_format parameter")
	end
	
	return input_unit, output_unit, length, output_format, display_unit, array_names
end

function precision(value, decimals)
	local string = string.format('%.' .. decimals .. 'f', value)
	return string
end

function check_for_string(string)
	return string ~= "" and string ~= nil
end

function check_for_number(value)
	return type(tonumber(value)) == "number"
end

local function convert(value, decimals, unit) -- Unit is the unit being converted from. It defaults to input_unit.
	if not unit then
		unit = input_unit
	end
	if check_for_number(value) then
		local value = tonumber(value)
		if unit == "C" then
			return precision(value * 9/5 + 32, decimals)
		elseif unit == "F" then
			return precision((value - 32) * 5/9, decimals)
		else
			error("Input unit not recognized", 2)
		end
	else
		return "" -- Setting result to empty string if value is not a number avoids concatenation errors.
	end
end

function make_array(parameter, array, frame)
	get_format(frame)
	local array = {}
	local n = 1
	for number in parameter:gmatch('%-?%d+%.?%d?') do
		local number = number
		table.insert(array, n, number)
		if array[n] == nil then
			if n > 1 then
				error("There should be " .. length .. " values in the " .. parameter .. " parameter, but there are only " .. n .. " values")
			else
				error("There should be " .. length .. " values in the " .. parameter .. " parameter, but there is only " .. n .. " value")
			end
		end
		n = n + 1
		if n > length then
			break
		end
	end
	return array
end

function make_arrays(frame)
	get_format(frame)
	local parameter_a = frame.args.a
	local parameter_b = frame.args.b
	local parameter_c = frame.args.c
	if parameter_a then
		a = make_array(parameter_a, a, frame)
	else
		error("Please provide a set of numbers in parameter <span style=\"background-color: #EEE; font-family: monospace;\">a</span>")
	end
	if parameter_b then
		b = make_array(parameter_b, b, frame)
	else
		add_message("There is no content in parameter <span style=\"background-color: #EEE; font-family: monospace;\">b</span>.")
	end
	if parameter_c then
		c = make_array(parameter_c, c, frame)
	else
		add_message("There is no content in parameter <span style=\"background-color: #EEE; font-family: monospace;\">c</span>.")
	end
	return a, b, c
end

local output_formats = {
	high_low_average_F = 
		{ first = "F",
		line_break = "yes",
		convert_units = "yes",
		unit_names = "no",
		brackets = "yes",
		tooltip = "yes",
		add_color = "yes",
		small_font = "no",
		sortable = "yes", },
	high_low_F =
		{ line_break = "yes",
		first = "F",
		convert_units = "yes",
		unit_names = "no",
		brackets = "yes",
		tooltip = "no",
		add_color = "no",
		small_font = "no",
		sortable = "yes", },
	average_F = 
		{ first = "F",
		line_break = "yes",
		convert_units = "yes",
		unit_names = "yes",
		brackets = "yes",
		tooltip = "no",
		add_color = "yes",
		small_font = "no",
		sortable = "no", },
	}

local function add_unit_names(value, unit)
	if not unit then unit = input_unit end
	if output_format.unit_names == "yes" then
		if value == "" then
			return value -- Don't add a unit name to an empty string
		else
			return value .. degree .. unit
		end
	else
		return value
	end
end

local function interpret_format(parameter, realization1, realization2)
	if realization1 then
		if realization2 then
			if parameter == "yes" then
				parameter = { realization1, realization2 }
			else
				parameter = { "", "" }
			end
		else
			if parameter == "yes" then
				parameter = realization1
			else
				parameter = ""
			end
		end
	else
		parameter = ""
		add_message("<span style=\"background-color: #EEE; font-family: monospace;\">interpret_format</span> needs at least one realization")
	end
	return parameter
end

function make_cell(row, output_format, a, b, c)
	local cell, CSS, cell_content = "", "", ""
	local title_content, sort_attribute, sortkey, attribute_separator
	local style_attribute, title_attribute, values_separator = {}, {}, {}
	
	local values, converted_units
	local line_break, brackets = interpret_format(output_format.line_break, "<br>"), interpret_format(output_format.brackets, "(", ")" )
	if a then
		if b then
			values, values_separator = { a, b  }, { "/", interpret_format(output_format.convert_units, "/") }
		else
			values, values_separator = { a, "" }, { "", "" } -- Empty values must be strings, or concatenation will not work.
		end
	end
	if input_unit == output_format.first then
		converted_units = interpret_format(output_format.convert_units, add_unit_names(convert(values[1], 1), output_unit), add_unit_names(convert(values[2], 1), output_unit))
		values = { add_unit_names(values[1]), add_unit_names(values[2]) }
	elseif output_format.first == "C" or output_format.first == "F" then
		converted_units = interpret_format(output_format.convert_units, add_unit_names(values[1]), add_unit_names(values[2]) )
		values = { add_unit_names(convert(values[1], 1), output_unit), add_unit_names(convert(values[2], 1), output_unit) }
	else
		add_message("The value for <span style=\"background-color: #EEE; font-family: monospace;\">first</span> in <span style=\"background-color: #EEE; font-family: monospace;\">output_format</span> is not recognized.")
	end
	
	cell_content = values[1] .. values_separator[1] .. values[2] .. line_break .. brackets[1] .. converted_units[1] .. values_separator[2] .. converted_units[2] .. brackets[2]
	
	if a and b and c then
		CSS = interpret_format(output_format.add_color, temperature_CSS(c, input_unit))
		if input_unit == output_format.first then
			title_content = "Average temperature: " .. c .. interpret_format(output_format.convert_units, degree .. input_unit)
			sortkey = c
		else
			title_content = "Average temperature: " .. convert(c, 1) .. interpret_format(output_format.convert_units, degree .. output_unit)
			sortkey = convert(c, 1)
		end
		title_content = interpret_format(output_format.tooltip, title_content)
		sortkey = interpret_format(output_format.sortable, sortkey)
	elseif a and not b then
		CSS = interpret_format(output_format.add_color, temperature_CSS(a, input_unit))
	end
	CSS = CSS .. interpret_format(output_format.small_font, "font-size: 85%;")
	--[[
	if color_CSS == "" and other_CSS == "" then
		style_attribute = { "", "" }
	else
		style_attribute = { "style=\"", "\"" }
	end
	]]
	
	--[[
	if other_CSS == "" and color_CSS == "" and title_content == "" and sort_attribute == "" then
		attribute_separator = ""
	else
		attribute_separator = " | "
	end
	]]
	
	local td = row:tag("td")
		if check_for_string(cell_content) then
			td:wikitext (cell_content)
		else
			add_message("<span style=\"background-color: #EEE; font-family: monospace;\">cell_content</span> is not defined.")
		end
		if check_for_string(CSS) then
			td:cssText (CSS)
		end
		if check_for_string(title_content) then
			td:attr ("title", title_content)
		end
		if check_for_string(sortkey) then
			td:attr ("data-sort-value", sortkey)
		end
	-- cell = "\n| " .. style_attribute[1] ..  .. style_attribute[2] .. title_attribute[1] .. title_content .. title_attribute[2] .. sort_attribute .. attribute_separator .. cell_content
	return td
end

function print_arrays(frame)
	make_arrays(frame)
	local classes = "wikitable"
	if sortable == "yes" then
		classes = classes .. "sortable"
	end
	
	local t = mw.html.create("table")
		t:addClass(classes)
	local tr = t:tag("tr")
	if a and b and c then
		for i = 1, length do
			make_cell(tr, output_formats.high_low_average_F, a[i], b[i], c[i])
		end
	elseif a and b then
		for i = 1, length do
			make_cell(tr, output_formats.high_low_F, a[i], b[i])
		end
	elseif a then
		for i = 1, length do
			make_cell(tr, output_formats.average_F, a[i])
		end
	end
	return tostring(t) .. "\n\n<span style=\"color: red; font-size: 80%; line-height: 100%;\">" .. message .. "</span>"
end

return { print_arrays = print_arrays }