模块:GFInfobox:修订间差异
来自OGAS数据中枢
更多操作
无编辑摘要 |
无编辑摘要 |
||
| (未显示同一用户的11个中间版本) | |||
| 第1行: | 第1行: | ||
local p = {} | local p = {} | ||
function | local function cleanParam(s) | ||
if not s then return nil end | |||
s = s:gsub('^[%s\n\r\t]+', ''):gsub('[%s\n\r\t]+$', '') | |||
if s == '' then return nil end | |||
s = s:gsub('^%s*<p[^>]*>', ''):gsub('</p>%s*$', '') | |||
return s | |||
end | |||
-- 递归展开模板和wikitext | |||
local function expandWikitext(frame, text) | |||
if not text then return nil end | |||
-- | -- 先展开所有模板 | ||
local | local expanded = text | ||
-- | -- 处理 {{ruby|文字|注音}} 模板 | ||
expanded = expanded:gsub('{{ruby|([^|]+)|([^}]+)}}', function(base, ruby) | |||
return frame:expandTemplate{ title = 'ruby', args = { base, ruby } } | |||
: | end) | ||
-- | -- 处理 {{黑幕|文字}} 模板 | ||
expanded = expanded:gsub('{{黑幕|([^}]+)}}', function(content) | |||
return frame:expandTemplate{ title = '黑幕', args = { content } } | |||
end) | |||
{' | |||
-- 处理 {{lang|语言|文字}} 模板(如果有) | |||
expanded = expanded:gsub('{{lang|([^|]+)|([^}]+)}}', function(lang, text) | |||
return frame:expandTemplate{ title = 'lang', args = { lang, text } } | |||
end) | |||
end | |||
-- | -- 如果有其他常用模板,可以继续添加 | ||
return | return expanded | ||
end | end | ||
-- | -- 安全展开不含用户输入的模板(如颜色模板) | ||
function | local function expandSafe(frame, s) | ||
if not s then return nil end | if not s then return nil end | ||
return frame:preprocess(s) | |||
end | end | ||
function p.formatRarity(rarity) | |||
function | if not rarity then return nil end | ||
if not | local colors = { | ||
[2] = '#777', | |||
[3] = '#33566f', | |||
[4] = '#7b813f', | |||
[5] = '#a7753b', | |||
[6] = '#ad4229', | |||
} | |||
local num = tonumber(rarity) | |||
or (rarity:find('★') and select(2, rarity:gsub('★', '★'))) | |||
return | if num and colors[math.floor(num)] then | ||
return string.format( | |||
'<span style="color:%s">%s</span>', | |||
colors[math.floor(num)], | |||
string.rep('★', math.floor(num)) | |||
), false | |||
end | |||
return rarity, false | |||
end | end | ||
function p.main(frame) | |||
function | local parentFrame = frame:getParent() | ||
local | local args = parentFrame.args | ||
if | |||
return | local name = cleanParam(args['标题']) | ||
or cleanParam(args['名字']) | |||
or mw.title.getCurrentTitle().subpageText | |||
-- 颜色字段:由 Lua 构造模板调用字符串,用 preprocess 展开,安全 | |||
local function fmtColor(rawColor, cType) | |||
rawColor = cleanParam(rawColor) | |||
if not rawColor then return nil end | |||
return expandSafe(frame, '{{' .. cType .. '_color|' .. rawColor .. '}}') | |||
end | end | ||
local | local hairColor = fmtColor(args['多种发色'] or args['发色'], 'Hair') | ||
local eyeColor = fmtColor(args['多种瞳色'] or args['瞳色'], 'Eye') | |||
local rarity = p.formatRarity(cleanParam(args['稀有度'])) | |||
-- 声优字段 | |||
local function fmtVoice() | |||
local v = cleanParam(args['多位声优'] or args['声优']) | |||
if not v then return nil end | |||
if v:find('%[%[') then return v end | |||
return '[[' .. v .. ']]' | |||
end | end | ||
-- | -- 获取字段值并展开其中的模板 | ||
function | local function getField(key) | ||
local raw = cleanParam(args[key]) | |||
if not raw then return nil end | |||
return | return expandWikitext(frame, raw) | ||
end | end | ||
local | ---------- 拼 wikitext + HTML 混合字符串 ---------- | ||
if | local parts = {} | ||
local function push(s) parts[#parts + 1] = s end | |||
push('<div class="gf-infobox">') | |||
push('<div class="gf-title">' .. name .. '</div>') | |||
local image = cleanParam(args['image']) | |||
push('<div class="gf-image-container">') | |||
if image then | |||
push('[[File:' .. image .. '|280px]]') | |||
local caption = getField('图片说明') | |||
if caption then | |||
push('<div style="font-size:0.9em;">' .. caption .. '</div>') | |||
end | |||
end | end | ||
push('</div>') | |||
push('<div class="gf-section">基础资料</div>') | |||
push('<div class="gf-table">') | |||
local fields = { | |||
{ '本名', getField('本名') }, | |||
local | { '别名', getField('别名') }, | ||
{ '发色', hairColor }, | |||
{ '瞳色', eyeColor }, | |||
{ '声优', fmtVoice() }, | |||
{ '萌点', getField('萌点') }, | |||
{ '类型', getField('类型') }, | |||
{ '稀有度', rarity }, | |||
{ '团体', getField('所属团体') }, | |||
{ '状态', getField('个人状态') }, | |||
} | } | ||
for _, field in ipairs(fields) do | |||
local label, value = field[1], field[2] | |||
if value then | |||
push('<div class="gf-row">') | |||
push('<div class="gf-label">' .. label .. '</div>') | |||
push('<div class="gf-value">' .. value .. '</div>') | |||
push('</div>') | |||
end | end | ||
end | end | ||
-- | push('</div>') -- gf-table | ||
local | |||
local related = getField('相关人士') | |||
if | if related then | ||
push('<div class="gf-section">亲属或相关人</div>') | |||
push('<div class="gf-related">' .. related .. '</div>') | |||
end | end | ||
-- | push('</div>') -- gf-infobox | ||
return | |||
return table.concat(parts, '\n') | |||
end | end | ||
return p | return p | ||
2026年5月13日 (三) 09:56的最新版本
此模块的文档可以在模块: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]+$', '')
if s == '' then return nil end
s = s:gsub('^%s*<p[^>]*>', ''):gsub('</p>%s*$', '')
return s
end
-- 递归展开模板和wikitext
local function expandWikitext(frame, text)
if not text then return nil end
-- 先展开所有模板
local expanded = text
-- 处理 {{ruby|文字|注音}} 模板
expanded = expanded:gsub('{{ruby|([^|]+)|([^}]+)}}', function(base, ruby)
return frame:expandTemplate{ title = 'ruby', args = { base, ruby } }
end)
-- 处理 {{黑幕|文字}} 模板
expanded = expanded:gsub('{{黑幕|([^}]+)}}', function(content)
return frame:expandTemplate{ title = '黑幕', args = { content } }
end)
-- 处理 {{lang|语言|文字}} 模板(如果有)
expanded = expanded:gsub('{{lang|([^|]+)|([^}]+)}}', function(lang, text)
return frame:expandTemplate{ title = 'lang', args = { lang, text } }
end)
-- 如果有其他常用模板,可以继续添加
return expanded
end
-- 安全展开不含用户输入的模板(如颜色模板)
local function expandSafe(frame, s)
if not s then return nil end
return frame:preprocess(s)
end
function p.formatRarity(rarity)
if not rarity then return nil end
local colors = {
[2] = '#777',
[3] = '#33566f',
[4] = '#7b813f',
[5] = '#a7753b',
[6] = '#ad4229',
}
local num = tonumber(rarity)
or (rarity:find('★') and select(2, rarity:gsub('★', '★')))
if num and colors[math.floor(num)] then
return string.format(
'<span style="color:%s">%s</span>',
colors[math.floor(num)],
string.rep('★', math.floor(num))
), false
end
return rarity, false
end
function p.main(frame)
local parentFrame = frame:getParent()
local args = parentFrame.args
local name = cleanParam(args['标题'])
or cleanParam(args['名字'])
or mw.title.getCurrentTitle().subpageText
-- 颜色字段:由 Lua 构造模板调用字符串,用 preprocess 展开,安全
local function fmtColor(rawColor, cType)
rawColor = cleanParam(rawColor)
if not rawColor then return nil end
return expandSafe(frame, '{{' .. cType .. '_color|' .. rawColor .. '}}')
end
local hairColor = fmtColor(args['多种发色'] or args['发色'], 'Hair')
local eyeColor = fmtColor(args['多种瞳色'] or args['瞳色'], 'Eye')
local rarity = p.formatRarity(cleanParam(args['稀有度']))
-- 声优字段
local function fmtVoice()
local v = cleanParam(args['多位声优'] or args['声优'])
if not v then return nil end
if v:find('%[%[') then return v end
return '[[' .. v .. ']]'
end
-- 获取字段值并展开其中的模板
local function getField(key)
local raw = cleanParam(args[key])
if not raw then return nil end
return expandWikitext(frame, raw)
end
---------- 拼 wikitext + HTML 混合字符串 ----------
local parts = {}
local function push(s) parts[#parts + 1] = s end
push('<div class="gf-infobox">')
push('<div class="gf-title">' .. name .. '</div>')
local image = cleanParam(args['image'])
push('<div class="gf-image-container">')
if image then
push('[[File:' .. image .. '|280px]]')
local caption = getField('图片说明')
if caption then
push('<div style="font-size:0.9em;">' .. caption .. '</div>')
end
end
push('</div>')
push('<div class="gf-section">基础资料</div>')
push('<div class="gf-table">')
local fields = {
{ '本名', getField('本名') },
{ '别名', getField('别名') },
{ '发色', hairColor },
{ '瞳色', eyeColor },
{ '声优', fmtVoice() },
{ '萌点', getField('萌点') },
{ '类型', getField('类型') },
{ '稀有度', rarity },
{ '团体', getField('所属团体') },
{ '状态', getField('个人状态') },
}
for _, field in ipairs(fields) do
local label, value = field[1], field[2]
if value then
push('<div class="gf-row">')
push('<div class="gf-label">' .. label .. '</div>')
push('<div class="gf-value">' .. value .. '</div>')
push('</div>')
end
end
push('</div>') -- gf-table
local related = getField('相关人士')
if related then
push('<div class="gf-section">亲属或相关人</div>')
push('<div class="gf-related">' .. related .. '</div>')
end
push('</div>') -- gf-infobox
return table.concat(parts, '\n')
end
return p