Module:Citation

From IFWiki

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

local p = {}
local cargo = mw.ext.cargo

function dump(o)
	function dumper(o)
	   if type(o) == 'table' then
	      local s = '{ '
	      for k,v in pairs(o) do
	         if type(k) ~= 'number' then k = '"'..k..'"' end
	         s = s .. '['..k..'] = ' .. dumper(v) .. ','
	      end
	      return s .. '} '
	   else
	      return tostring(o)
	   end
	end
	echo("<pre>")
	echo(dumper(o))
	echo("</pre>")
end

function stringToTable(str)
	local result = {}
	if str then
		for word in string.gmatch(str, "([^,]+)") do
	    	table.insert(result, word:match("^%s*(.-)%s*$")) -- Trim spaces
		end
	end
	return result
end

---------------------------------------------------------------

function p.Main( frame )
	gf = require('Module:Game functions')

    local output = {}

	-- Easier to type
	function echo(text)
		table.insert(output, text)
	end

 	-- Get game name
	local game = frame.args['game']
	if not game or game=='' then
		return "Error: no game specified."
	end   
	gameEscaped = string.gsub(game, '"', '\\"') -- for MySQL
	
	-- Get data from Games table
	local tables = 'Games'
    local fields = 'Authoring_system, File_format, Z_code_version, System, Old_infobox_date, Game_date, Game_date_uncertain, Corrected_date, Corrected_date_uncertain, Language, Other_title'
    local args = {
    	where = '_pageName = "' .. gameEscaped .. '"'
    }
    local gameQueryResults = cargo.query( tables, fields, args )
    if #gameQueryResults~=0 then
	    -- These are strings
		authoringSystem = gameQueryResults[1]['Authoring_system']
		fileFormat = gameQueryResults[1]['File_format']
		system = gameQueryResults[1]['System']
		oldInfoboxDate = gameQueryResults[1]['Old_infobox_date']
		gameDate = gameQueryResults[1]['Game_date']
		gameDateUncertain = gameQueryResults[1]['Game_date_uncertain'] 
		language = gameQueryResults[1]['Language']
    end

	if gameDate then
		-- Calculated by template from release information or from corrected date field
		published = gameDate
		publishedUncertain = gameDateUncertain
	elseif oldInfoboxDate then
		-- There only are about a dozen of these left
		published = oldInfoboxDate:match('%d%d%d%d')
		publishedUncertain = 0 --not ideal
	end

	-- This groups the rows of a table according to one of its fields
	-- Used for Game_people, Game_companies to group by 'Role'
	function arrangeIntoGroups(tableName, groupName)
		local groupedTable = {}
		for _, v in ipairs(tableName) do
		    local group = v[groupName]
		    if group then
		        if not groupedTable[group] then
		            groupedTable[group] = {} 
		        end
		        table.insert(groupedTable[group], v)
		    end
		end
		return groupedTable
	end    
    
	-- Get all data from Game_people table
    local tables = 'Game_people'
	local fields = 'Name, Pseudonym, Role' 
    local args = {
    	where = 'Game_people._pageName="' .. gameEscaped .. '"',
    	orderBy = '_rowID'
    }
    local results = cargo.query( tables, fields, args )
	gamePerson = results
	if gamePerson then
		rolesTable = arrangeIntoGroups(gamePerson, 'Role')
		author = rolesTable['Author']
		pseudonym = rolesTable['Pseudonym']
		porter = rolesTable['Porter']
		translator = rolesTable['Translator']
	end
	
	-- Get all data from Game_companies table
    local tables = 'Game_companies'
	local fields = 'Name, Role' 
    local args = {
    	where = 'Game_companies._pageName="' .. gameEscaped .. '"',
    }
    local results = cargo.query( tables, fields, args )
	gameCompany = results
	if gameCompany then
	    rolesTable = arrangeIntoGroups(gameCompany, 'Role')
		developmentCompany = rolesTable['Development company']
		publisher = rolesTable['Publisher']
	end

	-- Only display game name if no citation information available
	if ( next(gameQueryResults)==nil and not published and next(gamePerson)==nil and next(gameCompany)==nil ) then
		return ( '[[' .. game .. ']]' )
	end
	
	-------------------------------------------------
	
	-- Start citation
	content = mw.title.new(game):getContent()
	displayTitle = content:match("{{DISPLAYTITLE:(.-)}}")
	if displayTitle then
		-- Use DISPLAYTITLE
		citationGame = mw.text.trim(displayTitle)
	else
		-- Use page name, minus "(by...)" or "(game)"
		citationGame = string.gsub(game, "%(by [^)]+%)", "")
		citationGame = string.gsub(citationGame, "%(game%)", "")
	end

	if mw.title.getCurrentTitle().text == game then
		-- no wikilink needed as citation is on game page
		echo('<i>' .. citationGame .. '</i>')
	else
		-- wikilink
		echo('<i>[[' .. game .. '|' .. citationGame .. ']]</i>' )
	end
	
	-- Opening bracket
	echo ' ('

	-- Author, including pseudonym
	if type(author) == "table" and next(author) ~= nil then
		gf.displayEntities(author, 'Person', 'Citation')
	else
		echo('Anonymous')
	end		

	-- Porter
	if type(porter) == "table" and next(porter) ~= nil then
		if #porter==1 then
			echo ('; porter: ')
		else 
			echo ('; porters: ')
		end
		gf.displayEntities(porter, 'Person', 'Citation')
	end	
	
	-- Translator
	if type(translator) == "table" and next(translator) ~= nil then
		if #translator==1 then
			echo ('; translator: ')
		else 
			echo ('; translators: ')
		end
		gf.displayEntities(translator, 'Person', 'Citation')
	end	
		
	-- Development company
	if type(developmentCompany) == "table" and next(developmentCompany) ~= nil then
		if #developmentCompany==1 then
			echo ('; development company: ')
		else 
			echo ('; development companies: ')
		end
		gf.displayEntities(developmentCompany, 'Company', 'Citation')
	end		

	-- Publisher 
	if type(publisher) == "table" and next(publisher) ~= nil then
		if #publisher==1 then
			echo ('; publisher: ')
		else 
			echo ('; publishers: ')
		end
		gf.displayEntities(publisher, 'Company', 'Citation')
	end			

	-- Publication date
	if published then
		echo ('; ')
		if publishedUncertain=='1' then
			echo('c. ' )
		end
		echo ( string.sub(published, 1, 4) ) -- year
	else
		echo ('; Date unknown')
	end

	-- Authoring system
	if authoringSystem then
		echo ('; [[' .. string.gsub(authoringSystem, ',' , ']], [[') .. ']]')
	end	
	
	-- File format, if different from authoring system
	-- Comparing individual elements rather than whole list
	if fileFormat then
		authoringSystemTable = stringToTable(authoringSystem)
		fileFormatTable = stringToTable(fileFormat)
		printFileFormat = ''
		for _,f in ipairs(fileFormatTable) do
			local p = true
			for _,a in ipairs(authoringSystemTable) do
			    if f == a then
			        p = false
			    end
			end
			if p then
				if printFileFormat ~= '' then
					printFileFormat = printFileFormat .. ', '
				end
				printFileFormat = printFileFormat .. f
			end
		end
		if printFileFormat ~= '' then
			echo ('; [[' .. string.gsub(printFileFormat, ',' , ']], [[') .. ']]')
		end
	end	

	-- System
	if system then
		echo ('; [[' .. string.gsub(system, ',' , ']], [[') .. ']]')
	end	
	
	--Language
	if language and language~='English' then
			echo ('; [[' .. string.gsub(language, ',' , ']], [[') .. ']]')
	end		
	
	-- Final bracket
	echo ')'

    output = table.concat(output)
	return output
end

return p