Edge Rewrite
// HTMLRewriter · presentation

This page was redesigned at the edge.

Cloudflare fetched the original article and streamed it through HTMLRewriter to apply an entirely new visual system without rebuilding the source page.

Jump to content

Module:Object size

Permanently protected module
From Wikipedia, the free encyclopedia

-- This module is based off of [[Module:Person length]]

local p = {}

-- This function 100% written by AI!
local function replace_all_but_last(str, pattern, replacement)
    local last_occurrence_start, last_occurrence_end = str:find(pattern, 1, true) -- Find the first occurrence
    local temp_start, temp_end
    while last_occurrence_start do -- Keep finding until the last one
        temp_start, temp_end = last_occurrence_start, last_occurrence_end
        last_occurrence_start, last_occurrence_end = str:find(pattern, last_occurrence_end + 1, true)
    end

    if not temp_start then -- No occurrences found
        return str
    end

    local before_last = str:sub(1, temp_start - 1)
    local after_last = str:sub(temp_start)

    local replaced_before = before_last:gsub(pattern, replacement)

    return replaced_before .. after_last
end

function is_valid_unit(str)
	local units = {'mm','cm','in'}
    for index, value in ipairs(units) do
        if value == str then
            return true
        end
    end
    return false
end

local function clean_length(s)
	s = mw.ustring.gsub(s, '^%s*','')
	s = mw.ustring.gsub(s, '(%S)[×x](%S)', '%1 x %2') 
	s = mw.ustring.gsub(s, 'X', 'x')
	s = mw.ustring.gsub(s, '%s[×xX]%s', ' * ')
	s = mw.ustring.gsub(s, 'millimeter', 'mm')
	s = mw.ustring.gsub(s, 'millimetre', 'mm')
	s = mw.ustring.gsub(s, 'inches', 'in')
	s = mw.ustring.gsub(s, 'inch', 'in')
	s = mw.ustring.gsub(s, 'ins', 'in')
	s = mw.ustring.gsub(s, 'in%.', 'in')
	s = mw.ustring.gsub(s, 'centimetre', 'cm')
	s = mw.ustring.gsub(s, 'centimeter', 'cm')
	s = mw.ustring.gsub(s, 'cms', 'cm')
	s = mw.ustring.gsub(s, 'cm%.', 'cm')
	
	s = replace_all_but_last(s, 'mm', '')
	s = replace_all_but_last(s, 'cm', '')
	s = replace_all_but_last(s, 'in', '')
	
	return s
end

local function isnumber(s)
	if s then
		s = mw.ustring.gsub(s, '%+%s*%d+%s*/%s*%d+%s*$', '')
		s = mw.ustring.gsub(s, '%s*[–%-]%s*', '')
		return s
	end
	return nil
end

local function get_convert_length_args(s, prefer, enforce)
 	local original_string = s
 	s = clean_length(original_string or '') -- basic unit cleaning
	
	s = mw.ustring.gsub(s, '&[Nn][Bb][Ss][Pp];', ' ')
	
	local unit = mw.ustring.match(s, '^%s*[%d%.]*%s*%*%s*[%d%.]*%s*%*%s*[%d%.]*%s*(%a+)')
	if not is_valid_unit(unit) then
		return '', original_string
	end
	
	local m = mw.ustring.find(s, 'mm')
	local i = mw.ustring.find(s, 'in')
	local c = mw.ustring.find(s, 'cm')
	
	if m == nil and i == nil and c == nil then
		return '', original_string
	end

	if m ~= nil and i == nil then
		local n = mw.ustring.sub(s, 1, m - 1)
		if isnumber(n) then
			return {n,'mm','in',['abbr']='on'}, mw.ustring.sub(s, m+2)
		end
		return '', original_string
	end
	
	if i ~= nil and m == nil then
		local n = mw.ustring.sub(s, 1, i - 1)
		if isnumber(n) then
			return {n,'in','mm',['abbr']='on'}, mw.ustring.sub(s, i+2)
		end
		return '', original_string
	end
	
	if c ~= nil and i == nil then
		local n = mw.ustring.sub(s, 1, c - 1)
		if isnumber(n) then
			return {n,'cm','in',['abbr']='on'}, mw.ustring.sub(s, c+2)
		end
		return '', original_string
	end
	
	return '', original_string
end

function convert_length(frame, args)
	local targs, str = get_convert_length_args(args[1], args['prefer'] or '', args['enforce'] or '')

	if type(targs) == 'table' then
		return frame:expandTemplate{ title = 'convert', args = targs} .. str
	else
		return str
	end
end

function p.size(frame)
	return convert_length(frame, frame.args[1] and frame.args or frame:getParent().args)
end

return p