local p = {}
local getArgs = require('Module:Arguments').getArgs
-- local Tabs = require('Module:Tabs') -- We might need to use frame:expandTemplate for Tabs if it's a template, or require the module if it exists. Assuming we use expandTemplate for now or return HTML directly.
-- Using HTML directly is better for control, but Tabs has JS logic?
-- The original uses {{Tabs}}. We should probably invoke the template.
-- Helper to get colors based on style
local function getColors(isV5)
if isV5 then
return {
bg_primary = '#000080',
bg_secondary = 'yellow',
text_primary = 'yellow',
text_secondary = '#000',
border_primary = '#000080',
border_secondary = 'yellow',
shadow_primary = '#000080',
shadow_secondary = 'yellow',
header_gradient = 'linear-gradient(45deg, yellow 25%, #000080 0, #000080 50%, yellow 0, yellow 75%, #000080 0)'
}
else
return {
bg_primary = 'red',
bg_secondary = '#fff',
text_primary = '#000',
text_secondary = '#000',
border_primary = 'red',
border_secondary = '#fff',
shadow_primary = 'red',
shadow_secondary = '#fff',
header_gradient = 'linear-gradient(45deg, red 25%, #fff 0, #fff 50%, red 0, red 75%, #fff 0)'
}
end
end
-- Helper to create a styled P5 cell
-- type: 'primary' or 'secondary'
-- margin: specific margin string (e.g. '10px 5px')
-- shadowDir: {x, y}
local function createCell(content, type, margin, shadowDir, colors)
local box = mw.html.create('div')
local bg = (type == 'primary') and colors.bg_primary or colors.bg_secondary
local text = (type == 'primary') and colors.text_primary or colors.text_secondary
local border = (type == 'primary') and colors.border_primary or colors.border_secondary
local shadowColor = (type == 'primary') and colors.shadow_secondary or colors.shadow_primary
box:css({
['width'] = '125px',
['float'] = 'left',
['border'] = '1px solid ' .. border,
['font-size'] = '100%',
['padding'] = '8px 8px 8px 8px',
['margin'] = margin,
['text-align'] = 'center',
['background-color'] = bg,
['height'] = 'auto',
['box-shadow'] = (shadowDir.x)..'px '..(shadowDir.y)..'px '..shadowColor
})
box:tag('span')
:css({
['color'] = text,
['font'] = 'bold 20px/10px KaiTi,A-OTF A1 Mincho Std,Yu Mincho',
['vertical-align'] = 'bottom'
})
:wikitext(content)
return box
end
-- Render "Other Info" Tab
local function renderOtherInfo(args, isV5)
local colors = getColors(isV5)
-- Main container table for this tab
local root = mw.html.create('table')
root:css({width='200px', height='auto'})
local outerContainer = root:tag('tr'):tag('td'):tag('div')
outerContainer:css({
['width'] = 'auto',
['float'] = 'left',
['border'] = '1px solid #000', -- Always black outer border?
['border-radius'] = '20px 20px 20px 20px',
['font-size'] = '100%',
['padding'] = '8px 5px 10px 15px',
['margin'] = '0 auto',
['text-align'] = 'center',
['background-color'] = '#000',
['height'] = 'auto',
['box-shadow'] = '10px 10px ' .. (isV5 and 'yellow' or 'red')
})
local innerTable = outerContainer:tag('table')
innerTable:css({width='auto', height='auto', margin='3px 0 3px 3px'}):attr('align', 'center')
-- Star Header
innerTable:wikitext('<tr><td><div style="float:left;height:50px;width:50px;">[[File:Main star1(persona5).png]]</div></td><td><div style="float:right;height:50px;width:50px;">[[File:Main star2(persona5).png]]</div></td></tr>')
-- Section Header
local headerRow = innerTable:tag('tr'):tag('td'):attr('colspan', 2):css({width='250px', height='30px'})
local headerBox = headerRow:tag('div')
headerBox:css({
['width'] = '260px',
['border'] = '1px solid ' .. colors.border_secondary, -- Usually secondary color border
['border-radius'] = '20px 20px 0 0',
['height'] = '30px',
['font-size'] = '100%',
['margin'] = '0 20px 0 5px',
['vertical-align'] = 'bottom',
['background'] = colors.header_gradient,
['background-size'] = '30px 30px'
})
headerBox:tag('span')
:css({
['color'] = (isV5 and '#fff' or '#000'), -- V5 header text is white/black inverse? Check specific overrides if needed
['font'] = 'bold 20px/30px KaiTi,A-OTF A1 Mincho Std,Yu Mincho',
['vertical-align'] = 'bottom'
})
:wikitext('其他信息')
-- Helper to render a section (Moe Points or Related Characters)
-- keyPrefix: '萌点' or '相关人物'
-- title: '萌点' or '相关人物'
local function renderSection(keyPrefix, title)
local count = tonumber(args[keyPrefix .. '数量'])
-- If count not provided, estimate from existence of keys 1..7 (max 7 in V5 snippet)
if not count then
count = 0
for i=1,7 do
if args[keyPrefix .. i] and args[keyPrefix .. i] ~= '' then count = i end
end
if count == 0 then return end -- Skip if empty (or render at least 1?)
if count < 1 then count = 1 end
end
local row = innerTable:tag('tr')
-- Header Cell (Left)
local hCell = row:tag('td')
hCell:attr('rowspan', count)
:css({width='85px', height=(count*50)..'px'})
local hBox = hCell:tag('div')
hBox:css({
['width'] = (keyPrefix == '萌点' and '100px' or '95px'),
['float'] = 'left',
['border'] = '1px solid ' .. ((keyPrefix == '萌点') and colors.border_primary or colors.border_secondary),
['height'] = (count*50 + 30)..'px',
['font-size'] = '100%',
['padding'] = '8px 8px 8px 8px',
['margin'] = '5px 0 0 5px',
['text-align'] = 'center',
['background-color'] = ((keyPrefix == '萌点') and colors.bg_primary or colors.bg_secondary),
['box-shadow'] = (keyPrefix == '萌点' and '-10px 10px ' or '10px 10px ') .. ((keyPrefix == '萌点') and colors.shadow_secondary or colors.shadow_primary)
})
hBox:tag('span')
:css({
['color'] = ((keyPrefix == '萌点') and colors.text_primary or colors.text_secondary),
['font'] = 'bold 20px/'..(count*50 + 30)..'px KaiTi,A-OTF A1 Mincho Std,Yu Mincho',
['vertical-align'] = 'bottom'
})
:wikitext("'''"..title.."'''")
-- Item Cells (Right)
for i=1, count do
local itemRow
if i == 1 then
itemRow = row -- reuse the first row
else
itemRow = innerTable:tag('tr')
end
local cell = itemRow:tag('td'):css({width='165px', height='10px'})
local val = args[keyPrefix .. i] or ''
-- Determine styles based on index (Chaos logic)
local margin, sx, sy, type
if isV5 then
-- V5 Chaos Margins
if i == 1 then margin = '10px 20px 0 10px'; sx=10; sy=-10; type='secondary'
elseif i == 2 then margin = '15px 5px 0 15px'; sx=-10; sy=-10; type='primary'
elseif i == 3 then margin = '5px 0 5px 5px'; sx=10; sy=10; type='secondary'
elseif i == 4 then margin = '20px 5px 5px 15px'; sx=-10; sy=-10; type='primary'
elseif i == 5 then margin = '0 0 5px 5px'; sx=10; sy=10; type='secondary'
elseif i == 6 then margin = '20px 5px 5px 15px'; sx=-10; sy=-10; type='primary'
elseif i == 7 then margin = '0 0 5px 5px'; sx=10; sy=10; type='secondary'
else margin = '5px'; sx=5; sy=5; type='secondary' end
else
-- Normal Alternating Styles
if i % 2 == 1 then -- Odd
margin = '10px 10px 0 10px'; sx=10; sy=10; type='primary'
else
margin = '20px 0px 0px 10px'; sx=-10; sy=-10; type='secondary'
end
end
cell:node(createCell(val, type, margin, {x=sx, y=sy}, colors))
end
end
renderSection('萌点', '萌点')
renderSection('相关人物', '相关人物')
return root
end
function p.renderOtherInfo(frame)
local args = getArgs(frame)
if not args then args = frame.args end -- fallback if no args passed
local isV5 = (args['资料样式'] == '5')
return tostring(renderOtherInfo(args, isV5))
end
function p.main(frame)
-- Main entry point
-- Currently only exposing renderOtherInfo for testing mostly
-- Full implementation requires connecting all parts
local args = getArgs(frame)
local isV5 = (args['资料样式'] == '5')
-- For now return basic Hello or just renderOtherInfo result
-- The user has asked to "reuse repetitive parts", so they probably want this module to be callable
-- with {{#invoke:P5Chara|renderOtherInfo|...}} as well.
return p.renderOtherInfo(frame)
end
return p