Module:References

From Brighter Shores Wiki
Jump to navigation Jump to search

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

--               Master module implementing reference templates               --

local onmain = require('Module:Mainonly').on_main
local paramtest = require('Module:Paramtest')
local hc = paramtest.has_content
local dt = paramtest.default_to
local yn = require('Module:Yesno')
local lang = mw.getContentLanguage()

local p = {} --all template entrance points here
local r = {} --reference formatters here to not expose them to #invoke, and to not clutter p

local lostReferenceMsg = '<sup class="noprint fact">&#91;<span class="fact-text"title="The page referenced can no longer be accessed. Please try to find an archived version of it or another reference for this statement if possible.">Lost reference</span>&#93;</sup>'

function string.starts(String, Start)
	return string.sub(String, 1, string.len(Start)) == Start
end

-- for consistent date formats - cons: can't link dates
local function formatDate(datep)
	local datetbl = {}
	datetbl.day = lang:formatDate('j', datep)
	datetbl.month = lang:formatDate('F', datep)
	datetbl.year = lang:formatDate('Y', datep)
	return lang:formatDate('j F Y', datep), datetbl
end

-- create the ref tag to be returned
local function reftag(frame, reftype, forcedArgs)
	local args = frame:getParent().args
	local s = ''
	local opts = {}
	
	if forcedArgs ~= nil then
		for k, v in pairs(forcedArgs) do
			args[k] = v
		end
	end
	
	if hc(args.name) then
		opts.name = args.name
	end
	if hc(args.group) then
		opts.group = args.group
	end
	
	local ref, cat = r[reftype](args)
	
	return frame:extensionTag{name = 'ref', content = mw.text.tag('span', {['class']= 'citation ' .. reftype }, ref .. cat), args = opts}
end

local function plainref(frame, reftype, forcedArgs)
	local args = frame:getParent().args
	
	if forcedArgs ~= nil then
		for k, v in pairs(forcedArgs) do
			args[k] = v
		end
	end
	
	local ref, cat = r[reftype](args)
	
	return mw.text.tag('span', {['class']= 'citation ' .. reftype }, ref .. cat)
end

------------ Helper Templates -----------------

--[==[
[[Template:NamedRef]]
--]==]
function p.namedref(frame)
	local args = frame:getParent().args
	local opts = {}
	opts.name = args.name or args[1]
	if hc(args.group) then
		opts.group = args.group
	elseif hc(args[2]) then
		opts.group = args[2]
	end
	
	return frame:extensionTag{name = 'ref', args = opts}
end


--[==[
[[Template:Reflist]]
--]==]
function p.reflist(frame)
	local args = frame:getParent().args
	local div = mw.html.create('div')
	local resp = 1
	
	if hc(args[1]) or hc(args.colwidth) then
		div:css({ ['column-width'] = args[1] or args.colwidth })
		resp = 0
	end
	
	div
		:addClass('reflist')
		:wikitext(frame:extensionTag{name = 'references', args = {group = args.group, responsive = resp}})
	
	-- Implement {{Notelist}}
	if args.group == 'lower-alpha' then
		div:addClass('reflist-lower-alpha')
	end
	
	if not yn(args.quotes) then
		div:addClass('hideQuotes')
	end
	
	return div
end


------------ General Citation Templates -----------------


--[==[
[[Template:CitePub]] and [[Template:PlainCitePub]]
--]==]
function p.pubref(frame)
	return reftag(frame, 'pub')
end

function p.pubplain(frame)
	return plainref(frame, 'pub')
end

function r.pub(a)
	local ref = ''
	local c = ''
	
	if hc(a.author) then
		ref = a.author .. '. '
	end
	
	local str = ''
	if hc(a.title) then
		ref = ref .. "''" .. a.title .. "''"
		if hc(a.pages) then
			ref = ref .. ', (' .. a.pages .. ')'
		end
		ref = ref .. '. '
	end
	if hc(a.publisher) then
		ref = ref .. a.publisher
		if hc(a.pubyear) then
			ref = ref .. ', ' .. a.pubyear
		end
		ref = ref .. '. '
	elseif hc(a.pubyear) then
		ref = ref .. a.pubyear .. '. '
	end
	ref = ref .. (a.notes or '')
	
	if onmain() and not (hc(a.title) and hc(a.publisher) and hc(a.pubyear)) then
		c = c .. '[[Category:Incomplete references]]'
	end
	return ref, c
end


--[==[
[[Template:CiteTwitter]] and [[Template:PlainCiteTwitter]]
--]==]
function p.twitterref(frame)
	return reftag(frame, 'twitter')
end

function p.twitterplain(frame)
	return plainref(frame, 'twitter')
end

function r.twitter(a)
	local ref
	local c = ''
	ref = 'Fen Research. '
	
	if hc(a.url) or hc(a.archiveurl) then --url, if present makes a link
		if hc(a.archiveurl) then
			ref = ref .. '[' .. a.archiveurl
		elseif hc(a.url) then
			ref = ref .. '[' .. a.url
		end
		if hc(a.author) then
			ref = ref .. ' ' .. a.author .. "'s Twitter account"--if title not present leave as link
		end
		ref = ref .. ']. '
	elseif hc(a.author) then
		ref = ref .. ' ' .. a.author .. "'s Twitter account. "
	end
	
	if hc(a.date) then
		a.date = formatDate(a.date)
		ref = ref .. a.date .. '. '
	end
	
	if hc(a.archivedate) then
		a.archivedate = formatDate(a.archivedate)
		ref = ref .. ' Archived from [' .. a.url .. ' the original] on ' .. a.archivedate .. '. '
	end
	
	if hc(a.quote) then
		if hc(a.author) then
			ref = ref .. a.author .. ': '
		end
		ref = ref .. '"' .. a.quote .. '" '
	end
	ref = ref .. (a.notes or '')
	if hc(a.lost) then
		ref = ref .. lostReferenceMsg
	end
	
	local err = ''
	if not (hc(a.url) and hc(a.author) and hc(a.date)) then
		err = err .. "Error calling CiteTwitter: parameters '''url''', '''author''', '''quote''', and '''date''' must be specified.<br>"
	end
	
	if hc(a.archiveurl) ~= hc(a.archivedate) then --xor
		err = err .. "Error calling CiteTwitter: parameters '''archiveurl''' and '''archivedate''' must both be specified or both be unspecified.<br>"
	end
	
	
	if onmain() and err ~= '' then
		c = c .. '[[Category:Incomplete references]]'
	end
	
	if onmain() and not hc(a.archiveurl) then
		if hc(a.lost) then
			c = c .. '[[Category:Lost Twitter references]]'
		else
			c = c .. '[[Category:Unarchived Twitter references]]'
		end
	end
	
	return ref, c
end

--[==[
[[Template:CiteVideo]] and [[Template:PlainCiteVideo]]
--]==]
function p.videoref(frame)
	return reftag(frame, 'video')
end

function p.videoplain(frame)
	return plainref(frame, 'video')
end

function r.video(a)
	local ref
	local c = ''
	if hc(a.author) then
		ref = a.author .. '. '
	end
	if hc(a.url) then --url, if present makes a link
		if string.lower(a.site) == 'youtube' then
			if string.starts(a.url, 'https://www.youtube.com/watch?v=') then
				ref = ref .. '[' .. a.url
			else
				ref = ref .. '[https://www.youtube.com/watch?v=' .. a.url
			end
		elseif string.lower(a.site) == 'twitch' then
			if string.starts(a.url, 'https://www.twitch.tv/videos/') then
				ref = ref .. '[' .. a.url
			elseif string.starts(a.url, 'https://clips.twitch.tv/') then
				ref = ref .. '[' .. a.url
			else
				ref = ref .. '[https://www.twitch.tv/videos/' .. a.url
			end
		else
			ref = ref .. '[' .. a.url
		end
		if hc(a.title) then
			ref = ref .. ' "' .. a.title .. '"'--if title not present leave as link
		end
		ref = ref .. '] '
	else
		if hc(a.title) then
			ref = ref .. '"' .. a.title .. '" '
		end
	end
	
	if hc(a.timestamp) then
		ref = ref .. '(in ' .. a.timestamp .. '). '
	else
		ref = ref .. '. '
	end
	
	ref = ref .. dt(a.site, 'YouTube') .. ' video. '
	
	if hc(a.date) then
		a.date = formatDate(a.date)
		ref = ref .. a.date .. '. '
	end
	ref = ref .. (a.notes or '')
	
	if onmain() then
		if not (hc(a.author) and hc(a.url) and hc(a.title) and hc(a.date)) then
			c = c .. '[[Category:Incomplete references]]'
		end
	end
	return ref, c
end

--[==[
[[Template:CiteGeneral]] and [[Template:PlainCiteGeneral]]
--]==]
function p.generalref(frame)
	return reftag(frame, 'general')
end

function p.generalplain(frame)
	return plainref(frame, 'general')
end

function r.general(a)
	local ref = ''
	local c = ''
	local str = ''
	
	if hc(a.author) or hc(a.last) then
		if hc(a.last) then
			str = a.last
			if hc(a.first) then
				str = str .. ', ' .. a.first
			end
		else
			str = a.author
		end
		
		if hc(a.authorlink) then
			ref = ref .. '[' .. a.authorlink
			if str ~= '' then
				ref = ref .. ' ' .. str
			end
			ref = ref .. ']'
		else
			ref = ref .. str
		end
		
		if hc(a.coauthors) then
			ref = ref .. '; ' .. a.coauthors
		end
		
		ref = ref .. '. '
	end
	
	if hc(a.title) then
		if hc(a.archiveurl) then
			ref = ref .. '[' .. a.archiveurl .. ' ' .. a.title .. ']'
		elseif hc(a.url) then
			ref = ref .. '[' .. a.url .. ' ' .. a.title .. ']'
		end
	end
	
	if hc(a.format) then
		ref = ref .. ' (' .. a.format .. ')'
	end
	
	if hc(a.language) then
		ref = ref .. ' (in ' .. a.language .. ')'
	end
	
	if hc(a.work) then
		ref = ref .. ". ''" .. a.work .. "''"
	end
	
	if hc(a.pages) then
		ref = ref .. ' pp. ' .. a.pages
	end
	
	if hc(a.publisher) then
		ref = ref .. '. ' .. a.publisher
	end
	
	if hc(a.date) then
		a.date = formatDate(a.date)
		ref = ref .. '. ' .. a.date
	elseif hc(a.year) then
		if hc(a.month) then
			ref = ref .. '. ' .. a.month .. ' ' .. a.year
		else
			ref = ref .. '. ' .. a.year
		end
	end
	
	if ref ~= '' then
		ref = ref .. '.'
	end
	
	if hc(a.archivedate) then
		a.archivedate = formatDate(a.archivedate)
		ref = ref .. ' Archived from [' .. a.url .. ' the original] on ' .. a.archivedate .. '.'
	end
	
	if hc(a.quote) then
		ref = ref .. ' "' .. a.quote .. '"'
	end
	
	if hc(a.notes) then
		ref = ref .. ' ' .. a.notes
	end
	if hc(a.lost) then
		ref = ref .. lostReferenceMsg
	end
	
	local err = ''
	if not (hc(a.url) and hc(a.title)) then
		err = err .. "Error calling CiteGeneral: parameters '''url''' and '''title''' must be specified.<br>"
	end
	if hc(a.archiveurl) ~= hc(a.archivedate) then --xor
		err = err .. "Error calling CiteGeneral: parameters '''archiveurl''' and '''archivedate''' must both be specified or both be unspecified.<br>"
	end
	if not (hc(a.archiveurl) and hc(a.archivedate)) then
		ref = err .. ref .. mw.getCurrentFrame():expandTemplate{title = 'RefDate', args = { (a.accessdate or ''), '180'} }
	end
	
	if onmain() and err ~= '' then
		c = c .. '[[Category:Incomplete references]]'
	end
	--[==[ are these needed?
	if onmain() and not hc(a.archiveurl) then
		if hc(a.lost) then
			c = c .. '[[Category:Lost web references]]'
		else
			c = c .. '[[Category:Unarchived web references]]'
		end
	end
	]==]--
	return ref, c
end

--[==[
[[Template:CiteReddit]] and [[Template:PlainCiteReddit]]
--]==]
function p.redditref(frame)
	return reftag(frame, 'reddit')
end

function p.redditplain(frame)
	return plainref(frame, 'reddit')
end

function r.reddit(a)
	local ref, c = '', ''
	
	ref = dt(a.author, 'Fen Research') --author, defaults to Fen Research
	ref = ref .. '. '
	
	if hc(a.url) or hc(a.archiveurl) then --url, if present makes a link
		if hc(a.archiveurl) then
			ref = ref .. '[' .. a.archiveurl
		elseif hc(a.url) then
			ref = ref .. '[' .. a.url
		end
		if hc(a.title) then
			ref = ref .. ' "' .. a.title
		end
		ref = ref .. '"]. '
	end
	ref = ref .. "''Reddit''. "
	if hc(a.date) then
		a.date = formatDate(a.date)
		ref = ref .. a.date .. '. '
	end
	
	if hc(a.archivedate) then
		a.archivedate = formatDate(a.archivedate)
		ref = ref .. ' Archived from [' .. a.url .. ' the original] on ' .. a.archivedate .. '. '
	end
	
	if hc(a.quote) then
		if hc(a.author) then
			ref = ref .. a.author .. ': '
		end
		ref = ref .. '"' .. a.quote .. '" '
	end
	ref = ref .. (a.notes or '')
	if hc(a.lost) then
		ref = ref .. lostReferenceMsg
	end
	
	local err = ''
	if not (hc(a.url) and hc(a.author) and hc(a.quote) and hc(a.date) and hc(a.title)) then
		err = err .. "Error calling CiteReddit: parameters '''url''', '''author''', '''quote''', and '''date''', and '''title''' must be specified.<br />"
	end
	
	if hc(a.archiveurl) ~= hc(a.archivedate) then --xor
		err = err .. "Error calling CiteReddit: parameters '''archiveurl''' and '''archivedate''' must both be specified or both be unspecified.<br />"
	end
	
	if onmain() and err ~= '' then
		c = c .. '[[Category:Incomplete references]]'
	end
	
	if onmain() and not hc(a.archiveurl) then
		c = c .. '[[Category:Unarchived Reddit references]]'
	end
	
	return ref, c
end

return p