Module:Item infobox: Difference between revisions
From Space Station 14 Wiki
GOD I LOVE FOOD |
No edit summary |
||
(4 intermediate revisions by the same user not shown) | |||
Line 22: | Line 22: | ||
-- ========================== | -- ========================== | ||
local function assert_not_nil(value, error_message) | |||
if value == nil then | |||
if error_message == nil then | |||
error("value is nil") | |||
else | |||
error(error_message) | |||
end | |||
end | |||
end | |||
local function starts_with(str, substr) | local function starts_with(str, substr) | ||
Line 58: | Line 68: | ||
local function table_contains(tbl, findFn) | local function table_contains(tbl, findFn) | ||
return table_find(tbl, findFn) ~= nil | return table_find(tbl, findFn) ~= nil | ||
end | |||
local function table_contains_value(tbl, value) | |||
return table_find(tbl, function(iter_value) | |||
return iter_value == value | |||
end) ~= nil | |||
end | end | ||
Line 103: | Line 119: | ||
if table_length(edible_by_args) == 0 then | if table_length(edible_by_args) == 0 then | ||
return | return "" | ||
end | end | ||
Line 129: | Line 145: | ||
-- returns the index ("order") of that entry. | -- returns the index ("order") of that entry. | ||
-- throws if no param was found (ie not defined in the table). | -- throws if no param was found (ie not defined in the table). | ||
function find_edible_by_order(param_name_lc) | local function find_edible_by_order(param_name_lc) | ||
local index = table_find_index(edible_by_display_tbl, function(value) | local index = table_find_index(edible_by_display_tbl, function(value) | ||
return value.param == param_name_lc | return value.param == param_name_lc | ||
end) | end) | ||
assert_not_nil(index, "failed to find edible by order: param name '" .. | |||
param_name_lc .. "' if not defined in the edible by params table") | |||
return index | return index | ||
Line 165: | Line 179: | ||
local list_el = mw.html.create('ul') | local list_el = mw.html.create('ul') | ||
function append_li(text) | local function append_li(text) | ||
list_el | list_el | ||
:tag("li") | :tag("li") | ||
Line 171: | Line 185: | ||
end | end | ||
function append_li_and_subli(li_text, subli_els) | local function append_li_and_subli(li_text, subli_els) | ||
local li_el = mw.html.create("li") | local li_el = mw.html.create("li") | ||
:wikitext(li_text) | :wikitext(li_text) | ||
Line 193: | Line 207: | ||
append_li(edible_by_rest_entry.display[1]) | append_li(edible_by_rest_entry.display[1]) | ||
else | else | ||
if is_edible_by_rest then | if is_edible_by_rest then | ||
-- edible by | -- if edible by contains the rest option, we compile a list of those excluded from the display table. | ||
-- those selected are excluded from the compiled list. | |||
local | -- compile a list of those potentially excluded | ||
local excluded_pool = table_filter(edible_by_display_tbl, function(entry) | |||
return entry.param ~= edible_by_rest_param_name_lc | |||
end) | |||
return | -- find whose excluded (not selected) | ||
local excluded = table_filter(excluded_pool, function(entry) | |||
return not table_contains_value(selected_params_lc, entry.param) | |||
end) | end) | ||
local | -- format em as li els | ||
local excluded_as_li_els = table_map(excluded, function(value) | |||
return mw.html.create("li") | return mw.html.create("li") | ||
:wikitext(value.display) | :wikitext(value.display) | ||
end) | end) | ||
append_li_and_subli(edible_by_rest_entry.display[2], | append_li_and_subli(edible_by_rest_entry.display[2], excluded_as_li_els) | ||
else | |||
-- if edible by doesn't contain the rest option, then its a regular list | |||
for _, param_name_lc in ipairs(selected_params_lc) do | |||
local entry = table_find(edible_by_display_tbl, function(entry) | |||
return entry.param == param_name_lc | |||
end) | |||
assert_not_nil(entry, "failed to generate edible by param: param '" .. | |||
param_name_lc .. "' (lowercase) is not defined in the edible by display table") | |||
append_li(entry.display) | |||
end | |||
end | end | ||
end | end | ||
return list_el | return tostring(list_el) | ||
end | end | ||
return p | return p |
Latest revision as of 01:58, 4 April 2025
Module documentation
|
---|
View or edit this documentation • (about module documentation) |
Contains partial implementation for {{Item infobox}}.
Edible by params
Edible by parameters are implemented in this module, entrypoint generate_edible_by
.
List of edible by params is defined by edible_by_display_tbl
.
Tests
Module:Item infobox/testcases/edible by
✅ All tests passed.
Name | Expected | Actual | |
---|---|---|---|
✅ | test_empty | ||
✅ | test_everyone | ||
✅ | test_everyone_except_other_options | ||
✅ | test_everyone_except_reptilians | ||
✅ | test_moth | ||
✅ | test_reptilian |
local p = {}
local getArgs = require('Module:Arguments').getArgs
local yesNo = require('Module:Yesno')
-- ==========================
local edible_by_rest_param_name_lc = "edible by rest"
-- A list of edible by parameters along with the texts to display for each.
-- Param names defined here must be lowercase.
--
-- "edible by rest" is a special case, hence the table format.
-- * If all options are selected, including "edible by rest" (ie food is edible by everyone),
-- then the first form will be used.
-- * If only some options are selected, including "edible by rest",
-- then the second form will be used, following by a list of unselected options.
local edible_by_display_tbl = {
{ param = "edible by reptilians", display = "Reptilians" },
{ param = "edible by moths", display = "Moth people" },
{ param = edible_by_rest_param_name_lc, display = { "Everyone", "Everyone, except:" } },
}
-- ==========================
local function assert_not_nil(value, error_message)
if value == nil then
if error_message == nil then
error("value is nil")
else
error(error_message)
end
end
end
local function starts_with(str, substr)
return string.sub(str, 1, string.len(substr)) == substr
end
local function ends_with(str, substr)
local substr_length = string.len(substr)
return string.sub(str, string.len(str) - substr_length + 1, string.len(str)) == substr
end
local function starts_with_insensitive(str, substr)
return starts_with(string.lower(str), string.lower(substr))
end
local function ends_with_insensitive(str, substr)
return ends_with(string.lower(str), string.lower(substr))
end
local function table_filter(tbl, filterFn)
local out = {}
for k, v in pairs(tbl) do
if filterFn(v, k, tbl) then out[k] = v end
end
return out
end
local function table_find(tbl, findFn)
for k, v in pairs(tbl) do
if findFn(v, k, tbl) then return v end
end
end
local function table_contains(tbl, findFn)
return table_find(tbl, findFn) ~= nil
end
local function table_contains_value(tbl, value)
return table_find(tbl, function(iter_value)
return iter_value == value
end) ~= nil
end
local function table_find_key(tbl, findFn)
for k, v in pairs(tbl) do
if findFn(v, k, tbl) then return k end
end
end
local function table_find_index(tbl, findFn)
for i, v in ipairs(tbl) do
if findFn(v, i, tbl) then return i end
end
end
local function table_map(tbl, mapFn)
local res = {}
for k, v in pairs(tbl) do
table.insert(res, mapFn(v, k, tbl))
end
return res
end
local function numeric_table_length(t)
local count = 0
for _ in ipairs(t) do count = count + 1 end
return count
end
local function table_length(t)
local count = 0
for _ in pairs(t) do count = count + 1 end
return count
end
-- ==========================
function p.generate_edible_by(frame)
local args = getArgs(frame)
local edible_by_args = table_filter(args, function(value, key)
return starts_with_insensitive(key, "edible by")
end)
if table_length(edible_by_args) == 0 then
return ""
end
local edible_by_rest_key = table_find_key(edible_by_args, function(value, key)
return ends_with_insensitive(key, "rest")
end)
-- save the edible by rest value to use later
local is_edible_by_rest = yesNo(edible_by_args[edible_by_rest_key])
-- generate a temp table made up only of numerical params to make it sortable.
-- get rid of unselected "edible by"s.
local selected_params_lc = {}
for key, value in pairs(edible_by_args) do
-- iterate over each key except edible by rest
if key ~= edible_by_rest_key then
-- check if its selected
if yesNo(value) then
table.insert(selected_params_lc, string.lower(key))
end
end
end
-- searches for a param name in the params table,
-- returns the index ("order") of that entry.
-- throws if no param was found (ie not defined in the table).
local function find_edible_by_order(param_name_lc)
local index = table_find_index(edible_by_display_tbl, function(value)
return value.param == param_name_lc
end)
assert_not_nil(index, "failed to find edible by order: param name '" ..
param_name_lc .. "' if not defined in the edible by params table")
return index
end
-- sort the temp table based on predefine order
table.sort(selected_params_lc, function(a, b)
return find_edible_by_order(a) > find_edible_by_order(b)
end)
-- render out the params
local edible_by_rest_entry = is_edible_by_rest
and table_find(edible_by_display_tbl, function(value)
return value.param == edible_by_rest_param_name_lc
end)
if is_edible_by_rest and edible_by_rest_entry == nil then
error(
"failed to generate edible by: edible by rest param is enabled, but it is not defined in the display table")
end
local selected_params_lc_len = numeric_table_length(selected_params_lc)
-- count total selected "edible by" params, including the edible by rest
local total_selected_params = selected_params_lc_len + (is_edible_by_rest and 1 or 0)
local display_table_len = numeric_table_length(edible_by_display_tbl)
local list_el = mw.html.create('ul')
local function append_li(text)
list_el
:tag("li")
:wikitext(text) -- relates to the li el, not the list el
end
local function append_li_and_subli(li_text, subli_els)
local li_el = mw.html.create("li")
:wikitext(li_text)
local subli_ul = mw.html.create('ul')
for _, node in ipairs(subli_els) do
subli_ul
:node(node)
end
li_el:
node(subli_ul)
list_el
:node(li_el)
end
if total_selected_params == display_table_len then
-- all params selected, edible by everyone
-- edible by rest is assumed to be on implicitly, cz otherwise the count won't match.
append_li(edible_by_rest_entry.display[1])
else
if is_edible_by_rest then
-- if edible by contains the rest option, we compile a list of those excluded from the display table.
-- those selected are excluded from the compiled list.
-- compile a list of those potentially excluded
local excluded_pool = table_filter(edible_by_display_tbl, function(entry)
return entry.param ~= edible_by_rest_param_name_lc
end)
-- find whose excluded (not selected)
local excluded = table_filter(excluded_pool, function(entry)
return not table_contains_value(selected_params_lc, entry.param)
end)
-- format em as li els
local excluded_as_li_els = table_map(excluded, function(value)
return mw.html.create("li")
:wikitext(value.display)
end)
append_li_and_subli(edible_by_rest_entry.display[2], excluded_as_li_els)
else
-- if edible by doesn't contain the rest option, then its a regular list
for _, param_name_lc in ipairs(selected_params_lc) do
local entry = table_find(edible_by_display_tbl, function(entry)
return entry.param == param_name_lc
end)
assert_not_nil(entry, "failed to generate edible by param: param '" ..
param_name_lc .. "' (lowercase) is not defined in the edible by display table")
append_li(entry.display)
end
end
end
return tostring(list_el)
end
return p