Module:Legislationuk/new

From Wikipedia, the free encyclopedia
local export = {}

local data = mw.loadData("Module:Legislationuk/data")

-- TODO: Use [[Module:Roman]].
local function roman(num)
end

-- Constructor for an Act object.
local function makeAct(text)
	local Act = {_args={}}
	local links = {}
	
	-- Parse the pseudo-template used for each Act and extract the parameters.
	text = text:gsub("^.-{{|", ""):gsub("}}$", "")
	
	-- Wikilinks need to be temporarily substituted to prevent middle pipes from disrupting the parse.
	local u, i = mw.ustring.char, 1
	for link in text:gmatch("%[%[(.-)%]%]") do
		links[i] = "[[" .. link .. "]]"
		text = text:gsub("%[%[" .. link .. "%]%]", u(0xE000+i))
	end
	
	--Extract the arguments.
	local args = mw.text.split(text, "|")
	
	--Re-substitute any links.
	local cp = mw.ustring.codepoint
	for i, arg in ipairs(args) do
		args[i] = mw.ustring.gsub(arg, "[" .. u(0xE000) .. "-" .. u(0xF000) .. "]", function(cap1) return links[cp(cap1)-0xE000] end)
	end
	
	-- Parse each argument to extract the key and value. Any numbered arguments preceded by a named argument in the wikitext will need to have their keys adjusted downwards.
	for i, arg in ipairs(args) do
		local name = arg:match("^(.-)=") or i
		local val = arg:gsub("^" .. name .. "=", "") or arg
		while type(name) == "number" and name > 1 and Act._args[name-1] == nil do
			name = name - 1
		end
		Act._args[name] = val
	end
	
	function Act:getArgs()
		return self._args
	end
	
	-- Give the (English) short title as a link (which may be given explicitly in the wikitext, so as to support piped links).
	-- FIXME: This will break if a user tries to link only part of the title. Do we want to allow that?
	function Act:shortTitle()
		if self:getArgs()[1]:match("^%[%[.*%]%]$") then
			return self:getArgs()[1]
		else
			return "[[" .. self:getArgs()[1] .. "]]"
		end
	end
	
	function Act:cyShortTitle()
		return self:getArgs().cyshort
	end
	
	function Act:longTitle()
		return self:getArgs()[5]
	end
	
	function Act:cyLongTitle()
		return self:getArgs().cylong
	end
	
	-- Gives the legislation type, which may be contextually adjusted based on an optional parameter (e.g. for URLs).
	function Act:type(context)
		if context == "govUK" then
			local leg_type = {
				["public"] = "ukpga",
				["local"] = "ukla",
				["nawm"] = "mwa",
				["ania"] = "nia",
				["church"] = "ukcm"
			}
			return leg_type[self:getArgs()[2]] or self:getArgs()[2]
		else
			return self:getArgs()[2]
		end
	end
	
	-- TODO: Roman numeral for local Acts (and italic for private?), depending on context.
	function Act:number()
		return self:getArgs()[3]
	end
	
	function Act:date()
		local day, month, year = self:getArgs()[4]:match("(%d%d)-(%d%d)-(%d%d%d%d)")
		return os.time{day = day, month = month, year = year}
	end
	
	-- FIXME: (Foot)note parameters are currently numbered in correspondence with the parameter they refer to. There's probably a better way to handle these, as it isn't very flexible.
	function Act:note(n)
		return self:getArgs()["note" .. n]
	end
	
	--TODO: Allow a wider range of inputs (e.g. 1/0, y/n, yes/no etc.)
	function Act:isRepealed()
		return self:getArgs().repealed == "y" or false
	end
	
	function Act:isMaintained()
		return self:getArgs().maintained == "y" or false
	end
	
	function Act:isArchived()
		return self:getArgs().archived ~= "n" or false
	end
	
	function Act:govUKurl()
		return "https://www.legislation.gov.uk/" .. self:type("govUK") .. "/" .. os.date("%Y", self:date()) .. "/" .. self:number() .. "/contents"
	end
	
	function Act:NAurl(context, leg_type)
		if context == "welsh" then
			return "https://archives.library.wales/index.php/" .. self:getArgs().url
		else
			leg_type = "public" and "PU" or "PB"
			local session = ""
			if self:date() < os.time {day=1, month=1, year=1963} then
				for _, t in ipairs(data) do
					if legDate >= t.sDate.date and legDate <= t.eDate.date then
						session = t.archive
					end
				end
			end
			local num = self:type() == "local" and roman(self:number()) or self:number()
			-- TODO: Finish.
		end
	end
	
	function Act:linkedIcon(context, leg_type)
		if context == "govUK" then
			return "[[File:Legislation.gov.uk External.svg|29x14px|link=" .. self:govUKurl() .. "]]"
		elseif context == "NA" then
			local welsh = {
				["nawm"] = true,
				["anaw"] = true,
				["asc"] = true
			}
			if welsh[leg_type] then
				return "[[File:Library External.svg|26x17px|link=" .. self:NAurl("welsh", leg_type) .. "]]"
			else
				return "[[File:Parliamentary Archives External.svg|27x19px|link=" .. self:NAurl("PA", leg_type) .. "]]"
			end
		end
	end
	
	-- TODO: Check for more of these.
	function Act:sortkey()
		return self:getArgs()[1]:gsub("%(No%.?.-(%d+)%) (.*)$", "%2 %1")
	end
	
	Act.__index = Act
	
	return setmetatable({}, Act)
end

function export.main(frame)
	local html = mw.html
	local args = frame:getParent().args[1] and frame:getParent().args or frame.args
	local Act
	
	-- Iterate over the pseudo-templates to generate the HTML row for each Act.
	for i, arg in ipairs(args) do
		if arg:match("{{|") then
			Act = makeAct(arg)
			
			local enShortTitle = html.create("span")
				:css("font-weight", "700")
				:wikitext(Act:shortTitle())
			
			local cyShortTitle = Act:cyShortTitle() and html.create("span")
				:css("font-size", "0.975em")
				:css("font-weight", "700")
				:css("font-style", "italic")
				:wikitext(Act:cyShortTitle())
				
			local shortTitle = html.create("div")
				:css("flex-grow", "9")
				:node(enShortTitle)
				:wikitext(Act:isRepealed() and " (repealed)" or "")
				:node(cyShortTitle and html.create("br") or "")
				:node(cyShortTitle and cyShortTitle or "")
				
			local linksBoxesWidth = Act:isArchived() and Act:isMaintained() and "4.5em" or "2.25em"
			local linksBoxes = html.create("div")
				:css("float", "right")
				:css("min-width", linksBoxesWidth)
				:css("max-width", linksBoxesWidth)
				:wikitext(Act:isMaintained() and Act:linkedIcon("govUK", Act:type()))
				:node(Act:isArchived() and Act:isMaintained() and html.create("wbr") or "")
				--:wikitext(Act:isArchived() and Act:linkedIcon("NA", Act:type()))
				
			local titleBox = html.create("div")
				:css("display", "flex")
				:css("align-items", "center")
				:css("width", "42em")
				:css("max-width", "51vw")
				:attr("class", "box")
				:node(shortTitle)
				
			-- ETC.
		end
	end
	--return
end

return export