首页
随机
登录
设置
关于Bleap Wiki
免责声明
Bleap Wiki
搜索
查看“︁Module:曲目列表”︁的源代码
←
Module:曲目列表
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
local p = {} -- 数据页: 存 JSON 原文 (json 内容模型) local DATA_TITLE = '模板:曲目列表.json' local validator = require('模块:数据页校验') local parse = require('模块:署名解析') -- 署名→主名义(马甲/合作名义归并) local ARTIST_MAP = '模板:曲师映射.json' local function esc(s) -- 防御 wikitext 特殊字符 (当前数据无, 以防未来出现) return (s:gsub('|', '|')) end local function loadJson(title) local t = mw.title.new(title) if not t or not t.exists then return nil end local ok, data = pcall(mw.text.jsonDecode, t:getContent()) if not ok then return nil end return data end -- 曲师列表里实际有小节的曲师(= songs/special 的曲师;教程/训练场的独占曲师不在其中) local function knownArtists(data, lk) local known = {} local function eat(list) for _, s in ipairs(list or {}) do local parts = parse.attribute(lk, s['曲师']) or parse.parts(s['曲师']) for _, pt in ipairs(parts) do known[pt.base] = true end end end eat(data.songs); eat(data.special) return known end -- 曲师署名 → 链到 [[曲师列表#主名义]](马甲/合作名义自动归并;无小节则纯文本) local function creditLinks(raw, lk, known) if not raw or raw == '' then return '' end local parts = parse.attribute(lk, raw) or parse.parts(raw) local out = {} for _, pt in ipairs(parts) do local text = pt.rawPart or pt.base if known and not known[pt.base] then out[#out + 1] = esc(text) else out[#out + 1] = '[[曲师列表#' .. esc(pt.base) .. '|' .. esc(text) .. ']]' end end -- 本曲实际使用的名义(真·马甲/组合标签/带注释 才提示) local note = '' if parse.creditNote(raw, lk) and parse.norm(raw) ~= parse.norm(table.concat((function() local t = {} for _, pt in ipairs(parts) do t[#t + 1] = (pt.rawPart or pt.base) end return t end)(), ' / ')) then note = ' <span style="font-size:85%;color:#666">(名义:' .. esc(raw) .. ')</span>' end return table.concat(out, ' / ') .. note end -- 链接目标: # 是 MediaWiki 的锚点分隔符, 标题里一律换成全角 # -- 优先用「链接名」字段; 没有就回退到曲名并自动替换 (双保险) -- 注意: 光用 <nowiki>#</nowiki> 之类的转义救不了 —— # 在标题解析阶段就被切走了 local function pageName(song, suffix) local n = song['链接名'] or song['曲名'] if suffix then n = n .. '(' .. suffix .. ')' end return (n:gsub('#', '#')) end local function norm(s) -- 曲绘文件名规范: 空格 -> 下划线 return (s:gsub(' ', '_')) end local function langWrap(song) local lang = song['lang'] if lang == 'ja' then return '{{lang|ja|' .. esc(song['曲名']) .. '}}' elseif lang == 'zh-Hant' then return '{{lang|zh-Hant|' .. esc(song['曲名']) .. '}}' end return esc(song['曲名']) end local DIFF_CLASS = { CASUAL = 'cas', TOUGH = 'tou', INSANE = 'ins', PRO = 'pro' } local function diffsCell(diffs) if #diffs == 1 and diffs[1] == '?' then return '? ? ?' end local out = {} for _, d in ipairs(diffs) do table.insert(out, '{{难度|' .. d .. '}}') end return table.concat(out, '<br>') end local function songRow(song, suffix, lk, known) local art = song['曲绘'] or '' if suffix then art = art:gsub('(' .. suffix .. ')$', '') .. '_' .. suffix end local link = esc(pageName(song, suffix)) local artist = creditLinks(song['曲师'], lk, known) return '|-\n| [[File:曲绘-' .. norm(art) .. '.png|96px|link=曲目:' .. link .. ']] || [[' .. '曲目:' .. link .. '|' .. langWrap(song) .. ']] || ' .. artist .. ' || style="text-align:center" | ' .. diffsCell(song['难度']) end local function tableOpen() return '{| class="wikitable sortable" style="width:100%"\n! 曲绘 !! 曲名 !! 曲师 !! style="text-align:center" | 难度' end local function loadData() -- 结构校验集中在 模块:数据页校验(缺 songs 时显红字 + 分类,不再静默空表) return validator.load(DATA_TITLE) end function p.render(frame) local demomode = frame and frame.args['demo'] local data, err = loadData() if not data then return tostring(err) end local out = { tableOpen() } local lk = parse.buildLookup(loadJson(ARTIST_MAP)) local known = knownArtists(data, lk) local function section(title, intro, list, suffix) if not list or #list == 0 then return end table.insert(out, '\n== ' .. title .. ' ==') if intro and intro ~= '' then table.insert(out, intro .. '\n') end table.insert(out, tableOpen()) for _, song in ipairs(list) do table.insert(out, songRow(song, suffix, lk, known)) end table.insert(out, '|}') end for _, song in ipairs(data.songs) do table.insert(out, songRow(song, nil, lk, known)) end table.insert(out, '|}') section('教程', '游戏内新手/进阶教学关卡。', data.tutorial) local story = data.story or {} section('剧情模式 · 剧情歌曲', '剧情章节中出现的曲目。', story.songs) section('剧情模式 · 训练场', '剧情模式中的练习关卡(不计入定数与榜单)。', story.training) section('石墩子模式', '愚人节限定的特殊谱面,正常游玩时不会出现。石墩子模式中,会将游戏角色强行锁定为石墩子:', data.special, '石墩子模式') if not demomode then table.insert(out, '\n[[Category:曲目]]') end -- Scribunto 返回文本中的 {{模板}} 不会被自动展开, 必须显式 preprocess return frame:preprocess(table.concat(out, '\n')) end return p
此页面嵌入的页面:
Module:曲目列表/doc
(
查看源代码
)
返回
Module:曲目列表
。