Module:署名解析:修订间差异
外观
署名→主名义解析抽到 模块:署名解析 共用;曲目列表/曲目页面 自动索引曲师与谱师 |
名义提示判定:只在真·马甲/组合标签/带注释时显示(排除纯写法差异) |
||
| 第46行: | 第46行: | ||
if type(data) ~= 'table' or type(data['主名义']) ~= 'table' then return nil end | if type(data) ~= 'table' or type(data['主名义']) ~= 'table' then return nil end | ||
local alias, collab, extra = {}, {}, {} | local alias, collab, extra = {}, {}, {} | ||
local majia, writing = {}, {} | |||
for _, m in pairs(data['主名义']) do -- 第一趟: 显示名/写法 | for _, m in pairs(data['主名义']) do -- 第一趟: 显示名/写法 | ||
if type(m) == 'table' and m['显示名'] then | if type(m) == 'table' and m['显示名'] then | ||
| 第51行: | 第52行: | ||
extra[p.norm(dn)] = m | extra[p.norm(dn)] = m | ||
alias[p.norm(dn)] = dn | alias[p.norm(dn)] = dn | ||
for _, w in ipairs(m['_写法'] or {}) do alias[p.norm(w)] = dn end | writing[p.norm(dn)] = true | ||
for _, w in ipairs(m['_写法'] or {}) do alias[p.norm(w)] = dn; writing[p.norm(w)] = true end | |||
end | end | ||
end | end | ||
for _, m in pairs(data['主名义']) do -- 第二趟: 马甲优先 | for _, m in pairs(data['主名义']) do -- 第二趟: 马甲优先 | ||
if type(m) == 'table' and m['显示名'] then | if type(m) == 'table' and m['显示名'] then | ||
for _, a in ipairs(m['马甲'] or {}) do alias[p.norm(a)] = m['显示名'] end | for _, a in ipairs(m['马甲'] or {}) do | ||
alias[p.norm(a)] = m['显示名'] | |||
majia[p.norm(a)] = true | |||
end | |||
end | end | ||
end | end | ||
| 第63行: | 第68行: | ||
extra[p.norm(u['名义'])] = { ['显示名'] = u['名义'], ['_未确认'] = true } | extra[p.norm(u['名义'])] = { ['显示名'] = u['名义'], ['_未确认'] = true } | ||
alias[p.norm(u['名义'])] = u['名义'] | alias[p.norm(u['名义'])] = u['名义'] | ||
majia[p.norm(u['名义'])] = true | |||
end | end | ||
end | end | ||
| 第70行: | 第76行: | ||
end | end | ||
end | end | ||
return { alias = alias, collab = collab, extra = extra } | return { alias = alias, collab = collab, extra = extra, majia = majia, writing = writing } | ||
end | |||
-- 是否需要提示「本曲使用的名义」: 只有真·马甲 / 组合标签 / 带括号注释才提示, | |||
-- 纯写法差异(如 TSAR → TSAR崔瀚普、Shiroi-Ice → Shiroi-Ice白井冰)不提示 | |||
function p.creditNote(raw, lk) | |||
if not lk or not raw or raw == '' then return false end | |||
local parts = p.splitRaw(raw) | |||
local bases = {} | |||
for _, pt in ipairs(parts) do | |||
bases[#bases + 1] = pt.base | |||
if lk.majia[p.norm(pt.base)] then return true end -- 马甲/未确认 | |||
end | |||
local key = p.norm(raw) | |||
local c = lk.collab[key] | |||
if c and #c > #parts then return true end -- 组合标签(名称≠成员名) | |||
local stripped = p.norm((raw:gsub('[/、,,&&+%s]', ''))) | |||
if stripped ~= p.norm(table.concat(bases, '')) then return true end -- 含括号注释等额外信息 | |||
return false | |||
end | end | ||
2026年10月3日 (六) 03:47的版本
此模块的文档可以在Module:署名解析/doc创建
-- 名称署名解析: 归一化 + 拆分合作署名
-- 由 模块:曲师列表 / 模块:谱师列表 / 模块:映射检查 共用, 避免拆词规则各写一份而漂移
local p = {}
-- 含分隔符但其实是"单人名义"的写法, 不拆分 (键为 p.norm() 后的值)
p.NO_SPLIT = {
['w/csθ'] = true, -- 单人名, 含斜杠
['↑=192.333kb/s'] = true, -- 单人名, 含斜杠
['t+pazolite'] = true, -- 单人名, 含加号
}
function p.norm(s)
return (mw.ustring.lower(tostring(s or '')):gsub('%s+', ''))
end
-- 拆分合作者: 先归一化 vs./feat./x 为 '/', 再按分隔符切, 并抽出括号注释
function p.splitRaw(raw)
local out = {}
raw = tostring(raw or '')
raw = raw:gsub('%s+[Vv][Ss]%.?%s+', '/'):gsub('%s+[Ff][Ee][Aa][Tt]%.?%s*', '/')
raw = raw:gsub('%s+[Xx]%s+', '/')
for part in mw.text.gsplit(raw, '[/、,,&&%+]') do
part = mw.text.trim(part)
if part ~= '' then
local base, ann = mw.ustring.match(part, '^(.-)%s*[((]([^))]*)[))]')
if base then
table.insert(out, { base = mw.text.trim(base), ann = ann })
else
table.insert(out, { base = part, ann = '' })
end
end
end
return out
end
-- 带 NO_SPLIT 白名单的拆分(列表与检查统一走这里)
function p.parts(raw)
if p.NO_SPLIT[p.norm(raw)] then
return { { base = raw, ann = '' } }
end
return p.splitRaw(raw)
end
-- ===== 两段式映射页 → 查找表(曲师列表/谱师列表/曲目列表/曲目页面 共用)=====
function p.buildLookup(data)
if type(data) ~= 'table' or type(data['主名义']) ~= 'table' then return nil end
local alias, collab, extra = {}, {}, {}
local majia, writing = {}, {}
for _, m in pairs(data['主名义']) do -- 第一趟: 显示名/写法
if type(m) == 'table' and m['显示名'] then
local dn = m['显示名']
extra[p.norm(dn)] = m
alias[p.norm(dn)] = dn
writing[p.norm(dn)] = true
for _, w in ipairs(m['_写法'] or {}) do alias[p.norm(w)] = dn; writing[p.norm(w)] = true end
end
end
for _, m in pairs(data['主名义']) do -- 第二趟: 马甲优先
if type(m) == 'table' and m['显示名'] then
for _, a in ipairs(m['马甲'] or {}) do
alias[p.norm(a)] = m['显示名']
majia[p.norm(a)] = true
end
end
end
for _, u in pairs(data['未确认名义'] or {}) do -- 第三段: 主名义未确认
if type(u) == 'table' and u['名义'] then
extra[p.norm(u['名义'])] = { ['显示名'] = u['名义'], ['_未确认'] = true }
alias[p.norm(u['名义'])] = u['名义']
majia[p.norm(u['名义'])] = true
end
end
for _, c in pairs(data['合作名义']) do
if type(c) == 'table' and c['名义'] then
collab[p.norm(c['名义'])] = c['组合'] or {}
end
end
return { alias = alias, collab = collab, extra = extra, majia = majia, writing = writing }
end
-- 是否需要提示「本曲使用的名义」: 只有真·马甲 / 组合标签 / 带括号注释才提示,
-- 纯写法差异(如 TSAR → TSAR崔瀚普、Shiroi-Ice → Shiroi-Ice白井冰)不提示
function p.creditNote(raw, lk)
if not lk or not raw or raw == '' then return false end
local parts = p.splitRaw(raw)
local bases = {}
for _, pt in ipairs(parts) do
bases[#bases + 1] = pt.base
if lk.majia[p.norm(pt.base)] then return true end -- 马甲/未确认
end
local key = p.norm(raw)
local c = lk.collab[key]
if c and #c > #parts then return true end -- 组合标签(名称≠成员名)
local stripped = p.norm((raw:gsub('[/、,,&&+%s]', '')))
if stripped ~= p.norm(table.concat(bases, '')) then return true end -- 含括号注释等额外信息
return false
end
-- 署名原串 → 归属列表: 合作名义→每位成员; 马甲→主名义(备注标出名义); 其余→原样
function p.attribute(lk, raw)
if not lk then return nil end
local key = p.norm(raw)
local c = lk.collab[key]
if c then
local out = {}
for _, m in ipairs(c) do out[#out + 1] = { base = m, ann = '', other = c } end
return out
end
local m = lk.alias[key]
if m then
local ann = (p.norm(raw) == p.norm(m)) and '' or ('名义:' .. raw)
return { { base = m, ann = ann } }
end
return { { base = raw, ann = '' } }
end
return p