Внимание! Начат процесс обновления Wiki до версии игры 10.x. Если у Вас есть желание принять участие, то Вы можете найти больше информации в нашем ECO Contribution Wiki Discord.

Модуль:Unit

Материал из Eco - Русская Wiki
Перейти к:навигация, поиск

Для документации этого модуля может быть создана страница Модуль:Unit/doc

local p = {}
local Utils = require("Module:Utils")
local UnitsData = mw.loadData("Module:Unit/data")
local HTMLUtils = require("Module:UtilsHTML")

--- Find a definition for a unit measurement with the given case sensitive abbreviation and return a HTML <code>abbr</code> tag with the appropriate unit details.
--
-- Most abbreviations are <strong>case sensitive</strong> to differentiate between the milli- and mega- prefixes for example (e.g., millihertz (mHz) and megahertz (MHz)), but about a third of the abbreviations are not.
-- Non-case sensitivity is simply provided as an <em>ease of use</em> feature in the case that user mistypes a unit (e.g., writing "MO" instead of "mo" for month): the only way to truly know if a unit is or is not case sensitive is to read the module data file.
--
-- For example the meter per second abbreviation ("m/s" or "mps") is not case sensitive as there is no other unit defined by just the letter "m".
-- All units that contain a forward slash (e.g., "rad/s" radian per second) can be written with the character "p" replacing the slash. So "radps" and "rad/s" are equivalent.
-- @param #string abbr Abbreviation for a unit. This should be treated as case sensitive because <strong>most</strong>, but not all, units are case sensitive.
-- @return #table Unit abbreviation data.
-- @author User:Demian
-- @see _unit
-- @usage getUnit("kWh") = { "kW&sdot;h", { "kilowatt-hour", "kilowatt-hours" } }
-- @usage getUnit("ppm") = { "ppm", { "part per million", "parts per million" } }
-- @usage getUnit("GiB") = { "GiB", { "gibibyte", "gibibytes" } }
function p.getUnit(abbr)
	local abbrKey = tostring(abbr)
	local unitData = UnitsData["caseSensitiveUnits"][abbrKey]

	if not unitData then
		-- All case insensitive unit abbreviations are lower case, the user written abbreviation may not be.
		abbrKey = mw.ustring.lower(abbrKey)
		unitData = UnitsData["caseInsensitiveUnits"][abbrKey]
	end

	return unitData
end

--- Find a definition for a unit measurement with the given case sensitive abbreviation and return a HTML <code>abbr</code> tag with the appropriate unit details.
-- @param #string number Numerical value to format with a thousands separator. Optional.
-- @param #string abbr Case sensitive abbreviation for a unit. Optional.
-- @param #bool plural Override abbreviation plurality. If <code>nil</code>, determine plurality from number. Optional. Default: <code>nil</code>
-- @return #string "<code>number</code> <code>abbr</code>" where <code>number</code> is formatted with a thousands separator and <code>abbr</code> is an HTML abbr element, if a unit definition was found.
-- @return #string "<code>number</code>" with whitespace trimmed if <code>abbr</code> was undefined and no unit definition is found for <code>number</code>.
-- @return #string An HTML abbr element, if a unit definition was found for <code>number</code>.
-- @return #string "<code>number</code>" formatted with a thousands separator if <code>abbr</code> was undefined and no unit definition is found for <code>number</code>.
-- @return #string "" if both <code>number</code> and <code>abbr</code> evaluate as <code>false</code>.
-- @author User:Demian
-- @see getUnit
-- @usage _unit("kWh") = "<abbr title="kilowatt-hour">kW&sdot;h</abbr>"
-- @usage _unit(nil, "ppm", true) = "<abbr title="parts per million">ppm</abbr>"
-- @usage _unit("GiB") = "<abbr title="gibibyte">GiB</abbr>"
-- @usage _unit(-1200.34, "MHz", false) = "-1 200.34 <abbr title="megahertz">MHz</abbr>"
-- @usage _unit("123456789", "kg") = "123 456 789 <abbr title="kilograms">kg</abbr>"
function p._unit(number, abbr, plural)
	local unitData = nil
	local pluralIdx = 1

	if true == plural then
		pluralIdx = 2
	end

	if number and abbr then
		-- Has both.
		-- This can be done through the template or Lua.

		unitData = p.getUnit(abbr)

		if unitData then
			-- Check if number is 1, otherwise use plural.
			if nil == plural then
				local num = tonumber(number)
				pluralIdx = (1 == num or -1 == num) and 1 or 2
			end

			abbr = HTMLUtils.tagAbbr(unitData[1], unitData[2][pluralIdx])
		end

		return mw.ustring.format("%s %s", Utils.formatNumber(number), abbr)
	elseif number and not abbr then
		-- Only has number.
		-- This is a likely use case from the template.

		-- Try to get it as a unit instead.
		unitData = p.getUnit(number)

		if unitData then
			-- No number given, just return the unit.
			return HTMLUtils.tagAbbr(unitData[1], unitData[2][pluralIdx])
		else
			-- Did not find it as unit, assume it is a unitless number.
			return Utils.formatNumber(number)
		end
	elseif not number and abbr then
		-- Only has unit but no number.
		-- This is an invalid use case from the template, expecting use through Lua.

		unitData = p.getUnit(abbr)

		if unitData then
			abbr = HTMLUtils.tagAbbr(unitData[1], unitData[2][pluralIdx])
		end

		-- Else did not find it as unit, don't know what to do, return it back unchanged.
		return abbr
	else
		-- Has neither.
		return ""
	end
end

function p.unit(frame)
	local args = Utils.normaliseArgs(frame)
	return p._unit(args[1], args[2])
end

return p