打开/关闭菜单
26
6675
46
1.2万
OGAS数据中枢
打开/关闭外观设置菜单
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。

Module:少女前线立绘:修订间差异

来自OGAS数据中枢
弃权者留言 | 贡献
无编辑摘要
弃权者留言 | 贡献
无编辑摘要
 
(未显示同一用户的7个中间版本)
第8行: 第8行:
     if not s then return '' end
     if not s then return '' end
     return s:gsub('&','&amp;'):gsub('<','&lt;'):gsub('>','&gt;'):gsub('"','&quot;')
     return s:gsub('&','&amp;'):gsub('<','&lt;'):gsub('>','&gt;'):gsub('"','&quot;')
end
local function getArg(args, key)
    local v = args[key]
    if v and v ~= '' then return v end
    return nil
end
end


第19行: 第25行:
                 for k = i, math.min(i + 2, 30) do
                 for k = i, math.min(i + 2, 30) do
                     if args['tag' .. k] and args['tag' .. k] ~= '' then
                     if args['tag' .. k] and args['tag' .. k] ~= '' then
                         allEmpty = false
                         allEmpty = false; break
                        break
                     end
                     end
                 end
                 end
第36行: 第41行:
                     else
                     else
                         label = args['tag' .. i .. 'name' .. j]
                         label = args['tag' .. i .. 'name' .. j]
                         if not label or label == '' then
                         if not label or label == '' then label = '差分' .. j end
                            label = '差分' .. j
                        end
                     end
                     end
                     table.insert(pics, { file = picFile, label = label })
                     table.insert(pics, { file = picFile, label = label })
                 end
                 end
             end
             end
             table.insert(groups, {
             table.insert(groups, { label = tag, groupType = groupType, pics = pics })
                label = tag,
                groupType = groupType,
                pics = pics,
            })
         end
         end
     end
     end
第54行: 第53行:


local function renderSwitcher(groups)
local function renderSwitcher(groups)
     local html = {}
     local parts = {}
     table.insert(html, '<div class="gf-switcher-overlay">')
     table.insert(parts, '<div class="gf-switcher-overlay">')
     table.insert(html, '<div class="gf-switcher-toggle" title="展开/隐藏菜单"></div>')
     table.insert(parts, '<div class="gf-switcher-toggle" title="展开/隐藏菜单"></div>')
     table.insert(html, '<div class="gf-switcher-list">')
     table.insert(parts, '<div class="gf-switcher-list">')
     for gi, group in ipairs(groups) do
     for gi, group in ipairs(groups) do
         local isFirst = gi == 1
         local isFirst = gi == 1
         table.insert(html, string.format(
         table.insert(parts, string.format(
             '<div class="gf-group-btn%s" data-group="%d">%s</div>',
             '<div class="gf-group-btn%s" data-group="%d">%s</div>',
             isFirst and ' active' or '', gi, escape(group.label)
             isFirst and ' active' or '', gi, escape(group.label)
         ))
         ))
         table.insert(html, string.format(
         table.insert(parts, string.format(
             '<div class="gf-variant-list%s" data-group="%d">',
             '<div class="gf-variant-list%s" data-group="%d">',
             isFirst and '' or ' collapsed', gi
             isFirst and '' or ' collapsed', gi
         ))
         ))
         for vi, pic in ipairs(group.pics) do
         for vi, pic in ipairs(group.pics) do
             table.insert(html, string.format(
             table.insert(parts, string.format(
                 '<div class="gf-switch-btn%s" data-group="%d" data-variant="%d" data-filename="%s">%s</div>',
                 '<div class="gf-switch-btn%s" data-group="%d" data-variant="%d" data-filename="%s">%s</div>',
                 (isFirst and vi == 1) and ' active' or '',
                 (isFirst and vi == 1) and ' active' or '',
第75行: 第74行:
             ))
             ))
         end
         end
         table.insert(html, '</div>')
         table.insert(parts, '</div>')
     end
     end
     table.insert(html, '</div>')
     table.insert(parts, '</div>')
     table.insert(html, '</div>')
     table.insert(parts, '</div>')
     return table.concat(html, '\n')
     return table.concat(parts, '\n')
end
end


local function renderImageContainer(groups)
local function renderImageContainer(groups)
     local html = {}
     local parts = {}
     table.insert(html, '<div class="gf-image-container">')
     table.insert(parts, '<div class="gf-image-container">')
    local defaultFile = ''
     if groups[1] and groups[1].pics[1] then
     if groups[1] and groups[1].pics[1] then
         defaultFile = groups[1].pics[1].file
         table.insert(parts, string.format(
            '<div class="gf-main-img">[[File:%s|link=|class=gf-img-inner]]</div>',
            groups[1].pics[1].file
        ))
    end
    table.insert(parts, '</div>')
    return table.concat(parts, '\n')
end
 
--[[
local function renderOverlay(args, frame)
    local parts = {}
 
    local argCV      = getArg(args, '声优')
    local argIllust  = getArg(args, '人设')
    local argRarity  = getArg(args, '稀有度')
    local argNo      = getArg(args, '编号')
    local argSubname = getArg(args, '本名')
    local argTitle  = getArg(args, '标题')
    local argName    = getArg(args, '名字')
    local argType    = getArg(args, '类型')
    local argDept    = getArg(args, '归属部门')
    local argOrg    = getArg(args, '归属组织')
    local pageName  = mw.title.getCurrentTitle().subpageText
 
    table.insert(parts, '<div class="gf-info-overlay">')
 
    if argCV or argIllust then
        table.insert(parts, '<div class="gf-cv-block">')
        if argCV then
            table.insert(parts, string.format(
                '<div class="gf-cv-row"><span class="gf-cv-label">CV</span><span class="gf-cv-value">%s</span></div>',
                escape(argCV)
            ))
        end
        if argIllust then
            table.insert(parts, string.format(
                '<div class="gf-cv-row"><span class="gf-cv-label">Illustrator</span><span class="gf-cv-value">%s</span></div>',
                escape(argIllust)
            ))
        end
        table.insert(parts, '</div>')
    end
 
    if argRarity then
        local isMod = ''
        if argNo then
            isMod = frame:preprocess('{{#invoke:GfAvatarIndex|isMod|' .. argNo .. '}}')
        end
        local stars = frame:preprocess('{{User:弃权者/Template:少女前线稀有度|' .. argRarity .. '|' .. isMod .. '}}')
        table.insert(parts, '<div class="gf-stars">' .. stars .. '</div>')
    end
 
    if argSubname then
        table.insert(parts, '<div class="gf-subname">' .. escape(argSubname) .. '</div>')
     end
     end
     if defaultFile ~= '' then
 
        table.insert(html, string.format(
     local displayName = argTitle or argName or pageName
            '<div class="gf-main-img">[[File:%s|link=]]</div>',
    table.insert(parts, '<div class="gf-profile-wrap">')
             defaultFile
    table.insert(parts, '<div class="gf-name">' .. escape(displayName) .. '</div>')
         ))
    table.insert(parts, '<div class="gf-profile-watermark">PROFILE</div>')
    table.insert(parts, '</div>')
 
    local typeMap = {
        ['突击步枪'] = 'AR', ['手枪'] = 'HG', ['步枪'] = 'RF',
        ['机枪'] = 'MG', ['霰弹枪'] = 'SG', ['冲锋枪'] = 'SMG'
    }
 
    if argType or argDept or argOrg then
        table.insert(parts, '<div class="gf-bottom-info">')
        if argType then
            local rarity = argRarity or ''
            local typeCode = typeMap[argType] or argType
            local icon = frame:preprocess('{{GfTypeIcon|' .. typeCode .. '|' .. rarity .. '|60}}')
            table.insert(parts, '<div class="gf-type-icon">' .. icon .. '</div>')
        end
        if argDept or argOrg then
            table.insert(parts, '<div class="gf-affiliation">')
            if argDept then
                table.insert(parts, '<div class="gf-affil-row">' .. frame:preprocess(argDept) .. '</div>')
            end
            if argOrg then
                table.insert(parts, '<div class="gf-affil-row">' .. frame:preprocess(argOrg) .. '</div>')
            end
             table.insert(parts, '</div>')
         end
        table.insert(parts, '</div>')
     end
     end
    table.insert(html, '<div class="gf-controls">')
 
    table.insert(html, '<div class="gf-view-original" title="查看原图"></div>')
     table.insert(parts, '</div>')
    table.insert(html, '</div>')
     return table.concat(parts, '\n')
     table.insert(html, '</div>')
     return table.concat(html, '\n')
end
end
]]--


function p.main(frame)
function p.main(frame)
第108行: 第185行:
     local boxId = 'gf-box-' .. mw.uri.encode(pageName, 'PATH')
     local boxId = 'gf-box-' .. mw.uri.encode(pageName, 'PATH')


     local html = {}
     local parts = {}
     table.insert(html, frame:extensionTag('templatestyles', '', { src = STYLES_PAGE }))
     table.insert(parts, frame:extensionTag('templatestyles', '', { src = STYLES_PAGE }))
     table.insert(html, frame:preprocess('{{#widget:' .. WIDGET_NAME .. '}}'))
     table.insert(parts, frame:preprocess('{{#widget:' .. WIDGET_NAME .. '}}'))
     table.insert(html, string.format('<div class="gf-infobox-new" id="%s">', escape(boxId)))
     table.insert(parts, string.format('<div class="gf-infobox-new" id="%s">', escape(boxId)))
     table.insert(html, '<div class="gf-left-panel">')
     table.insert(parts, '<div class="gf-left-panel">')
     if #groups > 0 then
     if #groups > 0 then
         table.insert(html, renderImageContainer(groups))
         table.insert(parts, renderImageContainer(groups))
         table.insert(html, renderSwitcher(groups))
         table.insert(parts, renderSwitcher(groups))
     end
     end
     table.insert(html, '</div>')
     -- gf-info-overlay、gf-left-panel、gf-infobox-new 由模板闭合
 
     return table.concat(parts, '\n')
     return table.concat(html, '\n')
end
end


return p
return p

2026年5月19日 (二) 22:03的最新版本

此模块的文档可以在Module:少女前线立绘/doc创建

local p = {}

local PIC_NAMES = { '普通', '重创', '和谐', '重创和谐' }
local STYLES_PAGE = 'User:弃权者/Template:少女前线信息/styles.css'
local WIDGET_NAME = 'GF立绘切换'

local function escape(s)
    if not s then return '' end
    return s:gsub('&','&amp;'):gsub('<','&lt;'):gsub('>','&gt;'):gsub('"','&quot;')
end

local function getArg(args, key)
    local v = args[key]
    if v and v ~= '' then return v end
    return nil
end

local function parseGroups(args)
    local groups = {}
    for i = 1, 30 do
        local tag = args['tag' .. i]
        if not tag or tag == '' then
            if i > 3 then
                local allEmpty = true
                for k = i, math.min(i + 2, 30) do
                    if args['tag' .. k] and args['tag' .. k] ~= '' then
                        allEmpty = false; break
                    end
                end
                if allEmpty then break end
            end
        else
            local groupType = args['type' .. i] or 'pic'
            local pics = {}
            for j = 1, 20 do
                local picFile = args['tag' .. i .. 'pic' .. j]
                if picFile and picFile ~= '' then
                    local label
                    if groupType == 'pic' then
                        label = PIC_NAMES[j] or ('差分' .. j)
                    else
                        label = args['tag' .. i .. 'name' .. j]
                        if not label or label == '' then label = '差分' .. j end
                    end
                    table.insert(pics, { file = picFile, label = label })
                end
            end
            table.insert(groups, { label = tag, groupType = groupType, pics = pics })
        end
    end
    return groups
end

local function renderSwitcher(groups)
    local parts = {}
    table.insert(parts, '<div class="gf-switcher-overlay">')
    table.insert(parts, '<div class="gf-switcher-toggle" title="展开/隐藏菜单"></div>')
    table.insert(parts, '<div class="gf-switcher-list">')
    for gi, group in ipairs(groups) do
        local isFirst = gi == 1
        table.insert(parts, string.format(
            '<div class="gf-group-btn%s" data-group="%d">%s</div>',
            isFirst and ' active' or '', gi, escape(group.label)
        ))
        table.insert(parts, string.format(
            '<div class="gf-variant-list%s" data-group="%d">',
            isFirst and '' or ' collapsed', gi
        ))
        for vi, pic in ipairs(group.pics) do
            table.insert(parts, string.format(
                '<div class="gf-switch-btn%s" data-group="%d" data-variant="%d" data-filename="%s">%s</div>',
                (isFirst and vi == 1) and ' active' or '',
                gi, vi, escape(pic.file), escape(pic.label)
            ))
        end
        table.insert(parts, '</div>')
    end
    table.insert(parts, '</div>')
    table.insert(parts, '</div>')
    return table.concat(parts, '\n')
end

local function renderImageContainer(groups)
    local parts = {}
    table.insert(parts, '<div class="gf-image-container">')
    if groups[1] and groups[1].pics[1] then
        table.insert(parts, string.format(
            '<div class="gf-main-img">[[File:%s|link=|class=gf-img-inner]]</div>',
            groups[1].pics[1].file
        ))
    end
    table.insert(parts, '</div>')
    return table.concat(parts, '\n')
end

--[[
local function renderOverlay(args, frame)
    local parts = {}

    local argCV      = getArg(args, '声优')
    local argIllust  = getArg(args, '人设')
    local argRarity  = getArg(args, '稀有度')
    local argNo      = getArg(args, '编号')
    local argSubname = getArg(args, '本名')
    local argTitle   = getArg(args, '标题')
    local argName    = getArg(args, '名字')
    local argType    = getArg(args, '类型')
    local argDept    = getArg(args, '归属部门')
    local argOrg     = getArg(args, '归属组织')
    local pageName   = mw.title.getCurrentTitle().subpageText

    table.insert(parts, '<div class="gf-info-overlay">')

    if argCV or argIllust then
        table.insert(parts, '<div class="gf-cv-block">')
        if argCV then
            table.insert(parts, string.format(
                '<div class="gf-cv-row"><span class="gf-cv-label">CV</span><span class="gf-cv-value">%s</span></div>',
                escape(argCV)
            ))
        end
        if argIllust then
            table.insert(parts, string.format(
                '<div class="gf-cv-row"><span class="gf-cv-label">Illustrator</span><span class="gf-cv-value">%s</span></div>',
                escape(argIllust)
            ))
        end
        table.insert(parts, '</div>')
    end

    if argRarity then
        local isMod = ''
        if argNo then
            isMod = frame:preprocess('{{#invoke:GfAvatarIndex|isMod|' .. argNo .. '}}')
        end
        local stars = frame:preprocess('{{User:弃权者/Template:少女前线稀有度|' .. argRarity .. '|' .. isMod .. '}}')
        table.insert(parts, '<div class="gf-stars">' .. stars .. '</div>')
    end

    if argSubname then
        table.insert(parts, '<div class="gf-subname">' .. escape(argSubname) .. '</div>')
    end

    local displayName = argTitle or argName or pageName
    table.insert(parts, '<div class="gf-profile-wrap">')
    table.insert(parts, '<div class="gf-name">' .. escape(displayName) .. '</div>')
    table.insert(parts, '<div class="gf-profile-watermark">PROFILE</div>')
    table.insert(parts, '</div>')

    local typeMap = {
        ['突击步枪'] = 'AR', ['手枪'] = 'HG', ['步枪'] = 'RF',
        ['机枪'] = 'MG', ['霰弹枪'] = 'SG', ['冲锋枪'] = 'SMG'
    }

    if argType or argDept or argOrg then
        table.insert(parts, '<div class="gf-bottom-info">')
        if argType then
            local rarity = argRarity or ''
            local typeCode = typeMap[argType] or argType
            local icon = frame:preprocess('{{GfTypeIcon|' .. typeCode .. '|' .. rarity .. '|60}}')
            table.insert(parts, '<div class="gf-type-icon">' .. icon .. '</div>')
        end
        if argDept or argOrg then
            table.insert(parts, '<div class="gf-affiliation">')
            if argDept then
                table.insert(parts, '<div class="gf-affil-row">' .. frame:preprocess(argDept) .. '</div>')
            end
            if argOrg then
                table.insert(parts, '<div class="gf-affil-row">' .. frame:preprocess(argOrg) .. '</div>')
            end
            table.insert(parts, '</div>')
        end
        table.insert(parts, '</div>')
    end

    table.insert(parts, '</div>')
    return table.concat(parts, '\n')
end
]]--

function p.main(frame)
    local args = frame:getParent().args
    local pageName = mw.title.getCurrentTitle().subpageText
    local groups = parseGroups(args)
    local boxId = 'gf-box-' .. mw.uri.encode(pageName, 'PATH')

    local parts = {}
    table.insert(parts, frame:extensionTag('templatestyles', '', { src = STYLES_PAGE }))
    table.insert(parts, frame:preprocess('{{#widget:' .. WIDGET_NAME .. '}}'))
    table.insert(parts, string.format('<div class="gf-infobox-new" id="%s">', escape(boxId)))
    table.insert(parts, '<div class="gf-left-panel">')
    if #groups > 0 then
        table.insert(parts, renderImageContainer(groups))
        table.insert(parts, renderSwitcher(groups))
    end
    -- gf-info-overlay、gf-left-panel、gf-infobox-new 由模板闭合
    return table.concat(parts, '\n')
end

return p