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},
{"asteroidcluster","🧱",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(lines,children,rest,expand)
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
table.insert(lines,"\n"..loc["ListEntry"])
locChl = findChildren(rest,loc["ProperName"])
rest=locChl[3]
if #locChl>0 then
table.insert(lines,"\n<div class=\"locationnavplate-item-group\">")
local update = iterateToPopulate(lines,locChl,rest,expand)
lines=update[1]
rest=update[2]
table.insert(lines,"\n</div>")
end
table.insert(lines,"\n</div>")
end
if #unimportant>0 then
if expand == false then
table.insert(lines,"\n<div class=\"locationnavplate-item-other mw-collapsible mw-collapsed\">\n<div class=\"locationnavplate-item-other-header\">"..#unimportant.." Minor Locations</div>\n<div class=\"locationnavplate-item-group mw-collapsible-content\">")
end
for j, loc in ipairs(unimportant) do
table.insert(lines,"\n "..loc["ListEntry"])
locChl = findChildren(rest,loc["ProperName"])
rest=locChl[3]
if #locChl>0 then
local update = iterateToPopulate(lines,locChl,rest,true)
lines=update[1]
rest=update[2]
end
table.insert(lines,"\n</div>")
end
if expand == false then
table.insert(lines,"\n</div>")
end
end
end
local ret = {lines,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
--MAIN FUNCTION
--Takes the system from args (spits error if it can't) and a true/false for a nowiki wrapper.
p.fullplate= function(frame)
local searchCategory = frame.args[1]
local nowiki = frame.args[2]
if searchCategory == "" or searchCategory == nil then
return "Looks like the search category was set up incorrectly"
end
if nowiki == "true" then
nowiki=true
else
nowiki=false
end
-- Get the pages from the category of Stanton System
-- Potential to make this more elegant
local list = dpl.ask({
namespace = '',
category = searchCategory,
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"]= name
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
if loctype == "Asteroid Formation" 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
local class = "item"
if loctype == "star" then class = "heading" end
entry["ListEntry"] = "<div class=\"locationnavplate-"..loctype.." locationnavplate-"..class.."\"><span class=\"locationnavplate-item-icon\">"..category[2].."</span><span class=\"locationnavplate-item-name\">[["..name.."]]</span>"
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 lines = {}
if nowiki then tables.insert(lines,"<nowiki>NOWIKI ENABLED\n") end
table.insert(lines,"<div class=\"locationnavplate\" role=\"navigation\">\n<div class=\"locationnavplate-header\">Locations in<div class=\"locationnavplate-source\">[["..searchCategory.."]]</div>\n</div>")
if star == {} then
table.insert(lines,"Star Not Properly identified in infobox. You can help by fixing this.")
update = iterateToPopulate(lines,objects,{},false)
lines=update[1]
objects=update[2]
else
table.sort(stars,compareObjects)
table.insert(lines,stars[1]["ListEntry"])
local orbitSun = findChildren(objects,stars[1]["ProperName"])
objects = orbitSun[3]
for i=2,#stars,1 do
table.insert(lines,"\n"..stars[i]["ListEntry"])
orbitSun = mergeTab(orbitSun,findChildren(objects,stars[i]["ProperName"]))
end
table.insert(lines,"\n</div>")
if #orbitSun > 0 then
update = iterateToPopulate(lines,orbitSun,objects,false)
lines=update[1]
objects=update[2]
else
table.insert(lines,"\nCannot identify Objects orbiting star")
update = iterateToPopulate(lines,objects,{},false)
lines=update[1]
objects=update[2]
end
table.insert(lines,"\n</div>")
end
if #objects>0 then
table.insert(lines,"\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.(link to specific article about this problem)")
table.sort(objects,compareObjects)
for i, obj in ipairs(objects) do
table.insert(lines,"\n".. obj["ListEntry"])
end
end
if #orphans>0 then
table.insert(lines,"\nThe following locations are not formatting correctly because they do not have infoboxes. You can help by providing them with one. (link to specific article about this problem)")
for i, obj in ipairs(orphans) do
table.insert(lines,"\n".. obj)
end
end
if nowiki then tables.insert(lines,"</nowiki>\n") end
return table.concat(lines)
end
return p