Module:Callout

From Space Station 14 Wiki

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

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

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

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

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

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

	-- [REQUIRED]
	
	-- Callout type.
	local type = args[1]
    assert_value_not_nil(type, "failed to generate a callout: type was not provided")
    
    -- Callout content.
    local content = args[2]
    assert_value_not_nil(content, "failed to generate a callout: content was not provided")

	-- [OPTIONAL]

    -- Haeder. Can be `nil` - inferred from the type in that case.
    local header = args.header or args.h

    -- Callout align.
    local align = string.lower(args.align or args.a or 'left')

    -- An image to add to the callout.
    local image1 = args.image or args.image1 or args.i

    -- A second image to add to the callout.
    local image2 = args.image2 or args.i2

    -- A flag for making compact, same-width callouts that can be stacked on top of each other.
    local stacked = yesNo(args.stacked or false)

    -- A class to add to the wrapper element.
    local wrapper_class = args["wrapper class"]

    -- [HARDCODED]

    -- Default size of an image.
    local image_size = '80px'

    -- Width of the left thicc border.
    local strip_width = '10px'

    -- [AUTOCALCULATED]

    -- When in this mode, the callout will span almost fully across the page.
    local in_banner_mode = align == "center"

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

    local callout_wrapper_el = mw.html.create("div")
        :addClass("callout-wrapper")
        :css('justify-content', align)

    if stacked then
        callout_wrapper_el:addClass("stacked-notice");
    end

    if(wrapper_class) then
        callout_wrapper_el:addClass(wrapper_class)
    end

    local type_lower = string.lower(type)
    

    local callout_el = mw.html.create("div")
        :addClass("callout")
        :addClass("callout-type-" .. type_lower)
        :css('--strip-size', strip_width)
        :css('clip-path', "polygon(0 0, 100% 0, 100% 100%, calc(var(--strip-size) / 2) 100%, 0 calc(100% - var(--strip-size) / 2))")

    if in_banner_mode then
        callout_el:addClass("callout-banner")
    end

    callout_wrapper_el:node(callout_el)

   
    local header_by_type
    if type_lower == 'info' then
        header_by_type = 'Info'
    elseif type_lower == 'warning' then
        header_by_type = 'Warning'
    elseif type_lower == 'danger' then
        header_by_type = 'Danger'
    elseif type_lower == 'tip' then
        header_by_type = 'Tip'
    elseif type_lower == 'example' then
        header_by_type = 'Example'
    else
        error("failed to generate a callout: unknow callout type: " .. type)
    end

    -- if header is unset, infer it from the type
    if header == nil then
        header = header_by_type
    end


    local callout_images_el = mw.html.create("div")
        :addClass("callout-images")

    if image1 then
        callout_images_el:wikitext("[[File:" .. image1 .. "|" .. image_size .. "]]")
    end

    if image2 then
        callout_images_el:wikitext("[[File:" .. image2 .. "|" .. image_size .. "]]")
    end

    callout_el:node(callout_images_el)


    local callout_header_content_container_el = mw.html.create("div")
        :addClass("callout-header-content-container")

    callout_el:node(callout_header_content_container_el)


    local callout_header = mw.html.create("div")
        :addClass("callout-header")
        :node(header)

    callout_header_content_container_el:node(callout_header)


    local callout_content_container = mw.html.create("div")
        :addClass("callout-content-container")

    callout_header_content_container_el:node(callout_content_container)


    local callout_content = mw.html.create("div")
        :addClass("callout-content")
        :node(content)

    callout_content_container:node(callout_content)


    return callout_wrapper_el
        :allDone()

end

return p