WARFRAME Wiki
WARFRAME Wiki
WARFRAME Wiki
Official wiki
9,067
pages


Reference is used to create citations in Wikipedia's Citation Style 1 format. Code forked from dev.fandom.com https://dev.fandom.com/wiki/Global_Lua_Modules/Ref

Usage

Direct Invocation

{{#invoke:Reference|main}}

Template

In template: {{#invoke:Reference|main}}
In articles: {{Ref|param1=arg1|param2=arg2|...}}

See https://dev.fandom.com/wiki/Global_Lua_Modules/Ref#Parameters for full documentation.

Documentation


Created with Docbunto

See Also

Code


---	'''Reference''' is used to create citations in
--	[[wikipedia:Help:Citation_Style_1|Wikipedia's Citation Style 1]] format.
--	Code forked from dev.fandom.com https://dev.fandom.com/wiki/Global_Lua_Modules/Ref
--	
--	@module		reference
--	@alias		ref
--	@require	[[Module:Arguments]]
--	@author		[[User:Jak Himself]]
--	@author		[[User:Technobliterator]]
--	@release	stable
--	<nowiki>

local ref = {}
local getArgs = require('Module:Arguments').getArgs
local Lang = mw.language.getContentLanguage()

--sourcedata used for autofill functions
ref.sourcedata = {}

--[[--------------------------< A U T O F I L L  D A T A >-------------------------------------------------

looks for a module containing data that autofills a reference, aby finding its entry on a table using a shorthand

for example, "|game=FFVII" to autofill a reference for "Final Fantasy VII" based on a module containing as much

]]
--helper function for all to allow for recursion
local function recover(data, default_source, alternate_source, category, new, author_type)
	local target = new or category
	
	--use the currently selected version by default; if it has nothing, use the base case
	local source = default_source[category] or alternate_source[category]
	
	--if the data is an author table, split to first[n]= and last[n]=
	if type(source) == 'table' then
		if target == 'author' and author_type ~= 'developer' then
			if type(source[1]) == 'table' then
				for i, y in ipairs(source) do
					data['first' .. i] = source[i][1]
					data['last' .. i] = source[i][2]
				end
				if (author_type) then
					data['author-type'] = author_type
				end
			else
				data.first = source[1]
				data.last = source[2]
				if (author_type) then
					data['author-type'] = author_type
				end
			end
		else
			--if it is a table, split to target[n]
			for i, y in ipairs(source) do
				data[target .. i] = y
			end
		end
	else
		--if no table was found, assign as desired
		data[target] = source
	end
end

local function game_ref(data, game, game_version)
	recover(data, game_version, game, 'developer', 'author', 'developer')
	recover(data, game_version, game, 'year')
	recover(data, game_version, game, 'month')
	recover(data, game_version, game, 'day')
	data['link'] = game_version['link'] or game['link']
	data['title'] = game_version['title'] or game['title']
	data['media'] = 'game'
	data['publisher']  = game_version['publisher'] or game['publisher']
	recover(data, game_version, game, 'platform')
end

--Automatically creates a reference for movies based on shorthand data module
local function movie_ref(data, movie, movie_version)
	recover(data, movie_version, movie, 'director', 'author')
	data['author-type'] = 'Director'
	recover(data, movie_version, movie, 'year')
	recover(data, movie_version, movie, 'month')
	recover(data, movie_version, movie, 'day')
	data['link'] = movie['link']
	data['title'] = movie['title']
	data['title'] = movie_version['title'] or movie['title']
	data['media'] = 'film'
	data['publisher'] = movie_version['studio'] or movie['studio']
end

--Automatically creates a reference for series based on shorthand data module
local function series_ref(data, series)
	recover(data, series, series, 'executive', 'author', 'Executive Producer')
	recover(data, series, series, 'year')
	data['link'] = series['link']
	data['title'] = series['title']
	data['media'] = 'series'
	data['publisher'] = series['studio']
end

--Automatically creates a reference for episode based on shorthand data module
local function episode_ref(data, episode, series)
	recover(data, episode, episode, 'writer', 'author', 'Writer')
	recover(data, episode, episode, 'director', 'author', 'Director')
	recover(data, episode, episode, 'writerdirector', 'author', 'Writer & Director')
	recover(data, episode, episode, 'year')
	data['entry-link'] = episode['link']
	data['entry'] = episode['title']
	data['link'] = series['link']
	data['title'] = series['title']
	data['media'] = 'episode'
	data['publisher'] = episode['studio']
end

--Automatically creates a reference for books or manga based on shorthand data module
--Can also be used with a guide or design bible for a game
local function book_ref(data, book)
	recover(data, book, book, 'author')
	recover(data, book, book, 'year')
	recover(data, book, book, 'month')
	recover(data, book, book, 'day')
	data['link'] = book['link']
	data['title'] = book['title']
	data['media'] = 'book'
	data['additional-authors'] = book['additional-authors']
	data['publisher'] = book['publisher']
	data['isbn'] = book['isbn']
end

--Automatically creates a reference for an album based on shorthand data module
local function album_ref(data, album, album_version)
	recover(data, album_version, album, 'artist', 'author')
	recover(data, album_version, album, 'year')
	recover(data, album_version, album, 'month')
	recover(data, album_version, album, 'day')
	data['link'] = album['link']
	data['title'] = album['title']
	data['title'] = album_version['title'] or album['title']
	data['media'] = 'album'
	data['publisher'] = album_version['label']
end

--Automatically creates a reference for an album based on shorthand data module
local function song_ref(data, song, song_version)
	recover(data, song_version, song, 'artist', 'author')
	recover(data, song_version, song, 'year')
	recover(data, song_version, song, 'month')
	recover(data, song_version, song, 'day')
	data['entry-link'] = song['link']
	data['entry'] = song_version['title'] or song['title']
	data['title'] = song_version['album'] or song['album']
	data['additional-authors'] = song_version['featured']
	data['media'] = 'song'
	data['publisher'] = song_version['label']
end

--[[--------------------------< H E L P E R  F U N C T I O N S >-------------------------------------------------

helper functions for parts of the reference, applies to all formats

]]
--Assistant to generate the id
local function make_id(data)
	local id = ''
	if data['id'] then
		id = data['id']
	else
		--first half of concatenated id, either author or publisher
		local authorid = ''
		if data['last'] then authorid = data['last']
		elseif data['last1'] then
			for n = 1, 10, 1 do
				if data['last' .. n] then
					authorid = authorid .. data['last' .. n]
				end
			end
		elseif data['author'] or data['author1'] or data['publisher'] then
			if data['author'] then
				authorid = data['author']
			elseif data['author1'] then
				authorid = data['author1']
			elseif data['publisher'] then
				authorid = data['publisher']
			end
			
			authorid = authorid:gsub('%[%[(.-)%]%]', '')
			authorid = authorid:gsub('%s+', '')
			authorid = authorid:match("%|(.*)") or authorid
		end
		
		--last half of concatenated id, either year or nothing
		year = ''
		if data['year'] then
			year = data['year']
		elseif data['year1'] then
			year = data['year1']
		end
		
		id = string.format('%s%s', authorid, year)
	end
	
	return id
end

--Assistant for dates
local function format_dates(data)
	local dates = ''
	
	--up to 10 dates
	for n = 0, 10, 1 do
		local m
		if n == 0 then m = '' else m = n end
		local to_append = ''
		
		--different output depending on chosen date format; defaults to just the year
		if data['month'..m] and data['showmonth'] then
			to_append = Lang:formatDate('Y, F', data['year'..m] .. '-' .. data['month'..m])
		elseif data['day'..m] and data['showfulldate'] then
			to_append = Lang:formatDate('Y, F j', data['year'..m] .. '-' .. data['month'..m] .. '-' .. data['day'..m])
		elseif data['dateformat'] then
			to_append = Lang:formatDate(data['dateformat'], data['year'..m] .. '-' .. data['month'..m] .. '-' .. data['day'..m])
		else
			to_append = data['year'..m] or ''
		end
		
		if not (dates == '') and not (to_append == '') then dates = dates .. '; ' end
		dates = dates .. to_append
	end
	
	return dates
end

--Assistant for author section
local function format_authors(data)
	local authors = ''
	--up to 10 authors
	for n = 0, 10, 1 do
		local m
		if n == 0 then m = '' else m = n end
		local to_append = ''
		local separator = ','

		--either the first/last name of a person author, or name of the authoring group/organization
		if data['last'..m] then
			to_append = string.format('%s, %s', data['last'..m], data['first'..m])
			separator = ';'
			if data['author-link'..m] then
				to_append = string.format('[[%s|%s]]', data['author-link'..m], to_append)
			end
		elseif data['author'..m] then
			to_append = data['author'..m]
		end
			
		--the type of each author, if applicable; if all authors are the same type, 'author-type' applies
		if n > 0 and data['author-type'..m] then
			to_append = to_append .. ' (' .. (data['author-type'..m]:gsub('^%l', string.upper)) .. ')'
		end
		
		if not (authors == '') and not (to_append == '') then authors = authors .. separator .. ' ' end
		authors = authors .. to_append
	end
	
	--if referencing a tweet, add handle; a tweet can only have one author	
	if data['author-id'] and data['tweet-id'] then
		authors = authors .. string.format(
			' \[[https://www.twitter.com/%s @%s]\]',
			data['author-id'], data['author-id'])
	end
	
	--if referencing youtube, add channel name; applies to all authors 
	if data['channel-id'] and data['channel'] and data['youtube-id'] then
		authors = authors .. string.format(
			' \[[https://www.youtube.com/channel/%s %s]\]',
			data['channel-id'], data['channel'])
	end
	
	--if referencing instagram, add account name; applies to all authors 
	if data['author-id'] and data['instagram-id'] then
		authors = authors .. string.format(
			' \[[https://www.instagram.com/%s %s]\]',
			data['author-id'], data['author-id'])
	end
	
	--the type of all authors, if applicable; should not be used if individual 'author-typen' are set
	if data['author-type'] then
		authors = authors .. string.format(' (%s)', data['author-type'])
	end
	
	return authors
end

--Assistant for url links section; formats either entry or title to be a link
local function format_url(data, to_format)
	if data['archive-url'] and data['brokenlink'] then
		to_format = string.format('[%s %s]', data['archive-url'], to_format)
	elseif data['url'] then
		to_format = string.format('[%s %s]', data['url'], to_format)
	elseif data['youtube-id'] then
		to_format = string.format('[https://www.youtube.com/watch?v=%s %s]', data['youtube-id'], to_format)
	elseif data['tweet-id'] then
		to_format = string.format('[https://twitter.com/%s/status/%s %s]', data['author-id'], data['tweet-id'], to_format)
	elseif data['instagram-id'] then
		to_format = string.format('[https://instagram.com/p/%s %s]', data['instagram-id'], data['instagram-id'], to_format)
	end
	
	return to_format
end
	
--Assistant for title section
local function format_title(data)
	local title = assert(data['title'], 'Title is mandatory')
	-- Converting tokens to HTML entities so they don't render as wikitext
	title = mw.text.nowiki(title)
	
	if data['link'] then
		title = string.format("[[%s|%s]]", data['link'], title)
	elseif not data['entry'] and data['url'] then
		title = format_url(data, title)
	elseif data['youtube-id'] then
		title = string.format('[https://www.youtube.com/watch?v=%s %s]', data['youtube-id'], title)
	elseif data['tweet-id'] then
		title = string.format('[https://twitter.com/%s/status/%s %s]', data['author-id'], data['tweet-id'], title)
	elseif data['instagram-id'] then
		title = string.format('[https://www.instagram.com/p/%s %s]', data['instagram-id'], title)
	end
	
 	if not data['noitalictitle'] then
 		title = string.format("''%s''", title)
 	else
 		title = string.format('"%s"', title)
	end
	
	return title
end

--Assistant for url archives links
local function format_archive(url, accessdate, archiveurl, archivedate)
	local link = ''
	if archiveurl then
		link = archiveurl
	else
		link = string.format('https://web.archive.org/web/%s', url)
	end
	
	if archivedate then
		return string.format('Accessed %s. [%s Archived] from the original on %s. ', accessdate, link, archivedate)
	else
		return string.format('[%s Archived] from the original on %s. ', link, accessdate)
	end
end

--Assistant for additional content on the end of a reference
local function additional_content(data)
	local additional = {}
	
	if data['publisher'] then
		table.insert(additional, string.format(' %s. ', data['publisher']))
	end
	
	if data['additional-authors'] then
		table.insert(additional, string.format('%s. ', (data['additional-authors'])))
	end
	
	if data['youtube-id'] then
		table.insert(additional, '[[wikipedia:YouTube|YouTube]]. ')
	elseif data['tweet-id'] then
		table.insert(additional, '[[wikipedia:Twitter|Twitter]]. ')
	elseif data['instagram-id'] then
		table.insert(additional, '[[wikipedia:Instagram|Instagram]]. ')
	elseif data['platform'] then
		table.insert(additional, string.format(' %s. ', data['platform']))
	end

	if data['isbn'] then
		table.insert(additional, string.format('[[wikipedia:ISBN|ISBN]] [[Special:Booksources/%s|%s]]. ', (data['isbn']), (data['isbn'])))
	end
	
	if data['url'] and not data['broken-link'] then
		table.insert(additional, format_archive(data['url'], assert(data['access-date'], 'Access dates are required for website references'), data['archive-url'], data['archive-date']))
	elseif data['broken-link'] then
		table.insert(additional, string.format('Archived from the [%s original] on %s. ', data['url'], assert(data['access-date'], 'Access dates are required for website references') or data['archive-date']))
	end
	
	if data['extra'] then
		table.insert(additional, ' ' .. data['extra'] .. '.')
	end
	
	return table.concat(additional, '')
end

--[[--------------------------< C O N S T R U C T O R  F U N C T I O N S >-------------------------------------------------

fuctions to construct the full reference

(note: only constructs Wikipedia CS1 ref at this stage)

]]

--constructs reference, in standard style similar to Wikipedia's CS1.
local function construct_wiki_ref(data)
	local refcontent = ''
	
	--if author and date, print Author (Date)
	--n.d. if no date, no author if no author found
	has_author = (data['last1'] or data['last'] or data['author1'] or data['author'])
	if has_author then
		refcontent = format_authors(data) .. ' '
	end
	has_date = (data['year1'] or data['year'])
	if has_date then
		refcontent = refcontent .. string.format('(%s). ', format_dates(data))
	else
		refcontent = refcontent .. '(n.d.) . '
	end
	
	--if pointing to a location in a source, Location in Title
	if data['location'] then
		refcontent = refcontent .. string.format('"%s" in ', data['location'])
	end
	
	--if the media type is included, add this either after title or entry name
	local media = ''
	if data['media'] then
		--first letter of the media type is capitalized
		media = string.format(' [%s]', data['media']:gsub("^%l", string.upper))
	end
	
	--if pointing to an entry of a work, "Entry" before Title
	if data['entry'] then
		local entry = data['entry']
		if data['entry-link'] then
			entry = string.format('[[%s|%s]]', data['entry-link'], data['entry'])
		elseif data['url'] then
			entry = format_url(data, entry)
		end
		refcontent = refcontent .. string.format('"%s"', entry)
		if data['season'] or data['number'] then
			refcontent = refcontent .. ' (' 
			if data['season'] then
				refcontent = refcontent .. data['season']
			end
			if data['season'] and data['number'] then
				refcontent = refcontent .. ', '
			end
			if data['number'] then
				refcontent = refcontent .. data['number']
			end
			refcontent = refcontent .. ') '
		end
		if data['media'] then 
			refcontent = refcontent .. media
		end
		refcontent = refcontent .. '. From '
	end
	
	--Title is mandatory
	refcontent = refcontent .. format_title(data)
	
	--if media type here, append title
	if data['media'] and not data['entry'] then 
		refcontent = refcontent .. media
	end
	--if volume or issue no., append title
	if data['volume'] or data['issue'] then
		refcontent = refcontent .. ' (' 
		if data['volume'] then
			refcontent = refcontent .. data['volume']
		end
		if data['volume'] and data['issue'] then
			refcontent = refcontent .. ', '
		end
		if data['issue'] then
			refcontent = refcontent .. data['issue']
		end
		refcontent = refcontent .. ') '
	end
	--period after title either way
	refcontent = refcontent .. '. '
	
	--if pointing to a page number, add page number after Title
	if data['p'] or data['page'] then
		refcontent = refcontent .. string.format(' p. %s.', (data['p'] or data['page']))
	end
	
	--added additional fields to be appended at the end
	refcontent = refcontent .. string.format(' %s', additional_content(data))
	
	return refcontent
end

--[[--------------------------< M A I N  F U N C T I O N S >-------------------------------------------------

process parameter input to return reference

]]
--function to take argument inputs to pass to core functions
--parameter inputs override autogeeration
local function core_input(frame)
	--parameters/data
	local args = getArgs(frame)
	local data = {}
	
	if args['game'] then
		game = assert(ref.sourcedata[args['game']], 'Could not find an entry in shorthand data module matching this input')
		game_version = game
		if args['version'] then
			game_version = assert(game['versions'][args['version']], 'Could not find version matching this input')
		end
		game_ref(data, game, game_version)
	elseif args['movie'] then
		movie = assert(ref.sourcedata[args['movie']], 'Could not find an entry in shorthand data module matching this input')
		movie_version = movie
		if args['version'] then
			movie_version = assert(movie['versions'][args['version']], 'Could not find version matching this input')
		end
		movie_ref(data, movie, movie_version)
	elseif args['series'] then
		series = assert(ref.sourcedata[args['series']], 'Could not find an entry in shorthand data module matching this input')
		series_ref(data, series)
	elseif args['episode'] then
		episode = assert(ref.sourcedata[args['episode']], 'Could not find an entry in shorthand data module matching this input')
		series = ref.sourcedata[args['episode']]['series']
		series_ref(data, episode, series)
	elseif args['book'] then
		book = assert(ref.sourcedata[args['book']], 'Could not find an entry in shorthand data module matching this input')
		if args['version'] then
			book = assert(book['versions'][args['version']], 'Could not find version matching this input')
		end
		book_ref(data, book)
	elseif args['db'] then 
		game = assert(ref.sourcedata[args['db']], 'Could not find an entry in shorthand data module matching this input')
		db = assert(game['db'], 'Could not find a design bible for this game')
		if args['version'] then
			db = assert(db[args['version']], 'Could not find version matching this input')
		end
		book_ref(data, db)
	elseif args['guide'] then
		game = assert(ref.sourcedata[args['guide']], 'Could not find an entry in shorthand data module matching this input')
		guide = assert(game['guide'], 'Could not find a guide for this game')
		if args['version'] then
			guide = assert(guide[args['version']], 'Could not find version matching this input')
		end
		book_ref(data, guide)
	elseif args['album'] then
		album = assert(ref.sourcedata[args['album']], 'Could not find an entry in shorthand data module matching this input')
		album_version = album
		if args['version'] then
			album_version = assert(album['versions'][args['version']], 'Could not find version matching this input')
		end
		album_ref(data, album, album_version)
	elseif args['song'] then
		song = assert(ref.sourcedata[args['song']], 'Could not find an entry in shorthand data module matching this input')
		song_version = song
		if args['version'] then
			song_version = assert(song['versions'][args['version']], 'Could not find version matching this input')
		end
		song_ref(data, song, song_version)
	end

	--merge data and args, where args takes priority
	for k, v in pairs(args) do
		data[k] = v or data[k]
	end
	
	--automatic types for refs not auto-generated
	if data['url'] then
		data['showfulldate'] = true
	elseif data['youtube-id'] then
		data['media'] = 'video'
		data['showfulldate'] = true
	elseif data['tweet-id'] then
		data['media'] = 'tweet'
		data['showfulldate'] = true
	elseif data['instagram-id'] then
		data['media'] = 'instagram'
		data['showfulldate'] = true
	end
	
	local id = make_id(data)
	
	return data, id
end

--pass to this function to build reference
local function core_output(refcontent, id)
	refoutput = mw.html.create('span')
		:attr('id', id)
		:wikitext(refcontent)
	
	return refoutput
end

--returns reference in wiki-style format
function ref.wiki(frame)
	local data, id = core_input(frame)
	local refcontent = construct_wiki_ref(data)
	return core_output(refcontent, id)
end

--main function (defaults to wiki reference)
ref.main = ref.wiki

--when importing this module, fill sourcedata table from another given module or input
function ref.custom_sourcedata(...)
	local sourcedata = {...}
	for i,source in ipairs(sourcedata) do
		for k, val in pairs(source) do
			ref.sourcedata[k] = val
		end
	end
	return ref
end

return ref