Changes

Jump to navigation Jump to search
1,464 bytes removed ,  19:41, 24 October 2018
minor optimisations (minimise tables, no need to trim named template arguments, build HTML directly where safe, use numeric for loops), fix missing commas in alt names
Line 1: Line 1:  
local p = {}
 
local p = {}
 
local private = {}
 
local private = {}
  −
--##########
  −
--## Constants
  −
--##########
  −
-- The valid status values.
  −
local statuses = {
  −
  ok = "ok",
  −
  optional = "optional",
  −
  unofficial = "unofficial",
  −
  workaround = "workaround",
  −
  broken = "broken",
  −
  abandoned = "abandoned",
  −
  obsolete = "obsolete"
  −
}
  −
      
--##########
 
--##########
Line 23: Line 8:  
-- @test mw.log(p.header())
 
-- @test mw.log(p.header())
 
function p.header()
 
function p.header()
   local row = mw.html.create("tr")
+
   return
  row:node(mw.html.create("th"):wikitext("mod name"))
+
    '<table class="wikitable plainlinks">'
  row:node(mw.html.create("th"):wikitext("author"))
+
    .. "<tr><th>mod name</th><th>author</th><th>compatibility</th><th>broke in</th><th>source</th><th>&nbsp;</th></tr>";
  row:node(mw.html.create("th"):wikitext("compatibility"))
  −
  row:node(mw.html.create("th"):wikitext("broke in"))
  −
  row:node(mw.html.create("th"):wikitext("source"))
  −
  row:node(mw.html.create("th"):wikitext("&nbsp;"))
  −
 
  −
  return '<table class="wikitable plainlinks">' .. tostring(row)
   
end
 
end
   Line 45: Line 24:  
function p.entry(frame)
 
function p.entry(frame)
 
   -- read input args
 
   -- read input args
   local names      = private.parseCommaDelimited((private.trim(frame.args["name"]) or '') .. ',' .. (private.trim(frame.args["name2"]) or ''))
+
   local names      = private.parseCommaDelimited((frame.args["name"] or '') .. ',' .. (frame.args["name2"] or ''))
   local authors    = private.parseCommaDelimited((private.trim(frame.args["author"]) or '') .. ',' .. (private.trim(frame.args["author2"]) or ''))
+
   local authors    = private.parseCommaDelimited((frame.args["author"] or '') .. ',' .. (frame.args["author2"] or ''))
   local ids        = private.parseCommaDelimited((private.trim(frame.args["id"]) or '') .. ',' .. (private.trim(frame.args["old ids"]) or ''))
+
   local ids        = private.parseCommaDelimited((frame.args["id"] or '') .. ',' .. (frame.args["old ids"] or ''))
   local nexusID    = private.emptyToNil(private.trim(frame.args["nexus id"]))
+
   local nexusID    = private.emptyToNil(frame.args["nexus id"])
   local github    = private.emptyToNil(private.trim(frame.args["github"]))
+
   local github    = private.emptyToNil(frame.args["github"])
   local summary    = private.emptyToNil(private.trim(frame.args["summary"]))
+
   local summary    = private.emptyToNil(frame.args["summary"])
   local brokeIn    = private.emptyToNil(private.trim(frame.args["broke in"]))
+
   local brokeIn    = private.emptyToNil(frame.args["broke in"])
   −
   local status    = private.emptyToNil(private.trim(frame.args["status"]))
+
   local status    = private.emptyToNil(frame.args["status"])
   local unofficialVersion = private.emptyToNil(private.trim(frame.args["unofficial version"]))
+
   local unofficialVersion = private.emptyToNil(frame.args["unofficial version"])
   local unofficialUrl    = private.emptyToNil(private.trim(frame.args["unofficial url"]))
+
   local unofficialUrl    = private.emptyToNil(frame.args["unofficial url"])
   local oldIDs        = private.emptyToNil(private.trim(frame.args["old ids"]))
+
   local oldIDs        = private.emptyToNil(frame.args["old ids"])
   local chucklefishID = private.emptyToNil(private.trim(frame.args["cf id"]))
+
   local chucklefishID = private.emptyToNil(frame.args["cf id"])
   local customUrl    = private.emptyToNil(private.trim(frame.args["url"]))
+
   local customUrl    = private.emptyToNil(frame.args["url"])
   local customSource  = private.emptyToNil(private.trim(frame.args["source"]))
+
   local customSource  = private.emptyToNil(frame.args["source"])
   local name2        = private.emptyToNil(private.trim(frame.args["name2"]))
+
   local name2        = private.emptyToNil(frame.args["name2"])
   local author2      = private.emptyToNil(private.trim(frame.args["author2"]))
+
   local author2      = private.emptyToNil(frame.args["author2"])
 
   local links        = private.parseCommaDelimited(frame.args["links"])
 
   local links        = private.parseCommaDelimited(frame.args["links"])
 
   local warnings      = private.parseCommaDelimited(frame.args["warnings"])
 
   local warnings      = private.parseCommaDelimited(frame.args["warnings"])
   −
   local betaSummary = private.emptyToNil(private.trim(frame.args["beta summary"]))
+
   local betaSummary = private.emptyToNil(frame.args["beta summary"])
   local betaBrokeIn = private.emptyToNil(private.trim(frame.args["beta broke in"]))
+
   local betaBrokeIn = private.emptyToNil(frame.args["beta broke in"])
   local betaStatus  = private.emptyToNil(private.trim(frame.args["beta status"]))
+
   local betaStatus  = private.emptyToNil(frame.args["beta status"])
   local betaUnofficialVersion = private.emptyToNil(private.trim(frame.args["beta unofficial version"]))
+
   local betaUnofficialVersion = private.emptyToNil(frame.args["beta unofficial version"])
   local betaUnofficialUrl    = private.emptyToNil(private.trim(frame.args["beta unofficial url"]))
+
   local betaUnofficialUrl    = private.emptyToNil(frame.args["beta unofficial url"])
    
   -- parse compatibility
 
   -- parse compatibility
Line 96: Line 75:  
   -- get background color
 
   -- get background color
 
   local background = '#999'
 
   local background = '#999'
   if compat.status == statuses.ok or compat.status == statuses.optional then
+
   if compat.status == "ok" or compat.status == "optional" then
 
     background = '#9F9'
 
     background = '#9F9'
   elseif compat.status == statuses.workaround or compat.status == statuses.unofficial then
+
   elseif compat.status == "workaround" or compat.status == "unofficial" then
 
     background = '#CF9'
 
     background = '#CF9'
   elseif compat.status == statuses.broken then
+
   elseif compat.status == "broken" then
 
     background = '#F99'
 
     background = '#F99'
   elseif compat.status == statuses.obsolete or compat.status == statuses.abandoned then
+
   elseif compat.status == "obsolete" or compat.status == "abandoned" then
 
     background = '#999'
 
     background = '#999'
 
   end
 
   end
Line 109: Line 88:  
   local row = mw.html.create("tr")
 
   local row = mw.html.create("tr")
 
   row:addClass("mod")
 
   row:addClass("mod")
   row:attr("id", names[1] and mw.uri.anchorEncode(names[1]) or nil);
+
   row:attr("id", names[1] and mw.uri.anchorEncode(names[1]));
 
   row:attr("data-name", table.concat(names, ","))
 
   row:attr("data-name", table.concat(names, ","))
 
   row:attr("data-id", table.concat(ids, ","))
 
   row:attr("data-id", table.concat(ids, ","))
Line 123: Line 102:  
   row:attr("data-unofficial-version", compat.unofficialVersion)
 
   row:attr("data-unofficial-version", compat.unofficialVersion)
 
   row:attr("data-unofficial-url", compat.unofficialUrl)
 
   row:attr("data-unofficial-url", compat.unofficialUrl)
   row:attr("data-beta-status", betaCompat and betaCompat.status or nil)
+
   row:attr("data-beta-status", betaCompat and betaCompat.status)
   row:attr("data-beta-summary", betaCompat and betaCompat.summary or nil)
+
   row:attr("data-beta-summary", betaCompat and betaCompat.summary)
   row:attr("data-beta-broke-in", betaCompat and betaCompat.brokeIn or nil)
+
   row:attr("data-beta-broke-in", betaCompat and betaCompat.brokeIn)
   row:attr("data-beta-unofficial-version", betaCompat and betaCompat.unofficialVersion or nil)
+
   row:attr("data-beta-unofficial-version", betaCompat and betaCompat.unofficialVersion)
   row:attr("data-beta-unofficial-url", betaCompat and betaCompat.unofficialUrl or nil)
+
   row:attr("data-beta-unofficial-url", betaCompat and betaCompat.unofficialUrl)
 
   row:attr("data-warnings", private.emptyToNil(table.concat(warnings, ",")))
 
   row:attr("data-warnings", private.emptyToNil(table.concat(warnings, ",")))
 
   row:attr("style", "line-height: 1em; background: " .. background .. ";")
 
   row:attr("style", "line-height: 1em; background: " .. background .. ";")
Line 135: Line 114:  
   do
 
   do
 
     local field = mw.html.create("td")
 
     local field = mw.html.create("td")
 +
 
     field:wikitext("[" .. (url or '') .. " " .. (names[1] or '') .. "]")
 
     field:wikitext("[" .. (url or '') .. " " .. (names[1] or '') .. "]")
   −
     if #names > 1 then
+
     local nameCount = #names
       local altNames = mw.html.create("small"):wikitext("(aka ")
+
    if nameCount > 1 then
       for k, v in pairs(names) do
+
       field:wikitext("<br /><small>(aka ")
         if k > 1 then
+
       for i = 1, nameCount do
           altNames:wikitext(v)
+
         if i > 1 then
 +
           field:wikitext(names[i])
 +
          if i < nameCount then
 +
            field:wikitext(", ")
 +
          end
 
         end
 
         end
 
       end
 
       end
       altNames:wikitext(")")
+
       field:wikitext(")</small>")
      field:node(mw.html.create("br"))
  −
      field:node(altNames)
   
     end
 
     end
   Line 158: Line 140:     
     field:wikitext(authors[1])
 
     field:wikitext(authors[1])
     if #authors > 1 then
+
 
       local altNames = mw.html.create("small"):wikitext("(aka ")
+
     local authorCount = #authors
       for k, v in pairs(authors) do
+
    if authorCount > 1 then
         if k > 1 then
+
       field:wikitext("<br /><small>(aka ")
           altNames:wikitext(v)
+
       for i = 1, authorCount do
 +
         if i > 1 then
 +
           field:wikitext(authors[i])
 +
          if i < authorCount then
 +
            field:wikitext(", ")
 +
          end
 
         end
 
         end
 
       end
 
       end
       altNames:wikitext(")")
+
       field:wikitext(")</small>")
      field:node(mw.html.create("br"))
  −
      field:node(altNames)
   
     end
 
     end
   Line 180: Line 165:  
     -- stable status
 
     -- stable status
 
     field:wikitext(compat.summaryIcon .. " " .. compat.summary)
 
     field:wikitext(compat.summaryIcon .. " " .. compat.summary)
     if compat.status == statuses.optional then
+
     if compat.status == "optional" then
 
       field:wikitext("<ref name=\"optional-update\" />")
 
       field:wikitext("<ref name=\"optional-update\" />")
 
     end
 
     end
Line 186: Line 171:  
     -- beta status
 
     -- beta status
 
     if betaCompat ~= nill then
 
     if betaCompat ~= nill then
       field:node(mw.html.create("br"))
+
       field:wikitext("<br />")
 
       field:wikitext("'''SDV beta only:''' " .. betaCompat.summaryIcon .. " " .. betaCompat.summary)
 
       field:wikitext("'''SDV beta only:''' " .. betaCompat.summaryIcon .. " " .. betaCompat.summary)
       if betaCompat.status == statuses.optional then
+
       if betaCompat.status == "optional" then
 
         field:wikitext("<ref name=\"optional-update\" />")
 
         field:wikitext("<ref name=\"optional-update\" />")
 
       end
 
       end
Line 194: Line 179:     
     -- warnings
 
     -- warnings
     if #warnings > 0 then
+
     do
      for k, v in pairs(warnings) do
+
      local warningCount = #warnings
        field:node(mw.html.create("br"))
+
      if warningCount > 0 then
        field:wikitext("⚠ " .. v)
+
        for i = 1, warningCount do
 +
          field:wikitext("<br />⚠ " .. warnings[i])
 +
        end
 
       end
 
       end
 
     end
 
     end
Line 221: Line 208:  
   -- add 'source' field
 
   -- add 'source' field
 
   do
 
   do
    local field = mw.html.create("td")
  −
   
     if sourceUrl then
 
     if sourceUrl then
       field:wikitext("[" .. sourceUrl .. " source]")
+
       row:wikitext("<td>[" .. sourceUrl .. " source]</td>")
 
     else
 
     else
       field:wikitext("<span style=\"color: red; font-size: 0.85em; opacity: 0.5;\">closed source</span>")
+
       row:wikitext("<td><span style=\"color: red; font-size: 0.85em; opacity: 0.5;\">closed source</span></td>")
 
     end
 
     end
  −
    row:node(field)
   
     row:newline()
 
     row:newline()
 
   end
 
   end
Line 242: Line 225:     
     -- reference links
 
     -- reference links
     for k, v in pairs(links) do
+
     do
      field:wikitext("[" .. v .. " " .. k .. "] ")
+
      local linkCount = #links
 +
      for i = 1, linkCount do
 +
        field:wikitext("[" .. links[i] .. " " .. i .. "] ")
 +
      end
 
     end
 
     end
   Line 252: Line 238:     
     -- backwards-compatible metadata (temporary)
 
     -- backwards-compatible metadata (temporary)
     local metadata = mw.html.create("div")
+
     field:wikitext('<div div class="mod-metadata" style="display: none;">')
    metadata:addClass("mod-metadata")
+
     field:wikitext('<div class="mod-anchor">' .. (names[1] and mw.uri.anchorEncode(names[1])) .. "</div>")
    metadata:attr("style", "display: none;")
+
    field:wikitext('<div class="mod-id">' .. mw.text.encode(table.concat(ids, ",")) .. "</div>")
     metadata:node(mw.html.create("div"):addClass("mod-anchor"):wikitext(names[1] and mw.uri.anchorEncode(names[1])))
+
    field:wikitext('<div class="mod-url">' .. mw.text.encode(url) .. "</div>")
    metadata:node(mw.html.create("div"):addClass("mod-id"):wikitext(table.concat(ids, ",")))
  −
    metadata:node(mw.html.create("div"):addClass("mod-url"):wikitext(url))
   
     if nexusID ~= nil then
 
     if nexusID ~= nil then
       metadata:node(mw.html.create("div"):addClass("mod-nexus-id"):wikitext(nexusID))
+
       field:wikitext('<div class="mod-nexus-id">' .. mw.text.encode(nexusID) .. "</div>")
 
     end
 
     end
 
     if chucklefishID ~= nil then
 
     if chucklefishID ~= nil then
       metadata:node(mw.html.create("div"):addClass("mod-cf-id"):wikitext(chucklefishID))
+
       field:wikitext('<div class="mod-cf-id">' .. mw.text.encode(chucklefishID) .. "</div>")
 
     end
 
     end
 
     if github ~= nil then
 
     if github ~= nil then
       metadata:node(mw.html.create("div"):addClass("mod-github"):wikitext(github))
+
       field:wikitext('<div class="mod-github">' .. mw.text.encode(github) .. '</div>')
 
     end
 
     end
 
     if customSource ~= nil then
 
     if customSource ~= nil then
       metadata:node(mw.html.create("div"):addClass("mod-custom-source"):wikitext(customSource))
+
       field:wikitext('<div class="mod-custom-source">' .. mw.text.encode(customSource) .. '</div>')
 
     end
 
     end
     metadata:node(mw.html.create("div"):addClass("mod-status"):wikitext(compat.status))
+
     field:wikitext('<div class="mod-status">' .. mw.text.encode(compat.status) .. '</div>')
 
     if compat.brokeIn ~= nil then
 
     if compat.brokeIn ~= nil then
       metadata:node(mw.html.create("div"):addClass("mod-broke-in"):wikitext(compat.brokeIn))
+
       field:wikitext('<div class="mod-broke-in">' .. mw.text.encode(compat.brokeIn) .. '</div>')
 
     end
 
     end
 
     if compat.unofficialVersion ~= nil and compat.unofficialUrl ~= nil then
 
     if compat.unofficialVersion ~= nil and compat.unofficialUrl ~= nil then
       metadata:node(mw.html.create("div"):addClass("mod-unofficial-version"):wikitext(compat.unofficialVersion))
+
       field:wikitext('<div class="mod-unofficial-version">' .. mw.text.encode(compat.unofficialVersion) .. '</div>')
       metadata:node(mw.html.create("div"):addClass("mod-unofficial-url"):wikitext(compat.unofficialUrl))
+
       field:wikitext('<div class="mod-unofficial-url">' .. mw.text.encode(compat.unofficialUrl) .. '</div>')
 
     end
 
     end
 
     if betaCompat ~= nil then
 
     if betaCompat ~= nil then
       metadata:node(mw.html.create("div"):addClass("mod-beta-status"):wikitext(betaCompat.status))
+
       field:wikitext('<div class="mod-beta-status">' .. mw.text.encode(betaCompat.status) .. '</div>')
 
       if betaCompat.brokeIn ~= nil then
 
       if betaCompat.brokeIn ~= nil then
         metadata:node(mw.html.create("div"):addClass("mod-beta-broke-in"):wikitext(betaCompat.brokeIn))
+
         field:wikitext('<div class="mod-beta-broke-in">' .. mw.text.encode(betaCompat.brokeIn) .. '</div>')
 
       end
 
       end
 
       if betaCompat.unofficialVersion ~= nil and betaCompat.unofficialUrl ~= nil then
 
       if betaCompat.unofficialVersion ~= nil and betaCompat.unofficialUrl ~= nil then
         metadata:node(mw.html.create("div"):addClass("mod-beta-unofficial-version"):wikitext(betaCompat.unofficialVersion))
+
         field:wikitext('<div class="mod-beta-unofficial-version">' .. mw.text.encode(betaCompat.unofficialVersion) .. '</div>')
         metadata:node(mw.html.create("div"):addClass("mod-beta-unofficial-url"):wikitext(betaCompat.unofficialUrl))
+
         field:wikitext('<div class="mod-beta-unofficial-url">' .. mw.text.encode(betaCompat.unofficialUrl) .. '</div>')
 
       end
 
       end
 
     end
 
     end
 
     if #warnings > 0 then
 
     if #warnings > 0 then
       metadata:node(mw.html.create("div"):addClass("mod-warnings"):wikitext(table.concat(warnings, ",")))
+
       field:wikitext('<div class="mod-warnings">' .. mw.text.encode(table.concat(warnings, ",")) .. '</div>')
 
     end
 
     end
 +
    field.wikitext("</div>")
   −
    field:node(metadata)
   
     row:node(field)
 
     row:node(field)
 
   end
 
   end
Line 308: Line 292:  
   if value == nil or value == "" then
 
   if value == nil or value == "" then
 
     return ""
 
     return ""
   else  
+
   else
 
     return key .. "=\"" .. mw.text.encode(value) .. "\""
 
     return key .. "=\"" .. mw.text.encode(value) .. "\""
 
   end
 
   end
Line 318: Line 302:  
--##########
 
--##########
 
-- Get the normalised compatibility info for a mod.
 
-- Get the normalised compatibility info for a mod.
-- @param status The specified status code (one of the `statuses` values). If nil or blank, it'll be derived from the other fields.
+
-- @param status The specified status code. If nil or blank, it'll be derived from the other fields.
 
-- @param summary A human-readable summary of the compatibility info. If nil or blank, it'll be derived from the other fields.
 
-- @param summary A human-readable summary of the compatibility info. If nil or blank, it'll be derived from the other fields.
 
-- @param brokeIn The SMAPI or Stardew Valley version which broke the mod, if applicable.
 
-- @param brokeIn The SMAPI or Stardew Valley version which broke the mod, if applicable.
Line 325: Line 309:  
-- @param hasSource Whether the mod has public source code available.
 
-- @param hasSource Whether the mod has public source code available.
 
function private.getCompatInfo(status, summary, brokeIn, unofficialVersion, unofficialUrl, hasSource)
 
function private.getCompatInfo(status, summary, brokeIn, unofficialVersion, unofficialUrl, hasSource)
  -- normalise values
  −
  status = private.emptyToNil(private.trim(status))
  −
  summary = private.emptyToNil(private.trim(summary))
  −
  brokeIn = private.emptyToNil(private.trim(brokeIn))
  −
  unofficialVersion = private.emptyToNil(private.trim(unofficialVersion))
  −
  unofficialUrl = private.emptyToNil(private.trim(unofficialUrl))
  −
   
   -- derive status
 
   -- derive status
 
   if status == nil then
 
   if status == nil then
 
     if unofficialVersion ~= nil then
 
     if unofficialVersion ~= nil then
       status = statuses.unofficial
+
       status = "unofficial"
 
     elseif brokeIn ~= nil then
 
     elseif brokeIn ~= nil then
       status = statuses.broken
+
       status = "broken"
 
     else
 
     else
       status = statuses.ok
+
       status = "ok"
 
     end
 
     end
 
   end
 
   end
Line 345: Line 322:  
   -- derive summary icon
 
   -- derive summary icon
 
   local summaryIcon = "✓"
 
   local summaryIcon = "✓"
   if status == statuses.unofficial or status == statuses.workaround then
+
   if status == "unofficial" or status == "workaround" then
 
     summaryIcon = "⚠"
 
     summaryIcon = "⚠"
   elseif status == statuses.broken and hasSource then
+
   elseif status == "broken" and hasSource then
 
     summaryIcon = "↻"
 
     summaryIcon = "↻"
   elseif status == statuses.broken or status == statuses.obsolete or status == statuses.abandoned then
+
   elseif status == "broken" or status == "obsolete" or status == "abandoned" then
 
     summaryIcon = "✖"
 
     summaryIcon = "✖"
 
   end
 
   end
Line 355: Line 332:  
   -- derive summary
 
   -- derive summary
 
   if summary == nil then
 
   if summary == nil then
     if status == statuses.ok then
+
     if status == "ok" then
 
       summary = "use latest version."
 
       summary = "use latest version."
     elseif status == statuses.optional then
+
     elseif status == "optional" then
 
       summary = "use optional download."
 
       summary = "use optional download."
     elseif status == statuses.unofficial then
+
     elseif status == "unofficial" then
 
       summary = "broken, use [" .. (unofficialUrl or "") .. " " .. "unofficial version]"
 
       summary = "broken, use [" .. (unofficialUrl or "") .. " " .. "unofficial version]"
 
       if unofficialVersion ~= nil then
 
       if unofficialVersion ~= nil then
Line 365: Line 342:  
       end
 
       end
 
       summary = summary .. "."
 
       summary = summary .. "."
     elseif status == statuses.workaround then
+
     elseif status == "workaround" then
 
       summary = "broken. '''error:''' should specify summary."
 
       summary = "broken. '''error:''' should specify summary."
     elseif status == statuses.broken then
+
     elseif status == "broken" then
 
       if hasSource then
 
       if hasSource then
 
         summary = "broken, not updated yet."
 
         summary = "broken, not updated yet."
Line 373: Line 350:  
         summary = "broken, not open-source."
 
         summary = "broken, not open-source."
 
       end
 
       end
     elseif status == statuses.obsolete then
+
     elseif status == "obsolete" then
 
       summary = "obsolete."
 
       summary = "obsolete."
     elseif status == statuses.abandoned then
+
     elseif status == "abandoned" then
 
       summary = "no longer maintained."
 
       summary = "no longer maintained."
 
     else
 
     else
Line 390: Line 367:  
     unofficialUrl = unofficialUrl
 
     unofficialUrl = unofficialUrl
 
   }
 
   }
end
  −
  −
-- Trim a string value.
  −
-- @param value The string to trim.
  −
function private.trim(value)
  −
  if value ~= nil then
  −
    return mw.text.trim(value)
  −
  else
  −
    return value
  −
  end
   
end
 
end
   Line 418: Line 385:     
   if value ~= nil then
 
   if value ~= nil then
     for k, v in pairs(mw.text.split(value, ",", true)) do
+
     local values = mw.text.split(value, ",", true)
       v = mw.text.trim(v)
+
    for i = 1, #values do
 +
       v = mw.text.trim(values[i])
 
       if v ~= "" then
 
       if v ~= "" then
 
         table.insert(result, v)
 
         table.insert(result, v)
translators
8,404

edits

Navigation menu