モジュール:Userbox/sandbox

-- This module implements .
local categoryHandler = require('Module:Category handler').main
local p = {}
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local function checkNum(val, default)
	-- Checks whether a value is a number greater than or equal to zero. If so,
	-- returns it as a number. If not, returns a default value.
	val = tonumber(val)
	if val and val >= 0 then
		return val
	else
		return default
	end
end
local function addSuffix(num, suffix)
	-- Turns a number into a string and adds a suffix.
	if num then
		return tostring(num) .. suffix
	else
		return nil
	end
end
local function checkNumAndAddSuffix(num, default, suffix)
	-- Checks a value with checkNum and adds a suffix.
	num = checkNum(num, default)
	return addSuffix(num, suffix)
end
local function makeCat(cat, sort)
	-- Makes a category link.
	if sort then
		return mw.ustring.format(, cat, sort)
	else
		return mw.ustring.format(, cat)
	end
end
--------------------------------------------------------------------------------
-- Argument processing
--------------------------------------------------------------------------------
local function makeInvokeFunc(funcName)
	return function (frame)
		local origArgs = require('Module:Arguments').getArgs(frame)
		local args = {}
		for k, v in pairs(origArgs) do
			argsk = v
		end
		return p.main(funcName, args)
	end
end
p.userbox = makeInvokeFunc('_userbox')
p'userbox-2' = makeInvokeFunc('_userbox-2')
p'userbox-r' = makeInvokeFunc('_userbox-r')
--------------------------------------------------------------------------------
-- Main functions
--------------------------------------------------------------------------------
function p.main(funcName, args)
	local userboxData = pfuncName(args)
	local userbox = p.render(userboxData)
	local cats = p.categories(args)
	return userbox .. (cats or )
end
function p._userbox(args)
	-- Does argument processing for .
	local data = {}
	-- Get div tag values.
	data.float = args.float or 'left'
	local borderWidthNum = checkNum(args'border-width' or args'border-s', 1) -- Used to calculate width.
	data.borderWidth = addSuffix(borderWidthNum, 'px')
	data.borderColor = args'border-color' or args'border-c' or args1 or args'id-c' or 'var(--background-color-interactive)'
	data.width = addSuffix(240 - 2 * borderWidthNum, 'px') -- Also used in the table tag.
	data.bodyClass = args.bodyclass
	-- Get table tag values.
	data.backgroundColor = args'info-background' or args2 or args'info-c' or 'var(--background-color-interactive-subtle)'
	-- Get info values.
	data.info = args.info or args4 or ""
	data.infoTextAlign = args'info-a' or 'left'
	data.infoFontSize = checkNumAndAddSuffix(args'info-size' or args'info-s', 8, 'pt')
	data.infoHeight = checkNumAndAddSuffix(args'logo-height' or args'id-h', 45, 'px')
	data.infoPadding = args'info-padding' or args'info-p' or '0 4px 0 4px'
	data.infoLineHeight = args'info-line-height' or args'info-lh' or '1.25em'
	data.infoColor = args'info-color' or args'info-fc' or 'var(--color-emphasized)'
	data.infoOtherParams = args'info-other-param' or args'info-op'
	data.infoClass = args'info-class'
	-- Get id values.
	local id = args.logo or args3 or args.id
	data.id = id
	data.showId = id and true or false
	data.idWidth = checkNumAndAddSuffix(args'logo-width' or args'id-w', 45, 'px')
	data.idHeight = checkNumAndAddSuffix(args'logo-height' or args'id-h', 45, 'px')
	data.idBackgroundColor = args'logo-background' or args1 or args'id-c' or '#ddd'
	data.idTextAlign = args'id-a' or 'center'
	data.idFontSize = checkNumAndAddSuffix(args'logo-size' or args5 or args'id-s', 14, 'pt')
	data.idColor = args'logo-color' or args'id-fc' or data.infoColor
	data.idPadding = args'logo-padding' or args'id-p' or '0 1px 0 0'
	data.idLineHeight = args'logo-line-height' or args'id-lh' or '1em'
	data.idOtherParams = args'logo-other-param' or args'id-op'
	data.idClass = args'id-class'
	return data
end
p'_userbox-2' = function (args)
	-- Does argument processing for .
	local data = {}
	-- Get div tag values.
	data.float = args.float or 'left'
	local borderWidthNum = checkNum(args'border-s' or args9, 1) -- Used to calculate width.
	data.borderWidth = addSuffix(borderWidthNum, 'px')
	data.borderColor = args'border-c' or args6 or args'id1-c' or args1 or '#999999'
	data.width = addSuffix(240 - 2 * borderWidthNum, 'px') -- Also used in the table tag.
	data.bodyClass = args.bodyclass
	-- Get table tag values.
	data.backgroundColor = args'info-c' or args2 or '#eeeeee'
	-- Get info values.
	data.info = args.info or args4 or ""
	data.infoTextAlign = args'info-a' or 'left'
	data.infoFontSize = checkNumAndAddSuffix(args'info-s', 8, 'pt')
	data.infoColor = args'info-fc' or args8 or 'black'
	data.infoPadding = args'info-p' or '0 4px 0 4px'
	data.infoLineHeight = args'info-lh' or '1.25em'
	data.infoOtherParams = args'info-op'
	-- Get id values.
	data.showId = true
	data.id = args.logo or args3 or args.id1 or 'id1'
	data.idWidth = checkNumAndAddSuffix(args'id1-w', 45, 'px')
	data.idHeight = checkNumAndAddSuffix(args'id-h', 45, 'px')
	data.idBackgroundColor = args'id1-c' or args1 or '#dddddd'
	data.idTextAlign = 'center'
	data.idFontSize = checkNumAndAddSuffix(args'id1-s', 14, 'pt')
	data.idLineHeight = args'id1-lh' or '1em'
	data.idColor = args'id1-fc' or data.infoColor
	data.idPadding = args'id1-p' or '0 1px 0 0'
	data.idOtherParams = args'id1-op'
	-- Get id2 values.
	data.showId2 = true
	data.id2 = args.logo or args5 or args.id2 or 'id2'
	data.id2Width = checkNumAndAddSuffix(args'id2-w', 45, 'px')
	data.id2Height = data.idHeight
	data.id2BackgroundColor = args'id2-c' or args7 or args1 or '#dddddd'
	data.id2TextAlign = 'center'
	data.id2FontSize = checkNumAndAddSuffix(args'id2-s', 14, 'pt')
	data.id2LineHeight = args'id2-lh' or '1em'
	data.id2Color = args'id2-fc' or data.infoColor
	data.id2Padding = args'id2-p' or '0 0 0 1px'
	data.id2OtherParams = args'id2-op'
	return data
end
p'_userbox-r' = function (args)
	-- Does argument processing for .
	local data = {}
	-- Get div tag values.
	data.float = args.float or 'left'
	local borderWidthNum = checkNum(args'border-width' or args'border-s', 1) -- Used to calculate width.
	data.borderWidth = addSuffix(borderWidthNum, 'px')
	data.borderColor = args'border-color' or args'border-c' or args1 or args'id-c' or '#999'
	data.width = addSuffix(240 - 2 * borderWidthNum, 'px') -- Also used in the table tag.
	data.bodyClass = args.bodyclass
	
	-- Get table tag values.
	data.backgroundColor = args'info-background' or args2 or args'info-c' or '#eee'
	-- Get id values.
	data.showId = false -- We only show id2 in userbox-r.
	-- Get info values.
	data.info = args.info or args4 or ""
	data.infoTextAlign = args'info-align' or args'info-a' or 'left'
	data.infoFontSize = checkNumAndAddSuffix(args'info-size' or args'info-s', 8, 'pt')
	data.infoPadding = args'info-padding' or args'info-p' or '0 4px 0 4px'
	data.infoLineHeight = args'info-line-height' or args'info-lh' or '1.25em'
	data.infoColor = args'info-color' or args'info-fc' or 'black'
	data.infoOtherParams = args'info-other-param' or args'info-op'
	
	-- Get id2 values.
	data.showId2 = true
	data.id2 = args.logo or args3 or args.id or 'id'
	data.id2Width = checkNumAndAddSuffix(args'logo-width' or args'id-w', 45, 'px')
	data.id2Height = checkNumAndAddSuffix(args'logo-height' or args'id-h', 45, 'px')
	data.id2BackgroundColor = args'logo-background' or args1 or args'id-c' or '#ddd'
	data.id2TextAlign = args'id-a' or 'center'
	data.id2FontSize = checkNumAndAddSuffix(args'logo-size' or args5 or args'id-s', 14, 'pt')
	data.id2Color = args'logo-color' or args'id-fc' or data.infoColor
	data.id2Padding = args'logo-padding' or args'id-p' or '0 0 0 1px'
	data.id2LineHeight = args'logo-line-height' or args'id-lh' or '1em'
	data.id2OtherParams = args'logo-other-param' or args'id-op'
	return data
end
function p.render(data)
	-- Renders the userbox html using the content of the data table. 
	-- Render the div tag html.
	local root = mw.html.create('div')
	root
		:css('float', data.float)
		:css('border', (data.borderWidth or ) .. ' solid ' .. (data.borderColor or ))
		:css('margin', '1px')
		:css('width', data.width)
		:addClass('wikipediauserbox')
		:addClass(data.bodyClass)
	-- Render the table tag html.
	local tableroot = root:tag('table')
	tableroot
		:attr('role', 'presentation')
		:css('border-collapse', 'collapse')
		:css('width', data.width)
		:css('margin-bottom', '0')
		:css('margin-top', '0')
		:css('background', data.backgroundColor)
	
	-- Render the id html.
	local tablerow = tableroot:tag('tr')
	if data.showId then
		tablerow:tag('td')
			:css('border', '0')
			:css('width', data.idWidth)
			:css('height', data.idHeight)
			:css('background', data.idBackgroundColor)
			:css('text-align', data.idTextAlign)
			:css('font-size', data.idFontSize)
			:css('font-weight', 'bold')
			:css('color', data.idColor)
			:css('padding', data.idPadding)
			:css('line-height', data.idLineHeight)
			:css('vertical-align', 'middle')
			:cssText(data.idOtherParams)
			:addClass(data.idClass)
			:wikitext(data.id)
	end
	-- Render the info html.
	tablerow:tag('td')
		:css('border', '0')
		:css('text-align', data.infoTextAlign)
		:css('font-size', data.infoFontSize)
		:css('padding', data.infoPadding)
		:css('height', data.infoHeight)
		:css('line-height', data.infoLineHeight)
		:css('color', data.infoColor)
		:css('vertical-align', 'middle')
		:cssText(data.infoOtherParams)
		:addClass(data.infoClass)
		:wikitext(data.info)
	
	-- Render the second id html.
	if data.showId2 then
		tablerow:tag('td')
			:css('border', '0')
			:css('width', data.id2Width)
			:css('height', data.id2Height)
			:css('background', data.id2BackgroundColor)
			:css('text-align', data.id2TextAlign)
			:css('font-size', data.id2FontSize)
			:css('font-weight', 'bold')
			:css('color', data.id2Color)
			:css('padding', data.id2Padding)
			:css('line-height', data.id2LineHeight)
			:css('vertical-align', 'middle')
			:cssText(data.id2OtherParams)
			:wikitext(data.id2)
	end
	local title = mw.title.getCurrentTitle()
	if (title.namespace == 2) and not title.text:match("/") then
		return tostring(root) -- regular user page
	elseif title.namespace == 14 then
		return tostring(root) -- category
	elseif title.isTalkPage then
		return tostring(root) -- talk page
	end
	local legible = true
	local contrast = require('Module:Color contrast')._ratio
	local function has_text(wikitext)
		local function get_alt(text)
			return text:match("|alt=(*)") or ""
		end
	
		wikitext = wikitext:gsub("", "|")
		wikitext = wikitext:gsub("%%%s*MmEeDdIiAa%s*:-(|.-)", get_alt)
		wikitext = wikitext:gsub("%%%s*IiMmAaGgEe%s*:-(|.-)", get_alt)
		wikitext = wikitext:gsub("%%%s*FfIiLlEe%s*:-(|.-)", get_alt)
		wikitext = wikitext:gsub("%%.-)", get_alt)
		wikitext = wikitext:gsub("%%.-)", get_alt)
		return mw.text.trim(wikitext) ~= ""
	end
	if contrast { data.infoColor, data.backgroundColor, error = 0 }  0 then
		-- Get the title object
		local title
		if page then
			title = mw.title.new(page)
		else
			title = mw.title.getCurrentTitle()
		end
		-- Build category handler arguments.
		local chargs = {}
		chargs.page = page
		chargs.nocat = args.nocat
		chargs.main = 
		if args.notcatsubpages then
			chargs.subpage = 'no'
		end
		-- User namespace.
		local user = 
		for i, cat in ipairs(cats) do
			user = user .. makeCat(cat)
		end
		chargs.user = user
		-- Template namespace.
		local basepage = title.baseText
		local template = 
		for i, cat in ipairs(cats) do
			template = template .. makeCat(cat, ' ' .. basepage)
		end
		chargs.template = template
		return categoryHandler(chargs)
	else
		return nil
	end
end
return p