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