Module:Infobox/sandbox: Difference between revisions

From Official Factorio Wiki
Jump to navigation Jump to search
(Better account for fully whitespace args in row and vrow)
No edit summary
(One intermediate revision by the same user not shown)
Line 3: Line 3:
function p.row(frame)
function p.row(frame)
   local args = frame.args
   local args = frame.args
   if not p.clean_arg(args[2]) then
   if p._empty_arg(args[2]) then
     return
     return
   end
   end
Line 24: Line 24:
function p.vrow(frame)
function p.vrow(frame)
   local args = frame.args
   local args = frame.args
  if p._empty_arg(args[2]) and p._empty_arg(args[4]) then
    return
  end


   local label = frame:expandTemplate{title = 'Translation', args = {args[1]}}
   local label = frame:expandTemplate{title = 'Translation', args = {args[1]}}
   local content = ""
   local content = ""
   if p.clean_arg(args[2]) then
   if not p._empty_arg(args[2]) then
     content = args[3] or args[2]
     content = args[3] or args[2]
   elseif p.clean_arg(args[4]) then -- We might want to remove this since it is only used to display "None required" for field required-technologies, but it's kind of obvious no technologies are required if it's not in the infobox already
   else -- We might want to remove this since it is only used to display "None required" for field required-technologies, but it's kind of obvious no technologies are required if it's not in the infobox already
     content = "<i>" .. args[4] .. "</i>"
     content = "<i>" .. args[4] .. "</i>"
   end
   end
Line 137: Line 140:
end
end


 
-- @param arg string The argument to check
function p._clean_arg(arg)
-- @return boolean @Whether the argument is an whitespace string or empty string or nil
if type(arg) == "string" then
function p._empty_arg(arg)
arg = mw.text.trim(arg)
  if type(arg) == "string" then
if arg == "" then
    return not string.find(arg, "%S")
return nil
  else
else
    return not arg
return arg
  end
end
else
return arg
end
end
end



Revision as of 19:08, 23 October 2024

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

local p = {}

function p.row(frame)
  local args = frame.args
  if p._empty_arg(args[2]) then
    return
  end

  local label = frame:expandTemplate{title = 'Translation', args = {args[1]}}

  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)
  local args = frame.args
  if p._empty_arg(args[2]) and p._empty_arg(args[4]) then
    return
  end

  local label = frame:expandTemplate{title = 'Translation', args = {args[1]}}
  local content = ""
  if not p._empty_arg(args[2]) then
    content = args[3] or args[2]
  else -- We might want to remove this since it is only used to display "None required" for field required-technologies, but it's kind of obvious no technologies are required if it's not in the infobox already
    content = "<i>" .. args[4] .. "</i>"
  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,
    content)
end

function p.technology_parsing(frame)
  local args = frame.args
  if args[1] == "?" then
    return args[1] -- same as old template, likely not needed
  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)
  local args = frame.args
  if args[1] == "?" then
    return args[1] -- same as old template, likely not needed
  end

  local ret = {}
  local items = p._split(args[1], "+")
  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)
  local args = frame.args
  if args[1] == "?" then
    return args[1] -- same as old template, likely not needed
  end
  
  local recipe_parts = p._split(args[1], "=")  
  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)
  local args = frame.args
  if args[1] == "?" then
    return args[1] -- same as old template, likely not needed
  end

  local recipe_parts = p._split(args[1], "=")
  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

-- @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

return p