Module:StringCompare

From Parallel Wiki
Jump to navigation Jump to search

Documentation for this module may be created at Module:StringCompare/doc

local p = {}

-- compares arguments [1] and [2]
-- returns -1, 0, 1
-- ci=1 		case-insensitive comparison
-- versions=1	splits on whitespace and compares tokens alphabetically, 
-- 					except when tokens are all digits/periods, 
--					in which case it splits the token on the period and compares the numbers numerically.

function p.base( ... )

	p.current_frame = mw.getCurrentFrame()

	local args = { ... }
	if args[1] == p.current_frame then 
		args = require( 'Module:ProcessArgs' ).merge( true )
	else
		args = args[1]
	end
	
	if args[1] == nil or args[2] == nil then
		return 0
	end

	local a = args[1] .. ''
	local b = args[2] .. ''
	
	if args.ci ~= nil and args.ci ~= false then
		a = a:lower()
		b = b:lower()
	end

	if args.versions ~= nil and args.versions ~= false then
		local a_tokens = {}
		local b_tokens = {}
		for t in string.gmatch(a,"%S+") do table.insert( a_tokens, t ) end
		for t in string.gmatch(b,"%S+") do table.insert( b_tokens, t ) end
		
		for i, a_token in pairs(a_tokens) do
			if b_tokens[i] == nil then return 1 end
			local b_token = b_tokens[i]
			local a_token_is_ver = ( string.find(a_token,"^[%d%.]+$") ~= nil )
			local b_token_is_ver = ( string.find(b_token,"^[%d%.]+$") ~= nil )
			if a_token_is_ver and b_token_is_ver then
				local a_nums = {}
				local b_nums = {}
				for t in string.gmatch(a_token,"%d+") do table.insert( a_nums, t ) end
				for t in string.gmatch(b_token,"%d+") do table.insert( b_nums, t ) end
				for j, a_num in pairs(a_nums) do
					if b_nums[j] == nil then return 1 end
					local b_num = b_nums[j]
				    if tonumber(a_num) < tonumber(b_num) then return -1 end
				    if tonumber(a_num) > tonumber(b_num) then return 1 end
				end
				if #a_nums < #b_nums then return -1 end
			else
			    if a_token < b_token then return -1 end
			    if a_token > b_token then return 1 end
			end
		end
		if #a_tokens < #b_tokens then return -1 end
		return 0
	end

    if a <  b then return -1 end
    if a >  b then return 1 end
    if a == b then return 0 end
end

return p