local p = {}
local getArgs = require('Module:Arguments').getArgs
-- Load and cache the character data from the JSON data template
local charData = nil
local function getCharData(frame)
if charData then return charData end
local raw = frame:expandTemplate({ title = '彩虹社/charbox/data' })
local ok, decoded = pcall(mw.text.jsonDecode, raw)
charData = ok and decoded or {}
return charData
end
function p._main(args, frame)
local arg1 = args[1] or ''
local arg2 = args[2] or ''
local arg3 = args[3] or 'ja'
local l = args.l or ''
local retire = args.retire or ''
local t = args.t or 'S'
local k = args.k or ''
local name = args.name or ''
-- Look up character data by arg1 first, then arg2
local data = getCharData(frame)
local charEntry = (arg1 ~= '' and data[arg1])
or (arg2 ~= '' and data[arg2])
or (name ~= '' and data[name])
or {}
-- 鼓励完善Template:彩虹社/charbox/data数据表格,便于其他模板使用
if arg3 ~= 'ko' and type(charEntry) == "table" and next(charEntry) == nil then
error('Please complete the Template:彩虹社/charbox/data')
end
-- Resolve i, h, n: explicit args take priority, then fall back to data entry
local i = args.i or ''
local h, n, c
if i ~= '' then
-- Explicit custom image: h/n irrelevant, but respect explicit n/c if given
h = nil
n = tonumber(args.n) or 1
c = tonumber(args.c) or 1
elseif charEntry.file then
-- Data entry has a file: use it as the image, ignore sprite
i = charEntry.file
n = tonumber(args.n) or 1
c = tonumber(args.c) or 1
h = nil
else
-- Use sprite: prefer explicit args, fall back to data entry
h = tonumber(args.h) or tonumber(charEntry.h) or nil
n = tonumber(args.n) or tonumber(charEntry.n) or 1
c = tonumber(args.c) or 1
end
-- Link target: l > arg1 > arg2
local linkTarget
if l ~= '' then
linkTarget = l
elseif arg1 ~= '' then
linkTarget = arg1
else
linkTarget = arg2
end
-- Italic style when |retire= is set
local outerStyle = ''
if retire ~= '' then
outerStyle = ' style="font-style:italic;"'
end
-- Expand {{arg2}} template for the Japanese name display
local function expandArg2()
if arg2 == '' then return '' end
local ok, result = pcall(function()
return frame:expandTemplate({ title = arg2 })
end)
return ok and result or arg2
end
-- Build the two name spans (shared between icon block and outer text)
local function makeSpans()
local s = ''
if arg1 ~= '' then
s = s .. '<span>' .. arg1 .. '</span>'
end
if arg2 ~= '' then
s = s .. string.format('<span lang="%s">-{%s}-</span>', arg3, expandArg2())
end
return s
end
local linkContent = ''
local hasIcon = (i ~= '') or (h ~= nil)
if hasIcon then
local innerStyle = ''
if k ~= '' then
innerStyle = 'background-color:' .. k .. ';'
end
if i ~= '' then
-- File/image path
local marginLeft = 30 - 30 * n
local imgWidth = 30 * c
local filepath = frame:callParserFunction('filepath', i)
local imgTag = frame:callParserFunction('#img', {
'',
src = filepath,
width = imgWidth,
})
imgTag = string.format(
'<div style="margin-left:%dpx; pointer-events:none;">%s</div>',
marginLeft, imgTag
)
linkContent = string.format(
'<div><div data-cb="%s"><div style="%s">%s</div>%s</div></div>',
t, innerStyle, imgTag, makeSpans()
)
else
-- Sprite path
local xPos = 30 - 30 * n
local yPos = 30 - 30 * (h or 1)
innerStyle = innerStyle .. string.format('background-position:%dpx %dpx;', xPos, yPos)
linkContent = string.format(
'<div><div data-cb="%s"><div style="%s"></div>%s</div></div>',
t, innerStyle, makeSpans()
)
end
end
linkContent = linkContent .. makeSpans()
local wikilink = '[[' .. linkTarget .. '|' .. linkContent .. ']]'
return string.format(
'<div class="charbox textToggleDisplay" data-id="charname"%s>%s </div>',
outerStyle, wikilink
)
end
function p.main(frame)
local args = getArgs(frame, {
parentFirst = true,
})
return p._main(args, frame)
end
return p