Open main menu

Module:FindYDCportal

Revision as of 02:21, 2 January 2019 by Johannes Axner (talk | contribs) (1 revision imported)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Documentation for this module may be created at Module:FindYDCportal/doc

--[[
   For a given 3- or 4-digit year or decade, find the most specific portal
   which actually exists.
   Takes one parameter, which must be either a year (e.g. "1879", "1123")
   or a decade (e.g. "1940s", "790s").
   If a portal is found, return its name with out the nmaespace prefix
   (e.g. for "Portal:1980s" rerurn "1980s"); otherwise return an empty string.
   If the parameter is missing, empty, or does not fit the required format,
   an empty string is returned"
]]

local p = {}

-- check for the existence of a portal with the given name
-- if it exists, returns the name
-- otherwise returns nil
function doesPortalExist(portalName)
	local portalPage = mw.title.new( portalName, "Portal" )
	if (portalPage.exists) then
		return portalName
	end
	return nil
end


-- check for the existence of a portal with the name of that year
-- if it exists, returns the year
-- otherwise calls decadeCheck, and returns that result
-- otherwise returns nil
function checkYear(yearParam)
	if doesPortalExist(yearParam) then
		return yearParam
	end
	-- myDecade = the year, with the last digit stripped
	--            e.g. "1694" → "1690"
	--            Note that a decade is written as usul=ally written "YYY0s"
	local myDecade = mw.ustring.gsub(yearParam, "%d$", "")
	return checkDecade(myDecade)
end

-- check for the existence of a portal with the name of that decade
-- if it exists, returns the year
-- otherwise calls decadeCheck, and returns that result
-- otherwise returns nil
function checkDecade(decadeParam)
	local mydecade = decadeParam .. "0s"
	if doesPortalExist(mydecade) then
		return mydecade
	end
	-- We don't have a portal for the decade, so now try the century.
	local myCenturyString = mw.ustring.gsub(decadeParam, "%d$", "")
	local myCenturyNum = tonumber(myCenturyString)
	local myCenturyNum = tonumber(myCenturyString)
	-- increment by one, because we have now conveted e.g. "1870s" to "18"
	-- but that's the 19th century
	myCenturyNum = myCenturyNum + 1
	return checkCentury(tostring(myCenturyNum))
end

-- check for the existence of a portal with the name of that century
-- if it exists, returns the century
-- otherwise returns an empty string
function checkCentury(centuryParam)
	local myCenturyString = ordinal_numbers(centuryParam) .. " century"
	if doesPortalExist(myCenturyString) then
		return myCenturyString
	end
	return ""
end


-- converts a string number to an string ordinal
-- e.g. 21 → 21st
--      17 → 17th
-- code copied from https://stackoverflow.com/questions/20694133/how-to-to-add-th-or-rd-to-the-date (license:CC BY-SA 3.0 )
function ordinal_numbers(n)
  local ordinal, digit = {"st", "nd", "rd"}, string.sub(n, -1)
  if tonumber(digit) > 0 and tonumber(digit) <= 3 and string.sub(n,-2) ~= 11 and string.sub(n,-2) ~= 12 and string.sub(n,-2) ~= 13 then
    return n .. ordinal[tonumber(digit)]
  else
    return n .. "th"
  end
end

function trim(s)
   return s:match "^%s*(.-)%s*$"
end

function p.findydcportal(frame)
	-- Expects one parameter
	-- {{{1}}} = a 3- or 4-digit year or deacde
	--    e.g. 1916
	--         1504
	--         1630s
	--         920s
	local arg1 = frame.args[1]
	if arg1 == nil then
		return ""
	end
	arg1 = trim(arg1) -- strip leading and trailing spaces
	if (mw.ustring.match(arg1, "^%d%d%d%d?$")) then
		-- it's a 3- or 4-digit-year
		return checkYear(arg1)
	elseif (mw.ustring.match(arg1, "^%d%d%d?0s$")) then
		-- it's a 3- or 4-digit decade
		-- so strip the trailing "0s"
		local decadeArg = mw.ustring.gsub(arg1, "0s$", "")
		return checkDecade(decadeArg)
	end
	-- If we get here, then arg1 was neither a year nor a decade
	-- This is going to be a helper template, and diagnostics woud be intrusive
	-- So just return an empty string
	return ""
end

return p