欢迎大家来到沙石镇时光中文维基!本站编辑权限开放,欢迎加入中文维基 QQ 群「沙海时光」:372816689
目前正在进行全站数据更新,期间可能会存在显示异常的问题。

全站通知:

模块:ImageUnifier

来自沙石镇时光维基
跳到导航 跳到搜索

此模块的文档可以在模块:ImageUnifier/doc创建

-- ----------------------------------------
-- <pre> Module:ImageUnifier
-- ----------------------------------------
local Self = {} -- table of functions
local Helper = require("Module:Helper") -- basic helper functions
local cache = require "mw.ext.LuaCache" -- https://help.fandom.com/wiki/Extension:LuaCache
local ustr = mw.ustring -- quick/short access to ustring table

-- ----------------------------------------
-- Constants
-- ----------------------------------------
local C = require("Module:ImageUnifier/constants")
local KEY_PREFIX = "Module:ImageUnifier"
local EXP_TIME = 172800
-- ----------------------------------------
-- Variables
-- ----------------------------------------
-- local g_ImgCache = {}
local g_ImageFixedCache = {}
-- ----------------------------------------
-- GetImages
-- ----------------------------------------
Self.GetImages = function(frame)
    return Self.GetImagesMain(Self.ProcessParams(Helper.GetArgs(frame), false))
end

function Self.GetImagesMain(images, params, sizeParam, skipCache)
    --[[ Direct Call params
        images = filename array
        params = table of [File:  params
        sizeParam = size group or size
    --]]
    local hash
    local cacheKey

    if not skipCache then
        hash = Helper.HashArgs(images, params, sizeParam)
        -- if g_ImgCache[hash] then
        -- if we already did this image then returned the cached version
        -- return g_ImgCache[hash]
        -- end
        cacheKey = KEY_PREFIX .. "GetImagesMain" .. hash

        if (cache.get(cacheKey)) then
            local result = cache.get(cacheKey)
            return result
        end
    end
    -- Make the code string
    local code = ""
    for i, img in ipairs(images) do
        local styles, needspan = Self.GetStyles(img, sizeParam)
        local nowrap = styles.whitespace == "nowrap"
        local prefix = ""
        local wiki = ""
        local suffix = ""
        -- --------------
        -- Span Prefix
        -- --------------
        if needspan then
            prefix = prefix .. "<span style='"
            for k, v in pairs(styles) do
                -- Size gets added elsewhere; Only do padleft on the first img and padright on last img
                if k ~= "size" and (k ~= "padleft" or i == 1) and (k ~= "padright" or i == #images) then
                    prefix = prefix .. (C.SHORTSTYLES[k] or k) .. ":" .. v .. "; "
                end
            end
            prefix = prefix .. "'>"
            if nowrap then
                prefix = prefix .. "&#8288;"
            end
        end
        -- --------------
        -- Image WikiCode
        -- --------------
        wiki = wiki .. "[[" .. "File:" .. Self.GetFileExt(img)
        local size = styles.size or sizeParam
        if size then
            wiki = wiki .. "|" .. size
        end
        local caption = ""
        for k, v in pairs(params) do
            if k == "caption" then
                -- Syntax requires captions to be listed last
                caption = "|" .. v
            elseif k == "tooltip" and sizeParam == "medium" then
                -- Temp logic for buggy tooltips
                prefix = prefix .. "<span class='tooltip'>"
                suffix = suffix .. "<span class='tooltiptext'>" .. v .. "</span></span>"
            elseif k == "options" then
                -- All the non named parameters
                wiki = wiki .. "|" .. ustr.gsub(v, ",", "|")
            else
                wiki = wiki .. "|" .. k .. "=" .. v
            end
        end
        wiki = wiki .. caption .. "]]"
        -- --------------
        -- Span Suffix
        -- --------------
        if needspan then
            if nowrap then
                suffix = suffix .. "&#8288;"
            end
            suffix = suffix .. "</span>"
        end
        code = code .. prefix .. wiki .. suffix
    end

    if not skipCache then
        -- g_ImgCache[hash] = code
        code = mw.getCurrentFrame():preprocess(code)
        cache.set(cacheKey, code, EXP_TIME)
    end

    return code
end

function Self.ProcessParams(args, skipCache)
    local images = {}
    local params = {}
    local sizeParam = nil
    for k, v in pairs(args) do
        -- --------------
        -- Image Names
        -- --------------
        if tonumber(k) then
            -- --------------
            -- Size Param
            -- --------------
            v = Self.CleanFileName(v)
            if v ~= "" then
                images[k] = v
            end
        elseif k == "size" then
            -- --------------
            -- Other Params
            -- --------------
            if C.DEFAULTS[v] then
                -- The size group was provided
                sizeParam = v
            else
                -- width, height, type
                local w, h, t = ustr.match(v or "", "^(%d*)x?(%d*)(pxo?)$")
                if t == "px" then
                    -- convert existing hardcoded sizes into named size groups
                    local m = math.max(tonumber(w) or 0, tonumber(h) or 0)
                    if m <= 35 then
                        sizeParam = "text"
                    elseif m <= 55 then
                        sizeParam = "medium"
                    elseif m <= 80 then
                        sizeParam = "large"
                    else
                        sizeParam = v
                    end
                elseif t == "pxo" then
                    -- allows for the system to be overridden if necessary
                    sizeParam = ustr.sub(v, 1, -2)
                end
            end
        else
            params[k] = v
        end
    end
    if not params.caption and params.link and ustr.sub(params.link, 1, 1) == "#" then
        -- If the link is to a section on the same page, make a caption without the #
        params.caption = ustr.sub(params.link, 2)
    end
    return images, params, sizeParam, skipCache
end

function Self.GetStyles(img, sizeParam)
    local styles = {}
    local needspan = false
    if C.DEFAULTS[sizeParam] then
        for k, v in pairs(C.DEFAULTS[sizeParam]) do
            styles[k] = v
            needspan = needspan or k ~= "size"
        end
    end
    if C.OVERRIDES[sizeParam] and C.OVERRIDES[sizeParam][img] then
        for k, v in pairs(C.OVERRIDES[sizeParam][img]) do
            styles[k] = v
            needspan = needspan or k ~= "size"
        end
    end
    return styles, needspan
end

-- ----------------------------------------
-- ImageFixed
-- ----------------------------------------
Self.ImageFixed = function(frame)
    return Self.ImageFixedMain(Helper.GetArgs(frame), frame, false)
end

function Self.ImageFixedMain(args, frame, skipCache)
    --[[ Direct Call args =
        [1] = filename,
        [2] = size or size group
        [3] = w or h for scaling to axis
        link = link location, empty string for no link, or nil for image zoom link
    --]]
    local hash

    if not skipCache then
        hash = Helper.HashArgs(args)
        if g_ImageFixedCache[hash] then
            -- if we already did this image then returned the cached version
            return g_ImageFixedCache[hash]
        end
    end
    if not frame then
        frame = mw.getCurrentFrame()
    end
    local filename = Self.CleanFileName(args[1])
    filename = Self.GetFileExt(filename or "zzZ___")
    local url = frame:preprocess("{{filepath:" .. filename .. "}}")
    assert(url, "First parameter needs to be a valid file")
    local size = args[2]
    size = C.SIZE_GROUPS[size] or tonumber(size)
    local scale = ustr.lower(ustr.sub(args[3] or "h", 1, 1)) == "w" and "width" or "height"
    local link = args.link
    local code = ""
    local code_end = ""
    -- Span for mouseover caption and link
    if link == nil then
        -- Default Link
        code = code .. "<span>[" .. url .. " "
        code_end = "]</span>"
    elseif link == "" then
        -- No Link
        code = code .. "<span>"
        code_end = "</span>"
    else
        -- Supplied Link
        link = ustr.gsub(args.link, " ", "_")
        code = code .. "<span title='" .. link .. "'>[https://wiki.biligame.com/mtas/" .. link .. " "
        code_end = "]</span>"
    end
    if size then
        url = ustr.gsub(url, "%?", "/scale-to-" .. scale .. "-down/" .. size .. "?")
    end
    code = code .. url .. code_end
    if Helper.IfDesktop() then
        code = code .. "<span style='display:none'>[[" .. "File:" .. filename .. "|20px]]</span>"
    end
    if not skipCache then
        g_ImageFixedCache[hash] = code
    end
    return code
end

-- ----------------------------------------
-- Infobox Gallery
-- ----------------------------------------
Self.InfoboxGallery = function(frame)
    return Self.InfoboxGalleryMain(Helper.GetArgs(frame), frame)
end

function Self.InfoboxGalleryMain(args, frame)
    local code = ""
    local isDesktop = Helper.IfDesktop()
    if isDesktop then
        code = code .. "<tabber>"
    else
        code = code .. "<gallery>"
    end
    for _, image in ipairs(args) do
        image = mw.text.trim(image)
        local file, cap = ustr.match(image, "^([^#]+)#?(.-)$")
        cap = cap ~= "" and cap or file
        file = Self.GetFileExt(file)
        cap = mw.text.decode(cap)
        cap = cap .. ustr.char(0x2060) -- adds a non-breaking zero width space to the cap to prevent it from matching page headers
        if isDesktop then
            -- \n|-|Apple=[[File:Apple.png|48px|center|link=]]
            code = code .. "\n|-|" .. cap .. "=[[" .. "File:" .. file .. "|48px|center|link=]]"
        else
            -- \nApple.png|Apple
            code = code .. "\n" .. file .. "|" .. cap
        end
    end
    if isDesktop then
        code = code .. "\n</tabber>"
    else
        code = code .. "\n</gallery>"
    end
    return frame:preprocess(code)
end

-- ----------------------------------------
-- Infobox Image Type
-- ----------------------------------------
Self.InfoboxImageType = function(frame)
    local hash = Helper.HashArgs(frame.args)
    local cacheKey = KEY_PREFIX .. "InfoboxImageType" .. hash

    if (cache.get(cacheKey)) then
        local result = cache.get(cacheKey)
        return result
    end

    local args = Helper.GetArgs(frame)
    local result = Self.InfoboxImageTypeMain(args, frame)
    cache.set(cacheKey, result, EXP_TIME)
    return result
end

function Self.InfoboxImageTypeMain(args, frame)
    local image = args[1]
    local stripped = mw.text.killMarkers(image)
    if ustr.match(stripped, "^%s*$") then
        if Helper.IfDesktop() and ustr.match(image, "gallery") then
            image = "Use [[" .. ":Template:InfoboxGallery]] instead[[" .. "Category:InfoboxGallery]]"
        end
        return image
    else
        return "[[" .. "File:" .. Self.GetFileExt(image) .. "|48px|center|link=]]"
    end
end

-- ----------------------------------------
-- Common Functions
-- ----------------------------------------
function Self.GetFileExt(name)
    -- Allow # (which can't be in an image name) to be a stand in for the file extension period
    local file = ustr.gsub(name, "#", ".")
    local ext = ustr.match(name, "%.([^%.]*)$")
    if not ext or not C.VALID_EXTS[ustr.lower(ext)] then
        file = file .. ".png"
    end
    return file
end

function Self.CleanFileName(name)
    -- Strip out any encoding and get plain text image names
    -- uneeded? name = mw.text.decode(name)
    name = mw.uri.decode(name, "WIKI")
    -- Also fix the case insensitivity of the first letter
    name = ustr.upper(ustr.sub(name, 1, 1)) .. ustr.sub(name, 2)
    -- Convert invalid characters in file name to hyphen
    name, _ = ustr.gsub(name, ":", "-")
    return name
end

function Self.debug()
    mw.log(Self.InfoboxImageType({
        args = {
            [1] = "Water"
        }
    }))
end
-------------------------------------------
-- Required for Modules to function
-- ----------------------------------------
return Self