打开/关闭菜单
打开/关闭外观设置菜单
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。

Module:GFInfobox:修订间差异

来自OGAS数据中枢
弃权者留言 | 贡献
无编辑摘要
弃权者留言 | 贡献
无编辑摘要
第1行: 第1行:
local p = {}
local p = {}
-- 基础清理函数:去除首尾空白和换行
local function cleanParam(s)
    if not s then return nil end
    s = s:gsub('^[%s\n\r\t]+', ''):gsub('[%s\n\r\t]+$', '')
    return s ~= '' and s or nil
end
-- 增强版混合内容处理
local function processMixedContent(s, frame)
    s = cleanParam(s)
    if not s then return nil end
    -- 将换行符替换为换行标签或保持格式,取决于你希望备注怎么排
    -- 如果希望自动流式排版,就把换行转为空格
    s = s:gsub('\n', ' ')
    return s
end


function p.main(frame)
function p.main(frame)
     local args = frame.args
     local args = frame:getParent().args -- 建议使用 getParent() 获取模板输入的参数
     local html = mw.html.create('div')
     local html = mw.html.create('div')
         :addClass('moe-infobox gf-infobox')
         :addClass('gf-infobox')
      
      
     -- 标题
     -- 1. 标题
    local name = cleanParam(args['标题']) or cleanParam(args['名字']) or mw.title.getCurrentTitle().subpageText
     html:tag('div')
     html:tag('div')
         :addClass('gf-title')
         :addClass('gf-title')
         :wikitext(cleanParam(args['标题'] or args['名字'] or mw.title.getCurrentTitle().subpageText))
         :wikitext(name)
      
      
     -- 图片
     -- 2. 图片
     local image = cleanParam(args['image'])
     local image = cleanParam(args['image'])
     if image and image ~= '' then
     local imgContainer = html:tag('div'):addClass('gf-image-container')
        local imgContainer = html:tag('div')
    if image then
            :addClass('gf-image-container')
         imgContainer:wikitext(string.format('[[File:%s|280px|class=infobox-image]]', image))
         imgContainer:wikitext(string.format('[[File:%s|280px|class=infobox-image]]', image))
         if cleanParam(args['图片说明']) ~= '' then
         local imgCaption = cleanParam(args['图片说明'])
             imgContainer:wikitext('<br/>')
        if imgCaption then
            imgContainer:wikitext(cleanParam(args['图片说明']))
             imgContainer:tag('div')
                :css('font-size', '0.9em')
                :css('margin-top', '4px')
                :wikitext(imgCaption)
         end
         end
     else
     else
         html:tag('div')
         imgContainer:addClass('gf-no-image')
            :addClass('gf-image-container')
             :wikitext('啊嘞?!<br/>这个妹子怎么没有头的样子……')
             :wikitext('啊嘞?!<br/>怎么回事<br/>这个妹子怎么没有头的样子……')
     end
     end
      
      
     -- 基础资料
     -- 3. 基础资料分区
     html:tag('div')
     html:tag('div'):addClass('gf-section'):wikitext('基础资料')
        :addClass('gf-section')
        :wikitext('基础资料')
      
      
     -- 信息字段列表
     -- 4. 信息字段映射
     local fields = {
     local fields = {
         {'本名', cleanParam(args['本名'])},
         {'本名', cleanParam(args['本名'])},
         {'别名', processMixedContent(args['别名'], frame)},
         {'别名', processMixedContent(args['别名'], frame)},
         {'发色', formatHairColor(args, frame)},
         {'发色', p.formatHairColor(args, frame)},
         {'瞳色', formatEyeColor(args, frame)},
         {'瞳色', p.formatEyeColor(args, frame)},
         {'声优', formatVoiceActor(args)},
         {'声优', p.formatVoiceActor(args)},
         {'萌点', processMixedContent(args['萌点'], frame)},
         {'萌点', processMixedContent(args['萌点'], frame)},
         {'类型', formatWeaponType(cleanParam(args['类型']))},
         {'类型', cleanParam(args['类型'])},
         {'稀有度', formatRarity(cleanParam(args['稀有度']))},
         {'稀有度', p.formatRarity(cleanParam(args['稀有度']))},
        {'原产国', cleanParam(args['原产国'])},
        {'研发者', cleanParam(args['研发者'])},
        {'研发商', cleanParam(args['研发商'])},
        {'研发日期', cleanParam(args['研发日期'])},
        {'生产商', cleanParam(args['生产商'])},
        {'生产日期', cleanParam(args['生产日期'])},
        {'服役期间', cleanParam(args['服役期间'])},
        {'出身地区', cleanParam(args['出身地区'])},
        {'活动范围', cleanParam(args['活动范围'])},
         {'所属团体', cleanParam(args['所属团体'])},
         {'所属团体', cleanParam(args['所属团体'])},
         {'个人状态', cleanParam(args['个人状态'])}
         {'个人状态', cleanParam(args['个人状态'])}
第57行: 第65行:
     for _, field in ipairs(fields) do
     for _, field in ipairs(fields) do
         local label, value = field[1], field[2]
         local label, value = field[1], field[2]
         if value and value ~= '' then
         if value then
             local row = html:tag('div'):addClass('gf-row')
             local row = html:tag('div'):addClass('gf-row')
             row:tag('div')
             row:tag('div'):addClass('gf-label'):wikitext(label)
                :addClass('gf-label')
             row:tag('div'):addClass('gf-value'):wikitext(value)
                :wikitext(label)
             row:tag('div')
                :addClass('gf-value')
                :wikitext(value)
         end
         end
     end
     end
      
      
     -- 亲属或相关人
     -- 5. 相关人士分区
     local related = processMixedContent(args['相关人士'], frame)
     local related = processMixedContent(args['相关人士'], frame)
     if related and related ~= '' then
     if related then
         html:tag('div')
         html:tag('div'):addClass('gf-section'):wikitext('亲属或相关人')
            :addClass('gf-section')
         html:tag('div'):addClass('gf-related'):wikitext(related)
            :wikitext('亲属或相关人')
         html:tag('div')
            :addClass('gf-related')
            :wikitext(related)
     end
     end
      
      
第82行: 第82行:
end
end


-- 基础清理函数:去除首尾空白和换行
-- 内部格式化函数 (保持原逻辑并修正)
function cleanParam(s)
function p.formatHairColor(args, frame)
     if not s then return nil end
    local v = cleanParam(args['多种发色']) or cleanParam(args['发色'])
     -- 去除首尾空白字符(包括换行、回车、制表符等)
     if not v then return nil end
    s = s:gsub('^[%s\n\r\t]+', ''):gsub('[%s\n\r\t]+$', '')
     return frame:preprocess('{{Hair_color|' .. v .. '}}')
    return s
end
end


-- 处理包含模板的混合内容:将换行符替换为空格,但保留模板展开的内容
function p.formatEyeColor(args, frame)
function processMixedContent(s, frame)
     local v = cleanParam(args['多种瞳色']) or cleanParam(args['瞳色'])
     if not s then return nil end
     if not v then return nil end
    -- 先清理首尾空白
     return frame:preprocess('{{Eye_color|' .. v .. '}}')
    s = cleanParam(s)
     if s == '' then return nil end
      
    -- 将内容中的换行符替换为空格,但小心不要破坏模板调用
    -- 更安全的方法:将连续的空白字符替换为单个空格
    s = s:gsub('%s+', ' ')
   
    return s
end
end


-- 格式化发色
function p.formatVoiceActor(args)
function formatHairColor(args, frame)
     local va = cleanParam(args['多位声优']) or cleanParam(args['声优'])
     local multiColor = cleanParam(args['多种发色'])
     if not va then return nil end
    if multiColor and multiColor ~= '' then
    return string.format('[[%s]]', va)
        return multiColor
    end
   
    local hairColor = cleanParam(args['发色'])
     if hairColor and hairColor ~= '' then
        return frame:preprocess('{{Hair_color|' .. hairColor .. '}}')
    end
   
    return nil
end
end


-- 格式化瞳色
function p.formatRarity(rarity)
function formatEyeColor(args, frame)
    if not rarity then return nil end
     local multiColor = cleanParam(args['多种瞳色'])
     local rarityColors = {[2]='#777', [3]='#33566f', [4]='#7b813f', [5]='#a7753b', [6]='#ad4229'}
     if multiColor and multiColor ~= '' then
    local num = tonumber(rarity) or (rarity:find('★') and #rarity/3) -- 简单计算星星数
         return multiColor
     if num and rarityColors[math.floor(num)] then
        local color = rarityColors[math.floor(num)]
        local stars = type(num) == "number" and string.rep('', num) or rarity
         return string.format('<span style="color:%s">%s</span>', color, stars)
     end
     end
   
     return rarity
    local eyeColor = cleanParam(args['瞳色'])
    if eyeColor and eyeColor ~= '' then
        return frame:preprocess('{{Eye_color|' .. eyeColor .. '}}')
    end
   
    return nil
end
 
-- 格式化声优
function formatVoiceActor(args)
    local multiVA = cleanParam(args['多位声优'])
    if multiVA and multiVA ~= '' then
        return multiVA
    end
   
    local voiceActor = cleanParam(args['声优'])
    if voiceActor and voiceActor ~= '' then
        return string.format('[[%s]]', voiceActor)
    end
   
    return nil
end
 
-- 格式化武器类型
function formatWeaponType(weaponType)
    local weaponTypes = {
        ['手枪'] = '手枪',
        ['冲锋枪'] = '冲锋枪',
        ['步枪'] = '步枪',
        ['突击步枪'] = '突击步枪',
        ['机枪'] = '机枪',
        ['霰弹枪'] = '霰弹枪'
    }
   
    if weaponType and weaponTypes[weaponType] then
        return weaponTypes[weaponType]
    end
   
    return weaponType
end
 
-- 格式化稀有度
function formatRarity(rarity)
    if not rarity or rarity == '' then
        return nil
    end
   
    local rarityColors = {
        [2] = '#777777',
        [3] = '#33566f',
        [4] = '#7b813f',
        [5] = '#a7753b',
        [6] = '#ad4229'
    }
   
    -- 处理数字
    local num = tonumber(rarity)
    if num then
        local color = rarityColors[num]
        if color then
            return string.format('<span style="color:%s">%s</span>', color, string.rep('★', num))
        end
        return rarity
    end
   
    -- 处理星星
    local starCount = 0
    rarity:gsub('★', function() starCount = starCount + 1 end)
    if starCount > 0 then
        local color = rarityColors[starCount]
        if color then
            return string.format('<span style="color:%s">%s</span>', color, rarity)
        end
        return rarity
    end
   
    -- 处理箭头
     return rarity:gsub('%s*→%s*', ' → '):gsub('%s*->%s*', ' → ')
end
end


return p
return p

2026年5月8日 (五) 22:34的版本

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

local p = {}

-- 基础清理函数:去除首尾空白和换行
local function cleanParam(s)
    if not s then return nil end
    s = s:gsub('^[%s\n\r\t]+', ''):gsub('[%s\n\r\t]+$', '')
    return s ~= '' and s or nil
end

-- 增强版混合内容处理
local function processMixedContent(s, frame)
    s = cleanParam(s)
    if not s then return nil end
    -- 将换行符替换为换行标签或保持格式,取决于你希望备注怎么排
    -- 如果希望自动流式排版,就把换行转为空格
    s = s:gsub('\n', ' ')
    return s
end

function p.main(frame)
    local args = frame:getParent().args -- 建议使用 getParent() 获取模板输入的参数
    local html = mw.html.create('div')
        :addClass('gf-infobox')
    
    -- 1. 标题
    local name = cleanParam(args['标题']) or cleanParam(args['名字']) or mw.title.getCurrentTitle().subpageText
    html:tag('div')
        :addClass('gf-title')
        :wikitext(name)
    
    -- 2. 图片
    local image = cleanParam(args['image'])
    local imgContainer = html:tag('div'):addClass('gf-image-container')
    if image then
        imgContainer:wikitext(string.format('[[File:%s|280px|class=infobox-image]]', image))
        local imgCaption = cleanParam(args['图片说明'])
        if imgCaption then
            imgContainer:tag('div')
                :css('font-size', '0.9em')
                :css('margin-top', '4px')
                :wikitext(imgCaption)
        end
    else
        imgContainer:addClass('gf-no-image')
            :wikitext('啊嘞?!<br/>这个妹子怎么没有头的样子……')
    end
    
    -- 3. 基础资料分区
    html:tag('div'):addClass('gf-section'):wikitext('基础资料')
    
    -- 4. 信息字段映射
    local fields = {
        {'本名', cleanParam(args['本名'])},
        {'别名', processMixedContent(args['别名'], frame)},
        {'发色', p.formatHairColor(args, frame)},
        {'瞳色', p.formatEyeColor(args, frame)},
        {'声优', p.formatVoiceActor(args)},
        {'萌点', processMixedContent(args['萌点'], frame)},
        {'类型', cleanParam(args['类型'])},
        {'稀有度', p.formatRarity(cleanParam(args['稀有度']))},
        {'所属团体', cleanParam(args['所属团体'])},
        {'个人状态', cleanParam(args['个人状态'])}
    }
    
    for _, field in ipairs(fields) do
        local label, value = field[1], field[2]
        if value then
            local row = html:tag('div'):addClass('gf-row')
            row:tag('div'):addClass('gf-label'):wikitext(label)
            row:tag('div'):addClass('gf-value'):wikitext(value)
        end
    end
    
    -- 5. 相关人士分区
    local related = processMixedContent(args['相关人士'], frame)
    if related then
        html:tag('div'):addClass('gf-section'):wikitext('亲属或相关人')
        html:tag('div'):addClass('gf-related'):wikitext(related)
    end
    
    return tostring(html)
end

-- 内部格式化函数 (保持原逻辑并修正)
function p.formatHairColor(args, frame)
    local v = cleanParam(args['多种发色']) or cleanParam(args['发色'])
    if not v then return nil end
    return frame:preprocess('{{Hair_color|' .. v .. '}}')
end

function p.formatEyeColor(args, frame)
    local v = cleanParam(args['多种瞳色']) or cleanParam(args['瞳色'])
    if not v then return nil end
    return frame:preprocess('{{Eye_color|' .. v .. '}}')
end

function p.formatVoiceActor(args)
    local va = cleanParam(args['多位声优']) or cleanParam(args['声优'])
    if not va then return nil end
    return string.format('[[%s]]', va)
end

function p.formatRarity(rarity)
    if not rarity then return nil end
    local rarityColors = {[2]='#777', [3]='#33566f', [4]='#7b813f', [5]='#a7753b', [6]='#ad4229'}
    local num = tonumber(rarity) or (rarity:find('★') and #rarity/3) -- 简单计算星星数
    if num and rarityColors[math.floor(num)] then
        local color = rarityColors[math.floor(num)]
        local stars = type(num) == "number" and string.rep('★', num) or rarity
        return string.format('<span style="color:%s">%s</span>', color, stars)
    end
    return rarity
end

return p