Module:Chem box: Difference between revisions

From Space Station 14 Wiki
(beep boop)
(header text theming)
(9 intermediate revisions by the same user not shown)
Line 3: Line 3:
local yesNo = require('Module:Yesno')
local yesNo = require('Module:Yesno')


local chem_data = mw.loadJsonData("User:UpAndLeaves/chemData.json")
local chem_data = mw.loadJsonData("Module:Chem box/chem data.json")


local current_frame = mw.getCurrentFrame()
local current_frame = mw.getCurrentFrame()
Line 76: Line 76:


     return table.concat(temp_table, sep)
     return table.concat(temp_table, sep)
end
local function ternary_strict(valueToCheck, valueIfTrue, valueIfFalse)
    if valueToCheck == true then
        return valueIfTrue
    else
        return valueIfFalse
    end
end
end


Line 85: Line 93:
-- Set `no_error` to `true` to return `nil` instead.
-- Set `no_error` to `true` to return `nil` instead.
function p.lookup_reagent(query, no_error)
function p.lookup_reagent(query, no_error)
    local query_lower = string.lower(query)
     for _, reagent in ipairs(chem_data) do
     for _, reagent in ipairs(chem_data) do
         assert_value_not_nil(reagent.id)
         assert_value_not_nil(reagent.id)
Line 90: Line 100:


         if reagent.id == query then return reagent end
         if reagent.id == query then return reagent end
         if reagent.name == query then return reagent end
         if string.lower(reagent.name) == query_lower then return reagent end
     end
     end


Line 117: Line 127:
     assert_value_not_nil(reagent.desc)
     assert_value_not_nil(reagent.desc)
     assert_value_not_nil(reagent.physicalDesc)
     assert_value_not_nil(reagent.physicalDesc)
    assert_value_not_nil(reagent.textColorTheme)


     local recipes_container_el = mw.html.create("div")
     local recipes_container_el = mw.html.create("div")
     for _, recipe in ipairs(reagent.recipes) do
     if numeric_table_length(reagent.recipes) == 0 then
         assert_value_not_nil(recipe.id)
         local no_recipes_text_el = mw.html.create("span")
        assert_value_not_nil(recipe.reactants)
            :css("color", "gray")
        assert_value_not_nil(recipe.products)
            :node("No recipes")


         local recipe_box_template_args = {}
         recipes_container_el:node(no_recipes_text_el)
        recipe_box_template_args.name = recipe.id
    else
        for _, recipe in ipairs(reagent.recipes) do
            assert_value_not_nil(recipe.id)
            assert_value_not_nil(recipe.reactants)
            assert_value_not_nil(recipe.products)
 
            local recipe_box_template_args = {}
            recipe_box_template_args.name = recipe.id
 
            -- a list of catalist reactants.
            -- contains "id" and "amount"
            local catalyst_reactants = {}


        for reactant_i, reactant in ipairs(recipe.reactants) do
            for reactant_i, reactant in ipairs(recipe.reactants) do
             local component_el = current_frame:expandTemplate {
                local reactant_id = reactant[1]
                title = 'Recipe Component',
                local reactant_amount = reactant[2]
                args = {
                local reactant_is_catalyst = reactant[3] or false
                    item = reactant[1],
 
                    amount = reactant[2]
                local label = reactant_id
                    -- TODO
 
                    -- image = ""
                if reactant_is_catalyst then
                    table.insert(catalyst_reactants, {
                        id = reactant_id,
                        amount = reactant_amount
                    })
                end
 
                local component_el = current_frame:expandTemplate {
                    title = 'Recipe Component',
                    args = {
                        item = label,
                        amount = reactant_amount
                        -- TODO
                        -- image = ""
                    }
                }
 
                recipe_box_template_args['component-' .. reactant_i] = component_el
             end
 
            recipe_box_template_args.transformer = beaker_el
 
            for product_i, product in ipairs(recipe.products) do
                local component_el = current_frame:expandTemplate {
                    title = 'Recipe Component',
                    args = {
                        item = product[1],
                        amount = product[2]
                        -- TODO
                        -- image = ""
                    }
                 }
                 }
            }


            recipe_box_template_args['component-' .. reactant_i] = component_el
                recipe_box_template_args['result-' .. product_i] = component_el
        end
            end
 
            -- add catalysts as products, if any
            for catalyst_product_i, catalyst_product_entry in ipairs(catalyst_reactants) do
                local product_id = catalyst_product_entry.id
                local product_amount = catalyst_product_entry.amount


        recipe_box_template_args.transformer = beaker_el
                local label = current_frame:expandTemplate {
                    title = 'Tooltip',
                    args = {
                        '<sup class="quickbox-catalyst-note">+</sup>',
                        '<span class="quickbox-catalyst-note-tooltip">This product is a catalyst reactant, remaining after the reaction.</span>'
                    }
                } .. product_id


        for product_i, product in ipairs(recipe.products) do
                local component_el = current_frame:expandTemplate {
            local component_el = current_frame:expandTemplate {
                    title = 'Recipe Component',
                title = 'Recipe Component',
                    args = {
                args = {
                        item = label,
                    item = product[1],
                        amount = product_amount
                    amount = product[2]
                        -- TODO
                    -- TODO
                        -- image = ""
                    -- image = ""
                    }
                 }
                 }
                local index = numeric_table_length(recipe.products) + catalyst_product_i
                recipe_box_template_args['result-' .. index] = component_el
            end
            local recipes_el = current_frame:expandTemplate {
                title = 'Recipe Box',
                args = recipe_box_template_args
             }
             }


             recipe_box_template_args['result-' .. product_i] = component_el
             recipes_container_el:node(recipes_el)
         end
         end
    end


        local recipes_el = current_frame:expandTemplate {
    local effects = concat_numberic_table(reagent.effects, "")
            title = 'Recipe Box',
            args = recipe_box_template_args
        }


        recipes_container_el:node(recipes_el)
     local text_color = ternary_strict(
    end
        reagent.textColorTheme == 'light',
 
        'var(--quickbox-header-text-theme-light)',
     local effects = concat_numberic_table(reagent.effects, "\n")
        'var(--quickbox-header-text-theme-dark)'
    )


     return current_frame:expandTemplate {
     return current_frame:expandTemplate {
Line 171: Line 240:
         args = {
         args = {
             color = reagent.color,
             color = reagent.color,
             -- textcolor = "",
             textcolor = text_color,
             name = reagent.name,
             name = capitalize(reagent.name),
             recipes = tostring(recipes_container_el:allDone()),
             recipes = tostring(recipes_container_el:allDone()),
             metabolisms = effects,
             metabolisms = effects,
Line 179: Line 248:
         }
         }
     }
     }
end
function p.generate_chem_boxes_for_all_reagents()
    local container_el = mw.html.create("div")
        :addClass("reagents-list")
    for _, reagent in ipairs(chem_data) do
        assert_value_not_nil(reagent.id)
        container_el:node(
            p.generate_chem_box {
                reagent.id
            }
        )
    end
    return container_el:allDone()
end
end


return p
return p

Revision as of 19:27, 17 September 2024

Module documentation
View or edit this documentation (about module documentation)
Uses JSON data
This module uses JSON data pages:

Implements {{chem box}}.


local p = {} --p stands for package
local getArgs = require('Module:Arguments').getArgs
local yesNo = require('Module:Yesno')

local chem_data = mw.loadJsonData("Module:Chem box/chem data.json")

local current_frame = mw.getCurrentFrame()

local beaker_el = current_frame:expandTemplate {
    title = 'Beaker'
}

-- ====================


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

local function table_has_value(tab, val)
    for _, value in ipairs(tab) do
        if value == val then
            return true
        end
    end

    return false
end

local function assert_value_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

-- Makes the first letter uppercase.
-- Source: https://stackoverflow.com/a/2421746
local function capitalize(str)
    return (str:gsub("^%l", string.upper))
end

local function passthrough_assert_true(value, valueToReturnIfTrue, errorMessageOnFalse)
    if value then
        return valueToReturnIfTrue
    else
        error(errorMessageOnFalse)
    end
end

local function find_first_numeric_table_item_matching_condition(table, condition)
    for i, item in ipairs(table) do
        if condition(item, i, table) then
            return item
        end
    end
end

-- table concat function because ofcourse fucking table.concat doesn't work
local function concat_numberic_table(tbl, sep)
    local temp_table = {}
    for i = 1, numeric_table_length(tbl) do
        table.insert(temp_table, tbl[i])
    end

    return table.concat(temp_table, sep)
end

local function ternary_strict(valueToCheck, valueIfTrue, valueIfFalse)
    if valueToCheck == true then
        return valueIfTrue
    else
        return valueIfFalse
    end
end

-- ====================

-- Lookups reagent by ID or name.
--
-- Raises an error if no reagent was found.
-- Set `no_error` to `true` to return `nil` instead.
function p.lookup_reagent(query, no_error)
    local query_lower = string.lower(query)

    for _, reagent in ipairs(chem_data) do
        assert_value_not_nil(reagent.id)
        assert_value_not_nil(reagent.name)

        if reagent.id == query then return reagent end
        if string.lower(reagent.name) == query_lower then return reagent end
    end

    return passthrough_assert_true(
        no_error,
        nil,
        "failed to lookup reagent: no match was found"
    )
end

-- ====================

function p.generate_chem_box(frame)
    local args = getArgs(frame)

    local query = args[1]
    assert_value_not_nil(query, "failed to generate chem box: query was not provided")

    -- ===================

    local reagent = p.lookup_reagent(query)
    assert_value_not_nil(reagent.color)
    assert_value_not_nil(reagent.name)
    assert_value_not_nil(reagent.recipes)
    assert_value_not_nil(reagent.effects)
    assert_value_not_nil(reagent.desc)
    assert_value_not_nil(reagent.physicalDesc)
    assert_value_not_nil(reagent.textColorTheme)

    local recipes_container_el = mw.html.create("div")
    if numeric_table_length(reagent.recipes) == 0 then
        local no_recipes_text_el = mw.html.create("span")
            :css("color", "gray")
            :node("No recipes")

        recipes_container_el:node(no_recipes_text_el)
    else
        for _, recipe in ipairs(reagent.recipes) do
            assert_value_not_nil(recipe.id)
            assert_value_not_nil(recipe.reactants)
            assert_value_not_nil(recipe.products)

            local recipe_box_template_args = {}
            recipe_box_template_args.name = recipe.id

            -- a list of catalist reactants.
            -- contains "id" and "amount"
            local catalyst_reactants = {}

            for reactant_i, reactant in ipairs(recipe.reactants) do
                local reactant_id = reactant[1]
                local reactant_amount = reactant[2]
                local reactant_is_catalyst = reactant[3] or false

                local label = reactant_id

                if reactant_is_catalyst then
                    table.insert(catalyst_reactants, {
                        id = reactant_id,
                        amount = reactant_amount
                    })
                end

                local component_el = current_frame:expandTemplate {
                    title = 'Recipe Component',
                    args = {
                        item = label,
                        amount = reactant_amount
                        -- TODO
                        -- image = ""
                    }
                }

                recipe_box_template_args['component-' .. reactant_i] = component_el
            end

            recipe_box_template_args.transformer = beaker_el

            for product_i, product in ipairs(recipe.products) do
                local component_el = current_frame:expandTemplate {
                    title = 'Recipe Component',
                    args = {
                        item = product[1],
                        amount = product[2]
                        -- TODO
                        -- image = ""
                    }
                }

                recipe_box_template_args['result-' .. product_i] = component_el
            end

            -- add catalysts as products, if any
            for catalyst_product_i, catalyst_product_entry in ipairs(catalyst_reactants) do
                local product_id = catalyst_product_entry.id
                local product_amount = catalyst_product_entry.amount

                local label = current_frame:expandTemplate {
                    title = 'Tooltip',
                    args = {
                        '<sup class="quickbox-catalyst-note">+</sup>',
                        '<span class="quickbox-catalyst-note-tooltip">This product is a catalyst reactant, remaining after the reaction.</span>'
                    }
                } .. product_id

                local component_el = current_frame:expandTemplate {
                    title = 'Recipe Component',
                    args = {
                        item = label,
                        amount = product_amount
                        -- TODO
                        -- image = ""
                    }
                }

                local index = numeric_table_length(recipe.products) + catalyst_product_i
                recipe_box_template_args['result-' .. index] = component_el
            end

            local recipes_el = current_frame:expandTemplate {
                title = 'Recipe Box',
                args = recipe_box_template_args
            }

            recipes_container_el:node(recipes_el)
        end
    end

    local effects = concat_numberic_table(reagent.effects, "")

    local text_color = ternary_strict(
        reagent.textColorTheme == 'light',
        'var(--quickbox-header-text-theme-light)',
        'var(--quickbox-header-text-theme-dark)'
    )

    return current_frame:expandTemplate {
        title = 'Manual Chem Box',
        args = {
            color = reagent.color,
            textcolor = text_color,
            name = capitalize(reagent.name),
            recipes = tostring(recipes_container_el:allDone()),
            metabolisms = effects,
            desc = reagent.desc,
            physicalDesc = reagent.physicalDesc,
        }
    }
end

function p.generate_chem_boxes_for_all_reagents()
    local container_el = mw.html.create("div")
        :addClass("reagents-list")

    for _, reagent in ipairs(chem_data) do
        assert_value_not_nil(reagent.id)

        container_el:node(
            p.generate_chem_box {
                reagent.id
            }
        )
    end

    return container_el:allDone()
end

return p