Module:Cite RSI

From IxWiki
Revision as of 10:51, 10 June 2023 by sc>Alistair3149 (Allow unnamed parameter)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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

local p = {}
local args

--- Helper function checking if a substring is in a string
--
-- @param needle string - Value to search for
-- @param haystack string - String to search in
--
-- @return bool - True if found
local function stringContains( needle, haystack )
    return string.find( mw.ustring.lower( haystack ), needle, 1, true )
end

-- This is from Module:String2
-- FIXME: Figure out how to call in from Lua properly
local function titlecase( text )
	local alwayslower = {['a'] = 1, ['an'] = 1, ['the'] = 1,
	['and'] = 1, ['but'] = 1, ['or'] = 1, ['for'] = 1,
	['nor'] = 1, ['on'] = 1, ['in'] = 1, ['at'] = 1, ['to'] = 1,
	['from'] = 1, ['by'] = 1, ['of'] = 1, ['up'] = 1 }
	local res = ''
	local s =  mw.text.trim( text or "" )
	local words = mw.text.split( s, " ")
	for i, s in ipairs(words) do
		-- {{lc:}} is strip-marker safe, string.lower is not.
		s = mw.getCurrentFrame():callParserFunction('lc', s)
		if i == 1 or alwayslower[s] ~= 1 then
			s = mw.getContentLanguage():ucfirst(s)
		end
		words[i] = s
	end
	return table.concat(words, " ")
end

--- Remove hyphen and format string into title case
--
-- @param title string
--
-- @return string
local function formatTitle( title )
	if title == nil or title == '' then return title end

	-- Replace hyphens with space
	title = string.gsub( title, '-', ' ' )
	-- Format into title case
	title = titlecase( title )

	return title
end

-- @param url string
--
-- @return string
local function sanitizeURL( url )
	local santizedURL

	if stringContains('robertsspaceindustries.com', url) then
		-- Remove 'www.' from the link
		santizedURL = mw.ustring.gsub( url, 'www%.', '' )
	else
		-- Add "https://robertsspaceindustries.com/" to url if it is not present
		santizedURL = 'https://robertsspaceindustries.com/' .. url
	end

	return santizedURL
end

--- Determine which type of RSI website it is
--
-- @param url string - RSI website URL
--
-- @return string - Site type or nil if unknown
local function getType( url )
	local type

	if stringContains( '/comm-link/', url ) then
		type = 'Comm-Link'
    elseif stringContains( '/galactapedia/', url ) then
		type = 'Galactapedia'
    elseif stringContains( '/spectrum/', url ) then
		type = 'Spectrum'
    elseif stringContains( '/pledge/', url ) then
		type = 'Pledge Store'
    elseif stringContains( '/starmap', url ) then
		type = 'Starmap'
    elseif stringContains( '/issue-council', url ) then
		type = 'Issue Council'
	elseif stringContains( 'support.robertsspaceindustries', url ) then
		type = 'Knowledge Base'
    else
        type = nil
	end

	return type
end

local function getSubtype( url, type )
	local subtype = nil
	if type == 'Comm-Link' then
		subtype = string.match( url, '/comm%-link/([%w-]+)/%d+-[%w-]+' )
	end

	return formatTitle( subtype )
end

local function getTitle( url, type )
	local titleText
	local throwError = function()
		return error( 'Title can not be generated, please fill in the text parameter.' )
	end

	-- Auto title generation, might not be accurate since special characters
	-- are escaped in the URL
	--
	-- e.g. /comm-link/transmission/14710-Starfarer-Q-A-Part-1
	if type == 'Comm-Link' then
		titleText = string.match( url, '/comm%-link/[%w-]+/%d+-([%w-]+)' )
	-- e.g. /article/0j46Lzl8xm-torral-aggregate
	elseif type == 'Galactapedia' then
		titleText = 'Galactapedia: ' .. string.match( url, '/article/%w+-([%w-]+)' )
	-- NOTE: Only support threads at the moment
	-- e.g. /thread/star-citizen-alpha-3-13-0-live-7319707-patch-notes
	elseif type == 'Spectrum' then
		titleText = string.match( url, '/thread/%w+-([%w-]+)' )
	-- e.g. /hc/en-us/categories/360000295274-Updates-and-Info
	elseif type == 'Knowledge Base' then
		titleText = string.match( url, '/hc/.+/.+/%d+-([%w-]+)' )
	-- Will still try its best to extact a title
	else
		local urlParts = mw.text.split(url, '[/]')
		titleText = urlParts[ #urlParts ]
	end

	return formatTitle( titleText )
end

-- NOTE: Don't have internal link support yet
function p.main( frame )
	if args == nil then
        args = require( 'Module:Arguments' ).getArgs( frame )
	end

	local url = sanitizeURL( args.url or args[1] )
	local type = getType( url )
	local date = args.accessdate
	local title
	local output
	
	if args.text then
		title = args.text
	else
		title = getTitle( url, type )
	end
	
	-- Maybe there is a smarter way?
	-- This needs to be redone with mw.html
	output = '<cite class="citation rsi_site">' ..
		'<span class="metadata citation-icon" title="RSI site">[[File:RSIsite.svg|x11px|link=]]</span>' ..
		'[' .. url .. ' ' .. title .. ']'
	
	if type then
		local subtype = getSubtype( url, type )
		
		output = output .. '. '
		if subtype then
			output = output .. '<i>' .. subtype .. '</i> - '
		end
		output = output .. '<i>' .. type .. '</i>' 
	end
	
	if date then
		output = output .. '. Retrieved ' .. date
	end
	
	output = output .. '</cite>'

	return mw.getCurrentFrame():extensionTag{
		name = 'templatestyles', args = { src = 'Module:Cite/styles.css' }
	} .. output
end
return p