Jump to content

Module:Progression rainbow: Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
clean
gentle cleaning
Line 12: Line 12:
end
end


local function class_percent(param, total)
local function percent(param, total)
-- These suck for i18n because the % is forced to the right without spacing,
-- These suck for i18n because the % is forced to the right without spacing,
-- both in a required context (CSS) and unrequired (to-be-displayed text).
-- both in a required context (CSS) and unrequired (to-be-displayed text).
-- I.e., there should be a separate version of this or a function parameter
-- I.e., there should be a separate version of this
-- which takes a boolean. :(
return tostring(round(100 * param / total)) .. '%'
return tostring(round(100 * param / total)) .. '%'
end
end
Line 23: Line 22:
local remaining = total - sum
local remaining = total - sum
if remaining > 0 then
if remaining > 0 then
return tostring(round(100 * remaining / total)) .. '%'
return percent(remaining, total)
else
else
return nil
return nil
Line 44: Line 43:
return default
return default
end
end
end

function p.main(frame)
return p._main(require('Module:Arguments').getArgs(frame))
end
end


Line 84: Line 79:
else
else
for i, class in ipairs(classes) do
for i, class in ipairs(classes) do
-- 'or class.count' to keep us safe from a non-numeric value in args.
-- 'or class.count' to keep us safe from nil arg
class.count = tonumber(args[i]) or class.count
class.count = tonumber(args[i]) or class.count
sum_classes = sum_classes + class.count
sum_classes = sum_classes + class.count
Line 105: Line 100:
root:addClass('progression-rainbow')
root:addClass('progression-rainbow')


-- Don't care which frame it is if all I want to do is expand templates
-- and extension tags
local current_frame = mw.getCurrentFrame()
local current_frame = mw.getCurrentFrame()
for _, class in ipairs(classes) do
for _, class in ipairs(classes) do
if class.count ~= 0 then
if class.count ~= 0 then
local percentage = class_percent(class.count, total)
local percentage = percent(class.count, total)
root:newline() -- sprinkled through to make the HTML easier to read
root:newline() -- sprinkled through to make the HTML easier to read
root:tag('li')
root:tag('li')
:css('background', current_frame:expandTemplate{
:css('background', current_frame:expandTemplate{
title = 'class/colour', args = { class.class }
title = 'class/colour', args = { class.class }
})
})
:css('width', percentage)
:css('width', percentage)
:tag('span')
:tag('span')
:addClass('sr-only')
:addClass('sr-only')
:wikitext(string.format('%s %s', percentage, class.category))
:wikitext(string.format('%s %s', percentage, class.category))
:done()
:done()
:done()
:done()
end
end
end
end
Line 129: Line 122:
if remaining then
if remaining then
root:tag('li')
root:tag('li')
:addClass('remaining')
:addClass('remaining')
:css('width', remaining)
:css('width', remaining)
:tag('span')
:tag('span')
:addClass('sr-only')
:addClass('sr-only')
:wikitext(string.format('%s remaining', remaining))
:wikitext(string.format('%s remaining', remaining))
:done()
:done()
:done()
:done()
:newline()
:newline()
end
end
Line 144: Line 137:
name = 'templatestyles', args = { src = 'Screen reader-only/styles.css'}
name = 'templatestyles', args = { src = 'Screen reader-only/styles.css'}
} .. '\n' .. tostring(root)
} .. '\n' .. tostring(root)
end

function p.main(frame)
return p._main(require('Module:Arguments').getArgs(frame))
end
end



Revision as of 14:25, 8 October 2021

--[[
This implements {{progression rainbow}}

]]
require('Module:No globals')

local p = {}

-- rounding to first decimal, from http://lua-users.org/wiki/SimpleRound
local function round(num)
	return math.floor(num * 10 + 0.5) / 10
end

local function percent(param, total)
	-- These suck for i18n because the % is forced to the right without spacing,
	-- both in a required context (CSS) and unrequired (to-be-displayed text).
	-- I.e., there should be a separate version of this
	return tostring(round(100 * param / total)) .. '%'
end

local function percent_remaining(sum, total)
	local remaining = total - sum
	if remaining > 0 then
		return percent(remaining, total)
	else
		return nil
	end
end

local function category_count(category, project)
	return mw.site.stats.pagesInCategory(
		string.format('%s %s articles', category, project),
		'pages'
	)
end

-- This is only done once in this module, here for demonstration.
-- Gist: Make it cleaner to initialize 'trivial' variables.
local function arg_or_default(args, from_arg, default)
	if args[from_arg] and args[from_arg] ~= '' then
		return args[from_arg]
	else
		return default
	end
end

function p._main(args)

	local classes = {
		{count = 0, class = 'List', category = 'List-Class'},
		{count = 0, class = 'Stub', category = 'Stub-Class'},
		{count = 0, class = 'Start', category = 'Start-Class'},
		{count = 0, class = 'C', category = 'C-Class'},
		{count = 0, class = 'B', category = 'B-Class'},
		{count = 0, class = 'GA', category = 'GA-Class'},
		{count = 0, class = 'A', category = 'A-Class'},
		{count = 0, class = 'FA', category = 'FA-Class'}
	}
	
	local project_classes = {
		{count = 0, class = 'FL', category = 'FL-Class'},
		{count = 0, class = 'Unassessed', category = 'Unassessed'}
	}

	local project = arg_or_default(args, "project", nil)
	
	local sum_classes = 0
	if project then
		for _, class in ipairs(classes) do
			class.count = category_count(class.category, project)
			if class.class == 'FA' then
				class.count = class.count + category_count(
					project_classes[1].category,
					project
				)
			end
			sum_classes = sum_classes + class.count
		end
	else
		for i, class in ipairs(classes) do
			-- 'or class.count' to keep us safe from nil arg
			class.count = tonumber(args[i]) or class.count
			sum_classes = sum_classes + class.count
		end
	end

	local total
	if project then
		-- It makes more sense to do this sum here rather than in the project
		-- loop above because total is initialized here in the non-project case
		total = sum_classes + category_count(
			project_classes[2].category,
			project
		)
	else
		total = tonumber(args[9]) or 100
	end
	
	local root = mw.html.create('ul')
	root:addClass('progression-rainbow')

	local current_frame = mw.getCurrentFrame()
	for _, class in ipairs(classes) do
		if class.count ~= 0 then
			local percentage = percent(class.count, total)
				root:newline() -- sprinkled through to make the HTML easier to read
				root:tag('li')
					:css('background', current_frame:expandTemplate{
						title = 'class/colour', args = { class.class }
					})
					:css('width', percentage)
					:tag('span')
						:addClass('sr-only')
						:wikitext(string.format('%s %s', percentage, class.category))
						:done()
					:done()
		end
	end
	root:newline()
	
	local remaining = percent_remaining(sum_classes, total)
	if remaining then
		root:tag('li')
			:addClass('remaining')
			:css('width', remaining)
			:tag('span')
				:addClass('sr-only')
				:wikitext(string.format('%s remaining', remaining))
				:done()
			:done()
		:newline()
	end
	root:allDone()
	return current_frame:extensionTag{
		name = 'templatestyles', args = { src = 'Module:Progression rainbow/styles.css'}
	} .. current_frame:extensionTag{
		name = 'templatestyles', args = { src = 'Screen reader-only/styles.css'}
	} .. '\n' .. tostring(root)
end

function p.main(frame)
	return p._main(require('Module:Arguments').getArgs(frame))
end

return p