local p = {}
local getArgs = require('Module:Arguments').getArgs
-- 从数据表中加载预构建的映射表,减少大量调用时多次标准化所需的开销
local normalized_map = mw.loadData('Module:ImasColor/Data').normalized_map
-- 预定义HTML模板,减少字符串拼接时间
local BLOCK_HTML = '<span title="%s" style="width:10px;height:10px;background-color:%s;display:inline-block;"></span> '
local FONT_HTML_DARK = '<span style="color:black;background-color:%s;padding:0 2px;">%s</span>'
local FONT_HTML_LIGHT = '<span style="color:%s;">%s</span>'
-- 建立标准化名称缓存,优化重复调用时的性能
local normalize_cache = {}
local PATTERN = '[%·%.‧•・・**×_!!#〜~%-‐−–―—%s]'
-- 标准化处理函数
local function normalize_name(name)
if name == nil then return '' end
if normalize_cache[name] then return normalize_cache[name] end -- 如果名称被缓存,则从缓存中读取
-- 如果名称未被缓存,则进行标准化处理并缓存
local res = name:lower():gsub(PATTERN, '')
normalize_cache[name] = res
return res
end
-- 处理单个名称
local function process_name(frame, name, block, font, ref_flag)
local norm = normalize_name(name)
local data = norm ~= '' and normalized_map[norm]
-- 未找到匹配数据时返回空字符串
if not data or not data[1] then return '' end
local hex = data[1]
-- 构建颜色块
local block_html = block and BLOCK_HTML:format(hex, hex) or ''
-- 构建带颜色的文本
local text_html = hex
if font then
local lum = tonumber(data[2]) or 0.5
text_html = lum > 0.55 and
FONT_HTML_DARK:format(hex, hex) or
FONT_HTML_LIGHT:format(hex, hex)
end
-- 处理引注:使用frame:extensionTag
local ref_html = ''
if ref_flag and data[3] then
ref_html = frame:extensionTag('ref', '来源:' .. data[3])
end
return block_html .. text_html .. ref_html
end
-- 主函数
function p.main(frame)
local args = getArgs(frame, {
trim = false, -- 不自动去除空白
removeBlanks = false, -- 不移除空白参数
wrappers = 'Template:ImasColor' -- 包装模板名称
})
-- 初始化命名参数标记
local block_flag, font_flag, ref_flag = false, false, false
local names = {}
-- 检查命名参数,若存在则标记为有,并进行小写处理
if args.block then block_flag = args.block:lower() == 'block' end
if args.fontcolor then font_flag = args.fontcolor:lower() == 'fontcolor' end
if args.ref then ref_flag = args.ref:lower() == 'ref' end
-- 处理位置参数
local i = 1
while true do
local arg = args[i]
if arg == nil then break end
-- 跳过已处理的命名参数
if type(arg) == "string" then
local val = arg:lower()
if val == 'block' then
block_flag = true
elseif val == 'fontcolor' then
font_flag = true
elseif val == 'ref' then
ref_flag = true
else
table.insert(names, arg)
end
end
i = i + 1
end
-- 处理所有名称并拼接结果
local results = {}
for _, name in ipairs(names) do
local res = process_name(frame, name, block_flag, font_flag, ref_flag)
if res ~= '' then table.insert(results, res) end
end
return table.concat(results, ' ')
end
return p