Module:ExperimentalNavplate

From the Star Citizen Wiki, the fidelity™ encyclopedia
Revision as of 13:16, 4 August 2020 by Jale (talk | contribs)

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

--[[This Mess is an experimental module for seeing if we can create a navplate that populates itself
as an ordered, nested list.

It works by getting all of the pages from the category (in this example, Stanton) including their infobox data
through a single DPLlua request. It then parses these into categories and assigns a sort order.
These lists are then iterated through to find the objects that orbit the star, objects that orbit
those objects, etc. Those lists are then sorted by their orbit location (a new required field) and then
semantic precedence defined by a precedence score. As this sorting goes on, a string is built up to generate the list.]]--

local p = {};    
local dpl = require( 'Module:DPLlua' )

--List of possible categories for each location ordered :
--Category Name, Bullet symbol, Important?, Precedence Score
--Mistakes/inadequacies arising from the code are likely to originate here!
local typelist = {
	{"tradehub","💰",true,4},
	{"asteroidbase","☠",true,4.5},
	{"reststop","🏨",false,5},
	{"spacestation","🚀", false,6},
	{"planet","🪐",true,1},
	{"moon","🌙",true,5},
	{"asteroidbelt","⭕",true,3},
	{"asteroidformation","🧱",false,7},
	{"jumppoint","🌌", true,99},
	{"landingzone", "✈",true,0},
	{"spaceport","⚓",true,1},
	{"landmark","🏠", false,2}
}

--Special cases for the star and unidentified.	
local starSymb = "☀"
local miscLandSymb = "🏚"
local miscSpaceSymb = "🌠"
local orphanSymbol = "?"
--How small to make the minor location expandables.
local minorlocationfontsize = 60


iterateToPopulate = function(str,children,rest,indent,expand)

	local newindent = indent..":"
	for i=1 ,2, 1 do
		obj = children[i]
		important = obj[1]
		table.sort(important,compareObjects)
		unimportant = obj[2]
		table.sort(unimportant,compareObjects)
		for j,loc in ipairs(important) do
			
			str = str..newindent..loc["ListEntry"]
			locChl = findChildren(rest,loc["ProperName"])
			rest=locChl[3]
			if #locChl>0 then
				local update = iterateToPopulate(str,locChl,rest,newindent,expand)
				str=update[1]
				rest=update[2]
			end
		end
		if #unimportant>0 then
			if expand == false then
				str = str.."\n<div style=\"font-size: ".. minorlocationfontsize.."%\">\n{| class=\"mw-collapsible mw-collapsed article-table\"\n!"..#unimportant.." Direct Minor Locations"
			end
			for j, loc in ipairs(unimportant) do 
				str = str.."\n|-\n|"..loc["ListEntry"]
				locChl = findChildren(rest,loc["ProperName"])
				rest=locChl[3]
				if #locChl>0 then
					local update = iterateToPopulate(str,locChl,rest,newindent,true)
					str=update[1]
					rest=update[2]
				end
			end
			if expand == false then
				str = str.."\n|}\n</div>"
			end
		end
	end
	
	local ret = {str,rest}
	return ret
end

--Find all objects in list that mention string s in their location descriptor. Returns in format:
--{{important land, unimportant land},{important space},{unimportant space},{remainder]}
findChildren = function (list, s)
	local found={{{},{}},{{},{}},{}}
	s = string.lower(s)
	s = s:gsub("%s+", "")
	s = s:gsub("%p+", "")

	local brack = "[["..s.."]]"
	
	for x, item in ipairs(list) do
		loc = item["Location"]
		if loc == nil then loc = item["Orbits"] end
		if loc == nil then
			table.insert(found[3],item)
		else
			loc = string.lower(loc)
			loc = loc:gsub("%s+", "")
			loc = loc:gsub("%p+", "")
			if string.find(loc,s)~=nil or string.find(loc,brack)~=nil  then
				local important = 2
				local space = 2
				if item["inSpace"] == true then land = 1 end
				if item["Important"] == true then important = 1 end
				table.insert(found[land][important],item)
			else
				table.insert(found[3],item)
			end
		end
	end
	return found
end

--Return a table that combines 	
mergeTab = function (table1, table2)
	local newtab = {}
	for x,item in ipairs(table1) do
		newtab.insert(table1[i])
	end
	for x,item in ipairs(table2) do
		include = true
		for y,item2 in ipairs(table1) do
			if item == item2 then
				include = false
				break
			end
		end
		if include then newtab.insert(table2[i]) end
	end
	return newtab
end


--Sort objects by Orbital Position, if not (absent data or idential position) 
-- then Precedence, if not then alphabetically.
compareObjects = function  (a,b)
	orbA = a["Orbital Position"]
	orbB = b["Orbital Position"]
	if orbA == nil or orbB == nil or orbA == orbB then
		if a["SortPower"] == b["SortPower"] then 
			return a["ProperName"]<b["ProperName"] 
		else 
			return a["SortPower"] < b["SortPower"] 
		end
	else 
		return orbA<orbB
	end
end

p.fullplate= function(frame )    
	
	-- Get the pages from the category of Stanton System
	-- Potential to make this more elegant
   local list = dpl.ask({
		namespace = '',
		category = 'Stanton System',
		include='{Infobox Astronomical Object},{Infobox Location},{Infobox Space Station}'
	} )

   local stars={}
   local objects = {}
   local orphans = {} --pages without the infobox
   local infoboxtypes = {true,false,true}
   
   --Iterate through list, categorise and populate accordingly
	for i, line in ipairs(list) do
		local entry = {}
		
		local name = "[["..line["title"].."]]"
		
		local loctype = "orphan"
		local inspace = true
		
		for j, cat in ipairs(infoboxtypes) do
			entry = line["include"][j]
			if type(entry)== "table" then
				entry["ProperName"]= line["title"]
				loctype = entry["Type"]
				entry["inSpace"] = cat
				entry["SortPower"] = 9999
				break
			end
		end
		
		--A lot of space stations are categorised in their classifications
		if loctype == "Space Station" and entry["Classification"]~=nil then
			loctype = entry["Classification"]
		end
		
		loctype = string.lower(loctype)
		loctype = loctype:gsub("%s+", "")
		loctype = loctype:gsub("%p+", "")
		
		if loctype =="star" then
			entry["ListEntry"] = starSymb.." "..name
			table.insert(stars,entry)
			entry["ProperName"] = line["title"]
		elseif loctype == "orphan" then
			table.insert(orphans,orphanSymbol..name)
		else 
			entry["ProperName"] = line["title"]
			local found = false
			for j, category in ipairs(typelist) do
				if string.find(loctype,category[1])~=nil then
					entry["ListEntry"] = category[2].." "..name
					entry["Important"] = category[3]
					entry["SortPower"] = category[4]
					
					table.insert(objects,entry)
					found = true
					break;
				end
			end
			if found == false then
				if entry["inSpace"] == true then
					entry["ListEntry"] = miscSpaceSymb.." "..name
				else
					entry["ListEntry"] = miscLandSymb.." "..name
				end
				entry["Important"] = false
				entry["SortPower"] = 10
				table.insert(objects,entry)
			end
		end
	end
	
	local str = ""

	if star == {} then
		str = "Star Not Properly identified in infobox. You can help by fixing this."
		update = iterateToPopulate(str,objects,{},"\n",false)
		str=update[1]
		objects=update[2]
	else 
		table.sort(stars,compareObjects)
		str=stars[1]["ListEntry"]
		local orbitSun = findChildren(objects,stars[1]["ProperName"])
		objects = orbitSun[3]
		for i=2,#stars,1 do
			str = str..stars[i]["ListEntry"]
			orbitSun = mergeTab(orbitSun,findChildren(objects,stars[i]["ProperName"]))
		end
		
		if #orbitSun > 0 then
			update = iterateToPopulate(str,orbitSun,objects,"\n",false)
			str=update[1]
			objects=update[2]
		else 
			str = str.."\nCannot identify Objects orbiting star"
			update = iterateToPopulate(str,objects,{},"\n",false)
			str=update[1]
			objects=update[2]
		end
	end
	
	if #objects>0 then
		str = str .."\nThe following locations are not formatting correctly, either because their infoboxes need updating, or due to an error. You can help by editing the wiki."
		table.sort(objects,compareObjects)
		for i, obj in ipairs(objects) do
			str = str .."\n:".. obj["ListEntry"]
		end
	end
	
	if #orphans>0 then
		str = str .."\nThe following locations are not formatting correctly because they do not have infoboxes. You can help by providing them with one."
		for i, obj in ipairs(orphans) do
			str = str .."\n:".. obj
		end
	end


	

    return str
end


return p
🍪 We use cookies to keep session information to provide you a better experience.