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:Regional articles

From Wikipedia, the free encyclopedia

local p = {};
local mRedirect = require('Module:Redirect')
local ISO = require('Module:ISO_3166')
local getArgs = require('Module:Arguments').getArgs

-- Based off https://www.kaggle.com/datasets/andradaolteanu/country-mapping-iso-continent-region
local REGIONS = {
	Northern_Africa = "DZ;EG;EH;LY;MA;SD;TN",
	Sub_Saharan_Africa = "AO;BF;BI;BJ;BW;CD;CF;CG;CI;CM;CV;DJ;ER;ET;GA;GH;GM;GN;GQ;GW;IO;KE;ZW",
	Africa = "DZ;EG;EH;LY;MA;SD;TN;AO;BF;BI;BJ;BW;CD;CF;CG;CI;CM;CV;DJ;ER;ET;GA;GH;GM;GN;GQ;GW;IO;KE;ZW",
	Latin_America = "AG;AI;AR;AW;BB;BL;BO;BQ;BR;BS;BV;BZ;CL;CO;CR;CU;CW;DM;DO;VI",
	Northern_America = "BM;CA;GL;PM;US",
	Americas = "BM;CA;GL;PM;US;AG;AI;AR;AW;BB;BL;BO;BQ;BR;BS;BV;BZ;CL;CO;CR;CU;CW;DM;DO;VI",
	Central_Asia = "KG;KZ;TJ;TM;UZ",
	Eastern_Asia = "CN;HK;JP;KP;KR;MN;MO;TW",
	South_Eastern_Asia = "BN;ID;KH;LA;MM;MY;PH;SG;TH;TL;VN;AF",
	Southern_Asia = "BD;BT;IN;IR;LK;MV;NP;PK",
	Western_Asia = "AE;AM;AZ;BH;CY;GE;IL;IQ;JO;KW;LB;OM;PS;QA;SA;SY;TR;YE",
	Asia = "AE;AM;AZ;BH;CY;GE;IL;IQ;JO;KW;LB;OM;PS;QA;SA;SY;TR;YE;BD;BT;IN;IR;LK;MV;NP;PK;BN;ID;KH;LA;MM;MY;PH;SG;TH;TL;VN;AF;CN;HK;JP;KP;KR;MN;MO;TW;KG;KZ;TJ;TM;UZ",
	Eastern_Europe = "BG;BY;CZ;HU;MD;PL;RO;RU;SK;UA",
	Northern_Europe = "AX;DK;EE;FI;FO;GB;GG;IE;IM;IS;JE;LT;LV;NO;SE;SJ",
	Southern_Europe = "AD;AL;BA;ES;GI;GR;HR;IT;ME;MK;MT;PT;RS;SI;SM;VA",
	Western_Europe = "AT;BE;CH;DE;FR;LI;LU;MC;NL",
	Europe = "AT;BE;CH;DE;FR;LI;LU;MC;NL;AD;AL;BA;ES;GI;GR;HR;IT;ME;MK;MT;PT;RS;SI;SM;VA;AX;DK;EE;FI;FO;GB;GG;IE;IM;IS;JE;LT;LV;NO;SE;SJ;BG;BY;CZ;HU;MD;PL;RO;RU;SK;UA",
	Australia_New_Zealand = "AU;CC;CX;HM;NF;NZ",
	Melanesia = "FJ;NC;PG;SB;VU",
	Micronesia = "FM;GU;KI;MH;MP;NR;PW;UM",
	Polynesia = "AS;CK;NU;PF;PN;TK;TO;TV;WF;WS",
	Oceania = "AS;CK;NU;PF;PN;TK;TO;TV;WF;WS;FM;GU;KI;MH;MP;NR;PW;UM;FJ;NC;PG;SB;VU;AU;CC;CX;HM;NF;NZ",
	all = "AF;AX;AL;DZ;AS;AD;AO;AI;AQ;AG;AR;AM;AW;AU;AT;AZ;BS;BH;BD;BB;BY;BE;BZ;BJ;BM;BT;BO;BO;BQ;BA;BW;BV;BR;IO;BN;BN;BG;BF;MM;BI;KH;CM;CA;CV;KY;CF;TD;CL;CN;CX;CC;CO;KM;CD;CG;CK;CR;CI;HR;CU;CW;CY;CZ;DK;DJ;DM;DO;EC;EG;SV;GQ;ER;EE;ET;FK;FO;FJ;FI;FR;GF;PF;TF;GA;GM;GE;DE;GH;GI;GR;GL;GD;GP;GU;GT;GG;GW;GN;GY;HT;HM;VA;HN;HK;HU;IS;IN;ID;IR;IQ;IE;IM;IL;IT;CI;JM;JP;JE;JO;KZ;KE;KI;KP;KR;XK;KW;KG;LA;LV;LB;LS;LR;LY;LY;LI;LT;LU;MO;MK;MG;MW;MY;MV;ML;MT;MH;MQ;MR;MU;YT;MX;FM;MD;MC;MN;ME;MS;MA;MZ;MM;NA;NR;NP;NL;NC;NZ;NI;NE;NG;NU;NF;MP;NO;OM;PK;PW;PS;PA;PG;PY;PE;PH;PN;PL;PT;PR;QA;RE;RO;RU;RU;RW;BL;SH;KN;LC;MF;PM;VC;VC;WS;SM;ST;SA;SN;RS;SC;SL;SG;SX;SK;SI;SB;SO;ZA;GS;KR;SS;ES;LK;VC;SD;SR;SJ;SZ;SE;CH;SY;TW;TJ;TZ;TH;TL;TG;TK;TO;TT;TN;TR;TM;TC;TV;UG;UA;AE;GB;UM;US;UY;UZ;VU;VE;VE;VN;VN;VG;VI;WF;EH;YE;ZM;ZW",
	us_states = "Alabama;Alaska;Arizona;Arkansas;California;Colorado;Connecticut;Delaware;Florida;Georgia (U.S. state);Hawaii;Idaho;Illinois;Indiana;Iowa;Kansas;Kentucky;Louisiana;Maine;Maryland;Massachusetts;Michigan;Minnesota;Mississippi;Missouri;Montana;Nebraska;Nevada;New Hampshire;New Jersey;New Mexico;New York;North Carolina;North Dakota;Ohio;Oklahoma;Oregon;Pennsylvania;Rhode Island;South Carolina;South Dakota;Tennessee;Texas;Utah;Vermont;Virginia;Washington (state);West Virginia;Wisconsin;Wyoming"
	
};

-- Utils
--- String splitting helper
local function split(inputstr, sep)
    if sep == nil then
        sep = "%s+" -- default to splitting by one or more whitespace characters
    end
    local t, i = {}, 1
    -- The pattern "([^"..sep.."]+)" matches one or more characters that are *not* the separator.
    for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
        t[i] = str
        i = i + 1
    end
    return t
end

--- Turn country codes into names, add "the " as prefix to some countries
local function country_name(iso_code)
	local name = ""
	local messy_names = "BS;NL;GB;UK;US;AE;DO;PH;CD;CG;CF;VI;FO;AX;IM;CK;MH;FM"
	if string.find(messy_names, iso_code) then
		name = "the "
	end
	-- If it's bigger than that it's not a country code presumably
	if #iso_code > 3 then
		return iso_code
	end
	iso_name = ISO.name({iso_code})
	if iso_name == "" then
		name = name .. iso_code
	else
		name = name .. iso_name
	end
	return name
end



--- Expand pre-coded regions
local function parse_regions(raw_regions)
	return REGIONS[raw_regions] or raw_regions
end


-- Table generation functions
local function prettify_cell(raw_title, region, short, stat)
	local title = mw.ustring.gsub(raw_title, "XXX", region)
	local titleObj = mw.title.new(title)
	local out = ""
	local redirTarget = ""
	local tl = "[[" .. title 
		if short == "yes" then
			tl = tl .. "|" .. region
		end
	tl = tl .. "]]"
	if stat == "no" then
		return tl
	end
	if titleObj and titleObj.isRedirect then
		out = "{{Class/icon|Redirect}} " .. tl
		redirTarget = titleObj.redirectTarget
	elseif titleObj and titleObj.exists then
		-- disable protection icon for now, if going to enable, better to directly call the invoked module in the aad template for performance
		out = "{{aad|aq|" .. title .. "}} " .. tl -- .. " {{aad|protection|" .. title .. "}}" 
	else
		out = "{{Class/icon|}} " .. tl
	end
	if redirTarget ~= "" then
		out = out .. "{{br}}→<small>" .. mRedirect.luaMain(title, 1) .. "</small>"
	end
	return out
end

local function make_row(cols, label)
	local row = "|-\n"
	if label == "no" then
		row = row .. "| "
	else
		row = row .. "! "	
	end
	local col_count = #cols
	for i, col in ipairs(cols) do
		if i == 1 then
			if label ~= "no" then
				row = row .. col .. "\n| "
			end
		else
			row = row .. col
			if i ~= col_count then
				row = row .. " || "
			end			
		end

	end
	return row .. "\n"
end

local function make_header_row(cols, label)
	local row = "|-\n"
	if label ~= "no" then
		row = row .. "! Title/Region\n"
	end
	for i, col in ipairs(cols) do
		row = row .. "! " .. col .. "\n"
	end
	return row
end

local function make_table(titles, rows, label, height)
	local t = '<templatestyles src="Template:Sticky table start/styles.css" />\n'
	local style = "scrollbar-gutter: stable; height: " .. (height or "")
	t = t .. '<div class="sticky-table-scroll" style="' .. style .. '">\n'
	t = t .. '{| class="wikitable sticky-table-row1" \n'
	t = t .. make_header_row(titles, label)
	for k, cols in ipairs(rows) do 
		t = t .. make_row(cols, label)
	end
	t = t .. "|}\n</div>"
	return t
end

-- Helper function to cut down expensive parser functions
--- This reduced EPF count by factor of 25
local function batch_lookup(titles, regions)
	local all_titles = {}
	for rkey, region_code in ipairs(regions) do
		local region = country_name(region_code)
		for tkey, title in ipairs(titles) do
			all_titles[#all_titles + 1] =  mw.ustring.gsub(title, "XXX", region)
		end
	end
	mw.title.newBatch(all_titles):lookupExistence():getTitles()
end

function p.main( frame )
	local f = getArgs(frame, {
		wrappers = 'Template:Regional articles'
	})
	local titles = split(f["titles"], ";")
	local regions = split(parse_regions(f["regions"]), ";")
	local label = f["label"] or "no"
	local short = f["short"] or "no"
	local height = f["height"] or ""
	local stat = f["status"] or "yes"

	batch_lookup(titles, regions)
	local rows, r_i = {}, 1
	for rkey, region_code in ipairs(regions) do
		local region = country_name(region_code)
		local cols, c_i = {region}, 2
		for tkey, title in ipairs(titles) do
			cols[c_i] = prettify_cell(title, region, short, stat)
			c_i = c_i + 1
		end
		rows[r_i] = cols
		r_i = r_i + 1

	end
	if f["test"] == "yes" then
		return make_table(titles, rows, label, height)
	end
	return frame:preprocess(make_table(titles, rows, label, height))
end

return p