Module:曲师列表:修订间差异
去掉小节下的「共 N 首曲目/张谱面」计数行;曲师列表新增 p.rank 自动排行榜 |
输出加 __NOCONTENTCONVERT__/__NOTITLECONVERT__:署名与曲名保持 UTF-8 原字,不做繁简变体转换(无需给名字加包裹,无 DOM 开销) |
||
| (未显示同一用户的4个中间版本) | |||
| 第16行: | 第16行: | ||
local parse = require('模块:署名解析') | local parse = require('模块:署名解析') | ||
local norm = parse.norm | local norm = parse.norm | ||
-- ===== 工具 ===== | -- ===== 工具 ===== | ||
| 第149行: | 第100行: | ||
local args = frame.args or {} | local args = frame.args or {} | ||
local minN = tonumber(args['min']) or 3 | local minN = tonumber(args['min']) or 3 | ||
local mode = args['mode'] or '署名' | |||
local data = validator.load(DATA_TITLE) | local data = validator.load(DATA_TITLE) | ||
if not data then return '<span class="error">数据页错误</span>' end | if not data then return '<span class="error">数据页错误</span>' end | ||
local map = loadJson(MAP_TITLE) or {} | local map = loadJson(MAP_TITLE) or {} | ||
local lk = buildLookup(map) | local lk = parse.buildLookup(map) | ||
local | local roles = loadJson('模板:曲师参与.json') or {} | ||
local sets, display = {}, {} | |||
local function touch(key, name) | |||
if not sets[key] then sets[key] = {}; display[key] = name end | |||
end | |||
for _, song in ipairs(data.songs or {}) do | for _, song in ipairs(data.songs or {}) do | ||
local raw = song['曲师'] | local raw = song['曲师'] | ||
if type(raw) == 'table' then raw = raw[1] end | if type(raw) == 'table' then raw = raw[1] end | ||
local parts = attribute(lk, raw) or parse.parts(raw) | local parts = parse.attribute(lk, raw) or parse.parts(raw) | ||
local seen = {} | local seen = {} | ||
for _, pt in ipairs(parts) do | for _, pt in ipairs(parts) do | ||
| 第164行: | 第120行: | ||
seen[key] = true | seen[key] = true | ||
local m = (lk and lk.extra[key]) or map[key] or {} | local m = (lk and lk.extra[key]) or map[key] or {} | ||
touch(key, m['显示名'] or pt.base) | |||
sets[key][song['曲名']] = true -- 署名归属 | |||
end | end | ||
end | end | ||
if mode == '参与' then | |||
for ak, songs in pairs(roles) do | |||
if ak ~= '_说明' and type(songs) == 'table' and songs[song['曲名']] then | |||
local m = (lk and lk.extra[ak]) or map[ak] or {} | |||
touch(ak, m['显示名'] or ak) | |||
sets[ak][song['曲名']] = true -- 参与记录 | |||
end | |||
end | |||
end | |||
end | |||
local counts = {} | |||
for k, set in pairs(sets) do | |||
local n = 0 | |||
for _ in pairs(set) do n = n + 1 end | |||
counts[k] = n | |||
end | end | ||
local byCount, nums = {}, {} | local byCount, nums = {}, {} | ||
| 第178行: | 第149行: | ||
for c in pairs(byCount) do table.insert(nums, c) end | for c in pairs(byCount) do table.insert(nums, c) end | ||
table.sort(nums, function(a, b) return a > b end) | table.sort(nums, function(a, b) return a > b end) | ||
local out = { '{| class="wikitable"', '|+ | local out = { '{| class="wikitable"', '|+收录曲数量排行榜(' .. mode .. ')', '!名次!!数量!!名字' } | ||
local emitted = 0 | local emitted = 0 | ||
for _, c in ipairs(nums) do | for _, c in ipairs(nums) do | ||
| 第197行: | 第168行: | ||
end | end | ||
table.insert(out, '|}') | table.insert(out, '|}') | ||
if emitted == 0 then return '<span class="error">没有达到门槛(' .. minN .. ' | if emitted == 0 then return '<span class="error">没有达到门槛(' .. minN .. ')的曲师</span>' end | ||
return frame:preprocess(table.concat(out, '\n')) | return frame:preprocess('__NOCONTENTCONVERT__\n__NOTITLECONVERT__\n' .. table.concat(out, '\n')) | ||
end | end | ||
| 第208行: | 第179行: | ||
local map = loadJson(MAP_TITLE) or {} | local map = loadJson(MAP_TITLE) or {} | ||
local roles = loadJson('模板:曲师参与.json') or {} -- 参与(作曲/作词/人声…):人工知识,并入备注 | local roles = loadJson('模板:曲师参与.json') or {} -- 参与(作曲/作词/人声…):人工知识,并入备注 | ||
local lk = buildLookup(map) | local lk = parse.buildLookup(map) | ||
local intros = loadIntros() | local intros = loadIntros() | ||
| 第216行: | 第187行: | ||
local raw = song['曲师'] | local raw = song['曲师'] | ||
if type(raw) == 'table' then raw = raw[1] end | if type(raw) == 'table' then raw = raw[1] end | ||
local parts = attribute(lk, raw) or parse.parts(raw) | local parts = parse.attribute(lk, raw) or parse.parts(raw) | ||
local seen = {} | local seen = {} | ||
for _, pt in ipairs(parts) do | for _, pt in ipairs(parts) do | ||
| 第270行: | 第241行: | ||
local rawS = type(s['曲师']) == 'table' and s['曲师'][1] or s['曲师'] | local rawS = type(s['曲师']) == 'table' and s['曲师'][1] or s['曲师'] | ||
local notes = {} | local notes = {} | ||
local r = roles[ | local r = roles[key] -- 参与数据以「艺术家」为键(= 该行归属的主名义) | ||
if r and type(r[s['曲名']]) == 'table' then | if r and type(r[s['曲名']]) == 'table' then | ||
local rl = {} | local rl = {} | ||
| 第299行: | 第270行: | ||
table.insert(out, '\n[[Category:曲师]]') | table.insert(out, '\n[[Category:曲师]]') | ||
return frame:preprocess(table.concat(out, '\n')) | return frame:preprocess('__NOCONTENTCONVERT__\n__NOTITLECONVERT__\n' .. table.concat(out, '\n')) | ||
end | end | ||
return p | return p | ||