Module:Infobox/sandbox: Difference between revisions

From Official Factorio Wiki
Jump to navigation Jump to search
(Added defaults to space age recipe, total raw, cost and cost multiplier)
mNo edit summary
 
(28 intermediate revisions by 2 users not shown)
Line 1: Line 1:
local util = require("Module:Util")
local parsing = require("Module:Infobox/parsing/sandbox")
local p = {}
local p = {}


Line 4: Line 7:
   local args = frame:getParent().args
   local args = frame:getParent().args
   local ret = {}
   local ret = {}
    
   local sa = frame:expandTemplate{title = "Space age"} .. " "


   if not p._empty_arg(args["recipe"]) then
   if not util._empty_arg(args["recipe"]) then
     ret[#ret+1] = p._vrow(frame, {"Recipe",    args["recipe"], p._crafting_parsing(frame, args["recipe"])})
     ret[#ret+1] = p._vrow(frame, {"Recipe",    args["recipe"], parsing._crafting(frame, args["recipe"])})
     ret[#ret+1] = p._vrow(frame, {"Total raw", args["recipe"], p._crafting_raw(frame, p._arg_or(args["total-raw"], args["recipe"]))})
     ret[#ret+1] = p._vrow(frame, {"Total raw", args["recipe"], parsing._crafting_raw(frame, util._arg_or(args["total-raw"], args["recipe"]))})
   end
   end


   if not p._empty_arg(args["cost"]) then
   if not util._empty_arg(args["cost"]) then
     local cost = p._item_parsing(frame, args["cost"]) .. ((not p._empty_arg(args["cost-multiplier"])) and "✖ <big>" .. args["cost-multiplier"] .. "</big>" or "")
     local cost = parsing._item(frame, args["cost"]) .. ((not util._empty_arg(args["cost-multiplier"])) and "✖ <big>" .. args["cost-multiplier"] .. "</big>" or "")
     ret[#ret+1] = p._vrow(frame, {"Cost", args["cost"], cost})
     ret[#ret+1] = p._vrow(frame, {"Cost", args["cost"], cost})
  end
  if not util._empty_arg(args["technology-trigger"]) then
    ret[#ret+1] = p._vrow(frame, {"Researched by", args["technology-trigger"], parsing._technology_trigger(frame, args["technology-trigger"])})
   end
   end


   ret[#ret+1] = p._extra    (frame,                          args["extra1"])
   ret[#ret+1] = p._extra    (frame,                          args["extra1"])
    
    
   if not p._empty_arg(args["map-color"]) then
   if not util._empty_arg(args["map-color"]) then
     local color = frame:expandTemplate{title = 'Color', args = {args["map-color"]}}
     local color = frame:expandTemplate{title = 'Color', args = {args["map-color"]}}
     ret[#ret+1] = p._row(frame, {"Map color", args["map-color"], color})
     ret[#ret+1] = p._row(frame, {"Map color", args["map-color"], color})
Line 29: Line 35:
   ret[#ret+1] = p._row_simple(frame, "Fluid storage volume",  args["fluid-storage-volume"])
   ret[#ret+1] = p._row_simple(frame, "Fluid storage volume",  args["fluid-storage-volume"])


   if not p._empty_arg(args["expected-resources"]) then
   if not util._empty_arg(args["expected-resources"]) then
     local label = p._translate(frame, "Expected resources")
     local label = p._translate(frame, "Expected resources")
     ret[#ret+1] = string.format(
     ret[#ret+1] = string.format(
Line 49: Line 55:
   ret[#ret+1] = p._row_simple(frame, "Equipment grid size",  args["grid-size"])
   ret[#ret+1] = p._row_simple(frame, "Equipment grid size",  args["grid-size"])
   ret[#ret+1] = p._row_simple(frame, "Stack size",            args["stack-size"])
   ret[#ret+1] = p._row_simple(frame, "Stack size",            args["stack-size"])
  ret[#ret+1] = p._row_simple(frame, "Rocket capacity",      args["rocket-capacity"], sa)
   ret[#ret+1] = p._row_simple(frame, "Range",                args["range"])
   ret[#ret+1] = p._row_simple(frame, "Range",                args["range"])
   ret[#ret+1] = p._row_simple(frame, "Shooting speed",        args["shooting-speed"])
   ret[#ret+1] = p._row_simple(frame, "Shooting speed",        args["shooting-speed"])
Line 69: Line 76:
   ret[#ret+1] = p._row_simple(frame, "Repair speed",          args["repair-speed"])
   ret[#ret+1] = p._row_simple(frame, "Repair speed",          args["repair-speed"])
   ret[#ret+1] = p._row_simple(frame, "Charging stations",    args["charging-stations"])
   ret[#ret+1] = p._row_simple(frame, "Charging stations",    args["charging-stations"])
  ret[#ret+1] = p._row_simple(frame, "Rotation speed",        args["rotation-speed"])
   ret[#ret+1] = p._row_simple(frame, "Belt speed",            args["belt-speed"])
   ret[#ret+1] = p._row_simple(frame, "Belt speed",            args["belt-speed"])
  ret[#ret+1] = p._row_simple(frame, "Collection area",      args["asteroid-collection-area"])
  ret[#ret+1] = p._row_simple(frame, "Collection arm speed",  args["asteroid-collection-arm-speed"])
  ret[#ret+1] = p._row_simple(frame, "Collection arm count",  args["asteroid-collection-arm-count"])
   ret[#ret+1] = p._row_simple(frame, "Movement bonus",        args["movement-bonus"])
   ret[#ret+1] = p._row_simple(frame, "Movement bonus",        args["movement-bonus"])
   ret[#ret+1] = p._row_type  (frame, "Energy capacity",      args["energy-capacity"])
   ret[#ret+1] = p._row_type  (frame, "Energy capacity",      args["energy-capacity"])
   ret[#ret+1] = p._row_simple(frame, "Power input",          args["power-input"])
   ret[#ret+1] = p._row_simple(frame, "Power input",          args["power-input"])
   ret[#ret+1] = p._row_simple(frame, "Power output",          args["power-output"])
   ret[#ret+1] = p._row_simple(frame, "Power output",          args["power-output"])
  ret[#ret+1] = p._row_simple(frame, "Heat output",          args["heat-output"])
   ret[#ret+1] = p._row_simple(frame, "Maximum temperature",  args["maximum-temperature"])
   ret[#ret+1] = p._row_simple(frame, "Maximum temperature",  args["maximum-temperature"])
   ret[#ret+1] = p._row_simple(frame, "Fluid consumption",    args["fluid-consumption"])
   ret[#ret+1] = p._row_simple(frame, "Fluid consumption",    args["fluid-consumption"])
Line 84: Line 96:
   ret[#ret+1] = p._row_simple(frame, "Speed",                args["speed"])
   ret[#ret+1] = p._row_simple(frame, "Speed",                args["speed"])
   ret[#ret+1] = p._row_simple(frame, "Productivity",          args["productivity"])
   ret[#ret+1] = p._row_simple(frame, "Productivity",          args["productivity"])
  ret[#ret+1] = p._row_simple(frame, "Quality",              args["quality"], sa)
   ret[#ret+1] = p._row_simple(frame, "Mining speed",          args["mining-speed"])
   ret[#ret+1] = p._row_simple(frame, "Mining speed",          args["mining-speed"])
   ret[#ret+1] = p._row_unit  (frame, "Mining area",          args["mining-area"],          "tiles")
   ret[#ret+1] = p._row_unit  (frame, "Mining area",          args["mining-area"],          "tiles")
  ret[#ret+1] = p._row_simple(frame, "Resource drain",        args["resource-drain"])
  ret[#ret+1] = p._row_simple(frame, "Science pack drain",    args["science-pack-drain"])
  ret[#ret+1] = p._row_simple(frame, "Base productivity",    args["base-productivity"])
   ret[#ret+1] = p._row_type  (frame, "Fuel value",            args["fuel-value"])
   ret[#ret+1] = p._row_type  (frame, "Fuel value",            args["fuel-value"])
   ret[#ret+1] = p._row_simple(frame, "Vehicle acceleration",  args["vehicle-acceleration"])
   ret[#ret+1] = p._row_simple(frame, "Vehicle acceleration",  args["vehicle-acceleration"])
Line 93: Line 109:
   ret[#ret+1] = p._row_unit  (frame, "Construction area",    args["construction-area"],    "tiles")
   ret[#ret+1] = p._row_unit  (frame, "Construction area",    args["construction-area"],    "tiles")
   ret[#ret+1] = p._row_simple(frame, "Pollution",            args["pollution"])
   ret[#ret+1] = p._row_simple(frame, "Pollution",            args["pollution"])
   ret[#ret+1] = p._row_simple(frame, "Weight",                args["weight"])
  ret[#ret+1] = p._row_item  (frame, "Buildable only on",    args["buildable-on"], sa)
  ret[#ret+1] = p._row_item  (frame, "Crafted only on",      args["crafted-on"], sa)
  ret[#ret+1] = p._row_unit  (frame, "Spoil time",            args["spoil-time"],            "minutes", sa)
  ret[#ret+1] = p._row_item  (frame, "Spoil result",          args["spoil-result"], sa)
   ret[#ret+1] = p._row_simple(frame, "Weight",                args["vehicle-weight"])
   ret[#ret+1] = p._row_unit  (frame, "Module slots",          args["modules"],              "slots")
   ret[#ret+1] = p._row_unit  (frame, "Module slots",          args["modules"],              "slots")


   if not p._empty_arg(args["prototype-type"]) then
   if not util._empty_arg(args["prototype-type"]) then
     local prototype_type = frame:expandTemplate{title = 'Prototype page', args = {args["prototype-type"]}}
     local prototype_type = frame:expandTemplate{title = 'Prototype page', args = {args["prototype-type"]}}
     ret[#ret+1] = p._row(frame, {"Prototype type", args["prototype-type"], prototype_type})
     ret[#ret+1] = p._row(frame, {"Prototype type", args["prototype-type"], prototype_type})
Line 111: Line 131:
   ret[#ret+1] = p._vrow_item (frame, "Valid fuel",            args["valid-fuel"])
   ret[#ret+1] = p._vrow_item (frame, "Valid fuel",            args["valid-fuel"])
   ret[#ret+1] = p._vrow_item (frame, "Used as fuel by",      args["used-as-fuel-by"])
   ret[#ret+1] = p._vrow_item (frame, "Used as fuel by",      args["used-as-fuel-by"])
  ret[#ret+1] = p._vrow_item (frame, "Recycling results",    args["recycling-results"], sa)
   ret[#ret+1] = p._extra    (frame,                          args["extra2"])
   ret[#ret+1] = p._extra    (frame,                          args["extra2"])


Line 119: Line 140:
   local args = frame:getParent().args
   local args = frame:getParent().args
   local ret = {}
   local ret = {}
  local sa = frame:expandTemplate{title = "Space age"} .. " "
    
    
   local recipe = p._arg_or(args["space-age-recipe"], args["recipe"])
   local recipe = util._arg_or(args["space-age-recipe"], args["recipe"])
   if not p._empty_arg(recipe) then
   if not util._empty_arg(recipe) then
     ret[#ret+1] = p._vrow(frame, {"Recipe",    recipe, p._crafting_parsing(frame, recipe)})
     ret[#ret+1] = p._vrow(frame, {"Recipe",    recipe, parsing._crafting(frame, recipe)})
     local vanilla_total_raw = p._arg_or(args["total-raw"], args["recipe"])
     local vanilla_total_raw = util._arg_or(args["total-raw"], args["recipe"])
     ret[#ret+1] = p._vrow(frame, {"Total raw", recipe, p._crafting_raw(frame, p._arg_or(args["space-age-total-raw"],  p._arg_or(args["space-age-recipe"], vanilla_total_raw)))})
     ret[#ret+1] = p._vrow(frame, {"Total raw", recipe, parsing._crafting_raw(frame, util._arg_or(args["space-age-total-raw"],  util._arg_or(args["space-age-recipe"], vanilla_total_raw)))})
   end
   end


   local cost_arg = p._arg_or(args["space-age-cost"], args["cost"])
   local cost_arg = util._arg_or(args["space-age-cost"], args["cost"])
   if not p._empty_arg(cost_arg) then
  local tech_trigger_arg = util._arg_or(args["space-age-technology-trigger"], args["technology-trigger"])
     local cost_multiplier_arg = p._arg_or(args["space-age-cost-multiplier"], args["cost-multiplier"])
   if not util._empty_arg(cost_arg) and cost_arg ~= "none" then
     local cost = p._item_parsing(frame, cost_arg) .. ((not p._empty_arg(cost_multiplier_arg)) and "✖ <big>" .. cost_multiplier_arg .. "</big>" or "")
     local cost_multiplier_arg = util._arg_or(args["space-age-cost-multiplier"], args["cost-multiplier"])
     local cost = parsing._item(frame, cost_arg) .. ((not util._empty_arg(cost_multiplier_arg)) and "✖ <big>" .. cost_multiplier_arg .. "</big>" or "")
     ret[#ret+1] = p._vrow(frame, {"Cost", cost_arg, cost})
     ret[#ret+1] = p._vrow(frame, {"Cost", cost_arg, cost})
  end
  if not util._empty_arg(tech_trigger_arg) and tech_trigger_arg ~= "none" then
    ret[#ret+1] = p._vrow(frame, {"Researched by", tech_trigger_arg, parsing._technology_trigger(frame, tech_trigger_arg)})
   end
   end


   ret[#ret+1] = p._extra    (frame,                          args["extra1"])
   ret[#ret+1] = p._extra    (frame,                          args["extra1"])
    
    
   if not p._empty_arg(args["map-color"]) then
   if not util._empty_arg(args["map-color"]) then
     local color = frame:expandTemplate{title = 'Color', args = {args["map-color"]}}
     local color = frame:expandTemplate{title = 'Color', args = {args["map-color"]}}
     ret[#ret+1] = p._row(frame, {"Map color", args["map-color"], color})
     ret[#ret+1] = p._row(frame, {"Map color", args["map-color"], color})
Line 144: Line 170:
   ret[#ret+1] = p._row_simple(frame, "Added in",              args["added-in"])
   ret[#ret+1] = p._row_simple(frame, "Added in",              args["added-in"])
   ret[#ret+1] = p._row_simple(frame, "Walking speed",        args["walking-speed"])
   ret[#ret+1] = p._row_simple(frame, "Walking speed",        args["walking-speed"])
   ret[#ret+1] = p._row_simple(frame, "Storage size",          args["storage-size"])
   ret[#ret+1] = p._row_simple(frame, "Storage size",          util._arg_or(args["space-age-storage-size"], args["storage-size"]))
   ret[#ret+1] = p._row_simple(frame, "Fluid storage volume",  args["fluid-storage-volume"])
   ret[#ret+1] = p._row_simple(frame, "Fluid storage volume",  args["fluid-storage-volume"])


   if not p._empty_arg(args["expected-resources"]) then
   if not util._empty_arg(args["expected-resources"]) then
     local label = p._translate(frame, "Expected resources")
     local label = p._translate(frame, "Expected resources")
     ret[#ret+1] = string.format(
     ret[#ret+1] = string.format(
Line 166: Line 192:
   ret[#ret+1] = p._row_simple(frame, "Inventory size bonus",  args["inventory-size-bonus"])
   ret[#ret+1] = p._row_simple(frame, "Inventory size bonus",  args["inventory-size-bonus"])
   ret[#ret+1] = p._row_simple(frame, "Equipment grid size",  args["grid-size"])
   ret[#ret+1] = p._row_simple(frame, "Equipment grid size",  args["grid-size"])
   ret[#ret+1] = p._row_simple(frame, "Stack size",            args["stack-size"])
   ret[#ret+1] = p._row_simple(frame, "Stack size",            util._arg_or(args["space-age-stack-size"], args["stack-size"]))
  ret[#ret+1] = p._row_simple(frame, "Rocket capacity",      args["rocket-capacity"], sa)
   ret[#ret+1] = p._row_simple(frame, "Range",                args["range"])
   ret[#ret+1] = p._row_simple(frame, "Range",                args["range"])
   ret[#ret+1] = p._row_simple(frame, "Shooting speed",        args["shooting-speed"])
   ret[#ret+1] = p._row_simple(frame, "Shooting speed",        args["shooting-speed"])
Line 187: Line 214:
   ret[#ret+1] = p._row_simple(frame, "Repair speed",          args["repair-speed"])
   ret[#ret+1] = p._row_simple(frame, "Repair speed",          args["repair-speed"])
   ret[#ret+1] = p._row_simple(frame, "Charging stations",    args["charging-stations"])
   ret[#ret+1] = p._row_simple(frame, "Charging stations",    args["charging-stations"])
  ret[#ret+1] = p._row_simple(frame, "Rotation speed",        args["rotation-speed"])
   ret[#ret+1] = p._row_simple(frame, "Belt speed",            args["belt-speed"])
   ret[#ret+1] = p._row_simple(frame, "Belt speed",            args["belt-speed"])
  ret[#ret+1] = p._row_simple(frame, "Collection area",      args["asteroid-collection-area"])
  ret[#ret+1] = p._row_simple(frame, "Collection arm speed",  args["asteroid-collection-arm-speed"])
  ret[#ret+1] = p._row_simple(frame, "Collection arm count",  args["asteroid-collection-arm-count"])
   ret[#ret+1] = p._row_simple(frame, "Movement bonus",        args["movement-bonus"])
   ret[#ret+1] = p._row_simple(frame, "Movement bonus",        args["movement-bonus"])
   ret[#ret+1] = p._row_type  (frame, "Energy capacity",      args["energy-capacity"])
   ret[#ret+1] = p._row_type  (frame, "Energy capacity",      args["energy-capacity"])
   ret[#ret+1] = p._row_simple(frame, "Power input",          args["power-input"])
   ret[#ret+1] = p._row_simple(frame, "Power input",          args["power-input"])
   ret[#ret+1] = p._row_simple(frame, "Power output",          args["power-output"])
   ret[#ret+1] = p._row_simple(frame, "Power output",          args["power-output"])
  ret[#ret+1] = p._row_simple(frame, "Heat output",          args["heat-output"])
   ret[#ret+1] = p._row_simple(frame, "Maximum temperature",  args["maximum-temperature"])
   ret[#ret+1] = p._row_simple(frame, "Maximum temperature",  args["maximum-temperature"])
   ret[#ret+1] = p._row_simple(frame, "Fluid consumption",    args["fluid-consumption"])
   ret[#ret+1] = p._row_simple(frame, "Fluid consumption",    args["fluid-consumption"])
Line 202: Line 234:
   ret[#ret+1] = p._row_simple(frame, "Speed",                args["speed"])
   ret[#ret+1] = p._row_simple(frame, "Speed",                args["speed"])
   ret[#ret+1] = p._row_simple(frame, "Productivity",          args["productivity"])
   ret[#ret+1] = p._row_simple(frame, "Productivity",          args["productivity"])
  ret[#ret+1] = p._row_simple(frame, "Quality",              args["quality"])
   ret[#ret+1] = p._row_simple(frame, "Mining speed",          args["mining-speed"])
   ret[#ret+1] = p._row_simple(frame, "Mining speed",          args["mining-speed"])
   ret[#ret+1] = p._row_unit  (frame, "Mining area",          args["mining-area"],          "tiles")
   ret[#ret+1] = p._row_unit  (frame, "Mining area",          args["mining-area"],          "tiles")
  ret[#ret+1] = p._row_simple(frame, "Resource drain",        args["resource-drain"])
  ret[#ret+1] = p._row_simple(frame, "Science pack drain",    args["science-pack-drain"])
  ret[#ret+1] = p._row_simple(frame, "Base productivity",    args["base-productivity"])
   ret[#ret+1] = p._row_type  (frame, "Fuel value",            args["fuel-value"])
   ret[#ret+1] = p._row_type  (frame, "Fuel value",            args["fuel-value"])
   ret[#ret+1] = p._row_simple(frame, "Vehicle acceleration",  args["vehicle-acceleration"])
   ret[#ret+1] = p._row_simple(frame, "Vehicle acceleration",  args["vehicle-acceleration"])
Line 211: Line 247:
   ret[#ret+1] = p._row_unit  (frame, "Construction area",    args["construction-area"],    "tiles")
   ret[#ret+1] = p._row_unit  (frame, "Construction area",    args["construction-area"],    "tiles")
   ret[#ret+1] = p._row_simple(frame, "Pollution",            args["pollution"])
   ret[#ret+1] = p._row_simple(frame, "Pollution",            args["pollution"])
   ret[#ret+1] = p._row_simple(frame, "Weight",                args["weight"])
  ret[#ret+1] = p._row_item  (frame, "Buildable only on",    args["buildable-on"], sa)
  ret[#ret+1] = p._row_item  (frame, "Crafted only on",      args["crafted-on"], sa)
  ret[#ret+1] = p._row_unit  (frame, "Spoil time",            args["spoil-time"],            "minutes", sa)
  ret[#ret+1] = p._row_item  (frame, "Spoil result",          args["spoil-result"], sa)
   ret[#ret+1] = p._row_simple(frame, "Weight",                args["vehicle-weight"])
   ret[#ret+1] = p._row_unit  (frame, "Module slots",          args["modules"],              "slots")
   ret[#ret+1] = p._row_unit  (frame, "Module slots",          args["modules"],              "slots")


   if not p._empty_arg(args["prototype-type"]) then
   if not util._empty_arg(args["prototype-type"]) then
     local prototype_type = frame:expandTemplate{title = 'Prototype page', args = {args["prototype-type"]}}
     local prototype_type = frame:expandTemplate{title = 'Prototype page', args = {args["prototype-type"]}}
     ret[#ret+1] = p._row(frame, {"Prototype type", args["prototype-type"], prototype_type})
     ret[#ret+1] = p._row(frame, {"Prototype type", args["prototype-type"], prototype_type})
Line 221: Line 261:


   ret[#ret+1] = p._vrow_item (frame, "Accepted equipment",    args["equipment"])
   ret[#ret+1] = p._vrow_item (frame, "Accepted equipment",    args["equipment"])
   ret[#ret+1] = p._vrow_tech (frame, "Required technologies", p._arg_or(args["space-age-required-technologies"], args["required-technologies"]))
   ret[#ret+1] = p._vrow_tech (frame, "Required technologies", util._arg_or(args["space-age-required-technologies"], args["required-technologies"]))
   ret[#ret+1] = p._vrow_tech (frame, "Allows",                p._arg_or(args["space-age-allows"], args["allows"]))
   ret[#ret+1] = p._vrow_tech (frame, "Allows",                util._arg_or(args["space-age-allows"], args["allows"]))
   ret[#ret+1] = p._vrow_item (frame, "Effects",              p._arg_or(args["space-age-effects"], args["effects"]))
   ret[#ret+1] = p._vrow_item (frame, "Effects",              util._arg_or(args["space-age-effects"], args["effects"]))
   ret[#ret+1] = p._vrow_tech (frame, "Boosting technologies", args["boosting-technologies"])
   ret[#ret+1] = p._vrow_tech (frame, "Boosting technologies", args["boosting-technologies"])
   ret[#ret+1] = p._vrow_item (frame, "Produced by",          args["producers"])
   ret[#ret+1] = p._vrow_item (frame, "Produced by",          util._arg_or(args["space-age-producers"], args["producers"]))
   ret[#ret+1] = p._vrow_item (frame, "Consumed by",          p._arg_or(args["space-age-consumers"], args["consumers"]))
   ret[#ret+1] = p._vrow_item (frame, "Consumed by",          util._arg_or(args["space-age-consumers"], args["consumers"]))
   ret[#ret+1] = p._vrow_item (frame, "Valid fuel",            args["valid-fuel"])
   ret[#ret+1] = p._vrow_item (frame, "Valid fuel",            args["valid-fuel"])
   ret[#ret+1] = p._vrow_item (frame, "Used as fuel by",      args["used-as-fuel-by"])
   ret[#ret+1] = p._vrow_item (frame, "Used as fuel by",      args["used-as-fuel-by"])
  ret[#ret+1] = p._vrow_item (frame, "Recycling results",    args["recycling-results"], sa)
   ret[#ret+1] = p._extra    (frame,                          args["extra2"])
   ret[#ret+1] = p._extra    (frame,                          args["extra2"])


Line 235: Line 276:


function p._translate(frame, str)
function p._translate(frame, str)
   return frame:expandTemplate{title = 'Translation', args = {str}}
   return frame:expandTemplate{title = "Translation", args = {str}}
end
end


function p._row_simple(frame, label, arg)
function p._row_simple(frame, label, arg, label_prefix)
   if p._empty_arg(arg) then
   if util._empty_arg(arg) or arg == "none" then return end
    return
  end
    
    
   return p._row(frame, {label, arg})
   return p._row(frame, {label, arg}, label_prefix)
end
end


function p._row_unit(frame, label, arg, unit)
function p._row_unit(frame, label, arg, unit, label_prefix)
   if p._empty_arg(arg) then
   if util._empty_arg(arg) then return end
    return
  end
    
    
   return p._row(frame, {label, arg, arg .. " " .. p._translate(frame, unit)})
   return p._row(frame, {label, arg, arg .. " " .. p._translate(frame, unit)}, label_prefix)
end
end


function p._row_type(frame, label, arg)
function p._row_type(frame, label, arg, label_prefix)
   if p._empty_arg(arg) then
   if util._empty_arg(arg) then return end
    return
  end
    
    
   return p._row(frame, {label, arg, frame:expandTemplate{title = 'Type', args = {arg}}})
   return p._row(frame, {label, arg, frame:expandTemplate{title = "Type", args = {arg}}}, label_prefix)
end
end


function p._row_item(frame, label, arg)
function p._row_item(frame, label, arg, label_prefix)
   if p._empty_arg(arg) then
   if util._empty_arg(arg) then return end
    return
  end
    
    
   return p._row(frame, {label, arg, p._item_parsing(frame, arg)})
   return p._row(frame, {label, arg, parsing._item(frame, arg)}, label_prefix)
end
end


function p._vrow_item(frame, label, arg)
function p._vrow_item(frame, label, arg, label_prefix)
   if p._empty_arg(arg) then
   if util._empty_arg(arg) or arg == "none" then return end
    return
  end
    
    
   return p._vrow(frame, {label, arg, p._item_parsing(frame, arg)})
   return p._vrow(frame, {label, arg, parsing._item(frame, arg)}, label_prefix)
end
end


function p._vrow_tech(frame, label, arg)
function p._vrow_tech(frame, label, arg, label_prefix)
   if p._empty_arg(arg) then
   if util._empty_arg(arg) or arg == "none" then return end
    return
  end
    
    
   return p._vrow(frame, {label, arg, p._technology_parsing(frame, {arg, color = "228B22"})})
   return p._vrow(frame, {label, arg, parsing._technology(frame, {arg, color = "228B22"})}, label_prefix)
end
end


function p._row(frame, args)
function p._row(frame, args, label_prefix)
   if p._empty_arg(args[2]) then
   if util._empty_arg(args[2]) then
     return
     return
   end
   end


   local label = p._translate(frame, args[1])
   local label = p._translate(frame, args[1])
  if label_prefix then
    label = label_prefix .. label
  end


   return string.format(
   return string.format(
Line 306: Line 338:
end
end


function p._vrow(frame, args)
function p._vrow(frame, args, label_prefix)
   if p._empty_arg(args[2]) then
   if util._empty_arg(args[2]) then
     return
     return
   end
   end


   local label = p._translate(frame, args[1])
   local label = p._translate(frame, args[1])
  if label_prefix then
    label = label_prefix .. label
  end


   return string.format(
   return string.format(
Line 329: Line 364:


function p._extra(frame, arg)
function p._extra(frame, arg)
   if p._empty_arg(arg) then
   if util._empty_arg(arg) then
     return
     return
   end
   end
Line 342: Line 377:
</tr>]],
</tr>]],
     label)
     label)
end
function p.technology_parsing(frame)
  return p._technology_parsing(frame, frame.args)
end
function p._technology_parsing(frame, args)
  if args[1] == "?" or p._empty_arg(args[1]) then
    return args[1]
  end
  local ret = {}
  local techs = p._split(args[1], "+")
  for _, tech in ipairs(techs) do
    local tech_parts = p._split(tech, ",")
    local tech_name = tech_parts[1] .. " (research)"
    if not p._page_exists(tech_name) then -- fall back to plain name if page with " (research)" doesn't exist
      tech_name = tech_parts[1]
    end
    local tech_level = tech_parts[2] or ""
    if tech_level == "" then -- fall back to level from tech name if none given manually
      local second_to_last_char = string.sub(tech_parts[1], -2, -2)
      if second_to_last_char == " " then
        tech_level = string.sub(tech_parts[1], -1) -- last character should be the level of the tech
      end
    end
    ret[#ret+1] = frame:expandTemplate{title = 'icon/special', args = {tech_name, tech_level, color=args.color or "999"}}
  end
  return table.concat(ret)
end
function p.item_parsing(frame)
  return p._item_parsing(frame, frame.args[1])
end
function p._item_parsing(frame, item_string)
  if item_string == "?" or p._empty_arg(item_string) then
    return item_string
  end
  local ret = {}
  local items = p._split(item_string, "+")
  for _, item in ipairs(items) do
    local icon_args = p._split(item, ",")
    icon_args[2] = icon_args[2] or ""
    ret[#ret+1] = frame:expandTemplate{title = 'icon/special', args = icon_args}
  end
  return table.concat(ret)
end
function p.crafting_parsing(frame)
  return p._crafting_parsing(frame, frame.args[1])
end
function p._crafting_parsing(frame, recipe)
  if recipe == "?" or p._empty_arg(recipe) then
    return recipe
  end
 
  local recipe_parts = p._split(recipe, "=") 
  local ingredients = p._crafting_parsing_split(frame, recipe_parts[1])
 
  local products = recipe_parts[2]
  if products then
    products = "&rarr; " .. p._crafting_parsing_split(frame, products)
  else
    local item_name = frame:expandTemplate{title = 'No language suffix/No namespace'}
    products = "&rarr; " .. frame:expandTemplate{title = 'icon/special', args = {item_name, "1"}}
  end
 
  return ingredients .. products
end
function p.crafting_raw(frame)
  return p._crafting_raw(frame, frame.args[1])
end
function p._crafting_raw(frame, recipe)
  if recipe == "?" or p._empty_arg(recipe) then
    return recipe
  end
  local recipe_parts = p._split(recipe, "=")
  return p._crafting_parsing_split(frame, recipe_parts[1])
end
-- @param frame
-- @param str string A list of "item, count" separated by "+"
-- @return string @The resulting icons with a "+" between each icon
function p._crafting_parsing_split(frame, str)
  local ret = {}
  local items = p._split(str, "+")
  for _, item in ipairs(items) do
    local item_parts = p._split(item, ",")
    local item_count = item_parts[2] or "1" -- fall back to 1, not empty!
    item_count = frame:expandTemplate{title = 'Crop', args = {item_count}}
    ret[#ret+1] = frame:expandTemplate{title = 'icon/special', args = {item_parts[1], item_count}}
  end
  return table.concat(ret, "+")
end
function p._arg_or(arg, default)
  if p._empty_arg(arg) then
    return default
  else
    return arg
  end
end
-- @param arg string The argument to check
-- @return boolean @Whether the argument is an whitespace string or empty string or nil
function p._empty_arg(arg)
  if type(arg) == "string" then
    return not string.find(arg, "%S")
  else
    return not arg
  end
end
-- @param inputstr string A string to be split
-- @param separator string The separator
-- @return string[] @The separated strings, without the separator
function p._split(inputstr, separator)
  local result = {}
  for str in string.gmatch(inputstr, "([^"..separator.."]+)") do
    table.insert(result, mw.text.trim(str))
  end
  return result
end
-- @param page_title string The title of the page
-- @return boolean
function p._page_exists(page_title)
  if page_title and page_title ~= "" then
    return mw.title.new(page_title).exists
  else
    return false
  end
end
end


return p
return p

Latest revision as of 04:21, 10 November 2024

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

local util = require("Module:Util")
local parsing = require("Module:Infobox/parsing/sandbox")

local p = {}

function p.base_tab(frame) -- no prefix for args. Used for vanilla tab or if no tabs
  local args = frame:getParent().args
  local ret = {}
  local sa = frame:expandTemplate{title = "Space age"} .. " "

  if not util._empty_arg(args["recipe"]) then
    ret[#ret+1] = p._vrow(frame, {"Recipe",    args["recipe"], parsing._crafting(frame, args["recipe"])})
    ret[#ret+1] = p._vrow(frame, {"Total raw", args["recipe"], parsing._crafting_raw(frame, util._arg_or(args["total-raw"], args["recipe"]))})
  end

  if not util._empty_arg(args["cost"]) then
    local cost = parsing._item(frame, args["cost"]) .. ((not util._empty_arg(args["cost-multiplier"])) and "✖ <big>" .. args["cost-multiplier"] .. "</big>" or "")
    ret[#ret+1] = p._vrow(frame, {"Cost", args["cost"], cost})
  end
  if not util._empty_arg(args["technology-trigger"]) then
    ret[#ret+1] = p._vrow(frame, {"Researched by", args["technology-trigger"], parsing._technology_trigger(frame, args["technology-trigger"])})
  end

  ret[#ret+1] = p._extra     (frame,                          args["extra1"])
  
  if not util._empty_arg(args["map-color"]) then
    local color = frame:expandTemplate{title = 'Color', args = {args["map-color"]}}
    ret[#ret+1] = p._row(frame, {"Map color", args["map-color"], color})
  end

  ret[#ret+1] = p._row_simple(frame, "Map icon",              args["map-icon"])
  ret[#ret+1] = p._row_simple(frame, "Added in",              args["added-in"])
  ret[#ret+1] = p._row_simple(frame, "Walking speed",         args["walking-speed"])
  ret[#ret+1] = p._row_simple(frame, "Storage size",          args["storage-size"])
  ret[#ret+1] = p._row_simple(frame, "Fluid storage volume",  args["fluid-storage-volume"])

  if not util._empty_arg(args["expected-resources"]) then
    local label = p._translate(frame, "Expected resources")
    ret[#ret+1] = string.format(
[[<tr class="border-top">
<td>
%s
</td>
<td style="width: 70%%;">
%s
</td>
</tr>]], label, args["expected-resources"])
  end

  ret[#ret+1] = p._row_simple(frame, "Health",                args["health"])
  ret[#ret+1] = p._row_unit  (frame, "Restores",              args["restores"],             "health")
  ret[#ret+1] = p._row_simple(frame, "Resistances",           args["resistance"])
  ret[#ret+1] = p._row_unit  (frame, "Lifespan",              args["lifespan"],             "seconds")
  ret[#ret+1] = p._row_simple(frame, "Inventory size bonus",  args["inventory-size-bonus"])
  ret[#ret+1] = p._row_simple(frame, "Equipment grid size",   args["grid-size"])
  ret[#ret+1] = p._row_simple(frame, "Stack size",            args["stack-size"])
  ret[#ret+1] = p._row_simple(frame, "Rocket capacity",       args["rocket-capacity"], sa)
  ret[#ret+1] = p._row_simple(frame, "Range",                 args["range"])
  ret[#ret+1] = p._row_simple(frame, "Shooting speed",        args["shooting-speed"])
  ret[#ret+1] = p._row_simple(frame, "Damage",                args["damage"])
  ret[#ret+1] = p._row_simple(frame, "Damage bonus",          args["damage-bonus"])
  ret[#ret+1] = p._row_simple(frame, "Cluster size",          args["cluster-size"])
  ret[#ret+1] = p._row_simple(frame, "Area of effect size",   args["area-of-effect-size"])
  ret[#ret+1] = p._row_simple(frame, "Durability",            args["durability"])
  ret[#ret+1] = p._row_simple(frame, "Magazine size",         args["magazine-size"])
  ret[#ret+1] = p._row_item  (frame, "Ammunition",            args["ammunition"])
  ret[#ret+1] = p._vrow_item (frame, "Used as ammunition by", args["used-as-ammo-by"])
  ret[#ret+1] = p._row_simple(frame, "Efficiency",            args["efficiency"])
  ret[#ret+1] = p._row_simple(frame, "Dimensions",            args["dimensions"])
  ret[#ret+1] = p._row_type  (frame, "Energy consumption",    args["energy"])
  ret[#ret+1] = p._row_type  (frame, "Drain",                 args["drain"])
  ret[#ret+1] = p._row_type  (frame, "Robot recharge rate",   args["robot-recharge-rate"])
  ret[#ret+1] = p._row_type  (frame, "Internal buffer recharge rate", args["internal-buffer-recharge-rate"])
  ret[#ret+1] = p._vrow_item (frame, "Placed in",             args["equipped-in"])
  ret[#ret+1] = p._row_simple(frame, "Robot limit",           args["robot-limit"])
  ret[#ret+1] = p._row_simple(frame, "Repair speed",          args["repair-speed"])
  ret[#ret+1] = p._row_simple(frame, "Charging stations",     args["charging-stations"])
  ret[#ret+1] = p._row_simple(frame, "Rotation speed",        args["rotation-speed"])
  ret[#ret+1] = p._row_simple(frame, "Belt speed",            args["belt-speed"])
  ret[#ret+1] = p._row_simple(frame, "Collection area",       args["asteroid-collection-area"])
  ret[#ret+1] = p._row_simple(frame, "Collection arm speed",  args["asteroid-collection-arm-speed"])
  ret[#ret+1] = p._row_simple(frame, "Collection arm count",  args["asteroid-collection-arm-count"])
  ret[#ret+1] = p._row_simple(frame, "Movement bonus",        args["movement-bonus"])
  ret[#ret+1] = p._row_type  (frame, "Energy capacity",       args["energy-capacity"])
  ret[#ret+1] = p._row_simple(frame, "Power input",           args["power-input"])
  ret[#ret+1] = p._row_simple(frame, "Power output",          args["power-output"])
  ret[#ret+1] = p._row_simple(frame, "Heat output",           args["heat-output"])
  ret[#ret+1] = p._row_simple(frame, "Maximum temperature",   args["maximum-temperature"])
  ret[#ret+1] = p._row_simple(frame, "Fluid consumption",     args["fluid-consumption"])
  ret[#ret+1] = p._row_simple(frame, "Shield hitpoints",      args["shield"])
  ret[#ret+1] = p._row_type  (frame, "Energy per hitpoint",   args["energy-per-hitpoint"])
  ret[#ret+1] = p._row_simple(frame, "Maximum recharge speed",args["maximum-recharge-speed"])
  ret[#ret+1] = p._row_simple(frame, "Crafting speed",        args["crafting-speed"])
  ret[#ret+1] = p._row_simple(frame, "Pumping speed",         args["pumping-speed"])
  ret[#ret+1] = p._row_simple(frame, "Mining time",           args["mining-time"])
  ret[#ret+1] = p._row_simple(frame, "Speed",                 args["speed"])
  ret[#ret+1] = p._row_simple(frame, "Productivity",          args["productivity"])
  ret[#ret+1] = p._row_simple(frame, "Quality",               args["quality"], sa)
  ret[#ret+1] = p._row_simple(frame, "Mining speed",          args["mining-speed"])
  ret[#ret+1] = p._row_unit  (frame, "Mining area",           args["mining-area"],           "tiles")
  ret[#ret+1] = p._row_simple(frame, "Resource drain",        args["resource-drain"])
  ret[#ret+1] = p._row_simple(frame, "Science pack drain",    args["science-pack-drain"])
  ret[#ret+1] = p._row_simple(frame, "Base productivity",     args["base-productivity"])
  ret[#ret+1] = p._row_type  (frame, "Fuel value",            args["fuel-value"])
  ret[#ret+1] = p._row_simple(frame, "Vehicle acceleration",  args["vehicle-acceleration"])
  ret[#ret+1] = p._row_simple(frame, "Vehicle top speed",     args["vehicle-top-speed"])
  ret[#ret+1] = p._row_unit  (frame, "Supply area",           args["supply-area"],           "tiles")
  ret[#ret+1] = p._row_unit  (frame, "Wire reach",            args["wire-reach"],            "tiles")
  ret[#ret+1] = p._row_unit  (frame, "Construction area",     args["construction-area"],     "tiles")
  ret[#ret+1] = p._row_simple(frame, "Pollution",             args["pollution"])
  ret[#ret+1] = p._row_item  (frame, "Buildable only on",     args["buildable-on"], sa)
  ret[#ret+1] = p._row_item  (frame, "Crafted only on",       args["crafted-on"], sa)
  ret[#ret+1] = p._row_unit  (frame, "Spoil time",            args["spoil-time"],            "minutes", sa)
  ret[#ret+1] = p._row_item  (frame, "Spoil result",          args["spoil-result"], sa)
  ret[#ret+1] = p._row_simple(frame, "Weight",                args["vehicle-weight"])
  ret[#ret+1] = p._row_unit  (frame, "Module slots",          args["modules"],               "slots")

  if not util._empty_arg(args["prototype-type"]) then
    local prototype_type = frame:expandTemplate{title = 'Prototype page', args = {args["prototype-type"]}}
    ret[#ret+1] = p._row(frame, {"Prototype type", args["prototype-type"], prototype_type})
  end
  ret[#ret+1] = p._row_simple(frame, "Internal name",         args["internal-name"])

  ret[#ret+1] = p._vrow_item (frame, "Accepted equipment",    args["equipment"])
  ret[#ret+1] = p._vrow_tech (frame, "Required technologies", args["required-technologies"])
  ret[#ret+1] = p._vrow_tech (frame, "Allows",                args["allows"])
  ret[#ret+1] = p._vrow_item (frame, "Effects",               args["effects"])
  ret[#ret+1] = p._vrow_tech (frame, "Boosting technologies", args["boosting-technologies"])
  ret[#ret+1] = p._vrow_item (frame, "Produced by",           args["producers"])
  ret[#ret+1] = p._vrow_item (frame, "Consumed by",           args["consumers"])
  ret[#ret+1] = p._vrow_item (frame, "Valid fuel",            args["valid-fuel"])
  ret[#ret+1] = p._vrow_item (frame, "Used as fuel by",       args["used-as-fuel-by"])
  ret[#ret+1] = p._vrow_item (frame, "Recycling results",     args["recycling-results"], sa)
  ret[#ret+1] = p._extra     (frame,                          args["extra2"])

  return table.concat(ret)
end

function p.space_age_tab(frame) -- space-age prefix for some args. Used for space age mod tab
  local args = frame:getParent().args
  local ret = {}
  local sa = frame:expandTemplate{title = "Space age"} .. " "
  
  local recipe = util._arg_or(args["space-age-recipe"], args["recipe"])
  if not util._empty_arg(recipe) then
    ret[#ret+1] = p._vrow(frame, {"Recipe",    recipe, parsing._crafting(frame, recipe)})
    local vanilla_total_raw = util._arg_or(args["total-raw"], args["recipe"])
    ret[#ret+1] = p._vrow(frame, {"Total raw", recipe, parsing._crafting_raw(frame, util._arg_or(args["space-age-total-raw"],  util._arg_or(args["space-age-recipe"], vanilla_total_raw)))})
  end

  local cost_arg = util._arg_or(args["space-age-cost"], args["cost"])
  local tech_trigger_arg = util._arg_or(args["space-age-technology-trigger"], args["technology-trigger"])
  if not util._empty_arg(cost_arg) and cost_arg ~= "none" then
    local cost_multiplier_arg = util._arg_or(args["space-age-cost-multiplier"], args["cost-multiplier"])
    local cost = parsing._item(frame, cost_arg) .. ((not util._empty_arg(cost_multiplier_arg)) and "✖ <big>" .. cost_multiplier_arg .. "</big>" or "")
    ret[#ret+1] = p._vrow(frame, {"Cost", cost_arg, cost})
  end
  if not util._empty_arg(tech_trigger_arg) and tech_trigger_arg ~= "none" then
    ret[#ret+1] = p._vrow(frame, {"Researched by", tech_trigger_arg, parsing._technology_trigger(frame, tech_trigger_arg)})
  end

  ret[#ret+1] = p._extra     (frame,                          args["extra1"])
  
  if not util._empty_arg(args["map-color"]) then
    local color = frame:expandTemplate{title = 'Color', args = {args["map-color"]}}
    ret[#ret+1] = p._row(frame, {"Map color", args["map-color"], color})
  end

  ret[#ret+1] = p._row_simple(frame, "Map icon",              args["map-icon"])
  ret[#ret+1] = p._row_simple(frame, "Added in",              args["added-in"])
  ret[#ret+1] = p._row_simple(frame, "Walking speed",         args["walking-speed"])
  ret[#ret+1] = p._row_simple(frame, "Storage size",          util._arg_or(args["space-age-storage-size"], args["storage-size"]))
  ret[#ret+1] = p._row_simple(frame, "Fluid storage volume",  args["fluid-storage-volume"])

  if not util._empty_arg(args["expected-resources"]) then
    local label = p._translate(frame, "Expected resources")
    ret[#ret+1] = string.format(
[[<tr class="border-top">
<td>
%s
</td>
<td style="width: 70%%;">
%s
</td>
</tr>]], label, args["expected-resources"])
  end

  ret[#ret+1] = p._row_simple(frame, "Health",                args["health"])
  ret[#ret+1] = p._row_unit  (frame, "Restores",              args["restores"],             "health")
  ret[#ret+1] = p._row_simple(frame, "Resistances",           args["resistance"])
  ret[#ret+1] = p._row_unit  (frame, "Lifespan",              args["lifespan"],             "seconds")
  ret[#ret+1] = p._row_simple(frame, "Inventory size bonus",  args["inventory-size-bonus"])
  ret[#ret+1] = p._row_simple(frame, "Equipment grid size",   args["grid-size"])
  ret[#ret+1] = p._row_simple(frame, "Stack size",            util._arg_or(args["space-age-stack-size"], args["stack-size"]))
  ret[#ret+1] = p._row_simple(frame, "Rocket capacity",       args["rocket-capacity"], sa)
  ret[#ret+1] = p._row_simple(frame, "Range",                 args["range"])
  ret[#ret+1] = p._row_simple(frame, "Shooting speed",        args["shooting-speed"])
  ret[#ret+1] = p._row_simple(frame, "Damage",                args["damage"])
  ret[#ret+1] = p._row_simple(frame, "Damage bonus",          args["damage-bonus"])
  ret[#ret+1] = p._row_simple(frame, "Cluster size",          args["cluster-size"])
  ret[#ret+1] = p._row_simple(frame, "Area of effect size",   args["area-of-effect-size"])
  ret[#ret+1] = p._row_simple(frame, "Durability",            args["durability"])
  ret[#ret+1] = p._row_simple(frame, "Magazine size",         args["magazine-size"])
  ret[#ret+1] = p._row_item  (frame, "Ammunition",            args["ammunition"])
  ret[#ret+1] = p._vrow_item (frame, "Used as ammunition by", args["used-as-ammo-by"])
  ret[#ret+1] = p._row_simple(frame, "Efficiency",            args["efficiency"])
  ret[#ret+1] = p._row_simple(frame, "Dimensions",            args["dimensions"])
  ret[#ret+1] = p._row_type  (frame, "Energy consumption",    args["energy"])
  ret[#ret+1] = p._row_type  (frame, "Drain",                 args["drain"])
  ret[#ret+1] = p._row_type  (frame, "Robot recharge rate",   args["robot-recharge-rate"])
  ret[#ret+1] = p._row_type  (frame, "Internal buffer recharge rate", args["internal-buffer-recharge-rate"])
  ret[#ret+1] = p._vrow_item (frame, "Placed in",             args["equipped-in"])
  ret[#ret+1] = p._row_simple(frame, "Robot limit",           args["robot-limit"])
  ret[#ret+1] = p._row_simple(frame, "Repair speed",          args["repair-speed"])
  ret[#ret+1] = p._row_simple(frame, "Charging stations",     args["charging-stations"])
  ret[#ret+1] = p._row_simple(frame, "Rotation speed",        args["rotation-speed"])
  ret[#ret+1] = p._row_simple(frame, "Belt speed",            args["belt-speed"])
  ret[#ret+1] = p._row_simple(frame, "Collection area",       args["asteroid-collection-area"])
  ret[#ret+1] = p._row_simple(frame, "Collection arm speed",  args["asteroid-collection-arm-speed"])
  ret[#ret+1] = p._row_simple(frame, "Collection arm count",  args["asteroid-collection-arm-count"])
  ret[#ret+1] = p._row_simple(frame, "Movement bonus",        args["movement-bonus"])
  ret[#ret+1] = p._row_type  (frame, "Energy capacity",       args["energy-capacity"])
  ret[#ret+1] = p._row_simple(frame, "Power input",           args["power-input"])
  ret[#ret+1] = p._row_simple(frame, "Power output",          args["power-output"])
  ret[#ret+1] = p._row_simple(frame, "Heat output",           args["heat-output"])
  ret[#ret+1] = p._row_simple(frame, "Maximum temperature",   args["maximum-temperature"])
  ret[#ret+1] = p._row_simple(frame, "Fluid consumption",     args["fluid-consumption"])
  ret[#ret+1] = p._row_simple(frame, "Shield hitpoints",      args["shield"])
  ret[#ret+1] = p._row_type  (frame, "Energy per hitpoint",   args["energy-per-hitpoint"])
  ret[#ret+1] = p._row_simple(frame, "Maximum recharge speed",args["maximum-recharge-speed"])
  ret[#ret+1] = p._row_simple(frame, "Crafting speed",        args["crafting-speed"])
  ret[#ret+1] = p._row_simple(frame, "Pumping speed",         args["pumping-speed"])
  ret[#ret+1] = p._row_simple(frame, "Mining time",           args["mining-time"])
  ret[#ret+1] = p._row_simple(frame, "Speed",                 args["speed"])
  ret[#ret+1] = p._row_simple(frame, "Productivity",          args["productivity"])
  ret[#ret+1] = p._row_simple(frame, "Quality",               args["quality"])
  ret[#ret+1] = p._row_simple(frame, "Mining speed",          args["mining-speed"])
  ret[#ret+1] = p._row_unit  (frame, "Mining area",           args["mining-area"],           "tiles")
  ret[#ret+1] = p._row_simple(frame, "Resource drain",        args["resource-drain"])
  ret[#ret+1] = p._row_simple(frame, "Science pack drain",    args["science-pack-drain"])
  ret[#ret+1] = p._row_simple(frame, "Base productivity",     args["base-productivity"])
  ret[#ret+1] = p._row_type  (frame, "Fuel value",            args["fuel-value"])
  ret[#ret+1] = p._row_simple(frame, "Vehicle acceleration",  args["vehicle-acceleration"])
  ret[#ret+1] = p._row_simple(frame, "Vehicle top speed",     args["vehicle-top-speed"])
  ret[#ret+1] = p._row_unit  (frame, "Supply area",           args["supply-area"],           "tiles")
  ret[#ret+1] = p._row_unit  (frame, "Wire reach",            args["wire-reach"],            "tiles")
  ret[#ret+1] = p._row_unit  (frame, "Construction area",     args["construction-area"],     "tiles")
  ret[#ret+1] = p._row_simple(frame, "Pollution",             args["pollution"])
  ret[#ret+1] = p._row_item  (frame, "Buildable only on",     args["buildable-on"], sa)
  ret[#ret+1] = p._row_item  (frame, "Crafted only on",       args["crafted-on"], sa)
  ret[#ret+1] = p._row_unit  (frame, "Spoil time",            args["spoil-time"],            "minutes", sa)
  ret[#ret+1] = p._row_item  (frame, "Spoil result",          args["spoil-result"], sa)
  ret[#ret+1] = p._row_simple(frame, "Weight",                args["vehicle-weight"])
  ret[#ret+1] = p._row_unit  (frame, "Module slots",          args["modules"],               "slots")

  if not util._empty_arg(args["prototype-type"]) then
    local prototype_type = frame:expandTemplate{title = 'Prototype page', args = {args["prototype-type"]}}
    ret[#ret+1] = p._row(frame, {"Prototype type", args["prototype-type"], prototype_type})
  end
  ret[#ret+1] = p._row_simple(frame, "Internal name",         args["internal-name"])

  ret[#ret+1] = p._vrow_item (frame, "Accepted equipment",    args["equipment"])
  ret[#ret+1] = p._vrow_tech (frame, "Required technologies", util._arg_or(args["space-age-required-technologies"], args["required-technologies"]))
  ret[#ret+1] = p._vrow_tech (frame, "Allows",                util._arg_or(args["space-age-allows"], args["allows"]))
  ret[#ret+1] = p._vrow_item (frame, "Effects",               util._arg_or(args["space-age-effects"], args["effects"]))
  ret[#ret+1] = p._vrow_tech (frame, "Boosting technologies", args["boosting-technologies"])
  ret[#ret+1] = p._vrow_item (frame, "Produced by",           util._arg_or(args["space-age-producers"], args["producers"]))
  ret[#ret+1] = p._vrow_item (frame, "Consumed by",           util._arg_or(args["space-age-consumers"], args["consumers"]))
  ret[#ret+1] = p._vrow_item (frame, "Valid fuel",            args["valid-fuel"])
  ret[#ret+1] = p._vrow_item (frame, "Used as fuel by",       args["used-as-fuel-by"])
  ret[#ret+1] = p._vrow_item (frame, "Recycling results",     args["recycling-results"], sa)
  ret[#ret+1] = p._extra     (frame,                          args["extra2"])

  return table.concat(ret)
end

function p._translate(frame, str)
  return frame:expandTemplate{title = "Translation", args = {str}}
end

function p._row_simple(frame, label, arg, label_prefix)
  if util._empty_arg(arg) or arg == "none" then return end
  
  return p._row(frame, {label, arg}, label_prefix)
end

function p._row_unit(frame, label, arg, unit, label_prefix)
  if util._empty_arg(arg) then return end
  
  return p._row(frame, {label, arg, arg .. " " .. p._translate(frame, unit)}, label_prefix)
end

function p._row_type(frame, label, arg, label_prefix)
  if util._empty_arg(arg) then return end
  
  return p._row(frame, {label, arg, frame:expandTemplate{title = "Type", args = {arg}}}, label_prefix)
end

function p._row_item(frame, label, arg, label_prefix)
  if util._empty_arg(arg) then return end
  
  return p._row(frame, {label, arg, parsing._item(frame, arg)}, label_prefix)
end

function p._vrow_item(frame, label, arg, label_prefix)
  if util._empty_arg(arg) or arg == "none" then return end
  
  return p._vrow(frame, {label, arg, parsing._item(frame, arg)}, label_prefix)
end

function p._vrow_tech(frame, label, arg, label_prefix)
  if util._empty_arg(arg) or arg == "none" then return end
  
  return p._vrow(frame, {label, arg, parsing._technology(frame, {arg, color = "228B22"})}, label_prefix)
end

function p._row(frame, args, label_prefix)
  if util._empty_arg(args[2]) then
    return
  end

  local label = p._translate(frame, args[1])
  if label_prefix then
    label = label_prefix .. label
  end

  return string.format(
[[<tr class="border-top">
<td>
%s
</td>
<td>
%s
</td>
</tr>]],
    label,
    args[3] or args[2])
end

function p._vrow(frame, args, label_prefix)
  if util._empty_arg(args[2]) then
    return
  end

  local label = p._translate(frame, args[1])
  if label_prefix then
    label = label_prefix .. label
  end

  return string.format(
[[<tr class="border-top">
<td colspan=2>
%s
</td>
</tr>
<tr>
<td class="infobox-vrow-value" colspan=2>
%s
</td>
</tr>]],
    label,
    args[3] or args[2])
end

function p._extra(frame, arg)
  if util._empty_arg(arg) then
    return
  end

  local label = p._translate(frame, arg)

  return string.format(
[[<tr class="border-top">
<td colspan=2 class="infobox-extra">
%s
</td>
</tr>]],
    label)
end

return p