<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://the-democratika.com/wiki/index.php?action=history&amp;feed=atom&amp;title=Module%3AConvertIB</id>
	<title>Module:ConvertIB - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://the-democratika.com/wiki/index.php?action=history&amp;feed=atom&amp;title=Module%3AConvertIB"/>
	<link rel="alternate" type="text/html" href="https://the-democratika.com/wiki/index.php?title=Module:ConvertIB&amp;action=history"/>
	<updated>2026-04-04T21:40:25Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>https://the-democratika.com/wiki/index.php?title=Module:ConvertIB&amp;diff=6072&amp;oldid=prev</id>
		<title>&gt;Pppery: Changed protection settings for &quot;Module:ConvertIB&quot;: High-risk template or module ([Edit=Require template editor access] (indefinite) [Move=Require template editor access] (indefinite))</title>
		<link rel="alternate" type="text/html" href="https://the-democratika.com/wiki/index.php?title=Module:ConvertIB&amp;diff=6072&amp;oldid=prev"/>
		<updated>2024-06-28T16:46:56Z</updated>

		<summary type="html">&lt;p&gt;Changed protection settings for &amp;quot;&lt;a href=&quot;/wiki/index.php/Module:ConvertIB&quot; title=&quot;Module:ConvertIB&quot;&gt;Module:ConvertIB&lt;/a&gt;&amp;quot;: &lt;a href=&quot;/wiki/index.php?title=WP:High-risk_templates&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;WP:High-risk templates (page does not exist)&quot;&gt;High-risk template or module&lt;/a&gt; ([Edit=Require template editor access] (indefinite) [Move=Require template editor access] (indefinite))&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;require(&amp;#039;strict&amp;#039;)&lt;br /&gt;
local p = {}&lt;br /&gt;
local getArgs = require(&amp;#039;Module:Arguments&amp;#039;).getArgs&lt;br /&gt;
&lt;br /&gt;
-- Units accepted by {{convert}} that come in groups (e.g., &amp;quot;5 ft 6 in&amp;quot;)&lt;br /&gt;
local multiple = &lt;br /&gt;
{&amp;#039;mich&amp;#039;, &amp;#039;michlk&amp;#039;, &amp;#039;michainlk&amp;#039;, &amp;#039;miyd&amp;#039;, &amp;#039;miydftin&amp;#039;, &amp;#039;mift&amp;#039;, &amp;#039;ydftin&amp;#039;, &amp;#039;ydft&amp;#039;,&lt;br /&gt;
&amp;#039;ftin&amp;#039;, &amp;#039;footin&amp;#039;, &amp;#039;handin&amp;#039;, &amp;#039;lboz&amp;#039;, &amp;#039;stlb&amp;#039;, &amp;#039;stlboz&amp;#039;, &amp;#039;stlb&amp;#039;}&lt;br /&gt;
&lt;br /&gt;
-- Convert unit list to hash&lt;br /&gt;
local mult_table = {}&lt;br /&gt;
for _, v in ipairs(multiple) do&lt;br /&gt;
	mult_table[v] = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Function to pull out values and units from numeric args&lt;br /&gt;
-- Returns:&lt;br /&gt;
--   values:  list of numeric values, or &amp;quot;false&amp;quot; if no numeric argument is given&lt;br /&gt;
--   units: list of units (str)&lt;br /&gt;
--   value: if there is a last numeric value unpaired with a unit, it becomes the precision&lt;br /&gt;
--   anyValue: whether there is a non-false value in the values list&lt;br /&gt;
local function parseValuesUnits(args)&lt;br /&gt;
	local values = {}&lt;br /&gt;
	local units = {}&lt;br /&gt;
	local indx = 1&lt;br /&gt;
	local value = nil&lt;br /&gt;
	local anyValue = false&lt;br /&gt;
	-- loop through numeric arguments in pairs&lt;br /&gt;
	while args[indx] or args[indx+1] do&lt;br /&gt;
		value = args[indx]&lt;br /&gt;
		anyValue = anyValue or value&lt;br /&gt;
		-- if there is a unit, save in output lists&lt;br /&gt;
		if args[indx+1] then&lt;br /&gt;
			table.insert(values, value or false)&lt;br /&gt;
			table.insert(units, args[indx+1])&lt;br /&gt;
			value = nil&lt;br /&gt;
		end&lt;br /&gt;
		indx = indx+2&lt;br /&gt;
	end&lt;br /&gt;
	return values, units, value, anyValue&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Function to identify multiple units and rewrite them as new input or output groups&lt;br /&gt;
-- Args:&lt;br /&gt;
--   values, units: numeric values and units, as lists with same length&lt;br /&gt;
-- Returns:&lt;br /&gt;
--   newValues, newUnits: same lists rewritten&lt;br /&gt;
local function parseMultiples(values, units)&lt;br /&gt;
	local newValues = {}&lt;br /&gt;
	local newUnits = {}&lt;br /&gt;
	local i = 1&lt;br /&gt;
	-- we will search for multiples with up to 4 entries (depending on length)&lt;br /&gt;
	local maxMultiple = math.min(4,#units-1)&lt;br /&gt;
	local valueFound = false -- flag to suppress second (and later) input values&lt;br /&gt;
	--- Hack for handling &amp;quot;stone&amp;quot;: check if only value supplied is &amp;quot;lb&amp;quot;&lt;br /&gt;
	local onlyPounds = true&lt;br /&gt;
	for i = 1, #units do&lt;br /&gt;
		if values[i] and units[i] ~= &amp;#039;lb&amp;#039; then&lt;br /&gt;
			onlyPounds = false&lt;br /&gt;
			break&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	-- sweep through units&lt;br /&gt;
	while i &amp;lt;= #units do&lt;br /&gt;
		-- determine index of last possible unit that could contain a multiple&lt;br /&gt;
		local last_unit = math.min(i+maxMultiple-1,#units)&lt;br /&gt;
		local multipleFound = false&lt;br /&gt;
		-- try from longest multiple down to double multiple (prefer longest ones)&lt;br /&gt;
		for j = last_unit, i+1, -1 do&lt;br /&gt;
			local key = table.concat({unpack(units,i,j)}, &amp;#039;&amp;#039;)&lt;br /&gt;
			if mult_table[key] then&lt;br /&gt;
				-- we found a multiple unit&lt;br /&gt;
				multipleFound = true&lt;br /&gt;
				-- Hack for &amp;quot;stone&amp;quot;: add either &amp;#039;lb&amp;#039; or multiple unit string to output units&lt;br /&gt;
				--    depending on whether &amp;#039;lb&amp;#039; was the only unit string with a value&lt;br /&gt;
				if mw.ustring.sub(key,1,2) == &amp;#039;st&amp;#039; then&lt;br /&gt;
					table.insert(newValues, false)&lt;br /&gt;
					table.insert(newUnits, onlyPounds and key or &amp;#039;lb&amp;#039;)&lt;br /&gt;
				end&lt;br /&gt;
				-- if there are any value in the span of the multiple,&lt;br /&gt;
				-- then the multiple is an input&lt;br /&gt;
				-- assume all missing values after the first are zero&lt;br /&gt;
				local firstValueFound = false&lt;br /&gt;
				for k = i, j do&lt;br /&gt;
					firstValueFound = not valueFound and (firstValueFound or values[k])&lt;br /&gt;
					if firstValueFound then&lt;br /&gt;
						table.insert(newValues, values[k] or 0)&lt;br /&gt;
						table.insert(newUnits, units[k])&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				valueFound = valueFound or firstValueFound&lt;br /&gt;
				-- if no values in the span of the multiple,&lt;br /&gt;
				-- then the multiple is an output. Insert combined string as output unit&lt;br /&gt;
				if not firstValueFound then&lt;br /&gt;
					table.insert(newValues, false)&lt;br /&gt;
					table.insert(newUnits, key)&lt;br /&gt;
				end&lt;br /&gt;
				i = j+1&lt;br /&gt;
				break&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		--- If no multiple unit was found, insert value[i] and unit[i] into rewritten lists&lt;br /&gt;
		if not multipleFound then&lt;br /&gt;
			if valueFound then&lt;br /&gt;
				table.insert(newValues, false) -- skip writing value if it is a duplicate&lt;br /&gt;
			else&lt;br /&gt;
				table.insert(newValues,values[i])&lt;br /&gt;
				valueFound = values[i]&lt;br /&gt;
			end&lt;br /&gt;
			table.insert(newUnits, units[i])&lt;br /&gt;
			i = i+1&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return newValues, newUnits			&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Implement {{convinfobox}}&lt;br /&gt;
function p._convert(args)&lt;br /&gt;
	-- find all values and units in numeric args (and the precision, if it exists)&lt;br /&gt;
	local values, units, precision, anyValue = parseValuesUnits(args)&lt;br /&gt;
	-- bail if no values at all&lt;br /&gt;
	if not anyValue then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	-- rewrite values and units if multiple units are found&lt;br /&gt;
	values, units = parseMultiples(values, units)&lt;br /&gt;
	-- sort input and outputs into different buckets&lt;br /&gt;
	local input_values = {}&lt;br /&gt;
	local input_units = {}&lt;br /&gt;
	local output_units = {}&lt;br /&gt;
	for i = 1, #units do&lt;br /&gt;
		if values[i] then&lt;br /&gt;
			table.insert(input_values, values[i])&lt;br /&gt;
			table.insert(input_units, units[i])&lt;br /&gt;
		else&lt;br /&gt;
			table.insert(output_units, units[i])&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	-- bail if nothing to convert&lt;br /&gt;
	if #input_values == 0 or #output_units == 0 then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	-- assemble argument list to {{convert}}&lt;br /&gt;
	local innerArgs = {}&lt;br /&gt;
	-- First, pass all input unit(s)&lt;br /&gt;
	for i, v in ipairs(input_values) do&lt;br /&gt;
		table.insert(innerArgs,v)&lt;br /&gt;
		table.insert(innerArgs,input_units[i])&lt;br /&gt;
	end&lt;br /&gt;
	-- Then the output unit(s) [concatenated as single argument]&lt;br /&gt;
	table.insert(innerArgs,table.concat(output_units,&amp;quot;+&amp;quot;))&lt;br /&gt;
	if precision then&lt;br /&gt;
		table.insert(innerArgs,precision) -- last non-nil value contains precision&lt;br /&gt;
	end&lt;br /&gt;
	-- now handle all non-numeric arguments, passing to {{convert}}&lt;br /&gt;
	innerArgs.abbr = &amp;#039;on&amp;#039;  -- abbr=on by default&lt;br /&gt;
	for k, v in pairs(args) do&lt;br /&gt;
		if not tonumber(k) then&lt;br /&gt;
			innerArgs[k] = v&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	-- Call {{convert}} with innerArgs&lt;br /&gt;
	local frame = mw.getCurrentFrame()&lt;br /&gt;
	return frame:expandTemplate{title=&amp;#039;Convert&amp;#039;, args=innerArgs}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.convert(frame)&lt;br /&gt;
	local args = getArgs(frame)&lt;br /&gt;
	return p._convert(args) or &amp;quot;&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>&gt;Pppery</name></author>
	</entry>
</feed>