Module:Sandbox/trappist the monk/cat chart properties

Revision as of 21:09, 23 October 2022 by imported>Legoktm (Replace Module:No globals with require( "strict" ))
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Documentation for this module may be created at Module:Sandbox/trappist the monk/cat chart properties/doc

require('strict');
local getArgs = require ('Module:Arguments').getArgs;

local function cat_info_get (frame)
	local args = getArgs (frame);
	local raw = {};																-- count, legend, and category extracted from category
	local out = {};																-- formatted output suitable for [[Module:Chart]]
	local link = 'yes' == frame.args.link:lower();								-- make a boolean
	local delimiter = args.delimiter or ':';
	local selector = args.selector and args.selector:lower() or 'pages';
	selector = ({all='all', pages='pages', subcats='subcats', files='files'})[selector] or 'pages';

	for _, cat in ipairs (args) do												-- spin through args and extract info for chart
		local t = {}
		table.insert (t, frame:callParserFunction ({name='PAGESINCATEGORY', args={cat, selector, 'R'}}));	-- get count of pages in this category in raw number form
		table.insert (t, cat and cat:match (args.pattern or '.*') or cat);						-- extract legend; use cat name if pattern not provided
		if link then
			table.insert (t, cat);												-- add cat name for linking
		end
		table.insert (raw, t);													-- save this
	end

	if 0==#raw then
		return string.format ('(%s%s%s%s%s)', -1, delimiter, 'error no slices', delimiter, '#d33');
	end

	for i, v in ipairs (raw) do													-- look for duplicate names
		for j=i+1, #raw do
			if raw[i][2] == raw[j][2] then
				return string.format ('(%s%s%s %s%s%s)', -1, delimiter, 'error duplicate names', raw[i][2], delimiter, '#d33');
			end
		end
	end

	local function comp (a, b)													-- used in following table.sort()
		if a[1] == b[1] then													-- when same do
			return a[2] < b[2];													-- ascending alpha sort on name
		end
		return tonumber (a[1]) > tonumber(b[1]);								-- descending sort
	end
	
	table.sort (raw, comp);														-- descending sort
	
	local non_empty_count = 0;													-- count of categories with at least one page
	local empty_count = 0;
	local other_pages_tally = 0;												-- tally of pages not included in the first 25 slices
	
	for i, t in ipairs (raw) do
		if 26 > i and '0' ~= t[1] then											-- slices 1 - 25 separately in the chart (as long as they have something in them)
			if link and t[3] then												-- build a linked slice; t[3] may be nil if cat doesn't match |pattern=
				table.insert (out, string.format ('(%s%s%s%s%s[[:Category:%s]])', t[1], delimiter, t[2], delimiter, delimiter, t[3]));
			else																-- build an unlinked slice
				table.insert (out, string.format ('(%s%s%s)', t[1], delimiter, t[2]));
			end
		elseif '0' ~= t[1] then													-- would-be slices 26+
			non_empty_count = non_empty_count + 1;								-- count the number of non-empty cats
			if t[1] then														-- in case t[1] is nil for whatever reason; shouldn't be; TODO: do we need this?
				other_pages_tally = other_pages_tally + t[1];					-- sum the number of pages in these non-empty cats
			end
		else
			empty_count = empty_count + 1;										-- count the number of empty cats
		end
	end

	if 0 == #out then															-- nothing in out{}
		return string.format ('(%s%s%s%s%s)', -1, delimiter, 'error slice values all zero', delimiter, '#d33');
	end

	if 0 ~= non_empty_count or 0 ~= empty_count then							-- 26th slice
		table.insert (out, string.format ('(%s%s%s+%s others)', other_pages_tally, delimiter, non_empty_count, empty_count));
	end

--error (table.concat (out, '\n'))
	return table.concat (out, '\n')
end


--[[--------------------------< E X P O R T E D   F U N C T I O N S >------------------------------------------
]]

return {
	cat_info_get = cat_info_get,
	}